commit 95a2f5468398a9e83a132627fc633baa61af8862 Author: xyrus02 Date: Sun Jul 28 08:58:33 2013 +0000 ADMIN: migration complete git-svn-id: https://svn.code.sf.net/p/apophysis7x/svn/trunk@1 a5d1c0f9-a0e9-45c6-87dd-9d276e40c949 diff --git a/Apophysis7X.dpr b/Apophysis7X.dpr new file mode 100644 index 0000000..144ff38 --- /dev/null +++ b/Apophysis7X.dpr @@ -0,0 +1,222 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program Apophysis7X; + +{%ToDo 'Assets\Apophysis7X.todo'} +{$R 'Resources\Apophysis7X.res'} +{$SetPEFlags $20} + +{$ifdef VER240} + // we need to update TMS Scripter to the XE3 version... + {$ifndef DisableScripting} + {$Define DisableScripting} + {$endif} +{$endif} + +uses + +{-- BASIC --} + FastMM4 in 'System\FastMM4.pas', + FastMM4Messages in 'System\FastMM4Messages.pas', + Forms, Dialogs, SysUtils, + Binary in 'IO\Binary.pas', + Base64 in 'IO\Base64.pas', + sdStringTable in 'System\sdStringTable.pas', + CustomDrawControl in 'System\CustomDrawControl.pas', + LibXmlComps in 'System\LibXmlComps.pas', + LibXmlParser in 'System\LibXmlParser.pas', + Windows7 in 'System\Windows7.pas', + RegexHelper in 'System\RegexHelper.pas', + CurvesControl in 'System\CurvesControl.pas', + + {$ifdef Apo7X64} + // if on x64, we don't use assembler + {$else} + AsmRandom in 'System\AsmRandom.pas', + {$endif} + +{-- CORE --} + Global in 'Core\Global.pas', + CommandLine in 'IO\CommandLine.pas', + MissingPlugin in 'IO\MissingPlugin.pas', + Settings in 'IO\Settings.pas', + Translation in 'Core\Translation.pas', + ParameterIO in 'IO\ParameterIO.pas', + Bezier in 'Core\Bezier.pas', + +{-- FLAME --} + RndFlame in 'Flame\RndFlame.pas', + ControlPoint in 'Flame\ControlPoint.pas', + cmapdata in 'ColorMap\cmapdata.pas', + cmap in 'ColorMap\cmap.pas', + GradientHlpr in 'ColorMap\GradientHlpr.pas', + XFormMan in 'Core\XFormMan.pas', + XForm in 'Flame\XForm.pas', + BaseVariation in 'Core\BaseVariation.pas', + +{-- RENDERER --} + RenderingCommon in 'Rendering\RenderingCommon.pas', + RenderingInterface in 'Rendering\RenderingInterface.pas', + RenderingImplementation in 'Rendering\RenderingImplementation.pas', + BucketFillerThread in 'Rendering\BucketFillerThread.pas', + RenderThread in 'Rendering\RenderThread.pas', + ImageMaker in 'Rendering\ImageMaker.pas', + +{-- VARIATIONS --} + varHemisphere in 'Variations\varHemisphere.pas', + varLog in 'Variations\varLog.pas', + varPolar2 in 'Variations\varPolar2.pas', + varRings2 in 'Variations\varRings2.pas', + varFan2 in 'Variations\varFan2.pas', + varCross in 'Variations\varCross.pas', + varWedge in 'Variations\varWedge.pas', + varEpispiral in 'Variations\varEpispiral.pas', + varBwraps in 'Variations\varBwraps.pas', + varPDJ in 'Variations\varPDJ.pas', + varJuliaN in 'Variations\varJuliaN.pas', + varJuliaScope in 'Variations\varJuliaScope.pas', + varJulia3Djf in 'Variations\varJulia3Djf.pas', + varJulia3Dz in 'Variations\varJulia3Dz.pas', + varCurl in 'Variations\varCurl.pas', + varCurl3D in 'Variations\varCurl3D.pas', + varRadialBlur in 'Variations\varRadialBlur.pas', + varBlurCircle in 'Variations\varBlurCircle.pas', + varBlurZoom in 'Variations\varBlurZoom.pas', + varBlurPixelize in 'Variations\varBlurPixelize.pas', + varFalloff2 in 'Variations\varFalloff2.pas', + varRectangles in 'Variations\varRectangles.pas', + varSplits in 'Variations\varSplits.pas', + varSeparation in 'Variations\varSeparation.pas', + varBipolar in 'Variations\varBipolar.pas', + varLoonie in 'Variations\varLoonie.pas', + varEscher in 'Variations\varEscher.pas', + varScry in 'Variations\varScry.pas', + varNGon in 'Variations\varNGon.pas', + varFoci in 'Variations\varFoci.pas', + varLazysusan in 'Variations\varLazysusan.pas', + varMobius in 'Variations\varMobius.pas', + varCrop in 'Variations\varCrop.pas', + // circlecrop + varElliptic in 'Variations\varElliptic.pas', + varWaves2 in 'Variations\varWaves2.pas', + varAuger in 'Variations\varAuger.pas', + // glynnsim2 + // flux + // boarders2 + varPreSpherical in 'Variations\varPreSpherical.pas', + varPreSinusoidal in 'Variations\varPreSinusoidal.pas', + varPreDisc in 'Variations\varPreDisc.pas', + // pre_boarders2 + varPreBwraps in 'Variations\varPreBwraps.pas', + varPreCrop in 'Variations\varPreCrop.pas', + // pre_circlecrop + varPreFalloff2 in 'Variations\varPreFalloff2.pas', + // post_boarders2 + varPostBwraps in 'Variations\varPostBwraps.pas', + varPostCurl in 'Variations\varPostCurl.pas', + varPostCurl3D in 'Variations\varPostCurl3D.pas', + varPostCrop in 'Variations\varPostCrop.pas', + // post_circlecrop + varPostFalloff2 in 'Variations\varPostFalloff2.pas', + varGenericPlugin in 'Variations\varGenericPlugin.pas', + +{-- GUI --} + Main in 'Forms\Main.pas' {MainForm}, + Tracer in 'Forms\Tracer.pas' {TraceForm}, + About in 'Forms\About.pas' {AboutForm}, + Adjust in 'Forms\Adjust.pas' {AdjustForm}, + Browser in 'Forms\Browser.pas' {GradientBrowser}, + Editor in 'Forms\Editor.pas' {EditForm}, + FormExport in 'Forms\FormExport.pas' {ExportDialog}, + formPostProcess in 'Forms\formPostProcess.pas' {frmPostProcess}, + FormRender in 'Forms\FormRender.pas' {RenderForm}, + Fullscreen in 'Forms\Fullscreen.pas' {FullscreenForm}, + ImageColoring in 'Forms\ImageColoring.pas' {frmImageColoring}, + LoadTracker in 'Forms\LoadTracker.pas' {LoadForm}, + Mutate in 'Forms\Mutate.pas' {MutateForm}, + Options in 'Forms\Options.pas' {OptionsForm}, + Save in 'Forms\Save.pas' {SaveForm}, + SavePreset in 'Forms\SavePreset.pas' {SavePresetForm}, + SplashForm in 'Forms\SplashForm.pas' {SplashWindow}, + Template in 'Forms\Template.pas' {TemplateForm}, + Curves in 'Forms\Curves.pas' {CurvesForm} + + {$ifdef DisableScripting}; + // if scripting is disabled, don't import the scripting form units + {$else}, + Preview in 'Forms\Preview.pas' {PreviewForm}, + FormFavorites in 'Forms\FormFavorites.pas' {FavoritesForm}, + ScriptForm in 'Forms\ScriptForm.pas' {ScriptEditor}, + ScriptRender in 'Forms\ScriptRender.pas'; {ScriptRenderForm} + {$endif} + +begin + InitializePlugins; + + SplashWindow := TSplashWindow.Create(Application); + SplashWindow.Show; + + Application.Initialize; + SplashWindow.Update; + + {$ifdef Apo7X64} + Application.Title := 'Apophysis 7x (32 bit)'; + {$else} + Application.Title := 'Apophysis 7x (64 bit)'; + {$endif} + Application.HelpFile := 'Apophysis7x.chm'; + Application.CreateForm(TMainForm, MainForm); + Application.CreateForm(TTraceForm, TraceForm); + Application.CreateForm(TAboutForm, AboutForm); + Application.CreateForm(TAdjustForm, AdjustForm); + Application.CreateForm(TGradientBrowser, GradientBrowser); + Application.CreateForm(TEditForm, EditForm); + Application.CreateForm(TExportDialog, ExportDialog); + Application.CreateForm(TfrmPostProcess, frmPostProcess); + Application.CreateForm(TRenderForm, RenderForm); + Application.CreateForm(TFullscreenForm, FullscreenForm); + Application.CreateForm(TfrmImageColoring, frmImageColoring); + Application.CreateForm(TLoadForm, LoadForm); + Application.CreateForm(TMutateForm, MutateForm); + Application.CreateForm(TOptionsForm, OptionsForm); + Application.CreateForm(TSaveForm, SaveForm); + Application.CreateForm(TSavePresetForm, SavePresetForm); + Application.CreateForm(TTemplateForm, TemplateForm); + Application.CreateForm(TCurvesForm, CurvesForm); + + {$ifdef DisableScripting} + // if scripting is disabled, don't create the scripting forms + {$else} + Application.CreateForm(TPreviewForm, PreviewForm); + Application.CreateForm(TFavoritesForm, FavoritesForm); + Application.CreateForm(TScriptEditor, ScriptEditor); + Application.CreateForm(TScriptRenderForm, ScriptRenderForm); + {$endif} + + Application.UpdateFormatSettings := False; + {$ifdef VER240} + FormatSettings.DecimalSeparator := '.'; + {$else} + DecimalSeparator := '.'; + {$endif} + Application.Run; +end. + + diff --git a/Apophysis7X.dproj b/Apophysis7X.dproj new file mode 100644 index 0000000..8ced832 --- /dev/null +++ b/Apophysis7X.dproj @@ -0,0 +1,360 @@ + + + {AC01F3AB-4101-4C09-A648-1CC8E2C412D5} + Apophysis7X.dpr + True + Release + 3 + Application + VCL + 14.3 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + DisableScripting;$(DCC_Define) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0 + $(BDS)\bin\default_app.manifest + Apophysis7X_Icon.ico + false + 1325 + false + vcl;rtl;dbrtl;adortl;vcldb;vclx;bdertl;vcldbx;dsnap;cds;bdecds;teeui;teedb;tee;dss;visualclx;visualdbclx;dsnapcrba;dsnapcon;VclSmp;vclie;xmlrtl;inet;inetdbbde;inetdbxpress;inetdb;nmfast;webdsnap;websnap;soaprtl;dbexpress;dbxcds;dclOffice2k;FlatStyle_D6;S303_R60;RzLPDB60;RzLPND60;vclshlctrls;B302vr60;VirtualTreesD6;o403_r60;ibxpress;CSP20I60;Rz30Ctls60;Rz30DBCtls60;indy;Indy60;vclactnband;$(DCC_UsePackage) + 00400000 + false + false + 2 + false + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;System.Win;$(DCC_Namespace) + false + ..\..\out + $(BDS)\lib\Debug;$(BDS)\Lib\Debug\Indy10;$(DELPHI)\Lib\Debug;$(DCC_UnitSearchPath) + false + true + false + false + 9 + false + false + ..\..\out\dcu + false + false + 1033 + false + + + + + 0 + 1 + 0 + ..\..\Out\x64\ + ..\..\Out\x64\dcu\ + Apo7X64;$(DCC_Define) + Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + true + + + ..\..\Out\x86\ + ..\..\Out\x86\dcu\ + Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + + + false + false + 0 + RELEASE;$(DCC_Define) + + + true + 1 + 0 + 0 + + + DEBUG;$(DCC_Define) + false + true + + + 1 + 0 + 0 + true + Resources\MAINICON.ico + true + false + true + + + 1590 + true + 1 + 15 + CompanyName=;FileDescription=;FileVersion=2.1.15.1590;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0 + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MainForm
+
+ +
TraceForm
+
+ +
AboutForm
+
+ +
AdjustForm
+
+ +
GradientBrowser
+
+ +
EditForm
+
+ +
ExportDialog
+
+ +
frmPostProcess
+
+ +
RenderForm
+
+ +
FullscreenForm
+
+ +
frmImageColoring
+
+ +
LoadForm
+
+ +
MutateForm
+
+ +
OptionsForm
+
+ +
SaveForm
+
+ +
SavePresetForm
+
+ +
SplashWindow
+
+ +
TemplateForm
+
+ +
CurvesForm
+
+ + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + Delphi.Personality.12 + + + + + Apophysis7X.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1031 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + True + True + + + 12 + + + + + DEL /Q "$(OUTPUTDIR)*$(OUTPUTEXT)" + False + + False + COPY /Y "$(OUTPUTDIR)$(OUTPUTFILENAME)" "$(OUTPUTDIR)Apophysis7X64$(OUTPUTEXT)"&&DEL /Q "$(OUTPUTDIR)$(OUTPUTFILENAME)" + False + + + DEL /Q "$(OUTPUTDIR)*$(OUTPUTEXT)" + False + + False + COPY /Y "$(OUTPUTDIR)$(OUTPUTFILENAME)" "$(OUTPUTDIR)Apophysis7X64$(OUTPUTEXT)"&&DEL /Q "$(OUTPUTDIR)$(OUTPUTFILENAME)" + False + +
diff --git a/Apophysis7X.groupproj b/Apophysis7X.groupproj new file mode 100644 index 0000000..a8ce5bc --- /dev/null +++ b/Apophysis7X.groupproj @@ -0,0 +1,36 @@ + + + {2C89F2DE-83E1-4164-B84E-1D0509F8AB8C} + + + + + + + + Default.Personality.12 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Apophysis7X.res b/Apophysis7X.res new file mode 100644 index 0000000..e2f569a Binary files /dev/null and b/Apophysis7X.res differ diff --git a/Apophysis7X.todo b/Apophysis7X.todo new file mode 100644 index 0000000..e69de29 diff --git a/Apophysis7X_Icon.ico b/Apophysis7X_Icon.ico new file mode 100644 index 0000000..3347702 Binary files /dev/null and b/Apophysis7X_Icon.ico differ diff --git a/ColorMap/GradientHlpr.pas b/ColorMap/GradientHlpr.pas new file mode 100644 index 0000000..26e0ec2 --- /dev/null +++ b/ColorMap/GradientHlpr.pas @@ -0,0 +1,167 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit GradientHlpr; + +interface + +uses + windows, Graphics, Cmap; + +const + PixelCountMax = 32768; + +type + pRGBTripleArray = ^TRGBTripleArray; + TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple; + +type + TGradientHelper = class + private + procedure RGBBlend(a, b: integer; var Palette: TColorMap); + public + function GetGradientBitmap(Index: integer; const hue_rotation: double): TBitmap; + function RandomGradient: TColorMap; + end; + +var + GradientHelper: TGradientHelper; + +implementation + +uses + Global; + +{ TGradientHelper } + +function TGradientHelper.GetGradientBitmap(Index: integer; const hue_rotation: double): TBitmap; +var + BitMap: TBitMap; + i, j: integer; + Row: pRGBTripleArray; + pal: TColorMap; +begin + GetCMap(index, hue_rotation, pal); + + BitMap := TBitMap.create; + Bitmap.PixelFormat := pf24bit; + BitMap.Width := 256; + BitMap.Height := 2; + + for j := 0 to Bitmap.Height - 1 do begin + Row := Bitmap.Scanline[j]; + for i := 0 to Bitmap.Width - 1 do begin + Row[i].rgbtRed := Pal[i][0]; + Row[i].rgbtGreen := Pal[i][1]; + Row[i].rgbtBlue := Pal[i][2]; + end + end; + + Result := BitMap; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TGradientHelper.RandomGradient: TColorMap; +var + a, b, n, nodes: integer; + rgb: array[0..2] of double; + hsv: array[0..2] of double; + pal: TColorMap; +begin + rgb[0] := 0; + rgb[1] := 0; + rgb[2] := 0; + + inc(MainSeed); + RandSeed := Mainseed; + nodes := random((MaxNodes - 1) - (MinNodes - 2)) + (MinNodes - 1); + n := 256 div nodes; + b := 0; + hsv[0] := 0.01 * (random(MaxHue - (MinHue - 1)) + MinHue); + hsv[1] := 0.01 * (random(MaxSat - (MinSat - 1)) + MinSat); + hsv[2] := 0.01 * (random(MaxLum - (MinLum - 1)) + MinLum); + hsv2rgb(hsv, rgb); + Pal[0][0] := Round(rgb[0] * 255); + Pal[0][1] := Round(rgb[1] * 255); + Pal[0][2] := Round(rgb[2] * 255); + repeat + a := b; + b := b + n; + hsv[0] := 0.01 * (random(MaxHue - (MinHue - 1)) + MinHue); + hsv[1] := 0.01 * (random(MaxSat - (MinSat - 1)) + MinSat); + hsv[2] := 0.01 * (random(MaxLum - (MinLum - 1)) + MinLum); + hsv2rgb(hsv, rgb); + if b > 255 then b := 255; + Pal[b][0] := Round(rgb[0] * 255); + Pal[b][1] := Round(rgb[1] * 255); + Pal[b][2] := Round(rgb[2] * 255); + RGBBlend(a, b, pal); + until b = 255; + Result := Pal; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TGradientHelper.RGBBlend(a, b: integer; var Palette: TColorMap); +{ Linear blend between to indices of a palette } +var + c, v: real; + vrange, range: real; + i: integer; +begin + if a = b then + begin + Exit; + end; + range := b - a; + vrange := Palette[b mod 256][0] - Palette[a mod 256][0]; + c := Palette[a mod 256][0]; + v := vrange / range; + for i := (a + 1) to (b - 1) do + begin + c := c + v; + Palette[i mod 256][0] := Round(c); + end; + vrange := Palette[b mod 256][1] - Palette[a mod 256][1]; + c := Palette[a mod 256][1]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][1] := Round(c); + end; + vrange := Palette[b mod 256][2] - Palette[a mod 256][2]; + c := Palette[a mod 256][2]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][2] := Round(c); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + GradientHelper := TGradientHelper.create; +finalization + GradientHelper.Free; +end. diff --git a/ColorMap/cmap.pas b/ColorMap/cmap.pas new file mode 100644 index 0000000..77b5aa5 --- /dev/null +++ b/ColorMap/cmap.pas @@ -0,0 +1,374 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Cmap; + +interface + +uses sysutils, classes; + +type + TColorMap = array[0..255, 0..3] of integer; + +type + EFormatInvalid = class(Exception); + +const + RANDOMCMAP = -1; + NRCMAPS = 701; + +procedure GetCmap(var Index: integer; const hue_rotation: double; out cmap: TColorMap); +procedure GetCmapName(var Index: integer; out Name: string); +procedure rgb2hsv(const rgb: array of double; out hsv: array of double); +procedure hsv2rgb(const hsv: array of double; out rgb: array of double); +function GetGradient(FileName, Entry: string): string; +function GetPalette(strng: string; var Palette: TColorMap): boolean; +procedure GetTokens(s: string; var mlist: TStringList); + +implementation + +uses + cmapdata, Math; + +procedure rgb2hsv(const rgb: array of double; out hsv: array of double); +var + maxval, minval: double; + del: double; +begin + Maxval := Max(rgb[0], Max(rgb[1], rgb[2])); + Minval := Min(rgb[0], Min(rgb[1], rgb[2])); + + hsv[2] := maxval; // v + + if (Maxval > 0) and (maxval <> minval) then begin + del := maxval - minval; + hsv[1] := del / Maxval; //s + + hsv[0] := 0; + if (rgb[0] > rgb[1]) and (rgb[0] > rgb[2]) then begin + hsv[0] := (rgb[1] - rgb[2]) / del; + end else if (rgb[1] > rgb[2]) then begin + hsv[0] := 2 + (rgb[2] - rgb[0]) / del; + end else begin + hsv[0] := 4 + (rgb[0] - rgb[1]) / del; + end; + + if hsv[0] < 0 then + hsv[0] := hsv[0] + 6; + + end else begin + hsv[0] := 0; + hsv[1] := 0; + end; +end; + +procedure hsv2rgb(const hsv: array of double; out rgb: array of double); +var + j: integer; + f, p, q, t, v: double; +begin + try +// rgb[0] := 0; +// rgb[1] := 0; +// rgb[2] := 0; + + j := floor(hsv[0]); + + f := hsv[0] - j; + v := hsv[2]; + p := hsv[2] * (1 - hsv[1]); + q := hsv[2] * (1 - hsv[1] * f); + t := hsv[2] * (1 - hsv[1] * (1 - f)); + case j of + 0: begin rgb[0] := v; rgb[1] := t; rgb[2] := p; end; + 1: begin rgb[0] := q; rgb[1] := v; rgb[2] := p; end; + 2: begin rgb[0] := p; rgb[1] := v; rgb[2] := t; end; + 3: begin rgb[0] := p; rgb[1] := q; rgb[2] := v; end; + 4: begin rgb[0] := t; rgb[1] := p; rgb[2] := v; end; + 5: begin rgb[0] := v; rgb[1] := p; rgb[2] := q; end; + end; + except on EMathError do + end; +end; + +procedure GetCmap(var Index: integer; const hue_rotation: double; out cmap: TColorMap); +var + i: Integer; + rgb: array[0..2] of double; + hsv: array[0..2] of double; +begin + if Index = RANDOMCMAP then + Index := Random(NRCMAPS); + + if (Index < 0) or (Index >= NRCMAPS) then + Index := 0; + + for i := 0 to 255 do begin + rgb[0] := cmaps[Index][i][0] / 255.0; + rgb[1] := cmaps[Index][i][1] / 255.0; + rgb[2] := cmaps[Index][i][2] / 255.0; + + rgb2hsv(rgb, hsv); + hsv[0] := hsv[0] + hue_rotation * 6; + hsv2rgb(hsv, rgb); + + cmap[i][0] := Round(rgb[0] * 255); + cmap[i][1] := Round(rgb[1] * 255); + cmap[i][2] := Round(rgb[2] * 255); + end; +end; + +procedure GetCmapName(var Index: integer; out Name: string); +begin + if Index = RANDOMCMAP then + Index := Random(NRCMAPS); + + if (Index < 0) or (Index >= NRCMAPS) then + Index := 0; + + Name := CMapNames[Index]; +end; + + +procedure RGBBlend(a, b: integer; var Palette: TColorMap); +{ Linear blend between to indices of a palette } +var + c, v: real; + vrange, range: real; + i: integer; +begin + if a = b then + begin + Exit; + end; + range := b - a; + vrange := Palette[b mod 256][0] - Palette[a mod 256][0]; + c := Palette[a mod 256][0]; + v := vrange / range; + for i := (a + 1) to (b - 1) do + begin + c := c + v; + Palette[i mod 256][0] := Round(c); + end; + vrange := Palette[b mod 256][1] - Palette[a mod 256][1]; + c := Palette[a mod 256][1]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][1] := Round(c); + end; + vrange := Palette[b mod 256][2] - Palette[a mod 256][2]; + c := Palette[a mod 256][2]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][2] := Round(c); + end; +end; + +function GetVal(token: string): string; +var + p: integer; +begin + p := Pos('=', token); + Delete(Token, 1, p); + Result := Token; +end; + +function ReplaceTabs(str: string): string; +{Changes tab characters in a string to spaces} +var + i: integer; +begin + for i := 1 to Length(str) do + begin + if str[i] = #9 then + begin + Delete(str, i, 1); + Insert(#32, str, i); + end; + end; + Result := str; +end; + +procedure GetTokens(s: string; var mlist: TStringList); +var + test, token: string; +begin + mlist.clear; + test := s; + while (Length(Test) > 0) do + begin + while (Length(Test) > 0) and CharInSet(test[1],[#32]) do + Delete(test, 1, 1); + if (Length(Test) = 0) then + exit; + token := ''; + while (Length(Test) > 0) and (not CharInSet(test[1],[#32])) do + begin + token := token + test[1]; + Delete(test, 1, 1); + end; + mlist.add(token); + end; +end; + + +function GetPalette(strng: string; var Palette: TColorMap): boolean; +{ Loads a palette from a gradient string } +var + Strings: TStringList; + index, i: integer; + Tokens: TStringList; + Indices, Colors: TStringList; + a, b: integer; +begin + GetPalette := True; + Strings := TStringList.Create; + Tokens := TStringList.Create; + Indices := TStringList.Create; + Colors := TStringList.Create; + try + try + Strings.Text := strng; + if Pos('}', Strings.Text) = 0 then raise EFormatInvalid.Create('No closing brace'); + if Pos('{', Strings[0]) = 0 then raise EFormatInvalid.Create('No opening brace.'); + GetTokens(ReplaceTabs(Strings.Text), Tokens); + i := 0; + while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do + begin + if Pos('index=', LowerCase(Tokens[i])) <> 0 then + Indices.Add(GetVal(Tokens[i])) + else if Pos('color=', LowerCase(Tokens[i])) <> 0 then + Colors.Add(GetVal(Tokens[i])); + inc(i) + end; + for i := 0 to 255 do + begin + Palette[i][0] := 0; + Palette[i][1] := 0; + Palette[i][2] := 0; + end; + if Indices.Count = 0 then raise EFormatInvalid.Create('No color info'); + for i := 0 to Indices.Count - 1 do + begin + try + index := StrToInt(Indices[i]); + while index < 0 do inc(index, 400); + index := Round(Index * (255 / 399)); + indices[i] := IntToStr(index); + assert(index>=0); + assert(index<256); + Palette[index][0] := StrToInt(Colors[i]) mod 256; + Palette[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256; + Palette[index][2] := trunc(StrToInt(Colors[i]) / 65536); + except + end; + end; + i := 1; + repeat + a := StrToInt(Indices[i - 1]); + b := StrToInt(Indices[i]); + RGBBlend(a, b, Palette); + inc(i); + until i = Indices.Count; + if (Indices[0] <> '0') or (Indices[Indices.Count - 1] <> '255') then + begin + a := StrToInt(Indices[Indices.Count - 1]); + b := StrToInt(Indices[0]) + 256; + RGBBlend(a, b, Palette); + end; + except on EFormatInvalid do + begin + Result := False; + end; + end; + finally + Tokens.Free; + Strings.Free; + Indices.Free; + Colors.Free; + end; +end; + +function GetGradient(FileName, Entry: string): string; +var + FileStrings: TStringList; + GradStrings: TStringList; + i: integer; +begin + FileStrings := TStringList.Create; + GradStrings := TStringList.Create; + try + try + FileStrings.LoadFromFile(FileName); + for i := 0 to FileStrings.count - 1 do + if Pos(Entry + ' ', Trim(FileStrings[i])) = 1 then break; + GradStrings.Add(FileStrings[i]); + repeat + inc(i); + GradStrings.Add(FileStrings[i]); + until Pos('}', FileStrings[i]) <> 0; + GetGradient := GradStrings.Text; + except on exception do + Result := ''; + end; + finally + GradStrings.Free; + FileStrings.Free; + end; +end; + +function LoadGradient(FileName, Entry: string; var gString: string; var Pal: TColorMap): boolean; +var + FileStrings: TStringList; + GradStrings: TStringList; + i: integer; +begin + FileStrings := TStringList.Create; + GradStrings := TStringList.Create; + try + try + FileStrings.LoadFromFile(FileName); + for i := 0 to FileStrings.count - 1 do + if Pos(Entry + ' ', Trim(FileStrings[i])) = 1 then break; + GradStrings.Add(FileStrings[i]); + repeat + inc(i); + GradStrings.Add(FileStrings[i]); + until Pos('}', FileStrings[i]) <> 0; + gString := GradStrings.Text; + Result := GetPalette(GradStrings.Text, Pal); + except on exception do + Result := False; + end; + finally + GradStrings.Free; + FileStrings.Free; + end; +end; + + +end. + diff --git a/ColorMap/cmapdata.pas b/ColorMap/cmapdata.pas new file mode 100644 index 0000000..f616f6f --- /dev/null +++ b/ColorMap/cmapdata.pas @@ -0,0 +1,47741 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cmapdata; + +// updated on 2004-12-10 by Ralf Lehmann to match Flam3's color maps from: +// "@(#) $Id: cmapdata.pas,v 1.2 2005/09/08 16:52:12 zueuk Exp $" + +interface + +Const + cmaps : array[0..700,0..255,0..2] of byte = +( +// 0 south-sea-bather +((185, 234, 235), (193, 238, 235), (197, 242, 235), (201, 242, 235), + (201, 246, 235), (205, 246, 235), (205, 246, 235), (205, 242, 235), + (209, 242, 235), (210, 238, 235), (209, 242, 225), (214, 242, 235), + (221, 246, 254), (213, 242, 244), (242, 250, 244), (226, 242, 235), + (222, 242, 235), (214, 242, 235), (214, 242, 244), (209, 238, 244), + (209, 238, 244), (205, 238, 244), (205, 238, 235), (201, 238, 235), + (201, 238, 235), (201, 238, 244), (201, 238, 244), (201, 242, 244), + (205, 242, 244), (209, 242, 244), (210, 242, 244), (209, 246, 244), + (205, 242, 244), (197, 242, 244), (189, 242, 244), (189, 242, 244), + (185, 238, 244), (181, 242, 244), (189, 242, 244), (193, 242, 244), + (197, 242, 254), (197, 242, 254), (189, 242, 244), (181, 242, 244), + (177, 242, 244), (181, 238, 244), (189, 234, 235), (189, 234, 235), + (193, 230, 235), (193, 230, 235), (189, 230, 225), (181, 230, 225), + (165, 230, 225), (165, 226, 225), (161, 226, 235), (157, 230, 234), + (153, 222, 244), (165, 226, 244), (165, 230, 244), (165, 230, 244), + (169, 226, 244), (173, 226, 235), (177, 226, 235), (177, 222, 235), + (177, 226, 235), (177, 230, 244), (177, 226, 244), (177, 226, 244), + (177, 226, 244), (173, 226, 244), (169, 226, 244), (161, 230, 254), + (157, 230, 254), (165, 234, 244), (173, 234, 244), (177, 238, 234), + (185, 238, 235), (193, 238, 235), (197, 238, 235), (197, 238, 235), + (201, 238, 235), (201, 242, 244), (197, 242, 244), (197, 238, 244), + (197, 234, 244), (197, 234, 244), (197, 234, 244), (193, 230, 235), + (193, 230, 235), (197, 234, 225), (197, 230, 226), (194, 226, 207), + (206, 155, 132), (178, 127, 113), (166, 132, 85), (145, 128, 85), + (154, 128, 85), (162, 114, 85), (162, 118, 75), (182, 114, 75), + (186, 127, 103), (210, 164, 132), (198, 226, 198), (201, 234, 225), + (206, 238, 216), (222, 171, 131), (206, 155, 122), (190, 144, 122), + (202, 151, 122), (219, 163, 132), (230, 183, 150), (250, 233, 206), + (222, 234, 235), (209, 238, 235), (193, 226, 235), (189, 222, 235), + (181, 222, 235), (173, 226, 244), (169, 226, 244), (169, 226, 244), + (173, 230, 244), (173, 234, 235), (173, 234, 234), (173, 230, 235), + (173, 226, 235), (173, 226, 234), (177, 230, 226), (181, 230, 226), + (189, 230, 235), (193, 230, 244), (197, 234, 244), (201, 234, 244), + (201, 238, 244), (201, 238, 244), (201, 238, 244), (201, 238, 244), + (201, 238, 244), (201, 242, 244), (201, 242, 244), (201, 242, 244), + (201, 242, 244), (201, 242, 244), (197, 238, 244), (193, 238, 254), + (177, 238, 254), (173, 230, 244), (177, 230, 244), (177, 234, 244), + (181, 238, 244), (189, 238, 244), (193, 242, 244), (201, 246, 244), + (205, 246, 244), (205, 246, 244), (205, 246, 244), (205, 242, 244), + (205, 238, 244), (205, 238, 254), (201, 238, 254), (197, 238, 254), + (193, 238, 244), (193, 238, 244), (193, 234, 244), (193, 234, 235), + (193, 234, 235), (193, 234, 235), (189, 234, 244), (185, 234, 244), + (181, 234, 244), (181, 230, 244), (181, 230, 244), (181, 234, 244), + (189, 234, 244), (193, 234, 244), (197, 234, 235), (197, 234, 235), + (201, 234, 235), (201, 234, 244), (205, 234, 244), (205, 238, 244), + (205, 238, 244), (205, 238, 244), (205, 242, 244), (201, 242, 235), + (201, 242, 235), (197, 242, 235), (193, 234, 244), (185, 230, 244), + (181, 226, 244), (181, 226, 244), (181, 230, 244), (181, 230, 244), + (185, 234, 235), (189, 238, 235), (189, 242, 235), (193, 238, 235), + (197, 238, 235), (197, 238, 235), (197, 238, 225), (193, 234, 225), + (189, 222, 216), (170, 148, 113), (117, 104, 66), (72, 55, 37), + (11, 12, 9), (36, 44, 37), (76, 117, 103), (158, 145, 113), + (177, 206, 197), (189, 226, 216), (189, 234, 226), (193, 238, 235), + (189, 238, 244), (189, 238, 244), (189, 238, 244), (185, 234, 244), + (185, 234, 244), (185, 230, 244), (189, 230, 235), (189, 230, 235), + (189, 234, 244), (193, 238, 244), (197, 242, 254), (201, 246, 254), + (201, 242, 254), (197, 238, 254), (193, 238, 244), (189, 238, 235), + (185, 234, 235), (177, 230, 234), (181, 230, 235), (181, 230, 235), + (185, 226, 235), (181, 230, 235), (189, 230, 235), (193, 234, 235), + (193, 234, 244), (189, 234, 244), (185, 230, 244), (181, 230, 244), + (177, 230, 244), (177, 230, 235), (169, 226, 235), (169, 226, 235), + (161, 222, 225), (137, 190, 197), (158, 145, 122), (149, 124, 103), + (133, 121, 103), (141, 106, 75), (141, 95, 66), (133, 99, 66), + (121, 108, 66), (121, 100, 56), (117, 104, 65), (93, 89, 56) + ), + +// 1 sky-flesh +((166, 148, 122), (219, 162, 132), (238, 212, 178), (250, 237, 206), + (238, 250, 235), (226, 242, 235), (218, 242, 225), (206, 242, 225), + (206, 238, 225), (206, 234, 207), (182, 169, 141), (178, 138, 103), + (178, 130, 103), (170, 147, 113), (177, 198, 179), (181, 230, 225), + (185, 230, 235), (189, 230, 244), (197, 230, 244), (201, 234, 244), + (205, 234, 244), (205, 238, 244), (201, 234, 235), (197, 234, 225), + (193, 222, 207), (170, 148, 122), (145, 127, 94), (117, 100, 66), + (60, 64, 47), (20, 36, 28), (8, 20, 9), (20, 28, 18), + (56, 60, 37), (113, 91, 56), (145, 106, 75), (166, 121, 85), + (190, 137, 103), (230, 190, 169), (218, 230, 226), (214, 238, 235), + (209, 238, 244), (205, 238, 244), (205, 238, 244), (201, 238, 244), + (197, 234, 244), (197, 234, 244), (197, 230, 244), (197, 230, 244), + (197, 230, 244), (193, 234, 244), (185, 230, 244), (177, 226, 235), + (157, 206, 206), (120, 153, 141), (96, 133, 132), (108, 141, 141), + (141, 177, 178), (173, 226, 225), (177, 230, 235), (185, 234, 235), + (185, 242, 244), (197, 242, 244), (197, 238, 244), (197, 238, 244), + (197, 238, 244), (193, 234, 244), (189, 230, 235), (185, 214, 197), + (154, 144, 122), (150, 127, 94), (146, 128, 85), (133, 115, 75), + (133, 120, 75), (125, 107, 75), (125, 112, 85), (133, 111, 75), + (141, 101, 66), (129, 106, 75), (137, 106, 66), (133, 102, 66), + (141, 91, 66), (141, 93, 56), (137, 93, 47), (117, 87, 37), + (109, 74, 37), (56, 44, 28), (12, 20, 9), (4, 16, 0), + (12, 28, 9), (52, 47, 28), (80, 76, 47), (113, 91, 56), + (121, 94, 56), (125, 98, 56), (113, 87, 37), (85, 63, 28), + (40, 44, 28), (12, 12, 9), (0, 12, 0), (4, 24, 9), + (28, 60, 37), (56, 88, 75), (121, 104, 84), (145, 132, 103), + (170, 160, 132), (193, 226, 207), (197, 238, 225), (205, 242, 235), + (205, 242, 244), (205, 238, 244), (201, 238, 244), (201, 238, 244), + (201, 238, 244), (197, 238, 244), (193, 234, 244), (189, 230, 235), + (189, 226, 225), (186, 189, 151), (186, 150, 103), (166, 135, 94), + (166, 134, 94), (162, 130, 94), (162, 130, 94), (166, 130, 85), + (162, 130, 85), (158, 126, 75), (150, 118, 75), (158, 113, 75), + (150, 117, 66), (154, 117, 66), (149, 114, 75), (158, 131, 85), + (166, 139, 85), (174, 142, 85), (182, 155, 113), (198, 194, 169), + (205, 230, 216), (205, 234, 235), (197, 222, 244), (193, 226, 244), + (185, 230, 244), (181, 226, 244), (177, 226, 226), (145, 165, 160), + (158, 144, 103), (158, 144, 94), (166, 143, 94), (186, 160, 122), + (197, 222, 207), (202, 226, 226), (201, 234, 235), (197, 234, 235), + (193, 238, 244), (189, 234, 244), (173, 226, 244), (173, 222, 235), + (137, 157, 160), (137, 120, 113), (129, 124, 103), (141, 132, 94), + (158, 126, 94), (170, 143, 113), (178, 185, 160), (185, 230, 225), + (189, 230, 235), (193, 234, 235), (193, 234, 235), (193, 234, 225), + (182, 194, 170), (162, 144, 113), (146, 119, 85), (113, 92, 66), + (68, 64, 37), (24, 32, 9), (0, 16, 9), (0, 12, 9), + (12, 16, 18), (56, 47, 28), (113, 83, 46), (133, 90, 56), + (150, 108, 56), (154, 109, 66), (158, 104, 66), (153, 100, 56), + (165, 95, 47), (158, 103, 47), (158, 108, 56), (158, 104, 66), + (157, 110, 75), (158, 104, 75), (162, 113, 75), (162, 108, 75), + (158, 113, 66), (170, 112, 66), (174, 116, 75), (182, 124, 75), + (174, 120, 75), (182, 124, 85), (190, 142, 103), (214, 192, 169), + (210, 230, 225), (214, 234, 235), (214, 234, 235), (210, 234, 235), + (209, 234, 235), (205, 234, 235), (205, 238, 235), (202, 238, 235), + (197, 238, 235), (197, 238, 235), (197, 238, 235), (197, 238, 235), + (201, 238, 235), (202, 238, 235), (205, 238, 235), (205, 238, 235), + (210, 242, 235), (214, 242, 235), (214, 238, 225), (210, 234, 226), + (198, 210, 188), (178, 151, 122), (158, 115, 103), (125, 107, 85), + (92, 97, 94), (48, 76, 66), (12, 24, 28), (8, 12, 18), + (4, 8, 9), (16, 28, 18), (56, 56, 37), (100, 75, 56), + (133, 98, 66), (146, 110, 85), (154, 123, 94), (158, 140, 103), + (178, 177, 141), (185, 230, 216), (193, 234, 235), (197, 234, 235), + (206, 234, 225), (206, 234, 207), (214, 162, 132), (190, 137, 94), + (178, 125, 94), (170, 123, 94), (170, 125, 94), (166, 135, 113), + (178, 168, 141), (185, 226, 207), (181, 230, 235), (185, 230, 244), + (185, 230, 244), (181, 226, 235), (190, 210, 198), (170, 152, 113) + ), + +// 2 blue-bather +((125, 100, 84), (162, 99, 75), (174, 99, 75), (182, 115, 104), + (190, 124, 122), (190, 137, 141), (194, 153, 151), (206, 161, 160), + (218, 173, 169), (230, 169, 188), (238, 172, 197), (234, 180, 197), + (234, 176, 188), (222, 180, 188), (222, 173, 179), (226, 161, 169), + (226, 149, 169), (214, 141, 151), (210, 141, 151), (198, 145, 141), + (194, 137, 132), (190, 132, 122), (178, 124, 104), (150, 104, 85), + (113, 92, 75), (56, 64, 75), (52, 68, 103), (48, 60, 122), + (40, 60, 132), (39, 56, 132), (40, 56, 122), (36, 52, 122), + (36, 52, 103), (40, 36, 56), (31, 24, 47), (12, 24, 37), + (4, 20, 28), (0, 16, 28), (4, 16, 28), (12, 24, 28), + (40, 31, 37), (52, 40, 56), (44, 48, 66), (52, 56, 113), + (48, 68, 141), (56, 81, 160), (64, 85, 170), (68, 97, 179), + (72, 97, 188), (72, 97, 188), (72, 101, 188), (72, 105, 179), + (76, 101, 179), (80, 101, 179), (173, 124, 123), (186, 136, 132), + (186, 141, 132), (190, 141, 141), (190, 141, 132), (190, 145, 132), + (194, 141, 132), (190, 137, 132), (186, 137, 132), (177, 128, 132), + (76, 105, 179), (80, 105, 188), (84, 109, 188), (186, 153, 151), + (190, 157, 151), (198, 161, 151), (202, 165, 160), (202, 161, 170), + (202, 165, 170), (202, 169, 170), (202, 169, 170), (206, 173, 170), + (206, 173, 170), (210, 173, 170), (210, 169, 170), (202, 165, 160), + (202, 165, 160), (202, 161, 151), (198, 153, 151), (198, 145, 141), + (194, 145, 141), (194, 145, 141), (198, 145, 132), (198, 136, 122), + (182, 120, 113), (170, 103, 94), (158, 88, 75), (84, 60, 56), + (48, 52, 56), (40, 40, 47), (36, 48, 47), (40, 48, 56), + (40, 52, 66), (40, 52, 113), (48, 56, 132), (52, 68, 151), + (60, 81, 170), (72, 93, 179), (72, 97, 179), (72, 97, 179), + (72, 97, 179), (73, 93, 170), (169, 111, 122), (186, 128, 132), + (186, 132, 132), (190, 128, 141), (194, 116, 132), (182, 115, 113), + (190, 111, 104), (178, 99, 85), (170, 84, 75), (117, 84, 84), + (68, 60, 85), (52, 68, 113), (48, 64, 132), (56, 73, 141), + (109, 88, 122), (158, 116, 104), (169, 124, 113), (161, 128, 113), + (73, 101, 170), (72, 101, 179), (72, 101, 179), (73, 97, 170), + (165, 120, 113), (170, 120, 113), (178, 124, 113), (182, 120, 113), + (178, 119, 103), (154, 107, 85), (121, 96, 94), (52, 64, 132), + (44, 64, 132), (48, 68, 141), (52, 73, 151), (56, 85, 160), + (64, 89, 170), (64, 93, 170), (64, 93, 170), (68, 93, 170), + (68, 97, 170), (84, 97, 151), (145, 104, 94), (174, 80, 75), + (162, 72, 66), (84, 60, 65), (64, 52, 66), (52, 48, 66), + (77, 73, 75), (141, 100, 84), (170, 116, 104), (182, 120, 113), + (182, 120, 113), (178, 124, 113), (174, 124, 122), (141, 104, 132), + (64, 77, 151), (52, 68, 151), (48, 64, 141), (44, 56, 141), + (52, 68, 151), (56, 81, 170), (68, 89, 179), (64, 97, 188), + (72, 97, 188), (76, 101, 188), (76, 105, 188), (80, 109, 188), + (182, 137, 151), (194, 149, 151), (198, 153, 160), (198, 153, 160), + (194, 153, 151), (186, 149, 141), (186, 141, 132), (169, 128, 122), + (76, 101, 179), (72, 101, 179), (68, 101, 179), (60, 93, 170), + (52, 81, 160), (48, 73, 151), (52, 73, 151), (60, 77, 151), + (129, 100, 113), (169, 120, 113), (182, 132, 122), (186, 132, 122), + (186, 132, 122), (170, 124, 123), (76, 97, 170), (68, 93, 170), + (68, 93, 170), (68, 85, 170), (64, 85, 170), (64, 81, 160), + (68, 85, 122), (129, 92, 84), (170, 95, 75), (178, 91, 75), + (186, 111, 94), (194, 119, 94), (186, 119, 104), (186, 132, 113), + (186, 136, 113), (182, 140, 113), (174, 128, 113), (166, 120, 113), + (80, 84, 151), (56, 73, 151), (52, 68, 151), (48, 68, 151), + (48, 68, 151), (44, 64, 151), (44, 64, 141), (44, 68, 141), + (48, 73, 141), (48, 73, 141), (44, 73, 151), (56, 85, 170), + (68, 97, 179), (72, 97, 188), (72, 101, 188), (72, 105, 198), + (76, 101, 188), (80, 109, 188), (186, 141, 141), (186, 141, 141), + (194, 149, 151), (202, 157, 151), (206, 157, 151), (202, 161, 151), + (198, 153, 141), (194, 149, 132), (190, 148, 122), (186, 136, 113), + (182, 123, 104), (182, 115, 104), (166, 103, 75), (113, 92, 65), + (56, 60, 56), (36, 52, 47), (36, 52, 47), (32, 44, 37), + (56, 39, 28), (146, 68, 66), (174, 80, 66), (182, 87, 66), + (194, 107, 104), (194, 111, 113), (194, 115, 113), (190, 116, 103) + ), + +// 3 no-name +((16, 9, 9), (57, 50, 24), (85, 76, 49), (100, 96, 80), + (121, 117, 88), (138, 105, 74), (141, 92, 73), (144, 76, 66), + (139, 70, 53), (127, 60, 43), (99, 44, 25), (75, 35, 29), + (61, 27, 18), (41, 12, 9), (19, 8, 8), (13, 8, 8), + (14, 8, 8), (31, 12, 10), (45, 34, 14), (71, 49, 21), + (89, 72, 38), (103, 70, 29), (107, 74, 31), (107, 76, 31), + (95, 75, 35), (82, 65, 33), (68, 40, 18), (52, 24, 12), + (41, 11, 7), (16, 7, 7), (11, 6, 6), (8, 6, 6), + (7, 6, 6), (8, 6, 6), (8, 6, 6), (9, 7, 7), + (11, 8, 8), (13, 8, 12), (15, 9, 13), (19, 18, 20), + (41, 32, 16), (59, 53, 27), (87, 74, 37), (115, 89, 34), + (129, 97, 34), (137, 107, 44), (136, 103, 35), (136, 108, 36), + (141, 109, 38), (137, 109, 44), (139, 113, 45), (140, 111, 47), + (140, 108, 50), (155, 102, 67), (148, 101, 76), (151, 100, 78), + (153, 105, 84), (155, 104, 89), (162, 113, 99), (170, 123, 116), + (172, 140, 123), (168, 144, 123), (168, 140, 121), (169, 140, 125), + (164, 141, 121), (165, 135, 116), (156, 123, 99), (153, 117, 94), + (141, 104, 88), (132, 93, 72), (99, 89, 54), (90, 75, 43), + (46, 45, 33), (17, 26, 41), (16, 20, 38), (18, 25, 32), + (47, 42, 23), (65, 58, 32), (92, 75, 43), (116, 93, 36), + (122, 96, 37), (135, 97, 41), (138, 87, 56), (147, 91, 69), + (141, 91, 68), (140, 85, 58), (140, 88, 69), (143, 84, 66), + (135, 76, 53), (134, 76, 53), (130, 71, 46), (127, 70, 44), + (126, 66, 43), (128, 71, 43), (127, 87, 31), (126, 89, 30), + (131, 93, 34), (129, 97, 33), (128, 91, 34), (122, 87, 34), + (112, 76, 30), (96, 67, 28), (79, 48, 24), (56, 39, 21), + (36, 32, 19), (19, 17, 22), (15, 8, 14), (12, 8, 12), + (10, 8, 8), (10, 7, 7), (9, 7, 8), (8, 8, 8), + (9, 8, 8), (10, 8, 8), (11, 8, 8), (13, 8, 8), + (16, 9, 8), (36, 11, 8), (49, 18, 14), (69, 39, 21), + (96, 59, 24), (122, 75, 23), (139, 97, 32), (148, 109, 39), + (148, 119, 52), (148, 120, 58), (148, 118, 60), (148, 106, 81), + (150, 108, 81), (156, 110, 86), (162, 117, 98), (165, 127, 114), + (162, 144, 123), (145, 144, 133), (140, 140, 125), (139, 142, 126), + (141, 161, 177), (169, 153, 146), (166, 152, 140), (167, 148, 135), + (171, 143, 125), (167, 138, 120), (167, 128, 110), (163, 118, 96), + (154, 109, 85), (146, 100, 76), (136, 80, 58), (117, 58, 52), + (84, 46, 39), (62, 27, 19), (47, 15, 8), (25, 8, 8), + (14, 8, 8), (14, 8, 8), (32, 11, 7), (48, 17, 11), + (70, 35, 17), (88, 44, 27), (118, 51, 33), (119, 65, 38), + (119, 65, 38), (122, 66, 43), (116, 69, 36), (101, 76, 38), + (90, 73, 39), (68, 53, 25), (43, 33, 21), (17, 20, 31), + (15, 17, 34), (16, 16, 29), (14, 10, 21), (15, 8, 17), + (38, 26, 16), (67, 35, 14), (91, 51, 19), (106, 58, 20), + (121, 72, 23), (124, 83, 26), (118, 86, 39), (105, 91, 37), + (90, 73, 40), (63, 56, 33), (26, 30, 32), (16, 17, 32), + (14, 15, 27), (12, 8, 17), (14, 8, 14), (17, 8, 8), + (40, 11, 7), (53, 24, 15), (75, 31, 18), (103, 48, 18), + (122, 55, 33), (120, 71, 30), (130, 88, 30), (141, 101, 40), + (139, 100, 51), (139, 103, 70), (120, 121, 97), (118, 113, 124), + (137, 138, 123), (137, 140, 123), (130, 131, 117), (123, 123, 98), + (128, 125, 108), (125, 125, 93), (151, 109, 83), (169, 127, 69), + (166, 129, 66), (167, 131, 62), (167, 130, 62), (160, 123, 54), + (155, 129, 57), (152, 124, 55), (153, 124, 53), (154, 120, 46), + (154, 119, 48), (146, 116, 53), (135, 108, 46), (128, 107, 56), + (104, 95, 65), (92, 85, 52), (93, 80, 46), (81, 68, 35), + (59, 51, 27), (41, 32, 16), (20, 11, 9), (13, 8, 8), + (12, 8, 8), (12, 8, 8), (13, 8, 8), (13, 7, 7), + (16, 8, 8), (36, 9, 7), (49, 15, 7), (50, 15, 10), + (54, 21, 14), (63, 27, 16), (67, 28, 16), (70, 27, 20), + (74, 26, 16), (80, 31, 17), (86, 30, 16), (84, 37, 20), + (98, 55, 20), (101, 65, 25), (111, 70, 23), (121, 83, 29), + (122, 96, 37), (130, 105, 44), (126, 103, 44), (108, 94, 64), + (109, 98, 68), (106, 98, 69), (106, 102, 74), (116, 105, 71) + ), + +// 4 pillows +((75, 58, 47), (58, 43, 43), (43, 34, 28), (28, 28, 22), + (17, 17, 17), (17, 17, 17), (17, 17, 17), (11, 17, 11), + (11, 11, 11), (11, 11, 11), (11, 11, 11), (11, 11, 11), + (11, 11, 11), (11, 17, 11), (17, 17, 17), (28, 17, 17), + (43, 22, 17), (60, 28, 22), (77, 45, 28), (94, 54, 32), + (119, 68, 34), (141, 90, 45), (173, 101, 50), (191, 106, 50), + (203, 117, 67), (186, 117, 78), (175, 112, 67), (141, 96, 62), + (128, 79, 62), (113, 73, 51), (114, 66, 43), (122, 77, 43), + (151, 73, 22), (160, 73, 28), (138, 73, 22), (117, 65, 26), + (103, 60, 37), (83, 49, 26), (77, 49, 20), (60, 28, 17), + (45, 17, 11), (26, 17, 11), (17, 17, 17), (17, 17, 17), + (17, 17, 17), (28, 22, 17), (39, 22, 22), (54, 34, 28), + (60, 34, 22), (81, 34, 22), (81, 34, 17), (87, 39, 17), + (104, 45, 11), (131, 50, 0), (156, 61, 0), (153, 67, 5), + (136, 67, 5), (125, 50, 11), (107, 51, 17), (107, 51, 17), + (104, 50, 17), (102, 51, 17), (90, 62, 34), (83, 54, 32), + (92, 64, 30), (96, 68, 39), (96, 62, 45), (104, 73, 56), + (119, 79, 56), (126, 81, 58), (136, 96, 62), (136, 96, 62), + (136, 90, 56), (117, 83, 54), (102, 73, 51), (100, 60, 49), + (96, 60, 43), (96, 62, 39), (90, 62, 39), (90, 62, 39), + (86, 64, 41), (86, 64, 47), (81, 58, 52), (71, 54, 49), + (73, 62, 56), (92, 75, 69), (119, 79, 90), (130, 102, 102), + (145, 162, 173), (175, 192, 197), (210, 216, 227), (243, 243, 243), + (252, 246, 252), (246, 246, 241), (250, 250, 239), (246, 246, 241), + (242, 197, 157), (201, 121, 88), (169, 112, 96), (141, 102, 90), + (134, 84, 79), (107, 68, 68), (85, 51, 62), (69, 49, 49), + (54, 39, 39), (45, 34, 28), (34, 28, 22), (34, 22, 17), + (54, 22, 17), (58, 20, 32), (62, 35, 35), (73, 51, 39), + (79, 56, 39), (81, 58, 47), (92, 64, 47), (96, 68, 51), + (92, 75, 58), (107, 85, 62), (111, 83, 60), (113, 85, 62), + (122, 66, 77), (134, 83, 83), (121, 76, 93), (119, 73, 84), + (103, 70, 65), (104, 73, 56), (100, 66, 49), (86, 64, 47), + (73, 62, 45), (73, 51, 39), (56, 39, 28), (28, 28, 28), + (17, 22, 17), (17, 17, 17), (17, 17, 17), (22, 28, 22), + (28, 39, 45), (28, 53, 78), (64, 58, 52), (75, 51, 51), + (100, 60, 54), (119, 68, 79), (121, 76, 76), (145, 62, 79), + (130, 85, 73), (147, 84, 34), (179, 56, 56), (158, 73, 22), + (171, 73, 11), (201, 5, 11), (182, 49, 0), (153, 61, 11), + (153, 78, 11), (167, 78, 5), (150, 56, 11), (134, 50, 5), + (124, 22, 11), (109, 17, 17), (96, 34, 22), (83, 45, 22), + (83, 39, 17), (73, 34, 22), (62, 28, 22), (54, 28, 17), + (41, 35, 18), (28, 22, 17), (22, 17, 17), (17, 17, 17), + (11, 17, 11), (11, 17, 11), (11, 17, 11), (17, 17, 17), + (17, 17, 17), (17, 17, 17), (17, 17, 17), (17, 17, 17), + (11, 11, 11), (11, 11, 11), (5, 5, 5), (5, 5, 5), + (0, 5, 0), (0, 11, 0), (0, 11, 0), (0, 11, 0), + (0, 11, 0), (5, 11, 5), (5, 11, 5), (11, 17, 5), + (17, 11, 11), (26, 11, 11), (34, 17, 11), (52, 17, 11), + (56, 28, 22), (60, 34, 34), (62, 37, 37), (75, 49, 43), + (66, 54, 49), (66, 54, 49), (60, 54, 49), (62, 51, 45), + (66, 45, 39), (69, 43, 43), (58, 32, 47), (45, 34, 39), + (34, 28, 28), (34, 34, 22), (45, 39, 28), (52, 47, 35), + (71, 54, 43), (79, 51, 56), (96, 68, 79), (119, 79, 90), + (149, 115, 109), (164, 169, 175), (185, 191, 196), (222, 228, 233), + (241, 241, 241), (254, 214, 186), (240, 206, 139), (203, 128, 78), + (186, 112, 78), (173, 90, 67), (141, 84, 51), (124, 79, 56), + (113, 79, 62), (86, 81, 75), (86, 86, 118), (134, 134, 156), + (167, 139, 162), (197, 140, 135), (173, 127, 116), (155, 133, 104), + (141, 102, 79), (156, 90, 67), (169, 106, 50), (164, 101, 28), + (151, 73, 16), (116, 45, 17), (88, 34, 17), (77, 28, 11), + (66, 17, 17), (36, 5, 5), (22, 11, 0), (17, 20, 0), + (17, 11, 5), (17, 11, 0), (11, 11, 11), (11, 11, 11), + (11, 11, 11), (11, 11, 11), (5, 11, 5), (5, 17, 5), + (5, 17, 5), (5, 11, 5), (11, 11, 11), (17, 11, 11) + ), + +// 5 mauve-splat +((22, 22, 22), (22, 22, 22), (22, 17, 20), (22, 11, 15), + (17, 5, 11), (11, 5, 11), (11, 5, 11), (11, 5, 11), + (11, 5, 11), (11, 5, 11), (11, 5, 11), (11, 5, 15), + (11, 11, 15), (11, 11, 15), (11, 11, 17), (17, 11, 17), + (17, 17, 17), (17, 17, 17), (17, 17, 17), (17, 11, 11), + (17, 11, 11), (17, 11, 11), (17, 5, 11), (11, 5, 9), + (5, 5, 5), (5, 5, 5), (5, 5, 5), (5, 5, 9), + (5, 5, 11), (5, 5, 15), (11, 5, 17), (17, 5, 17), + (17, 5, 15), (17, 5, 15), (11, 5, 11), (11, 5, 11), + (11, 5, 11), (11, 5, 11), (11, 5, 15), (11, 11, 17), + (11, 11, 17), (17, 11, 17), (17, 11, 20), (17, 5, 22), + (17, 11, 20), (22, 11, 20), (22, 17, 22), (22, 22, 22), + (22, 28, 17), (22, 28, 22), (22, 22, 22), (22, 22, 22), + (22, 22, 22), (22, 22, 22), (22, 22, 22), (22, 17, 22), + (22, 17, 20), (22, 17, 17), (22, 17, 17), (28, 17, 17), + (28, 17, 17), (22, 17, 17), (22, 11, 17), (22, 11, 17), + (17, 17, 17), (17, 17, 22), (17, 11, 22), (11, 11, 17), + (11, 11, 17), (11, 11, 17), (5, 11, 15), (5, 5, 11), + (5, 0, 11), (5, 0, 9), (5, 5, 5), (11, 5, 5), + (17, 5, 5), (22, 11, 11), (22, 17, 17), (28, 22, 22), + (28, 22, 22), (28, 22, 22), (28, 22, 34), (28, 22, 37), + (22, 17, 32), (17, 11, 30), (11, 11, 24), (11, 11, 20), + (11, 11, 20), (11, 5, 26), (11, 5, 20), (11, 5, 20), + (11, 5, 20), (11, 5, 17), (11, 5, 17), (17, 5, 17), + (17, 5, 17), (17, 5, 20), (17, 5, 20), (17, 5, 20), + (22, 11, 26), (17, 11, 32), (26, 20, 39), (28, 28, 43), + (77, 66, 72), (96, 122, 101), (174, 172, 129), (84, 139, 146), + (240, 195, 184), (191, 112, 78), (159, 90, 73), (210, 73, 44), + (120, 94, 66), (107, 90, 90), (84, 88, 90), (118, 90, 67), + (85, 96, 107), (66, 100, 117), (75, 75, 64), (54, 80, 74), + (54, 66, 54), (39, 45, 17), (28, 28, 28), (32, 32, 32), + (45, 39, 34), (83, 37, 37), (131, 28, 11), (213, 22, 0), + (218, 16, 5), (148, 27, 0), (75, 16, 22), (43, 22, 17), + (28, 22, 11), (22, 22, 5), (32, 17, 0), (28, 37, 0), + (17, 17, 5), (17, 22, 11), (17, 17, 11), (17, 11, 11), + (17, 11, 11), (17, 11, 11), (11, 11, 11), (11, 5, 11), + (11, 5, 11), (11, 5, 11), (17, 5, 11), (17, 5, 11), + (17, 5, 11), (11, 0, 11), (11, 0, 11), (11, 0, 11), + (11, 0, 11), (11, 5, 11), (11, 5, 11), (11, 5, 11), + (11, 5, 11), (11, 5, 11), (11, 11, 11), (11, 11, 15), + (11, 5, 17), (11, 5, 17), (17, 5, 17), (17, 5, 17), + (17, 11, 17), (17, 11, 17), (17, 11, 17), (17, 11, 17), + (17, 11, 15), (17, 11, 11), (17, 11, 5), (11, 11, 0), + (17, 5, 0), (17, 5, 5), (17, 5, 5), (17, 5, 11), + (17, 5, 11), (17, 5, 11), (17, 5, 11), (17, 0, 11), + (17, 0, 11), (17, 0, 5), (11, 5, 5), (11, 5, 5), + (5, 5, 5), (0, 0, 5), (5, 5, 5), (11, 5, 5), + (11, 5, 5), (11, 11, 11), (11, 11, 11), (11, 11, 11), + (11, 5, 11), (11, 5, 11), (11, 5, 11), (11, 5, 11), + (11, 5, 11), (5, 5, 15), (5, 0, 15), (5, 0, 17), + (11, 0, 17), (11, 0, 15), (11, 0, 11), (11, 0, 11), + (11, 0, 11), (11, 0, 9), (11, 0, 5), (11, 0, 0), + (11, 0, 0), (11, 0, 5), (11, 0, 5), (11, 0, 5), + (11, 5, 5), (17, 5, 5), (17, 5, 5), (17, 11, 11), + (17, 11, 11), (17, 11, 11), (17, 11, 11), (20, 11, 11), + (22, 17, 11), (22, 17, 17), (22, 17, 17), (22, 17, 17), + (17, 11, 17), (17, 11, 17), (17, 11, 17), (17, 11, 17), + (17, 11, 17), (17, 11, 17), (17, 11, 17), (17, 11, 17), + (17, 11, 17), (17, 11, 17), (17, 11, 17), (17, 11, 20), + (17, 11, 22), (17, 17, 26), (17, 22, 30), (22, 22, 32), + (28, 17, 28), (28, 17, 22), (34, 17, 26), (37, 26, 20), + (45, 28, 22), (54, 49, 26), (100, 51, 51), (77, 56, 50), + (77, 58, 58), (50, 78, 90), (49, 54, 60), (71, 50, 56), + (62, 58, 52), (60, 66, 22), (79, 68, 45), (45, 34, 37) + ), + +// 6 facial-treescape 6 +((39, 34, 26), (52, 37, 56), (37, 60, 58), (52, 73, 52), + (73, 85, 51), (110, 87, 59), (164, 147, 127), (133, 105, 88), + (166, 134, 117), (122, 133, 142), (137, 125, 91), (150, 129, 56), + (152, 101, 0), (135, 73, 39), (62, 71, 17), (39, 86, 17), + (34, 62, 22), (37, 77, 43), (39, 62, 34), (39, 79, 28), + (45, 92, 51), (54, 79, 49), (52, 64, 58), (49, 69, 49), + (39, 64, 45), (47, 62, 30), (39, 62, 17), (39, 49, 11), + (45, 45, 17), (39, 49, 22), (34, 54, 28), (32, 55, 35), + (39, 56, 39), (45, 51, 34), (45, 60, 34), (34, 49, 22), + (28, 39, 17), (20, 35, 15), (22, 34, 11), (17, 39, 11), + (22, 28, 11), (17, 34, 11), (17, 39, 17), (11, 28, 11), + (11, 28, 5), (11, 28, 11), (17, 28, 11), (22, 22, 11), + (22, 17, 5), (22, 11, 0), (22, 11, 0), (22, 17, 0), + (22, 17, 0), (35, 20, 9), (60, 22, 17), (82, 39, 16), + (81, 49, 20), (132, 80, 41), (135, 123, 90), (178, 166, 112), + (197, 203, 169), (205, 233, 222), (178, 218, 212), (107, 158, 175), + (50, 96, 132), (49, 86, 103), (37, 55, 55), (34, 45, 39), + (34, 39, 34), (28, 28, 34), (34, 22, 22), (28, 17, 17), + (22, 22, 17), (22, 22, 17), (22, 17, 17), (17, 17, 11), + (15, 20, 9), (17, 22, 5), (22, 26, 0), (22, 28, 0), + (34, 32, 0), (28, 32, 5), (34, 28, 5), (34, 28, 0), + (28, 28, 0), (34, 22, 11), (34, 22, 11), (28, 17, 17), + (28, 22, 11), (28, 22, 11), (22, 22, 11), (22, 28, 11), + (22, 28, 17), (22, 28, 17), (17, 22, 22), (17, 17, 17), + (22, 17, 11), (22, 17, 11), (22, 17, 11), (22, 17, 11), + (22, 11, 11), (17, 11, 11), (17, 11, 11), (17, 11, 11), + (15, 9, 9), (22, 5, 5), (22, 11, 5), (22, 11, 5), + (22, 17, 5), (22, 22, 5), (17, 22, 5), (17, 28, 11), + (17, 28, 11), (17, 26, 11), (11, 22, 11), (11, 22, 11), + (11, 17, 5), (11, 17, 5), (5, 17, 5), (11, 17, 0), + (11, 17, 5), (17, 17, 5), (17, 17, 11), (17, 22, 17), + (22, 28, 22), (28, 28, 37), (22, 39, 64), (51, 83, 73), + (85, 117, 74), (122, 176, 142), (193, 222, 227), (220, 231, 237), + (215, 226, 232), (250, 216, 154), (244, 205, 109), (195, 114, 69), + (149, 114, 58), (93, 103, 53), (62, 71, 34), (51, 54, 22), + (39, 34, 17), (32, 26, 20), (17, 22, 11), (11, 11, 11), + (11, 5, 5), (11, 5, 5), (11, 5, 5), (11, 11, 5), + (11, 11, 0), (11, 11, 5), (17, 11, 5), (17, 11, 5), + (17, 17, 5), (17, 22, 5), (11, 22, 0), (11, 17, 0), + (11, 11, 0), (11, 11, 0), (11, 5, 0), (17, 5, 0), + (20, 5, 0), (17, 5, 0), (17, 5, 0), (17, 0, 0), + (17, 0, 0), (11, 0, 0), (11, 5, 0), (11, 5, 0), + (11, 5, 0), (0, 0, 0), (11, 5, 0), (5, 5, 0), + (5, 5, 0), (5, 11, 0), (5, 11, 5), (11, 11, 5), + (17, 17, 5), (17, 22, 0), (22, 28, 0), (22, 37, 5), + (26, 37, 9), (28, 43, 15), (26, 57, 29), (43, 68, 43), + (28, 64, 43), (28, 69, 34), (32, 80, 35), (41, 77, 47), + (56, 96, 68), (73, 110, 76), (45, 111, 79), (82, 105, 94), + (62, 114, 116), (67, 147, 147), (78, 175, 197), (180, 220, 220), + (216, 222, 222), (250, 210, 131), (180, 123, 95), (121, 87, 59), + (73, 68, 39), (58, 72, 44), (51, 66, 34), (37, 49, 32), + (34, 39, 22), (28, 34, 17), (28, 22, 11), (22, 17, 11), + (17, 11, 5), (17, 11, 5), (17, 11, 0), (11, 11, 0), + (11, 11, 0), (11, 11, 0), (17, 17, 0), (22, 22, 5), + (26, 26, 9), (28, 34, 11), (28, 34, 11), (26, 37, 15), + (28, 39, 17), (28, 34, 22), (28, 32, 22), (32, 32, 20), + (34, 34, 17), (34, 37, 17), (39, 43, 11), (37, 43, 15), + (34, 39, 17), (34, 37, 11), (28, 32, 11), (22, 28, 11), + (28, 28, 11), (26, 26, 9), (34, 34, 11), (45, 28, 11), + (49, 37, 15), (54, 39, 22), (69, 39, 28), (56, 39, 28), + (41, 35, 26), (34, 34, 28), (28, 34, 28), (26, 34, 22), + (28, 37, 22), (34, 39, 22), (34, 45, 22), (34, 39, 22), + (34, 39, 17), (34, 37, 17), (45, 39, 11), (45, 39, 20), + (45, 39, 22), (51, 39, 17), (49, 43, 20), (51, 57, 36) + ), + +// 7 fasion-bug +((24, 19, 26), (45, 31, 41), (67, 45, 51), (122, 31, 44), + (144, 31, 39), (145, 29, 37), (146, 30, 35), (150, 30, 36), + (144, 30, 36), (133, 33, 35), (69, 45, 44), (47, 34, 40), + (35, 29, 36), (31, 25, 30), (27, 23, 27), (26, 21, 26), + (27, 22, 28), (30, 24, 33), (32, 28, 34), (37, 34, 41), + (48, 43, 47), (59, 53, 56), (83, 77, 73), (95, 77, 69), + (123, 90, 77), (130, 109, 88), (124, 116, 98), (148, 142, 112), + (176, 164, 120), (201, 192, 153), (214, 208, 194), (228, 222, 206), + (230, 224, 205), (230, 225, 201), (230, 221, 202), (229, 213, 190), + (219, 190, 158), (176, 152, 111), (141, 109, 83), (152, 73, 69), + (156, 58, 53), (146, 125, 94), (182, 149, 123), (218, 205, 144), + (229, 216, 191), (230, 222, 205), (230, 224, 218), (230, 226, 219), + (228, 226, 220), (230, 227, 221), (232, 228, 217), (236, 232, 204), + (233, 231, 191), (230, 222, 199), (229, 219, 200), (217, 212, 198), + (221, 209, 181), (199, 168, 145), (156, 127, 125), (92, 74, 81), + (69, 50, 51), (55, 40, 50), (41, 34, 40), (29, 29, 34), + (23, 24, 32), (21, 24, 29), (22, 21, 28), (24, 20, 27), + (30, 21, 29), (37, 25, 29), (45, 25, 32), (56, 30, 34), + (108, 29, 38), (142, 30, 39), (149, 34, 37), (150, 32, 36), + (148, 30, 36), (146, 29, 36), (142, 29, 35), (136, 31, 36), + (72, 50, 53), (63, 47, 50), (59, 48, 48), (57, 45, 49), + (63, 48, 51), (78, 55, 58), (92, 80, 76), (126, 112, 95), + (167, 147, 117), (206, 160, 142), (204, 195, 168), (214, 206, 190), + (172, 155, 142), (146, 130, 123), (115, 95, 88), (90, 74, 81), + (61, 54, 56), (55, 40, 52), (49, 40, 43), (46, 41, 45), + (44, 42, 46), (46, 42, 46), (46, 38, 40), (42, 41, 37), + (37, 33, 33), (34, 27, 27), (31, 23, 28), (29, 21, 23), + (25, 18, 23), (24, 13, 21), (22, 14, 21), (20, 15, 21), + (19, 16, 21), (19, 17, 21), (20, 16, 23), (22, 17, 24), + (25, 19, 25), (28, 19, 27), (31, 21, 29), (44, 24, 36), + (52, 33, 41), (66, 40, 44), (122, 29, 33), (142, 28, 35), + (143, 28, 35), (140, 31, 34), (119, 34, 33), (68, 40, 40), + (43, 30, 33), (31, 19, 27), (24, 16, 20), (18, 14, 17), + (16, 12, 16), (13, 12, 16), (12, 11, 17), (13, 11, 16), + (15, 12, 16), (18, 14, 18), (22, 20, 24), (27, 25, 29), + (37, 33, 35), (52, 39, 43), (69, 45, 48), (127, 30, 36), + (142, 29, 36), (148, 30, 36), (152, 29, 38), (156, 29, 39), + (156, 28, 35), (154, 28, 36), (148, 29, 32), (145, 33, 33), + (138, 32, 34), (74, 48, 52), (59, 40, 50), (48, 34, 44), + (44, 34, 40), (38, 33, 36), (31, 31, 36), (33, 28, 34), + (41, 26, 31), (46, 27, 37), (58, 37, 41), (116, 28, 35), + (139, 27, 33), (144, 27, 35), (149, 29, 39), (153, 31, 38), + (156, 31, 39), (157, 33, 39), (154, 36, 40), (151, 34, 42), + (145, 30, 37), (136, 27, 35), (95, 24, 29), (49, 32, 25), + (32, 24, 25), (25, 20, 23), (20, 17, 24), (18, 16, 23), + (17, 15, 21), (18, 16, 22), (16, 15, 24), (20, 16, 27), + (18, 19, 35), (32, 25, 35), (42, 36, 38), (46, 42, 41), + (52, 53, 45), (67, 68, 46), (98, 75, 65), (101, 69, 63), + (146, 34, 48), (150, 33, 43), (157, 33, 41), (160, 30, 39), + (160, 32, 39), (162, 29, 37), (161, 35, 40), (171, 37, 38), + (157, 37, 40), (151, 36, 40), (144, 32, 39), (138, 32, 38), + (79, 44, 48), (61, 41, 46), (55, 36, 39), (47, 32, 42), + (35, 28, 35), (27, 24, 29), (27, 21, 27), (22, 20, 26), + (19, 20, 24), (16, 18, 24), (15, 16, 22), (15, 16, 23), + (15, 19, 22), (16, 16, 22), (17, 15, 22), (14, 16, 21), + (12, 15, 20), (15, 13, 20), (18, 14, 21), (19, 16, 21), + (22, 16, 21), (25, 20, 21), (24, 22, 25), (25, 24, 29), + (29, 25, 31), (32, 27, 32), (31, 27, 33), (31, 25, 29), + (27, 21, 26), (28, 19, 26), (26, 16, 24), (25, 17, 23), + (23, 14, 23), (19, 15, 22), (16, 14, 19), (14, 13, 18), + (13, 11, 18), (15, 12, 18), (16, 14, 17), (15, 15, 19), + (16, 16, 20), (16, 16, 21), (18, 15, 23), (20, 16, 23), + (23, 18, 26), (24, 19, 33), (29, 18, 30), (35, 24, 32), + (43, 28, 34), (55, 32, 37), (69, 42, 43), (131, 27, 32) + ), + +// 8 leafy-face +((42, 37, 33), (31, 23, 25), (23, 19, 22), (20, 20, 24), + (24, 23, 25), (31, 25, 25), (47, 37, 39), (64, 40, 39), + (81, 51, 51), (74, 59, 57), (73, 69, 63), (77, 81, 72), + (95, 98, 94), (200, 168, 134), (215, 188, 153), (223, 209, 177), + (238, 225, 207), (237, 227, 215), (238, 227, 201), (225, 195, 162), + (210, 182, 147), (191, 163, 133), (91, 98, 97), (75, 74, 79), + (70, 70, 67), (73, 69, 59), (83, 76, 55), (84, 74, 55), + (107, 79, 73), (197, 132, 96), (218, 159, 116), (222, 174, 130), + (225, 182, 134), (222, 182, 137), (220, 173, 131), (215, 164, 114), + (163, 109, 88), (103, 83, 68), (90, 83, 61), (145, 104, 88), + (208, 163, 121), (209, 174, 138), (213, 176, 151), (213, 178, 151), + (211, 183, 143), (206, 174, 133), (197, 154, 120), (89, 91, 91), + (72, 77, 78), (66, 71, 69), (64, 66, 63), (62, 56, 59), + (60, 59, 58), (58, 58, 55), (56, 54, 54), (50, 51, 48), + (60, 47, 46), (65, 50, 46), (65, 50, 46), (67, 52, 49), + (66, 59, 57), (65, 67, 59), (68, 73, 68), (78, 84, 80), + (130, 120, 108), (206, 162, 135), (217, 172, 144), (223, 184, 152), + (224, 188, 154), (226, 188, 154), (226, 187, 152), (225, 190, 148), + (226, 195, 144), (224, 195, 146), (220, 190, 147), (223, 190, 153), + (226, 193, 152), (227, 192, 152), (223, 187, 152), (223, 187, 147), + (227, 184, 143), (223, 184, 141), (221, 174, 135), (204, 162, 130), + (130, 108, 102), (82, 82, 75), (74, 77, 63), (70, 76, 63), + (68, 71, 63), (68, 71, 63), (66, 72, 63), (71, 76, 66), + (78, 89, 77), (138, 122, 109), (205, 166, 137), (210, 179, 149), + (213, 182, 152), (222, 189, 155), (226, 199, 156), (237, 210, 172), + (240, 227, 199), (238, 229, 214), (238, 231, 222), (239, 232, 227), + (235, 230, 227), (230, 228, 223), (220, 217, 207), (203, 193, 176), + (206, 166, 149), (194, 148, 118), (87, 98, 78), (72, 89, 71), + (82, 86, 69), (139, 116, 93), (208, 167, 123), (219, 170, 135), + (219, 179, 138), (218, 182, 149), (214, 176, 151), (212, 174, 147), + (198, 160, 136), (98, 97, 97), (78, 76, 82), (68, 71, 71), + (60, 66, 68), (65, 67, 69), (67, 72, 71), (82, 87, 80), + (168, 130, 113), (208, 164, 139), (209, 167, 138), (189, 141, 129), + (99, 86, 90), (80, 75, 64), (82, 71, 63), (83, 77, 68), + (98, 94, 96), (202, 155, 123), (219, 170, 130), (212, 164, 117), + (142, 106, 92), (81, 81, 74), (72, 73, 68), (71, 73, 67), + (73, 79, 69), (83, 99, 85), (164, 149, 121), (207, 166, 140), + (213, 177, 153), (224, 193, 170), (222, 210, 207), (223, 222, 215), + (232, 231, 225), (233, 227, 226), (226, 226, 223), (218, 226, 216), + (222, 222, 214), (222, 213, 199), (225, 191, 157), (213, 184, 148), + (209, 176, 138), (199, 165, 128), (96, 96, 95), (75, 77, 69), + (70, 67, 64), (68, 61, 60), (68, 62, 59), (70, 63, 58), + (74, 72, 63), (82, 88, 77), (175, 142, 113), (217, 171, 125), + (221, 170, 130), (207, 159, 122), (112, 86, 73), (83, 64, 60), + (51, 41, 43), (29, 27, 31), (21, 18, 24), (13, 11, 15), + (19, 16, 17), (22, 17, 23), (30, 24, 29), (46, 37, 41), + (44, 41, 44), (43, 46, 38), (32, 32, 27), (25, 26, 28), + (28, 22, 25), (32, 30, 32), (41, 41, 42), (43, 41, 47), + (47, 50, 49), (55, 55, 53), (58, 63, 60), (61, 68, 58), + (64, 70, 57), (67, 74, 62), (75, 76, 65), (88, 89, 83), + (176, 145, 118), (206, 166, 144), (224, 190, 168), (238, 223, 210), + (233, 230, 225), (233, 229, 224), (227, 218, 210), (220, 188, 162), + (204, 167, 151), (150, 142, 132), (85, 97, 95), (75, 78, 72), + (70, 70, 65), (67, 64, 57), (63, 61, 52), (57, 55, 49), + (62, 56, 46), (60, 59, 46), (61, 59, 52), (64, 61, 58), + (64, 68, 57), (62, 70, 54), (62, 67, 54), (63, 67, 55), + (64, 64, 55), (66, 65, 51), (67, 65, 50), (69, 65, 51), + (69, 65, 54), (76, 66, 55), (84, 65, 54), (121, 72, 64), + (197, 132, 96), (217, 166, 119), (222, 178, 124), (225, 188, 129), + (224, 188, 138), (222, 184, 139), (209, 178, 141), (206, 171, 134), + (162, 144, 108), (78, 90, 81), (67, 76, 72), (72, 72, 72), + (83, 70, 82), (114, 112, 105), (203, 167, 143), (213, 184, 157), + (219, 210, 199), (221, 220, 210), (218, 213, 200), (183, 173, 165), + (107, 106, 103), (77, 83, 78), (74, 83, 75), (82, 95, 83) + ), + +// 9 mouldy-sun +((17, 11, 11), (11, 11, 11), (11, 11, 5), (11, 17, 0), + (11, 17, 0), (17, 22, 0), (22, 28, 0), (34, 28, 11), + (51, 39, 22), (69, 64, 24), (84, 105, 50), (129, 135, 73), + (189, 166, 78), (195, 194, 78), (207, 189, 83), (208, 180, 95), + (214, 203, 90), (214, 197, 90), (207, 179, 105), (191, 173, 92), + (191, 163, 90), (180, 158, 62), (177, 149, 45), (180, 146, 39), + (174, 145, 55), (159, 130, 65), (126, 109, 60), (144, 104, 34), + (148, 104, 45), (153, 115, 48), (146, 93, 31), (154, 96, 17), + (163, 115, 25), (180, 123, 16), (183, 138, 28), (173, 129, 45), + (210, 135, 61), (225, 146, 67), (197, 174, 123), (148, 193, 193), + (191, 191, 180), (204, 192, 170), (213, 196, 139), (203, 208, 135), + (165, 185, 156), (113, 124, 90), (67, 113, 50), (77, 84, 26), + (60, 68, 20), (66, 64, 20), (83, 69, 20), (120, 82, 20), + (159, 104, 11), (172, 126, 39), (186, 134, 45), (208, 146, 39), + (242, 146, 44), (206, 148, 39), (164, 121, 45), (145, 95, 45), + (128, 84, 34), (89, 39, 22), (58, 28, 17), (43, 22, 11), + (28, 17, 11), (22, 11, 11), (22, 11, 11), (22, 11, 11), + (17, 11, 11), (11, 5, 26), (11, 11, 11), (17, 11, 17), + (17, 17, 11), (22, 22, 5), (17, 11, 0), (22, 22, 0), + (17, 22, 0), (17, 11, 0), (28, 17, 0), (37, 11, 0), + (49, 22, 5), (62, 39, 0), (71, 58, 9), (119, 73, 0), + (164, 72, 28), (186, 117, 22), (203, 157, 33), (242, 174, 50), + (248, 208, 89), (244, 239, 154), (254, 248, 169), (237, 220, 135), + (240, 206, 88), (231, 186, 72), (203, 174, 50), (178, 146, 39), + (139, 127, 16), (116, 101, 11), (94, 81, 5), (51, 58, 0), + (22, 32, 0), (17, 26, 0), (11, 17, 0), (5, 17, 0), + (5, 5, 5), (0, 0, 0), (5, 0, 0), (11, 5, 0), + (11, 5, 5), (11, 5, 5), (17, 5, 5), (17, 5, 5), + (22, 5, 5), (22, 5, 5), (17, 5, 5), (17, 5, 5), + (17, 5, 5), (11, 11, 0), (11, 11, 0), (11, 5, 5), + (11, 5, 5), (17, 5, 0), (17, 5, 0), (17, 5, 0), + (17, 5, 0), (22, 5, 5), (17, 0, 0), (17, 0, 0), + (17, 0, 0), (17, 5, 5), (17, 17, 11), (11, 17, 9), + (11, 22, 0), (11, 28, 0), (17, 39, 17), (45, 69, 0), + (62, 86, 25), (84, 98, 11), (107, 99, 17), (119, 93, 17), + (122, 99, 20), (134, 101, 28), (141, 112, 22), (150, 110, 33), + (130, 113, 39), (128, 111, 75), (133, 132, 87), (165, 142, 120), + (197, 163, 135), (220, 202, 146), (225, 225, 180), (229, 229, 190), + (250, 239, 199), (244, 233, 188), (242, 237, 163), (218, 200, 127), + (225, 202, 118), (224, 201, 105), (227, 205, 91), (225, 208, 78), + (237, 220, 44), (237, 197, 50), (248, 191, 67), (225, 174, 89), + (181, 146, 85), (144, 138, 76), (124, 124, 51), (108, 119, 43), + (96, 99, 42), (73, 73, 28), (71, 52, 20), (79, 50, 22), + (79, 39, 22), (93, 50, 56), (154, 90, 84), (158, 107, 67), + (162, 127, 66), (197, 163, 50), (210, 176, 47), (203, 168, 33), + (180, 139, 0), (152, 118, 5), (125, 80, 0), (96, 73, 11), + (69, 45, 11), (54, 28, 22), (39, 34, 22), (34, 34, 22), + (28, 28, 17), (28, 28, 11), (39, 22, 5), (34, 22, 0), + (28, 24, 0), (22, 28, 5), (28, 34, 20), (51, 52, 30), + (66, 54, 24), (94, 60, 46), (126, 86, 47), (132, 118, 82), + (158, 140, 90), (208, 168, 101), (214, 197, 140), (233, 227, 188), + (252, 240, 201), (252, 252, 212), (252, 246, 201), (250, 244, 176), + (254, 242, 152), (254, 220, 95), (248, 208, 84), (231, 174, 44), + (203, 157, 28), (194, 126, 0), (191, 123, 5), (190, 112, 5), + (175, 118, 16), (138, 116, 0), (107, 99, 0), (99, 96, 14), + (91, 89, 20), (54, 64, 9), (39, 28, 17), (28, 17, 17), + (17, 11, 11), (11, 5, 5), (11, 5, 5), (11, 5, 5), + (11, 5, 5), (11, 5, 5), (5, 5, 5), (5, 0, 0), + (5, 0, 0), (11, 0, 0), (11, 5, 0), (11, 5, 5), + (17, 5, 5), (17, 11, 17), (17, 17, 17), (28, 33, 33), + (57, 63, 46), (77, 71, 34), (91, 75, 43), (124, 88, 33), + (155, 112, 11), (186, 135, 22), (203, 146, 39), (231, 157, 39), + (225, 168, 50), (237, 203, 90), (239, 233, 148), (252, 235, 189), + (248, 242, 208), (229, 218, 224), (244, 244, 210), (237, 208, 169) + ), + +// 10 sunny-harvest +((0, 0, 0), (34, 4, 13), (71, 19, 23), (105, 20, 32), + (107, 51, 32), (102, 30, 34), (70, 23, 27), (52, 20, 20), + (18, 6, 8), (4, 0, 1), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (8, 5, 6), (16, 12, 21), (58, 29, 30), (89, 49, 39), + (116, 94, 73), (149, 126, 100), (193, 171, 144), (208, 199, 181), + (213, 202, 184), (204, 203, 195), (227, 209, 188), (228, 210, 184), + (219, 200, 171), (216, 190, 148), (212, 182, 123), (211, 171, 108), + (189, 137, 88), (173, 125, 72), (167, 123, 82), (157, 127, 103), + (184, 159, 137), (204, 180, 162), (205, 185, 156), (206, 182, 146), + (200, 168, 133), (170, 131, 87), (163, 112, 64), (145, 103, 68), + (132, 98, 68), (123, 102, 49), (93, 65, 39), (84, 57, 33), + (86, 64, 30), (118, 81, 44), (137, 96, 57), (148, 118, 62), + (159, 116, 64), (176, 136, 77), (195, 143, 90), (206, 164, 112), + (186, 160, 114), (169, 130, 85), (151, 114, 89), (121, 104, 81), + (112, 93, 68), (102, 77, 53), (86, 52, 33), (76, 49, 28), + (82, 63, 30), (92, 79, 38), (113, 102, 71), (132, 128, 98), + (154, 155, 150), (201, 187, 161), (207, 191, 163), (215, 191, 174), + (204, 181, 165), (185, 169, 137), (143, 133, 100), (99, 88, 80), + (61, 41, 39), (41, 16, 21), (17, 3, 12), (6, 0, 3), + (0, 0, 0), (0, 0, 0), (3, 1, 3), (16, 8, 9), + (54, 24, 30), (65, 63, 43), (85, 87, 72), (124, 122, 90), + (182, 154, 108), (201, 174, 136), (202, 181, 122), (207, 183, 113), + (218, 169, 91), (208, 146, 67), (213, 132, 64), (227, 133, 48), + (226, 130, 48), (223, 124, 47), (213, 122, 45), (211, 112, 41), + (215, 101, 43), (214, 103, 44), (205, 112, 45), (194, 106, 42), + (175, 100, 37), (169, 89, 35), (164, 74, 39), (166, 83, 42), + (163, 74, 36), (176, 92, 35), (187, 102, 42), (202, 116, 54), + (218, 131, 45), (229, 156, 54), (229, 164, 62), (229, 179, 77), + (224, 183, 95), (222, 193, 115), (224, 189, 123), (218, 195, 149), + (223, 200, 158), (215, 190, 172), (202, 179, 157), (154, 144, 119), + (143, 122, 97), (122, 94, 70), (119, 85, 51), (101, 45, 32), + (97, 47, 31), (83, 35, 29), (71, 29, 33), (56, 21, 24), + (16, 8, 21), (2, 0, 3), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (16, 10, 8), (23, 16, 11), + (62, 40, 29), (92, 66, 41), (138, 99, 61), (193, 146, 50), + (215, 170, 60), (222, 164, 57), (229, 168, 54), (233, 168, 56), + (236, 175, 55), (238, 180, 55), (236, 177, 57), (235, 179, 60), + (236, 183, 59), (231, 190, 63), (234, 184, 61), (236, 173, 60), + (233, 169, 59), (235, 170, 58), (235, 166, 58), (233, 160, 58), + (233, 151, 58), (233, 150, 59), (226, 137, 53), (231, 125, 50), + (219, 101, 46), (202, 98, 45), (207, 84, 39), (193, 77, 37), + (190, 74, 37), (178, 62, 39), (179, 52, 35), (183, 57, 36), + (191, 62, 40), (190, 80, 45), (187, 97, 43), (170, 114, 57), + (174, 124, 71), (181, 151, 81), (205, 170, 95), (218, 189, 119), + (215, 190, 114), (227, 191, 103), (225, 190, 96), (235, 192, 73), + (235, 186, 67), (233, 174, 68), (233, 152, 56), (216, 126, 43), + (198, 94, 40), (183, 72, 41), (151, 71, 39), (128, 43, 33), + (89, 14, 25), (25, 15, 6), (6, 0, 2), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (3, 0, 1), (18, 4, 7), (33, 13, 19), (60, 28, 33), + (74, 44, 36), (87, 53, 35), (93, 62, 37), (122, 84, 46), + (121, 88, 45), (141, 90, 51), (140, 67, 41), (122, 81, 49), + (139, 60, 40), (135, 61, 34), (150, 57, 34), (145, 38, 38), + (149, 64, 37), (123, 56, 32), (154, 40, 39), (158, 46, 36), + (175, 45, 38), (179, 56, 41), (164, 72, 39), (160, 85, 40), + (150, 81, 47), (166, 93, 48), (157, 99, 55), (135, 106, 66), + (116, 109, 74), (136, 114, 90), (141, 108, 86), (159, 115, 69), + (180, 133, 80), (211, 175, 110), (214, 190, 145), (224, 203, 178), + (232, 226, 194), (235, 218, 187), (225, 213, 184), (212, 196, 164), + (193, 177, 137), (180, 135, 90), (175, 113, 57), (198, 110, 44), + (208, 113, 41), (222, 136, 45), (233, 152, 53), (235, 157, 54), + (231, 160, 55), (231, 160, 54), (228, 151, 52), (216, 130, 45), + (197, 106, 43), (173, 84, 39), (150, 67, 37), (133, 55, 31) + ), + +// 11 peach-tree +((170, 59, 28), (170, 63, 28), (129, 68, 37), (68, 84, 37), + (77, 109, 37), (81, 121, 47), (81, 113, 47), (93, 113, 56), + (101, 133, 75), (117, 141, 85), (137, 161, 94), (141, 162, 84), + (194, 173, 65), (218, 139, 47), (222, 119, 37), (214, 103, 47), + (214, 106, 37), (194, 95, 28), (145, 76, 37), (76, 105, 37), + (52, 80, 18), (32, 68, 9), (32, 60, 18), (32, 48, 18), + (32, 56, 18), (44, 72, 18), (64, 105, 37), (97, 137, 56), + (141, 178, 94), (170, 198, 122), (238, 209, 122), (250, 225, 84), + (230, 151, 46), (230, 122, 37), (230, 122, 37), (219, 105, 37), + (202, 94, 37), (182, 76, 28), (133, 55, 18), (84, 43, 9), + (36, 27, 9), (28, 32, 0), (28, 48, 9), (32, 64, 9), + (64, 92, 28), (84, 121, 56), (105, 145, 75), (145, 174, 103), + (150, 178, 113), (149, 174, 113), (141, 170, 113), (113, 141, 85), + (81, 109, 66), (64, 68, 47), (36, 52, 28), (16, 24, 18), + (12, 12, 9), (4, 8, 0), (0, 4, 0), (0, 4, 0), + (0, 4, 0), (0, 0, 0), (4, 0, 0), (12, 0, 0), + (16, 11, 0), (36, 15, 0), (68, 23, 18), (129, 38, 18), + (170, 55, 18), (194, 95, 28), (178, 124, 47), (154, 174, 103), + (166, 194, 122), (170, 202, 122), (178, 210, 141), (190, 218, 160), + (190, 210, 151), (202, 214, 151), (226, 222, 132), (182, 218, 141), + (182, 210, 141), (186, 206, 141), (190, 206, 151), (198, 206, 169), + (210, 218, 179), (234, 230, 197), (234, 234, 197), (250, 241, 188), + (246, 229, 188), (234, 192, 141), (210, 172, 150), (190, 202, 150), + (178, 198, 151), (182, 206, 141), (182, 202, 141), (182, 198, 132), + (170, 202, 132), (166, 198, 132), (158, 186, 122), (141, 178, 113), + (113, 149, 75), (81, 117, 56), (60, 84, 37), (48, 64, 28), + (24, 56, 9), (20, 40, 9), (20, 24, 9), (12, 16, 9), + (7, 12, 9), (4, 8, 9), (8, 4, 9), (20, 7, 9), + (28, 15, 9), (36, 23, 9), (80, 39, 18), (129, 47, 18), + (178, 59, 18), (198, 87, 37), (219, 102, 37), (222, 102, 37), + (222, 117, 28), (226, 135, 28), (230, 142, 28), (242, 146, 37), + (250, 155, 28), (246, 187, 28), (234, 127, 47), (250, 188, 103), + (250, 225, 112), (250, 225, 84), (254, 211, 46), (254, 207, 46), + (254, 208, 74), (218, 181, 94), (149, 120, 103), (89, 121, 66), + (64, 93, 47), (32, 60, 18), (20, 44, 9), (4, 24, 0), + (0, 12, 0), (4, 8, 0), (0, 4, 0), (0, 4, 0), + (0, 4, 0), (4, 0, 0), (4, 0, 0), (4, 4, 0), + (4, 4, 0), (4, 8, 0), (4, 8, 0), (4, 8, 0), + (0, 4, 0), (0, 0, 0), (0, 0, 9), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (4, 0, 0), (4, 4, 0), (12, 8, 0), + (16, 16, 0), (32, 16, 0), (56, 27, 9), (89, 51, 9), + (125, 67, 9), (166, 63, 18), (178, 72, 18), (198, 90, 28), + (190, 107, 37), (157, 112, 56), (153, 99, 47), (89, 121, 56), + (85, 101, 56), (113, 72, 28), (182, 80, 37), (206, 98, 37), + (210, 102, 37), (214, 110, 28), (214, 110, 28), (218, 118, 37), + (222, 110, 28), (226, 114, 37), (222, 110, 47), (238, 111, 65), + (198, 160, 84), (169, 148, 112), (161, 186, 122), (170, 194, 132), + (190, 206, 151), (206, 214, 160), (226, 238, 188), (246, 238, 197), + (254, 250, 254), (250, 254, 206), (242, 254, 206), (230, 238, 197), + (198, 214, 160), (170, 194, 132), (145, 149, 113), (84, 109, 66), + (56, 64, 37), (28, 44, 18), (24, 36, 9), (20, 20, 9), + (32, 19, 9), (48, 15, 9), (101, 39, 18), (137, 47, 18), + (166, 51, 19), (145, 55, 18), (101, 47, 18), (68, 39, 18), + (32, 56, 9), (28, 44, 9), (20, 28, 9), (16, 20, 9), + (8, 16, 0), (8, 16, 0), (4, 12, 0), (4, 16, 0), + (8, 20, 9), (16, 32, 9), (20, 48, 18), (40, 72, 18), + (68, 109, 37), (97, 129, 56), (137, 170, 103), (149, 182, 113), + (145, 182, 113), (129, 161, 94), (105, 133, 75), (68, 89, 56), + (60, 76, 37), (48, 64, 37), (60, 68, 28), (113, 55, 18), + (166, 51, 19), (190, 76, 28), (202, 91, 28), (210, 94, 28), + (210, 98, 28), (198, 87, 18), (158, 55, 9), (105, 34, 0), + (44, 15, 0), (20, 4, 0), (12, 0, 0), (8, 4, 0), + (4, 8, 0), (8, 16, 0), (16, 32, 9), (28, 52, 9) + ), + +// 12 fire-dragon +((88, 3, 9), (64, 0, 9), (44, 3, 9), (24, 4, 9), + (15, 0, 9), (16, 4, 9), (28, 8, 9), (40, 4, 9), + (48, 3, 0), (52, 0, 0), (52, 0, 0), (48, 0, 0), + (40, 0, 0), (28, 4, 0), (16, 0, 0), (8, 0, 9), + (8, 0, 9), (15, 0, 9), (28, 0, 0), (40, 0, 0), + (44, 0, 0), (48, 0, 0), (56, 4, 0), (56, 3, 0), + (52, 0, 0), (48, 0, 0), (40, 0, 0), (28, 0, 0), + (16, 0, 0), (4, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 4, 0), + (0, 4, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (4, 0, 0), (8, 4, 0), (12, 4, 0), (24, 4, 0), + (32, 4, 0), (40, 4, 9), (48, 4, 9), (52, 3, 9), + (68, 3, 9), (81, 4, 0), (101, 3, 0), (117, 0, 0), + (137, 0, 9), (158, 0, 9), (182, 0, 9), (202, 7, 0), + (210, 10, 0), (202, 7, 0), (190, 0, 9), (174, 0, 9), + (145, 3, 9), (113, 3, 0), (89, 3, 0), (68, 3, 9), + (48, 7, 9), (36, 4, 9), (20, 0, 0), (8, 0, 0), + (4, 0, 0), (4, 0, 0), (4, 0, 0), (8, 4, 0), + (24, 4, 0), (40, 4, 0), (60, 3, 0), (84, 3, 0), + (109, 3, 0), (125, 3, 0), (145, 0, 0), (158, 0, 0), + (162, 0, 0), (162, 0, 0), (162, 0, 0), (162, 0, 0), + (162, 3, 0), (153, 7, 9), (157, 11, 0), (153, 0, 0), + (145, 3, 0), (129, 0, 0), (109, 0, 0), (89, 0, 0), + (73, 3, 0), (52, 3, 0), (36, 4, 0), (16, 0, 0), + (8, 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, 9), (4, 0, 9), + (0, 0, 9), (0, 0, 9), (0, 0, 9), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 4, 0), (0, 4, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (4, 0, 0), + (16, 0, 0), (40, 4, 0), (60, 0, 0), (73, 0, 0), + (97, 0, 0), (113, 0, 0), (133, 0, 0), (157, 0, 0), + (166, 7, 0), (182, 7, 0), (174, 10, 0), (174, 15, 9), + (166, 29, 0), (157, 35, 9), (121, 30, 9), (93, 15, 9), + (93, 11, 9), (92, 11, 0), (89, 3, 9), (88, 3, 9), + (80, 3, 9), (76, 0, 0), (68, 0, 0), (64, 3, 0), + (68, 3, 0), (76, 0, 0), (89, 3, 0), (105, 0, 0), + (121, 0, 0), (145, 0, 0), (158, 0, 0), (162, 3, 0), + (153, 18, 9), (169, 7, 0), (166, 0, 0), (174, 3, 0), + (174, 0, 0), (178, 0, 0), (178, 3, 0), (182, 3, 0), + (190, 11, 9), (206, 14, 9), (234, 58, 9), (246, 131, 28), + (242, 179, 28), (250, 187, 37), (250, 233, 84), (246, 254, 102), + (250, 254, 140), (254, 249, 140), (250, 241, 102), (242, 195, 46), + (246, 159, 46), (186, 91, 37), (137, 43, 18), (101, 55, 18), + (76, 39, 18), (56, 11, 9), (44, 11, 9), (28, 4, 0), + (16, 0, 0), (4, 0, 0), (4, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (4, 0, 0), + (8, 4, 0), (16, 8, 0), (24, 4, 0), (36, 7, 0), + (40, 4, 0), (32, 0, 0), (28, 0, 0), (20, 0, 0), + (12, 0, 0), (8, 0, 0), (4, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (4, 0, 0), + (8, 0, 0), (24, 0, 0), (44, 3, 0), (60, 0, 0), + (77, 0, 0), (101, 0, 0), (133, 3, 0), (162, 30, 0), + (182, 47, 0), (194, 79, 18), (197, 107, 18), (206, 95, 18), + (198, 86, 18), (198, 47, 0), (190, 39, 9), (194, 18, 9), + (182, 7, 0), (182, 10, 0), (186, 22, 9), (190, 22, 9), + (206, 66, 9), (230, 98, 9), (246, 134, 9), (246, 155, 28), + (238, 138, 9), (238, 142, 37), (226, 126, 18), (190, 87, 9), + (141, 48, 0), (125, 43, 9), (101, 15, 9), (101, 0, 9), + (97, 3, 0), (92, 7, 0), (89, 15, 9), (77, 24, 9), + (85, 7, 0), (64, 7, 0), (60, 3, 0), (52, 7, 0), + (48, 4, 0), (44, 4, 0), (44, 3, 0), (48, 0, 0), + (44, 0, 0), (40, 7, 0), (36, 4, 0), (28, 0, 0) + ), + +// 13 ice-dragon +((96, 43, 37), (113, 80, 75), (157, 120, 103), (174, 141, 122), + (178, 161, 151), (194, 173, 160), (186, 169, 170), (165, 141, 150), + (153, 129, 141), (141, 133, 131), (137, 129, 131), (137, 133, 141), + (141, 137, 141), (157, 157, 160), (161, 173, 188), (165, 189, 216), + (181, 205, 235), (193, 222, 235), (189, 226, 244), (193, 230, 244), + (197, 230, 254), (197, 226, 254), (189, 226, 244), (185, 222, 244), + (173, 209, 244), (157, 193, 235), (133, 177, 226), (120, 169, 235), + (124, 173, 225), (133, 185, 225), (144, 198, 235), (149, 193, 244), + (157, 201, 244), (161, 197, 235), (169, 193, 226), (161, 185, 197), + (177, 177, 179), (185, 177, 188), (193, 193, 207), (226, 222, 216), + (246, 246, 235), (254, 254, 254), (254, 254, 254), (254, 254, 254), + (250, 254, 254), (237, 245, 254), (209, 230, 244), (193, 201, 216), + (181, 173, 188), (173, 161, 179), (161, 157, 160), (145, 137, 141), + (149, 120, 122), (133, 96, 94), (121, 60, 56), (97, 56, 46), + (80, 39, 37), (60, 15, 18), (44, 19, 9), (48, 19, 18), + (56, 23, 18), (60, 31, 37), (64, 39, 56), (76, 52, 65), + (92, 72, 103), (97, 101, 122), (117, 113, 132), (125, 117, 132), + (133, 117, 122), (137, 117, 113), (125, 109, 94), (117, 92, 84), + (117, 88, 84), (133, 97, 94), (141, 100, 94), (133, 104, 113), + (129, 121, 132), (128, 145, 178), (116, 162, 216), (121, 149, 197), + (116, 112, 151), (108, 92, 122), (76, 48, 85), (56, 40, 66), + (60, 31, 37), (52, 27, 28), (44, 27, 28), (48, 19, 28), + (48, 27, 28), (56, 31, 47), (68, 56, 75), (96, 92, 113), + (113, 117, 151), (108, 153, 197), (108, 158, 225), (100, 154, 235), + (100, 158, 235), (108, 158, 235), (141, 189, 244), (157, 201, 244), + (169, 210, 244), (173, 209, 244), (165, 205, 244), (148, 197, 254), + (140, 193, 254), (116, 185, 254), (104, 173, 244), (100, 162, 244), + (96, 154, 244), (100, 158, 244), (104, 158, 244), (104, 165, 244), + (108, 181, 244), (141, 197, 244), (169, 210, 244), (185, 226, 244), + (205, 238, 254), (218, 246, 254), (230, 250, 254), (234, 254, 254), + (234, 254, 244), (213, 250, 244), (189, 242, 244), (177, 226, 254), + (173, 226, 244), (160, 226, 254), (173, 234, 254), (189, 238, 254), + (221, 246, 254), (250, 254, 254), (254, 254, 254), (254, 254, 254), + (250, 254, 254), (234, 250, 254), (222, 242, 254), (201, 226, 244), + (181, 210, 235), (161, 202, 235), (149, 189, 235), (120, 173, 235), + (108, 177, 235), (108, 177, 244), (112, 181, 244), (140, 197, 244), + (157, 205, 244), (177, 218, 244), (193, 234, 235), (214, 246, 244), + (222, 246, 254), (226, 250, 254), (222, 246, 244), (209, 226, 235), + (193, 197, 216), (173, 177, 207), (161, 161, 179), (145, 133, 150), + (125, 100, 122), (100, 72, 84), (88, 52, 66), (80, 48, 56), + (88, 43, 47), (68, 39, 47), (72, 39, 56), (80, 43, 56), + (80, 52, 65), (88, 64, 75), (113, 97, 103), (125, 129, 151), + (116, 154, 207), (104, 158, 235), (100, 158, 235), (100, 158, 244), + (100, 166, 254), (104, 173, 254), (100, 173, 244), (104, 189, 254), + (132, 202, 254), (161, 201, 244), (185, 202, 244), (201, 226, 254), + (221, 230, 254), (233, 250, 254), (250, 254, 254), (254, 254, 254), + (250, 250, 254), (230, 238, 235), (206, 202, 207), (178, 169, 169), + (149, 129, 132), (117, 88, 103), (93, 60, 65), (105, 56, 56), + (113, 56, 56), (133, 88, 75), (141, 108, 94), (149, 137, 132), + (170, 165, 169), (182, 190, 198), (214, 214, 226), (217, 230, 244), + (217, 234, 244), (209, 234, 254), (197, 226, 235), (173, 194, 226), + (149, 173, 198), (157, 165, 179), (149, 149, 160), (149, 121, 122), + (129, 100, 103), (113, 76, 84), (96, 56, 65), (92, 52, 56), + (88, 52, 56), (84, 68, 56), (97, 85, 94), (112, 109, 132), + (128, 129, 150), (133, 137, 179), (137, 157, 188), (161, 157, 169), + (161, 141, 150), (166, 136, 132), (153, 132, 122), (157, 120, 113), + (169, 141, 131), (198, 173, 160), (202, 177, 170), (218, 210, 207), + (246, 238, 244), (250, 254, 254), (254, 254, 254), (254, 254, 254), + (250, 254, 254), (238, 250, 244), (222, 242, 244), (218, 214, 226), + (190, 190, 198), (181, 177, 178), (185, 173, 169), (194, 173, 169), + (181, 173, 179), (161, 165, 179), (157, 169, 179), (141, 173, 207), + (133, 173, 216), (136, 169, 226), (137, 149, 188), (125, 121, 132), + (96, 92, 103), (84, 64, 75), (80, 60, 66), (88, 60, 66), + (104, 76, 85), (129, 125, 122), (161, 161, 169), (201, 193, 197) + ), + +// 14 german-landscape +((61, 62, 43), (52, 48, 45), (42, 44, 39), (37, 39, 34), + (33, 39, 23), (36, 44, 22), (46, 54, 32), (51, 55, 33), + (45, 49, 38), (45, 49, 38), (45, 45, 45), (45, 45, 45), + (35, 35, 35), (35, 39, 28), (36, 44, 22), (36, 44, 22), + (31, 39, 17), (31, 39, 17), (31, 39, 17), (31, 39, 17), + (31, 39, 17), (31, 39, 17), (28, 34, 18), (23, 29, 13), + (25, 29, 18), (30, 34, 23), (30, 34, 23), (33, 39, 23), + (36, 44, 22), (39, 48, 22), (45, 43, 38), (55, 55, 44), + (60, 54, 45), (63, 61, 54), (69, 68, 58), (70, 66, 54), + (66, 64, 48), (70, 69, 45), (79, 75, 50), (77, 85, 55), + (94, 101, 63), (100, 123, 70), (115, 123, 80), (131, 132, 106), + (134, 139, 102), (131, 130, 80), (120, 105, 63), (110, 98, 70), + (96, 76, 62), (77, 68, 57), (65, 79, 60), (72, 79, 65), + (90, 95, 69), (102, 99, 77), (118, 130, 107), (137, 163, 141), + (159, 182, 173), (167, 178, 180), (177, 170, 179), (178, 172, 183), + (183, 179, 196), (165, 177, 194), (151, 168, 185), (127, 154, 156), + (131, 133, 141), (132, 125, 149), (133, 139, 140), (151, 129, 154), + (163, 157, 170), (169, 168, 176), (164, 174, 180), (168, 179, 193), + (168, 187, 195), (161, 179, 194), (161, 195, 194), (174, 198, 204), + (193, 227, 202), (210, 230, 224), (214, 223, 214), (240, 234, 209), + (219, 215, 201), (201, 197, 192), (204, 180, 172), (197, 156, 171), + (184, 157, 167), (169, 156, 169), (177, 129, 137), (148, 105, 71), + (111, 83, 64), (101, 79, 57), (93, 80, 50), (81, 73, 45), + (79, 79, 47), (85, 89, 56), (100, 94, 74), (119, 120, 84), + (154, 109, 96), (132, 132, 120), (133, 188, 112), (124, 180, 99), + (130, 156, 103), (111, 139, 75), (102, 109, 62), (94, 94, 54), + (91, 79, 57), (86, 72, 56), (86, 70, 53), (78, 68, 49), + (68, 57, 46), (58, 58, 44), (53, 59, 43), (50, 54, 43), + (46, 50, 28), (41, 49, 27), (39, 48, 22), (39, 48, 22), + (39, 48, 22), (39, 48, 22), (44, 53, 27), (47, 57, 33), + (54, 63, 37), (70, 71, 45), (75, 79, 40), (84, 78, 41), + (96, 93, 46), (110, 106, 55), (122, 115, 50), (142, 158, 73), + (137, 185, 77), (132, 178, 79), (135, 150, 71), (114, 109, 53), + (97, 92, 58), (86, 97, 78), (97, 96, 62), (113, 121, 90), + (110, 129, 129), (138, 144, 170), (164, 173, 181), (183, 184, 200), + (194, 193, 202), (214, 210, 211), (208, 220, 216), (210, 220, 212), + (205, 202, 204), (186, 186, 193), (186, 173, 176), (176, 155, 152), + (185, 123, 88), (172, 130, 65), (161, 126, 53), (120, 106, 56), + (98, 83, 60), (76, 70, 51), (58, 58, 47), (58, 58, 44), + (64, 67, 43), (70, 78, 42), (80, 97, 50), (99, 111, 58), + (104, 140, 59), (113, 144, 62), (145, 139, 67), (164, 133, 60), + (172, 133, 65), (184, 149, 59), (158, 135, 56), (134, 109, 56), + (114, 100, 58), (106, 103, 65), (109, 108, 64), (114, 120, 75), + (123, 134, 118), (136, 147, 152), (145, 168, 187), (156, 179, 183), + (153, 174, 190), (153, 172, 190), (143, 161, 178), (130, 139, 150), + (114, 116, 120), (93, 89, 82), (87, 81, 62), (79, 79, 47), + (75, 85, 47), (76, 87, 46), (77, 85, 45), (84, 88, 45), + (87, 97, 46), (97, 97, 47), (116, 108, 56), (159, 130, 57), + (170, 120, 72), (137, 103, 67), (108, 85, 65), (99, 75, 56), + (87, 78, 54), (78, 68, 46), (69, 68, 44), (70, 64, 45), + (73, 67, 48), (77, 75, 55), (84, 88, 65), (97, 102, 83), + (108, 119, 128), (131, 146, 146), (151, 162, 177), (168, 172, 190), + (180, 182, 200), (168, 187, 195), (182, 190, 196), (194, 197, 197), + (212, 210, 202), (221, 217, 208), (220, 217, 217), (218, 217, 216), + (210, 205, 204), (200, 182, 162), (223, 194, 83), (220, 174, 75), + (225, 173, 78), (214, 151, 77), (170, 115, 76), (125, 88, 80), + (101, 83, 60), (88, 83, 55), (86, 91, 47), (83, 91, 50), + (82, 92, 57), (98, 99, 70), (114, 116, 69), (117, 137, 99), + (129, 148, 127), (143, 157, 168), (161, 171, 179), (160, 168, 189), + (153, 157, 182), (155, 139, 161), (179, 116, 112), (158, 104, 89), + (164, 97, 83), (161, 97, 68), (173, 102, 80), (182, 119, 100), + (181, 144, 157), (170, 170, 169), (156, 158, 172), (130, 141, 156), + (115, 140, 140), (124, 139, 130), (131, 155, 114), (130, 160, 116), + (126, 149, 104), (134, 148, 136), (147, 157, 172), (163, 178, 187) + ), + +// 15 no-name +((218, 222, 188), (238, 230, 197), (238, 242, 206), (238, 242, 207), + (230, 238, 225), (234, 238, 216), (242, 241, 235), (242, 245, 216), + (230, 242, 206), (222, 234, 197), (214, 218, 198), (206, 210, 188), + (194, 202, 169), (190, 202, 160), (206, 214, 170), (222, 226, 197), + (234, 237, 206), (234, 242, 197), (222, 226, 197), (194, 202, 170), + (174, 190, 170), (165, 178, 150), (162, 169, 141), (150, 162, 132), + (141, 141, 122), (133, 137, 113), (133, 141, 113), (133, 133, 103), + (121, 125, 103), (121, 125, 103), (113, 121, 94), (101, 109, 85), + (77, 93, 66), (52, 64, 37), (48, 64, 37), (48, 56, 28), + (44, 60, 28), (44, 52, 28), (36, 44, 18), (36, 36, 0), + (36, 44, 9), (40, 52, 9), (56, 64, 18), (48, 64, 28), + (64, 80, 47), (85, 105, 66), (101, 117, 85), (108, 125, 94), + (116, 141, 113), (116, 137, 132), (116, 141, 132), (120, 141, 132), + (121, 137, 122), (121, 133, 113), (117, 125, 103), (113, 121, 94), + (108, 113, 94), (109, 112, 94), (108, 121, 94), (104, 117, 94), + (105, 113, 85), (109, 117, 85), (109, 117, 85), (105, 113, 85), + (101, 113, 85), (105, 109, 85), (100, 113, 94), (104, 112, 103), + (104, 112, 103), (104, 108, 103), (108, 108, 94), (113, 113, 94), + (121, 121, 103), (129, 133, 113), (125, 145, 113), (133, 146, 122), + (133, 146, 122), (125, 146, 132), (121, 146, 132), (120, 146, 141), + (120, 141, 141), (116, 141, 132), (116, 146, 132), (117, 146, 122), + (108, 133, 103), (100, 121, 94), (89, 105, 75), (170, 87, 0), + (56, 68, 28), (48, 60, 28), (44, 60, 28), (52, 64, 37), + (80, 97, 75), (93, 109, 94), (100, 113, 94), (96, 113, 94), + (96, 117, 94), (104, 117, 94), (108, 121, 94), (108, 121, 94), + (113, 121, 103), (112, 121, 103), (108, 125, 103), (104, 121, 103), + (108, 121, 103), (108, 117, 103), (113, 117, 94), (113, 117, 94), + (117, 121, 94), (117, 125, 94), (129, 141, 94), (141, 146, 94), + (141, 146, 103), (154, 154, 113), (154, 162, 122), (154, 162, 122), + (154, 161, 122), (146, 154, 113), (137, 146, 103), (129, 133, 94), + (125, 125, 85), (105, 121, 75), (97, 109, 66), (68, 76, 37), + (56, 68, 28), (64, 81, 37), (69, 77, 37), (113, 109, 66), + (121, 125, 75), (129, 125, 85), (121, 121, 85), (109, 117, 85), + (105, 125, 85), (108, 121, 94), (101, 121, 84), (104, 121, 94), + (100, 121, 103), (100, 121, 103), (104, 117, 94), (100, 113, 94), + (100, 108, 94), (101, 109, 85), (77, 88, 66), (52, 64, 37), + (44, 56, 28), (32, 40, 28), (28, 20, 9), (24, 24, 0), + (4, 20, 0), (8, 16, 0), (12, 24, 0), (28, 40, 9), + (36, 48, 18), (60, 68, 37), (93, 101, 85), (117, 121, 85), + (133, 137, 94), (137, 145, 113), (150, 162, 113), (154, 162, 122), + (158, 170, 122), (158, 170, 122), (170, 174, 113), (166, 170, 122), + (162, 170, 122), (161, 165, 122), (150, 158, 122), (133, 150, 122), + (129, 146, 122), (120, 146, 122), (117, 146, 122), (117, 141, 122), + (112, 129, 103), (125, 125, 103), (137, 137, 103), (146, 154, 113), + (158, 170, 122), (170, 182, 132), (178, 182, 141), (182, 186, 151), + (194, 202, 151), (178, 190, 141), (178, 182, 141), (170, 178, 141), + (162, 174, 132), (154, 166, 122), (146, 158, 122), (133, 154, 122), + (125, 150, 122), (125, 146, 122), (125, 146, 132), (125, 146, 132), + (129, 150, 132), (133, 150, 132), (133, 150, 132), (129, 146, 132), + (133, 154, 132), (133, 154, 132), (141, 154, 132), (146, 150, 132), + (158, 169, 132), (174, 178, 132), (170, 186, 132), (178, 190, 141), + (182, 194, 160), (198, 202, 160), (198, 206, 170), (214, 218, 179), + (218, 226, 197), (210, 214, 188), (190, 194, 160), (170, 182, 141), + (158, 166, 122), (146, 154, 113), (137, 137, 113), (129, 125, 103), + (125, 125, 103), (129, 120, 103), (125, 125, 94), (121, 121, 94), + (121, 129, 94), (129, 125, 103), (129, 125, 103), (129, 129, 103), + (129, 137, 113), (133, 145, 122), (137, 146, 122), (150, 157, 122), + (150, 158, 122), (146, 150, 132), (150, 154, 141), (146, 146, 132), + (137, 145, 132), (129, 146, 132), (125, 146, 141), (120, 146, 141), + (116, 146, 141), (120, 146, 141), (120, 150, 151), (129, 150, 141), + (129, 150, 141), (129, 154, 141), (133, 154, 141), (137, 158, 141), + (137, 158, 141), (141, 162, 151), (149, 162, 151), (141, 162, 151), + (150, 166, 141), (154, 161, 141), (158, 169, 132), (158, 166, 122), + (162, 165, 113), (158, 166, 113), (154, 166, 113), (149, 157, 113) + ), + +// 16 living-mud-bomb +((193, 144, 35), (153, 117, 33), (133, 107, 35), (102, 76, 20), + (96, 67, 20), (79, 51, 16), (70, 47, 16), (66, 52, 16), + (64, 48, 16), (64, 47, 16), (61, 44, 16), (58, 41, 16), + (58, 42, 16), (64, 46, 16), (72, 48, 16), (85, 52, 18), + (86, 60, 18), (88, 64, 22), (85, 76, 24), (75, 76, 24), + (89, 56, 15), (84, 47, 16), (84, 46, 16), (84, 43, 16), + (84, 41, 16), (84, 40, 16), (84, 40, 16), (84, 39, 16), + (84, 39, 16), (84, 39, 16), (81, 39, 16), (79, 39, 16), + (75, 39, 16), (66, 39, 16), (64, 40, 16), (55, 40, 16), + (51, 40, 16), (48, 40, 16), (48, 40, 16), (49, 42, 16), + (53, 43, 16), (55, 41, 16), (55, 41, 16), (53, 41, 16), + (49, 40, 16), (48, 40, 16), (48, 40, 16), (48, 40, 16), + (48, 40, 16), (48, 40, 16), (48, 40, 16), (48, 38, 16), + (48, 38, 16), (48, 38, 16), (48, 38, 16), (48, 38, 16), + (45, 35, 16), (48, 38, 16), (48, 38, 16), (49, 40, 16), + (53, 40, 16), (58, 40, 16), (64, 40, 16), (75, 39, 16), + (81, 39, 16), (83, 39, 16), (84, 39, 16), (81, 39, 16), + (79, 39, 16), (75, 40, 16), (68, 47, 16), (64, 48, 16), + (64, 48, 16), (64, 48, 16), (58, 46, 16), (56, 44, 16), + (56, 44, 16), (53, 43, 16), (49, 40, 16), (48, 40, 16), + (48, 40, 16), (48, 40, 16), (48, 40, 16), (49, 40, 16), + (55, 41, 16), (63, 43, 16), (68, 47, 16), (79, 49, 16), + (93, 56, 15), (96, 68, 20), (120, 84, 20), (151, 110, 35), + (186, 141, 35), (236, 162, 35), (246, 167, 44), (238, 165, 35), + (226, 153, 33), (185, 106, 22), (128, 82, 15), (96, 70, 20), + (84, 60, 22), (72, 48, 16), (62, 47, 16), (55, 42, 16), + (49, 40, 16), (48, 40, 16), (48, 40, 16), (48, 40, 16), + (48, 40, 16), (48, 40, 16), (48, 40, 16), (48, 40, 16), + (48, 40, 16), (48, 40, 16), (48, 40, 16), (48, 40, 16), + (48, 40, 16), (48, 40, 16), (49, 40, 16), (55, 40, 16), + (58, 40, 16), (64, 42, 16), (68, 46, 16), (70, 47, 16), + (77, 43, 16), (81, 40, 16), (84, 39, 16), (85, 39, 16), + (91, 39, 15), (96, 39, 16), (96, 39, 16), (94, 39, 16), + (91, 39, 16), (85, 39, 16), (85, 39, 16), (84, 39, 16), + (84, 39, 16), (84, 39, 16), (84, 39, 16), (84, 39, 16), + (84, 39, 16), (84, 39, 16), (84, 39, 16), (84, 39, 16), + (84, 39, 16), (84, 39, 16), (85, 39, 16), (87, 42, 16), + (91, 43, 16), (96, 43, 16), (100, 40, 16), (106, 52, 22), + (124, 75, 17), (164, 105, 21), (217, 135, 30), (239, 162, 49), + (248, 175, 48), (237, 159, 49), (202, 125, 32), (163, 84, 15), + (130, 76, 20), (106, 71, 22), (98, 53, 15), (91, 43, 16), + (84, 41, 16), (77, 39, 16), (68, 39, 16), (64, 42, 16), + (64, 44, 16), (68, 47, 16), (75, 46, 16), (84, 42, 16), + (91, 40, 16), (98, 39, 16), (100, 40, 16), (101, 50, 15), + (117, 55, 15), (120, 53, 15), (120, 51, 15), (120, 54, 15), + (106, 52, 15), (102, 43, 15), (100, 39, 16), (92, 39, 16), + (87, 39, 16), (85, 39, 16), (84, 39, 16), (84, 39, 16), + (84, 39, 16), (84, 39, 16), (84, 39, 16), (84, 39, 16), + (84, 39, 16), (84, 39, 16), (84, 39, 16), (84, 39, 16), + (84, 39, 16), (84, 39, 16), (84, 39, 16), (85, 39, 16), + (92, 39, 16), (100, 39, 16), (100, 39, 16), (117, 46, 15), + (127, 62, 15), (175, 55, 15), (192, 53, 15), (237, 60, 15), + (247, 74, 20), (230, 62, 17), (184, 53, 15), (182, 56, 15), + (134, 48, 15), (128, 67, 20), (128, 78, 28), (137, 103, 28), + (188, 128, 30), (229, 153, 35), (245, 151, 35), (248, 133, 41), + (248, 106, 31), (202, 107, 22), (137, 94, 35), (108, 76, 15), + (93, 56, 15), (84, 47, 16), (84, 45, 16), (84, 42, 16), + (81, 39, 16), (81, 39, 16), (73, 39, 16), (64, 40, 16), + (58, 40, 16), (55, 39, 16), (49, 40, 16), (48, 40, 16), + (48, 40, 16), (48, 40, 16), (48, 40, 16), (48, 40, 16), + (48, 40, 16), (49, 40, 16), (53, 40, 16), (57, 40, 16), + (64, 40, 16), (66, 39, 16), (70, 39, 16), (77, 39, 16), + (81, 39, 16), (84, 39, 16), (84, 39, 16), (81, 41, 16), + (77, 40, 16), (68, 46, 16), (64, 47, 16), (64, 47, 16) + ), + +// 17 cars +((43, 30, 36), (38, 26, 33), (29, 22, 30), (32, 24, 32), + (31, 31, 35), (40, 39, 36), (51, 56, 42), (69, 71, 43), + (92, 94, 54), (116, 120, 64), (183, 130, 77), (221, 172, 85), + (218, 188, 136), (187, 189, 148), (190, 191, 173), (176, 180, 172), + (159, 184, 170), (142, 161, 152), (126, 135, 130), (104, 119, 98), + (98, 83, 78), (81, 60, 64), (87, 41, 42), (90, 44, 36), + (78, 35, 32), (59, 24, 34), (57, 24, 32), (54, 32, 38), + (51, 35, 37), (54, 32, 39), (64, 51, 38), (74, 59, 34), + (82, 70, 38), (91, 96, 51), (132, 137, 68), (207, 152, 66), + (229, 204, 97), (217, 199, 117), (213, 222, 147), (218, 215, 178), + (193, 204, 181), (177, 197, 185), (171, 199, 191), (165, 182, 185), + (155, 161, 156), (116, 122, 129), (91, 87, 99), (72, 74, 85), + (63, 55, 63), (44, 41, 50), (34, 33, 45), (33, 25, 34), + (27, 23, 28), (33, 21, 25), (39, 33, 24), (47, 45, 38), + (52, 51, 45), (67, 62, 56), (92, 82, 69), (120, 118, 89), + (152, 134, 85), (164, 135, 91), (152, 152, 93), (155, 166, 95), + (146, 157, 118), (138, 166, 102), (130, 164, 111), (133, 155, 93), + (113, 136, 88), (102, 131, 85), (96, 100, 60), (90, 81, 57), + (69, 70, 37), (59, 63, 38), (58, 49, 37), (49, 39, 39), + (43, 36, 32), (33, 23, 30), (27, 17, 30), (27, 19, 31), + (26, 23, 29), (24, 20, 27), (26, 21, 29), (33, 24, 32), + (45, 32, 37), (51, 45, 46), (70, 66, 62), (108, 94, 78), + (174, 107, 74), (205, 144, 56), (210, 171, 78), (205, 194, 148), + (211, 201, 178), (205, 226, 197), (195, 210, 202), (183, 207, 199), + (178, 206, 195), (162, 203, 184), (156, 195, 177), (158, 187, 169), + (152, 186, 156), (152, 162, 151), (143, 143, 137), (147, 147, 111), + (125, 138, 102), (125, 124, 97), (122, 132, 68), (109, 114, 62), + (92, 94, 49), (82, 73, 41), (72, 55, 49), (69, 50, 39), + (67, 49, 47), (69, 62, 60), (70, 70, 80), (84, 93, 100), + (96, 132, 114), (106, 133, 125), (113, 130, 123), (117, 128, 114), + (136, 138, 123), (143, 160, 126), (151, 174, 128), (157, 188, 118), + (165, 184, 135), (173, 203, 155), (186, 219, 163), (198, 226, 180), + (195, 244, 191), (203, 247, 199), (207, 238, 196), (205, 244, 226), + (221, 248, 232), (236, 250, 236), (222, 247, 232), (207, 230, 212), + (190, 212, 200), (165, 190, 191), (136, 162, 173), (107, 133, 128), + (96, 116, 109), (92, 105, 77), (76, 72, 69), (89, 76, 60), + (100, 92, 76), (120, 118, 98), (150, 164, 137), (167, 198, 158), + (188, 218, 157), (209, 237, 162), (215, 244, 184), (222, 254, 212), + (236, 253, 238), (246, 253, 239), (252, 252, 241), (251, 254, 243), + (248, 252, 241), (243, 251, 238), (242, 240, 224), (239, 239, 213), + (211, 229, 209), (224, 229, 197), (215, 229, 179), (203, 228, 197), + (190, 220, 180), (182, 218, 163), (159, 197, 139), (133, 167, 129), + (120, 145, 128), (106, 130, 110), (79, 82, 94), (64, 64, 70), + (52, 44, 57), (42, 31, 43), (39, 42, 46), (58, 59, 61), + (76, 73, 84), (108, 107, 114), (140, 148, 145), (169, 178, 165), + (195, 205, 186), (213, 227, 209), (218, 244, 225), (241, 253, 215), + (241, 254, 212), (239, 248, 180), (233, 247, 175), (223, 225, 171), + (183, 192, 147), (152, 143, 122), (123, 118, 103), (105, 112, 95), + (90, 89, 94), (76, 77, 89), (79, 88, 98), (96, 110, 112), + (116, 116, 116), (134, 134, 134), (144, 156, 164), (138, 166, 175), + (153, 184, 183), (166, 201, 161), (174, 218, 170), (179, 215, 175), + (182, 191, 169), (171, 184, 169), (149, 164, 168), (136, 158, 163), + (116, 131, 127), (92, 120, 99), (78, 101, 65), (77, 78, 61), + (66, 68, 48), (66, 67, 44), (75, 72, 52), (92, 77, 66), + (153, 100, 68), (178, 87, 59), (168, 60, 50), (152, 53, 43), + (92, 77, 50), (79, 68, 52), (68, 59, 66), (63, 59, 72), + (57, 71, 73), (79, 83, 91), (111, 110, 95), (134, 120, 91), + (182, 74, 55), (189, 30, 39), (189, 28, 37), (167, 26, 34), + (159, 32, 36), (97, 36, 37), (63, 36, 40), (48, 27, 36), + (40, 23, 24), (32, 22, 16), (24, 17, 23), (22, 17, 25), + (23, 17, 25), (24, 20, 27), (24, 19, 24), (26, 19, 26), + (30, 18, 26), (33, 16, 29), (36, 19, 27), (33, 19, 27), + (35, 22, 27), (45, 27, 21), (50, 34, 37), (49, 44, 43), + (64, 53, 45), (80, 69, 52), (92, 94, 68), (127, 123, 85) + ), + +// 18 unhealthy-tan +((218, 205, 192), (223, 205, 183), (219, 202, 177), (205, 193, 171), + (206, 186, 157), (189, 170, 147), (173, 151, 130), (163, 143, 129), + (160, 142, 119), (156, 141, 120), (159, 150, 133), (168, 161, 143), + (183, 172, 164), (211, 200, 191), (216, 206, 199), (218, 212, 211), + (220, 213, 206), (222, 213, 203), (223, 209, 199), (212, 203, 192), + (205, 194, 176), (198, 180, 151), (187, 160, 127), (173, 141, 106), + (153, 126, 101), (130, 108, 88), (104, 96, 79), (88, 76, 64), + (72, 59, 51), (67, 48, 48), (63, 42, 44), (58, 35, 38), + (60, 41, 45), (64, 46, 45), (76, 56, 50), (80, 60, 53), + (92, 66, 57), (96, 70, 58), (99, 77, 64), (105, 84, 67), + (114, 91, 71), (118, 97, 79), (121, 104, 84), (123, 105, 82), + (114, 101, 82), (113, 96, 72), (113, 89, 64), (113, 81, 60), + (108, 67, 51), (102, 65, 52), (88, 63, 53), (79, 54, 49), + (74, 48, 48), (65, 46, 47), (69, 46, 44), (68, 41, 43), + (70, 46, 46), (73, 48, 49), (77, 54, 52), (77, 58, 54), + (90, 70, 59), (93, 76, 64), (97, 85, 67), (101, 93, 81), + (115, 106, 87), (125, 112, 97), (141, 124, 97), (147, 121, 104), + (146, 120, 104), (138, 114, 91), (134, 109, 85), (122, 96, 75), + (111, 83, 66), (106, 70, 62), (102, 65, 53), (92, 58, 51), + (83, 49, 49), (83, 48, 46), (83, 54, 49), (94, 66, 56), + (99, 70, 54), (103, 75, 58), (108, 79, 63), (113, 85, 64), + (119, 90, 72), (123, 98, 76), (128, 102, 78), (130, 107, 78), + (131, 108, 79), (132, 104, 79), (131, 100, 79), (135, 99, 73), + (135, 98, 71), (131, 100, 70), (124, 94, 70), (118, 91, 71), + (114, 93, 70), (105, 96, 69), (105, 90, 67), (105, 86, 64), + (104, 81, 63), (103, 75, 62), (94, 73, 56), (88, 72, 58), + (85, 74, 59), (92, 70, 60), (87, 74, 60), (96, 79, 62), + (101, 87, 70), (112, 102, 77), (124, 107, 84), (133, 108, 87), + (143, 114, 92), (148, 119, 99), (149, 124, 104), (149, 124, 106), + (150, 131, 104), (165, 140, 109), (175, 148, 113), (189, 164, 131), + (199, 178, 144), (202, 182, 160), (209, 192, 178), (214, 202, 191), + (220, 210, 194), (219, 207, 192), (222, 204, 181), (208, 192, 165), + (196, 169, 138), (184, 153, 118), (176, 142, 104), (165, 129, 92), + (155, 115, 75), (142, 110, 77), (136, 108, 82), (136, 108, 84), + (134, 110, 84), (134, 115, 87), (136, 116, 90), (146, 123, 95), + (148, 126, 98), (149, 127, 102), (149, 125, 101), (149, 127, 97), + (150, 125, 99), (148, 124, 97), (140, 120, 92), (136, 118, 86), + (131, 118, 86), (129, 109, 85), (128, 108, 85), (125, 108, 89), + (126, 107, 97), (131, 112, 95), (140, 126, 101), (153, 135, 112), + (171, 147, 118), (195, 164, 136), (204, 177, 144), (199, 179, 149), + (201, 185, 160), (199, 184, 162), (182, 170, 153), (172, 156, 140), + (158, 148, 125), (144, 139, 121), (132, 125, 112), (129, 121, 100), + (124, 110, 92), (112, 100, 84), (104, 84, 68), (100, 76, 67), + (98, 75, 63), (94, 76, 60), (94, 76, 60), (94, 73, 60), + (102, 78, 61), (111, 81, 65), (113, 89, 65), (123, 93, 71), + (128, 101, 78), (132, 108, 80), (133, 108, 84), (130, 109, 80), + (123, 102, 78), (117, 101, 75), (112, 94, 71), (106, 86, 67), + (106, 82, 65), (109, 82, 60), (111, 84, 57), (113, 84, 57), + (118, 88, 57), (121, 92, 64), (125, 98, 69), (129, 106, 74), + (132, 109, 79), (143, 119, 82), (162, 125, 87), (168, 133, 95), + (162, 140, 115), (158, 144, 132), (156, 152, 147), (155, 152, 150), + (161, 159, 156), (183, 168, 159), (188, 174, 151), (190, 171, 145), + (194, 170, 143), (193, 173, 146), (193, 167, 145), (188, 163, 138), + (180, 155, 124), (162, 140, 118), (148, 123, 100), (137, 106, 85), + (130, 99, 76), (123, 94, 68), (124, 91, 62), (121, 89, 64), + (123, 91, 64), (126, 94, 69), (131, 97, 75), (128, 98, 75), + (123, 96, 72), (117, 94, 66), (117, 92, 65), (111, 89, 63), + (102, 83, 63), (90, 75, 60), (84, 66, 59), (79, 55, 55), + (72, 49, 52), (71, 46, 48), (72, 46, 48), (75, 50, 48), + (79, 54, 52), (92, 62, 53), (99, 67, 54), (109, 75, 59), + (122, 79, 55), (126, 89, 63), (132, 94, 67), (136, 97, 67), + (138, 102, 70), (135, 106, 80), (139, 114, 91), (152, 126, 96), + (163, 130, 101), (159, 134, 104), (162, 141, 109), (168, 136, 101), + (152, 132, 103), (151, 123, 95), (142, 115, 83), (138, 108, 78) + ), + +// 19 daffodil +((17, 0, 0), (54, 34, 22), (92, 62, 28), (128, 122, 46), + (214, 134, 0), (248, 152, 0), (242, 157, 5), (225, 157, 5), + (172, 143, 56), (133, 110, 56), (90, 90, 51), (65, 65, 46), + (66, 54, 43), (54, 54, 47), (37, 51, 45), (34, 49, 34), + (34, 60, 28), (39, 52, 36), (34, 45, 28), (51, 51, 30), + (49, 49, 32), (54, 49, 32), (49, 45, 26), (45, 39, 17), + (34, 28, 11), (22, 22, 11), (17, 17, 11), (17, 17, 5), + (17, 5, 5), (11, 5, 11), (5, 11, 11), (5, 5, 5), + (5, 0, 0), (5, 0, 0), (11, 5, 5), (11, 5, 5), + (11, 5, 5), (11, 5, 5), (11, 5, 0), (11, 5, 5), + (11, 0, 0), (11, 0, 0), (17, 0, 0), (17, 5, 0), + (28, 5, 5), (47, 22, 11), (75, 43, 20), (114, 83, 46), + (186, 134, 50), (239, 146, 11), (254, 146, 0), (237, 152, 5), + (210, 135, 28), (114, 101, 43), (68, 66, 22), (54, 60, 32), + (45, 56, 34), (51, 60, 28), (51, 54, 28), (47, 51, 24), + (54, 49, 15), (54, 49, 11), (51, 28, 5), (43, 26, 0), + (28, 22, 0), (22, 17, 0), (28, 34, 0), (30, 45, 15), + (43, 41, 15), (45, 45, 22), (49, 45, 22), (51, 45, 22), + (47, 37, 22), (45, 39, 22), (32, 32, 20), (28, 17, 17), + (22, 11, 11), (17, 11, 11), (17, 11, 11), (17, 17, 17), + (17, 17, 17), (17, 22, 17), (17, 20, 15), (17, 22, 5), + (17, 17, 0), (17, 11, 0), (17, 5, 5), (22, 11, 5), + (24, 9, 9), (28, 17, 11), (34, 22, 11), (41, 28, 17), + (45, 39, 22), (51, 53, 29), (68, 62, 34), (101, 78, 56), + (155, 116, 65), (220, 151, 73), (242, 157, 39), (254, 186, 39), + (248, 203, 33), (248, 191, 27), (248, 163, 11), (254, 134, 0), + (254, 129, 0), (212, 95, 0), (127, 62, 28), (77, 59, 25), + (60, 58, 32), (60, 63, 35), (68, 79, 45), (85, 93, 59), + (96, 96, 56), (103, 81, 92), (82, 124, 147), (60, 111, 139), + (45, 73, 131), (49, 83, 83), (51, 62, 68), (58, 52, 52), + (49, 43, 43), (35, 36, 36), (34, 34, 22), (22, 22, 20), + (22, 22, 26), (22, 17, 26), (22, 17, 17), (22, 17, 11), + (22, 22, 17), (22, 22, 17), (26, 32, 20), (28, 34, 22), + (34, 45, 26), (49, 49, 37), (56, 56, 49), (77, 71, 66), + (109, 112, 92), (120, 160, 159), (180, 186, 180), (218, 224, 190), + (239, 233, 205), (207, 218, 178), (158, 168, 123), (127, 155, 96), + (107, 113, 90), (66, 77, 66), (54, 79, 54), (49, 69, 49), + (56, 68, 36), (39, 72, 48), (49, 86, 63), (90, 102, 79), + (139, 133, 94), (179, 179, 122), (237, 214, 157), (246, 235, 189), + (248, 225, 163), (248, 208, 129), (248, 208, 73), (254, 197, 44), + (254, 197, 44), (248, 185, 56), (208, 180, 73), (189, 155, 59), + (152, 141, 79), (127, 138, 73), (138, 144, 67), (135, 141, 79), + (150, 156, 94), (177, 148, 103), (214, 180, 118), (246, 217, 161), + (244, 198, 159), (246, 229, 178), (254, 237, 180), (254, 237, 180), + (246, 223, 172), (171, 191, 142), (147, 152, 118), (147, 141, 107), + (135, 141, 107), (149, 131, 104), (158, 141, 108), (152, 141, 118), + (156, 154, 128), (188, 165, 154), (231, 208, 169), (248, 226, 186), + (248, 226, 197), (208, 225, 197), (175, 179, 152), (151, 145, 117), + (119, 124, 96), (86, 100, 66), (62, 85, 51), (45, 71, 22), + (49, 64, 26), (60, 69, 25), (101, 87, 50), (145, 113, 56), + (214, 135, 28), (248, 163, 16), (248, 169, 22), (254, 174, 16), + (254, 180, 11), (254, 180, 16), (242, 174, 11), (254, 168, 5), + (254, 157, 0), (254, 151, 0), (254, 157, 0), (254, 174, 0), + (254, 186, 0), (254, 191, 16), (242, 197, 28), (196, 178, 60), + (152, 130, 68), (113, 124, 59), (100, 100, 56), (68, 79, 59), + (53, 60, 39), (49, 37, 32), (39, 28, 22), (34, 17, 17), + (28, 22, 17), (34, 22, 11), (34, 32, 11), (49, 37, 15), + (56, 39, 28), (60, 47, 32), (77, 57, 31), (90, 80, 48), + (107, 116, 65), (164, 118, 84), (188, 148, 109), (197, 152, 107), + (231, 197, 129), (197, 174, 95), (158, 152, 95), (133, 121, 65), + (111, 82, 71), (90, 60, 54), (92, 75, 47), (110, 70, 42), + (132, 88, 50), (186, 112, 50), (220, 129, 28), (224, 117, 22), + (180, 95, 28), (102, 60, 34), (60, 60, 20), (43, 52, 15), + (26, 43, 5), (17, 31, 0), (11, 28, 5), (28, 22, 17) + ), + +// 20 rose +((113, 33, 37), (84, 23, 37), (55, 27, 28), (36, 40, 18), + (32, 56, 9), (60, 77, 18), (56, 101, 27), (60, 81, 28), + (52, 89, 18), (48, 85, 28), (40, 68, 28), (40, 56, 28), + (40, 52, 28), (76, 30, 28), (105, 18, 18), (121, 22, 19), + (125, 21, 28), (105, 22, 28), (84, 19, 28), (56, 23, 28), + (36, 36, 28), (32, 40, 28), (28, 36, 18), (28, 32, 18), + (27, 32, 9), (48, 27, 9), (77, 22, 9), (101, 15, 9), + (137, 14, 9), (150, 21, 19), (162, 28, 38), (178, 38, 57), + (166, 35, 86), (166, 39, 86), (178, 44, 86), (178, 47, 95), + (174, 68, 113), (170, 182, 170), (177, 190, 188), (181, 198, 179), + (166, 170, 160), (182, 52, 105), (198, 44, 96), (166, 31, 86), + (154, 30, 67), (146, 29, 47), (129, 25, 28), (101, 22, 18), + (68, 22, 18), (52, 23, 18), (36, 36, 18), (28, 36, 18), + (32, 44, 18), (36, 48, 18), (40, 56, 28), (52, 60, 28), + (52, 73, 28), (64, 73, 28), (101, 26, 28), (125, 25, 28), + (141, 22, 28), (129, 18, 28), (109, 21, 28), (76, 26, 28), + (48, 52, 37), (60, 72, 28), (73, 97, 47), (77, 109, 85), + (92, 133, 122), (100, 133, 132), (96, 133, 131), (85, 113, 85), + (93, 96, 47), (93, 117, 47), (113, 108, 37), (125, 63, 47), + (141, 29, 38), (146, 25, 28), (146, 22, 28), (146, 25, 38), + (146, 25, 57), (150, 26, 66), (158, 30, 76), (158, 35, 86), + (162, 27, 86), (166, 27, 86), (158, 34, 76), (153, 34, 57), + (141, 29, 47), (121, 33, 37), (76, 59, 37), (48, 60, 37), + (28, 56, 28), (28, 40, 18), (20, 28, 18), (20, 24, 18), + (23, 24, 18), (24, 32, 28), (28, 36, 37), (40, 39, 37), + (64, 23, 28), (101, 22, 28), (141, 19, 38), (146, 22, 47), + (150, 21, 47), (158, 26, 57), (150, 22, 47), (150, 21, 57), + (146, 22, 47), (141, 18, 38), (137, 21, 28), (137, 22, 28), + (133, 21, 28), (133, 21, 18), (113, 18, 9), (133, 20, 18), + (141, 21, 19), (146, 21, 28), (150, 21, 28), (154, 28, 28), + (158, 24, 28), (150, 28, 28), (154, 28, 38), (166, 33, 48), + (166, 25, 48), (154, 22, 47), (158, 30, 57), (162, 31, 67), + (162, 43, 76), (157, 140, 56), (129, 170, 103), (166, 186, 169), + (181, 189, 198), (173, 189, 207), (169, 185, 188), (154, 170, 170), + (182, 52, 133), (178, 44, 115), (178, 40, 105), (182, 56, 114), + (150, 170, 160), (165, 186, 188), (165, 185, 188), (112, 158, 160), + (104, 133, 113), (76, 113, 75), (85, 92, 47), (133, 30, 38), + (150, 29, 28), (158, 28, 28), (158, 29, 28), (170, 25, 28), + (166, 37, 38), (157, 30, 48), (150, 26, 57), (146, 22, 66), + (150, 34, 67), (150, 33, 57), (150, 25, 47), (146, 22, 47), + (146, 19, 38), (137, 21, 28), (109, 21, 28), (72, 19, 28), + (48, 27, 28), (43, 40, 37), (36, 44, 28), (36, 52, 28), + (48, 60, 37), (52, 77, 37), (52, 81, 47), (60, 77, 56), + (60, 85, 56), (77, 109, 66), (77, 125, 65), (77, 133, 56), + (93, 141, 46), (101, 146, 66), (93, 133, 74), (81, 129, 83), + (105, 137, 75), (109, 162, 94), (113, 158, 84), (121, 162, 85), + (142, 154, 66), (113, 141, 75), (109, 129, 56), (101, 121, 47), + (109, 137, 47), (97, 121, 37), (81, 117, 37), (73, 97, 28), + (81, 93, 18), (109, 25, 28), (129, 25, 28), (141, 25, 28), + (141, 22, 28), (141, 22, 28), (141, 21, 28), (137, 21, 37), + (93, 19, 28), (68, 19, 28), (51, 19, 28), (24, 24, 37), + (23, 24, 28), (24, 24, 18), (24, 24, 18), (27, 24, 18), + (28, 24, 18), (47, 23, 28), (63, 23, 28), (88, 19, 28), + (121, 18, 19), (133, 24, 19), (146, 21, 28), (146, 21, 28), + (146, 21, 28), (146, 18, 28), (146, 18, 28), (146, 18, 28), + (146, 17, 28), (146, 18, 28), (146, 21, 28), (146, 21, 19), + (146, 21, 19), (146, 17, 19), (141, 21, 19), (141, 21, 19), + (141, 21, 19), (133, 21, 19), (129, 21, 19), (109, 18, 18), + (80, 26, 18), (56, 27, 18), (32, 32, 18), (28, 28, 18), + (32, 32, 18), (56, 19, 18), (80, 19, 18), (113, 22, 28), + (146, 26, 57), (154, 34, 67), (161, 51, 85), (107, 133, 132), + (150, 174, 170), (165, 186, 179), (154, 174, 170), (124, 154, 122), + (170, 55, 85), (174, 39, 67), (182, 55, 66), (170, 37, 47), + (158, 32, 38), (145, 26, 38), (125, 25, 28), (68, 23, 28) + ), + +// 21 healthy-skin +((250, 225, 235), (194, 165, 188), (157, 133, 141), (137, 100, 94), + (96, 60, 47), (72, 43, 28), (60, 35, 28), (52, 23, 18), + (35, 16, 9), (35, 16, 9), (35, 16, 9), (32, 8, 0), + (31, 12, 9), (24, 12, 9), (35, 16, 18), (40, 19, 28), + (56, 27, 28), (80, 39, 47), (113, 64, 65), (141, 84, 75), + (166, 95, 85), (182, 107, 94), (186, 107, 94), (190, 111, 94), + (186, 111, 94), (182, 111, 85), (154, 92, 66), (141, 88, 47), + (105, 68, 46), (81, 51, 18), (56, 27, 18), (52, 23, 9), + (35, 16, 18), (27, 12, 18), (24, 8, 18), (0, 0, 0), + (0, 0, 0), (24, 4, 18), (35, 8, 18), (44, 12, 18), + (44, 20, 18), (44, 19, 18), (40, 12, 18), (52, 19, 18), + (52, 19, 28), (40, 16, 28), (35, 12, 28), (39, 16, 28), + (52, 23, 28), (56, 27, 28), (68, 39, 28), (76, 48, 47), + (101, 64, 65), (133, 100, 84), (158, 112, 94), (186, 119, 94), + (198, 136, 113), (206, 152, 132), (210, 157, 141), (226, 161, 160), + (238, 164, 160), (238, 180, 169), (246, 184, 169), (250, 184, 169), + (246, 180, 159), (242, 172, 150), (250, 160, 141), (242, 152, 122), + (242, 148, 122), (234, 144, 113), (234, 144, 122), (222, 145, 132), + (214, 149, 132), (214, 149, 122), (219, 149, 122), (210, 165, 132), + (219, 165, 141), (234, 172, 150), (238, 176, 150), (238, 176, 150), + (246, 176, 140), (250, 164, 141), (242, 160, 131), (234, 156, 113), + (234, 144, 103), (219, 128, 94), (214, 123, 85), (210, 119, 94), + (214, 124, 103), (226, 140, 113), (238, 152, 131), (238, 164, 141), + (238, 164, 150), (234, 160, 150), (238, 156, 141), (242, 148, 141), + (219, 141, 132), (210, 136, 122), (198, 119, 104), (194, 119, 103), + (182, 103, 94), (174, 103, 85), (170, 95, 75), (166, 88, 85), + (150, 88, 85), (149, 92, 75), (146, 96, 85), (141, 88, 75), + (121, 76, 65), (96, 60, 56), (84, 52, 47), (80, 47, 37), + (84, 51, 28), (92, 60, 37), (113, 60, 47), (137, 84, 56), + (166, 95, 75), (182, 115, 85), (186, 128, 104), (206, 157, 132), + (222, 165, 151), (238, 184, 169), (246, 197, 206), (246, 213, 244), + (234, 226, 254), (242, 226, 244), (214, 202, 207), (219, 169, 160), + (214, 149, 132), (219, 145, 122), (210, 137, 113), (214, 128, 113), + (210, 120, 104), (202, 124, 103), (206, 128, 113), (198, 119, 104), + (194, 107, 94), (178, 99, 85), (158, 84, 75), (154, 80, 75), + (137, 68, 66), (125, 68, 65), (125, 64, 56), (137, 72, 56), + (146, 84, 56), (158, 107, 75), (166, 111, 85), (182, 128, 103), + (202, 153, 141), (222, 185, 169), (246, 209, 188), (246, 222, 244), + (250, 226, 244), (246, 221, 244), (230, 205, 225), (206, 202, 198), + (226, 185, 179), (238, 184, 169), (234, 172, 150), (210, 161, 122), + (210, 141, 113), (190, 111, 94), (170, 103, 85), (146, 84, 75), + (117, 60, 56), (96, 47, 47), (80, 43, 37), (72, 39, 37), + (76, 43, 47), (96, 60, 47), (113, 76, 56), (141, 92, 66), + (162, 116, 94), (182, 140, 113), (190, 161, 150), (198, 157, 179), + (206, 169, 179), (210, 173, 170), (206, 160, 151), (194, 153, 151), + (194, 148, 151), (166, 133, 122), (149, 120, 113), (129, 104, 103), + (125, 100, 103), (101, 80, 84), (84, 56, 47), (80, 56, 37), + (88, 47, 37), (101, 56, 47), (121, 72, 56), (154, 88, 66), + (186, 115, 94), (202, 145, 132), (218, 161, 160), (230, 172, 169), + (226, 181, 188), (205, 185, 207), (202, 185, 198), (178, 174, 170), + (161, 137, 141), (133, 112, 113), (129, 84, 84), (100, 68, 56), + (84, 51, 47), (72, 39, 37), (72, 39, 28), (80, 43, 28), + (92, 64, 47), (117, 88, 75), (133, 112, 94), (170, 128, 103), + (186, 157, 141), (186, 165, 151), (186, 157, 160), (169, 149, 160), + (170, 137, 132), (170, 120, 104), (178, 111, 94), (186, 107, 94), + (194, 107, 85), (198, 111, 85), (186, 115, 85), (178, 111, 85), + (178, 107, 85), (178, 95, 56), (149, 63, 37), (101, 52, 47), + (84, 39, 37), (72, 31, 28), (72, 27, 28), (60, 27, 28), + (48, 31, 28), (56, 31, 28), (68, 35, 28), (68, 35, 28), + (80, 39, 28), (89, 56, 37), (113, 76, 56), (137, 96, 75), + (157, 120, 94), (178, 140, 103), (202, 153, 132), (198, 149, 141), + (198, 145, 132), (198, 128, 104), (194, 119, 94), (174, 103, 85), + (146, 104, 85), (145, 100, 85), (145, 104, 85), (153, 112, 103), + (170, 112, 103), (194, 119, 94), (214, 132, 94), (230, 140, 103) + ), + +// 22 orange +((123, 106, 57), (97, 100, 60), (91, 83, 58), (70, 74, 54), + (70, 71, 53), (59, 68, 51), (59, 56, 32), (54, 61, 44), + (57, 72, 57), (67, 74, 62), (81, 97, 76), (95, 114, 91), + (109, 114, 82), (115, 113, 84), (112, 120, 98), (128, 131, 98), + (130, 137, 106), (134, 142, 106), (150, 151, 107), (149, 150, 114), + (149, 152, 123), (148, 156, 135), (170, 161, 127), (188, 121, 129), + (228, 101, 100), (234, 92, 73), (224, 66, 57), (195, 72, 57), + (121, 65, 36), (86, 54, 32), (75, 73, 38), (29, 34, 39), + (54, 52, 52), (53, 57, 62), (60, 78, 68), (63, 69, 77), + (64, 89, 73), (84, 105, 77), (84, 114, 95), (98, 122, 108), + (120, 143, 125), (132, 158, 138), (138, 165, 137), (139, 162, 137), + (154, 153, 159), (178, 155, 163), (176, 154, 155), (183, 159, 157), + (187, 171, 130), (169, 174, 143), (165, 183, 130), (170, 171, 138), + (175, 179, 129), (159, 175, 124), (155, 156, 122), (143, 142, 110), + (131, 129, 116), (125, 128, 116), (127, 121, 131), (119, 119, 134), + (115, 118, 132), (121, 139, 133), (123, 138, 124), (124, 141, 130), + (136, 154, 141), (140, 148, 158), (131, 149, 158), (91, 155, 182), + (100, 132, 171), (83, 129, 184), (82, 128, 193), (85, 149, 207), + (93, 183, 236), (113, 192, 242), (137, 196, 237), (127, 191, 237), + (119, 187, 234), (114, 170, 214), (109, 156, 197), (144, 153, 173), + (153, 147, 160), (169, 161, 168), (175, 185, 189), (158, 196, 225), + (143, 193, 219), (161, 186, 214), (179, 185, 193), (199, 168, 158), + (225, 119, 116), (235, 102, 114), (230, 100, 108), (217, 112, 120), + (176, 143, 147), (141, 135, 141), (113, 145, 147), (95, 128, 153), + (103, 125, 146), (112, 129, 127), (122, 133, 106), (135, 148, 97), + (144, 134, 85), (163, 136, 81), (160, 143, 93), (198, 163, 73), + (220, 178, 61), (213, 162, 67), (201, 149, 50), (161, 119, 68), + (186, 108, 93), (166, 138, 99), (152, 149, 140), (156, 158, 164), + (142, 180, 213), (138, 181, 225), (117, 187, 236), (90, 177, 233), + (83, 153, 201), (111, 136, 164), (136, 113, 115), (187, 103, 92), + (236, 100, 67), (228, 75, 48), (247, 68, 36), (248, 69, 32), + (241, 64, 42), (233, 68, 41), (218, 64, 51), (136, 85, 64), + (96, 85, 68), (100, 103, 79), (91, 100, 77), (106, 99, 68), + (121, 113, 71), (136, 148, 79), (147, 152, 81), (158, 154, 91), + (191, 168, 101), (200, 179, 97), (190, 173, 101), (185, 175, 112), + (177, 194, 115), (172, 183, 132), (175, 191, 149), (149, 177, 132), + (136, 156, 131), (125, 139, 122), (107, 132, 119), (97, 119, 102), + (89, 109, 92), (84, 92, 72), (75, 75, 66), (79, 80, 73), + (76, 91, 73), (77, 106, 93), (76, 101, 107), (92, 121, 107), + (98, 125, 119), (112, 148, 137), (139, 170, 156), (150, 187, 213), + (144, 193, 230), (145, 192, 228), (146, 191, 222), (167, 180, 181), + (158, 185, 154), (157, 177, 121), (155, 160, 89), (158, 168, 78), + (172, 175, 93), (186, 158, 73), (186, 158, 73), (181, 153, 84), + (151, 157, 88), (133, 154, 91), (130, 151, 99), (132, 147, 98), + (126, 139, 105), (123, 129, 103), (106, 111, 96), (84, 95, 105), + (74, 81, 89), (71, 64, 92), (77, 73, 81), (90, 101, 83), + (96, 100, 90), (105, 105, 97), (115, 114, 97), (117, 122, 95), + (134, 137, 83), (136, 138, 55), (150, 126, 52), (110, 118, 59), + (85, 107, 55), (89, 96, 60), (76, 76, 53), (68, 67, 37), + (72, 73, 59), (90, 87, 73), (115, 107, 86), (144, 110, 76), + (150, 121, 87), (152, 123, 95), (139, 140, 106), (132, 144, 123), + (141, 151, 150), (162, 158, 160), (169, 178, 175), (185, 199, 218), + (191, 205, 221), (185, 202, 221), (185, 195, 212), (189, 197, 144), + (194, 177, 136), (213, 196, 90), (220, 182, 64), (208, 164, 76), + (238, 106, 91), (236, 103, 85), (240, 88, 83), (239, 80, 72), + (239, 82, 57), (236, 68, 52), (246, 65, 43), (245, 63, 26), + (244, 67, 16), (244, 78, 17), (244, 82, 23), (243, 76, 23), + (247, 69, 28), (243, 74, 28), (244, 72, 44), (238, 86, 55), + (243, 75, 60), (225, 84, 71), (159, 92, 97), (124, 125, 103), + (113, 117, 105), (92, 113, 100), (95, 113, 101), (106, 111, 113), + (107, 115, 109), (110, 115, 99), (117, 123, 90), (119, 123, 75), + (134, 122, 81), (130, 128, 71), (132, 142, 75), (155, 155, 94), + (163, 164, 121), (160, 152, 148), (130, 165, 160), (107, 163, 204), + (94, 183, 235), (96, 188, 238), (106, 180, 234), (126, 172, 209) + ), + +// 23 white-ivy +((242, 242, 254), (208, 231, 197), (163, 197, 152), (141, 175, 118), + (107, 152, 73), (96, 147, 51), (79, 124, 45), (79, 107, 28), + (85, 107, 22), (96, 124, 39), (107, 147, 62), (113, 164, 96), + (135, 169, 135), (152, 203, 152), (178, 212, 178), (208, 231, 197), + (220, 242, 225), (212, 246, 246), (208, 237, 254), (197, 242, 254), + (169, 233, 225), (169, 220, 186), (152, 208, 163), (152, 203, 152), + (163, 186, 152), (146, 163, 158), (156, 156, 156), (144, 158, 158), + (135, 152, 124), (118, 152, 118), (101, 130, 113), (82, 82, 82), + (58, 32, 32), (56, 28, 28), (84, 84, 39), (96, 113, 33), + (107, 130, 22), (118, 152, 28), (141, 175, 34), (135, 175, 67), + (113, 164, 90), (118, 152, 101), (112, 141, 112), (101, 137, 112), + (101, 135, 101), (96, 130, 96), (84, 118, 84), (67, 113, 62), + (56, 107, 51), (56, 107, 45), (68, 102, 34), (73, 124, 51), + (79, 118, 79), (107, 141, 96), (130, 164, 124), (158, 180, 141), + (186, 186, 169), (214, 220, 208), (239, 239, 239), (246, 246, 246), + (254, 254, 254), (254, 254, 254), (242, 254, 254), (242, 248, 254), + (237, 242, 248), (231, 242, 242), (220, 237, 203), (214, 208, 118), + (163, 197, 56), (169, 163, 28), (147, 169, 50), (141, 158, 84), + (118, 164, 118), (113, 169, 118), (107, 158, 118), (73, 141, 101), + (45, 128, 56), (34, 85, 34), (28, 73, 28), (28, 77, 28), + (45, 90, 56), (84, 118, 84), (118, 152, 118), (152, 180, 152), + (175, 203, 175), (197, 231, 208), (208, 231, 254), (208, 231, 254), + (208, 220, 254), (206, 214, 197), (192, 169, 169), (171, 180, 175), + (174, 208, 174), (180, 209, 180), (197, 231, 191), (220, 237, 214), + (237, 242, 237), (246, 246, 246), (254, 254, 254), (254, 254, 254), + (254, 254, 254), (242, 254, 254), (242, 254, 254), (242, 248, 254), + (237, 237, 248), (225, 225, 225), (231, 163, 163), (150, 112, 112), + (96, 84, 79), (82, 82, 82), (56, 96, 56), (50, 92, 45), + (34, 85, 28), (39, 90, 39), (73, 115, 73), (124, 135, 101), + (158, 175, 129), (163, 186, 163), (186, 209, 186), (208, 214, 254), + (208, 225, 254), (208, 208, 254), (174, 208, 197), (152, 192, 152), + (118, 152, 118), (84, 124, 79), (62, 101, 56), (28, 73, 28), + (5, 51, 0), (34, 0, 0), (0, 52, 0), (0, 51, 0), + (0, 52, 0), (11, 62, 5), (28, 79, 22), (28, 73, 28), + (56, 83, 11), (68, 68, 0), (45, 51, 0), (73, 96, 28), + (84, 101, 33), (90, 102, 28), (79, 130, 51), (90, 143, 112), + (90, 175, 118), (152, 203, 152), (163, 209, 186), (186, 220, 254), + (208, 225, 254), (220, 220, 254), (220, 220, 254), (220, 225, 254), + (220, 231, 254), (220, 231, 254), (231, 231, 254), (231, 231, 254), + (231, 231, 254), (231, 242, 254), (220, 254, 254), (208, 254, 254), + (208, 254, 254), (197, 254, 254), (208, 254, 254), (220, 254, 254), + (231, 248, 254), (231, 237, 254), (231, 231, 254), (231, 231, 254), + (231, 231, 254), (231, 237, 254), (231, 242, 254), (231, 242, 254), + (231, 242, 254), (231, 242, 254), (231, 237, 254), (231, 231, 254), + (231, 231, 254), (220, 237, 254), (220, 237, 254), (197, 254, 254), + (163, 254, 254), (140, 191, 197), (152, 175, 152), (152, 158, 129), + (124, 130, 90), (107, 67, 62), (124, 34, 34), (137, 45, 45), + (153, 51, 51), (153, 51, 51), (175, 95, 67), (141, 141, 112), + (135, 152, 124), (141, 163, 135), (152, 186, 152), (152, 203, 152), + (152, 203, 152), (163, 208, 163), (191, 225, 191), (231, 231, 231), + (220, 231, 254), (220, 225, 254), (220, 225, 254), (231, 231, 254), + (242, 242, 254), (242, 242, 254), (242, 248, 254), (242, 254, 254), + (254, 254, 254), (254, 254, 254), (254, 254, 254), (242, 248, 254), + (242, 242, 254), (231, 242, 254), (231, 242, 254), (231, 242, 254), + (231, 242, 231), (231, 225, 175), (220, 214, 135), (254, 169, 140), + (208, 197, 118), (208, 191, 112), (163, 191, 107), (107, 152, 73), + (96, 147, 51), (90, 141, 51), (90, 135, 39), (85, 136, 51), + (96, 141, 45), (101, 147, 45), (118, 141, 62), (135, 129, 78), + (135, 158, 107), (146, 192, 101), (146, 197, 112), (152, 197, 135), + (152, 203, 152), (186, 214, 186), (208, 242, 231), (220, 237, 254), + (231, 242, 254), (242, 242, 254), (242, 242, 254), (242, 242, 254), + (242, 242, 254), (242, 248, 254), (231, 254, 254), (231, 254, 254), + (231, 242, 254), (237, 237, 248), (214, 237, 220), (186, 220, 180), + (152, 203, 152), (141, 192, 84), (118, 164, 45), (96, 124, 28) + ), + +// 24 summer-makeup +((238, 193, 141), (238, 192, 141), (238, 192, 141), (234, 193, 141), + (234, 193, 141), (234, 193, 141), (230, 193, 141), (230, 189, 141), + (226, 189, 141), (226, 193, 141), (234, 193, 141), (238, 197, 141), + (238, 201, 141), (234, 197, 150), (234, 193, 150), (234, 197, 150), + (230, 193, 150), (226, 189, 141), (222, 185, 132), (219, 177, 113), + (210, 144, 85), (219, 106, 75), (219, 95, 66), (190, 63, 37), + (150, 64, 28), (145, 47, 28), (133, 51, 37), (101, 43, 28), + (84, 51, 37), (80, 52, 37), (80, 56, 37), (80, 60, 47), + (89, 72, 56), (109, 84, 56), (125, 104, 66), (166, 107, 66), + (198, 136, 75), (219, 161, 94), (222, 180, 103), (226, 193, 122), + (226, 189, 122), (222, 180, 113), (219, 169, 103), (198, 140, 85), + (178, 115, 66), (158, 99, 56), (158, 88, 47), (158, 88, 56), + (166, 107, 56), (186, 119, 66), (202, 140, 94), (219, 173, 103), + (230, 180, 113), (230, 180, 122), (226, 180, 122), (219, 165, 113), + (202, 140, 94), (162, 103, 66), (125, 80, 56), (113, 72, 46), + (89, 60, 37), (76, 52, 37), (64, 48, 37), (52, 39, 28), + (40, 35, 28), (36, 36, 28), (32, 36, 37), (36, 36, 37), + (40, 35, 37), (48, 40, 37), (52, 39, 37), (48, 35, 37), + (52, 40, 37), (64, 48, 37), (72, 52, 37), (80, 60, 47), + (96, 68, 56), (97, 68, 56), (100, 68, 56), (97, 64, 56), + (84, 56, 56), (76, 48, 47), (68, 47, 47), (64, 48, 47), + (68, 48, 47), (76, 52, 47), (84, 60, 47), (101, 68, 56), + (117, 84, 65), (137, 88, 66), (166, 103, 66), (206, 136, 75), + (210, 157, 85), (222, 164, 94), (214, 156, 85), (202, 140, 85), + (186, 123, 66), (150, 103, 66), (121, 88, 56), (105, 76, 56), + (88, 60, 47), (76, 48, 47), (64, 48, 37), (56, 44, 37), + (60, 48, 47), (68, 48, 47), (85, 60, 47), (105, 80, 56), + (137, 88, 66), (154, 107, 75), (194, 140, 85), (214, 169, 113), + (219, 177, 122), (222, 180, 141), (137, 145, 151), (88, 104, 94), + (76, 68, 66), (81, 68, 65), (80, 64, 56), (76, 60, 56), + (80, 56, 47), (76, 52, 47), (76, 52, 56), (76, 52, 56), + (68, 52, 56), (56, 44, 56), (48, 39, 47), (48, 35, 47), + (48, 35, 37), (40, 35, 37), (39, 32, 28), (36, 32, 28), + (36, 32, 28), (36, 32, 28), (32, 32, 28), (31, 28, 28), + (28, 32, 28), (31, 32, 28), (24, 32, 28), (31, 28, 28), + (32, 28, 28), (35, 28, 37), (36, 32, 37), (36, 32, 37), + (40, 31, 28), (44, 35, 28), (52, 36, 28), (56, 39, 28), + (52, 35, 37), (60, 39, 37), (52, 40, 37), (48, 40, 37), + (48, 48, 37), (44, 40, 28), (44, 36, 28), (44, 36, 28), + (48, 35, 28), (56, 39, 28), (64, 39, 28), (88, 51, 37), + (117, 72, 46), (146, 80, 56), (166, 111, 56), (198, 136, 75), + (214, 164, 94), (219, 177, 113), (222, 185, 132), (226, 184, 141), + (226, 189, 141), (230, 193, 131), (230, 197, 131), (234, 192, 131), + (230, 184, 131), (222, 185, 132), (230, 184, 131), (230, 184, 131), + (226, 189, 132), (222, 189, 132), (234, 188, 131), (234, 184, 131), + (230, 184, 122), (222, 180, 113), (219, 177, 103), (210, 148, 85), + (194, 132, 66), (190, 106, 56), (170, 95, 56), (174, 91, 47), + (194, 87, 28), (194, 72, 28), (154, 76, 37), (129, 64, 37), + (93, 51, 37), (72, 43, 37), (68, 43, 37), (64, 48, 37), + (60, 52, 37), (68, 52, 37), (89, 64, 47), (113, 84, 56), + (145, 100, 66), (182, 127, 85), (210, 165, 94), (219, 181, 103), + (234, 193, 112), (234, 193, 122), (234, 188, 122), (222, 176, 113), + (202, 148, 94), (186, 119, 75), (170, 103, 66), (146, 92, 75), + (137, 92, 75), (149, 104, 75), (174, 111, 75), (186, 127, 85), + (202, 144, 94), (222, 169, 122), (226, 180, 141), (234, 193, 150), + (234, 201, 160), (234, 205, 169), (234, 201, 160), (230, 197, 150), + (230, 189, 141), (226, 180, 122), (214, 161, 103), (186, 135, 85), + (153, 104, 84), (129, 108, 84), (121, 92, 75), (121, 80, 65), + (113, 76, 56), (121, 72, 56), (117, 72, 46), (125, 68, 47), + (125, 68, 56), (109, 64, 56), (109, 60, 46), (88, 55, 47), + (84, 43, 47), (72, 43, 47), (60, 44, 37), (52, 44, 37), + (44, 40, 37), (40, 35, 28), (36, 36, 28), (36, 36, 37), + (40, 35, 37), (44, 44, 37), (52, 48, 47), (80, 60, 47), + (109, 68, 46), (129, 84, 47), (158, 99, 66), (186, 119, 75) + ), + +// 25 glow-buzz +((182, 91, 37), (141, 84, 37), (121, 68, 46), (93, 60, 46), + (76, 48, 37), (72, 43, 37), (80, 48, 47), (101, 60, 46), + (137, 68, 47), (162, 76, 47), (178, 95, 56), (182, 102, 56), + (182, 99, 47), (182, 87, 47), (194, 84, 56), (198, 84, 56), + (190, 87, 66), (174, 87, 56), (146, 76, 56), (117, 60, 47), + (88, 51, 37), (64, 39, 28), (52, 27, 28), (44, 24, 28), + (40, 24, 28), (40, 23, 28), (40, 23, 28), (40, 23, 28), + (44, 27, 28), (52, 31, 28), (60, 39, 28), (84, 47, 37), + (109, 51, 47), (133, 59, 56), (162, 64, 56), (178, 68, 47), + (190, 68, 56), (198, 72, 47), (198, 72, 47), (198, 72, 47), + (190, 68, 47), (178, 68, 47), (166, 68, 47), (149, 71, 37), + (129, 64, 37), (100, 60, 28), (92, 47, 37), (76, 43, 37), + (72, 48, 37), (76, 52, 47), (100, 56, 56), (133, 76, 56), + (154, 80, 47), (178, 87, 47), (178, 80, 47), (158, 80, 47), + (141, 68, 47), (113, 60, 46), (96, 56, 47), (84, 47, 56), + (84, 48, 47), (92, 55, 47), (100, 51, 46), (96, 51, 47), + (92, 55, 47), (84, 56, 47), (93, 60, 47), (84, 52, 37), + (76, 52, 28), (72, 40, 18), (64, 35, 28), (56, 31, 28), + (48, 32, 37), (44, 35, 37), (48, 31, 37), (56, 35, 37), + (48, 36, 37), (56, 35, 37), (64, 35, 37), (60, 39, 47), + (60, 35, 47), (56, 35, 37), (52, 35, 28), (48, 31, 28), + (48, 31, 28), (44, 31, 28), (44, 31, 28), (44, 28, 28), + (40, 27, 28), (44, 28, 28), (56, 31, 37), (64, 43, 47), + (80, 43, 56), (100, 60, 56), (137, 76, 65), (178, 102, 56), + (210, 123, 66), (198, 144, 75), (214, 148, 75), (219, 157, 75), + (222, 160, 75), (222, 168, 84), (250, 179, 74), (250, 191, 65), + (246, 183, 56), (242, 183, 65), (238, 168, 56), (230, 152, 47), + (242, 159, 56), (219, 145, 75), (214, 128, 122), (222, 176, 169), + (190, 169, 122), (254, 212, 121), (250, 225, 150), (254, 212, 93), + (254, 221, 84), (250, 213, 93), (254, 217, 84), (250, 200, 74), + (254, 212, 84), (246, 208, 74), (254, 208, 74), (254, 191, 56), + (254, 178, 46), (234, 167, 46), (222, 149, 47), (210, 145, 56), + (206, 127, 56), (194, 106, 56), (190, 106, 56), (198, 91, 56), + (190, 91, 47), (186, 106, 56), (198, 119, 47), (219, 132, 56), + (230, 119, 56), (230, 110, 47), (230, 123, 47), (234, 148, 56), + (250, 166, 56), (250, 175, 56), (250, 179, 56), (250, 179, 56), + (238, 171, 56), (219, 153, 66), (230, 152, 56), (210, 140, 47), + (194, 106, 47), (174, 83, 37), (162, 72, 37), (154, 72, 47), + (166, 76, 47), (170, 84, 47), (170, 91, 47), (182, 95, 47), + (186, 84, 56), (198, 87, 56), (210, 102, 56), (226, 110, 56), + (226, 98, 47), (226, 102, 56), (222, 87, 56), (214, 83, 56), + (202, 84, 56), (194, 84, 56), (182, 80, 56), (162, 72, 56), + (146, 76, 47), (137, 64, 47), (125, 64, 47), (109, 56, 56), + (113, 56, 56), (129, 64, 56), (146, 76, 56), (166, 72, 56), + (182, 76, 56), (194, 72, 47), (182, 80, 56), (186, 72, 37), + (186, 59, 28), (194, 72, 37), (206, 72, 47), (206, 83, 37), + (206, 80, 47), (210, 87, 47), (219, 83, 47), (210, 80, 56), + (198, 76, 56), (174, 72, 56), (146, 60, 47), (129, 60, 37), + (109, 51, 28), (92, 47, 28), (101, 51, 28), (121, 51, 37), + (141, 55, 37), (158, 60, 37), (170, 56, 47), (174, 64, 47), + (174, 68, 47), (178, 64, 47), (182, 63, 47), (190, 80, 47), + (202, 80, 47), (202, 87, 47), (198, 83, 47), (182, 83, 47), + (178, 80, 47), (150, 72, 47), (133, 64, 47), (113, 60, 46), + (101, 51, 37), (76, 39, 37), (60, 31, 28), (44, 27, 28), + (40, 23, 28), (39, 19, 18), (36, 16, 18), (36, 16, 18), + (35, 20, 18), (35, 20, 28), (35, 24, 28), (36, 24, 18), + (35, 20, 9), (36, 20, 9), (36, 20, 18), (36, 24, 18), + (44, 31, 18), (56, 35, 28), (72, 43, 37), (96, 43, 37), + (109, 51, 46), (117, 60, 46), (129, 72, 47), (125, 68, 37), + (109, 60, 37), (96, 47, 37), (80, 39, 37), (60, 35, 37), + (48, 27, 28), (44, 27, 18), (40, 23, 18), (40, 23, 18), + (39, 24, 28), (36, 24, 28), (35, 20, 28), (35, 16, 28), + (35, 20, 37), (40, 28, 37), (56, 40, 37), (72, 43, 47), + (97, 52, 46), (113, 51, 47), (162, 60, 47), (186, 68, 47) + ), + +// 26 deep-water +((24, 20, 18), (24, 24, 28), (28, 28, 47), (27, 24, 66), + (24, 28, 75), (23, 28, 75), (23, 28, 66), (19, 28, 47), + (20, 24, 28), (20, 24, 18), (20, 24, 18), (24, 28, 28), + (28, 32, 56), (28, 36, 66), (28, 36, 85), (36, 52, 103), + (48, 64, 113), (48, 56, 122), (44, 64, 122), (52, 64, 132), + (52, 64, 113), (68, 60, 113), (68, 64, 103), (56, 77, 103), + (56, 68, 94), (52, 60, 94), (52, 52, 94), (36, 52, 94), + (36, 52, 85), (36, 40, 66), (32, 32, 56), (24, 24, 28), + (16, 16, 18), (11, 8, 18), (11, 8, 9), (8, 4, 0), + (8, 4, 0), (11, 4, 9), (11, 8, 18), (11, 8, 28), + (16, 16, 28), (19, 28, 37), (24, 32, 56), (24, 40, 75), + (28, 48, 94), (36, 64, 103), (40, 64, 113), (44, 68, 122), + (44, 68, 113), (40, 64, 113), (36, 60, 113), (36, 52, 103), + (28, 48, 94), (32, 40, 75), (36, 36, 66), (32, 36, 56), + (24, 32, 47), (19, 32, 37), (20, 32, 28), (11, 24, 18), + (8, 20, 18), (8, 16, 18), (12, 16, 18), (12, 16, 18), + (15, 20, 18), (16, 20, 28), (20, 28, 37), (23, 32, 47), + (27, 32, 56), (28, 28, 47), (27, 28, 37), (23, 20, 28), + (19, 16, 18), (15, 16, 18), (16, 16, 9), (12, 12, 0), + (8, 12, 0), (8, 8, 0), (8, 8, 9), (8, 8, 9), + (8, 8, 9), (8, 12, 9), (11, 12, 18), (11, 12, 18), + (11, 12, 18), (11, 12, 18), (12, 16, 18), (16, 24, 18), + (24, 32, 18), (28, 44, 37), (40, 52, 37), (48, 56, 66), + (48, 56, 75), (52, 68, 85), (56, 77, 113), (73, 97, 132), + (84, 109, 160), (100, 113, 160), (100, 117, 169), (101, 117, 160), + (104, 129, 151), (113, 129, 151), (104, 125, 170), (104, 125, 170), + (124, 137, 198), (104, 116, 170), (88, 100, 132), (68, 77, 103), + (52, 64, 94), (40, 56, 85), (28, 44, 75), (28, 36, 56), + (24, 32, 47), (24, 28, 28), (24, 24, 18), (20, 24, 18), + (15, 20, 18), (12, 16, 18), (12, 16, 18), (12, 16, 9), + (12, 12, 9), (12, 12, 9), (11, 12, 9), (11, 16, 9), + (12, 16, 9), (16, 16, 9), (16, 20, 0), (16, 24, 0), + (20, 20, 9), (24, 20, 18), (28, 24, 18), (32, 32, 28), + (32, 36, 47), (32, 40, 56), (32, 36, 66), (28, 36, 75), + (28, 36, 75), (28, 36, 75), (28, 36, 75), (28, 36, 66), + (24, 36, 66), (24, 36, 75), (20, 36, 85), (20, 36, 85), + (24, 36, 75), (24, 32, 66), (24, 32, 56), (23, 24, 28), + (20, 20, 18), (16, 16, 9), (16, 16, 9), (16, 20, 9), + (16, 20, 9), (19, 20, 9), (20, 24, 18), (20, 24, 18), + (20, 24, 18), (16, 16, 18), (15, 16, 18), (12, 12, 18), + (11, 12, 9), (11, 12, 9), (8, 12, 9), (12, 8, 9), + (8, 8, 9), (8, 8, 9), (4, 4, 9), (4, 4, 9), + (7, 0, 18), (3, 4, 18), (3, 8, 18), (3, 4, 9), + (4, 4, 9), (8, 8, 9), (8, 8, 9), (12, 12, 9), + (16, 12, 9), (16, 12, 9), (16, 16, 9), (19, 20, 9), + (20, 28, 18), (24, 32, 28), (32, 40, 37), (36, 44, 56), + (56, 68, 75), (84, 101, 113), (117, 125, 151), (149, 165, 188), + (157, 177, 216), (181, 189, 235), (193, 206, 216), (198, 202, 198), + (149, 177, 197), (141, 161, 188), (108, 146, 150), (92, 108, 141), + (68, 73, 113), (56, 64, 103), (48, 56, 94), (36, 52, 85), + (28, 40, 85), (32, 40, 85), (28, 36, 85), (32, 44, 85), + (36, 56, 94), (48, 68, 113), (52, 73, 132), (52, 73, 132), + (48, 73, 141), (56, 72, 141), (64, 81, 141), (73, 93, 141), + (76, 92, 132), (60, 77, 132), (56, 64, 132), (48, 48, 113), + (36, 40, 85), (32, 36, 75), (31, 32, 56), (23, 28, 37), + (19, 20, 28), (11, 20, 18), (7, 16, 9), (7, 16, 9), + (7, 12, 9), (7, 12, 9), (7, 8, 9), (4, 8, 0), + (4, 4, 0), (4, 4, 0), (4, 4, 0), (4, 4, 0), + (7, 8, 9), (8, 12, 9), (8, 16, 9), (11, 16, 18), + (12, 20, 18), (19, 24, 28), (20, 32, 47), (20, 36, 66), + (20, 36, 85), (20, 36, 85), (24, 32, 85), (24, 32, 85), + (23, 28, 85), (19, 28, 85), (20, 32, 85), (23, 32, 85), + (24, 32, 85), (31, 32, 94), (28, 36, 85), (24, 36, 85), + (27, 28, 66), (24, 28, 47), (23, 24, 28), (15, 16, 18) + ), + +// 27 afternoon-beach +((182, 162, 170), (190, 157, 132), (178, 136, 113), (174, 107, 75), + (162, 124, 85), (190, 160, 94), (219, 197, 103), (230, 210, 113), + (254, 245, 131), (254, 254, 159), (254, 254, 178), (250, 254, 206), + (254, 254, 216), (254, 254, 197), (250, 254, 169), (234, 222, 141), + (219, 193, 160), (202, 189, 170), (190, 185, 169), (181, 169, 179), + (181, 157, 179), (169, 153, 188), (173, 157, 198), (161, 149, 188), + (165, 149, 179), (162, 146, 170), (145, 141, 151), (108, 108, 141), + (112, 112, 103), (129, 129, 103), (149, 124, 103), (173, 149, 94), + (206, 149, 94), (234, 168, 103), (250, 192, 112), (250, 200, 112), + (242, 217, 122), (242, 229, 122), (254, 237, 112), (246, 229, 112), + (246, 209, 103), (254, 204, 93), (250, 196, 93), (238, 152, 94), + (194, 127, 75), (186, 111, 66), (190, 127, 75), (222, 168, 94), + (254, 204, 121), (254, 245, 169), (250, 254, 206), (250, 254, 225), + (222, 213, 225), (210, 193, 207), (238, 197, 169), (250, 233, 150), + (254, 249, 159), (254, 254, 169), (254, 254, 197), (250, 254, 216), + (254, 254, 197), (254, 254, 169), (254, 254, 159), (254, 241, 140), + (254, 221, 121), (250, 209, 112), (246, 209, 112), (254, 217, 112), + (254, 221, 121), (250, 225, 140), (238, 197, 169), (226, 185, 207), + (206, 185, 207), (205, 177, 207), (201, 185, 216), (189, 181, 226), + (189, 181, 216), (177, 165, 216), (173, 165, 207), (185, 169, 188), + (202, 165, 188), (219, 181, 160), (230, 184, 141), (234, 180, 131), + (230, 180, 122), (210, 181, 141), (210, 169, 151), (202, 161, 160), + (174, 154, 170), (177, 149, 179), (170, 150, 170), (169, 153, 179), + (166, 162, 170), (161, 165, 151), (174, 162, 151), (178, 157, 141), + (170, 157, 141), (158, 145, 113), (141, 116, 94), (125, 96, 75), + (97, 92, 47), (77, 77, 47), (73, 73, 47), (64, 68, 47), + (68, 64, 47), (64, 60, 47), (60, 52, 47), (56, 48, 47), + (48, 36, 47), (48, 40, 37), (52, 40, 37), (52, 39, 37), + (52, 39, 37), (64, 39, 37), (64, 44, 37), (72, 56, 37), + (64, 60, 37), (68, 60, 37), (84, 56, 56), (117, 76, 65), + (146, 88, 75), (145, 92, 75), (149, 99, 75), (146, 108, 85), + (145, 104, 103), (162, 108, 104), (158, 116, 94), (169, 115, 104), + (157, 129, 94), (162, 153, 103), (182, 186, 113), (222, 214, 122), + (246, 246, 131), (250, 254, 169), (254, 254, 197), (254, 254, 216), + (254, 254, 225), (234, 226, 254), (209, 201, 226), (206, 193, 207), + (210, 177, 198), (181, 165, 179), (162, 141, 160), (145, 121, 122), + (145, 100, 113), (121, 96, 94), (104, 93, 94), (85, 80, 75), + (89, 85, 75), (97, 93, 84), (100, 96, 94), (101, 105, 84), + (121, 121, 103), (137, 129, 113), (150, 150, 103), (182, 152, 103), + (206, 177, 113), (230, 197, 94), (238, 180, 84), (238, 168, 93), + (226, 172, 84), (189, 152, 84), (182, 112, 66), (166, 99, 66), + (133, 80, 56), (88, 59, 47), (68, 48, 47), (64, 44, 47), + (52, 39, 37), (48, 40, 28), (48, 35, 28), (52, 39, 28), + (48, 44, 37), (56, 48, 37), (56, 48, 47), (68, 52, 56), + (76, 64, 56), (85, 76, 65), (113, 88, 75), (117, 92, 84), + (125, 96, 84), (125, 96, 84), (125, 92, 84), (133, 88, 84), + (117, 88, 75), (92, 72, 56), (81, 68, 56), (72, 68, 56), + (68, 68, 56), (76, 76, 66), (81, 81, 75), (85, 77, 75), + (85, 68, 65), (72, 56, 66), (68, 64, 56), (64, 60, 66), + (64, 56, 56), (60, 48, 56), (60, 52, 56), (60, 56, 56), + (60, 56, 47), (68, 60, 47), (68, 64, 56), (73, 73, 56), + (81, 81, 66), (85, 96, 75), (97, 105, 75), (105, 109, 56), + (125, 117, 66), (125, 129, 66), (146, 141, 85), (170, 169, 85), + (198, 202, 113), (234, 205, 112), (250, 192, 112), (238, 172, 103), + (234, 152, 94), (190, 119, 66), (174, 106, 56), (166, 111, 66), + (141, 108, 75), (125, 112, 85), (108, 113, 103), (113, 129, 103), + (133, 125, 122), (182, 145, 160), (202, 161, 179), (210, 193, 179), + (254, 241, 197), (254, 254, 216), (254, 254, 216), (254, 254, 197), + (254, 254, 169), (254, 254, 159), (254, 245, 150), (254, 245, 140), + (250, 229, 131), (226, 206, 122), (182, 182, 113), (162, 141, 94), + (149, 128, 65), (145, 116, 75), (137, 100, 84), (125, 108, 85), + (129, 96, 84), (125, 112, 75), (117, 109, 84), (105, 109, 75), + (97, 109, 75), (101, 105, 75), (121, 112, 66), (141, 112, 75), + (149, 116, 85), (162, 141, 103), (194, 169, 122), (218, 201, 132) + ), + +// 28 dim-beach +((27, 28, 28), (48, 36, 37), (68, 48, 37), (72, 60, 37), + (68, 68, 37), (56, 60, 37), (44, 44, 28), (36, 36, 28), + (32, 32, 28), (28, 32, 28), (28, 28, 28), (28, 28, 28), + (28, 32, 28), (28, 36, 28), (32, 40, 37), (48, 60, 56), + (56, 73, 66), (60, 81, 75), (80, 93, 75), (92, 137, 141), + (100, 170, 160), (133, 185, 188), (153, 194, 188), (141, 182, 169), + (117, 162, 131), (109, 145, 122), (85, 113, 84), (69, 85, 56), + (64, 68, 47), (56, 56, 37), (40, 40, 28), (32, 36, 28), + (31, 32, 28), (28, 32, 28), (28, 32, 28), (32, 32, 28), + (36, 36, 28), (52, 44, 28), (72, 56, 18), (97, 60, 28), + (121, 84, 28), (129, 112, 37), (150, 107, 37), (141, 100, 37), + (129, 84, 28), (109, 72, 28), (64, 73, 28), (48, 44, 28), + (36, 40, 18), (36, 40, 18), (52, 56, 37), (64, 64, 47), + (68, 76, 56), (97, 88, 56), (109, 100, 56), (109, 100, 56), + (93, 97, 66), (68, 76, 66), (48, 76, 75), (48, 56, 56), + (40, 36, 37), (28, 32, 37), (28, 32, 37), (27, 32, 37), + (28, 32, 37), (32, 32, 28), (32, 32, 28), (28, 32, 28), + (28, 32, 28), (28, 28, 28), (27, 28, 28), (24, 28, 18), + (24, 28, 18), (23, 28, 18), (20, 28, 18), (20, 28, 28), + (19, 28, 28), (19, 28, 28), (16, 24, 28), (19, 28, 28), + (20, 28, 28), (24, 32, 28), (24, 36, 28), (24, 40, 28), + (24, 36, 37), (24, 32, 37), (32, 36, 37), (52, 60, 47), + (68, 77, 47), (105, 88, 46), (133, 116, 37), (166, 140, 37), + (182, 153, 103), (214, 206, 132), (222, 218, 169), (230, 234, 188), + (242, 242, 197), (242, 241, 197), (230, 226, 178), (246, 196, 93), + (242, 184, 74), (226, 156, 56), (210, 164, 56), (222, 160, 56), + (214, 156, 47), (222, 163, 37), (222, 152, 37), (214, 157, 37), + (186, 123, 37), (182, 114, 47), (174, 111, 47), (149, 99, 56), + (121, 92, 56), (101, 113, 75), (125, 170, 122), (154, 174, 160), + (185, 202, 188), (198, 218, 198), (169, 198, 188), (141, 178, 169), + (104, 154, 150), (52, 109, 151), (44, 89, 122), (40, 56, 75), + (20, 48, 56), (24, 36, 37), (24, 32, 28), (24, 32, 28), + (24, 32, 28), (24, 32, 28), (27, 32, 28), (28, 32, 28), + (28, 36, 28), (32, 40, 28), (40, 56, 47), (48, 60, 56), + (48, 64, 56), (56, 64, 56), (56, 64, 56), (80, 68, 56), + (92, 60, 46), (113, 96, 47), (150, 111, 56), (153, 128, 66), + (170, 166, 132), (210, 202, 160), (226, 226, 188), (246, 242, 197), + (250, 241, 206), (234, 230, 197), (226, 222, 188), (194, 189, 141), + (153, 145, 103), (105, 101, 66), (73, 77, 56), (60, 64, 47), + (44, 40, 37), (32, 32, 37), (27, 28, 37), (24, 24, 37), + (24, 28, 28), (24, 28, 28), (24, 28, 28), (27, 32, 28), + (31, 32, 28), (32, 36, 28), (40, 48, 37), (48, 64, 47), + (52, 73, 47), (56, 72, 56), (60, 68, 47), (68, 76, 56), + (93, 85, 47), (113, 96, 47), (105, 80, 47), (101, 72, 46), + (104, 72, 56), (97, 76, 46), (92, 68, 37), (89, 76, 37), + (88, 72, 47), (68, 73, 47), (48, 64, 37), (36, 40, 28), + (32, 36, 28), (28, 36, 28), (28, 32, 28), (28, 32, 18), + (32, 28, 18), (28, 28, 28), (28, 28, 28), (24, 28, 28), + (23, 28, 28), (24, 28, 28), (24, 28, 28), (24, 28, 28), + (24, 32, 28), (27, 36, 37), (28, 36, 37), (32, 60, 56), + (48, 64, 56), (48, 68, 56), (52, 73, 56), (52, 72, 56), + (48, 64, 56), (48, 60, 56), (52, 56, 47), (44, 40, 37), + (36, 36, 28), (36, 32, 28), (36, 36, 28), (44, 52, 37), + (60, 60, 47), (60, 64, 47), (68, 73, 56), (77, 84, 56), + (93, 97, 56), (93, 101, 56), (97, 101, 66), (97, 97, 56), + (97, 101, 66), (97, 109, 66), (88, 137, 112), (97, 154, 141), + (108, 158, 141), (116, 166, 160), (125, 182, 160), (125, 178, 141), + (141, 182, 132), (166, 157, 113), (174, 136, 75), (198, 140, 56), + (210, 149, 56), (219, 172, 66), (210, 206, 151), (210, 222, 198), + (214, 230, 207), (222, 230, 207), (226, 226, 197), (206, 206, 151), + (166, 162, 122), (125, 125, 75), (89, 101, 66), (60, 73, 47), + (40, 44, 28), (28, 32, 18), (24, 32, 18), (20, 32, 18), + (24, 32, 28), (28, 36, 37), (36, 40, 47), (36, 52, 66), + (40, 80, 85), (56, 85, 84), (88, 142, 141), (129, 182, 160) + ), + +// 29 cloudy-brick +((202, 206, 188), (178, 186, 160), (153, 157, 141), (129, 141, 122), + (112, 129, 113), (96, 125, 122), (104, 146, 141), (112, 158, 169), + (137, 181, 188), (157, 222, 225), (153, 218, 235), (132, 210, 235), + (100, 198, 216), (84, 154, 188), (60, 117, 122), (48, 80, 94), + (40, 60, 75), (28, 48, 56), (40, 44, 37), (24, 32, 28), + (48, 56, 37), (80, 35, 28), (76, 35, 37), (68, 35, 37), + (68, 39, 28), (68, 39, 37), (68, 72, 56), (56, 68, 47), + (68, 72, 56), (48, 72, 47), (60, 72, 66), (77, 97, 85), + (84, 113, 103), (100, 133, 132), (133, 162, 160), (173, 190, 188), + (189, 210, 198), (193, 218, 207), (193, 218, 216), (193, 218, 216), + (173, 210, 225), (132, 201, 225), (104, 161, 188), (84, 141, 169), + (80, 121, 141), (76, 109, 122), (93, 104, 84), (105, 92, 66), + (129, 80, 56), (145, 95, 28), (153, 95, 28), (174, 111, 66), + (226, 167, 84), (234, 155, 65), (194, 119, 37), (178, 63, 9), + (170, 33, 9), (129, 38, 18), (125, 63, 37), (153, 76, 28), + (170, 107, 56), (246, 188, 74), (246, 196, 103), (250, 217, 159), + (226, 213, 188), (230, 234, 216), (230, 237, 225), (230, 246, 235), + (218, 246, 244), (218, 242, 235), (209, 238, 225), (210, 230, 225), + (206, 222, 226), (197, 218, 216), (189, 218, 207), (185, 210, 207), + (153, 169, 188), (105, 150, 160), (80, 125, 141), (68, 101, 122), + (56, 93, 113), (52, 97, 122), (68, 105, 113), (92, 129, 132), + (129, 150, 141), (185, 177, 141), (242, 196, 122), (202, 165, 132), + (182, 115, 75), (170, 59, 28), (153, 59, 18), (125, 42, 28), + (113, 43, 28), (92, 35, 37), (80, 39, 37), (64, 64, 66), + (52, 76, 85), (56, 89, 84), (56, 81, 85), (64, 85, 94), + (73, 97, 94), (85, 109, 94), (100, 109, 94), (121, 145, 113), + (129, 166, 141), (146, 186, 169), (177, 210, 197), (189, 218, 207), + (197, 218, 226), (197, 222, 226), (206, 222, 226), (217, 226, 225), + (222, 234, 225), (218, 234, 226), (214, 234, 216), (201, 234, 216), + (201, 230, 216), (197, 230, 225), (197, 230, 225), (193, 230, 225), + (193, 230, 226), (193, 230, 226), (189, 242, 235), (201, 242, 244), + (213, 237, 244), (205, 234, 235), (201, 238, 235), (201, 234, 235), + (193, 230, 235), (193, 230, 226), (193, 226, 226), (189, 226, 225), + (181, 230, 225), (161, 198, 207), (108, 166, 178), (92, 153, 160), + (73, 126, 150), (88, 137, 150), (89, 142, 151), (125, 162, 151), + (149, 182, 170), (181, 202, 188), (189, 218, 207), (194, 226, 216), + (201, 230, 225), (205, 230, 225), (213, 234, 225), (214, 234, 225), + (214, 230, 216), (206, 230, 207), (194, 218, 198), (166, 190, 170), + (145, 149, 132), (121, 109, 84), (117, 104, 75), (141, 113, 103), + (166, 141, 132), (182, 174, 160), (206, 214, 179), (218, 238, 207), + (246, 249, 225), (250, 254, 235), (254, 254, 244), (254, 254, 254), + (254, 254, 254), (250, 254, 254), (254, 254, 254), (254, 254, 244), + (250, 250, 244), (246, 250, 244), (242, 250, 244), (230, 245, 235), + (226, 230, 225), (214, 222, 216), (226, 238, 216), (210, 222, 216), + (206, 222, 216), (201, 230, 226), (205, 226, 216), (206, 222, 207), + (198, 222, 207), (202, 222, 207), (201, 226, 216), (197, 222, 216), + (198, 222, 207), (198, 222, 198), (202, 210, 179), (174, 198, 169), + (153, 185, 188), (157, 190, 179), (181, 202, 188), (198, 210, 198), + (202, 210, 198), (193, 218, 207), (198, 226, 207), (206, 230, 207), + (206, 230, 207), (202, 230, 216), (202, 226, 216), (197, 218, 216), + (193, 218, 226), (185, 221, 235), (185, 230, 244), (181, 234, 244), + (173, 234, 244), (173, 230, 244), (116, 207, 235), (76, 194, 216), + (72, 185, 206), (60, 170, 207), (76, 153, 169), (68, 121, 122), + (76, 105, 94), (60, 85, 75), (73, 81, 75), (77, 77, 56), + (76, 68, 66), (73, 89, 85), (97, 80, 65), (80, 64, 47), + (96, 43, 37), (125, 38, 28), (125, 42, 28), (100, 47, 47), + (92, 72, 75), (68, 81, 85), (68, 85, 94), (84, 93, 103), + (72, 113, 122), (100, 149, 141), (133, 170, 169), (185, 202, 207), + (206, 222, 216), (226, 234, 225), (238, 250, 244), (246, 254, 244), + (250, 254, 244), (250, 250, 244), (250, 254, 244), (250, 254, 244), + (254, 254, 244), (250, 254, 235), (250, 254, 235), (250, 254, 225), + (254, 254, 216), (250, 249, 216), (210, 222, 207), (218, 181, 169), + (214, 185, 150), (182, 116, 103), (129, 120, 56), (129, 91, 56), + (125, 88, 65), (105, 88, 84), (129, 129, 113), (149, 161, 160) + ), + +// 30 burning-wood +((80, 35, 28), (92, 39, 28), (97, 39, 28), (96, 39, 37), + (97, 39, 28), (80, 43, 37), (68, 43, 37), (84, 39, 37), + (76, 43, 47), (72, 48, 56), (60, 43, 47), (44, 44, 47), + (36, 32, 37), (31, 28, 37), (27, 28, 37), (28, 32, 37), + (40, 28, 37), (48, 32, 37), (52, 31, 37), (56, 27, 28), + (68, 35, 28), (84, 35, 28), (96, 30, 28), (104, 34, 18), + (105, 30, 18), (97, 34, 18), (88, 34, 18), (76, 35, 28), + (68, 39, 28), (64, 43, 18), (60, 48, 37), (52, 52, 37), + (48, 44, 37), (32, 40, 28), (32, 32, 28), (27, 32, 28), + (28, 28, 28), (28, 28, 18), (31, 28, 18), (31, 28, 18), + (35, 28, 18), (36, 32, 18), (52, 35, 18), (56, 31, 18), + (76, 31, 18), (96, 30, 18), (113, 30, 18), (133, 26, 18), + (145, 26, 18), (154, 22, 19), (162, 22, 18), (174, 25, 0), + (178, 25, 0), (178, 46, 9), (190, 87, 18), (214, 105, 18), + (219, 97, 0), (198, 87, 18), (178, 72, 9), (162, 37, 0), + (158, 22, 0), (158, 22, 9), (154, 22, 0), (146, 22, 0), + (146, 26, 9), (137, 26, 9), (117, 30, 9), (105, 30, 18), + (92, 23, 18), (88, 23, 28), (92, 39, 28), (88, 39, 28), + (80, 52, 47), (72, 56, 56), (84, 68, 65), (73, 73, 75), + (64, 60, 56), (52, 56, 56), (36, 52, 47), (32, 36, 37), + (36, 32, 28), (40, 31, 28), (52, 31, 28), (48, 31, 18), + (60, 27, 18), (76, 31, 18), (88, 31, 18), (100, 30, 9), + (113, 34, 9), (121, 30, 9), (133, 30, 18), (125, 39, 18), + (121, 31, 28), (121, 38, 28), (109, 35, 37), (109, 34, 28), + (105, 31, 28), (101, 34, 28), (84, 35, 37), (72, 31, 37), + (68, 27, 37), (56, 27, 28), (48, 23, 28), (40, 24, 28), + (36, 27, 28), (35, 28, 28), (35, 28, 28), (36, 32, 18), + (48, 31, 18), (80, 43, 18), (101, 64, 28), (141, 76, 28), + (182, 95, 28), (214, 123, 37), (234, 163, 56), (234, 176, 84), + (234, 176, 75), (222, 157, 47), (222, 131, 47), (210, 110, 28), + (222, 79, 37), (194, 38, 18), (202, 14, 9), (206, 26, 19), + (186, 30, 9), (182, 30, 9), (186, 72, 9), (174, 83, 9), + (161, 79, 18), (141, 59, 9), (129, 64, 28), (121, 76, 47), + (121, 63, 56), (133, 46, 37), (125, 47, 28), (129, 43, 28), + (121, 47, 28), (113, 47, 28), (125, 47, 18), (121, 47, 28), + (109, 47, 18), (100, 43, 28), (92, 39, 28), (76, 31, 28), + (56, 31, 28), (48, 31, 37), (40, 27, 28), (35, 28, 28), + (32, 28, 28), (36, 31, 28), (44, 36, 28), (56, 35, 28), + (68, 35, 28), (76, 35, 37), (80, 47, 28), (88, 39, 28), + (88, 43, 37), (101, 43, 28), (105, 39, 28), (109, 43, 28), + (109, 60, 46), (97, 72, 56), (105, 88, 75), (113, 104, 84), + (133, 100, 94), (165, 91, 56), (165, 87, 47), (162, 71, 37), + (166, 59, 28), (162, 63, 18), (149, 64, 18), (150, 59, 18), + (146, 60, 9), (141, 33, 0), (129, 59, 0), (121, 59, 18), + (133, 64, 18), (149, 64, 28), (154, 80, 37), (174, 83, 18), + (182, 91, 18), (198, 96, 18), (202, 110, 28), (202, 106, 37), + (202, 106, 37), (198, 95, 47), (178, 86, 28), (133, 68, 28), + (113, 59, 28), (92, 43, 18), (76, 35, 28), (60, 35, 28), + (56, 31, 28), (64, 31, 28), (68, 27, 28), (72, 31, 28), + (76, 31, 28), (76, 35, 28), (80, 39, 18), (84, 31, 28), + (85, 35, 18), (81, 31, 18), (80, 31, 18), (76, 27, 28), + (64, 27, 28), (56, 27, 28), (44, 27, 28), (36, 28, 28), + (31, 28, 28), (27, 24, 28), (23, 24, 28), (27, 24, 28), + (31, 28, 28), (32, 28, 28), (35, 28, 28), (44, 31, 28), + (68, 31, 28), (88, 43, 28), (109, 60, 28), (133, 64, 28), + (166, 91, 28), (210, 140, 66), (214, 210, 188), (230, 180, 113), + (238, 176, 93), (219, 173, 85), (222, 164, 66), (202, 131, 47), + (174, 103, 47), (141, 100, 47), (121, 88, 66), (80, 60, 47), + (60, 43, 37), (48, 27, 37), (44, 27, 37), (36, 28, 28), + (32, 28, 28), (31, 28, 28), (27, 28, 28), (27, 28, 28), + (24, 28, 28), (27, 28, 28), (27, 28, 28), (31, 28, 28), + (32, 28, 28), (32, 36, 37), (44, 40, 37), (56, 31, 37), + (68, 35, 56), (89, 60, 47), (117, 64, 37), (121, 56, 37), + (125, 56, 47), (109, 47, 37), (105, 47, 37), (92, 27, 37) + ), + +// 31 aquatic-garden +((146, 80, 9), (133, 92, 28), (133, 108, 56), (153, 112, 75), + (141, 125, 84), (133, 113, 65), (105, 76, 56), (80, 72, 37), + (60, 68, 37), (52, 60, 47), (40, 44, 47), (36, 36, 37), + (32, 28, 37), (32, 28, 28), (32, 24, 28), (27, 24, 37), + (27, 28, 37), (28, 32, 37), (40, 44, 47), (60, 64, 56), + (77, 89, 66), (92, 105, 66), (117, 133, 85), (125, 158, 103), + (166, 177, 103), (149, 178, 122), (157, 157, 113), (125, 133, 103), + (109, 96, 94), (81, 93, 75), (64, 85, 75), (52, 68, 56), + (40, 56, 47), (40, 44, 37), (36, 36, 28), (32, 32, 28), + (28, 28, 28), (24, 28, 28), (23, 28, 28), (28, 32, 28), + (36, 36, 28), (40, 40, 28), (56, 39, 28), (72, 48, 28), + (84, 51, 28), (80, 56, 28), (84, 64, 28), (72, 64, 28), + (68, 39, 28), (56, 43, 28), (36, 32, 18), (28, 28, 18), + (24, 28, 28), (23, 24, 28), (20, 20, 28), (23, 20, 28), + (19, 20, 28), (19, 20, 28), (24, 24, 28), (31, 24, 28), + (31, 28, 28), (35, 28, 28), (48, 35, 28), (64, 43, 28), + (72, 52, 37), (76, 56, 37), (72, 52, 37), (56, 39, 28), + (48, 31, 28), (36, 28, 28), (32, 28, 28), (28, 28, 28), + (28, 32, 28), (28, 32, 28), (28, 32, 28), (24, 32, 28), + (24, 32, 28), (24, 32, 28), (24, 32, 28), (24, 32, 28), + (24, 32, 28), (28, 36, 28), (36, 40, 28), (44, 48, 37), + (64, 64, 47), (81, 97, 66), (96, 121, 103), (88, 146, 150), + (96, 158, 169), (100, 158, 179), (100, 150, 160), (100, 129, 141), + (85, 109, 113), (68, 93, 85), (44, 60, 66), (36, 44, 47), + (24, 40, 37), (24, 36, 37), (23, 32, 28), (20, 24, 18), + (24, 24, 18), (23, 20, 9), (24, 32, 18), (36, 44, 18), + (44, 48, 37), (52, 60, 47), (56, 81, 75), (64, 97, 85), + (68, 101, 94), (85, 113, 85), (96, 117, 94), (84, 84, 94), + (68, 80, 85), (64, 73, 75), (56, 56, 56), (52, 56, 47), + (40, 44, 37), (36, 36, 37), (35, 32, 28), (28, 24, 18), + (32, 28, 28), (32, 32, 18), (52, 39, 18), (60, 35, 18), + (84, 47, 37), (81, 55, 37), (80, 72, 56), (64, 76, 66), + (52, 64, 75), (48, 73, 85), (52, 81, 94), (60, 89, 122), + (64, 101, 122), (88, 105, 122), (89, 117, 113), (93, 117, 113), + (100, 117, 113), (100, 125, 103), (104, 125, 103), (109, 129, 85), + (96, 105, 75), (93, 101, 66), (89, 93, 66), (105, 105, 75), + (117, 125, 56), (121, 121, 75), (117, 100, 56), (109, 100, 47), + (89, 93, 56), (84, 93, 66), (73, 85, 66), (56, 64, 47), + (44, 48, 47), (40, 32, 37), (44, 31, 37), (40, 44, 37), + (56, 52, 28), (68, 68, 37), (64, 56, 37), (68, 56, 37), + (64, 48, 47), (48, 52, 47), (40, 40, 47), (32, 36, 37), + (32, 36, 28), (32, 36, 28), (36, 40, 37), (44, 52, 47), + (52, 60, 66), (64, 85, 85), (84, 109, 103), (100, 121, 122), + (104, 145, 151), (116, 158, 141), (112, 150, 151), (108, 129, 132), + (113, 105, 103), (89, 101, 75), (69, 93, 56), (68, 76, 37), + (68, 68, 28), (52, 48, 28), (40, 40, 28), (36, 36, 28), + (32, 36, 28), (32, 32, 28), (32, 32, 28), (32, 32, 28), + (32, 36, 28), (32, 40, 37), (28, 44, 47), (36, 68, 66), + (48, 85, 94), (44, 109, 160), (88, 150, 169), (113, 178, 159), + (116, 170, 169), (133, 173, 179), (92, 154, 197), (36, 93, 170), + (40, 93, 160), (36, 73, 103), (48, 56, 75), (44, 48, 56), + (36, 36, 37), (32, 32, 28), (27, 28, 18), (24, 28, 18), + (20, 32, 18), (24, 28, 18), (19, 28, 18), (19, 24, 28), + (20, 24, 28), (20, 28, 28), (23, 28, 28), (20, 32, 28), + (20, 28, 28), (24, 28, 28), (28, 28, 28), (28, 28, 28), + (28, 32, 28), (32, 32, 28), (36, 32, 37), (40, 36, 47), + (52, 48, 66), (60, 77, 94), (92, 121, 132), (125, 166, 160), + (145, 177, 179), (161, 190, 198), (169, 198, 188), (174, 186, 170), + (166, 186, 170), (145, 170, 132), (141, 162, 85), (129, 133, 85), + (137, 99, 47), (137, 72, 9), (125, 46, 0), (109, 47, 18), + (85, 51, 28), (105, 80, 28), (93, 64, 47), (104, 72, 75), + (125, 121, 94), (129, 137, 113), (108, 150, 122), (96, 146, 131), + (88, 137, 122), (68, 105, 141), (52, 72, 94), (28, 52, 56), + (23, 32, 47), (31, 28, 47), (32, 40, 47), (40, 52, 56) + ), + +// 32 no-name +((24, 24, 9), (24, 28, 9), (24, 28, 18), (28, 28, 18), + (28, 28, 28), (27, 28, 28), (24, 28, 28), (24, 28, 28), + (20, 28, 28), (19, 28, 18), (24, 28, 9), (23, 24, 9), + (20, 24, 18), (19, 20, 18), (20, 20, 18), (19, 20, 28), + (15, 24, 28), (11, 20, 18), (12, 16, 18), (12, 12, 9), + (16, 20, 18), (20, 24, 28), (24, 24, 28), (27, 32, 28), + (32, 36, 28), (32, 44, 28), (32, 52, 37), (48, 60, 37), + (76, 68, 47), (101, 80, 37), (150, 96, 28), (194, 102, 28), + (210, 106, 37), (214, 110, 37), (214, 127, 37), (210, 127, 37), + (206, 132, 47), (214, 156, 47), (226, 168, 47), (246, 191, 46), + (246, 208, 46), (254, 220, 56), (254, 207, 56), (250, 191, 46), + (250, 187, 46), (238, 179, 46), (238, 159, 46), (234, 148, 46), + (222, 136, 37), (218, 148, 37), (222, 179, 47), (230, 200, 37), + (227, 230, 46), (246, 225, 46), (226, 218, 47), (215, 192, 56), + (165, 149, 66), (101, 109, 47), (72, 72, 28), (56, 60, 28), + (40, 44, 28), (32, 32, 18), (28, 28, 18), (24, 32, 18), + (24, 32, 18), (24, 32, 18), (32, 32, 28), (32, 36, 28), + (40, 44, 37), (52, 48, 47), (64, 48, 56), (76, 64, 47), + (89, 64, 47), (109, 80, 56), (154, 96, 56), (190, 107, 47), + (186, 106, 47), (174, 123, 37), (149, 111, 37), (109, 84, 46), + (85, 80, 47), (81, 76, 56), (64, 77, 66), (56, 64, 66), + (48, 52, 56), (32, 36, 47), (28, 36, 37), (28, 32, 28), + (28, 32, 28), (35, 32, 18), (44, 40, 18), (72, 48, 28), + (101, 55, 37), (133, 72, 47), (186, 102, 47), (186, 91, 56), + (149, 84, 56), (109, 80, 56), (137, 99, 47), (162, 108, 47), + (178, 136, 56), (186, 148, 56), (210, 189, 75), (234, 209, 103), + (234, 205, 103), (234, 197, 103), (238, 180, 65), (210, 148, 56), + (226, 115, 65), (222, 115, 75), (198, 110, 66), (182, 110, 47), + (125, 80, 37), (105, 59, 37), (68, 52, 28), (44, 40, 28), + (32, 32, 18), (28, 28, 18), (24, 28, 18), (20, 24, 18), + (23, 24, 18), (28, 32, 28), (40, 40, 37), (52, 48, 37), + (72, 60, 37), (96, 72, 37), (145, 99, 56), (194, 102, 56), + (214, 123, 85), (230, 180, 103), (254, 245, 131), (254, 254, 140), + (250, 254, 197), (234, 234, 188), (190, 173, 151), (129, 146, 141), + (105, 137, 84), (85, 101, 47), (93, 77, 46), (109, 60, 37), + (121, 76, 37), (149, 108, 47), (182, 119, 47), (178, 140, 56), + (186, 144, 47), (194, 136, 47), (194, 123, 37), (178, 115, 37), + (117, 88, 47), (84, 64, 47), (60, 56, 47), (52, 60, 56), + (52, 64, 47), (60, 68, 56), (73, 81, 75), (116, 141, 141), + (182, 186, 151), (218, 222, 169), (206, 206, 179), (150, 166, 151), + (84, 109, 103), (60, 73, 85), (56, 73, 75), (73, 77, 75), + (85, 93, 65), (97, 113, 66), (129, 141, 75), (166, 157, 113), + (182, 169, 113), (198, 156, 103), (186, 132, 66), (174, 119, 47), + (121, 84, 37), (81, 60, 28), (64, 56, 28), (48, 52, 18), + (44, 44, 28), (40, 40, 37), (32, 36, 37), (32, 36, 37), + (40, 40, 37), (48, 48, 47), (48, 73, 56), (73, 117, 46), + (113, 125, 47), (150, 170, 94), (186, 181, 103), (215, 206, 94), + (246, 233, 74), (250, 249, 84), (254, 233, 84), (254, 241, 74), + (254, 229, 56), (250, 229, 56), (254, 225, 65), (250, 233, 84), + (238, 241, 112), (246, 217, 122), (206, 181, 113), (198, 123, 85), + (202, 119, 66), (194, 127, 56), (198, 131, 56), (194, 136, 66), + (222, 185, 84), (234, 230, 112), (254, 249, 112), (254, 254, 131), + (222, 226, 150), (214, 193, 132), (174, 157, 113), (105, 113, 56), + (77, 84, 56), (52, 68, 47), (44, 52, 37), (36, 40, 28), + (32, 36, 28), (36, 40, 28), (36, 36, 28), (40, 32, 37), + (48, 39, 37), (64, 39, 28), (80, 52, 37), (105, 55, 47), + (165, 84, 56), (194, 98, 47), (198, 106, 47), (202, 131, 56), + (238, 172, 84), (242, 196, 103), (250, 213, 103), (246, 221, 74), + (246, 200, 56), (210, 180, 56), (170, 149, 56), (141, 111, 47), + (93, 92, 47), (84, 72, 47), (64, 68, 28), (56, 64, 28), + (44, 52, 28), (36, 44, 28), (36, 36, 28), (40, 40, 28), + (40, 40, 28), (56, 43, 18), (60, 43, 18), (72, 52, 28), + (96, 64, 46), (117, 84, 65), (170, 123, 66), (170, 132, 66), + (121, 72, 56), (100, 55, 46), (56, 48, 37), (36, 36, 37) + ), + +// 33 fall-quilt +((24, 40, 37), (56, 52, 37), (93, 68, 37), (137, 68, 18), + (174, 76, 18), (190, 102, 9), (190, 94, 18), (178, 75, 18), + (162, 64, 18), (129, 60, 18), (105, 76, 18), (77, 68, 28), + (64, 60, 37), (40, 48, 37), (24, 40, 37), (20, 32, 37), + (19, 32, 37), (15, 32, 37), (15, 32, 37), (20, 36, 47), + (24, 40, 56), (24, 40, 56), (28, 40, 56), (28, 44, 56), + (28, 44, 56), (32, 44, 47), (36, 48, 37), (48, 52, 37), + (76, 68, 37), (81, 73, 37), (109, 80, 37), (137, 80, 28), + (170, 87, 37), (194, 98, 18), (198, 102, 18), (210, 110, 18), + (214, 118, 9), (198, 119, 18), (170, 128, 28), (146, 99, 28), + (117, 80, 28), (85, 72, 37), (68, 52, 37), (40, 40, 37), + (24, 36, 28), (19, 32, 28), (24, 24, 28), (32, 28, 28), + (40, 31, 18), (56, 35, 18), (76, 52, 28), (105, 84, 37), + (133, 96, 37), (194, 144, 56), (214, 197, 141), (214, 202, 179), + (234, 230, 216), (250, 233, 225), (250, 233, 216), (222, 193, 169), + (150, 145, 94), (109, 96, 56), (77, 68, 47), (40, 48, 56), + (36, 44, 56), (36, 40, 56), (32, 36, 56), (28, 40, 56), + (24, 36, 47), (20, 32, 47), (20, 32, 37), (24, 36, 37), + (24, 36, 37), (36, 36, 37), (36, 36, 28), (40, 32, 28), + (40, 31, 28), (48, 31, 28), (68, 47, 28), (109, 39, 28), + (129, 46, 18), (133, 47, 9), (162, 59, 0), (198, 114, 9), + (214, 145, 28), (226, 171, 47), (234, 183, 47), (230, 192, 65), + (222, 165, 65), (194, 144, 47), (145, 112, 47), (113, 88, 47), + (93, 72, 46), (60, 60, 47), (36, 48, 47), (32, 44, 47), + (32, 36, 47), (36, 36, 37), (36, 40, 37), (40, 40, 37), + (40, 44, 28), (48, 52, 28), (76, 68, 37), (93, 76, 37), + (113, 88, 28), (170, 123, 28), (194, 122, 28), (210, 132, 18), + (214, 141, 18), (210, 127, 18), (182, 119, 28), (153, 76, 28), + (137, 64, 18), (121, 55, 9), (93, 51, 18), (80, 64, 37), + (97, 76, 37), (113, 84, 37), (166, 115, 47), (214, 173, 75), + (230, 197, 75), (242, 200, 75), (218, 173, 66), (182, 132, 47), + (113, 88, 46), (77, 72, 37), (56, 48, 37), (44, 40, 37), + (35, 24, 28), (24, 12, 18), (23, 12, 18), (27, 20, 18), + (52, 31, 18), (93, 51, 18), (149, 92, 28), (194, 140, 37), + (226, 180, 75), (242, 213, 84), (250, 213, 112), (254, 212, 121), + (238, 222, 141), (250, 233, 197), (254, 241, 216), (250, 237, 225), + (254, 233, 197), (250, 229, 169), (254, 229, 150), (254, 229, 140), + (250, 221, 131), (246, 217, 112), (250, 209, 84), (250, 208, 74), + (238, 192, 56), (214, 131, 28), (186, 72, 9), (146, 38, 0), + (109, 30, 9), (76, 15, 9), (48, 16, 9), (27, 8, 9), + (23, 24, 28), (24, 32, 37), (24, 36, 37), (24, 40, 47), + (32, 44, 47), (40, 44, 56), (56, 52, 56), (89, 64, 56), + (125, 72, 37), (158, 60, 37), (162, 63, 28), (154, 55, 18), + (141, 38, 18), (133, 26, 9), (113, 22, 0), (89, 11, 9), + (73, 11, 0), (52, 11, 9), (36, 20, 0), (40, 16, 9), + (27, 20, 18), (23, 20, 28), (24, 24, 37), (19, 28, 47), + (15, 28, 47), (16, 32, 47), (12, 28, 37), (16, 28, 37), + (19, 28, 37), (16, 28, 37), (24, 36, 28), (40, 35, 18), + (44, 35, 18), (64, 35, 18), (97, 38, 0), (121, 51, 9), + (125, 42, 9), (121, 38, 9), (93, 31, 18), (52, 40, 28), + (36, 40, 47), (32, 44, 47), (32, 48, 47), (32, 48, 47), + (28, 44, 47), (24, 36, 47), (19, 28, 37), (19, 20, 28), + (20, 12, 18), (24, 4, 9), (16, 8, 0), (16, 12, 0), + (20, 12, 9), (20, 20, 18), (16, 28, 28), (16, 28, 37), + (15, 28, 37), (12, 28, 28), (23, 28, 18), (44, 27, 18), + (56, 19, 18), (80, 19, 28), (113, 30, 18), (129, 51, 9), + (145, 79, 28), (186, 127, 28), (226, 163, 47), (234, 192, 65), + (242, 200, 75), (226, 188, 84), (190, 144, 47), (125, 96, 47), + (97, 80, 56), (60, 60, 47), (36, 48, 47), (24, 40, 47), + (20, 32, 47), (16, 28, 47), (12, 24, 37), (12, 20, 37), + (12, 20, 47), (15, 24, 47), (15, 28, 56), (20, 28, 56), + (20, 36, 56), (28, 44, 56), (36, 48, 47), (52, 48, 47), + (77, 73, 37), (109, 88, 56), (125, 96, 47), (186, 127, 37), + (218, 163, 47), (230, 166, 37), (230, 144, 28), (198, 120, 37) + ), + +// 34 night-blue-sky +((3, 12, 66), (4, 12, 66), (7, 12, 66), (7, 8, 56), + (4, 8, 47), (3, 8, 37), (0, 4, 18), (0, 4, 9), + (0, 4, 0), (0, 4, 0), (0, 4, 0), (0, 4, 0), + (0, 4, 9), (0, 4, 18), (3, 4, 18), (4, 4, 18), + (4, 4, 18), (4, 4, 9), (4, 4, 9), (0, 4, 9), + (0, 0, 0), (0, 0, 0), (0, 4, 0), (0, 4, 0), + (4, 4, 9), (4, 4, 18), (4, 4, 18), (4, 8, 18), + (3, 8, 18), (0, 8, 18), (0, 4, 18), (0, 4, 18), + (0, 4, 18), (0, 4, 28), (0, 8, 37), (0, 12, 47), + (3, 12, 56), (3, 16, 66), (3, 16, 75), (3, 12, 75), + (3, 12, 75), (3, 16, 75), (3, 16, 75), (4, 16, 75), + (4, 12, 75), (3, 12, 75), (3, 12, 75), (3, 12, 75), + (0, 12, 66), (3, 8, 56), (3, 8, 56), (3, 8, 56), + (3, 4, 47), (4, 4, 47), (4, 4, 56), (4, 8, 56), + (4, 8, 56), (3, 8, 56), (3, 8, 47), (0, 8, 37), + (0, 8, 28), (0, 4, 28), (0, 4, 18), (0, 4, 18), + (4, 4, 18), (4, 4, 28), (3, 4, 28), (0, 4, 37), + (0, 4, 37), (0, 4, 37), (0, 4, 37), (0, 4, 28), + (0, 0, 18), (0, 0, 9), (0, 0, 9), (0, 4, 9), + (0, 4, 9), (0, 4, 9), (0, 4, 9), (0, 4, 0), + (0, 4, 0), (0, 4, 9), (0, 4, 9), (0, 8, 18), + (0, 8, 28), (0, 4, 28), (0, 4, 28), (3, 4, 28), + (4, 4, 18), (4, 4, 9), (4, 4, 9), (4, 4, 18), + (4, 4, 28), (7, 8, 37), (4, 12, 47), (8, 12, 56), + (7, 12, 66), (7, 16, 75), (7, 16, 75), (11, 16, 75), + (11, 16, 75), (11, 16, 75), (7, 16, 66), (7, 16, 66), + (7, 16, 66), (4, 16, 66), (3, 16, 66), (4, 12, 56), + (4, 8, 47), (4, 4, 37), (4, 4, 28), (4, 0, 18), + (4, 0, 18), (3, 0, 18), (0, 0, 9), (0, 0, 9), + (0, 4, 9), (0, 4, 9), (0, 4, 9), (0, 0, 9), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 9), + (4, 4, 9), (4, 4, 9), (4, 4, 9), (3, 4, 9), + (0, 4, 9), (0, 4, 9), (0, 0, 9), (0, 0, 9), + (0, 0, 9), (0, 4, 9), (0, 4, 9), (4, 4, 9), + (4, 4, 18), (4, 8, 28), (7, 8, 37), (4, 8, 47), + (3, 8, 47), (3, 8, 47), (0, 4, 47), (0, 4, 37), + (0, 4, 37), (0, 4, 37), (0, 4, 37), (0, 4, 47), + (0, 4, 56), (3, 8, 56), (4, 12, 56), (7, 20, 66), + (7, 24, 66), (3, 20, 66), (0, 16, 56), (0, 8, 56), + (0, 4, 47), (0, 4, 28), (0, 4, 18), (4, 4, 9), + (4, 4, 9), (0, 4, 18), (0, 4, 28), (0, 8, 37), + (0, 8, 56), (3, 12, 66), (7, 12, 75), (8, 16, 75), + (8, 16, 85), (7, 20, 85), (8, 20, 75), (7, 16, 75), + (7, 12, 66), (4, 12, 56), (3, 8, 47), (3, 8, 37), + (0, 8, 37), (0, 4, 28), (0, 4, 28), (0, 4, 28), + (0, 4, 28), (0, 4, 28), (0, 4, 28), (0, 8, 28), + (0, 8, 18), (0, 8, 9), (4, 8, 9), (4, 4, 9), + (4, 4, 18), (4, 8, 37), (4, 12, 56), (3, 12, 66), + (3, 16, 66), (3, 16, 56), (4, 16, 56), (8, 12, 56), + (7, 8, 56), (7, 8, 47), (4, 4, 47), (4, 4, 47), + (4, 4, 47), (3, 8, 56), (3, 12, 56), (3, 12, 66), + (3, 12, 66), (3, 12, 75), (3, 12, 75), (4, 12, 75), + (4, 12, 75), (7, 12, 75), (7, 12, 75), (7, 12, 66), + (4, 8, 56), (3, 4, 47), (0, 0, 28), (0, 0, 18), + (0, 0, 9), (0, 0, 9), (0, 0, 9), (4, 0, 9), + (4, 0, 9), (4, 0, 9), (4, 0, 9), (0, 0, 0), + (0, 0, 0), (0, 4, 0), (0, 4, 0), (0, 4, 9), + (0, 4, 9), (4, 4, 9), (4, 4, 9), (4, 4, 9), + (4, 4, 18), (4, 8, 28), (4, 8, 37), (4, 8, 47), + (4, 8, 56), (4, 12, 56), (3, 12, 47), (0, 16, 47), + (0, 8, 37), (0, 8, 28), (0, 4, 18), (0, 4, 9), + (0, 0, 9), (0, 0, 9), (0, 4, 9), (3, 4, 18), + (4, 8, 28), (4, 12, 37), (4, 16, 47), (4, 16, 47), + (4, 12, 37), (4, 8, 28), (4, 4, 18), (4, 4, 9) + ), + +// 35 shadow-iris +((36, 20, 18), (32, 20, 18), (31, 20, 18), (31, 20, 18), + (32, 24, 18), (35, 28, 18), (36, 32, 18), (28, 24, 18), + (27, 20, 18), (24, 16, 18), (23, 12, 18), (23, 12, 18), + (23, 16, 18), (24, 20, 18), (24, 20, 18), (23, 20, 18), + (19, 20, 18), (16, 20, 18), (19, 16, 9), (20, 12, 9), + (23, 12, 9), (24, 16, 9), (24, 20, 9), (24, 20, 9), + (20, 20, 9), (20, 16, 9), (20, 8, 9), (23, 12, 9), + (24, 12, 9), (28, 16, 9), (28, 20, 9), (28, 20, 9), + (27, 20, 9), (24, 20, 18), (23, 16, 18), (23, 16, 18), + (20, 16, 18), (19, 12, 18), (16, 12, 9), (19, 16, 9), + (20, 16, 9), (23, 16, 9), (28, 16, 9), (35, 16, 18), + (44, 20, 28), (56, 23, 37), (64, 19, 47), (76, 23, 47), + (80, 27, 37), (88, 35, 37), (88, 35, 37), (88, 31, 28), + (68, 31, 28), (52, 23, 28), (44, 20, 28), (36, 20, 28), + (35, 24, 28), (35, 24, 28), (35, 24, 28), (35, 20, 28), + (32, 20, 18), (28, 20, 18), (28, 20, 18), (27, 16, 18), + (27, 16, 18), (28, 16, 18), (31, 16, 18), (35, 16, 28), + (40, 19, 28), (48, 23, 37), (60, 23, 47), (72, 31, 56), + (88, 35, 66), (100, 39, 75), (96, 44, 75), (96, 48, 75), + (100, 40, 84), (100, 40, 75), (84, 27, 56), (72, 23, 47), + (56, 23, 37), (44, 23, 18), (36, 20, 9), (35, 16, 9), + (32, 16, 9), (28, 16, 9), (28, 20, 9), (35, 20, 9), + (35, 24, 9), (35, 24, 18), (35, 20, 18), (35, 20, 18), + (35, 24, 18), (36, 24, 28), (40, 23, 28), (44, 23, 28), + (56, 27, 28), (64, 27, 37), (72, 27, 37), (76, 35, 37), + (64, 31, 37), (52, 23, 28), (52, 23, 28), (52, 23, 28), + (60, 27, 37), (64, 23, 37), (68, 27, 47), (72, 27, 47), + (80, 35, 56), (88, 40, 65), (101, 44, 66), (100, 43, 56), + (84, 35, 56), (68, 39, 56), (40, 40, 47), (39, 28, 37), + (40, 23, 28), (43, 20, 28), (44, 23, 28), (48, 23, 37), + (52, 24, 37), (56, 27, 37), (52, 27, 37), (47, 27, 47), + (39, 24, 47), (35, 24, 37), (35, 20, 37), (28, 24, 28), + (28, 24, 18), (24, 24, 18), (23, 20, 18), (19, 16, 18), + (15, 16, 18), (16, 16, 18), (19, 16, 18), (20, 16, 18), + (23, 20, 18), (23, 20, 18), (23, 16, 18), (20, 12, 18), + (24, 12, 18), (27, 12, 18), (31, 16, 18), (32, 16, 18), + (35, 16, 18), (36, 16, 18), (36, 20, 18), (36, 20, 18), + (40, 20, 18), (40, 19, 18), (44, 20, 28), (56, 23, 37), + (64, 23, 56), (76, 31, 66), (84, 68, 75), (108, 60, 94), + (121, 64, 94), (125, 52, 94), (117, 56, 84), (109, 39, 75), + (104, 40, 75), (104, 43, 65), (109, 35, 66), (100, 35, 56), + (80, 31, 47), (72, 19, 37), (56, 19, 28), (52, 19, 28), + (48, 20, 28), (44, 19, 28), (39, 16, 28), (36, 16, 18), + (32, 16, 9), (36, 20, 9), (35, 20, 18), (40, 24, 18), + (48, 23, 28), (72, 31, 37), (92, 31, 56), (113, 44, 84), + (141, 60, 94), (202, 181, 188), (177, 116, 142), (145, 76, 122), + (145, 76, 113), (137, 80, 113), (129, 56, 94), (125, 56, 84), + (121, 47, 75), (104, 35, 66), (96, 35, 56), (84, 31, 47), + (76, 35, 37), (64, 23, 28), (52, 23, 28), (44, 20, 18), + (39, 16, 18), (31, 16, 18), (24, 16, 18), (20, 16, 18), + (16, 12, 9), (16, 12, 9), (16, 12, 9), (16, 16, 9), + (15, 16, 9), (15, 12, 9), (15, 12, 18), (16, 12, 18), + (16, 12, 18), (19, 12, 18), (20, 12, 18), (24, 12, 18), + (27, 12, 18), (27, 16, 28), (27, 16, 28), (27, 16, 28), + (28, 16, 28), (31, 16, 28), (40, 19, 28), (48, 23, 37), + (52, 23, 47), (56, 27, 47), (64, 35, 47), (72, 31, 47), + (68, 35, 47), (60, 36, 47), (48, 31, 37), (40, 24, 28), + (40, 24, 28), (43, 24, 28), (48, 28, 28), (52, 32, 37), + (64, 31, 47), (68, 27, 47), (80, 31, 47), (84, 31, 56), + (88, 35, 56), (96, 35, 56), (96, 31, 56), (84, 31, 56), + (76, 27, 56), (72, 27, 56), (68, 27, 56), (60, 27, 47), + (52, 23, 37), (40, 20, 28), (31, 20, 28), (16, 20, 28), + (20, 12, 28), (20, 12, 28), (23, 12, 18), (27, 16, 18), + (32, 20, 28), (35, 24, 28), (36, 28, 28), (40, 28, 37) + ), + +// 36 solid-sky +((145, 104, 84), (178, 111, 75), (202, 123, 75), (198, 127, 75), + (129, 112, 85), (84, 72, 37), (40, 40, 28), (20, 16, 18), + (11, 4, 28), (12, 4, 28), (23, 24, 28), (0, 93, 141), + (0, 109, 160), (4, 122, 170), (7, 134, 179), (19, 138, 188), + (24, 142, 179), (31, 151, 179), (44, 158, 179), (52, 162, 179), + (129, 117, 122), (190, 137, 103), (214, 152, 66), (206, 131, 37), + (202, 119, 28), (198, 106, 9), (194, 90, 9), (166, 43, 9), + (133, 18, 0), (72, 19, 9), (60, 19, 18), (36, 28, 9), + (36, 36, 18), (52, 60, 37), (0, 101, 150), (0, 109, 150), + (0, 109, 150), (0, 105, 150), (0, 97, 141), (20, 36, 18), + (16, 24, 9), (8, 8, 9), (12, 4, 9), (12, 4, 9), + (11, 4, 9), (8, 4, 9), (4, 4, 9), (7, 4, 9), + (8, 0, 9), (12, 0, 9), (15, 0, 9), (16, 4, 18), + (19, 12, 28), (0, 89, 141), (0, 97, 160), (0, 101, 160), + (0, 101, 150), (60, 60, 37), (68, 31, 18), (105, 30, 9), + (170, 80, 9), (198, 90, 0), (178, 67, 0), (133, 30, 0), + (72, 15, 9), (36, 12, 18), (23, 8, 9), (16, 4, 9), + (19, 8, 9), (27, 20, 18), (52, 44, 37), (4, 105, 150), + (60, 162, 188), (173, 173, 160), (198, 165, 151), (194, 148, 113), + (218, 160, 84), (222, 153, 84), (214, 132, 47), (210, 123, 37), + (202, 111, 28), (218, 118, 28), (202, 119, 47), (149, 104, 85), + (88, 116, 113), (4, 113, 160), (0, 118, 160), (0, 122, 160), + (0, 122, 160), (0, 122, 160), (0, 122, 170), (4, 122, 170), + (0, 118, 170), (0, 114, 170), (0, 109, 160), (0, 101, 150), + (44, 60, 28), (28, 36, 9), (20, 16, 9), (16, 8, 9), + (15, 4, 9), (12, 0, 18), (11, 0, 18), (8, 0, 18), + (8, 0, 18), (12, 4, 9), (15, 4, 9), (20, 4, 9), + (28, 12, 18), (36, 36, 18), (52, 52, 47), (0, 97, 150), + (0, 101, 150), (73, 73, 66), (64, 60, 37), (48, 56, 28), + (64, 64, 47), (0, 105, 150), (0, 118, 160), (4, 122, 170), + (8, 126, 170), (4, 130, 170), (4, 134, 170), (0, 130, 170), + (0, 126, 170), (0, 126, 170), (0, 122, 170), (0, 114, 170), + (0, 105, 160), (0, 93, 150), (16, 32, 28), (16, 12, 18), + (19, 8, 9), (20, 20, 18), (28, 44, 28), (0, 97, 141), + (4, 118, 160), (23, 142, 179), (44, 158, 188), (60, 166, 197), + (60, 166, 197), (68, 170, 197), (72, 170, 197), (72, 173, 197), + (96, 177, 188), (149, 145, 103), (214, 143, 75), (210, 127, 47), + (154, 99, 37), (68, 68, 28), (44, 35, 18), (24, 20, 18), + (15, 8, 18), (7, 4, 18), (4, 0, 18), (3, 4, 18), + (7, 4, 18), (11, 4, 18), (19, 8, 18), (32, 36, 28), + (0, 105, 150), (24, 138, 179), (72, 174, 188), (149, 190, 197), + (206, 218, 207), (210, 222, 207), (218, 210, 207), (218, 218, 198), + (218, 210, 198), (194, 194, 170), (194, 181, 160), (141, 137, 103), + (113, 81, 75), (72, 84, 37), (52, 68, 28), (52, 48, 28), + (68, 64, 28), (81, 80, 37), (141, 88, 47), (194, 106, 37), + (206, 106, 28), (206, 110, 18), (206, 110, 9), (194, 98, 18), + (174, 87, 37), (96, 88, 94), (4, 113, 150), (12, 134, 170), + (19, 142, 179), (31, 147, 179), (39, 151, 188), (48, 158, 188), + (48, 166, 188), (48, 162, 188), (43, 159, 197), (39, 151, 198), + (27, 147, 188), (23, 142, 179), (20, 138, 179), (19, 134, 179), + (8, 130, 179), (4, 122, 160), (4, 109, 160), (0, 97, 150), + (44, 36, 37), (31, 16, 18), (23, 8, 18), (23, 8, 18), + (27, 28, 28), (0, 93, 141), (0, 105, 150), (0, 97, 141), + (48, 39, 37), (28, 28, 18), (32, 24, 9), (44, 15, 9), + (60, 27, 18), (93, 55, 37), (154, 84, 37), (186, 98, 28), + (186, 102, 9), (170, 87, 18), (73, 80, 28), (40, 52, 18), + (40, 36, 18), (48, 35, 18), (64, 60, 18), (149, 75, 0), + (194, 94, 9), (198, 98, 9), (214, 105, 0), (210, 98, 9), + (210, 101, 18), (198, 112, 37), (190, 107, 56), (108, 108, 94), + (4, 105, 150), (0, 105, 160), (0, 109, 160), (0, 105, 160), + (0, 101, 160), (0, 89, 141), (11, 8, 37), (11, 4, 28), + (11, 4, 18), (12, 4, 18), (20, 8, 18), (36, 12, 18), + (64, 19, 9), (77, 11, 0), (109, 19, 0), (169, 14, 9), + (149, 67, 18), (85, 85, 66), (24, 113, 150), (35, 155, 188) + ), + +// 37 misty-field +((84, 89, 103), (96, 100, 94), (101, 105, 85), (93, 105, 84), + (89, 109, 85), (100, 113, 94), (109, 121, 103), (104, 117, 113), + (116, 117, 122), (121, 141, 141), (133, 166, 179), (153, 185, 197), + (161, 185, 207), (157, 189, 207), (161, 185, 207), (157, 177, 207), + (149, 169, 198), (133, 158, 188), (116, 146, 179), (108, 133, 179), + (108, 133, 179), (116, 141, 179), (112, 141, 170), (129, 150, 170), + (133, 157, 188), (141, 161, 188), (137, 153, 169), (125, 141, 141), + (121, 133, 113), (109, 121, 94), (105, 125, 85), (101, 133, 84), + (101, 133, 85), (109, 133, 85), (97, 133, 85), (93, 121, 75), + (97, 125, 85), (101, 117, 85), (105, 117, 75), (89, 117, 75), + (84, 121, 75), (93, 141, 75), (109, 150, 75), (117, 170, 103), + (133, 178, 122), (145, 170, 151), (169, 194, 188), (169, 198, 207), + (173, 193, 207), (169, 189, 207), (169, 189, 216), (165, 189, 216), + (165, 185, 216), (161, 181, 216), (157, 181, 226), (157, 185, 226), + (157, 189, 225), (177, 201, 226), (205, 210, 235), (214, 218, 244), + (214, 222, 244), (209, 222, 244), (205, 218, 244), (193, 214, 235), + (177, 197, 216), (177, 189, 207), (169, 185, 207), (169, 181, 207), + (165, 177, 216), (161, 181, 216), (165, 185, 216), (165, 189, 216), + (169, 193, 216), (177, 197, 216), (193, 206, 226), (206, 222, 226), + (218, 222, 235), (222, 226, 244), (226, 222, 235), (222, 230, 244), + (222, 226, 254), (222, 226, 244), (218, 226, 244), (218, 226, 244), + (222, 234, 244), (214, 226, 244), (205, 218, 235), (185, 197, 216), + (165, 181, 207), (141, 153, 169), (121, 121, 141), (105, 101, 113), + (84, 84, 94), (77, 85, 85), (73, 77, 75), (73, 73, 75), + (73, 73, 75), (73, 77, 75), (73, 85, 85), (77, 97, 85), + (84, 113, 94), (104, 133, 132), (112, 154, 132), (129, 162, 160), + (141, 169, 188), (145, 165, 198), (141, 165, 207), (137, 161, 207), + (124, 165, 207), (64, 139, 207), (64, 139, 207), (64, 135, 207), + (100, 129, 179), (96, 125, 160), (108, 145, 132), (112, 137, 103), + (97, 121, 94), (89, 113, 85), (89, 105, 85), (77, 89, 85), + (77, 81, 84), (77, 73, 75), (77, 73, 75), (77, 77, 75), + (81, 81, 84), (77, 77, 75), (73, 73, 66), (73, 73, 66), + (73, 77, 75), (76, 77, 94), (68, 68, 103), (72, 77, 103), + (92, 100, 132), (124, 133, 141), (145, 161, 179), (165, 185, 207), + (173, 201, 225), (201, 222, 235), (213, 230, 244), (222, 230, 235), + (222, 226, 235), (222, 226, 235), (209, 222, 235), (205, 218, 235), + (185, 206, 226), (173, 197, 216), (169, 189, 216), (165, 189, 207), + (165, 185, 198), (153, 169, 179), (141, 166, 141), (137, 154, 132), + (125, 157, 132), (121, 158, 103), (101, 149, 75), (85, 125, 65), + (81, 117, 75), (72, 109, 94), (77, 85, 85), (80, 81, 94), + (81, 77, 84), (77, 73, 75), (73, 73, 75), (68, 68, 66), + (68, 68, 66), (73, 73, 66), (73, 73, 75), (72, 72, 75), + (81, 85, 75), (81, 89, 75), (81, 89, 75), (85, 97, 75), + (89, 97, 94), (89, 93, 94), (85, 89, 85), (81, 81, 75), + (85, 97, 75), (85, 89, 75), (85, 85, 75), (81, 97, 75), + (81, 105, 66), (85, 97, 66), (85, 101, 75), (81, 101, 75), + (76, 101, 75), (73, 97, 75), (77, 93, 75), (73, 81, 75), + (68, 77, 75), (73, 73, 75), (73, 73, 75), (73, 73, 75), + (73, 73, 75), (73, 73, 66), (81, 85, 75), (81, 97, 66), + (81, 105, 56), (60, 101, 47), (73, 97, 56), (68, 89, 66), + (73, 77, 66), (73, 73, 66), (68, 68, 75), (52, 72, 103), + (44, 81, 141), (60, 130, 207), (60, 135, 207), (64, 138, 198), + (96, 125, 160), (88, 121, 122), (84, 108, 113), (92, 101, 103), + (101, 101, 113), (112, 117, 132), (104, 117, 141), (104, 125, 151), + (116, 133, 170), (128, 145, 188), (128, 157, 198), (129, 154, 207), + (129, 157, 197), (137, 173, 198), (145, 173, 198), (141, 165, 188), + (133, 165, 188), (125, 157, 188), (120, 145, 179), (112, 133, 170), + (96, 121, 160), (100, 117, 151), (72, 105, 122), (68, 89, 113), + (80, 93, 103), (76, 97, 132), (108, 125, 151), (137, 141, 160), + (145, 157, 188), (161, 181, 207), (169, 193, 216), (181, 210, 226), + (193, 222, 235), (197, 218, 235), (181, 201, 226), (165, 193, 216), + (161, 189, 216), (157, 181, 216), (157, 181, 216), (153, 181, 216), + (149, 181, 207), (157, 181, 207), (153, 177, 207), (149, 177, 207), + (149, 177, 207), (141, 169, 207), (137, 165, 198), (128, 161, 198) + ), + +// 38 wooden-highlight +((97, 76, 75), (85, 68, 56), (97, 72, 46), (125, 84, 56), + (141, 100, 85), (149, 107, 113), (137, 116, 122), (153, 112, 113), + (154, 133, 122), (157, 124, 103), (153, 124, 94), (161, 119, 94), + (178, 119, 85), (174, 132, 103), (170, 137, 122), (194, 153, 122), + (166, 124, 123), (162, 125, 123), (170, 120, 103), (178, 131, 85), + (174, 119, 66), (166, 111, 47), (154, 95, 47), (137, 80, 28), + (141, 72, 9), (141, 68, 18), (141, 64, 18), (137, 59, 18), + (125, 55, 9), (141, 51, 9), (125, 51, 9), (117, 51, 18), + (117, 55, 28), (109, 55, 28), (105, 55, 28), (109, 51, 28), + (97, 55, 28), (101, 51, 46), (88, 64, 47), (109, 68, 46), + (141, 96, 66), (166, 120, 85), (170, 119, 66), (174, 111, 75), + (170, 115, 85), (178, 123, 85), (150, 108, 94), (154, 107, 85), + (133, 92, 75), (141, 88, 47), (129, 76, 28), (121, 64, 28), + (133, 72, 28), (137, 80, 37), (146, 88, 37), (150, 96, 47), + (154, 99, 47), (154, 99, 47), (146, 92, 28), (154, 76, 18), + (146, 64, 18), (141, 64, 28), (141, 76, 28), (145, 80, 37), + (158, 95, 47), (174, 106, 37), (178, 110, 47), (170, 102, 28), + (150, 84, 18), (129, 72, 18), (109, 68, 18), (96, 47, 9), + (84, 35, 18), (72, 35, 18), (68, 35, 18), (68, 39, 18), + (76, 43, 28), (84, 43, 28), (92, 51, 28), (100, 55, 28), + (117, 72, 28), (133, 88, 28), (162, 106, 28), (170, 106, 28), + (162, 91, 28), (150, 80, 28), (141, 64, 28), (125, 51, 28), + (117, 47, 18), (101, 42, 18), (84, 39, 18), (60, 31, 9), + (44, 23, 9), (32, 16, 9), (24, 16, 9), (16, 16, 9), + (16, 20, 0), (16, 16, 9), (16, 16, 9), (16, 20, 9), + (20, 20, 9), (27, 20, 9), (27, 20, 9), (27, 24, 9), + (24, 20, 18), (32, 16, 18), (28, 16, 18), (20, 16, 18), + (19, 12, 18), (19, 12, 18), (16, 12, 18), (16, 16, 18), + (16, 16, 18), (15, 16, 18), (16, 16, 18), (19, 16, 18), + (27, 24, 18), (31, 20, 28), (36, 24, 28), (48, 24, 28), + (68, 35, 28), (80, 43, 28), (89, 51, 18), (105, 51, 18), + (109, 51, 18), (121, 51, 18), (121, 42, 9), (121, 51, 18), + (125, 46, 18), (121, 55, 18), (117, 64, 18), (113, 68, 18), + (109, 68, 18), (105, 64, 28), (105, 59, 28), (96, 51, 28), + (80, 43, 28), (56, 27, 28), (44, 19, 28), (36, 24, 28), + (24, 20, 28), (19, 16, 18), (12, 12, 9), (12, 12, 9), + (16, 16, 9), (24, 20, 9), (40, 23, 9), (68, 35, 9), + (85, 43, 9), (105, 42, 9), (109, 47, 18), (109, 47, 18), + (109, 46, 9), (109, 46, 9), (97, 38, 9), (80, 43, 9), + (60, 35, 9), (40, 24, 18), (32, 24, 18), (28, 24, 18), + (28, 24, 18), (40, 28, 18), (44, 23, 18), (56, 31, 18), + (68, 39, 18), (80, 43, 18), (85, 52, 28), (101, 72, 37), + (133, 88, 47), (141, 100, 75), (146, 112, 85), (146, 116, 85), + (146, 107, 75), (121, 72, 37), (113, 60, 28), (88, 47, 28), + (56, 35, 28), (35, 24, 18), (23, 16, 18), (19, 16, 18), + (16, 16, 18), (16, 12, 9), (16, 12, 9), (24, 16, 9), + (35, 20, 9), (48, 27, 9), (56, 31, 18), (60, 31, 18), + (68, 35, 37), (76, 39, 37), (76, 39, 28), (76, 35, 28), + (84, 35, 28), (96, 38, 18), (97, 39, 18), (100, 38, 18), + (84, 39, 28), (68, 35, 18), (56, 27, 18), (44, 23, 18), + (48, 23, 18), (56, 27, 18), (64, 35, 37), (72, 64, 56), + (89, 72, 65), (105, 93, 84), (137, 100, 85), (149, 108, 94), + (150, 104, 85), (129, 92, 84), (101, 84, 75), (101, 72, 37), + (113, 68, 28), (133, 68, 28), (129, 64, 18), (137, 68, 18), + (137, 72, 28), (125, 64, 18), (125, 60, 18), (121, 60, 18), + (117, 55, 18), (101, 47, 28), (84, 47, 28), (68, 39, 28), + (48, 31, 18), (31, 24, 18), (20, 16, 9), (16, 12, 9), + (12, 12, 9), (11, 12, 9), (12, 12, 9), (16, 12, 9), + (24, 12, 9), (31, 12, 9), (35, 16, 9), (60, 23, 9), + (64, 27, 9), (72, 39, 18), (72, 47, 18), (76, 47, 28), + (72, 52, 28), (76, 47, 28), (80, 43, 28), (72, 35, 28), + (64, 31, 18), (60, 31, 9), (40, 27, 9), (27, 20, 9), + (32, 20, 9), (36, 28, 9), (48, 27, 9), (56, 39, 18), + (81, 47, 18), (105, 59, 18), (121, 64, 18), (146, 76, 28) + ), + +// 39 jet-tundra +((109, 92, 75), (105, 85, 75), (105, 85, 75), (97, 89, 75), + (93, 85, 75), (93, 81, 75), (93, 80, 65), (85, 73, 65), + (84, 68, 56), (84, 68, 47), (80, 64, 47), (76, 64, 47), + (72, 60, 37), (68, 64, 37), (72, 64, 47), (77, 73, 47), + (85, 76, 47), (93, 76, 56), (97, 80, 56), (101, 80, 56), + (105, 80, 56), (109, 84, 56), (105, 88, 56), (101, 84, 56), + (97, 80, 56), (93, 76, 56), (85, 68, 47), (72, 60, 47), + (64, 56, 37), (60, 56, 37), (60, 56, 37), (68, 60, 37), + (72, 56, 37), (73, 64, 47), (76, 68, 56), (76, 68, 56), + (81, 64, 56), (80, 68, 56), (81, 73, 56), (85, 80, 65), + (93, 85, 65), (101, 93, 65), (101, 93, 75), (105, 97, 84), + (113, 96, 84), (113, 100, 94), (113, 104, 94), (113, 104, 94), + (117, 108, 94), (121, 108, 85), (121, 104, 84), (121, 104, 75), + (117, 100, 75), (109, 97, 75), (105, 93, 75), (105, 92, 65), + (105, 92, 66), (97, 89, 75), (93, 89, 75), (93, 85, 75), + (85, 77, 65), (81, 73, 65), (81, 72, 56), (77, 72, 56), + (73, 73, 56), (72, 68, 56), (72, 68, 56), (76, 68, 56), + (77, 68, 56), (85, 76, 56), (89, 80, 56), (93, 81, 65), + (97, 89, 75), (105, 92, 75), (113, 92, 75), (121, 92, 75), + (121, 92, 66), (113, 92, 65), (105, 88, 65), (93, 85, 56), + (89, 84, 56), (85, 77, 56), (73, 73, 56), (72, 68, 56), + (72, 64, 47), (68, 60, 47), (68, 60, 47), (64, 60, 47), + (64, 60, 56), (68, 60, 56), (68, 60, 56), (72, 64, 66), + (68, 68, 56), (68, 64, 47), (68, 64, 47), (64, 56, 47), + (56, 52, 37), (56, 52, 37), (52, 52, 37), (52, 52, 37), + (52, 48, 37), (48, 48, 37), (48, 48, 28), (60, 52, 28), + (60, 56, 28), (56, 52, 37), (52, 48, 37), (56, 48, 37), + (56, 48, 37), (60, 48, 37), (72, 60, 47), (85, 72, 56), + (97, 85, 65), (109, 96, 75), (121, 104, 85), (129, 116, 103), + (133, 125, 103), (137, 125, 113), (137, 124, 113), (133, 125, 103), + (137, 116, 103), (133, 112, 103), (129, 112, 94), (125, 116, 85), + (113, 108, 85), (105, 101, 75), (101, 92, 66), (93, 88, 65), + (89, 85, 65), (89, 85, 56), (89, 85, 56), (89, 85, 65), + (89, 89, 75), (93, 89, 84), (104, 104, 94), (108, 96, 94), + (108, 96, 94), (105, 97, 84), (101, 93, 84), (97, 80, 75), + (89, 76, 65), (81, 73, 56), (73, 68, 47), (68, 64, 47), + (60, 56, 47), (56, 56, 47), (64, 64, 47), (72, 68, 47), + (81, 73, 56), (93, 81, 56), (97, 88, 66), (101, 88, 75), + (105, 89, 84), (109, 97, 84), (117, 100, 84), (125, 100, 84), + (125, 100, 84), (121, 100, 84), (121, 104, 84), (121, 108, 94), + (121, 108, 94), (117, 108, 94), (121, 108, 94), (121, 117, 94), + (133, 121, 103), (145, 116, 103), (149, 124, 94), (150, 120, 94), + (154, 120, 94), (158, 128, 85), (158, 132, 85), (137, 120, 75), + (133, 112, 66), (113, 96, 65), (97, 88, 56), (85, 76, 47), + (73, 68, 47), (64, 56, 47), (60, 52, 47), (60, 48, 37), + (64, 52, 37), (73, 60, 37), (85, 72, 47), (89, 76, 47), + (93, 80, 47), (97, 81, 56), (97, 85, 65), (97, 88, 65), + (101, 92, 65), (101, 97, 75), (113, 104, 84), (125, 108, 94), + (133, 116, 103), (145, 120, 113), (154, 137, 122), (178, 149, 141), + (198, 165, 151), (218, 193, 179), (210, 185, 179), (178, 153, 141), + (166, 145, 132), (157, 141, 122), (153, 133, 132), (120, 112, 122), + (125, 108, 113), (121, 100, 94), (113, 97, 75), (109, 93, 65), + (109, 92, 65), (105, 93, 65), (109, 93, 75), (113, 104, 84), + (113, 100, 84), (113, 104, 84), (113, 104, 84), (113, 104, 75), + (109, 96, 66), (105, 92, 56), (105, 92, 56), (105, 88, 47), + (109, 93, 56), (113, 96, 65), (121, 100, 75), (125, 100, 84), + (129, 108, 85), (133, 112, 85), (133, 112, 94), (133, 116, 103), + (137, 120, 103), (145, 124, 103), (137, 120, 103), (141, 116, 94), + (133, 116, 75), (121, 100, 75), (121, 96, 75), (109, 92, 65), + (105, 88, 65), (101, 84, 56), (93, 77, 56), (85, 72, 47), + (80, 68, 37), (72, 64, 37), (68, 64, 28), (60, 56, 28), + (64, 60, 28), (68, 60, 37), (76, 64, 37), (85, 73, 37), + (89, 84, 47), (97, 88, 47), (97, 88, 56), (97, 85, 56), + (97, 80, 56), (93, 76, 56), (81, 72, 56), (73, 68, 56) + ), + +// 40 pastel-lime +((137, 149, 85), (133, 146, 94), (129, 141, 94), (109, 133, 85), + (121, 133, 85), (105, 121, 75), (133, 129, 75), (162, 128, 85), + (190, 107, 66), (158, 111, 37), (198, 115, 56), (202, 152, 66), + (174, 140, 85), (149, 149, 75), (137, 146, 94), (113, 133, 75), + (105, 121, 75), (101, 121, 75), (97, 121, 66), (93, 105, 56), + (93, 85, 56), (113, 76, 56), (146, 88, 18), (162, 59, 9), + (113, 68, 9), (85, 80, 37), (81, 68, 47), (64, 64, 47), + (52, 73, 47), (56, 73, 37), (64, 77, 37), (64, 77, 28), + (68, 73, 37), (68, 77, 37), (77, 89, 47), (89, 109, 56), + (113, 137, 75), (109, 133, 85), (121, 150, 103), (137, 162, 122), + (145, 166, 151), (150, 182, 151), (194, 198, 160), (234, 205, 150), + (214, 185, 132), (214, 181, 94), (210, 157, 103), (198, 144, 94), + (153, 116, 94), (109, 113, 85), (101, 109, 75), (89, 100, 66), + (77, 93, 66), (69, 89, 56), (64, 77, 56), (60, 77, 47), + (56, 81, 56), (56, 76, 56), (56, 73, 56), (60, 73, 56), + (68, 73, 56), (73, 81, 56), (73, 89, 56), (73, 89, 56), + (85, 113, 56), (101, 121, 75), (109, 129, 85), (129, 150, 94), + (141, 166, 113), (166, 173, 103), (162, 178, 132), (174, 182, 132), + (186, 190, 122), (194, 194, 132), (214, 202, 132), (186, 194, 141), + (170, 186, 122), (166, 173, 103), (162, 169, 85), (145, 166, 85), + (125, 133, 85), (109, 117, 66), (105, 109, 66), (97, 97, 56), + (93, 76, 56), (113, 88, 66), (113, 109, 75), (170, 91, 37), + (170, 119, 56), (174, 115, 56), (157, 145, 85), (125, 137, 85), + (109, 113, 75), (105, 109, 75), (101, 101, 75), (97, 105, 66), + (93, 109, 66), (89, 113, 66), (89, 109, 75), (89, 109, 75), + (85, 109, 75), (85, 105, 75), (84, 101, 66), (81, 101, 66), + (81, 101, 66), (81, 101, 66), (85, 105, 66), (85, 105, 56), + (89, 100, 56), (81, 97, 56), (73, 97, 56), (73, 93, 56), + (77, 81, 47), (93, 76, 47), (85, 72, 56), (81, 73, 56), + (81, 80, 66), (89, 73, 75), (101, 85, 84), (113, 96, 84), + (121, 121, 94), (137, 137, 103), (157, 149, 122), (178, 177, 122), + (202, 185, 151), (210, 206, 170), (214, 193, 170), (190, 190, 170), + (182, 190, 151), (170, 186, 160), (174, 190, 151), (170, 194, 151), + (158, 186, 141), (149, 178, 141), (162, 194, 160), (149, 170, 132), + (145, 153, 122), (125, 133, 113), (104, 117, 94), (89, 105, 75), + (77, 93, 66), (64, 76, 56), (56, 64, 56), (60, 60, 56), + (60, 60, 66), (76, 64, 65), (97, 76, 65), (97, 97, 75), + (101, 109, 75), (105, 121, 84), (125, 141, 103), (129, 158, 113), + (133, 158, 122), (129, 154, 122), (129, 158, 113), (117, 150, 103), + (109, 117, 75), (89, 97, 66), (73, 77, 56), (60, 60, 47), + (52, 48, 37), (44, 39, 28), (32, 40, 18), (20, 20, 18), + (23, 20, 28), (20, 24, 37), (19, 28, 37), (36, 32, 37), + (40, 48, 47), (44, 56, 66), (48, 44, 56), (48, 48, 56), + (44, 56, 56), (56, 64, 56), (56, 60, 56), (48, 56, 47), + (52, 52, 47), (60, 48, 47), (48, 48, 47), (48, 48, 47), + (36, 56, 47), (40, 48, 37), (32, 52, 37), (44, 60, 47), + (44, 52, 37), (40, 56, 37), (40, 64, 37), (40, 68, 37), + (48, 56, 28), (56, 68, 37), (48, 52, 28), (56, 64, 37), + (56, 52, 47), (52, 64, 47), (60, 68, 47), (64, 64, 56), + (64, 73, 56), (68, 73, 56), (68, 68, 47), (68, 73, 47), + (60, 77, 47), (68, 76, 47), (68, 81, 56), (60, 81, 56), + (60, 81, 56), (64, 81, 56), (68, 81, 66), (73, 77, 75), + (76, 88, 75), (81, 93, 75), (85, 97, 75), (89, 105, 75), + (89, 109, 75), (93, 117, 75), (93, 113, 85), (101, 117, 84), + (109, 129, 94), (125, 141, 113), (141, 161, 122), (174, 157, 122), + (190, 145, 132), (166, 170, 103), (162, 182, 113), (154, 178, 132), + (150, 174, 113), (141, 170, 132), (137, 170, 122), (137, 162, 113), + (125, 145, 103), (121, 133, 94), (105, 117, 85), (101, 109, 85), + (93, 109, 85), (93, 104, 85), (89, 109, 85), (101, 117, 85), + (117, 137, 103), (117, 150, 113), (116, 133, 113), (97, 109, 94), + (85, 105, 85), (73, 97, 75), (76, 84, 66), (77, 84, 66), + (81, 80, 56), (73, 81, 56), (68, 85, 56), (64, 85, 47), + (56, 85, 47), (69, 81, 47), (73, 81, 56), (68, 81, 47), + (73, 85, 47), (73, 89, 56), (81, 89, 56), (85, 97, 56) + ), + +// 41 hell +((141, 31, 18), (145, 38, 9), (149, 34, 9), (154, 34, 9), + (154, 34, 9), (153, 34, 18), (154, 34, 9), (162, 37, 0), + (166, 37, 0), (174, 46, 0), (186, 54, 0), (198, 67, 0), + (198, 62, 0), (174, 58, 0), (166, 38, 0), (158, 26, 0), + (137, 22, 0), (137, 11, 0), (133, 11, 0), (129, 7, 9), + (137, 22, 0), (137, 26, 9), (129, 26, 9), (141, 30, 0), + (154, 42, 0), (170, 50, 0), (178, 63, 9), (170, 75, 18), + (182, 75, 18), (182, 75, 18), (178, 71, 9), (186, 75, 0), + (186, 75, 9), (190, 67, 9), (194, 67, 9), (202, 63, 9), + (198, 67, 9), (206, 79, 9), (218, 94, 9), (214, 102, 18), + (230, 98, 9), (218, 103, 9), (242, 139, 56), (222, 98, 9), + (210, 86, 9), (194, 75, 28), (182, 63, 9), (170, 42, 9), + (150, 38, 9), (137, 34, 9), (125, 26, 9), (113, 15, 0), + (101, 7, 0), (85, 7, 0), (73, 11, 0), (76, 3, 0), + (73, 11, 0), (85, 11, 0), (89, 15, 9), (97, 26, 9), + (113, 39, 18), (125, 47, 28), (121, 67, 37), (133, 63, 18), + (158, 59, 9), (190, 87, 18), (210, 98, 9), (210, 107, 18), + (218, 103, 18), (214, 98, 9), (202, 90, 9), (182, 74, 9), + (162, 59, 9), (150, 42, 9), (133, 34, 9), (117, 26, 0), + (97, 19, 0), (80, 15, 9), (60, 11, 9), (56, 15, 9), + (56, 15, 0), (56, 7, 0), (64, 7, 0), (77, 15, 0), + (89, 19, 0), (97, 22, 0), (117, 34, 0), (129, 34, 0), + (133, 34, 0), (137, 34, 0), (137, 34, 0), (137, 38, 0), + (133, 34, 0), (129, 34, 0), (121, 27, 0), (113, 22, 0), + (113, 22, 0), (109, 22, 0), (105, 26, 9), (105, 23, 9), + (105, 19, 0), (105, 11, 0), (109, 11, 0), (109, 22, 0), + (113, 26, 0), (117, 31, 0), (121, 34, 0), (125, 30, 0), + (121, 30, 0), (117, 30, 0), (109, 26, 0), (101, 22, 0), + (89, 19, 0), (85, 19, 0), (77, 23, 0), (73, 19, 0), + (73, 19, 0), (68, 15, 9), (76, 19, 0), (76, 15, 9), + (76, 19, 9), (80, 27, 18), (80, 31, 18), (84, 23, 9), + (93, 23, 9), (105, 26, 9), (125, 26, 18), (117, 26, 18), + (105, 27, 18), (97, 31, 18), (93, 27, 18), (97, 23, 9), + (89, 26, 0), (89, 23, 0), (89, 27, 9), (93, 26, 0), + (97, 26, 0), (109, 27, 0), (117, 34, 0), (125, 34, 9), + (133, 34, 9), (141, 34, 0), (146, 34, 0), (154, 33, 0), + (158, 29, 0), (158, 33, 0), (158, 38, 9), (162, 34, 9), + (161, 42, 9), (161, 42, 9), (162, 38, 9), (166, 37, 0), + (170, 37, 0), (170, 50, 0), (174, 63, 0), (178, 63, 9), + (174, 59, 0), (162, 46, 0), (146, 42, 0), (129, 43, 9), + (121, 38, 9), (125, 38, 9), (121, 38, 9), (121, 38, 0), + (117, 42, 0), (121, 46, 9), (125, 42, 9), (129, 44, 18), + (149, 56, 28), (145, 75, 37), (153, 68, 28), (182, 80, 47), + (165, 95, 75), (165, 99, 84), (194, 124, 75), (178, 120, 56), + (173, 87, 37), (174, 83, 37), (174, 79, 28), (169, 55, 28), + (157, 46, 28), (154, 55, 9), (154, 55, 9), (146, 43, 9), + (149, 51, 0), (154, 46, 0), (146, 42, 0), (150, 42, 9), + (150, 38, 9), (146, 34, 9), (141, 39, 18), (133, 43, 18), + (133, 39, 18), (141, 42, 19), (146, 51, 9), (149, 59, 9), + (158, 67, 9), (190, 86, 18), (202, 95, 18), (206, 79, 9), + (194, 72, 0), (174, 63, 9), (149, 51, 18), (133, 46, 9), + (121, 55, 0), (113, 39, 0), (101, 31, 9), (92, 30, 9), + (101, 30, 9), (105, 26, 9), (117, 39, 9), (129, 38, 9), + (133, 34, 9), (137, 34, 9), (137, 38, 9), (141, 38, 9), + (145, 38, 9), (145, 38, 0), (146, 38, 0), (154, 34, 0), + (158, 34, 0), (150, 33, 0), (141, 27, 0), (133, 22, 0), + (125, 22, 0), (125, 22, 0), (121, 18, 0), (121, 18, 0), + (117, 22, 0), (125, 27, 0), (125, 34, 0), (121, 38, 9), + (121, 38, 9), (121, 38, 9), (113, 38, 9), (105, 26, 0), + (101, 19, 0), (97, 15, 0), (97, 15, 0), (85, 15, 0), + (84, 15, 0), (80, 15, 0), (77, 15, 0), (81, 19, 0), + (85, 19, 0), (89, 22, 0), (97, 22, 0), (105, 22, 0), + (113, 15, 9), (125, 26, 9), (129, 30, 0), (129, 30, 0), + (125, 22, 0), (125, 18, 0), (133, 18, 0), (133, 22, 0) + ), + +// 42 indian-coast +((68, 56, 47), (80, 64, 47), (89, 76, 47), (105, 68, 46), + (104, 68, 46), (80, 60, 37), (60, 52, 37), (52, 44, 37), + (44, 40, 37), (36, 40, 37), (32, 32, 37), (40, 44, 28), + (36, 44, 28), (36, 40, 28), (28, 36, 28), (20, 32, 28), + (19, 24, 28), (20, 24, 28), (28, 28, 28), (35, 32, 37), + (27, 36, 37), (12, 36, 47), (20, 36, 28), (32, 32, 28), + (32, 32, 28), (36, 44, 28), (36, 48, 28), (40, 48, 28), + (52, 56, 28), (56, 60, 28), (60, 60, 28), (64, 60, 37), + (81, 77, 47), (93, 89, 47), (109, 92, 37), (113, 88, 47), + (129, 96, 56), (125, 100, 56), (125, 100, 56), (129, 96, 56), + (121, 84, 56), (117, 84, 56), (109, 80, 47), (109, 76, 46), + (97, 80, 47), (85, 77, 56), (84, 76, 56), (81, 72, 66), + (77, 73, 66), (89, 97, 85), (137, 177, 188), (169, 210, 216), + (173, 210, 216), (173, 206, 216), (177, 202, 198), (182, 119, 75), + (166, 103, 56), (162, 99, 56), (178, 123, 75), (181, 206, 207), + (181, 210, 216), (181, 210, 216), (177, 210, 216), (177, 210, 216), + (177, 210, 207), (165, 133, 103), (149, 108, 56), (141, 107, 56), + (145, 103, 56), (145, 100, 56), (158, 103, 75), (169, 210, 197), + (169, 210, 216), (169, 206, 207), (141, 125, 113), (133, 88, 75), + (121, 84, 65), (125, 76, 56), (117, 80, 56), (117, 76, 47), + (121, 80, 46), (121, 88, 47), (125, 84, 56), (133, 92, 56), + (141, 103, 56), (141, 104, 75), (149, 149, 122), (177, 202, 216), + (177, 210, 216), (181, 214, 216), (185, 218, 216), (185, 214, 216), + (181, 210, 226), (181, 210, 226), (177, 210, 226), (173, 210, 216), + (161, 206, 197), (121, 121, 85), (101, 88, 56), (84, 76, 47), + (68, 68, 37), (52, 60, 37), (52, 60, 28), (40, 60, 47), + (56, 68, 28), (77, 64, 37), (109, 72, 46), (133, 88, 56), + (145, 96, 66), (170, 115, 85), (173, 206, 207), (177, 206, 216), + (177, 210, 226), (177, 206, 225), (177, 210, 216), (177, 214, 207), + (137, 137, 113), (129, 100, 75), (113, 88, 56), (93, 76, 37), + (85, 60, 9), (48, 44, 18), (44, 40, 28), (36, 28, 28), + (52, 35, 28), (52, 48, 47), (64, 56, 56), (76, 72, 56), + (93, 85, 56), (117, 109, 84), (157, 206, 207), (165, 206, 225), + (169, 206, 225), (169, 206, 225), (169, 210, 216), (165, 198, 207), + (121, 108, 94), (117, 88, 65), (109, 72, 56), (109, 72, 56), + (85, 72, 56), (80, 68, 56), (80, 64, 56), (76, 68, 56), + (81, 72, 56), (85, 76, 56), (105, 80, 56), (121, 80, 56), + (141, 96, 66), (145, 104, 75), (157, 166, 141), (181, 210, 207), + (189, 210, 216), (185, 214, 216), (185, 210, 207), (186, 127, 85), + (154, 99, 66), (145, 99, 56), (145, 99, 56), (146, 96, 47), + (158, 88, 47), (157, 99, 56), (186, 127, 75), (177, 206, 198), + (169, 210, 216), (153, 194, 207), (108, 104, 94), (85, 89, 75), + (73, 76, 56), (64, 68, 47), (56, 60, 47), (60, 60, 56), + (68, 60, 56), (72, 68, 56), (81, 77, 56), (89, 89, 47), + (93, 88, 56), (105, 97, 84), (165, 186, 197), (189, 206, 216), + (197, 214, 216), (206, 218, 216), (246, 229, 197), (246, 225, 188), + (206, 148, 94), (158, 100, 75), (133, 96, 65), (105, 76, 56), + (72, 60, 56), (32, 48, 56), (32, 48, 56), (32, 48, 56), + (24, 48, 66), (52, 68, 66), (77, 77, 84), (113, 121, 113), + (165, 206, 207), (181, 214, 216), (193, 218, 216), (193, 218, 216), + (202, 218, 216), (202, 218, 216), (202, 210, 198), (186, 131, 75), + (170, 119, 56), (174, 115, 66), (194, 144, 85), (185, 214, 207), + (181, 214, 216), (181, 218, 226), (181, 214, 226), (189, 214, 226), + (193, 218, 226), (197, 218, 226), (206, 218, 226), (206, 218, 226), + (201, 218, 226), (197, 218, 226), (198, 218, 207), (226, 214, 179), + (190, 136, 75), (174, 115, 66), (178, 111, 75), (194, 152, 103), + (185, 214, 207), (181, 210, 216), (177, 202, 216), (149, 133, 113), + (137, 100, 66), (141, 96, 56), (133, 84, 47), (125, 88, 37), + (129, 79, 37), (125, 80, 47), (109, 84, 37), (109, 76, 46), + (93, 80, 47), (68, 64, 47), (60, 60, 37), (60, 60, 37), + (68, 60, 47), (72, 68, 56), (73, 73, 66), (81, 85, 85), + (113, 133, 122), (165, 210, 216), (173, 210, 225), (173, 210, 226), + (173, 210, 216), (169, 214, 216), (165, 210, 207), (129, 125, 85), + (125, 104, 56), (109, 84, 56), (89, 76, 56), (81, 77, 56) + ), + +// 43 dentist-decor +((218, 185, 169), (214, 193, 151), (210, 189, 141), (202, 198, 132), + (178, 169, 113), (166, 162, 103), (149, 133, 94), (133, 120, 103), + (121, 109, 94), (109, 105, 84), (105, 101, 84), (105, 105, 85), + (109, 109, 85), (109, 109, 85), (109, 109, 85), (117, 109, 94), + (129, 129, 103), (137, 146, 94), (146, 166, 94), (146, 166, 85), + (137, 149, 85), (133, 141, 85), (141, 141, 85), (137, 146, 85), + (141, 137, 94), (137, 145, 103), (146, 154, 113), (158, 162, 122), + (157, 166, 113), (154, 170, 113), (150, 170, 122), (166, 182, 132), + (194, 177, 141), (210, 185, 141), (218, 185, 151), (230, 180, 141), + (234, 180, 150), (234, 176, 141), (230, 172, 131), (214, 157, 113), + (198, 145, 113), (182, 128, 103), (153, 108, 94), (141, 100, 84), + (121, 101, 84), (117, 92, 84), (109, 88, 94), (96, 80, 94), + (121, 76, 94), (117, 92, 94), (117, 105, 94), (117, 92, 94), + (129, 100, 94), (133, 125, 103), (153, 132, 103), (174, 141, 122), + (190, 148, 113), (194, 165, 113), (219, 161, 122), (230, 180, 141), + (230, 180, 141), (238, 180, 141), (234, 157, 151), (230, 172, 141), + (234, 157, 160), (234, 156, 150), (230, 157, 169), (222, 149, 151), + (219, 145, 141), (206, 149, 122), (198, 140, 113), (190, 128, 113), + (186, 136, 103), (194, 128, 104), (194, 136, 103), (202, 140, 103), + (202, 145, 113), (202, 152, 113), (210, 152, 113), (222, 161, 113), + (222, 169, 122), (219, 165, 122), (219, 169, 132), (214, 169, 132), + (210, 165, 132), (214, 161, 132), (219, 145, 141), (219, 141, 132), + (222, 141, 141), (219, 145, 141), (214, 161, 141), (206, 168, 132), + (202, 173, 132), (174, 170, 122), (149, 149, 103), (137, 133, 94), + (113, 108, 85), (101, 93, 84), (81, 77, 75), (77, 81, 75), + (85, 85, 84), (109, 97, 84), (137, 112, 75), (149, 112, 94), + (165, 119, 94), (186, 123, 94), (186, 128, 104), (194, 136, 113), + (194, 148, 113), (206, 165, 132), (222, 197, 160), (250, 245, 216), + (222, 197, 160), (214, 181, 160), (214, 181, 179), (250, 197, 197), + (238, 164, 169), (234, 157, 160), (234, 160, 150), (234, 145, 151), + (219, 141, 141), (206, 137, 141), (186, 144, 132), (178, 153, 132), + (166, 165, 122), (162, 170, 113), (146, 166, 103), (137, 150, 103), + (149, 137, 94), (174, 157, 103), (190, 173, 103), (202, 198, 113), + (206, 219, 132), (206, 202, 113), (190, 181, 122), (174, 169, 113), + (141, 141, 94), (105, 113, 85), (77, 81, 75), (60, 64, 66), + (48, 44, 47), (44, 44, 37), (36, 32, 37), (24, 32, 37), + (36, 36, 47), (52, 40, 56), (80, 64, 65), (84, 72, 75), + (105, 88, 84), (121, 113, 103), (145, 141, 113), (162, 149, 122), + (186, 157, 141), (202, 181, 151), (210, 189, 151), (210, 193, 160), + (222, 197, 160), (218, 189, 150), (206, 181, 141), (210, 165, 132), + (210, 153, 122), (210, 153, 122), (219, 141, 132), (219, 137, 132), + (206, 137, 122), (206, 148, 122), (206, 145, 122), (219, 137, 132), + (219, 141, 132), (222, 145, 141), (222, 153, 151), (222, 164, 150), + (219, 153, 151), (219, 145, 151), (206, 137, 151), (169, 132, 141), + (165, 141, 132), (145, 129, 113), (145, 108, 103), (133, 92, 103), + (137, 104, 103), (125, 113, 103), (125, 117, 103), (145, 116, 103), + (161, 128, 103), (178, 152, 94), (178, 161, 103), (178, 165, 94), + (166, 174, 94), (154, 166, 94), (174, 169, 94), (154, 162, 94), + (153, 149, 85), (157, 137, 94), (186, 132, 94), (186, 127, 94), + (190, 128, 94), (194, 136, 104), (190, 136, 104), (194, 140, 94), + (202, 140, 94), (202, 145, 103), (202, 145, 113), (206, 149, 122), + (206, 149, 132), (210, 141, 141), (214, 137, 141), (206, 137, 141), + (206, 137, 132), (198, 141, 132), (198, 145, 122), (194, 145, 122), + (178, 148, 122), (174, 161, 122), (166, 165, 103), (162, 178, 94), + (158, 170, 103), (162, 186, 113), (178, 186, 94), (190, 194, 103), + (190, 177, 122), (198, 173, 132), (186, 161, 151), (206, 145, 151), + (214, 141, 141), (219, 141, 132), (206, 141, 122), (219, 137, 113), + (202, 145, 122), (194, 140, 122), (182, 136, 113), (182, 132, 103), + (149, 120, 94), (121, 105, 84), (93, 76, 65), (85, 68, 66), + (72, 68, 75), (48, 48, 66), (48, 40, 47), (44, 44, 47), + (44, 40, 47), (40, 44, 47), (32, 40, 47), (28, 40, 56), + (32, 36, 56), (44, 44, 56), (68, 56, 66), (85, 81, 65), + (105, 101, 75), (117, 117, 85), (137, 133, 85), (133, 137, 94), + (145, 120, 85), (133, 108, 75), (97, 97, 66), (76, 68, 75) + ), + +// 44 greenland +((173, 210, 188), (169, 185, 198), (145, 169, 198), (141, 161, 188), + (137, 157, 179), (125, 153, 169), (120, 158, 169), (129, 158, 170), + (137, 174, 169), (162, 198, 160), (194, 234, 197), (206, 242, 206), + (229, 242, 225), (254, 238, 225), (254, 233, 216), (250, 237, 216), + (250, 229, 216), (234, 209, 188), (230, 201, 179), (222, 189, 169), + (206, 168, 141), (190, 173, 132), (214, 189, 160), (230, 197, 169), + (234, 201, 188), (230, 210, 197), (242, 225, 216), (250, 242, 235), + (238, 250, 244), (234, 242, 254), (218, 234, 254), (205, 222, 254), + (193, 210, 235), (181, 201, 226), (165, 181, 216), (141, 165, 198), + (137, 165, 188), (137, 169, 188), (145, 178, 170), (162, 210, 169), + (189, 226, 207), (197, 230, 216), (214, 238, 225), (222, 238, 244), + (222, 238, 254), (222, 238, 254), (221, 238, 254), (218, 238, 254), + (213, 242, 244), (197, 238, 225), (181, 230, 216), (177, 197, 216), + (137, 173, 188), (125, 158, 169), (120, 154, 170), (124, 157, 179), + (133, 165, 188), (153, 177, 198), (177, 193, 226), (189, 205, 235), + (201, 218, 235), (210, 238, 225), (214, 242, 225), (218, 242, 226), + (218, 242, 235), (218, 246, 235), (214, 242, 235), (214, 238, 235), + (214, 238, 235), (218, 238, 235), (218, 238, 235), (218, 238, 235), + (218, 238, 225), (214, 242, 225), (206, 238, 216), (198, 230, 207), + (181, 218, 188), (166, 186, 160), (150, 150, 170), (137, 141, 170), + (133, 141, 160), (125, 137, 160), (121, 145, 169), (120, 146, 170), + (124, 150, 170), (112, 153, 169), (116, 146, 170), (120, 154, 170), + (129, 154, 169), (145, 165, 179), (169, 202, 188), (189, 222, 207), + (189, 226, 207), (177, 206, 179), (174, 186, 151), (153, 166, 151), + (133, 146, 151), (133, 146, 151), (116, 141, 151), (108, 133, 151), + (104, 129, 151), (100, 129, 151), (104, 129, 160), (108, 133, 160), + (108, 137, 160), (112, 137, 160), (112, 137, 160), (113, 137, 160), + (116, 137, 160), (112, 141, 160), (112, 141, 170), (108, 141, 170), + (108, 137, 170), (108, 137, 170), (112, 133, 160), (116, 129, 141), + (104, 121, 132), (100, 117, 132), (100, 129, 132), (104, 133, 141), + (116, 133, 141), (116, 133, 151), (133, 141, 160), (145, 145, 160), + (166, 153, 151), (174, 161, 151), (182, 166, 160), (222, 189, 179), + (230, 201, 188), (206, 206, 216), (210, 222, 235), (222, 230, 244), + (222, 234, 254), (222, 234, 254), (226, 234, 254), (226, 234, 254), + (226, 242, 254), (226, 246, 254), (226, 246, 254), (230, 250, 254), + (234, 250, 254), (234, 250, 254), (230, 246, 254), (226, 246, 254), + (222, 242, 254), (218, 242, 244), (210, 238, 225), (193, 230, 216), + (202, 214, 197), (218, 193, 169), (202, 181, 151), (186, 169, 160), + (186, 181, 170), (189, 218, 207), (206, 238, 226), (214, 238, 235), + (222, 238, 244), (218, 234, 244), (213, 222, 244), (205, 218, 244), + (205, 218, 244), (197, 210, 235), (201, 206, 226), (193, 206, 226), + (189, 206, 226), (197, 214, 226), (214, 238, 226), (226, 242, 235), + (230, 246, 244), (230, 246, 244), (226, 246, 244), (222, 238, 244), + (222, 234, 244), (213, 218, 244), (201, 209, 235), (185, 201, 226), + (177, 193, 216), (161, 161, 179), (166, 153, 179), (170, 154, 151), + (178, 161, 151), (178, 169, 151), (202, 173, 151), (222, 193, 169), + (234, 205, 188), (246, 218, 216), (250, 230, 225), (230, 242, 244), + (226, 242, 254), (226, 242, 254), (226, 242, 254), (226, 242, 254), + (225, 238, 254), (222, 238, 254), (222, 238, 254), (222, 238, 254), + (222, 234, 254), (218, 234, 235), (217, 238, 225), (201, 234, 207), + (186, 222, 179), (162, 194, 160), (150, 182, 151), (129, 166, 141), + (125, 158, 132), (141, 146, 122), (145, 141, 132), (174, 153, 132), + (194, 161, 132), (202, 160, 132), (222, 189, 169), (234, 205, 188), + (238, 221, 216), (234, 234, 235), (226, 238, 244), (226, 238, 254), + (226, 238, 254), (226, 238, 254), (226, 238, 254), (230, 242, 254), + (230, 250, 244), (234, 254, 244), (246, 254, 235), (254, 245, 235), + (250, 242, 254), (238, 250, 254), (234, 246, 254), (234, 246, 244), + (234, 246, 244), (230, 242, 244), (226, 238, 244), (226, 242, 244), + (226, 242, 244), (226, 246, 244), (226, 246, 244), (226, 250, 244), + (226, 246, 244), (222, 242, 244), (222, 238, 244), (222, 234, 244), + (214, 226, 244), (205, 218, 244), (185, 201, 235), (173, 193, 216), + (145, 165, 188), (129, 153, 170), (125, 149, 160), (120, 146, 160), + (112, 146, 160), (112, 146, 151), (112, 142, 160), (112, 141, 160), + (112, 141, 170), (116, 141, 170), (116, 141, 170), (112, 141, 169) + ), + +// 45 purple-dress +((198, 96, 142), (206, 108, 142), (198, 136, 122), (178, 153, 132), + (182, 149, 141), (174, 149, 132), (158, 137, 113), (153, 120, 103), + (153, 111, 103), (153, 107, 94), (146, 104, 85), (137, 100, 84), + (121, 92, 84), (109, 89, 84), (109, 85, 84), (109, 85, 84), + (117, 84, 84), (137, 96, 94), (149, 104, 94), (170, 88, 113), + (178, 92, 123), (178, 88, 132), (186, 96, 142), (194, 100, 142), + (194, 104, 132), (182, 128, 113), (173, 132, 113), (162, 136, 113), + (154, 137, 113), (153, 133, 113), (157, 124, 113), (154, 116, 113), + (169, 92, 123), (177, 88, 132), (190, 100, 142), (206, 108, 151), + (219, 121, 170), (238, 141, 188), (246, 168, 207), (246, 205, 188), + (219, 173, 151), (246, 188, 178), (249, 225, 225), (190, 161, 151), + (174, 149, 132), (165, 128, 113), (165, 115, 94), (166, 111, 94), + (174, 120, 103), (170, 132, 113), (166, 141, 122), (165, 141, 122), + (161, 141, 132), (157, 137, 132), (157, 137, 141), (169, 141, 141), + (174, 150, 151), (178, 157, 141), (182, 157, 141), (178, 153, 141), + (186, 161, 151), (210, 117, 161), (218, 121, 161), (219, 121, 161), + (218, 112, 161), (222, 125, 160), (219, 157, 141), (219, 161, 141), + (202, 153, 122), (170, 140, 122), (161, 124, 122), (157, 96, 132), + (149, 88, 132), (153, 88, 132), (157, 84, 122), (161, 80, 123), + (169, 84, 142), (173, 92, 142), (177, 88, 142), (169, 88, 132), + (157, 84, 122), (149, 80, 113), (141, 80, 103), (137, 92, 94), + (145, 104, 94), (146, 116, 94), (145, 124, 103), (150, 129, 103), + (154, 128, 103), (161, 124, 94), (158, 116, 94), (158, 112, 94), + (153, 124, 113), (150, 128, 113), (150, 133, 113), (145, 133, 113), + (145, 133, 122), (153, 129, 132), (153, 133, 132), (154, 133, 132), + (154, 133, 122), (153, 133, 122), (153, 133, 113), (161, 128, 113), + (165, 120, 113), (186, 104, 123), (190, 96, 123), (198, 100, 132), + (202, 104, 132), (198, 104, 132), (182, 100, 132), (170, 112, 123), + (157, 128, 122), (162, 137, 122), (162, 140, 122), (161, 133, 113), + (170, 124, 113), (186, 104, 132), (198, 104, 132), (202, 104, 142), + (206, 104, 142), (206, 104, 142), (202, 100, 142), (202, 96, 142), + (198, 100, 142), (198, 104, 142), (202, 104, 142), (198, 100, 151), + (198, 101, 151), (198, 108, 151), (190, 100, 151), (198, 100, 151), + (194, 100, 142), (190, 104, 142), (182, 104, 132), (165, 120, 113), + (158, 124, 113), (158, 120, 113), (153, 108, 113), (153, 88, 122), + (165, 92, 122), (166, 104, 104), (157, 112, 104), (157, 120, 113), + (154, 120, 113), (149, 125, 113), (149, 116, 113), (141, 112, 103), + (133, 112, 103), (133, 108, 103), (133, 100, 94), (117, 92, 84), + (109, 85, 84), (97, 81, 84), (97, 85, 84), (117, 96, 84), + (145, 104, 94), (157, 111, 103), (174, 100, 123), (186, 96, 132), + (190, 100, 132), (190, 92, 132), (182, 100, 132), (157, 120, 122), + (141, 112, 113), (133, 104, 103), (117, 100, 103), (121, 108, 113), + (137, 116, 113), (145, 124, 113), (149, 129, 122), (153, 132, 122), + (157, 133, 122), (161, 141, 122), (165, 141, 122), (165, 137, 132), + (166, 137, 132), (186, 104, 142), (194, 100, 142), (198, 100, 142), + (198, 104, 142), (194, 100, 142), (190, 104, 132), (178, 124, 113), + (162, 124, 104), (145, 120, 113), (129, 112, 103), (108, 96, 94), + (100, 88, 94), (109, 89, 84), (121, 96, 84), (133, 100, 94), + (141, 104, 94), (137, 104, 94), (121, 100, 94), (108, 92, 94), + (100, 84, 94), (97, 81, 84), (89, 81, 75), (89, 73, 75), + (89, 73, 75), (93, 77, 84), (104, 84, 93), (133, 92, 94), + (161, 84, 122), (186, 96, 142), (198, 104, 151), (210, 112, 161), + (222, 125, 170), (238, 137, 188), (238, 137, 188), (234, 133, 189), + (222, 121, 170), (210, 112, 151), (202, 132, 122), (190, 136, 113), + (202, 149, 113), (186, 132, 104), (182, 128, 103), (182, 123, 104), + (166, 120, 113), (169, 88, 123), (165, 84, 123), (161, 80, 122), + (153, 76, 122), (153, 84, 122), (137, 92, 113), (141, 100, 103), + (141, 112, 113), (149, 120, 122), (145, 116, 122), (145, 120, 122), + (149, 124, 122), (157, 133, 122), (166, 141, 122), (170, 145, 122), + (170, 145, 122), (170, 145, 132), (162, 141, 132), (166, 141, 132), + (170, 137, 132), (194, 108, 151), (198, 112, 161), (198, 108, 161), + (202, 100, 161), (206, 104, 151), (206, 108, 151), (210, 108, 151), + (206, 100, 151), (202, 100, 151), (202, 100, 151), (202, 96, 142), + (198, 96, 142), (194, 92, 132), (178, 88, 123), (166, 84, 123) + ), + +// 46 no-name +((121, 92, 75), (162, 132, 103), (182, 152, 122), (198, 169, 141), + (210, 189, 160), (206, 210, 188), (194, 198, 188), (202, 185, 170), + (206, 181, 160), (206, 177, 151), (202, 177, 160), (198, 177, 151), + (194, 173, 160), (194, 173, 160), (194, 173, 160), (198, 173, 151), + (194, 165, 151), (186, 157, 141), (186, 153, 132), (186, 148, 122), + (170, 128, 94), (145, 84, 66), (109, 64, 37), (81, 68, 37), + (64, 60, 37), (48, 56, 37), (56, 52, 28), (48, 60, 37), + (56, 60, 37), (60, 60, 37), (72, 68, 37), (89, 51, 28), + (109, 59, 28), (133, 72, 28), (166, 115, 66), (186, 148, 103), + (190, 157, 132), (194, 165, 151), (190, 181, 170), (202, 206, 207), + (202, 214, 207), (197, 214, 216), (197, 214, 216), (197, 214, 216), + (193, 214, 216), (197, 214, 216), (201, 214, 216), (206, 214, 216), + (206, 210, 216), (206, 214, 207), (202, 214, 198), (194, 206, 188), + (186, 182, 169), (190, 173, 141), (194, 173, 113), (202, 173, 113), + (214, 181, 122), (230, 193, 141), (230, 201, 160), (234, 201, 169), + (234, 205, 169), (234, 205, 169), (230, 201, 169), (230, 197, 160), + (222, 189, 160), (202, 169, 141), (182, 153, 122), (158, 141, 94), + (121, 76, 56), (85, 52, 37), (68, 35, 28), (60, 40, 37), + (48, 39, 37), (52, 44, 28), (44, 44, 37), (44, 44, 37), + (44, 52, 37), (40, 44, 28), (36, 44, 37), (40, 48, 47), + (44, 44, 47), (48, 44, 47), (56, 48, 56), (68, 48, 56), + (72, 52, 47), (92, 68, 46), (105, 93, 65), (137, 141, 85), + (146, 154, 94), (154, 153, 103), (158, 157, 113), (129, 141, 132), + (84, 97, 85), (64, 81, 66), (44, 60, 47), (36, 44, 47), + (28, 32, 28), (31, 24, 18), (24, 28, 28), (20, 28, 28), + (20, 24, 28), (20, 24, 28), (20, 24, 28), (20, 32, 28), + (20, 32, 28), (20, 32, 28), (20, 36, 28), (32, 36, 37), + (40, 44, 47), (52, 52, 47), (64, 52, 47), (72, 68, 56), + (93, 105, 66), (133, 146, 94), (178, 169, 113), (222, 193, 151), + (234, 205, 169), (242, 217, 188), (222, 226, 207), (222, 226, 216), + (226, 222, 216), (226, 230, 216), (218, 226, 216), (202, 218, 216), + (201, 214, 216), (201, 210, 216), (202, 218, 216), (206, 218, 207), + (210, 218, 207), (234, 209, 179), (230, 205, 169), (226, 193, 160), + (202, 173, 132), (190, 165, 113), (162, 149, 94), (113, 97, 75), + (85, 80, 56), (64, 68, 47), (52, 56, 47), (44, 48, 47), + (40, 52, 47), (44, 52, 56), (52, 60, 56), (72, 72, 66), + (93, 80, 65), (105, 121, 85), (137, 150, 94), (166, 165, 103), + (178, 153, 113), (190, 169, 122), (194, 169, 132), (198, 169, 141), + (202, 185, 160), (202, 214, 198), (198, 214, 207), (198, 210, 207), + (189, 210, 207), (181, 198, 188), (190, 177, 170), (182, 161, 151), + (178, 145, 122), (146, 92, 75), (129, 68, 46), (129, 68, 47), + (141, 112, 85), (186, 153, 122), (219, 193, 160), (234, 209, 178), + (214, 214, 207), (210, 218, 207), (206, 218, 207), (206, 214, 198), + (194, 177, 170), (186, 153, 141), (169, 140, 113), (125, 104, 75), + (97, 80, 75), (77, 77, 66), (72, 76, 75), (97, 109, 75), + (146, 146, 94), (182, 157, 122), (202, 173, 141), (219, 185, 151), + (226, 189, 141), (214, 164, 132), (198, 161, 113), (182, 140, 94), + (141, 92, 66), (109, 59, 46), (117, 72, 46), (146, 88, 66), + (182, 131, 94), (202, 157, 122), (230, 193, 141), (242, 201, 150), + (242, 213, 169), (242, 213, 178), (238, 213, 178), (230, 201, 160), + (226, 193, 141), (206, 168, 113), (194, 161, 94), (170, 153, 103), + (137, 145, 85), (109, 104, 66), (77, 77, 56), (64, 64, 56), + (64, 64, 56), (76, 72, 66), (97, 88, 75), (129, 125, 85), + (169, 149, 122), (182, 145, 132), (190, 145, 132), (190, 157, 132), + (190, 157, 132), (194, 161, 132), (186, 157, 132), (178, 145, 122), + (137, 104, 84), (109, 64, 56), (72, 64, 56), (64, 60, 56), + (60, 64, 47), (60, 68, 47), (60, 64, 47), (68, 64, 56), + (93, 81, 65), (125, 133, 85), (150, 145, 103), (178, 153, 122), + (186, 165, 132), (190, 165, 132), (190, 161, 141), (194, 165, 141), + (190, 165, 132), (190, 165, 132), (190, 164, 132), (190, 161, 122), + (174, 152, 113), (150, 145, 94), (113, 84, 65), (89, 72, 56), + (68, 64, 47), (52, 48, 37), (36, 28, 37), (28, 28, 37), + (19, 32, 37), (16, 24, 28), (19, 20, 18), (16, 20, 28), + (20, 24, 28), (24, 28, 28), (32, 40, 28), (48, 44, 28) + ), + +// 47 spring-flora +((51, 67, 36), (53, 66, 34), (51, 62, 29), (40, 51, 23), +(40, 42, 26), (37, 43, 25), (36, 48, 25), (32, 46, 23), +(34, 44, 22), (21, 28, 17), (18, 19, 14), (16, 17, 11), +(15, 17, 11), (13, 15, 10), (13, 14, 12), (13, 14, 12), +(15, 17, 13), (17, 21, 14), (26, 35, 21), (34, 44, 28), +(42, 51, 39), (49, 59, 39), (50, 64, 54), (55, 57, 63), +(57, 54, 66), (55, 37, 59), (50, 27, 51), (44, 38, 28), +(26, 32, 18), (17, 20, 14), (15, 18, 12), (14, 16, 10), +(14, 14, 9), (18, 18, 13), (19, 23, 16), (31, 41, 36), +(44, 40, 58), (52, 48, 72), (66, 53, 79), (65, 63, 76), +(63, 61, 68), (54, 63, 42), (53, 66, 34), (46, 67, 34), +(46, 62, 32), (35, 51, 24), (26, 35, 19), (18, 19, 14), +(12, 13, 9), (9, 10, 7), (8, 6, 5), (7, 5, 4), +(9, 6, 6), (11, 9, 9), (14, 15, 11), (21, 22, 15), +(44, 31, 50), (48, 27, 54), (55, 39, 59), (53, 32, 59), +(48, 38, 62), (44, 43, 55), (50, 59, 42), (53, 67, 39), +(54, 72, 45), (58, 79, 44), (63, 87, 44), (61, 87, 42), +(58, 79, 42), (56, 74, 36), (50, 72, 34), (45, 66, 34), +(36, 57, 31), (32, 44, 26), (23, 33, 20), (16, 20, 15), +(15, 19, 12), (17, 19, 13), (17, 20, 15), (23, 33, 22), +(30, 46, 29), (36, 55, 32), (41, 62, 33), (46, 67, 34), +(48, 66, 36), (50, 66, 37), (50, 66, 37), (53, 66, 37), +(51, 67, 39), (53, 67, 38), (55, 72, 42), (57, 72, 42), +(52, 72, 45), (52, 72, 45), (49, 72, 45), (49, 72, 42), +(50, 72, 37), (50, 72, 37), (47, 72, 42), (51, 74, 39), +(57, 72, 34), (55, 72, 39), (57, 75, 39), (61, 79, 39), +(70, 81, 37), (76, 89, 51), (82, 102, 67), (86, 112, 73), +(100, 114, 76), (89, 118, 60), (102, 126, 88), (114, 140, 97), +(135, 152, 98), (112, 127, 93), (118, 140, 93), (191, 174, 163), +(143, 154, 113), (99, 127, 100), (93, 120, 59), (79, 102, 60), +(82, 103, 67), (83, 104, 71), (86, 103, 72), (86, 103, 64), +(87, 87, 52), (73, 88, 50), (76, 80, 52), (62, 87, 57), +(70, 88, 50), (71, 84, 56), (70, 75, 50), (67, 74, 44), +(57, 72, 42), (52, 72, 42), (47, 66, 40), (41, 54, 36), +(34, 42, 25), (21, 27, 16), (16, 19, 12), (12, 11, 10), +(10, 8, 7), (7, 5, 5), (6, 4, 4), (5, 4, 3), +(5, 3, 4), (5, 4, 3), (5, 5, 5), (6, 5, 5), +(6, 4, 5), (7, 4, 5), (7, 4, 5), (7, 5, 5), +(8, 6, 6), (10, 8, 7), (13, 11, 10), (14, 15, 11), +(19, 21, 15), (39, 33, 23), (48, 47, 30), (60, 57, 53), +(79, 65, 97), (74, 58, 76), (106, 59, 79), (96, 90, 85), +(84, 62, 85), (88, 79, 94), (80, 82, 72), (70, 69, 59), +(57, 69, 54), (60, 79, 47), (58, 79, 47), (58, 79, 46), +(54, 79, 44), (53, 79, 44), (53, 79, 44), (53, 79, 47), +(55, 79, 50), (60, 79, 50), (62, 87, 49), (60, 87, 52), +(61, 94, 52), (67, 94, 52), (76, 94, 56), (86, 118, 56), +(80, 96, 53), (83, 109, 44), (83, 110, 55), (76, 103, 55), +(73, 102, 54), (68, 88, 50), (63, 79, 44), (57, 72, 39), +(55, 72, 34), (53, 67, 34), (50, 66, 37), (44, 62, 36), +(44, 55, 38), (41, 57, 35), (40, 61, 36), (41, 62, 38), +(44, 72, 42), (55, 79, 41), (61, 87, 47), (67, 94, 47), +(77, 103, 53), (89, 118, 57), (86, 117, 57), (89, 118, 76), +(114, 127, 85), (106, 126, 97), (93, 119, 76), (82, 117, 72), +(73, 102, 59), (60, 87, 52), (49, 72, 45), (39, 57, 34), +(32, 46, 27), (23, 33, 18), (17, 23, 13), (17, 21, 13), +(17, 20, 14), (22, 27, 17), (33, 42, 25), (36, 47, 28), +(44, 57, 31), (49, 62, 33), (49, 63, 35), (45, 58, 33), +(37, 51, 27), (32, 44, 23), (23, 33, 17), (16, 21, 13), +(12, 15, 8), (11, 13, 7), (11, 11, 7), (10, 14, 8), +(12, 12, 9), (13, 15, 8), (15, 19, 11), (19, 23, 15), +(29, 44, 22), (35, 52, 29), (39, 57, 30), (46, 67, 28), +(50, 66, 28), (47, 72, 29), (47, 63, 30), (39, 57, 27), +(32, 51, 25), (28, 40, 25), (21, 26, 17), (19, 23, 15), +(28, 35, 21), (35, 47, 26), (46, 62, 33), (53, 67, 39) +), + +// 48 andi +((53, 15, 5), (77, 47, 22), (92, 69, 39), (112, 83, 55), +(126, 90, 59), (138, 87, 63), (140, 90, 66), (140, 93, 64), +(137, 88, 50), (122, 82, 32), (100, 62, 19), (72, 31, 12), +(52, 2, 1), (20, 0, 0), (2, 0, 0), (2, 0, 0), +(24, 21, 12), (72, 34, 30), (82, 53, 47), (97, 62, 41), +(108, 71, 42), (122, 77, 55), (132, 81, 65), (136, 92, 71), +(137, 92, 71), (137, 94, 71), (136, 92, 71), (135, 82, 69), +(132, 74, 61), (115, 67, 53), (106, 59, 54), (85, 45, 42), +(48, 13, 21), (16, 2, 1), (0, 0, 0), (0, 0, 0), +(0, 0, 0), (2, 0, 0), (46, 17, 5), (73, 36, 18), +(84, 60, 38), (116, 76, 52), (137, 83, 59), (148, 94, 71), +(157, 104, 76), (162, 109, 79), (160, 118, 82), (156, 116, 79), +(153, 110, 79), (148, 102, 73), (148, 93, 72), (143, 87, 65), +(145, 81, 58), (144, 81, 55), (146, 79, 49), (140, 81, 48), +(143, 84, 48), (149, 88, 63), (151, 91, 65), (148, 90, 67), +(145, 87, 68), (144, 87, 68), (138, 91, 68), (137, 88, 62), +(118, 85, 56), (111, 83, 43), (100, 74, 36), (100, 63, 33), +(100, 56, 24), (94, 63, 20), (96, 52, 20), (87, 56, 18), +(88, 48, 14), (72, 38, 7), (68, 23, 6), (69, 20, 11), +(83, 34, 12), (97, 43, 28), (100, 46, 40), (114, 66, 50), +(122, 87, 64), (129, 104, 76), (142, 119, 101), (162, 134, 122), +(170, 150, 140), (168, 162, 155), (184, 175, 167), (178, 167, 159), +(174, 157, 148), (164, 151, 133), (163, 143, 115), (149, 127, 91), +(140, 106, 63), (117, 76, 51), (89, 46, 30), (57, 13, 4), +(23, 0, 0), (2, 0, 0), (0, 0, 0), (0, 0, 0), +(19, 6, 1), (56, 21, 8), (86, 50, 35), (108, 57, 48), +(126, 65, 49), (130, 68, 57), (128, 72, 48), (133, 65, 46), +(128, 68, 40), (135, 65, 29), (120, 66, 24), (130, 57, 20), +(97, 47, 11), (73, 23, 7), (63, 14, 2), (54, 0, 0), +(54, 0, 0), (65, 18, 11), (83, 55, 30), (89, 61, 37), +(105, 74, 43), (116, 89, 52), (130, 96, 61), (129, 97, 66), +(132, 96, 71), (141, 100, 78), (142, 109, 76), (145, 108, 76), +(149, 114, 80), (151, 116, 80), (151, 117, 84), (154, 119, 87), +(170, 128, 103), (177, 137, 108), (173, 147, 120), (172, 152, 124), +(176, 156, 141), (187, 171, 142), (182, 172, 146), (174, 157, 140), +(172, 156, 121), (161, 145, 106), (155, 136, 98), (153, 132, 93), +(148, 118, 87), (150, 108, 77), (149, 100, 74), (150, 93, 72), +(145, 92, 61), (143, 89, 62), (140, 85, 57), (140, 89, 52), +(138, 100, 54), (134, 101, 59), (135, 99, 59), (141, 97, 64), +(142, 94, 66), (138, 98, 59), (132, 99, 54), (130, 96, 49), +(120, 91, 38), (105, 60, 17), (94, 14, 3), (61, 0, 0), +(59, 4, 2), (68, 13, 17), (88, 27, 10), (96, 48, 19), +(111, 73, 37), (125, 88, 42), (130, 94, 50), (140, 96, 58), +(148, 97, 69), (150, 98, 73), (153, 103, 80), (158, 110, 79), +(155, 110, 84), (158, 110, 80), (157, 105, 79), (155, 102, 75), +(152, 98, 73), (154, 97, 72), (163, 96, 70), (164, 106, 80), +(165, 112, 81), (164, 117, 80), (163, 118, 81), (162, 120, 81), +(158, 117, 80), (152, 109, 77), (140, 100, 73), (126, 87, 68), +(118, 80, 61), (105, 63, 45), (91, 53, 25), (88, 44, 12), +(86, 40, 15), (104, 35, 17), (117, 57, 30), (117, 68, 42), +(131, 80, 42), (127, 82, 47), (124, 86, 46), (126, 82, 39), +(120, 86, 40), (109, 68, 30), (104, 60, 25), (95, 65, 24), +(101, 66, 21), (103, 65, 36), (107, 72, 39), (116, 82, 42), +(124, 88, 46), (124, 91, 52), (121, 100, 56), (126, 102, 62), +(131, 100, 70), (136, 96, 72), (140, 95, 72), (142, 93, 72), +(142, 96, 72), (143, 93, 68), (140, 93, 70), (140, 90, 70), +(142, 89, 70), (140, 82, 64), (137, 75, 60), (132, 77, 55), +(125, 87, 60), (120, 89, 62), (128, 104, 70), (136, 111, 76), +(147, 118, 89), (156, 135, 117), (159, 145, 124), (174, 148, 130), +(179, 151, 125), (174, 151, 119), (173, 148, 113), (178, 146, 100), +(170, 143, 112), (161, 138, 109), (161, 134, 92), (160, 125, 81), +(161, 135, 91), (170, 123, 85), (164, 122, 88), (153, 130, 80), +(152, 118, 84), (148, 119, 80), (139, 111, 77), (141, 111, 73), +(137, 109, 79), (135, 108, 93), (143, 111, 94), (148, 128, 100) +), + +// 49 gig-o835 +((56, 97, 85), (76, 105, 84), (77, 117, 84), (76, 109, 94), +(84, 109, 94), (88, 113, 94), (92, 125, 94), (101, 121, 103), +(105, 133, 113), (113, 145, 122), (113, 149, 122), (101, 141, 113), +(92, 125, 103), (84, 113, 94), (81, 101, 75), (56, 97, 66), +(52, 89, 66), (36, 81, 66), (28, 77, 66), (44, 72, 47), +(20, 60, 47), (20, 60, 47), (16, 68, 66), (16, 68, 66), +(4, 68, 75), (4, 81, 84), (12, 89, 103), (16, 101, 122), +(28, 101, 122), (28, 105, 122), (28, 113, 122), (36, 105, 122), +(36, 105, 122), (48, 105, 122), (52, 105, 113), (48, 109, 103), +(44, 101, 93), (40, 97, 84), (48, 89, 75), (40, 76, 56), +(24, 72, 56), (28, 72, 56), (24, 76, 56), (40, 72, 66), +(48, 89, 75), (56, 93, 84), (68, 105, 103), (68, 117, 122), +(68, 117, 122), (72, 117, 122), (72, 121, 113), (76, 121, 113), +(84, 125, 103), (89, 125, 103), (92, 121, 113), (93, 129, 103), +(104, 145, 122), (100, 157, 141), (121, 162, 150), (125, 166, 169), +(161, 182, 169), (173, 210, 197), (161, 186, 160), (137, 178, 179), +(121, 165, 160), (108, 145, 141), (92, 141, 131), (80, 129, 131), +(80, 125, 122), (76, 125, 122), (76, 129, 112), (72, 125, 103), +(72, 117, 103), (72, 117, 103), (68, 121, 113), (60, 121, 112), +(52, 117, 122), (48, 121, 131), (40, 117, 141), (40, 113, 141), +(48, 121, 150), (56, 117, 160), (64, 125, 150), (76, 125, 132), +(89, 138, 132), (100, 146, 141), (112, 154, 150), (117, 149, 151), +(116, 145, 150), (112, 149, 150), (100, 146, 160), (80, 142, 160), +(60, 130, 150), (48, 121, 141), (36, 117, 131), (36, 113, 131), +(56, 113, 131), (68, 121, 131), (76, 125, 132), (84, 137, 131), +(96, 142, 141), (100, 149, 150), (100, 146, 160), (104, 150, 160), +(100, 142, 160), (100, 133, 150), (92, 129, 132), (88, 125, 122), +(89, 121, 103), (80, 113, 103), (72, 105, 94), (72, 101, 85), +(64, 93, 75), (36, 93, 84), (28, 97, 93), (12, 81, 84), +(12, 89, 103), (4, 77, 103), (16, 93, 103), (19, 97, 103), +(32, 93, 94), (48, 97, 94), (64, 105, 94), (76, 117, 94), +(93, 121, 103), (97, 121, 103), (92, 125, 113), (84, 125, 113), +(92, 129, 113), (84, 133, 113), (88, 129, 122), (88, 129, 122), +(92, 129, 122), (96, 129, 122), (108, 129, 122), (112, 141, 132), +(109, 153, 131), (108, 146, 141), (113, 149, 141), (125, 149, 132), +(113, 150, 132), (108, 153, 141), (108, 162, 150), (113, 166, 150), +(112, 154, 141), (116, 149, 141), (117, 153, 141), (120, 154, 151), +(125, 162, 151), (133, 162, 151), (141, 170, 151), (145, 174, 160), +(141, 178, 169), (137, 182, 179), (133, 162, 160), (125, 162, 141), +(121, 157, 132), (117, 146, 122), (109, 145, 122), (96, 133, 113), +(88, 121, 113), (84, 113, 103), (76, 113, 103), (68, 113, 103), +(60, 105, 103), (52, 101, 94), (48, 101, 103), (28, 101, 112), +(32, 109, 131), (28, 105, 132), (32, 113, 132), (39, 117, 131), +(56, 121, 132), (68, 125, 131), (68, 125, 131), (76, 129, 131), +(73, 130, 132), (72, 134, 141), (81, 134, 151), (80, 134, 160), +(84, 134, 150), (84, 134, 141), (88, 129, 132), (100, 133, 132), +(100, 137, 132), (100, 142, 132), (100, 137, 141), (100, 142, 141), +(97, 142, 132), (92, 146, 121), (88, 133, 122), (88, 129, 122), +(88, 129, 122), (88, 133, 122), (96, 137, 122), (96, 137, 122), +(108, 145, 132), (112, 141, 132), (108, 145, 141), (116, 141, 141), +(108, 141, 150), (96, 146, 160), (72, 130, 160), (60, 126, 150), +(44, 117, 141), (36, 109, 131), (40, 105, 122), (44, 109, 122), +(60, 113, 122), (72, 121, 122), (85, 129, 122), (96, 133, 131), +(100, 133, 132), (104, 133, 132), (104, 137, 141), (108, 137, 141), +(104, 133, 141), (100, 133, 132), (92, 121, 122), (88, 117, 122), +(76, 117, 113), (80, 117, 103), (76, 117, 103), (72, 117, 103), +(68, 113, 103), (64, 113, 113), (56, 109, 113), (56, 109, 113), +(48, 113, 113), (52, 113, 112), (60, 117, 122), (73, 126, 132), +(80, 130, 160), (88, 138, 170), (80, 138, 170), (68, 134, 160), +(56, 130, 160), (40, 117, 160), (28, 113, 141), (20, 101, 141), +(24, 97, 132), (16, 97, 122), (20, 97, 112), (36, 97, 94), +(48, 101, 93), (60, 105, 94), (72, 117, 94), (77, 121, 103), +(84, 125, 122), (84, 134, 132), (88, 134, 150), (88, 137, 160), +(84, 142, 160), (76, 133, 141), (80, 125, 132), (80, 121, 122) +), + +// 50 rie02 +((48, 72, 37), (60, 85, 28), (48, 88, 28), (60, 76, 37), +(56, 64, 37), (48, 52, 28), (44, 48, 28), (36, 44, 28), +(24, 36, 18), (20, 36, 18), (24, 40, 18), (28, 44, 18), +(36, 40, 18), (36, 28, 18), (20, 20, 18), (12, 16, 9), +(16, 20, 9), (20, 24, 9), (28, 28, 9), (40, 44, 18), +(56, 52, 28), (68, 64, 37), (88, 72, 47), (85, 93, 47), +(85, 100, 56), (88, 96, 75), (93, 97, 75), (92, 97, 66), +(85, 101, 56), (88, 105, 66), (89, 105, 75), (84, 105, 66), +(89, 113, 66), (113, 141, 85), (133, 157, 122), (141, 190, 150), +(145, 182, 169), (129, 189, 188), (169, 181, 179), (177, 189, 169), +(210, 230, 160), (222, 234, 179), (246, 241, 159), (214, 230, 141), +(190, 218, 160), (198, 226, 122), (234, 246, 121), (218, 209, 112), +(157, 173, 93), (125, 149, 94), (121, 149, 84), (101, 125, 66), +(93, 109, 66), (89, 101, 47), (89, 117, 47), (101, 113, 47), +(113, 125, 56), (125, 133, 75), (153, 141, 84), (153, 157, 103), +(162, 194, 103), (182, 202, 103), (182, 190, 84), (194, 152, 112), +(137, 129, 94), (113, 113, 75), (89, 109, 66), (72, 92, 56), +(60, 89, 56), (56, 92, 56), (60, 93, 47), (64, 88, 47), +(56, 89, 56), (52, 89, 56), (52, 80, 56), (56, 80, 56), +(48, 72, 47), (44, 72, 47), (36, 60, 47), (32, 52, 56), +(36, 56, 66), (36, 56, 56), (36, 68, 56), (48, 88, 56), +(68, 101, 65), (97, 125, 85), (113, 149, 94), (145, 170, 122), +(149, 177, 112), (125, 153, 103), (97, 121, 84), (85, 93, 66), +(60, 64, 66), (36, 44, 47), (20, 36, 28), (12, 24, 18), +(8, 16, 0), (12, 12, 0), (20, 24, 18), (32, 48, 28), +(44, 60, 37), (68, 76, 47), (72, 89, 47), (64, 84, 47), +(81, 88, 47), (72, 93, 28), (60, 76, 47), (56, 56, 47), +(44, 56, 37), (32, 52, 28), (24, 52, 28), (20, 44, 18), +(28, 48, 9), (24, 48, 18), (28, 56, 28), (24, 56, 37), +(24, 56, 37), (28, 56, 37), (36, 60, 47), (48, 72, 37), +(52, 88, 37), (60, 97, 37), (60, 93, 47), (60, 96, 46), +(48, 76, 47), (40, 68, 37), (32, 52, 28), (28, 56, 28), +(16, 44, 18), (16, 40, 18), (16, 44, 9), (28, 48, 9), +(44, 52, 28), (36, 56, 18), (40, 64, 18), (36, 72, 37), +(44, 76, 37), (44, 76, 37), (40, 72, 37), (44, 56, 28), +(36, 52, 28), (28, 48, 28), (32, 40, 28), (32, 32, 18), +(24, 32, 28), (20, 40, 28), (28, 40, 37), (28, 36, 28), +(24, 40, 37), (24, 44, 37), (24, 52, 47), (28, 44, 47), +(28, 40, 37), (28, 48, 37), (20, 40, 37), (12, 40, 28), +(20, 32, 18), (16, 20, 18), (12, 20, 18), (12, 24, 9), +(12, 24, 9), (16, 36, 18), (20, 52, 28), (24, 60, 37), +(32, 76, 47), (44, 80, 56), (44, 81, 47), (48, 97, 47), +(60, 121, 37), (64, 109, 37), (72, 101, 47), (60, 93, 56), +(56, 89, 75), (60, 80, 94), (76, 93, 103), (88, 121, 94), +(101, 129, 75), (97, 145, 75), (93, 133, 56), (113, 157, 65), +(93, 121, 66), (85, 117, 47), (77, 101, 47), (68, 85, 37), +(60, 68, 37), (60, 56, 37), (56, 52, 37), (60, 60, 47), +(80, 80, 56), (88, 104, 75), (117, 129, 94), (149, 173, 113), +(166, 186, 141), (166, 198, 122), (173, 186, 132), (162, 178, 122), +(133, 149, 94), (117, 133, 75), (93, 113, 75), (84, 105, 75), +(60, 97, 75), (64, 68, 66), (44, 64, 75), (36, 52, 66), +(28, 56, 66), (28, 56, 66), (32, 48, 56), (36, 48, 47), +(52, 48, 28), (48, 56, 37), (48, 44, 28), (44, 52, 28), +(56, 56, 28), (60, 60, 28), (64, 68, 37), (80, 80, 56), +(105, 101, 66), (129, 129, 85), (133, 133, 113), (129, 137, 122), +(117, 145, 103), (121, 157, 84), (113, 145, 66), (97, 117, 66), +(76, 105, 56), (72, 113, 56), (68, 129, 56), (60, 125, 55), +(52, 109, 65), (52, 97, 65), (64, 105, 75), (89, 133, 94), +(125, 149, 113), (162, 174, 132), (153, 198, 151), (170, 198, 141), +(169, 206, 141), (174, 210, 132), (181, 214, 131), (169, 214, 140), +(174, 222, 141), (182, 206, 151), (190, 202, 150), (198, 198, 150), +(218, 213, 141), (214, 214, 160), (189, 206, 141), (190, 210, 103), +(174, 210, 75), (117, 153, 56), (105, 133, 56), (105, 125, 56), +(109, 109, 56), (93, 113, 66), (105, 109, 75), (117, 125, 113) +), + +// 51 rie05 +((73, 125, 84), (77, 141, 83), (89, 146, 83), (104, 154, 94), +(109, 170, 103), (146, 198, 113), (162, 214, 132), (182, 226, 160), +(198, 234, 160), (206, 234, 169), (218, 242, 178), (222, 238, 169), +(218, 226, 150), (222, 230, 141), (218, 230, 131), (210, 222, 131), +(206, 222, 122), (190, 219, 113), (203, 226, 122), (206, 226, 103), +(218, 226, 94), (211, 222, 94), (198, 222, 75), (170, 210, 94), +(170, 206, 103), (150, 194, 113), (137, 174, 113), (121, 170, 103), +(129, 174, 113), (129, 182, 113), (146, 198, 132), (162, 222, 160), +(182, 218, 169), (210, 234, 197), (230, 246, 206), (230, 246, 216), +(230, 242, 207), (222, 234, 197), (214, 238, 188), (214, 234, 169), +(214, 230, 150), (210, 230, 131), (198, 230, 122), (186, 219, 122), +(170, 206, 122), (154, 198, 113), (137, 182, 85), (125, 178, 75), +(121, 170, 84), (137, 153, 94), (141, 174, 94), (162, 182, 113), +(193, 201, 141), (205, 205, 178), (222, 230, 197), (234, 250, 206), +(246, 254, 197), (254, 241, 169), (246, 234, 159), (242, 250, 112), +(230, 238, 94), (222, 234, 112), (198, 222, 113), (190, 219, 103), +(198, 206, 103), (186, 214, 103), (174, 214, 113), (166, 218, 113), +(182, 214, 113), (186, 219, 122), (198, 226, 132), (202, 226, 150), +(222, 222, 160), (238, 234, 159), (246, 233, 169), (226, 238, 178), +(210, 234, 169), (198, 234, 160), (198, 230, 150), (202, 226, 132), +(207, 230, 122), (198, 226, 122), (186, 222, 113), (178, 214, 103), +(166, 206, 103), (166, 202, 94), (150, 190, 84), (141, 186, 75), +(153, 174, 66), (165, 169, 66), (150, 182, 85), (158, 194, 94), +(162, 194, 103), (162, 206, 103), (158, 206, 103), (166, 210, 113), +(162, 202, 113), (162, 210, 122), (166, 214, 113), (158, 206, 94), +(142, 194, 85), (129, 174, 85), (121, 166, 75), (121, 174, 75), +(121, 157, 75), (129, 162, 75), (154, 148, 37), (137, 157, 75), +(109, 154, 75), (121, 162, 103), (137, 170, 132), (166, 198, 151), +(178, 218, 169), (182, 214, 179), (185, 210, 179), (178, 218, 169), +(154, 198, 141), (125, 178, 122), (125, 186, 113), (146, 194, 103), +(150, 194, 103), (150, 194, 103), (154, 194, 94), (146, 198, 85), +(142, 194, 85), (142, 182, 85), (141, 182, 84), (146, 194, 75), +(150, 194, 75), (154, 198, 75), (158, 194, 56), (170, 198, 56), +(162, 206, 66), (190, 210, 75), (230, 187, 28), (254, 198, 9), +(242, 208, 37), (242, 225, 75), (246, 237, 112), (222, 242, 159), +(226, 238, 178), (242, 242, 207), (246, 242, 216), (246, 246, 225), +(242, 242, 225), (242, 241, 216), (226, 242, 188), (206, 234, 179), +(194, 226, 150), (178, 214, 132), (162, 210, 122), (129, 194, 103), +(117, 166, 85), (109, 149, 65), (101, 153, 75), (89, 150, 74), +(97, 158, 75), (101, 162, 84), (113, 170, 85), (137, 194, 94), +(154, 206, 103), (170, 206, 94), (189, 193, 84), (238, 208, 65), +(254, 228, 84), (254, 233, 102), (254, 221, 93), (230, 205, 94), +(182, 206, 113), (153, 177, 122), (113, 154, 94), (100, 150, 94), +(84, 129, 93), (73, 121, 75), (65, 117, 65), (61, 113, 56), +(60, 109, 56), (65, 113, 47), (61, 109, 56), (65, 109, 56), +(65, 113, 56), (69, 117, 65), (77, 129, 65), (93, 141, 65), +(93, 150, 74), (113, 158, 85), (133, 170, 85), (146, 190, 103), +(150, 190, 122), (157, 190, 132), (158, 202, 132), (162, 210, 132), +(174, 219, 122), (186, 222, 122), (198, 230, 150), (206, 230, 169), +(214, 230, 179), (222, 234, 197), (230, 246, 216), (238, 237, 225), +(238, 234, 235), (238, 238, 216), (226, 238, 188), (214, 230, 160), +(194, 218, 141), (190, 198, 131), (174, 198, 122), (174, 202, 122), +(174, 214, 122), (182, 219, 122), (194, 214, 132), (198, 226, 160), +(202, 226, 160), (202, 226, 160), (190, 222, 179), (190, 222, 179), +(194, 230, 179), (202, 230, 178), (214, 234, 178), (222, 230, 179), +(218, 234, 178), (210, 230, 169), (206, 218, 169), (182, 222, 160), +(154, 194, 141), (129, 170, 113), (101, 154, 93), (81, 141, 83), +(81, 133, 83), (77, 125, 74), (73, 121, 74), (69, 129, 65), +(73, 121, 74), (77, 129, 74), (109, 133, 75), (97, 146, 75), +(108, 154, 94), (125, 178, 103), (150, 202, 113), (166, 210, 122), +(186, 222, 141), (194, 222, 151), (194, 218, 151), (182, 218, 151), +(162, 218, 131), (170, 214, 122), (174, 210, 122), (182, 210, 122), +(186, 214, 122), (190, 214, 122), (194, 218, 132), (198, 230, 141), +(202, 230, 150), (207, 230, 141), (202, 218, 131), (190, 206, 122) +), + +// 52 rie11 +((174, 144, 103), (129, 96, 85), (117, 80, 66), (105, 92, 56), +(113, 80, 47), (101, 92, 66), (109, 113, 85), (125, 137, 103), +(161, 136, 122), (198, 152, 122), (206, 157, 132), (174, 165, 132), +(145, 158, 103), (113, 117, 94), (88, 92, 66), (68, 68, 56), +(60, 56, 47), (52, 43, 37), (48, 40, 37), (44, 44, 28), +(44, 44, 28), (44, 44, 37), (48, 48, 47), (52, 52, 47), +(52, 52, 47), (52, 52, 47), (44, 52, 56), (52, 56, 56), +(56, 56, 56), (56, 56, 56), (56, 60, 56), (60, 60, 56), +(64, 60, 56), (68, 56, 56), (64, 56, 47), (60, 60, 47), +(56, 56, 37), (52, 52, 37), (48, 48, 37), (48, 44, 37), +(48, 44, 37), (48, 44, 47), (44, 44, 56), (40, 48, 56), +(44, 56, 56), (48, 60, 66), (52, 64, 75), (56, 72, 75), +(81, 85, 85), (105, 97, 84), (121, 121, 103), (153, 125, 103), +(174, 140, 122), (194, 148, 132), (190, 152, 132), (161, 141, 113), +(133, 121, 94), (113, 96, 66), (92, 80, 56), (68, 60, 47), +(60, 52, 37), (52, 43, 28), (48, 35, 28), (48, 40, 28), +(52, 52, 37), (52, 56, 47), (56, 60, 47), (60, 56, 47), +(56, 52, 47), (48, 52, 47), (40, 44, 37), (32, 36, 28), +(32, 36, 28), (28, 32, 28), (36, 36, 28), (48, 48, 37), +(68, 60, 47), (85, 72, 56), (113, 92, 75), (153, 129, 103), +(178, 153, 122), (198, 165, 151), (198, 165, 151), (198, 165, 141), +(158, 154, 113), (133, 133, 94), (101, 97, 66), (76, 60, 47), +(73, 56, 37), (64, 48, 47), (64, 48, 47), (60, 56, 56), +(68, 68, 66), (72, 89, 66), (97, 105, 85), (121, 129, 103), +(145, 145, 122), (194, 165, 132), (210, 165, 141), (210, 173, 141), +(218, 181, 151), (218, 180, 160), (218, 177, 160), (198, 169, 141), +(157, 145, 113), (125, 125, 103), (109, 109, 75), (77, 77, 66), +(72, 76, 66), (73, 73, 75), (68, 60, 66), (60, 56, 56), +(48, 48, 56), (48, 48, 47), (44, 44, 47), (32, 36, 37), +(24, 28, 28), (20, 20, 28), (15, 20, 28), (12, 20, 18), +(12, 16, 18), (12, 16, 9), (12, 20, 9), (16, 16, 9), +(12, 20, 9), (16, 20, 9), (20, 20, 9), (20, 20, 9), +(23, 20, 9), (24, 20, 9), (27, 16, 9), (28, 24, 9), +(24, 20, 9), (23, 20, 18), (19, 20, 18), (24, 20, 18), +(31, 20, 18), (35, 24, 28), (28, 24, 18), (32, 24, 28), +(31, 24, 28), (28, 28, 28), (28, 32, 37), (24, 36, 47), +(28, 32, 47), (28, 32, 37), (23, 24, 28), (23, 20, 28), +(24, 28, 28), (28, 36, 37), (40, 40, 37), (44, 44, 47), +(44, 40, 56), (40, 40, 56), (31, 28, 37), (20, 20, 28), +(19, 16, 28), (16, 16, 28), (16, 16, 18), (16, 20, 18), +(16, 24, 18), (16, 24, 18), (20, 24, 18), (23, 20, 18), +(20, 24, 18), (24, 24, 18), (28, 28, 28), (40, 44, 28), +(48, 60, 37), (56, 60, 47), (56, 72, 56), (64, 72, 56), +(68, 64, 56), (68, 64, 66), (64, 64, 56), (68, 64, 66), +(68, 73, 66), (76, 76, 66), (68, 89, 85), (84, 96, 113), +(113, 117, 103), (145, 137, 122), (149, 141, 132), (137, 141, 122), +(105, 121, 103), (81, 85, 84), (60, 68, 66), (48, 60, 56), +(52, 56, 56), (56, 56, 47), (52, 52, 47), (56, 52, 47), +(60, 43, 47), (56, 48, 47), (52, 44, 47), (48, 31, 37), +(40, 28, 28), (40, 32, 28), (36, 31, 28), (44, 32, 18), +(36, 36, 28), (36, 36, 28), (36, 36, 37), (40, 31, 37), +(36, 36, 37), (40, 36, 37), (48, 39, 37), (52, 40, 37), +(64, 44, 37), (64, 44, 37), (60, 48, 37), (56, 48, 47), +(52, 48, 56), (56, 52, 56), (60, 52, 56), (56, 52, 47), +(56, 48, 37), (60, 56, 37), (56, 48, 37), (52, 48, 37), +(48, 48, 37), (44, 44, 37), (44, 48, 28), (32, 44, 18), +(24, 32, 18), (23, 24, 18), (23, 16, 18), (20, 16, 18), +(15, 20, 28), (12, 24, 28), (15, 28, 28), (24, 24, 28), +(36, 28, 28), (44, 32, 28), (48, 40, 37), (52, 48, 47), +(52, 52, 47), (52, 56, 47), (56, 56, 47), (60, 60, 47), +(68, 56, 47), (76, 56, 47), (85, 64, 56), (121, 76, 56), +(153, 103, 75), (174, 136, 94), (210, 164, 132), (222, 189, 169), +(230, 197, 169), (234, 192, 178), (222, 189, 169), (206, 169, 151), +(174, 149, 132), (125, 112, 94), (64, 64, 47), (15, 16, 9) +), + +// 53 etretat.ppm +((37, 54, 37), (56, 74, 51), (72, 89, 61), (92, 102, 76), +(110, 104, 91), (122, 114, 96), (130, 115, 99), (147, 129, 105), +(156, 123, 113), (158, 122, 110), (154, 117, 112), (128, 105, 86), +(113, 95, 78), (111, 88, 68), (109, 75, 53), (119, 73, 54), +(113, 87, 64), (109, 90, 77), (112, 99, 83), (119, 107, 90), +(119, 106, 100), (111, 114, 107), (108, 108, 119), (111, 132, 117), +(122, 140, 117), (131, 147, 122), (125, 148, 116), (128, 146, 117), +(129, 134, 106), (119, 120, 100), (122, 118, 102), (126, 111, 93), +(128, 105, 83), (127, 100, 79), (116, 96, 68), (115, 95, 71), +(105, 93, 75), (96, 95, 76), (94, 88, 75), (91, 90, 84), +(89, 104, 99), (84, 113, 105), (86, 116, 115), (94, 113, 111), +(99, 115, 105), (90, 106, 97), (75, 101, 90), (66, 98, 88), +(64, 83, 77), (54, 80, 74), (48, 74, 60), (63, 77, 61), +(53, 84, 60), (58, 84, 68), (74, 78, 77), (87, 88, 83), +(102, 100, 95), (120, 112, 109), (142, 128, 126), (157, 150, 131), +(173, 160, 142), (172, 164, 151), (171, 163, 140), (152, 166, 129), +(146, 152, 117), (124, 122, 102), (119, 101, 83), (107, 87, 68), +(98, 77, 59), (83, 73, 56), (71, 70, 54), (64, 69, 53), +(62, 65, 49), (51, 58, 44), (46, 53, 42), (42, 55, 36), +(41, 51, 36), (33, 46, 29), (32, 35, 25), (32, 33, 25), +(32, 33, 26), (34, 33, 25), (49, 41, 28), (53, 42, 32), +(46, 46, 32), (35, 39, 27), (35, 36, 26), (33, 35, 26), +(33, 45, 33), (37, 50, 46), (43, 49, 49), (39, 53, 48), +(46, 60, 57), (64, 73, 61), (76, 83, 70), (98, 92, 88), +(120, 108, 103), (130, 119, 129), (133, 122, 130), (140, 134, 141), +(140, 136, 140), (149, 148, 129), (152, 158, 138), (163, 155, 142), +(166, 158, 139), (164, 150, 138), (160, 129, 117), (164, 127, 110), +(160, 117, 85), (129, 101, 81), (95, 89, 60), (75, 83, 56), +(57, 74, 54), (50, 72, 46), (50, 66, 45), (56, 66, 52), +(59, 61, 52), (54, 61, 52), (47, 62, 45), (48, 57, 47), +(45, 58, 46), (45, 51, 40), (50, 49, 35), (50, 48, 35), +(55, 49, 35), (58, 51, 45), (69, 65, 55), (76, 67, 59), +(85, 76, 68), (90, 80, 66), (96, 75, 58), (95, 73, 58), +(84, 72, 61), (83, 72, 62), (76, 71, 65), (72, 68, 63), +(67, 65, 58), (60, 61, 53), (53, 66, 55), (52, 70, 63), +(47, 70, 64), (48, 65, 61), (45, 66, 47), (41, 58, 40), +(38, 58, 38), (31, 46, 31), (31, 34, 25), (33, 33, 24), +(33, 33, 24), (36, 36, 26), (45, 45, 33), (47, 49, 35), +(49, 48, 38), (58, 57, 46), (71, 66, 49), (74, 71, 57), +(75, 74, 63), (70, 78, 64), (63, 77, 60), (59, 67, 51), +(54, 57, 38), (52, 52, 40), (59, 57, 50), (69, 64, 57), +(80, 83, 68), (98, 92, 81), (116, 107, 100), (135, 122, 110), +(149, 139, 125), (168, 152, 137), (173, 164, 146), (178, 166, 145), +(187, 161, 142), (175, 160, 139), (167, 156, 132), (157, 146, 127), +(154, 127, 107), (137, 103, 78), (118, 89, 65), (97, 74, 55), +(94, 64, 46), (81, 67, 51), (77, 68, 53), (77, 75, 64), +(75, 79, 74), (69, 86, 85), (81, 84, 88), (82, 92, 86), +(87, 93, 88), (91, 98, 98), (95, 112, 99), (100, 109, 98), +(92, 102, 92), (86, 97, 88), (95, 99, 92), (108, 109, 98), +(119, 115, 101), (120, 135, 102), (129, 145, 106), (123, 142, 117), +(121, 136, 119), (108, 117, 110), (101, 118, 101), (92, 104, 89), +(84, 95, 87), (83, 88, 74), (85, 82, 74), (82, 80, 72), +(85, 79, 66), (89, 82, 61), (95, 83, 56), (98, 81, 61), +(101, 80, 68), (92, 81, 69), (90, 84, 74), (94, 86, 82), +(98, 92, 86), (96, 99, 90), (113, 110, 94), (119, 105, 92), +(120, 104, 88), (103, 94, 86), (90, 91, 78), (76, 90, 75), +(78, 83, 79), (70, 84, 73), (66, 92, 77), (76, 94, 87), +(94, 99, 100), (103, 108, 119), (105, 132, 130), (129, 156, 139), +(158, 162, 146), (178, 172, 157), (178, 176, 173), (166, 166, 167), +(125, 150, 143), (97, 132, 135), (105, 129, 130), (104, 126, 123), +(100, 128, 120), (95, 119, 120), (95, 117, 107), (103, 127, 111), +(110, 137, 122), (130, 141, 133), (142, 138, 120), (137, 157, 120), +(139, 133, 110), (131, 123, 109), (127, 112, 99), (120, 105, 95), +(116, 103, 90), (103, 92, 79), (105, 92, 76), (114, 99, 83) +), + +// 54 the-hollow-needle-at-etretat.ppm +((106, 110, 103), (105, 117, 116), (105, 119, 120), (117, 133, 130), +(123, 144, 135), (124, 144, 138), (125, 149, 140), (123, 146, 140), +(122, 149, 150), (127, 156, 144), (128, 155, 142), (137, 151, 143), +(140, 148, 142), (143, 151, 132), (150, 154, 130), (151, 152, 135), +(147, 158, 149), (143, 154, 144), (139, 151, 144), (137, 150, 147), +(143, 152, 149), (137, 149, 146), (137, 147, 142), (134, 146, 140), +(131, 141, 135), (125, 140, 138), (123, 143, 138), (123, 144, 140), +(123, 144, 140), (128, 145, 142), (127, 150, 141), (120, 153, 141), +(125, 157, 144), (131, 159, 151), (134, 161, 147), (143, 160, 151), +(142, 166, 163), (136, 172, 169), (139, 163, 165), (130, 157, 142), +(130, 151, 141), (131, 146, 141), (134, 148, 150), (130, 152, 143), +(130, 156, 138), (132, 155, 137), (137, 158, 132), (134, 153, 129), +(134, 147, 129), (135, 143, 126), (133, 142, 127), (138, 135, 118), +(132, 125, 106), (125, 113, 95), (118, 101, 87), (103, 92, 72), +(78, 69, 55), (64, 59, 54), (59, 56, 53), (60, 58, 54), +(69, 64, 58), (88, 86, 83), (95, 101, 97), (93, 108, 101), +(91, 108, 101), (91, 109, 107), (91, 110, 109), (89, 114, 113), +(93, 112, 109), (93, 108, 105), (101, 112, 108), (107, 116, 118), +(115, 128, 125), (120, 147, 132), (125, 154, 134), (131, 150, 131), +(138, 147, 135), (138, 144, 132), (136, 139, 128), (138, 138, 127), +(138, 138, 115), (137, 134, 102), (132, 131, 102), (137, 124, 97), +(127, 120, 88), (120, 108, 84), (114, 110, 84), (112, 104, 84), +(113, 99, 83), (116, 105, 87), (118, 111, 89), (121, 117, 102), +(126, 127, 112), (131, 131, 121), (136, 137, 128), (136, 136, 130), +(135, 139, 131), (132, 140, 127), (131, 132, 126), (128, 121, 119), +(122, 110, 104), (106, 92, 92), (91, 75, 69), (70, 59, 53), +(60, 55, 52), (59, 54, 51), (59, 55, 48), (57, 54, 50), +(59, 53, 52), (58, 51, 51), (52, 51, 51), (52, 49, 50), +(55, 52, 51), (51, 53, 50), (55, 52, 52), (58, 53, 54), +(55, 55, 57), (58, 61, 59), (58, 79, 76), (85, 101, 93), +(95, 101, 97), (101, 102, 97), (103, 104, 99), (96, 106, 104), +(108, 116, 106), (116, 120, 110), (125, 129, 121), (129, 141, 131), +(129, 141, 135), (130, 139, 132), (126, 128, 128), (114, 120, 117), +(107, 106, 100), (100, 94, 85), (88, 80, 69), (68, 59, 55), +(60, 53, 52), (55, 51, 48), (53, 49, 48), (49, 52, 48), +(47, 50, 45), (47, 46, 47), (49, 44, 43), (51, 43, 42), +(52, 49, 45), (56, 52, 52), (58, 57, 56), (63, 81, 78), +(86, 105, 100), (102, 121, 118), (99, 124, 126), (105, 124, 123), +(117, 127, 119), (129, 135, 121), (133, 141, 123), (136, 139, 115), +(133, 130, 109), (127, 125, 102), (124, 118, 97), (116, 114, 98), +(120, 113, 99), (121, 113, 96), (125, 109, 96), (120, 110, 94), +(119, 106, 92), (112, 106, 92), (106, 94, 90), (92, 84, 78), +(69, 60, 61), (61, 55, 53), (58, 54, 53), (57, 54, 53), +(52, 54, 54), (52, 53, 51), (53, 55, 50), (60, 57, 52), +(71, 66, 59), (91, 97, 89), (96, 106, 102), (106, 121, 116), +(127, 138, 129), (128, 141, 135), (123, 139, 137), (116, 129, 123), +(103, 125, 111), (104, 121, 111), (111, 115, 106), (114, 114, 105), +(121, 111, 103), (120, 115, 110), (122, 120, 112), (127, 124, 112), +(131, 118, 107), (130, 116, 105), (128, 124, 102), (130, 124, 103), +(139, 121, 98), (143, 116, 99), (147, 128, 100), (154, 127, 99), +(147, 135, 109), (157, 128, 102), (158, 130, 115), (162, 148, 115), +(150, 137, 119), (144, 145, 121), (143, 148, 132), (141, 142, 126), +(135, 140, 128), (134, 141, 133), (134, 144, 132), (132, 140, 130), +(131, 142, 130), (132, 141, 128), (134, 141, 126), (133, 141, 123), +(136, 135, 113), (134, 129, 107), (127, 122, 100), (121, 119, 94), +(107, 116, 90), (106, 111, 91), (105, 103, 93), (107, 103, 92), +(108, 111, 94), (112, 119, 107), (114, 128, 121), (119, 139, 131), +(122, 145, 135), (126, 148, 136), (128, 147, 135), (138, 146, 137), +(139, 145, 132), (142, 142, 125), (143, 133, 118), (144, 132, 111), +(142, 136, 110), (140, 136, 110), (135, 130, 115), (132, 123, 106), +(130, 118, 92), (132, 115, 92), (142, 106, 91), (123, 109, 89), +(107, 101, 84), (95, 91, 86), (72, 64, 59), (64, 58, 53), +(59, 54, 54), (59, 56, 51), (63, 57, 55), (71, 69, 68), +(97, 100, 88), (112, 114, 103), (123, 135, 123), (132, 145, 128) +), + +// 55 rouen-cathedral-sunset.ppm +((137, 129, 126), (130, 125, 111), (120, 112, 98), (113, 109, 87), +(100, 101, 83), (91, 93, 81), (78, 84, 72), (82, 89, 66), +(86, 88, 71), (95, 95, 69), (100, 92, 61), (114, 94, 53), +(125, 91, 54), (127, 96, 57), (124, 99, 57), (115, 101, 64), +(101, 98, 68), (96, 101, 80), (100, 106, 87), (104, 104, 90), +(109, 106, 87), (115, 111, 90), (126, 115, 100), (133, 126, 107), +(143, 135, 116), (144, 133, 122), (149, 131, 136), (156, 134, 129), +(145, 134, 125), (141, 128, 118), (133, 129, 109), (131, 125, 111), +(129, 125, 110), (126, 124, 99), (126, 130, 107), (128, 129, 111), +(133, 129, 113), (136, 136, 123), (148, 145, 137), (156, 150, 144), +(159, 153, 146), (159, 150, 152), (160, 152, 145), (156, 147, 147), +(148, 143, 149), (141, 141, 144), (138, 133, 130), (135, 127, 125), +(134, 131, 124), (140, 131, 120), (140, 129, 126), (138, 137, 132), +(138, 138, 149), (135, 149, 160), (134, 149, 164), (134, 153, 171), +(138, 149, 164), (128, 140, 150), (137, 142, 147), (146, 144, 145), +(158, 141, 140), (163, 146, 139), (176, 154, 136), (179, 159, 144), +(187, 167, 151), (198, 171, 154), (190, 158, 132), (166, 145, 107), +(145, 133, 91), (146, 114, 79), (138, 108, 71), (119, 101, 76), +(107, 102, 78), (98, 98, 78), (94, 92, 78), (93, 90, 71), +(91, 88, 60), (90, 82, 53), (88, 77, 52), (73, 74, 52), +(84, 82, 57), (93, 89, 57), (105, 94, 71), (94, 91, 69), +(97, 94, 72), (108, 98, 64), (115, 99, 71), (110, 101, 74), +(115, 107, 73), (128, 112, 75), (142, 113, 73), (148, 117, 75), +(151, 128, 86), (156, 137, 106), (162, 141, 119), (163, 151, 126), +(167, 156, 133), (163, 155, 136), (152, 147, 144), (140, 147, 140), +(133, 139, 127), (126, 130, 125), (124, 125, 113), (115, 119, 108), +(112, 120, 111), (102, 118, 115), (104, 116, 116), (97, 117, 107), +(107, 113, 107), (111, 108, 103), (105, 109, 99), (104, 111, 97), +(106, 106, 91), (105, 101, 88), (108, 102, 85), (107, 102, 78), +(112, 105, 78), (129, 112, 90), (138, 127, 92), (144, 135, 111), +(138, 142, 129), (149, 149, 147), (155, 152, 161), (153, 158, 170), +(155, 159, 171), (163, 158, 161), (167, 155, 153), (173, 159, 145), +(169, 155, 135), (169, 141, 105), (162, 125, 95), (150, 117, 93), +(138, 116, 91), (134, 109, 85), (119, 109, 80), (119, 108, 82), +(122, 108, 77), (124, 105, 74), (125, 111, 79), (120, 109, 77), +(118, 111, 81), (116, 115, 87), (111, 113, 89), (114, 114, 91), +(116, 121, 96), (134, 128, 108), (153, 138, 122), (169, 146, 132), +(181, 154, 130), (168, 153, 130), (152, 142, 119), (143, 135, 108), +(133, 126, 95), (125, 123, 93), (119, 112, 86), (116, 106, 83), +(121, 111, 84), (128, 107, 87), (129, 110, 95), (138, 120, 91), +(140, 124, 91), (144, 126, 93), (141, 131, 91), (128, 122, 90), +(119, 119, 90), (116, 112, 102), (109, 114, 95), (109, 112, 110), +(109, 120, 119), (121, 129, 122), (132, 131, 122), (144, 145, 135), +(158, 148, 141), (175, 158, 144), (180, 158, 149), (187, 171, 158), +(188, 176, 158), (184, 167, 145), (175, 166, 137), (162, 151, 133), +(153, 137, 111), (144, 123, 100), (128, 119, 90), (120, 113, 85), +(113, 110, 80), (115, 104, 72), (116, 100, 68), (124, 101, 64), +(134, 100, 67), (135, 109, 63), (139, 112, 67), (135, 120, 75), +(133, 120, 93), (133, 127, 105), (132, 128, 123), (132, 136, 146), +(134, 143, 152), (140, 153, 164), (141, 154, 168), (142, 155, 165), +(157, 156, 151), (159, 159, 138), (173, 162, 141), (177, 164, 143), +(177, 163, 150), (181, 166, 158), (181, 169, 162), (175, 170, 163), +(179, 164, 162), (175, 162, 155), (161, 155, 148), (158, 157, 147), +(150, 155, 147), (147, 153, 144), (136, 138, 124), (128, 126, 114), +(112, 112, 107), (100, 106, 99), (96, 104, 99), (93, 103, 96), +(103, 102, 89), (111, 104, 84), (112, 102, 80), (118, 102, 74), +(119, 98, 70), (118, 95, 67), (116, 94, 61), (112, 90, 58), +(104, 90, 60), (103, 91, 56), (98, 86, 57), (92, 84, 51), +(89, 84, 60), (106, 82, 55), (111, 90, 56), (113, 85, 56), +(103, 92, 65), (109, 103, 77), (104, 99, 86), (106, 96, 89), +(101, 101, 95), (103, 105, 98), (109, 110, 103), (102, 114, 94), +(112, 114, 107), (126, 117, 99), (136, 130, 104), (150, 140, 107), +(157, 138, 106), (157, 142, 104), (154, 139, 109), (155, 146, 128), +(154, 142, 136), (155, 145, 145), (148, 151, 156), (135, 158, 170) +), + +// 56 the-houses-of-parliament.ppm +((105, 95, 133), (97, 86, 120), (81, 81, 103), (78, 71, 88), +(74, 66, 79), (75, 64, 73), (76, 68, 75), (79, 65, 74), +(81, 71, 74), (83, 74, 81), (88, 74, 87), (91, 81, 96), +(98, 92, 112), (101, 95, 126), (107, 95, 136), (110, 95, 141), +(109, 90, 136), (104, 88, 136), (105, 89, 130), (103, 87, 118), +(102, 88, 117), (105, 87, 110), (101, 84, 111), (105, 90, 112), +(103, 99, 115), (105, 101, 116), (107, 98, 117), (104, 90, 120), +(97, 87, 122), (98, 90, 114), (94, 89, 109), (90, 91, 103), +(88, 82, 96), (82, 76, 86), (78, 74, 77), (70, 72, 69), +(66, 72, 63), (57, 67, 60), (60, 67, 57), (68, 73, 65), +(77, 83, 71), (85, 94, 92), (94, 102, 97), (97, 101, 106), +(101, 101, 100), (99, 99, 106), (100, 98, 109), (103, 94, 112), +(103, 90, 112), (101, 87, 113), (104, 89, 111), (100, 96, 107), +(95, 96, 107), (95, 88, 106), (97, 88, 108), (99, 93, 112), +(98, 90, 105), (99, 89, 96), (97, 90, 96), (96, 87, 99), +(94, 88, 105), (97, 85, 111), (101, 86, 113), (105, 88, 117), +(109, 93, 128), (116, 98, 135), (115, 98, 135), (113, 103, 131), +(112, 105, 138), (108, 99, 133), (107, 95, 124), (109, 94, 123), +(106, 91, 122), (106, 88, 116), (107, 87, 116), (104, 84, 117), +(105, 84, 116), (109, 87, 112), (110, 91, 114), (107, 96, 117), +(111, 92, 117), (107, 89, 116), (105, 86, 118), (105, 80, 127), +(99, 75, 134), (98, 73, 129), (100, 80, 128), (98, 79, 126), +(101, 74, 127), (98, 78, 121), (97, 76, 113), (96, 75, 103), +(92, 76, 99), (88, 79, 90), (87, 75, 90), (90, 74, 94), +(87, 75, 92), (88, 76, 92), (91, 71, 96), (99, 77, 99), +(96, 80, 102), (95, 77, 105), (91, 71, 112), (94, 69, 117), +(98, 78, 117), (103, 87, 122), (114, 90, 141), (109, 96, 134), +(113, 101, 136), (126, 107, 140), (119, 100, 132), (114, 96, 113), +(108, 88, 109), (99, 87, 106), (92, 83, 102), (87, 79, 96), +(88, 76, 95), (85, 74, 97), (87, 69, 102), (88, 71, 101), +(88, 73, 97), (90, 79, 103), (93, 81, 107), (93, 82, 118), +(99, 81, 123), (96, 81, 125), (93, 84, 125), (94, 82, 129), +(100, 90, 128), (101, 97, 124), (100, 99, 116), (107, 103, 112), +(117, 106, 104), (114, 106, 108), (117, 106, 115), (108, 99, 108), +(104, 99, 107), (103, 107, 98), (103, 102, 98), (95, 96, 97), +(95, 94, 91), (87, 87, 83), (87, 79, 87), (81, 73, 84), +(77, 63, 79), (75, 60, 74), (73, 61, 75), (72, 61, 78), +(75, 63, 78), (73, 62, 78), (78, 63, 84), (77, 58, 97), +(85, 66, 100), (87, 65, 102), (82, 72, 104), (81, 66, 105), +(80, 60, 96), (73, 63, 82), (66, 63, 76), (57, 55, 54), +(21, 24, 21), (23, 29, 20), (48, 55, 48), (55, 64, 60), +(63, 67, 69), (70, 66, 72), (81, 74, 83), (89, 79, 89), +(96, 86, 96), (105, 86, 105), (117, 96, 112), (118, 114, 124), +(126, 123, 126), (135, 132, 151), (125, 115, 137), (119, 118, 134), +(109, 109, 133), (109, 101, 128), (112, 107, 128), (109, 104, 122), +(101, 103, 124), (106, 99, 117), (112, 100, 119), (109, 98, 112), +(106, 101, 114), (105, 102, 114), (100, 99, 111), (96, 94, 103), +(94, 89, 94), (94, 88, 88), (88, 92, 82), (82, 92, 73), +(79, 89, 73), (72, 84, 72), (70, 83, 68), (83, 75, 77), +(89, 76, 87), (91, 80, 103), (101, 84, 114), (108, 86, 126), +(110, 87, 139), (115, 90, 142), (124, 85, 142), (107, 82, 129), +(109, 92, 129), (100, 82, 119), (97, 82, 112), (97, 83, 102), +(89, 84, 97), (89, 83, 96), (92, 86, 94), (96, 87, 95), +(99, 86, 92), (95, 84, 96), (94, 85, 93), (91, 84, 85), +(86, 83, 84), (78, 85, 89), (73, 84, 86), (69, 76, 83), +(75, 71, 83), (77, 68, 83), (77, 69, 81), (79, 70, 84), +(80, 69, 82), (77, 68, 83), (78, 69, 85), (83, 72, 86), +(82, 75, 87), (84, 74, 84), (83, 72, 81), (77, 66, 76), +(73, 60, 73), (62, 52, 70), (60, 52, 63), (67, 65, 63), +(80, 68, 65), (84, 78, 71), (87, 78, 86), (88, 82, 93), +(92, 84, 96), (97, 85, 102), (105, 82, 108), (103, 84, 105), +(98, 82, 102), (94, 77, 103), (88, 74, 101), (88, 73, 102), +(89, 74, 104), (88, 75, 115), (90, 81, 118), (95, 83, 122), +(97, 82, 118), (100, 83, 113), (97, 86, 109), (91, 89, 101) +), + +// 57 starry-night.ppm +((23, 26, 18), (27, 29, 21), (30, 29, 21), (29, 30, 22), +(32, 35, 26), (40, 42, 32), (43, 47, 35), (45, 54, 38), +(52, 52, 36), (50, 54, 38), (51, 56, 39), (50, 56, 42), +(50, 60, 42), (52, 63, 47), (60, 68, 51), (69, 73, 55), +(67, 76, 55), (68, 78, 53), (69, 82, 55), (70, 87, 59), +(77, 101, 65), (87, 101, 66), (92, 108, 67), (93, 105, 65), +(93, 107, 65), (90, 110, 66), (93, 110, 65), (95, 111, 69), +(102, 114, 73), (104, 110, 69), (109, 110, 61), (98, 105, 65), +(94, 108, 61), (82, 98, 56), (78, 86, 53), (81, 79, 57), +(81, 82, 62), (88, 91, 60), (99, 93, 62), (95, 106, 64), +(91, 110, 65), (84, 117, 77), (89, 124, 81), (104, 128, 92), +(114, 130, 84), (120, 132, 84), (138, 148, 85), (148, 150, 76), +(134, 147, 76), (131, 138, 78), (110, 108, 66), (96, 89, 57), +(81, 72, 49), (66, 65, 45), (63, 60, 40), (60, 55, 44), +(58, 56, 43), (56, 56, 42), (53, 57, 42), (58, 59, 42), +(57, 61, 41), (57, 65, 42), (57, 65, 45), (59, 61, 49), +(63, 68, 55), (71, 77, 53), (76, 86, 54), (90, 95, 55), +(101, 108, 65), (114, 125, 74), (133, 146, 76), (142, 156, 82), +(161, 168, 92), (177, 178, 94), (177, 173, 93), (167, 158, 86), +(152, 147, 79), (133, 115, 72), (98, 100, 67), (80, 86, 54), +(73, 80, 53), (61, 71, 47), (44, 58, 38), (37, 46, 32), +(35, 38, 27), (29, 35, 23), (28, 36, 25), (28, 38, 24), +(33, 46, 30), (37, 47, 30), (44, 48, 34), (47, 49, 36), +(46, 51, 36), (41, 51, 31), (35, 50, 34), (35, 48, 31), +(42, 51, 35), (46, 53, 44), (53, 62, 43), (60, 70, 49), +(73, 77, 59), (80, 88, 64), (83, 98, 84), (86, 101, 99), +(100, 114, 92), (101, 108, 80), (93, 106, 76), (81, 103, 75), +(87, 101, 75), (85, 113, 85), (78, 110, 80), (83, 109, 74), +(86, 107, 71), (86, 113, 65), (89, 104, 67), (79, 101, 66), +(77, 98, 63), (70, 86, 63), (68, 76, 67), (69, 82, 61), +(73, 82, 59), (72, 84, 61), (70, 90, 69), (80, 98, 83), +(91, 106, 77), (102, 110, 80), (102, 120, 77), (98, 126, 70), +(99, 122, 78), (94, 114, 72), (84, 101, 67), (75, 84, 58), +(76, 78, 53), (69, 77, 48), (64, 65, 44), (58, 64, 43), +(51, 55, 41), (46, 51, 38), (40, 45, 35), (30, 34, 29), +(29, 29, 22), (26, 27, 22), (26, 28, 24), (25, 27, 22), +(28, 28, 22), (31, 30, 25), (37, 34, 28), (41, 37, 29), +(42, 39, 34), (47, 44, 36), (42, 47, 33), (38, 44, 30), +(33, 36, 27), (31, 31, 25), (29, 27, 21), (27, 24, 21), +(24, 26, 19), (23, 26, 18), (20, 18, 14), (24, 25, 18), +(30, 32, 23), (37, 40, 30), (42, 45, 37), (51, 55, 41), +(60, 63, 47), (70, 75, 52), (84, 78, 49), (100, 92, 59), +(112, 106, 63), (118, 115, 66), (121, 131, 78), (122, 138, 89), +(125, 149, 98), (139, 157, 105), (124, 152, 98), (113, 139, 83), +(103, 125, 72), (105, 112, 69), (93, 103, 63), (80, 88, 54), +(73, 78, 53), (61, 76, 49), (57, 66, 47), (54, 68, 47), +(50, 64, 40), (53, 60, 42), (56, 53, 44), (58, 54, 39), +(58, 56, 39), (53, 57, 37), (53, 56, 38), (56, 54, 36), +(52, 49, 33), (42, 44, 30), (35, 38, 26), (29, 35, 24), +(29, 35, 26), (38, 42, 31), (44, 44, 32), (53, 51, 31), +(62, 62, 41), (78, 77, 54), (91, 97, 67), (109, 122, 77), +(136, 138, 83), (149, 149, 83), (163, 154, 83), (167, 153, 89), +(156, 160, 90), (145, 153, 84), (129, 142, 79), (109, 130, 80), +(101, 123, 85), (98, 123, 94), (91, 102, 87), (90, 98, 79), +(94, 92, 81), (83, 92, 66), (78, 84, 59), (74, 77, 55), +(64, 65, 48), (58, 56, 43), (50, 48, 36), (45, 42, 31), +(37, 34, 25), (34, 30, 21), (34, 28, 24), (38, 39, 28), +(47, 48, 35), (52, 52, 41), (56, 59, 43), (59, 68, 57), +(57, 78, 58), (68, 89, 57), (69, 88, 56), (67, 80, 54), +(61, 77, 51), (56, 74, 47), (56, 69, 44), (53, 62, 42), +(51, 56, 42), (53, 53, 45), (51, 52, 44), (51, 54, 48), +(54, 59, 52), (64, 61, 53), (69, 66, 63), (63, 69, 56), +(75, 76, 52), (80, 79, 52), (78, 82, 51), (84, 91, 59), +(92, 100, 65), (97, 104, 63), (98, 99, 61), (92, 93, 57) +), + +// 58 water-lilies-sunset.ppm +((71, 67, 46), (71, 67, 50), (67, 72, 57), (72, 84, 60), +(81, 87, 72), (92, 93, 74), (84, 86, 74), (88, 100, 84), +(83, 84, 73), (77, 74, 68), (68, 62, 56), (60, 59, 48), +(60, 55, 47), (57, 49, 38), (53, 45, 38), (52, 44, 36), +(52, 46, 36), (57, 49, 37), (58, 49, 38), (60, 52, 39), +(63, 57, 43), (70, 60, 45), (80, 65, 48), (85, 71, 52), +(89, 76, 54), (90, 83, 53), (96, 92, 57), (102, 95, 62), +(106, 98, 61), (112, 100, 62), (115, 107, 65), (119, 106, 67), +(129, 111, 70), (132, 119, 74), (130, 120, 71), (126, 118, 69), +(112, 111, 84), (101, 100, 80), (87, 93, 92), (90, 101, 87), +(85, 94, 100), (107, 108, 90), (130, 118, 110), (135, 118, 104), +(153, 156, 127), (183, 183, 126), (189, 184, 126), (177, 165, 100), +(173, 153, 91), (162, 148, 88), (145, 135, 77), (134, 124, 72), +(116, 107, 66), (103, 91, 59), (89, 73, 62), (78, 65, 49), +(69, 58, 43), (67, 51, 41), (63, 50, 42), (66, 51, 48), +(69, 57, 49), (76, 58, 53), (81, 65, 54), (86, 73, 55), +(86, 81, 53), (95, 87, 55), (100, 87, 58), (101, 88, 65), +(112, 87, 80), (117, 98, 73), (114, 106, 68), (120, 110, 68), +(122, 109, 67), (122, 107, 66), (125, 104, 66), (116, 94, 63), +(114, 90, 60), (105, 84, 56), (93, 76, 53), (93, 75, 51), +(91, 75, 52), (84, 76, 49), (83, 73, 48), (82, 74, 48), +(77, 76, 51), (72, 74, 53), (68, 68, 54), (69, 66, 54), +(66, 66, 52), (65, 64, 48), (65, 62, 49), (64, 58, 49), +(63, 58, 46), (62, 60, 46), (61, 60, 46), (58, 57, 44), +(56, 55, 45), (56, 52, 44), (55, 51, 45), (49, 50, 41), +(51, 47, 38), (54, 49, 41), (50, 46, 38), (45, 49, 39), +(44, 47, 36), (50, 47, 34), (48, 44, 33), (51, 44, 34), +(51, 49, 37), (55, 51, 37), (56, 49, 38), (54, 52, 42), +(55, 50, 40), (57, 51, 39), (58, 53, 39), (60, 53, 38), +(59, 54, 40), (61, 55, 41), (61, 58, 43), (64, 60, 43), +(72, 64, 48), (83, 65, 47), (84, 72, 48), (93, 75, 51), +(102, 87, 55), (106, 97, 61), (113, 104, 64), (122, 109, 67), +(133, 113, 69), (136, 116, 69), (142, 123, 72), (142, 123, 74), +(144, 118, 73), (130, 100, 83), (134, 88, 71), (112, 86, 58), +(100, 68, 52), (80, 54, 44), (72, 52, 42), (66, 49, 38), +(63, 55, 41), (63, 57, 42), (63, 60, 44), (70, 64, 47), +(72, 68, 48), (78, 71, 47), (76, 77, 51), (78, 82, 52), +(82, 81, 52), (79, 74, 48), (78, 70, 47), (75, 67, 45), +(67, 64, 43), (62, 59, 42), (59, 55, 42), (57, 53, 40), +(56, 53, 44), (60, 55, 50), (67, 61, 49), (77, 68, 51), +(84, 74, 52), (89, 82, 53), (98, 89, 56), (101, 88, 58), +(102, 90, 59), (101, 95, 69), (95, 95, 61), (96, 94, 59), +(83, 88, 66), (84, 79, 68), (76, 73, 67), (73, 68, 54), +(68, 62, 51), (66, 61, 48), (61, 61, 47), (60, 57, 47), +(57, 55, 44), (57, 54, 40), (57, 56, 40), (57, 54, 39), +(56, 55, 38), (52, 51, 37), (48, 46, 38), (44, 41, 36), +(42, 42, 33), (44, 43, 33), (48, 40, 34), (52, 44, 36), +(57, 47, 42), (57, 49, 42), (62, 55, 41), (64, 55, 44), +(67, 56, 43), (68, 58, 44), (69, 61, 41), (71, 61, 41), +(78, 63, 48), (78, 72, 52), (86, 75, 58), (95, 85, 61), +(110, 99, 68), (119, 111, 69), (134, 124, 74), (149, 132, 78), +(152, 141, 84), (161, 143, 85), (143, 122, 76), (129, 116, 70), +(114, 90, 60), (98, 82, 55), (89, 66, 48), (79, 56, 45), +(74, 53, 44), (71, 54, 46), (66, 54, 42), (64, 56, 40), +(62, 56, 40), (64, 52, 39), (63, 48, 39), (61, 48, 43), +(58, 50, 44), (57, 51, 44), (61, 53, 46), (67, 53, 49), +(68, 57, 48), (71, 60, 52), (70, 63, 49), (69, 61, 48), +(70, 62, 49), (70, 65, 48), (68, 68, 47), (65, 67, 48), +(62, 64, 46), (63, 61, 43), (64, 60, 42), (68, 59, 43), +(72, 61, 44), (79, 56, 45), (85, 65, 47), (85, 71, 52), +(82, 77, 59), (79, 77, 63), (72, 71, 65), (70, 69, 56), +(63, 69, 53), (61, 66, 52), (58, 63, 47), (64, 62, 45), +(67, 59, 48), (71, 63, 51), (74, 64, 54), (74, 72, 52), +(84, 77, 54), (92, 84, 61), (105, 96, 62), (117, 102, 75) +), + +// 59 gogh.chambre-arles.ppm +( + (24, 17, 8), (25, 34, 4), (53, 56, 72), (75, 94, 108), + (86, 110, 145), (99, 141, 175), (125, 154, 163), (166, 146, 109), + (182, 142, 103), (191, 159, 113), (206, 191, 120), (238, 216, 142), + (252, 233, 156), (242, 229, 171), (220, 226, 215), (209, 216, 221), + (207, 213, 224), (199, 215, 224), (189, 208, 223), (171, 194, 208), + (176, 188, 187), (183, 159, 117), (172, 130, 92), (163, 113, 62), + (159, 109, 53), (176, 110, 9), (188, 116, 6), (196, 118, 6), + (202, 123, 10), (209, 126, 15), (200, 127, 38), (193, 145, 91), + (240, 193, 119), (251, 235, 153), (252, 240, 170), (246, 231, 174), + (229, 224, 220), (232, 232, 224), (224, 230, 230), (206, 219, 225), + (194, 207, 215), (177, 193, 190), (205, 177, 130), (196, 149, 101), + (191, 134, 97), (193, 146, 106), (196, 168, 125), (176, 190, 191), + (170, 197, 217), (187, 204, 220), (188, 206, 216), (178, 198, 204), + (171, 191, 183), (173, 147, 108), (162, 121, 84), (154, 108, 70), + (140, 98, 58), (116, 85, 48), (116, 84, 56), (131, 93, 52), + (148, 97, 49), (171, 95, 9), (183, 104, 7), (188, 110, 6), + (190, 110, 4), (193, 109, 2), (198, 109, 1), (193, 107, 1), + (194, 106, 7), (196, 109, 4), (196, 110, 6), (199, 108, 5), + (208, 107, 2), (208, 114, 3), (209, 118, 3), (207, 116, 4), + (207, 118, 1), (205, 116, 2), (205, 115, 2), (203, 113, 2), + (200, 113, 3), (199, 113, 4), (200, 113, 8), (198, 110, 6), + (195, 112, 4), (195, 111, 8), (197, 113, 9), (193, 112, 8), + (193, 108, 14), (169, 119, 67), (172, 143, 109), (171, 184, 178), + (169, 189, 198), (168, 187, 198), (168, 185, 180), (169, 148, 113), + (169, 132, 96), (167, 122, 89), (169, 124, 91), (169, 131, 94), + (166, 155, 102), (148, 172, 162), (129, 172, 187), (136, 170, 194), + (153, 157, 161), (165, 131, 95), (160, 121, 84), (161, 118, 85), + (163, 122, 91), (171, 133, 94), (184, 152, 116), (179, 181, 168), + (177, 188, 203), (169, 193, 202), (163, 191, 202), (149, 178, 194), + (133, 162, 176), (136, 138, 111), (132, 144, 61), (137, 134, 53), + (194, 125, 15), (190, 117, 10), (191, 118, 4), (193, 122, 4), + (200, 125, 8), (207, 130, 2), (210, 134, 2), (216, 134, 8), + (219, 135, 6), (219, 145, 9), (206, 205, 99), (232, 220, 127), + (222, 216, 127), (201, 205, 98), (196, 170, 103), (175, 139, 86), + (151, 118, 83), (115, 102, 102), (110, 133, 148), (120, 156, 176), + (134, 169, 197), (136, 177, 199), (161, 174, 178), (182, 144, 107), + (181, 124, 68), (201, 121, 16), (206, 122, 10), (208, 119, 4), + (214, 118, 1), (220, 132, 10), (212, 144, 55), (234, 182, 112), + (228, 188, 116), (194, 165, 109), (185, 142, 96), (187, 133, 83), + (177, 126, 79), (178, 127, 86), (187, 139, 104), (198, 164, 121), + (209, 185, 155), (216, 212, 192), (221, 224, 217), (227, 230, 223), + (230, 233, 226), (222, 228, 229), (207, 218, 218), (189, 198, 201), + (197, 169, 130), (181, 136, 99), (169, 120, 86), (155, 117, 75), + (153, 114, 75), (151, 110, 72), (144, 106, 72), (144, 104, 68), + (148, 105, 65), (147, 103, 64), (147, 100, 66), (145, 106, 67), + (141, 112, 72), (137, 119, 73), (134, 114, 77), (139, 118, 78), + (150, 115, 79), (164, 119, 78), (185, 138, 95), (195, 171, 118), + (243, 205, 123), (251, 237, 150), (253, 240, 166), (252, 235, 164), + (224, 211, 162), (191, 180, 120), (162, 128, 86), (132, 94, 56), + (84, 77, 37), (55, 30, 16), (64, 34, 7), (112, 61, 7), + (150, 78, 12), (177, 94, 6), (186, 107, 5), (192, 115, 5), + (200, 115, 7), (207, 117, 5), (205, 124, 12), (209, 130, 13), + (196, 163, 88), (221, 200, 109), (247, 221, 145), (239, 223, 166), + (217, 211, 177), (176, 195, 194), (129, 161, 184), (94, 125, 148), + (73, 92, 121), (85, 85, 107), (99, 94, 60), (97, 90, 58), + (106, 72, 24), (133, 77, 14), (143, 80, 7), (128, 63, 11), + (96, 59, 24), (100, 56, 31), (125, 80, 40), (142, 96, 59), + (158, 112, 62), (174, 133, 82), (185, 158, 112), (201, 192, 157), + (196, 206, 208), (197, 216, 223), (202, 212, 223), (198, 212, 215), + (190, 198, 209), (190, 188, 167), (184, 158, 112), (169, 129, 94), + (155, 114, 77), (146, 112, 78), (142, 112, 78), (142, 107, 75), + (142, 107, 69), (138, 104, 65), (144, 98, 61), (153, 107, 52), + (166, 97, 11), (174, 101, 5), (186, 109, 5), (190, 106, 5), + (190, 102, 4), (197, 41, 1), (116, 33, 7), (58, 32, 5) +), + +// 60 gogh.entrance.ppm +( + (2, 2, 1), (6, 5, 8), (5, 8, 7), (8, 15, 8), + (9, 21, 16), (11, 26, 20), (27, 49, 30), (35, 65, 35), + (54, 77, 47), (69, 106, 52), (94, 125, 64), (124, 137, 81), + (148, 157, 87), (169, 182, 104), (190, 193, 116), (207, 207, 129), + (219, 220, 140), (219, 208, 142), (217, 220, 140), (215, 214, 126), + (207, 199, 112), (188, 169, 87), (179, 142, 58), (182, 132, 44), + (185, 143, 29), (198, 203, 65), (220, 214, 99), (231, 222, 117), + (238, 228, 127), (234, 229, 136), (251, 245, 156), (235, 235, 144), + (240, 235, 151), (244, 234, 151), (241, 233, 149), (239, 236, 136), + (241, 230, 124), (233, 232, 116), (223, 216, 105), (213, 204, 98), + (179, 179, 91), (136, 145, 60), (93, 138, 53), (74, 111, 58), + (62, 113, 53), (59, 102, 62), (52, 94, 67), (43, 94, 70), + (45, 87, 61), (39, 83, 56), (38, 87, 54), (62, 100, 47), + (66, 108, 47), (89, 112, 52), (117, 127, 44), (139, 139, 44), + (139, 139, 50), (131, 129, 42), (102, 121, 60), (80, 112, 58), + (68, 94, 42), (47, 88, 28), (35, 68, 39), (42, 56, 54), + (45, 56, 61), (41, 64, 72), (37, 98, 69), (40, 111, 80), + (53, 139, 100), (77, 133, 110), (84, 136, 112), (81, 122, 117), + (77, 95, 121), (71, 97, 103), (59, 97, 100), (54, 90, 90), + (44, 80, 92), (44, 71, 79), (42, 80, 76), (63, 93, 67), + (88, 113, 66), (129, 128, 58), (155, 157, 69), (177, 179, 99), + (194, 197, 109), (206, 201, 124), (221, 216, 120), (233, 236, 121), + (240, 235, 118), (231, 221, 104), (221, 208, 98), (200, 199, 94), + (182, 172, 58), (171, 136, 47), (142, 133, 57), (124, 108, 46), + (81, 97, 48), (77, 94, 46), (89, 92, 52), (125, 84, 42), + (156, 99, 32), (134, 106, 41), (82, 99, 42), (76, 92, 40), + (65, 85, 37), (36, 75, 45), (23, 75, 49), (33, 79, 47), + (29, 90, 53), (41, 104, 75), (61, 112, 79), (74, 134, 72), + (109, 151, 93), (145, 173, 124), (174, 196, 161), (186, 206, 175), + (189, 207, 161), (175, 188, 141), (138, 168, 118), (109, 132, 109), + (73, 101, 101), (55, 95, 82), (46, 73, 57), (20, 55, 43), + (17, 36, 39), (12, 37, 36), (13, 28, 28), (20, 25, 20), + (21, 18, 23), (11, 15, 28), (30, 30, 17), (22, 29, 26), + (21, 28, 22), (19, 42, 22), (30, 37, 23), (31, 38, 30), + (25, 38, 31), (24, 27, 34), (25, 30, 48), (31, 46, 62), + (31, 55, 54), (35, 63, 60), (29, 76, 77), (31, 78, 79), + (36, 91, 82), (45, 90, 99), (49, 97, 111), (64, 108, 108), + (74, 122, 123), (99, 143, 139), (168, 173, 141), (190, 209, 149), + (204, 215, 159), (209, 226, 160), (209, 214, 153), (197, 207, 132), + (185, 180, 115), (169, 158, 102), (144, 149, 73), (102, 133, 62), + (73, 107, 58), (54, 74, 55), (42, 64, 52), (31, 52, 44), + (34, 45, 38), (39, 47, 30), (49, 51, 29), (55, 52, 34), + (44, 53, 45), (55, 76, 60), (81, 95, 78), (105, 124, 100), + (143, 165, 98), (182, 200, 132), (202, 214, 149), (215, 220, 168), + (230, 236, 165), (231, 235, 181), (216, 229, 170), (207, 213, 174), + (194, 210, 185), (180, 219, 201), (140, 198, 201), (142, 188, 193), + (159, 184, 158), (110, 160, 143), (82, 144, 137), (89, 145, 113), + (103, 137, 95), (131, 146, 98), (146, 151, 109), (156, 157, 110), + (196, 190, 134), (207, 201, 144), (208, 209, 154), (208, 211, 148), + (195, 201, 146), (131, 157, 129), (97, 132, 126), (77, 126, 117), + (49, 120, 108), (58, 113, 88), (65, 92, 76), (73, 95, 66), + (89, 94, 62), (123, 96, 47), (160, 100, 40), (165, 107, 42), + (143, 113, 58), (107, 105, 61), (88, 112, 70), (83, 97, 66), + (74, 81, 60), (57, 84, 64), (49, 90, 67), (54, 100, 76), + (60, 96, 84), (67, 115, 90), (98, 124, 91), (105, 118, 89), + (132, 135, 72), (163, 134, 84), (181, 167, 99), (198, 191, 105), + (210, 208, 116), (212, 212, 112), (219, 215, 108), (219, 219, 115), + (219, 221, 131), (227, 218, 137), (231, 228, 139), (228, 228, 135), + (226, 224, 134), (233, 228, 134), (236, 233, 129), (237, 233, 133), + (243, 233, 138), (243, 230, 134), (241, 232, 129), (237, 230, 123), + (226, 217, 108), (213, 211, 99), (193, 191, 89), (163, 175, 74), + (149, 155, 48), (144, 152, 62), (167, 155, 61), (182, 173, 83), + (186, 180, 104), (190, 176, 100), (178, 171, 89), (168, 141, 62), + (144, 137, 64), (107, 111, 51), (79, 86, 46), (35, 31, 17) +), + +// 61 gogh.the-night-cafe.ppm +( + (56, 36, 25), (72, 40, 16), (76, 46, 26), (96, 55, 31), + (121, 71, 41), (145, 88, 46), (161, 90, 60), (168, 109, 63), + (168, 119, 83), (169, 122, 86), (162, 123, 79), (139, 115, 75), + (102, 115, 73), (99, 123, 72), (105, 132, 75), (108, 137, 75), + (133, 147, 94), (146, 139, 137), (179, 173, 130), (198, 185, 140), + (202, 187, 145), (208, 180, 162), (215, 187, 141), (233, 188, 126), + (234, 192, 124), (212, 183, 114), (214, 176, 101), (222, 181, 93), + (214, 174, 83), (210, 165, 80), (207, 161, 83), (199, 155, 77), + (197, 154, 74), (194, 149, 67), (190, 144, 62), (187, 136, 62), + (188, 133, 66), (191, 122, 70), (192, 129, 67), (190, 137, 63), + (194, 137, 62), (196, 143, 64), (195, 149, 70), (200, 155, 70), + (201, 162, 73), (205, 165, 77), (206, 162, 85), (202, 160, 91), + (193, 150, 96), (183, 156, 98), (182, 153, 106), (179, 160, 112), + (163, 157, 107), (165, 147, 91), (163, 143, 88), (172, 137, 83), + (180, 134, 79), (181, 136, 77), (179, 132, 67), (175, 132, 72), + (178, 131, 73), (178, 124, 67), (180, 134, 64), (181, 131, 60), + (188, 126, 59), (181, 116, 63), (168, 117, 60), (173, 101, 61), + (161, 88, 58), (158, 80, 58), (144, 83, 53), (128, 81, 62), + (112, 94, 57), (98, 104, 62), (90, 102, 66), (89, 102, 71), + (99, 93, 83), (112, 100, 85), (127, 103, 76), (144, 107, 69), + (152, 110, 69), (150, 112, 63), (155, 113, 63), (162, 112, 60), + (157, 110, 57), (154, 109, 51), (154, 101, 55), (142, 91, 55), + (118, 79, 54), (107, 74, 48), (105, 74, 45), (103, 67, 36), + (108, 52, 39), (116, 56, 41), (122, 53, 37), (135, 60, 44), + (149, 67, 41), (155, 67, 45), (163, 68, 48), (170, 74, 50), + (175, 81, 55), (176, 98, 43), (173, 109, 37), (167, 112, 51), + (176, 116, 48), (170, 117, 57), (170, 119, 61), (170, 116, 55), + (168, 123, 59), (173, 129, 61), (174, 124, 65), (170, 120, 64), + (156, 126, 59), (157, 110, 61), (158, 93, 69), (140, 100, 55), + (132, 91, 47), (110, 76, 48), (93, 79, 54), (75, 63, 46), + (74, 52, 43), (70, 45, 43), (65, 48, 41), (72, 55, 41), + (80, 57, 37), (88, 61, 37), (97, 66, 44), (104, 66, 46), + (113, 69, 45), (125, 70, 43), (137, 83, 48), (149, 85, 42), + (158, 82, 45), (154, 90, 46), (155, 79, 49), (157, 81, 50), + (161, 80, 48), (165, 76, 55), (165, 75, 56), (160, 70, 49), + (159, 70, 45), (156, 74, 48), (158, 72, 45), (157, 68, 47), + (163, 67, 46), (161, 64, 45), (157, 66, 47), (162, 63, 44), + (162, 58, 43), (155, 59, 44), (154, 67, 47), (154, 76, 52), + (147, 80, 55), (134, 71, 58), (123, 73, 49), (115, 78, 57), + (113, 78, 59), (116, 89, 60), (119, 91, 69), (119, 92, 65), + (123, 92, 58), (129, 97, 52), (146, 103, 57), (152, 109, 61), + (151, 113, 61), (163, 114, 63), (163, 124, 60), (164, 122, 52), + (172, 133, 52), (166, 111, 58), (170, 101, 53), (168, 95, 51), + (163, 91, 51), (160, 91, 51), (160, 92, 52), (165, 97, 52), + (165, 96, 45), (171, 93, 49), (176, 92, 50), (180, 105, 51), + (186, 112, 59), (199, 121, 54), (201, 141, 67), (200, 146, 71), + (205, 156, 72), (207, 162, 76), (208, 165, 77), (212, 169, 86), + (215, 170, 89), (221, 174, 95), (218, 172, 100), (215, 172, 99), + (209, 166, 89), (206, 165, 83), (206, 165, 82), (196, 164, 86), + (195, 162, 91), (190, 160, 90), (189, 154, 92), (177, 149, 84), + (180, 142, 81), (172, 133, 70), (152, 129, 77), (109, 130, 76), + (100, 127, 70), (97, 123, 70), (98, 118, 68), (94, 116, 69), + (90, 113, 68), (87, 97, 55), (88, 80, 63), (92, 80, 57), + (86, 75, 61), (99, 73, 62), (119, 83, 63), (149, 98, 67), + (160, 113, 66), (171, 128, 69), (176, 142, 76), (190, 156, 75), + (204, 170, 86), (214, 175, 100), (225, 179, 110), (238, 201, 109), + (239, 196, 98), (225, 180, 89), (224, 178, 82), (218, 159, 77), + (212, 158, 81), (202, 155, 82), (200, 151, 79), (194, 149, 75), + (188, 141, 69), (188, 144, 69), (177, 140, 68), (188, 140, 66), + (178, 147, 70), (185, 141, 69), (186, 136, 77), (196, 138, 82), + (200, 143, 106), (211, 164, 103), (215, 172, 106), (208, 180, 132), + (202, 174, 141), (180, 169, 126), (181, 163, 117), (166, 141, 101), + (175, 131, 101), (149, 106, 85), (123, 92, 70), (99, 74, 55), + (76, 55, 43), (71, 47, 35), (68, 34, 33), (64, 45, 33) +), + +// 62 gogh.vegetable-montmartre.ppm +( + (40, 43, 29), (44, 40, 28), (66, 55, 30), (91, 61, 30), + (112, 65, 40), (137, 82, 49), (164, 102, 53), (196, 118, 67), + (220, 129, 69), (227, 128, 77), (232, 141, 72), (221, 151, 83), + (236, 161, 80), (225, 161, 82), (225, 163, 80), (221, 168, 96), + (221, 153, 88), (233, 171, 96), (210, 174, 105), (227, 161, 98), + (235, 172, 109), (238, 179, 116), (232, 176, 103), (231, 186, 102), + (227, 184, 110), (210, 171, 118), (190, 161, 102), (178, 160, 101), + (159, 156, 109), (143, 154, 124), (134, 149, 126), (132, 146, 120), + (127, 144, 118), (131, 144, 118), (144, 152, 114), (144, 150, 104), + (163, 143, 102), (185, 147, 93), (193, 154, 98), (199, 155, 92), + (198, 155, 90), (193, 146, 87), (192, 142, 90), (185, 142, 87), + (182, 141, 83), (169, 139, 80), (145, 132, 92), (125, 148, 90), + (127, 138, 106), (123, 137, 121), (120, 136, 121), (116, 132, 118), + (112, 134, 121), (106, 134, 117), (99, 122, 113), (96, 119, 109), + (91, 107, 99), (87, 103, 102), (89, 103, 86), (95, 100, 77), + (97, 96, 72), (95, 90, 64), (98, 89, 79), (100, 95, 69), + (117, 98, 64), (109, 97, 72), (104, 100, 72), (115, 96, 71), + (120, 99, 74), (133, 110, 70), (156, 123, 77), (165, 139, 76), + (177, 146, 79), (194, 150, 88), (210, 148, 87), (213, 156, 85), + (212, 158, 97), (211, 160, 98), (211, 161, 100), (218, 168, 111), + (222, 182, 114), (236, 194, 126), (232, 198, 125), (224, 187, 122), + (211, 183, 126), (228, 198, 141), (182, 189, 131), (151, 169, 141), + (144, 161, 134), (134, 155, 137), (129, 152, 136), (127, 149, 136), + (128, 148, 135), (124, 145, 132), (123, 145, 131), (116, 142, 132), + (111, 136, 131), (108, 130, 128), (107, 126, 122), (99, 122, 111), + (102, 105, 88), (107, 112, 82), (111, 107, 74), (115, 106, 67), + (123, 102, 60), (151, 111, 62), (162, 99, 57), (161, 103, 76), + (161, 115, 73), (154, 121, 70), (148, 125, 66), (139, 123, 78), + (143, 122, 88), (148, 124, 84), (135, 113, 77), (127, 117, 76), + (114, 111, 73), (114, 111, 73), (117, 106, 91), (114, 110, 74), + (111, 114, 83), (104, 111, 97), (99, 122, 112), (98, 124, 119), + (100, 127, 118), (105, 128, 119), (106, 129, 121), (112, 132, 121), + (114, 136, 127), (111, 136, 130), (112, 137, 131), (117, 141, 128), + (121, 147, 130), (125, 145, 126), (125, 141, 122), (124, 141, 120), + (129, 141, 111), (154, 137, 98), (166, 147, 94), (187, 148, 90), + (202, 147, 85), (211, 141, 84), (218, 142, 83), (219, 149, 89), + (227, 156, 96), (222, 155, 94), (210, 153, 97), (204, 152, 96), + (190, 148, 93), (172, 149, 91), (156, 147, 93), (143, 149, 103), + (137, 146, 106), (128, 143, 114), (125, 141, 115), (125, 138, 112), + (124, 131, 98), (122, 123, 91), (119, 120, 88), (105, 115, 79), + (103, 102, 69), (95, 94, 61), (84, 87, 62), (82, 78, 54), + (75, 75, 46), (71, 69, 54), (83, 76, 40), (99, 68, 31), + (101, 66, 33), (95, 48, 18), (107, 55, 26), (105, 60, 35), + (103, 57, 37), (111, 56, 27), (120, 40, 23), (117, 60, 29), + (118, 80, 46), (141, 99, 57), (149, 104, 54), (150, 98, 54), + (126, 88, 37), (128, 68, 33), (121, 73, 34), (117, 65, 22), + (133, 74, 34), (158, 66, 35), (168, 90, 53), (169, 97, 49), + (195, 102, 56), (200, 110, 61), (203, 118, 65), (209, 124, 65), + (196, 126, 55), (181, 128, 57), (174, 125, 72), (171, 121, 70), + (165, 114, 68), (168, 100, 58), (175, 105, 52), (182, 110, 62), + (178, 120, 72), (188, 131, 73), (197, 139, 79), (197, 143, 79), + (196, 155, 89), (195, 163, 97), (193, 159, 110), (193, 173, 124), + (185, 173, 134), (154, 164, 134), (150, 164, 131), (148, 159, 133), + (140, 157, 132), (135, 149, 128), (130, 152, 128), (124, 146, 126), + (121, 144, 124), (118, 142, 125), (116, 135, 118), (119, 130, 102), + (124, 131, 98), (125, 128, 95), (121, 120, 89), (114, 109, 76), + (114, 104, 70), (101, 95, 59), (103, 88, 59), (85, 84, 48), + (92, 75, 43), (97, 79, 55), (85, 85, 40), (97, 74, 35), + (103, 72, 40), (98, 76, 42), (103, 78, 45), (101, 83, 47), + (105, 88, 60), (115, 95, 59), (114, 99, 55), (138, 112, 55), + (151, 122, 65), (171, 130, 69), (175, 125, 74), (195, 135, 72), + (211, 143, 73), (219, 137, 76), (224, 140, 74), (215, 144, 71), + (198, 140, 76), (186, 137, 70), (173, 126, 68), (167, 109, 50), + (147, 102, 55), (110, 85, 39), (87, 62, 37), (52, 51, 30) +), + +// 63 matisse.bonheur-vivre.ppm +( + (3, 3, 3), (39, 31, 46), (91, 59, 63), (169, 125, 81), + (206, 159, 105), (208, 186, 115), (204, 196, 101), (223, 190, 85), + (245, 207, 76), (247, 210, 66), (248, 210, 60), (245, 197, 62), + (222, 186, 74), (207, 176, 85), (191, 155, 108), (161, 126, 102), + (105, 111, 111), (80, 98, 102), (43, 82, 60), (36, 61, 45), + (23, 54, 40), (18, 51, 42), (32, 60, 38), (53, 74, 51), + (73, 98, 67), (118, 135, 93), (175, 161, 120), (219, 165, 132), + (226, 171, 140), (226, 195, 154), (228, 206, 139), (241, 213, 115), + (239, 208, 112), (234, 199, 103), (223, 189, 95), (227, 161, 77), + (220, 151, 71), (205, 158, 48), (202, 142, 41), (184, 121, 37), + (177, 116, 25), (160, 107, 36), (100, 116, 44), (81, 66, 62), + (66, 52, 60), (75, 84, 83), (79, 90, 108), (94, 104, 112), + (122, 120, 122), (175, 163, 125), (212, 176, 145), (221, 190, 167), + (225, 201, 166), (232, 199, 158), (230, 198, 147), (228, 199, 107), + (228, 208, 101), (226, 206, 68), (230, 203, 59), (223, 197, 46), + (243, 199, 23), (232, 203, 40), (217, 191, 46), (218, 173, 35), + (201, 178, 35), (226, 186, 25), (210, 168, 29), (204, 176, 59), + (217, 150, 36), (188, 119, 21), (216, 163, 19), (220, 145, 9), + (225, 159, 1), (223, 157, 1), (219, 135, 0), (204, 134, 21), + (204, 113, 2), (193, 104, 2), (195, 112, 0), (186, 115, 18), + (173, 117, 13), (183, 104, 19), (183, 118, 32), (164, 155, 43), + (142, 155, 66), (97, 138, 69), (47, 88, 61), (48, 79, 51), + (35, 74, 49), (39, 72, 52), (42, 77, 57), (67, 86, 90), + (90, 95, 101), (142, 133, 104), (168, 142, 94), (187, 136, 104), + (201, 135, 106), (207, 138, 123), (209, 140, 121), (217, 151, 122), + (217, 151, 127), (222, 150, 126), (219, 152, 134), (222, 167, 136), + (227, 170, 144), (220, 174, 146), (220, 183, 156), (219, 176, 157), + (192, 169, 155), (138, 168, 128), (104, 149, 108), (65, 119, 86), + (38, 87, 71), (29, 70, 58), (25, 59, 54), (25, 69, 56), + (29, 66, 56), (43, 88, 64), (73, 117, 88), (118, 135, 93), + (153, 142, 78), (193, 146, 72), (198, 145, 61), (199, 162, 70), + (196, 157, 53), (219, 150, 47), (222, 163, 48), (217, 193, 59), + (222, 201, 62), (222, 189, 82), (207, 180, 93), (211, 185, 98), + (205, 179, 100), (190, 161, 97), (169, 154, 85), (117, 158, 94), + (82, 131, 102), (75, 121, 93), (78, 119, 94), (88, 121, 90), + (131, 102, 87), (162, 105, 38), (160, 101, 33), (163, 104, 28), + (166, 88, 30), (176, 78, 3), (169, 71, 3), (166, 43, 1), + (159, 15, 8), (154, 8, 8), (165, 6, 3), (160, 3, 0), + (149, 1, 0), (148, 9, 3), (50, 11, 10), (48, 29, 12), + (46, 24, 27), (48, 39, 33), (82, 70, 32), (155, 103, 30), + (172, 119, 46), (184, 130, 54), (210, 156, 69), (227, 161, 91), + (220, 169, 110), (224, 155, 107), (210, 131, 104), (184, 106, 94), + (170, 101, 86), (166, 91, 81), (156, 96, 85), (88, 111, 82), + (76, 123, 90), (62, 119, 86), (54, 116, 91), (66, 123, 102), + (86, 142, 116), (126, 158, 123), (163, 165, 118), (209, 168, 119), + (222, 178, 144), (225, 200, 163), (226, 212, 162), (221, 201, 167), + (225, 209, 170), (215, 213, 188), (234, 206, 190), (224, 210, 171), + (227, 201, 174), (223, 203, 178), (225, 181, 170), (218, 163, 147), + (196, 142, 130), (181, 132, 97), (180, 111, 63), (198, 93, 35), + (200, 101, 3), (213, 103, 26), (208, 94, 4), (209, 84, 8), + (210, 67, 1), (195, 66, 1), (194, 74, 2), (181, 70, 0), + (188, 65, 1), (189, 53, 4), (184, 50, 1), (179, 53, 3), + (170, 41, 4), (174, 13, 6), (176, 13, 3), (178, 48, 5), + (166, 64, 52), (197, 90, 56), (188, 99, 80), (209, 104, 96), + (222, 122, 92), (206, 131, 112), (206, 151, 120), (199, 161, 131), + (173, 180, 138), (136, 179, 145), (98, 156, 130), (83, 147, 117), + (70, 134, 107), (85, 132, 106), (110, 144, 103), (162, 140, 88), + (178, 118, 84), (192, 122, 93), (204, 122, 113), (203, 126, 119), + (196, 137, 118), (191, 131, 113), (182, 130, 107), (161, 153, 120), + (104, 145, 109), (78, 128, 103), (53, 112, 87), (35, 102, 80), + (40, 96, 71), (52, 103, 75), (97, 137, 79), (138, 159, 67), + (187, 173, 64), (192, 177, 59), (210, 190, 61), (219, 183, 91), + (224, 196, 104), (221, 205, 139), (225, 202, 155), (209, 201, 152), + (156, 176, 144), (115, 120, 128), (69, 87, 96), (27, 58, 48) +), + +// 64 matisse.flowers.ppm +( + (13, 10, 17), (66, 30, 14), (140, 53, 34), (165, 44, 33), + (205, 94, 45), (177, 121, 75), (182, 159, 89), (185, 175, 117), + (209, 186, 130), (203, 189, 140), (208, 192, 141), (214, 198, 142), + (220, 201, 150), (221, 204, 151), (222, 202, 151), (220, 198, 141), + (216, 197, 135), (220, 203, 142), (216, 203, 156), (224, 207, 168), + (227, 206, 168), (227, 212, 168), (230, 217, 173), (232, 217, 181), + (235, 218, 193), (241, 213, 200), (235, 218, 199), (233, 218, 198), + (231, 217, 185), (231, 219, 176), (228, 213, 170), (221, 208, 170), + (211, 204, 178), (206, 203, 188), (209, 205, 191), (214, 205, 197), + (211, 207, 198), (200, 201, 195), (199, 199, 187), (198, 197, 178), + (203, 198, 167), (206, 197, 164), (213, 202, 163), (216, 202, 164), + (218, 196, 160), (224, 191, 153), (225, 189, 141), (215, 194, 130), + (217, 191, 115), (220, 197, 104), (221, 188, 104), (217, 163, 87), + (215, 161, 51), (211, 172, 50), (213, 174, 59), (206, 166, 88), + (214, 164, 87), (208, 153, 87), (197, 121, 93), (209, 82, 39), + (193, 21, 8), (168, 38, 20), (170, 75, 61), (151, 127, 95), + (154, 165, 148), (180, 188, 174), (184, 187, 172), (181, 187, 175), + (178, 184, 177), (157, 178, 184), (152, 175, 182), (133, 172, 173), + (130, 171, 159), (139, 171, 165), (156, 177, 183), (175, 187, 185), + (180, 189, 190), (182, 189, 183), (189, 190, 174), (190, 192, 168), + (202, 194, 160), (206, 197, 153), (212, 201, 158), (218, 202, 169), + (225, 209, 179), (226, 216, 183), (237, 222, 193), (236, 222, 200), + (235, 223, 207), (235, 221, 210), (236, 222, 213), (233, 223, 214), + (234, 219, 215), (234, 221, 214), (233, 220, 212), (234, 221, 214), + (237, 222, 217), (239, 226, 216), (239, 233, 216), (239, 230, 221), + (239, 229, 219), (237, 228, 214), (233, 222, 211), (231, 221, 208), + (230, 223, 204), (232, 216, 201), (222, 215, 187), (207, 205, 185), + (199, 200, 185), (195, 197, 184), (195, 196, 182), (194, 195, 178), + (186, 190, 176), (180, 184, 177), (158, 174, 178), (143, 172, 156), + (116, 159, 149), (72, 103, 96), (55, 76, 65), (21, 42, 44), + (41, 38, 37), (70, 59, 35), (149, 106, 97), (175, 131, 93), + (213, 180, 99), (219, 188, 113), (221, 195, 117), (227, 204, 124), + (226, 206, 143), (233, 198, 151), (229, 211, 163), (230, 215, 178), + (233, 216, 200), (220, 218, 206), (211, 211, 204), (195, 198, 199), + (185, 197, 189), (187, 189, 187), (188, 182, 188), (181, 177, 182), + (175, 178, 176), (161, 175, 162), (163, 141, 151), (176, 112, 118), + (141, 99, 109), (82, 80, 53), (53, 51, 40), (36, 40, 51), + (60, 73, 63), (78, 111, 97), (131, 161, 125), (154, 178, 154), + (156, 181, 179), (157, 182, 187), (164, 192, 197), (180, 188, 197), + (192, 194, 200), (200, 200, 198), (209, 208, 199), (215, 214, 202), + (213, 218, 201), (212, 215, 205), (205, 207, 204), (198, 198, 204), + (192, 196, 199), (180, 193, 193), (176, 186, 192), (174, 184, 189), + (158, 181, 187), (151, 175, 178), (135, 169, 158), (116, 156, 147), + (57, 83, 86), (56, 31, 32), (70, 28, 19), (121, 56, 46), + (155, 75, 65), (178, 106, 114), (193, 133, 101), (182, 171, 116), + (165, 167, 140), (188, 139, 142), (184, 123, 127), (186, 114, 117), + (197, 146, 111), (208, 168, 141), (221, 184, 171), (208, 198, 181), + (213, 206, 191), (223, 209, 195), (232, 216, 201), (232, 216, 207), + (231, 217, 208), (232, 220, 213), (226, 220, 215), (219, 217, 209), + (217, 218, 209), (216, 209, 208), (202, 202, 202), (192, 197, 195), + (193, 195, 186), (192, 193, 185), (193, 195, 182), (194, 198, 191), + (205, 206, 200), (217, 210, 195), (231, 215, 202), (231, 218, 204), + (235, 220, 205), (236, 220, 204), (234, 221, 205), (232, 221, 205), + (231, 217, 207), (231, 214, 204), (225, 207, 196), (214, 200, 192), + (205, 191, 187), (204, 169, 169), (206, 173, 167), (200, 193, 175), + (195, 196, 180), (194, 198, 186), (198, 200, 196), (215, 201, 202), + (229, 214, 207), (231, 217, 208), (233, 219, 209), (234, 223, 211), + (238, 227, 211), (240, 229, 207), (240, 227, 208), (239, 226, 209), + (237, 224, 208), (236, 220, 205), (235, 215, 204), (227, 211, 197), + (214, 208, 193), (197, 197, 184), (188, 189, 172), (169, 180, 160), + (149, 169, 137), (115, 136, 85), (73, 66, 39), (51, 31, 30), + (35, 32, 12), (33, 28, 14), (38, 41, 33), (63, 55, 40), + (77, 100, 78), (129, 155, 131), (123, 162, 151), (129, 165, 159), + (135, 167, 158), (138, 150, 139), (124, 121, 135), (56, 54, 65) +), + +// 65 matisse.lecon-musique.ppm +( + (17, 24, 13), (25, 50, 37), (51, 60, 57), (56, 70, 71), + (50, 108, 84), (60, 120, 101), (78, 109, 104), (91, 110, 128), + (119, 123, 103), (131, 141, 108), (139, 147, 107), (140, 144, 102), + (129, 130, 88), (129, 120, 90), (142, 119, 69), (162, 122, 56), + (171, 127, 64), (179, 127, 69), (148, 107, 66), (133, 103, 70), + (107, 101, 68), (92, 116, 55), (83, 102, 62), (78, 127, 54), + (69, 132, 63), (77, 137, 76), (85, 144, 72), (89, 154, 81), + (103, 161, 72), (98, 163, 76), (101, 156, 80), (98, 164, 114), + (107, 177, 79), (106, 162, 118), (120, 164, 114), (128, 150, 134), + (129, 160, 141), (138, 163, 154), (140, 170, 157), (142, 170, 160), + (129, 167, 170), (152, 180, 168), (160, 179, 158), (173, 190, 157), + (172, 193, 172), (173, 201, 181), (183, 205, 191), (180, 198, 192), + (187, 202, 204), (191, 202, 196), (206, 209, 188), (211, 213, 196), + (209, 214, 190), (211, 208, 189), (200, 201, 185), (197, 199, 182), + (204, 198, 162), (196, 190, 159), (190, 192, 136), (179, 190, 122), + (181, 178, 114), (184, 163, 122), (175, 156, 120), (172, 156, 120), + (171, 156, 126), (147, 146, 127), (132, 151, 135), (141, 158, 139), + (153, 154, 141), (154, 149, 131), (148, 158, 114), (150, 150, 113), + (136, 142, 113), (128, 122, 96), (122, 119, 98), (114, 121, 95), + (113, 117, 90), (106, 107, 82), (112, 94, 85), (130, 95, 87), + (150, 92, 81), (167, 91, 92), (180, 78, 72), (181, 74, 75), + (185, 69, 75), (182, 67, 62), (194, 85, 50), (196, 122, 30), + (221, 159, 7), (226, 161, 6), (220, 163, 6), (234, 187, 37), + (190, 132, 59), (207, 156, 59), (186, 128, 40), (187, 130, 19), + (188, 129, 36), (186, 115, 28), (162, 108, 32), (154, 110, 45), + (115, 91, 48), (98, 100, 65), (93, 97, 62), (90, 93, 64), + (70, 81, 63), (71, 74, 57), (75, 78, 50), (96, 74, 40), + (107, 80, 43), (150, 81, 55), (178, 92, 50), (189, 88, 80), + (186, 105, 102), (175, 138, 121), (195, 151, 124), (205, 153, 135), + (187, 179, 141), (191, 210, 162), (209, 223, 182), (228, 234, 208), + (228, 225, 208), (219, 221, 207), (210, 212, 197), (206, 206, 195), + (188, 198, 189), (188, 194, 178), (183, 187, 160), (183, 191, 155), + (186, 186, 144), (185, 176, 141), (191, 175, 136), (191, 163, 124), + (168, 170, 111), (155, 184, 107), (145, 177, 97), (120, 168, 75), + (113, 149, 78), (117, 161, 80), (121, 171, 82), (134, 178, 96), + (152, 190, 111), (145, 194, 131), (150, 180, 133), (164, 179, 132), + (167, 177, 128), (178, 176, 139), (169, 166, 132), (162, 157, 129), + (156, 146, 119), (154, 146, 118), (154, 131, 117), (150, 109, 103), + (171, 93, 90), (185, 102, 92), (197, 102, 96), (193, 104, 95), + (183, 84, 82), (173, 71, 64), (173, 65, 63), (160, 58, 43), + (157, 48, 38), (120, 4, 5), (38, 30, 9), (32, 26, 12), + (31, 25, 14), (47, 48, 28), (63, 52, 26), (94, 63, 20), + (99, 66, 22), (115, 88, 28), (121, 98, 33), (158, 111, 48), + (176, 129, 61), (185, 121, 30), (192, 148, 29), (173, 124, 34), + (192, 107, 2), (192, 98, 3), (185, 91, 2), (161, 89, 9), + (158, 89, 22), (154, 96, 32), (122, 86, 46), (113, 85, 37), + (107, 94, 41), (88, 83, 60), (75, 80, 50), (68, 80, 54), + (65, 78, 58), (63, 71, 53), (59, 66, 40), (58, 51, 40), + (60, 68, 37), (49, 55, 37), (63, 65, 37), (62, 64, 42), + (66, 73, 52), (70, 80, 58), (80, 90, 74), (80, 95, 84), + (85, 93, 71), (94, 101, 70), (98, 98, 67), (96, 100, 77), + (103, 111, 82), (104, 115, 95), (111, 112, 91), (104, 109, 87), + (93, 113, 83), (76, 110, 84), (67, 93, 94), (69, 85, 89), + (75, 90, 74), (78, 81, 64), (72, 75, 57), (70, 73, 56), + (68, 71, 50), (92, 72, 33), (108, 59, 21), (138, 77, 13), + (161, 80, 5), (160, 65, 0), (154, 54, 0), (138, 34, 2), + (55, 42, 5), (20, 14, 6), (14, 9, 4), (24, 25, 12), + (33, 39, 30), (45, 45, 35), (45, 48, 40), (51, 62, 49), + (60, 74, 55), (63, 77, 63), (59, 103, 64), (75, 128, 70), + (89, 149, 79), (96, 157, 105), (101, 175, 137), (123, 187, 147), + (124, 194, 146), (137, 189, 144), (110, 177, 136), (115, 181, 127), + (112, 176, 129), (119, 162, 149), (91, 170, 136), (84, 152, 119), + (67, 152, 116), (52, 140, 116), (49, 141, 121), (46, 134, 117), + (28, 119, 107), (42, 88, 69), (47, 75, 61), (33, 50, 45) +), + +// 66 modigliani.nude-caryatid.ppm +( + (31, 24, 17), (57, 47, 38), (89, 77, 61), (119, 88, 86), + (151, 108, 104), (173, 128, 129), (184, 141, 152), (196, 148, 160), + (197, 156, 158), (201, 164, 169), (199, 171, 174), (200, 176, 179), + (203, 178, 181), (203, 179, 182), (203, 178, 185), (201, 178, 183), + (202, 177, 186), (198, 178, 184), (195, 179, 178), (203, 173, 173), + (202, 169, 169), (204, 167, 163), (199, 155, 155), (200, 158, 151), + (203, 157, 147), (199, 157, 148), (196, 152, 139), (202, 144, 123), + (200, 142, 123), (190, 130, 119), (175, 111, 102), (175, 92, 77), + (168, 91, 81), (158, 87, 83), (139, 73, 72), (133, 71, 62), + (114, 57, 55), (86, 51, 50), (50, 34, 32), (40, 32, 30), + (33, 31, 33), (33, 31, 34), (40, 35, 34), (57, 53, 43), + (82, 70, 66), (108, 84, 89), (130, 107, 112), (170, 134, 135), + (184, 142, 145), (191, 151, 145), (189, 151, 150), (181, 147, 146), + (172, 155, 132), (169, 153, 130), (168, 152, 129), (168, 151, 129), + (167, 149, 127), (149, 128, 113), (142, 120, 97), (140, 108, 87), + (127, 105, 84), (127, 85, 80), (118, 77, 78), (115, 76, 80), + (112, 80, 74), (96, 77, 60), (72, 57, 48), (44, 38, 36), + (38, 29, 34), (35, 29, 31), (37, 31, 27), (41, 33, 31), + (48, 40, 38), (86, 56, 51), (116, 79, 74), (125, 95, 94), + (153, 110, 106), (176, 122, 127), (185, 135, 135), (194, 143, 142), + (195, 145, 143), (190, 145, 134), (179, 129, 122), (164, 119, 119), + (156, 111, 108), (140, 106, 101), (128, 103, 98), (124, 106, 103), + (125, 97, 95), (145, 92, 89), (156, 93, 87), (157, 92, 91), + (164, 100, 96), (165, 109, 111), (182, 123, 125), (181, 124, 126), + (180, 134, 130), (169, 149, 128), (169, 151, 129), (171, 155, 130), + (193, 151, 139), (201, 154, 150), (204, 156, 152), (212, 163, 163), + (210, 166, 162), (216, 175, 169), (225, 188, 179), (218, 185, 188), + (217, 192, 196), (224, 195, 196), (224, 195, 200), (225, 205, 209), + (229, 209, 212), (226, 208, 211), (218, 203, 212), (217, 194, 200), + (215, 196, 199), (214, 191, 194), (218, 185, 183), (215, 183, 181), + (214, 175, 173), (206, 167, 164), (197, 159, 160), (193, 154, 153), + (177, 150, 148), (170, 154, 132), (168, 149, 127), (160, 139, 111), + (152, 126, 103), (152, 128, 104), (161, 142, 118), (168, 150, 129), + (174, 156, 134), (190, 157, 148), (196, 159, 161), (196, 164, 172), + (196, 174, 181), (198, 176, 183), (202, 180, 182), (206, 180, 180), + (210, 178, 180), (214, 187, 183), (209, 188, 189), (208, 184, 193), + (211, 189, 191), (215, 194, 193), (212, 196, 197), (207, 191, 199), + (194, 189, 194), (177, 176, 180), (173, 159, 165), (173, 149, 155), + (170, 149, 154), (167, 136, 146), (161, 125, 128), (146, 109, 113), + (132, 98, 92), (128, 80, 81), (133, 77, 80), (148, 92, 92), + (156, 102, 99), (165, 117, 113), (174, 131, 128), (187, 143, 140), + (181, 142, 139), (168, 122, 122), (144, 108, 104), (121, 92, 94), + (107, 83, 81), (74, 63, 54), (45, 43, 41), (41, 32, 31), + (37, 28, 26), (33, 25, 25), (35, 25, 24), (38, 28, 27), + (58, 40, 24), (76, 54, 40), (109, 68, 56), (104, 65, 44), + (67, 53, 40), (42, 34, 32), (36, 27, 28), (32, 23, 27), + (29, 20, 23), (30, 20, 21), (31, 21, 20), (29, 20, 19), + (21, 15, 15), (15, 11, 12), (15, 10, 11), (18, 7, 9), + (18, 12, 12), (21, 12, 14), (21, 12, 15), (21, 15, 17), + (25, 20, 21), (29, 23, 24), (30, 24, 27), (31, 24, 27), + (34, 25, 26), (40, 35, 33), (51, 49, 46), (68, 72, 61), + (105, 99, 94), (123, 109, 116), (144, 118, 116), (157, 149, 136), + (166, 150, 125), (154, 134, 102), (151, 127, 103), (147, 123, 99), + (143, 118, 96), (153, 104, 100), (160, 107, 104), (166, 115, 103), + (181, 121, 112), (187, 119, 112), (177, 123, 111), (155, 112, 108), + (142, 119, 97), (138, 122, 97), (126, 106, 85), (118, 99, 81), + (103, 80, 60), (80, 60, 48), (53, 45, 37), (42, 34, 32), + (41, 33, 31), (43, 38, 35), (66, 57, 53), (90, 71, 73), + (116, 80, 81), (135, 101, 104), (152, 117, 118), (168, 139, 142), + (164, 153, 155), (153, 157, 168), (147, 158, 172), (170, 152, 159), + (187, 158, 166), (186, 163, 166), (188, 164, 163), (192, 168, 167), + (201, 167, 164), (204, 168, 168), (202, 166, 167), (198, 163, 166), + (190, 161, 162), (185, 154, 157), (187, 149, 152), (182, 147, 147), + (166, 135, 138), (139, 114, 121), (104, 92, 88), (69, 62, 55) +), + +// 67 braque.instruments.ppm +( + (13, 9, 4), (22, 18, 10), (35, 31, 20), (48, 42, 14), + (56, 45, 7), (68, 57, 11), (83, 66, 15), (101, 82, 18), + (117, 89, 15), (116, 87, 19), (103, 83, 16), (88, 94, 25), + (72, 92, 33), (64, 83, 25), (58, 79, 20), (57, 68, 18), + (54, 66, 15), (62, 69, 15), (65, 73, 13), (70, 68, 11), + (78, 62, 12), (87, 61, 11), (103, 68, 11), (111, 70, 20), + (128, 81, 12), (132, 87, 23), (139, 85, 22), (134, 107, 24), + (138, 115, 30), (146, 118, 44), (157, 130, 56), (165, 139, 63), + (161, 145, 82), (170, 164, 114), (186, 177, 126), (195, 185, 128), + (210, 200, 137), (220, 213, 139), (234, 213, 133), (240, 213, 133), + (239, 220, 145), (249, 227, 147), (249, 227, 153), (250, 231, 160), + (244, 227, 162), (247, 232, 165), (249, 242, 188), (245, 242, 171), + (255, 252, 190), (251, 241, 168), (247, 241, 181), (241, 231, 170), + (237, 229, 166), (222, 217, 161), (212, 205, 159), (208, 202, 146), + (205, 192, 123), (196, 174, 99), (178, 150, 78), (168, 140, 66), + (150, 126, 52), (131, 117, 43), (127, 95, 33), (120, 96, 34), + (106, 95, 41), (95, 90, 45), (93, 87, 50), (93, 91, 54), + (97, 86, 62), (118, 109, 80), (146, 132, 93), (169, 161, 125), + (189, 183, 135), (207, 197, 145), (213, 206, 148), (221, 206, 139), + (223, 203, 137), (223, 202, 137), (225, 204, 134), (226, 207, 130), + (234, 207, 127), (222, 203, 126), (216, 188, 114), (210, 179, 98), + (223, 172, 46), (217, 171, 46), (211, 166, 46), (208, 159, 29), + (202, 145, 22), (199, 153, 33), (196, 161, 62), (203, 179, 91), + (211, 192, 115), (213, 197, 127), (220, 204, 130), (221, 208, 129), + (221, 201, 130), (212, 196, 124), (200, 179, 113), (194, 174, 96), + (175, 154, 83), (166, 146, 72), (167, 147, 76), (180, 156, 90), + (203, 177, 110), (211, 192, 115), (213, 198, 116), (218, 199, 122), + (209, 191, 107), (193, 167, 77), (206, 159, 42), (194, 146, 32), + (193, 141, 20), (186, 135, 10), (179, 141, 16), (179, 143, 8), + (153, 120, 7), (147, 110, 20), (128, 110, 25), (118, 103, 37), + (115, 107, 38), (110, 122, 46), (117, 120, 64), (132, 129, 74), + (140, 133, 89), (145, 133, 85), (135, 128, 80), (136, 112, 67), + (139, 116, 53), (138, 118, 31), (136, 109, 27), (133, 101, 14), + (135, 92, 4), (130, 80, 2), (123, 74, 6), (111, 73, 1), + (93, 67, 4), (80, 63, 8), (79, 61, 14), (82, 70, 22), + (89, 93, 19), (106, 100, 28), (119, 103, 39), (139, 125, 42), + (159, 138, 59), (176, 148, 84), (188, 162, 110), (207, 184, 130), + (215, 196, 131), (219, 193, 137), (208, 187, 126), (201, 174, 109), + (177, 158, 83), (179, 154, 61), (173, 137, 39), (177, 139, 26), + (177, 145, 20), (150, 115, 11), (139, 108, 7), (130, 101, 9), + (114, 76, 5), (103, 67, 8), (100, 55, 5), (82, 59, 8), + (82, 58, 17), (71, 64, 22), (66, 74, 18), (60, 73, 22), + (60, 73, 28), (68, 85, 27), (79, 88, 33), (87, 97, 37), + (90, 107, 37), (96, 97, 58), (120, 113, 63), (137, 121, 57), + (159, 131, 57), (171, 144, 64), (165, 147, 63), (161, 136, 48), + (162, 125, 34), (154, 122, 42), (145, 113, 29), (127, 102, 11), + (110, 93, 3), (87, 87, 1), (83, 59, 0), (79, 56, 5), + (81, 53, 6), (71, 45, 6), (61, 36, 2), (60, 34, 1), + (54, 31, 5), (51, 24, 3), (46, 19, 0), (39, 15, 4), + (34, 16, 2), (33, 15, 4), (36, 13, 5), (39, 16, 3), + (37, 29, 3), (38, 27, 8), (38, 27, 8), (44, 20, 9), + (56, 28, 6), (57, 26, 2), (61, 25, 2), (65, 29, 4), + (58, 30, 9), (65, 38, 10), (66, 45, 13), (73, 47, 10), + (70, 54, 8), (70, 55, 6), (56, 59, 6), (48, 61, 14), + (48, 55, 7), (43, 55, 5), (48, 55, 14), (45, 68, 8), + (48, 85, 20), (56, 86, 24), (60, 81, 22), (57, 81, 25), + (55, 82, 40), (71, 74, 51), (89, 75, 46), (90, 82, 53), + (102, 82, 64), (120, 106, 81), (130, 123, 78), (142, 137, 81), + (163, 153, 92), (178, 167, 112), (186, 175, 120), (180, 168, 120), + (164, 154, 93), (147, 144, 74), (134, 132, 71), (130, 115, 66), + (120, 108, 60), (109, 98, 44), (110, 87, 29), (128, 87, 22), + (122, 82, 10), (110, 77, 10), (100, 65, 5), (91, 55, 2), + (81, 54, 3), (76, 54, 7), (64, 50, 9), (44, 52, 13), + (35, 42, 8), (35, 41, 8), (29, 26, 9), (24, 12, 1) +), + +// 68 calcoast09.ppm +( + (32, 32, 44), (52, 56, 66), (68, 71, 89), (76, 94, 103), + (82, 116, 122), (83, 114, 143), (90, 123, 154), (94, 127, 158), + (96, 130, 161), (99, 134, 164), (99, 135, 167), (101, 136, 168), + (103, 138, 170), (103, 139, 171), (103, 139, 173), (103, 139, 174), + (103, 139, 175), (104, 140, 174), (106, 142, 176), (108, 143, 175), + (108, 143, 176), (109, 144, 176), (108, 143, 174), (106, 141, 172), + (103, 139, 173), (102, 138, 172), (100, 136, 170), (98, 134, 170), + (98, 133, 168), (97, 131, 166), (95, 129, 164), (95, 128, 159), + (95, 128, 156), (94, 126, 153), (92, 127, 145), (82, 118, 140), + (76, 115, 122), (69, 100, 107), (70, 89, 94), (61, 84, 91), + (64, 76, 88), (71, 75, 78), (70, 72, 68), (65, 73, 73), + (66, 65, 73), (56, 62, 74), (55, 59, 71), (54, 59, 69), + (50, 55, 64), (41, 45, 58), (42, 41, 53), (44, 44, 53), + (46, 44, 58), (48, 50, 55), (58, 56, 56), (57, 64, 65), + (72, 68, 63), (81, 77, 64), (96, 82, 62), (103, 93, 73), + (100, 92, 78), (92, 89, 71), (88, 88, 71), (89, 84, 73), + (87, 87, 77), (94, 94, 84), (99, 101, 89), (99, 107, 99), + (96, 110, 119), (85, 113, 143), (85, 115, 149), (91, 124, 155), + (96, 129, 160), (100, 135, 165), (106, 139, 170), (108, 143, 172), + (119, 146, 156), (127, 149, 160), (148, 165, 157), (165, 188, 190), + (179, 191, 172), (184, 189, 154), (190, 194, 149), (174, 155, 104), + (147, 131, 96), (144, 138, 108), (137, 135, 107), (138, 130, 112), + (145, 142, 115), (132, 137, 131), (114, 128, 136), (101, 130, 142), + (102, 130, 157), (96, 129, 162), (96, 130, 165), (98, 131, 166), + (99, 133, 168), (99, 134, 169), (100, 134, 169), (100, 136, 169), + (100, 134, 169), (100, 134, 169), (99, 134, 166), (96, 129, 164), + (94, 127, 160), (92, 124, 157), (90, 123, 154), (84, 114, 147), + (81, 109, 139), (75, 101, 129), (62, 91, 119), (59, 89, 105), + (55, 88, 99), (55, 87, 98), (57, 82, 112), (58, 81, 115), + (63, 87, 120), (67, 93, 126), (74, 100, 133), (77, 106, 138), + (81, 110, 143), (80, 110, 144), (78, 107, 141), (75, 101, 134), + (68, 94, 127), (62, 88, 121), (64, 90, 120), (73, 98, 128), + (75, 104, 136), (79, 110, 140), (81, 111, 144), (82, 112, 146), + (82, 111, 142), (77, 105, 135), (79, 108, 117), (81, 98, 115), + (87, 96, 103), (91, 95, 97), (94, 91, 91), (101, 102, 94), + (117, 116, 100), (125, 128, 107), (118, 134, 131), (122, 145, 148), + (130, 166, 167), (140, 176, 186), (156, 193, 200), (163, 204, 212), + (167, 213, 212), (169, 207, 215), (168, 207, 211), (157, 199, 205), + (137, 175, 189), (130, 166, 174), (118, 152, 164), (118, 153, 157), + (118, 158, 160), (123, 164, 166), (136, 177, 177), (146, 191, 197), + (162, 197, 198), (166, 201, 203), (161, 200, 203), (153, 189, 200), + (137, 175, 185), (121, 163, 167), (108, 147, 151), (106, 141, 153), + (98, 131, 161), (96, 131, 161), (100, 136, 155), (111, 132, 145), + (112, 134, 144), (105, 134, 138), (101, 134, 138), (105, 130, 141), + (109, 117, 128), (110, 115, 107), (104, 107, 95), (113, 111, 88), + (119, 112, 92), (126, 124, 103), (121, 116, 103), (119, 117, 90), + (117, 112, 85), (112, 102, 82), (95, 95, 81), (86, 86, 80), + (80, 84, 83), (81, 92, 101), (85, 112, 122), (94, 127, 132), + (106, 140, 143), (116, 162, 160), (142, 183, 185), (184, 201, 205), + (189, 224, 229), (214, 248, 247), (224, 251, 250), (201, 232, 240), + (187, 218, 222), (170, 194, 203), (138, 175, 176), (115, 153, 162), + (101, 137, 151), (83, 126, 132), (67, 106, 111), (70, 87, 93), + (73, 80, 82), (73, 76, 78), (71, 81, 80), (71, 78, 81), + (66, 75, 88), (61, 81, 97), (70, 91, 117), (73, 98, 127), + (77, 106, 138), (82, 110, 143), (83, 115, 148), (85, 118, 151), + (90, 123, 156), (90, 124, 157), (92, 125, 158), (93, 126, 159), + (93, 126, 159), (94, 127, 160), (94, 127, 162), (94, 127, 162), + (94, 128, 163), (95, 128, 163), (95, 129, 164), (95, 128, 163), + (95, 128, 161), (93, 126, 159), (93, 126, 157), (94, 124, 153), + (91, 122, 140), (81, 116, 124), (78, 105, 114), (81, 91, 96), + (84, 84, 80), (77, 78, 71), (64, 62, 54), (51, 43, 35), + (37, 29, 35), (26, 23, 30), (0, 0, 0), (5, 2, 12), + (22, 27, 46), (35, 32, 48), (43, 40, 50), (42, 49, 58), + (29, 56, 73), (35, 62, 80), (38, 47, 63), (29, 33, 53) +), + +// 69 dodge102.ppm +( + (47, 42, 46), (88, 93, 90), (136, 152, 150), (140, 218, 225), + (130, 242, 251), (123, 245, 243), (122, 188, 198), (99, 137, 153), + (74, 113, 109), (74, 89, 82), (58, 73, 61), (49, 64, 54), + (58, 41, 32), (64, 30, 24), (63, 28, 23), (65, 27, 22), + (76, 30, 21), (75, 34, 17), (74, 32, 14), (79, 31, 14), + (80, 32, 15), (85, 31, 18), (82, 34, 23), (89, 42, 25), + (85, 45, 27), (78, 49, 29), (77, 40, 29), (77, 36, 27), + (89, 39, 35), (112, 56, 39), (116, 69, 43), (118, 89, 51), + (124, 92, 37), (160, 122, 46), (171, 135, 56), (168, 156, 97), + (153, 159, 102), (144, 150, 88), (137, 115, 85), (118, 108, 89), + (108, 95, 75), (95, 87, 63), (95, 78, 55), (88, 65, 56), + (92, 57, 49), (94, 57, 48), (94, 53, 47), (98, 51, 43), + (105, 67, 50), (109, 74, 60), (116, 91, 81), (140, 119, 89), + (179, 161, 111), (235, 221, 170), (245, 246, 140), (237, 221, 102), + (227, 193, 91), (215, 181, 106), (197, 157, 88), (184, 153, 62), + (161, 124, 46), (149, 99, 41), (143, 84, 37), (130, 77, 42), + (117, 73, 48), (118, 67, 53), (124, 81, 60), (139, 107, 90), + (156, 161, 147), (192, 207, 161), (221, 235, 186), (216, 244, 206), + (178, 223, 200), (179, 187, 163), (154, 134, 116), (146, 106, 79), + (129, 105, 52), (114, 103, 49), (119, 122, 74), (135, 141, 112), + (147, 164, 149), (165, 213, 168), (199, 243, 222), (187, 251, 248), + (190, 248, 233), (169, 215, 199), (158, 176, 150), (136, 139, 120), + (119, 121, 104), (121, 120, 93), (146, 152, 109), (180, 159, 99), + (181, 191, 105), (181, 205, 157), (175, 231, 216), (168, 243, 243), + (138, 241, 247), (127, 247, 247), (138, 247, 240), (141, 188, 174), + (112, 136, 129), (91, 103, 81), (69, 86, 67), (69, 59, 41), + (62, 59, 21), (59, 36, 17), (61, 25, 14), (61, 24, 16), + (55, 25, 15), (44, 26, 23), (47, 31, 23), (54, 33, 22), + (60, 34, 30), (53, 42, 49), (51, 60, 66), (46, 72, 60), + (53, 84, 86), (54, 100, 125), (84, 149, 155), (92, 243, 249), + (108, 244, 249), (130, 219, 231), (125, 155, 166), (71, 105, 120), + (47, 89, 118), (26, 50, 68), (24, 25, 32), (13, 12, 21), + (12, 9, 8), (5, 4, 4), (5, 2, 2), (4, 0, 1), + (5, 1, 0), (12, 4, 2), (16, 7, 4), (21, 7, 1), + (22, 5, 2), (18, 5, 5), (16, 6, 6), (9, 5, 4), + (5, 2, 1), (1, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 0, 0), (3, 0, 1), (6, 0, 3), + (16, 5, 5), (23, 9, 4), (22, 15, 9), (18, 14, 14), + (20, 20, 26), (26, 26, 23), (43, 36, 29), (52, 42, 42), + (59, 67, 62), (75, 80, 80), (77, 116, 99), (97, 141, 153), + (121, 219, 225), (121, 246, 252), (136, 238, 245), (143, 176, 174), + (121, 125, 121), (107, 98, 94), (76, 93, 72), (77, 86, 51), + (83, 57, 49), (78, 51, 44), (70, 40, 41), (67, 31, 31), + (63, 28, 24), (62, 27, 20), (58, 29, 10), (55, 31, 12), + (49, 28, 13), (42, 23, 7), (37, 19, 7), (38, 17, 6), + (43, 13, 5), (47, 14, 5), (59, 15, 6), (61, 17, 6), + (63, 21, 5), (67, 23, 8), (69, 27, 6), (66, 28, 6), + (66, 30, 13), (70, 34, 18), (70, 40, 28), (78, 42, 35), + (88, 53, 39), (93, 69, 56), (113, 83, 83), (138, 119, 116), + (196, 181, 138), (222, 227, 216), (247, 245, 223), (250, 249, 228), + (247, 251, 242), (230, 247, 235), (199, 236, 231), (199, 236, 228), + (193, 231, 227), (165, 173, 178), (153, 134, 140), (128, 119, 110), + (112, 95, 87), (108, 78, 57), (99, 79, 48), (94, 71, 37), + (71, 52, 28), (65, 47, 26), (69, 31, 26), (61, 26, 22), + (56, 24, 19), (56, 21, 15), (55, 21, 13), (47, 16, 11), + (45, 11, 3), (41, 10, 4), (39, 10, 6), (37, 11, 5), + (33, 14, 3), (30, 9, 2), (30, 5, 0), (28, 9, 3), + (27, 11, 2), (27, 11, 3), (26, 14, 7), (24, 12, 5), + (22, 15, 5), (27, 12, 4), (31, 16, 6), (36, 17, 7), + (41, 21, 11), (48, 20, 12), (57, 18, 12), (61, 22, 11), + (65, 23, 13), (68, 23, 14), (68, 22, 9), (63, 19, 7), + (57, 17, 7), (46, 17, 7), (37, 18, 5), (34, 17, 6), + (30, 18, 14), (30, 26, 11), (25, 32, 17), (37, 31, 31) +), + +// 70 ernst.anti-pope.ppm +( + (60, 41, 44), (63, 44, 53), (61, 45, 54), (62, 43, 55), + (59, 42, 56), (61, 39, 55), (61, 43, 57), (65, 44, 53), + (67, 46, 53), (74, 44, 54), (76, 44, 57), (80, 48, 63), + (87, 49, 64), (89, 43, 57), (93, 46, 53), (96, 44, 53), + (106, 49, 53), (104, 56, 56), (108, 68, 64), (111, 72, 67), + (119, 70, 68), (129, 76, 71), (133, 79, 68), (133, 75, 74), + (139, 65, 65), (134, 69, 76), (143, 77, 76), (170, 77, 76), + (148, 92, 81), (136, 92, 73), (135, 90, 87), (149, 96, 75), + (174, 114, 73), (203, 130, 81), (202, 137, 86), (201, 164, 136), + (201, 164, 138), (176, 147, 135), (203, 131, 101), (167, 145, 117), + (186, 121, 108), (174, 107, 89), (146, 117, 90), (133, 112, 98), + (118, 112, 123), (100, 95, 100), (125, 102, 98), (113, 100, 93), + (102, 84, 81), (100, 74, 86), (99, 77, 97), (98, 63, 76), + (94, 53, 70), (86, 52, 65), (81, 49, 63), (75, 52, 61), + (71, 52, 64), (70, 49, 64), (70, 50, 62), (69, 52, 63), + (67, 50, 61), (64, 50, 63), (66, 51, 59), (63, 51, 62), + (63, 54, 61), (62, 50, 61), (62, 48, 61), (62, 48, 61), + (57, 45, 59), (57, 43, 56), (57, 46, 56), (55, 45, 56), + (53, 43, 56), (53, 43, 57), (54, 40, 53), (53, 41, 55), + (55, 43, 57), (57, 42, 59), (57, 47, 59), (59, 49, 60), + (53, 48, 68), (58, 50, 66), (51, 49, 70), (49, 49, 64), + (52, 51, 70), (54, 51, 69), (57, 53, 67), (61, 52, 73), + (65, 53, 75), (64, 52, 70), (62, 51, 67), (61, 50, 68), + (60, 48, 70), (58, 49, 70), (58, 49, 67), (60, 48, 62), + (61, 50, 64), (61, 50, 63), (62, 50, 62), (63, 48, 61), + (65, 47, 61), (67, 45, 59), (65, 46, 58), (64, 46, 58), + (63, 47, 58), (63, 45, 57), (59, 45, 58), (58, 44, 57), + (61, 43, 57), (61, 44, 57), (61, 43, 59), (62, 42, 60), + (64, 44, 60), (66, 45, 61), (67, 47, 62), (66, 48, 67), + (66, 50, 69), (72, 53, 68), (74, 56, 70), (78, 56, 71), + (73, 68, 75), (80, 55, 76), (85, 58, 78), (79, 60, 84), + (86, 65, 82), (96, 68, 76), (98, 72, 79), (108, 85, 78), + (123, 88, 70), (113, 83, 78), (122, 85, 81), (132, 104, 92), + (127, 111, 90), (136, 93, 101), (142, 83, 87), (137, 82, 75), + (121, 80, 77), (110, 67, 85), (102, 67, 77), (94, 66, 72), + (83, 68, 66), (80, 71, 76), (81, 73, 85), (87, 84, 89), + (85, 69, 84), (90, 84, 96), (82, 84, 88), (80, 90, 95), + (85, 84, 110), (93, 72, 86), (82, 72, 81), (77, 70, 82), + (74, 63, 77), (72, 56, 74), (71, 55, 68), (67, 51, 65), + (65, 51, 67), (64, 50, 65), (67, 50, 66), (72, 51, 68), + (74, 50, 66), (80, 53, 63), (86, 55, 68), (89, 63, 68), + (91, 66, 68), (97, 65, 65), (103, 66, 58), (99, 64, 64), + (102, 61, 71), (111, 58, 72), (104, 63, 63), (118, 53, 59), + (127, 52, 59), (141, 47, 52), (161, 39, 53), (164, 37, 51), + (143, 41, 51), (136, 46, 61), (118, 47, 50), (111, 47, 59), + (109, 45, 59), (106, 46, 61), (107, 42, 63), (109, 41, 58), + (106, 42, 53), (95, 44, 59), (88, 45, 57), (78, 43, 61), + (70, 47, 63), (67, 46, 61), (66, 45, 62), (64, 46, 62), + (62, 45, 60), (62, 46, 58), (60, 45, 58), (58, 45, 59), + (58, 47, 58), (62, 48, 62), (64, 50, 63), (66, 52, 65), + (69, 55, 68), (71, 63, 68), (68, 65, 76), (66, 66, 76), + (62, 61, 78), (62, 61, 79), (65, 55, 80), (66, 54, 76), + (65, 53, 77), (60, 52, 80), (57, 54, 73), (58, 58, 70), + (57, 59, 74), (62, 61, 80), (59, 67, 86), (63, 68, 86), + (63, 68, 88), (65, 70, 90), (67, 65, 93), (62, 70, 95), + (58, 68, 99), (62, 75, 92), (59, 77, 97), (61, 76, 109), + (61, 77, 100), (54, 70, 105), (56, 70, 105), (53, 67, 102), + (52, 65, 99), (55, 65, 102), (54, 68, 103), (61, 73, 92), + (64, 68, 94), (68, 76, 95), (74, 79, 89), (70, 77, 83), + (66, 72, 87), (68, 62, 92), (70, 56, 77), (72, 55, 76), + (68, 56, 75), (72, 53, 72), (74, 54, 66), (75, 56, 64), + (77, 53, 61), (81, 50, 58), (87, 54, 52), (96, 51, 58), + (92, 44, 61), (85, 45, 62), (75, 45, 58), (71, 41, 54), + (70, 41, 56), (70, 41, 56), (69, 41, 55), (66, 41, 53) +), + +// 71 ernst.ubu-imperator.ppm +( + (36, 57, 12), (87, 102, 130), (126, 148, 170), (137, 166, 178), + (146, 174, 185), (160, 179, 186), (163, 183, 190), (161, 180, 186), + (154, 172, 181), (147, 165, 174), (138, 144, 155), (144, 103, 23), + (127, 77, 3), (93, 20, 6), (78, 10, 6), (65, 4, 2), + (53, 0, 8), (30, 4, 0), (9, 3, 2), (1, 1, 0), + (0, 0, 1), (3, 1, 3), (5, 0, 9), (21, 15, 4), + (32, 17, 0), (39, 3, 2), (48, 5, 0), (54, 4, 0), + (56, 3, 3), (65, 3, 0), (66, 2, 2), (70, 3, 3), + (76, 7, 1), (80, 4, 1), (79, 3, 0), (80, 4, 0), + (81, 9, 0), (81, 15, 0), (87, 26, 1), (103, 68, 8), + (108, 151, 11), (93, 159, 31), (123, 149, 161), (139, 163, 175), + (149, 171, 181), (158, 176, 184), (162, 177, 186), (166, 178, 187), + (164, 175, 185), (161, 173, 181), (162, 170, 173), (172, 123, 74), + (178, 113, 3), (187, 117, 1), (190, 122, 0), (184, 122, 2), + (165, 123, 8), (108, 143, 36), (117, 147, 164), (129, 161, 176), + (129, 166, 182), (103, 148, 174), (92, 105, 135), (72, 69, 15), + (76, 24, 3), (72, 17, 3), (73, 16, 1), (75, 15, 2), + (77, 14, 3), (78, 11, 4), (78, 9, 3), (77, 9, 1), + (74, 9, 1), (72, 10, 2), (71, 10, 4), (66, 9, 4), + (66, 6, 1), (64, 6, 2), (66, 10, 1), (68, 12, 2), + (69, 8, 1), (68, 6, 1), (69, 6, 0), (71, 7, 0), + (71, 8, 1), (73, 10, 2), (75, 12, 1), (75, 14, 1), + (81, 13, 2), (84, 15, 1), (90, 17, 2), (99, 23, 2), + (139, 79, 0), (151, 87, 6), (134, 63, 9), (102, 21, 4), + (93, 15, 5), (92, 12, 6), (101, 10, 2), (125, 27, 3), + (163, 66, 2), (179, 76, 2), (190, 94, 5), (206, 116, 4), + (211, 121, 1), (213, 130, 2), (214, 136, 1), (209, 137, 1), + (198, 131, 2), (181, 112, 1), (167, 100, 0), (150, 90, 1), + (126, 87, 7), (58, 84, 7), (34, 64, 2), (62, 90, 10), + (131, 87, 4), (157, 83, 1), (166, 87, 2), (168, 88, 2), + (169, 88, 1), (175, 87, 1), (180, 90, 4), (177, 98, 4), + (181, 102, 1), (177, 105, 1), (179, 109, 3), (188, 112, 1), + (195, 107, 1), (197, 109, 0), (200, 116, 2), (192, 121, 4), + (191, 121, 2), (179, 113, 3), (173, 105, 2), (158, 106, 9), + (107, 121, 142), (114, 139, 162), (109, 136, 162), (88, 101, 138), + (92, 44, 33), (86, 16, 5), (84, 10, 2), (82, 9, 3), + (84, 7, 1), (89, 11, 0), (91, 14, 1), (99, 17, 1), + (110, 20, 0), (151, 57, 4), (165, 68, 2), (170, 70, 6), + (170, 69, 2), (168, 73, 2), (171, 78, 0), (173, 88, 0), + (175, 95, 2), (182, 105, 0), (189, 114, 0), (197, 123, 2), + (206, 127, 2), (209, 130, 2), (212, 129, 3), (208, 124, 1), + (206, 122, 1), (198, 124, 4), (191, 119, 2), (186, 104, 5), + (177, 89, 8), (169, 74, 5), (164, 73, 2), (157, 57, 1), + (124, 25, 6), (102, 16, 2), (95, 16, 3), (91, 14, 2), + (87, 16, 2), (88, 15, 4), (95, 22, 2), (131, 52, 2), + (159, 67, 1), (162, 76, 0), (162, 80, 2), (168, 88, 6), + (173, 96, 6), (175, 96, 3), (172, 97, 2), (173, 98, 3), + (174, 102, 2), (167, 102, 4), (162, 113, 19), (145, 151, 153), + (162, 171, 176), (163, 172, 179), (169, 178, 183), (168, 177, 186), + (168, 184, 193), (169, 185, 190), (176, 186, 188), (182, 191, 183), + (180, 189, 188), (173, 190, 196), (177, 191, 200), (169, 191, 198), + (159, 190, 201), (148, 176, 187), (138, 166, 178), (133, 158, 172), + (109, 126, 146), (74, 88, 37), (58, 27, 5), (71, 19, 2), + (78, 19, 3), (81, 15, 5), (92, 33, 34), (87, 99, 124), + (102, 126, 155), (94, 105, 113), (130, 95, 4), (146, 99, 3), + (152, 96, 1), (159, 92, 2), (166, 103, 2), (177, 113, 0), + (175, 117, 2), (171, 121, 16), (152, 133, 70), (146, 163, 173), + (150, 168, 177), (154, 172, 181), (153, 176, 184), (151, 173, 186), + (154, 171, 185), (149, 169, 184), (145, 169, 177), (138, 154, 157), + (172, 124, 23), (195, 124, 6), (197, 126, 7), (200, 127, 7), + (212, 130, 11), (175, 176, 172), (175, 183, 184), (173, 182, 181), + (160, 170, 179), (139, 161, 174), (125, 138, 160), (91, 98, 105), + (43, 58, 6), (29, 18, 5), (15, 12, 4), (3, 6, 4), + (1, 3, 4), (4, 3, 2), (11, 11, 1), (26, 25, 3) +), + +// 72 fighting-forms.ppm +( + (2, 3, 0), (11, 15, 2), (22, 23, 8), (40, 36, 23), + (82, 53, 40), (133, 63, 36), (149, 96, 18), (169, 100, 12), + (182, 122, 14), (214, 140, 47), (235, 178, 73), (230, 176, 63), + (220, 159, 44), (174, 151, 29), (141, 139, 43), (129, 99, 40), + (56, 61, 33), (35, 36, 18), (25, 24, 6), (17, 18, 3), + (18, 17, 0), (24, 19, 0), (27, 25, 3), (35, 29, 12), + (100, 42, 16), (140, 45, 14), (144, 52, 14), (120, 55, 39), + (75, 59, 56), (51, 40, 38), (34, 28, 15), (24, 19, 5), + (13, 13, 3), (12, 13, 1), (7, 8, 3), (11, 13, 2), + (9, 11, 0), (12, 11, 2), (13, 15, 2), (22, 23, 7), + (30, 31, 12), (40, 40, 28), (52, 63, 69), (63, 96, 65), + (66, 103, 73), (100, 114, 124), (105, 155, 133), (138, 146, 105), + (152, 125, 65), (159, 122, 55), (158, 94, 30), (156, 60, 7), + (149, 46, 14), (135, 43, 40), (124, 57, 81), (97, 58, 132), + (80, 70, 149), (66, 83, 139), (85, 94, 140), (97, 116, 153), + (96, 119, 151), (96, 102, 126), (97, 87, 79), (137, 77, 67), + (164, 55, 24), (174, 60, 16), (175, 42, 4), (175, 37, 7), + (164, 40, 12), (142, 47, 14), (111, 47, 30), (65, 46, 47), + (37, 34, 22), (32, 34, 12), (31, 32, 16), (43, 33, 25), + (88, 42, 37), (140, 30, 9), (164, 24, 1), (169, 28, 2), + (174, 34, 2), (168, 38, 1), (160, 41, 4), (131, 44, 7), + (71, 53, 21), (34, 30, 10), (27, 22, 5), (18, 15, 1), + (13, 16, 1), (18, 19, 3), (30, 27, 11), (37, 33, 32), + (46, 32, 70), (59, 38, 117), (66, 58, 127), (67, 60, 133), + (63, 63, 123), (53, 51, 71), (56, 50, 67), (55, 47, 64), + (45, 46, 37), (45, 40, 29), (48, 43, 39), (61, 50, 62), + (75, 90, 70), (81, 95, 120), (89, 100, 136), (99, 97, 124), + (130, 93, 79), (158, 58, 28), (174, 63, 9), (184, 51, 4), + (186, 46, 8), (190, 37, 18), (187, 40, 21), (180, 48, 10), + (174, 50, 3), (166, 69, 2), (181, 83, 21), (205, 97, 2), + (203, 115, 5), (212, 138, 3), (218, 141, 4), (237, 144, 0), + (233, 139, 5), (225, 115, 4), (207, 98, 4), (204, 58, 27), + (199, 52, 18), (199, 49, 16), (193, 39, 9), (194, 35, 6), + (189, 36, 5), (186, 35, 2), (186, 33, 6), (182, 37, 5), + (185, 39, 2), (186, 31, 2), (185, 30, 3), (186, 31, 3), + (187, 30, 3), (186, 30, 2), (183, 32, 2), (179, 27, 3), + (180, 31, 3), (184, 31, 5), (184, 29, 6), (181, 30, 3), + (181, 28, 0), (181, 30, 2), (179, 29, 2), (174, 29, 0), + (176, 33, 3), (178, 30, 3), (175, 25, 1), (174, 24, 1), + (173, 25, 0), (166, 24, 1), (153, 26, 7), (116, 30, 5), + (43, 25, 4), (28, 18, 2), (26, 15, 1), (27, 15, 1), + (32, 23, 8), (43, 28, 14), (111, 34, 2), (144, 39, 4), + (160, 30, 2), (163, 35, 4), (155, 41, 12), (129, 53, 66), + (132, 71, 99), (99, 109, 132), (95, 141, 145), (107, 135, 143), + (101, 125, 156), (100, 117, 143), (87, 111, 128), (66, 114, 73), + (72, 108, 48), (97, 111, 29), (108, 120, 58), (138, 150, 119), + (183, 165, 155), (195, 175, 164), (163, 166, 182), (125, 170, 197), + (131, 154, 188), (120, 117, 172), (86, 106, 175), (68, 81, 143), + (67, 61, 123), (85, 56, 66), (112, 37, 48), (154, 39, 15), + (180, 48, 24), (187, 60, 69), (188, 118, 123), (193, 146, 160), + (206, 170, 188), (162, 157, 190), (144, 136, 147), (139, 102, 158), + (173, 54, 109), (167, 45, 49), (177, 43, 13), (170, 41, 14), + (153, 40, 9), (126, 36, 5), (55, 29, 11), (29, 17, 2), + (21, 11, 1), (18, 10, 0), (25, 16, 1), (28, 19, 8), + (36, 28, 10), (91, 44, 9), (143, 38, 7), (146, 47, 6), + (142, 52, 5), (130, 73, 10), (78, 62, 22), (40, 37, 23), + (44, 26, 16), (90, 27, 4), (136, 30, 7), (158, 30, 2), + (169, 33, 1), (175, 32, 7), (166, 37, 17), (149, 51, 36), + (129, 48, 74), (99, 54, 126), (76, 51, 129), (73, 58, 137), + (84, 74, 148), (102, 79, 152), (119, 80, 142), (174, 57, 99), + (178, 50, 50), (175, 49, 49), (186, 58, 48), (186, 57, 99), + (176, 59, 115), (124, 107, 116), (116, 143, 147), (128, 161, 139), + (190, 169, 127), (235, 175, 114), (233, 175, 81), (148, 146, 56), + (151, 99, 30), (120, 86, 12), (120, 78, 22), (56, 50, 9) +), + +// 73 fog25.ppm +( + (11, 14, 2), (30, 28, 10), (35, 35, 14), (52, 43, 23), + (52, 61, 22), (61, 63, 29), (67, 62, 30), (83, 70, 39), + (113, 96, 63), (149, 134, 131), (163, 157, 162), (175, 169, 173), + (178, 172, 176), (173, 165, 170), (160, 149, 152), (162, 119, 78), + (159, 108, 65), (135, 95, 47), (112, 83, 32), (88, 81, 23), + (75, 72, 18), (72, 59, 18), (73, 63, 24), (70, 48, 22), + (72, 57, 30), (66, 52, 20), (64, 60, 21), (66, 71, 23), + (72, 62, 27), (66, 73, 21), (75, 66, 26), (80, 64, 23), + (103, 73, 33), (130, 88, 40), (163, 99, 47), (172, 100, 47), + (174, 106, 51), (185, 120, 60), (194, 128, 73), (206, 141, 84), + (201, 145, 94), (179, 165, 164), (191, 180, 184), (205, 196, 192), + (214, 212, 217), (231, 230, 236), (238, 242, 245), (239, 242, 247), + (233, 236, 241), (227, 226, 231), (213, 208, 214), (197, 192, 198), + (178, 172, 177), (150, 144, 146), (130, 103, 68), (86, 76, 53), + (74, 61, 44), (68, 58, 40), (61, 53, 28), (58, 51, 19), + (60, 53, 11), (62, 45, 5), (45, 43, 6), (34, 39, 4), + (31, 41, 3), (36, 36, 9), (32, 35, 9), (30, 36, 6), + (17, 16, 10), (21, 18, 2), (31, 13, 5), (28, 20, 7), + (28, 24, 4), (33, 24, 6), (35, 41, 17), (45, 42, 12), + (51, 36, 17), (53, 37, 22), (62, 38, 16), (78, 39, 12), + (81, 46, 17), (83, 52, 12), (89, 65, 13), (103, 76, 18), + (119, 80, 26), (137, 85, 29), (160, 92, 41), (162, 103, 54), + (171, 109, 59), (184, 120, 59), (196, 124, 60), (194, 131, 73), + (199, 146, 97), (181, 170, 172), (196, 186, 191), (203, 198, 202), + (215, 216, 218), (230, 229, 235), (231, 231, 239), (231, 230, 238), + (225, 225, 229), (211, 208, 207), (195, 189, 193), (173, 168, 171), + (145, 140, 142), (117, 103, 54), (98, 77, 33), (86, 61, 34), + (78, 63, 30), (76, 63, 31), (75, 64, 34), (70, 58, 42), + (76, 55, 36), (72, 58, 30), (67, 57, 17), (63, 55, 9), + (53, 62, 2), (50, 42, 4), (47, 40, 7), (46, 40, 6), + (51, 39, 8), (52, 39, 10), (55, 41, 12), (58, 45, 19), + (57, 48, 20), (63, 47, 18), (70, 48, 15), (71, 48, 16), + (87, 53, 19), (100, 72, 29), (110, 90, 39), (134, 119, 63), + (148, 138, 137), (167, 164, 163), (182, 177, 177), (186, 179, 187), + (184, 177, 185), (178, 171, 178), (168, 155, 158), (187, 143, 107), + (192, 130, 79), (179, 119, 63), (165, 111, 56), (159, 109, 55), + (160, 111, 61), (160, 114, 72), (153, 141, 142), (167, 159, 164), + (172, 167, 171), (171, 166, 170), (157, 151, 153), (151, 135, 129), + (143, 105, 64), (124, 86, 40), (112, 73, 31), (88, 62, 31), + (91, 64, 24), (90, 64, 19), (89, 63, 18), (92, 69, 20), + (102, 78, 19), (112, 78, 29), (123, 83, 37), (142, 97, 52), + (143, 118, 69), (155, 146, 149), (178, 172, 174), (194, 190, 190), + (203, 199, 202), (217, 216, 222), (232, 235, 239), (241, 245, 248), + (245, 249, 252), (247, 251, 254), (249, 253, 255), (251, 253, 255), + (253, 254, 255), (253, 254, 255), (253, 254, 255), (251, 255, 255), + (249, 254, 255), (249, 253, 254), (249, 253, 254), (247, 253, 255), + (245, 250, 253), (244, 249, 253), (244, 249, 252), (240, 245, 248), + (231, 232, 237), (219, 216, 218), (203, 196, 202), (189, 183, 187), + (169, 160, 164), (180, 133, 98), (169, 113, 66), (163, 109, 56), + (167, 105, 58), (167, 114, 65), (162, 115, 75), (155, 144, 148), + (173, 164, 171), (184, 177, 185), (187, 182, 189), (188, 182, 187), + (179, 173, 174), (166, 156, 155), (198, 138, 89), (181, 123, 67), + (163, 104, 55), (152, 95, 50), (133, 91, 37), (124, 81, 28), + (117, 81, 28), (108, 77, 27), (111, 79, 32), (118, 83, 39), + (133, 92, 51), (146, 97, 56), (153, 103, 61), (152, 104, 57), + (148, 104, 57), (142, 101, 48), (134, 95, 43), (123, 84, 31), + (109, 70, 28), (99, 66, 22), (95, 64, 28), (97, 65, 36), + (102, 78, 52), (120, 88, 58), (143, 110, 81), (152, 144, 147), + (174, 165, 170), (193, 182, 188), (205, 195, 203), (220, 217, 224), + (232, 235, 242), (243, 246, 251), (245, 250, 253), (248, 253, 254), + (249, 253, 254), (253, 255, 254), (255, 255, 255), (255, 255, 255), + (254, 255, 255), (253, 254, 255), (253, 254, 255), (250, 251, 253), + (244, 248, 250), (234, 236, 243), (222, 219, 229), (207, 197, 205), + (188, 181, 189), (170, 160, 167), (142, 133, 134), (76, 67, 44) +), + +// 74 geyser27.ppm +( + (0, 0, 0), (26, 5, 5), (77, 17, 6), (98, 45, 29), + (124, 78, 66), (114, 129, 146), (115, 168, 193), (132, 179, 210), + (152, 186, 220), (153, 176, 202), (142, 171, 181), (157, 169, 176), + (165, 162, 158), (154, 131, 103), (149, 104, 73), (152, 98, 60), + (140, 85, 46), (138, 67, 23), (163, 57, 6), (173, 55, 8), + (179, 56, 3), (190, 61, 8), (208, 86, 7), (210, 110, 25), + (221, 127, 29), (222, 150, 44), (226, 161, 53), (222, 159, 52), + (222, 152, 60), (213, 148, 66), (193, 134, 70), (164, 146, 113), + (138, 141, 159), (133, 144, 165), (154, 139, 122), (148, 108, 84), + (158, 115, 69), (189, 121, 57), (198, 124, 48), (212, 136, 45), + (224, 146, 39), (223, 143, 35), (222, 137, 31), (222, 136, 24), + (221, 137, 18), (205, 101, 19), (198, 76, 4), (176, 60, 14), + (148, 86, 43), (154, 110, 61), (141, 115, 89), (125, 168, 156), + (126, 173, 199), (109, 156, 212), (105, 144, 195), (96, 120, 161), + (71, 74, 121), (37, 58, 125), (26, 49, 119), (16, 42, 117), + (17, 41, 115), (18, 38, 106), (35, 42, 95), (53, 36, 45), + (59, 35, 35), (84, 25, 14), (98, 35, 15), (116, 48, 18), + (121, 56, 23), (135, 72, 28), (142, 82, 36), (163, 103, 51), + (178, 108, 56), (196, 123, 61), (214, 145, 68), (202, 165, 99), + (182, 166, 149), (177, 174, 165), (175, 176, 165), (157, 168, 171), + (135, 153, 167), (120, 125, 129), (126, 87, 69), (125, 82, 64), + (126, 81, 63), (127, 75, 46), (137, 83, 37), (142, 82, 36), + (142, 80, 35), (134, 70, 20), (116, 51, 9), (107, 38, 11), + (97, 29, 7), (86, 25, 13), (87, 26, 8), (93, 28, 8), + (103, 31, 6), (110, 40, 6), (111, 43, 7), (141, 28, 8), + (143, 31, 7), (145, 34, 10), (148, 36, 6), (145, 39, 3), + (128, 54, 22), (115, 51, 25), (99, 50, 25), (99, 47, 28), + (102, 44, 27), (95, 42, 26), (53, 35, 43), (23, 38, 100), + (14, 34, 103), (18, 28, 89), (4, 0, 2), (1, 0, 0), + (24, 3, 2), (75, 15, 6), (85, 15, 2), (98, 23, 4), + (101, 24, 2), (105, 32, 2), (106, 34, 2), (104, 37, 12), + (100, 33, 14), (91, 30, 11), (88, 29, 11), (93, 38, 18), + (96, 39, 24), (98, 47, 30), (69, 63, 76), (36, 54, 121), + (49, 63, 118), (100, 68, 69), (114, 71, 55), (131, 86, 57), + (159, 109, 61), (186, 112, 45), (200, 123, 46), (217, 143, 50), + (221, 149, 55), (221, 147, 50), (211, 139, 54), (188, 119, 49), + (175, 103, 38), (152, 85, 32), (165, 61, 23), (160, 43, 7), + (163, 41, 6), (153, 31, 3), (156, 35, 7), (162, 41, 7), + (164, 43, 5), (170, 53, 9), (182, 67, 12), (195, 110, 40), + (213, 134, 48), (224, 152, 58), (223, 161, 67), (222, 154, 64), + (195, 134, 61), (181, 119, 60), (156, 111, 61), (145, 104, 74), + (126, 81, 65), (91, 91, 112), (114, 123, 157), (118, 163, 183), + (127, 182, 196), (128, 186, 211), (132, 187, 192), (154, 193, 164), + (167, 204, 164), (170, 202, 163), (180, 203, 188), (163, 198, 225), + (139, 193, 222), (136, 192, 219), (119, 177, 225), (115, 173, 225), + (112, 166, 225), (109, 154, 202), (113, 118, 144), (119, 77, 72), + (112, 67, 52), (102, 53, 32), (102, 53, 33), (111, 67, 54), + (90, 85, 91), (44, 63, 127), (32, 52, 121), (26, 46, 119), + (18, 38, 109), (16, 31, 95), (2, 4, 21), (0, 0, 0), + (0, 0, 0), (6, 1, 0), (33, 11, 21), (46, 37, 52), + (55, 66, 120), (98, 107, 144), (133, 149, 176), (137, 158, 190), + (121, 132, 164), (76, 86, 128), (40, 58, 125), (30, 50, 118), + (27, 47, 121), (39, 50, 109), (107, 61, 46), (104, 57, 36), + (110, 60, 40), (130, 82, 55), (153, 108, 60), (155, 114, 66), + (186, 132, 68), (216, 177, 98), (221, 182, 114), (220, 213, 126), + (223, 205, 147), (194, 197, 178), (174, 198, 177), (183, 184, 159), + (192, 145, 102), (178, 111, 64), (170, 81, 28), (173, 58, 7), + (173, 52, 7), (173, 50, 5), (167, 48, 2), (160, 47, 3), + (158, 48, 2), (163, 51, 6), (174, 58, 8), (189, 97, 22), + (209, 124, 41), (219, 144, 52), (219, 148, 62), (200, 138, 62), + (187, 134, 72), (171, 156, 133), (167, 172, 160), (138, 150, 173), + (126, 139, 157), (142, 106, 81), (117, 71, 55), (108, 50, 28), + (98, 42, 18), (89, 28, 10), (81, 23, 6), (78, 14, 2), + (78, 14, 1), (75, 7, 1), (9, 0, 1), (0, 0, 0) +), + +// 75 gris.josette.ppm +( + (36, 41, 40), (71, 77, 82), (90, 114, 119), (120, 152, 164), + (158, 192, 200), (171, 198, 207), (176, 199, 207), (178, 198, 207), + (176, 199, 208), (179, 200, 207), (181, 202, 207), (184, 204, 213), + (186, 209, 219), (184, 209, 220), (183, 211, 217), (181, 207, 209), + (179, 205, 210), (187, 207, 213), (188, 211, 216), (188, 211, 217), + (188, 211, 217), (190, 209, 221), (194, 213, 219), (250, 249, 229), + (255, 250, 227), (255, 247, 228), (227, 228, 218), (193, 205, 212), + (188, 204, 204), (180, 195, 198), (162, 178, 167), (117, 146, 147), + (90, 124, 134), (81, 117, 123), (76, 105, 109), (71, 102, 97), + (63, 89, 80), (40, 59, 60), (33, 47, 50), (29, 43, 46), + (26, 36, 38), (18, 27, 26), (14, 23, 22), (19, 28, 27), + (30, 36, 35), (29, 36, 39), (32, 41, 46), (32, 46, 49), + (42, 48, 47), (42, 53, 46), (73, 82, 57), (72, 84, 72), + (73, 91, 84), (76, 95, 96), (79, 98, 94), (82, 102, 99), + (84, 104, 100), (93, 106, 100), (90, 111, 114), (88, 115, 124), + (94, 122, 133), (139, 153, 152), (175, 190, 183), (177, 193, 190), + (157, 174, 157), (94, 123, 129), (82, 108, 109), (66, 93, 89), + (37, 52, 58), (26, 38, 39), (11, 18, 22), (8, 11, 18), + (7, 9, 16), (9, 14, 18), (13, 20, 23), (26, 36, 38), + (36, 50, 55), (61, 80, 82), (70, 96, 93), (76, 100, 101), + (76, 103, 111), (79, 110, 113), (82, 110, 120), (85, 112, 125), + (86, 115, 129), (87, 118, 133), (90, 124, 143), (139, 166, 175), + (171, 187, 203), (180, 195, 202), (183, 198, 201), (180, 198, 199), + (174, 194, 195), (157, 160, 165), (97, 119, 125), (86, 106, 106), + (69, 83, 82), (37, 52, 53), (28, 39, 36), (16, 25, 24), + (10, 18, 21), (10, 16, 22), (12, 20, 23), (25, 39, 42), + (40, 59, 65), (69, 97, 94), (90, 117, 122), (125, 150, 154), + (173, 193, 185), (185, 200, 195), (184, 200, 200), (174, 196, 201), + (145, 179, 183), (91, 133, 141), (86, 120, 132), (86, 116, 127), + (86, 116, 127), (90, 116, 127), (99, 128, 135), (160, 176, 163), + (193, 195, 186), (190, 205, 197), (208, 214, 203), (255, 250, 223), + (254, 252, 232), (253, 252, 234), (253, 250, 231), (246, 245, 225), + (191, 210, 215), (186, 204, 213), (182, 203, 208), (178, 201, 209), + (174, 201, 209), (165, 197, 207), (142, 175, 185), (87, 123, 144), + (85, 119, 138), (87, 120, 141), (108, 137, 143), (145, 181, 181), + (175, 196, 201), (184, 197, 205), (189, 207, 207), (192, 206, 207), + (192, 209, 208), (214, 225, 211), (249, 253, 231), (253, 253, 243), + (253, 253, 244), (253, 252, 243), (247, 249, 225), (192, 209, 203), + (163, 178, 172), (118, 136, 143), (90, 119, 126), (85, 113, 120), + (84, 112, 115), (86, 110, 111), (88, 112, 116), (88, 117, 123), + (92, 122, 132), (118, 148, 148), (161, 181, 176), (176, 195, 200), + (178, 197, 204), (178, 198, 205), (172, 200, 204), (169, 192, 200), + (125, 156, 166), (91, 123, 135), (77, 112, 116), (68, 97, 97), + (53, 71, 81), (32, 49, 59), (30, 46, 57), (40, 60, 67), + (65, 88, 80), (72, 92, 91), (74, 95, 98), (75, 100, 97), + (77, 102, 99), (79, 104, 101), (78, 103, 100), (78, 101, 95), + (78, 101, 95), (78, 102, 95), (80, 103, 98), (81, 102, 101), + (81, 101, 102), (82, 102, 103), (80, 104, 105), (76, 106, 107), + (77, 106, 108), (79, 109, 108), (80, 110, 112), (79, 111, 114), + (81, 111, 114), (82, 113, 115), (85, 115, 116), (85, 114, 118), + (85, 113, 123), (85, 115, 127), (84, 116, 124), (83, 117, 127), + (86, 119, 125), (97, 126, 133), (149, 174, 171), (173, 194, 197), + (177, 197, 199), (179, 200, 200), (173, 193, 201), (144, 173, 179), + (91, 124, 141), (84, 118, 130), (76, 112, 121), (66, 106, 112), + (71, 104, 106), (73, 104, 103), (72, 101, 97), (68, 91, 83), + (46, 61, 68), (39, 50, 52), (36, 46, 39), (34, 38, 28), + (13, 19, 19), (9, 18, 17), (9, 20, 23), (24, 34, 37), + (34, 43, 42), (42, 52, 54), (70, 81, 71), (73, 88, 81), + (74, 96, 87), (72, 95, 86), (70, 90, 82), (70, 84, 79), + (44, 62, 67), (29, 48, 54), (30, 48, 52), (32, 51, 58), + (48, 63, 70), (69, 91, 89), (86, 108, 111), (95, 124, 130), + (181, 190, 150), (224, 207, 189), (250, 246, 219), (255, 251, 224), + (252, 250, 229), (238, 243, 231), (189, 212, 214), (181, 203, 201), + (174, 193, 194), (129, 156, 154), (92, 121, 120), (69, 90, 80) +), + +// 76 gris.landscape-ceret.ppm +( + (16, 15, 9), (38, 38, 25), (74, 64, 42), (102, 59, 39), + (124, 79, 40), (136, 91, 44), (160, 94, 56), (173, 80, 72), + (182, 80, 70), (210, 77, 71), (209, 82, 67), (202, 48, 38), + (227, 88, 54), (211, 102, 54), (226, 127, 50), (234, 143, 56), + (238, 156, 65), (228, 167, 71), (189, 166, 79), (133, 176, 107), + (119, 153, 122), (111, 145, 124), (96, 138, 126), (103, 124, 100), + (99, 100, 94), (78, 96, 107), (69, 100, 132), (64, 121, 173), + (98, 165, 196), (107, 165, 182), (122, 172, 179), (171, 201, 211), + (189, 209, 209), (201, 210, 207), (210, 219, 205), (196, 208, 204), + (163, 189, 199), (132, 166, 174), (118, 138, 153), (134, 115, 126), + (168, 130, 107), (180, 120, 108), (181, 101, 112), (209, 90, 97), + (215, 92, 95), (220, 95, 96), (217, 98, 100), (226, 98, 95), + (228, 105, 92), (232, 105, 88), (229, 97, 83), (224, 83, 73), + (227, 88, 85), (219, 100, 76), (227, 105, 83), (229, 106, 90), + (224, 107, 98), (226, 116, 103), (226, 121, 114), (215, 152, 155), + (218, 168, 168), (217, 172, 167), (222, 177, 172), (239, 183, 170), + (239, 185, 167), (226, 202, 144), (252, 231, 99), (252, 223, 89), + (248, 218, 82), (249, 200, 79), (228, 191, 83), (180, 160, 91), + (136, 184, 126), (112, 162, 130), (113, 156, 132), (111, 156, 135), + (124, 161, 154), (128, 163, 167), (126, 154, 174), (120, 141, 162), + (98, 123, 138), (101, 123, 131), (100, 132, 109), (100, 120, 96), + (96, 110, 85), (88, 94, 70), (112, 87, 42), (120, 85, 44), + (128, 86, 56), (139, 86, 54), (159, 115, 62), (177, 122, 52), + (198, 127, 62), (221, 146, 50), (221, 160, 47), (214, 166, 37), + (234, 179, 32), (248, 194, 35), (253, 197, 34), (252, 198, 35), + (249, 196, 31), (249, 195, 43), (249, 165, 48), (242, 150, 38), + (241, 151, 32), (242, 149, 36), (241, 150, 35), (237, 142, 33), + (225, 139, 28), (229, 140, 32), (230, 133, 43), (220, 126, 44), + (223, 122, 32), (221, 127, 29), (214, 135, 33), (207, 133, 39), + (210, 144, 43), (206, 140, 60), (193, 141, 67), (164, 143, 82), + (129, 131, 69), (109, 115, 58), (90, 116, 69), (85, 107, 68), + (76, 79, 81), (89, 93, 72), (78, 85, 68), (66, 71, 62), + (56, 62, 58), (48, 51, 51), (36, 35, 24), (25, 15, 16), + (10, 13, 9), (8, 7, 5), (4, 2, 3), (14, 13, 11), + (16, 14, 15), (19, 18, 15), (20, 18, 19), (28, 35, 24), + (33, 34, 32), (29, 38, 31), (45, 56, 40), (52, 57, 47), + (58, 54, 43), (57, 59, 46), (60, 53, 49), (62, 60, 58), + (69, 68, 63), (70, 80, 60), (83, 81, 70), (97, 87, 81), + (112, 94, 86), (116, 104, 83), (129, 111, 73), (130, 124, 55), + (125, 120, 57), (134, 112, 46), (163, 121, 48), (198, 142, 59), + (205, 153, 76), (218, 163, 137), (212, 164, 160), (208, 155, 162), + (199, 126, 129), (194, 113, 123), (189, 121, 124), (202, 126, 104), + (196, 116, 69), (198, 112, 35), (199, 108, 31), (207, 127, 39), + (211, 131, 40), (228, 140, 40), (244, 160, 44), (248, 194, 44), + (253, 199, 40), (253, 200, 35), (253, 201, 37), (254, 204, 41), + (251, 205, 41), (252, 206, 42), (254, 211, 39), (254, 206, 44), + (253, 202, 44), (249, 204, 53), (246, 196, 59), (241, 192, 54), + (236, 172, 64), (195, 164, 84), (132, 187, 124), (127, 189, 119), + (115, 171, 106), (111, 161, 95), (103, 126, 95), (97, 115, 89), + (94, 112, 86), (90, 108, 78), (106, 107, 67), (115, 94, 66), + (104, 87, 59), (100, 75, 56), (92, 69, 49), (85, 77, 61), + (93, 85, 62), (98, 89, 50), (96, 71, 46), (93, 74, 46), + (87, 73, 43), (79, 82, 63), (69, 89, 69), (69, 95, 62), + (52, 86, 60), (60, 84, 63), (64, 86, 47), (65, 71, 57), + (69, 70, 50), (76, 69, 49), (74, 80, 52), (72, 95, 61), + (78, 105, 71), (95, 123, 75), (108, 138, 71), (119, 138, 81), + (152, 142, 139), (201, 151, 162), (215, 173, 175), (218, 200, 175), + (227, 228, 211), (254, 251, 249), (252, 252, 250), (250, 252, 252), + (228, 234, 230), (219, 220, 216), (237, 189, 172), (253, 228, 97), + (251, 218, 72), (254, 213, 63), (251, 211, 67), (249, 214, 62), + (251, 212, 56), (252, 213, 52), (253, 210, 46), (254, 201, 44), + (246, 191, 47), (244, 164, 74), (222, 170, 100), (231, 157, 139), + (214, 165, 166), (213, 156, 162), (198, 135, 148), (178, 118, 131), + (161, 106, 115), (123, 76, 72), (75, 68, 56), (42, 42, 38) +), + +// 77 kandinsky.comp-9.ppm +( + (81, 31, 21), (121, 26, 10), (159, 21, 3), (194, 57, 2), + (216, 102, 0), (215, 111, 0), (215, 122, 1), (220, 132, 2), + (227, 148, 3), (233, 167, 22), (251, 191, 41), (252, 194, 60), + (253, 200, 72), (225, 192, 103), (216, 204, 135), (224, 205, 153), + (232, 201, 156), (251, 210, 92), (254, 207, 68), (254, 191, 42), + (248, 182, 7), (231, 146, 2), (225, 127, 2), (221, 107, 0), + (197, 62, 6), (169, 26, 4), (157, 35, 12), (154, 76, 92), + (162, 80, 100), (173, 137, 99), (141, 186, 121), (146, 183, 127), + (179, 183, 142), (192, 170, 137), (240, 177, 82), (254, 198, 69), + (254, 207, 68), (254, 203, 65), (252, 194, 62), (251, 190, 56), + (249, 181, 57), (243, 169, 37), (221, 129, 5), (210, 110, 0), + (195, 60, 4), (167, 19, 1), (129, 20, 3), (96, 28, 20), + (84, 30, 23), (88, 33, 27), (97, 29, 42), (84, 35, 46), + (92, 136, 115), (90, 161, 127), (125, 186, 117), (143, 187, 118), + (203, 172, 77), (200, 138, 40), (196, 115, 9), (170, 51, 13), + (123, 29, 7), (106, 35, 13), (92, 32, 18), (92, 29, 17), + (119, 28, 5), (125, 30, 7), (182, 57, 14), (210, 109, 3), + (218, 123, 10), (237, 165, 27), (235, 187, 61), (215, 194, 103), + (173, 197, 132), (146, 197, 126), (138, 195, 127), (134, 194, 124), + (137, 192, 130), (149, 193, 134), (178, 188, 138), (200, 205, 141), + (212, 205, 172), (216, 213, 187), (212, 217, 186), (180, 205, 174), + (157, 195, 166), (112, 187, 178), (103, 185, 183), (95, 177, 181), + (68, 160, 185), (69, 166, 201), (91, 173, 167), (112, 172, 141), + (129, 190, 123), (131, 188, 123), (128, 186, 116), (121, 182, 107), + (91, 149, 116), (102, 34, 47), (107, 34, 15), (123, 28, 10), + (170, 49, 11), (214, 97, 1), (217, 111, 0), (222, 124, 3), + (227, 141, 2), (234, 157, 22), (240, 176, 44), (249, 194, 54), + (250, 194, 60), (252, 202, 64), (254, 200, 63), (253, 196, 67), + (246, 192, 66), (219, 182, 92), (162, 192, 118), (141, 188, 124), + (133, 187, 123), (136, 186, 121), (137, 189, 128), (132, 187, 132), + (108, 176, 182), (98, 183, 188), (96, 185, 193), (81, 171, 198), + (67, 175, 209), (68, 174, 204), (81, 180, 196), (94, 181, 171), + (130, 192, 129), (136, 186, 120), (134, 118, 91), (127, 53, 73), + (94, 31, 50), (85, 26, 44), (81, 25, 40), (81, 25, 36), + (74, 29, 33), (73, 29, 30), (29, 41, 29), (28, 38, 27), + (11, 17, 13), (5, 16, 11), (10, 12, 8), (12, 12, 10), + (26, 18, 7), (71, 26, 33), (85, 30, 43), (96, 81, 53), + (86, 157, 121), (127, 184, 120), (145, 173, 143), (163, 176, 159), + (197, 184, 169), (215, 198, 190), (209, 202, 182), (179, 201, 158), + (155, 200, 143), (139, 195, 127), (134, 184, 113), (148, 113, 77), + (158, 36, 13), (165, 15, 3), (174, 4, 5), (178, 5, 1), + (181, 14, 1), (162, 18, 3), (131, 19, 0), (119, 22, 5), + (122, 28, 14), (144, 95, 64), (161, 147, 76), (136, 184, 115), + (138, 187, 118), (151, 186, 112), (213, 190, 86), (235, 190, 72), + (252, 203, 78), (239, 213, 117), (231, 214, 169), (234, 218, 179), + (228, 220, 181), (210, 214, 170), (160, 205, 149), (148, 202, 142), + (147, 200, 138), (161, 198, 139), (181, 200, 134), (198, 195, 118), + (234, 187, 70), (241, 174, 51), (230, 129, 18), (227, 125, 3), + (224, 121, 3), (228, 119, 2), (222, 123, 4), (224, 125, 4), + (223, 130, 1), (229, 145, 1), (232, 166, 29), (219, 181, 69), + (183, 183, 110), (153, 193, 124), (153, 201, 135), (158, 203, 146), + (188, 210, 164), (206, 218, 197), (202, 219, 203), (200, 214, 201), + (149, 193, 172), (112, 192, 183), (125, 194, 172), (144, 192, 132), + (166, 192, 126), (213, 152, 98), (213, 131, 14), (218, 121, 7), + (221, 113, 5), (220, 111, 2), (223, 117, 2), (223, 117, 4), + (222, 118, 1), (218, 119, 1), (218, 122, 0), (217, 125, 1), + (217, 134, 9), (231, 160, 32), (241, 171, 85), (206, 186, 135), + (230, 211, 173), (227, 216, 188), (227, 210, 192), (230, 220, 195), + (226, 221, 194), (225, 219, 188), (221, 218, 192), (223, 227, 196), + (219, 222, 207), (207, 221, 204), (216, 223, 196), (215, 218, 189), + (220, 218, 173), (204, 191, 145), (201, 135, 144), (218, 142, 83), + (196, 127, 22), (202, 87, 2), (163, 21, 0), (124, 19, 1), + (101, 32, 6), (84, 47, 14), (111, 120, 67), (85, 155, 123), + (89, 165, 129), (83, 157, 124), (70, 122, 117), (78, 32, 40) +), + +// 78 kandinsky.yellow-red-blue.ppm +( + (8, 1, 9), (18, 7, 12), (41, 2, 17), (56, 14, 26), + (97, 18, 40), (101, 48, 45), (110, 76, 36), (142, 112, 37), + (125, 122, 42), (118, 90, 40), (110, 72, 34), (104, 17, 29), + (111, 23, 27), (141, 41, 42), (168, 88, 88), (178, 116, 101), + (156, 118, 128), (138, 130, 114), (139, 126, 99), (132, 121, 90), + (129, 120, 101), (129, 118, 116), (110, 100, 123), (92, 69, 125), + (85, 65, 116), (98, 71, 105), (130, 98, 74), (137, 130, 54), + (140, 128, 55), (145, 118, 45), (149, 123, 38), (144, 128, 50), + (158, 141, 56), (172, 151, 55), (159, 145, 47), (171, 154, 58), + (184, 153, 66), (185, 154, 70), (183, 155, 68), (177, 163, 70), + (174, 160, 66), (168, 157, 71), (172, 159, 65), (168, 156, 68), + (163, 155, 67), (160, 147, 69), (164, 151, 85), (164, 153, 89), + (162, 153, 91), (156, 155, 98), (155, 142, 108), (158, 149, 97), + (152, 149, 96), (151, 147, 113), (143, 137, 124), (139, 128, 135), + (128, 118, 135), (119, 126, 142), (115, 128, 147), (116, 128, 154), + (117, 109, 167), (105, 110, 165), (103, 139, 206), (116, 143, 241), + (118, 132, 242), (128, 138, 243), (135, 150, 243), (148, 161, 244), + (140, 151, 239), (141, 160, 242), (145, 155, 240), (158, 145, 230), + (161, 146, 223), (144, 152, 223), (158, 136, 227), (170, 135, 216), + (169, 146, 220), (188, 165, 214), (210, 179, 238), (219, 192, 244), + (233, 209, 245), (236, 211, 243), (218, 190, 245), (191, 170, 246), + (178, 158, 247), (157, 144, 237), (147, 128, 230), (143, 125, 227), + (103, 124, 233), (100, 115, 200), (102, 87, 192), (75, 74, 148), + (27, 54, 120), (30, 45, 100), (30, 39, 66), (28, 37, 51), + (33, 31, 33), (32, 33, 37), (39, 45, 51), (40, 67, 94), + (59, 52, 113), (71, 66, 120), (78, 66, 158), (88, 66, 180), + (107, 75, 215), (120, 89, 216), (125, 84, 226), (132, 101, 228), + (141, 107, 236), (144, 113, 236), (139, 108, 233), (125, 104, 207), + (110, 95, 198), (133, 110, 177), (155, 133, 166), (168, 154, 171), + (163, 149, 162), (145, 134, 166), (129, 132, 161), (109, 121, 132), + (96, 114, 122), (86, 98, 124), (67, 76, 117), (56, 63, 104), + (60, 58, 69), (66, 35, 69), (95, 25, 56), (113, 29, 62), + (144, 42, 79), (157, 65, 100), (129, 75, 130), (98, 81, 181), + (97, 85, 199), (96, 61, 204), (94, 59, 202), (89, 57, 197), + (85, 53, 196), (92, 63, 190), (94, 61, 197), (90, 59, 188), + (74, 45, 173), (70, 43, 176), (69, 40, 160), (63, 36, 144), + (31, 33, 99), (20, 19, 67), (19, 16, 48), (17, 14, 39), + (19, 20, 27), (13, 9, 7), (5, 2, 9), (5, 0, 7), + (4, 0, 6), (1, 1, 3), (1, 0, 2), (3, 2, 2), + (3, 4, 4), (3, 2, 6), (3, 1, 10), (8, 6, 14), + (22, 19, 32), (34, 29, 31), (34, 30, 30), (42, 29, 38), + (44, 26, 48), (52, 37, 48), (60, 56, 66), (66, 66, 74), + (67, 75, 95), (128, 118, 104), (155, 142, 109), (168, 155, 126), + (178, 163, 154), (177, 167, 165), (183, 170, 173), (193, 175, 195), + (201, 183, 220), (214, 186, 227), (215, 178, 232), (219, 180, 240), + (208, 180, 244), (198, 175, 242), (178, 171, 231), (177, 160, 220), + (182, 156, 210), (184, 156, 207), (186, 155, 207), (181, 158, 187), + (180, 159, 185), (151, 141, 201), (143, 130, 204), (154, 126, 218), + (147, 120, 232), (148, 115, 236), (158, 120, 237), (158, 137, 235), + (156, 139, 240), (149, 152, 246), (148, 157, 250), (150, 160, 250), + (163, 158, 254), (182, 174, 250), (181, 177, 239), (175, 177, 235), + (176, 167, 212), (163, 149, 196), (147, 149, 183), (136, 140, 187), + (120, 119, 174), (126, 123, 191), (145, 138, 187), (139, 147, 196), + (149, 129, 196), (157, 132, 188), (164, 93, 177), (183, 94, 182), + (185, 110, 174), (183, 133, 144), (158, 138, 149), (166, 141, 158), + (159, 147, 145), (158, 150, 130), (160, 155, 125), (161, 156, 101), + (168, 157, 80), (175, 160, 75), (187, 159, 70), (192, 162, 64), + (228, 195, 48), (198, 165, 66), (200, 174, 84), (202, 169, 86), + (220, 171, 90), (216, 186, 60), (211, 181, 92), (211, 177, 96), + (221, 172, 100), (207, 178, 98), (219, 186, 97), (228, 203, 101), + (225, 197, 113), (223, 192, 148), (213, 188, 149), (209, 179, 151), + (194, 163, 141), (182, 166, 137), (162, 152, 107), (161, 150, 87), + (159, 145, 65), (158, 130, 56), (138, 129, 75), (125, 95, 54), + (104, 70, 31), (56, 19, 44), (27, 9, 40), (13, 2, 11) +), + +// 79 klee.insula-dulcamara.ppm +( + (23, 10, 4), (63, 38, 27), (144, 110, 85), (148, 131, 73), + (144, 136, 86), (163, 131, 90), (176, 146, 96), (192, 163, 102), + (193, 157, 114), (193, 161, 130), (193, 168, 147), (181, 169, 156), + (168, 169, 150), (146, 160, 158), (130, 147, 155), (120, 159, 162), + (121, 161, 146), (112, 150, 152), (87, 121, 142), (92, 116, 138), + (119, 138, 142), (131, 142, 131), (154, 158, 110), (156, 154, 101), + (171, 151, 99), (170, 147, 84), (166, 131, 76), (152, 128, 75), + (149, 122, 63), (109, 83, 48), (26, 8, 7), (24, 6, 4), + (19, 7, 6), (17, 3, 2), (9, 2, 2), (4, 11, 6), + (26, 20, 6), (87, 117, 85), (117, 151, 117), (145, 138, 113), + (143, 132, 87), (129, 107, 66), (28, 10, 7), (22, 7, 8), + (30, 15, 12), (92, 111, 109), (84, 117, 137), (84, 111, 146), + (110, 139, 153), (126, 157, 141), (153, 160, 132), (151, 165, 120), + (164, 171, 122), (171, 167, 111), (170, 169, 104), (177, 149, 104), + (186, 143, 93), (176, 148, 77), (160, 151, 65), (175, 150, 75), + (169, 141, 61), (163, 108, 61), (132, 86, 35), (32, 9, 1), + (34, 20, 5), (128, 109, 56), (159, 114, 78), (177, 117, 83), + (186, 129, 83), (184, 131, 89), (193, 134, 99), (187, 149, 91), + (192, 143, 100), (199, 154, 108), (201, 156, 119), (201, 169, 121), + (202, 174, 128), (201, 178, 133), (213, 183, 133), (206, 179, 137), + (210, 179, 137), (219, 180, 138), (219, 182, 133), (216, 185, 134), + (216, 185, 137), (221, 184, 144), (221, 193, 147), (221, 192, 158), + (219, 187, 159), (221, 190, 165), (221, 196, 167), (220, 197, 172), + (220, 200, 165), (206, 196, 165), (196, 191, 167), (195, 184, 166), + (192, 178, 167), (166, 178, 173), (160, 179, 167), (158, 168, 161), + (149, 165, 164), (148, 164, 167), (144, 170, 170), (142, 165, 178), + (121, 153, 171), (113, 138, 160), (94, 119, 147), (89, 110, 140), + (52, 49, 54), (23, 10, 7), (14, 5, 0), (6, 1, 0), + (9, 2, 1), (19, 8, 7), (26, 8, 6), (54, 34, 14), + (150, 122, 40), (147, 148, 57), (143, 149, 61), (155, 145, 69), + (176, 143, 69), (194, 151, 66), (199, 146, 64), (197, 145, 60), + (181, 145, 67), (178, 139, 72), (186, 142, 76), (183, 147, 72), + (185, 154, 80), (190, 156, 84), (191, 168, 99), (175, 179, 104), + (181, 168, 120), (195, 169, 133), (183, 174, 137), (197, 165, 130), + (206, 166, 126), (211, 176, 133), (209, 188, 136), (215, 181, 133), + (202, 184, 122), (205, 197, 119), (195, 192, 115), (203, 190, 107), + (210, 172, 110), (212, 189, 110), (207, 192, 106), (191, 190, 101), + (182, 186, 92), (174, 183, 78), (168, 179, 79), (158, 175, 75), + (157, 166, 69), (145, 164, 64), (129, 163, 91), (94, 146, 106), + (67, 58, 29), (24, 11, 6), (26, 9, 6), (95, 79, 42), + (121, 129, 96), (146, 161, 92), (166, 185, 88), (172, 177, 82), + (185, 184, 76), (184, 187, 85), (179, 177, 86), (189, 175, 97), + (203, 177, 100), (199, 168, 110), (211, 164, 112), (208, 162, 123), + (202, 166, 121), (210, 164, 134), (207, 167, 147), (207, 169, 135), + (207, 169, 130), (214, 174, 125), (210, 173, 122), (205, 172, 125), + (202, 178, 124), (187, 178, 120), (184, 182, 117), (203, 187, 95), + (209, 186, 94), (217, 193, 101), (213, 175, 93), (208, 171, 87), + (208, 165, 80), (205, 158, 79), (193, 160, 79), (192, 162, 80), + (203, 180, 85), (199, 187, 82), (217, 198, 90), (220, 201, 98), + (226, 204, 105), (221, 190, 103), (222, 200, 120), (222, 191, 127), + (234, 200, 134), (222, 186, 122), (221, 186, 133), (219, 186, 135), + (215, 185, 130), (206, 189, 130), (204, 185, 139), (206, 183, 146), + (200, 174, 144), (202, 177, 146), (193, 182, 150), (187, 184, 154), + (181, 174, 153), (194, 184, 149), (210, 178, 152), (209, 181, 157), + (216, 188, 146), (214, 191, 146), (216, 196, 147), (223, 197, 151), + (226, 198, 154), (223, 207, 156), (215, 203, 166), (221, 204, 164), + (222, 195, 177), (237, 204, 177), (223, 200, 171), (230, 221, 187), + (226, 219, 191), (217, 208, 195), (255, 250, 232), (210, 201, 181), + (217, 209, 167), (230, 208, 161), (227, 208, 158), (224, 207, 153), + (226, 202, 156), (227, 196, 161), (223, 191, 165), (224, 190, 159), + (219, 196, 162), (215, 198, 163), (212, 192, 167), (211, 191, 160), + (206, 196, 161), (206, 195, 165), (207, 186, 165), (200, 190, 166), + (199, 194, 160), (198, 197, 143), (179, 200, 141), (171, 171, 130), + (155, 147, 120), (147, 135, 111), (134, 114, 74), (34, 16, 7) +), + +// 80 nile.ppm +( + (6, 39, 66), (27, 62, 99), (97, 68, 75), (156, 67, 38), + (216, 117, 3), (235, 142, 3), (254, 172, 3), (250, 212, 163), + (252, 231, 218), (238, 226, 247), (239, 229, 249), (237, 221, 250), + (220, 207, 244), (203, 200, 243), (198, 194, 235), (198, 173, 212), + (205, 162, 167), (203, 138, 42), (233, 145, 2), (242, 148, 1), + (250, 157, 6), (215, 175, 140), (203, 175, 195), (190, 164, 195), + (190, 148, 137), (216, 135, 22), (215, 125, 10), (171, 102, 23), + (129, 100, 47), (121, 95, 144), (128, 142, 174), (173, 161, 221), + (183, 170, 228), (186, 173, 229), (188, 175, 237), (188, 180, 239), + (191, 178, 242), (191, 176, 241), (195, 171, 230), (193, 166, 240), + (196, 167, 231), (195, 168, 229), (185, 164, 220), (177, 160, 210), + (137, 139, 141), (134, 82, 60), (141, 38, 18), (116, 24, 1), + (112, 16, 1), (115, 28, 6), (120, 61, 52), (103, 73, 159), + (64, 36, 166), (29, 40, 175), (24, 42, 167), (8, 47, 170), + (2, 38, 172), (7, 34, 178), (9, 48, 185), (19, 54, 186), + (23, 67, 194), (40, 59, 185), (52, 61, 183), (65, 68, 191), + (68, 70, 191), (77, 86, 199), (84, 89, 201), (105, 106, 203), + (114, 114, 223), (178, 149, 221), (193, 157, 211), (211, 172, 164), + (248, 158, 11), (254, 165, 3), (252, 172, 8), (234, 191, 176), + (219, 196, 207), (212, 193, 216), (207, 192, 219), (205, 177, 227), + (203, 179, 227), (197, 183, 238), (196, 189, 244), (194, 184, 244), + (200, 187, 245), (205, 199, 251), (213, 215, 251), (217, 214, 254), + (236, 233, 250), (247, 232, 253), (251, 238, 253), (251, 242, 251), + (252, 243, 251), (251, 240, 252), (243, 231, 251), (233, 219, 231), + (235, 212, 214), (213, 182, 218), (204, 164, 169), (161, 110, 98), + (115, 59, 43), (119, 40, 3), (124, 31, 5), (132, 39, 8), + (174, 73, 7), (223, 128, 5), (243, 157, 10), (232, 179, 167), + (224, 196, 210), (239, 205, 211), (241, 221, 218), (234, 223, 238), + (236, 225, 248), (230, 217, 247), (229, 206, 234), (219, 205, 219), + (214, 196, 210), (215, 184, 163), (246, 158, 7), (249, 165, 3), + (245, 160, 4), (241, 146, 3), (233, 137, 2), (220, 122, 7), + (161, 88, 51), (153, 127, 130), (172, 145, 194), (191, 160, 214), + (192, 164, 225), (192, 162, 230), (185, 159, 232), (177, 156, 226), + (144, 147, 223), (98, 131, 220), (81, 124, 214), (64, 115, 203), + (61, 117, 181), (62, 111, 175), (69, 106, 162), (66, 106, 148), + (49, 100, 154), (25, 87, 150), (30, 80, 145), (13, 66, 130), + (17, 70, 121), (32, 80, 103), (68, 82, 99), (88, 34, 11), + (105, 17, 6), (106, 19, 3), (119, 56, 31), (114, 76, 83), + (118, 101, 167), (161, 150, 217), (176, 172, 233), (179, 177, 233), + (176, 183, 242), (171, 177, 238), (168, 181, 241), (177, 185, 242), + (178, 188, 241), (178, 190, 247), (189, 196, 252), (194, 208, 250), + (203, 203, 243), (197, 198, 244), (196, 195, 243), (192, 196, 244), + (196, 193, 238), (192, 187, 239), (183, 191, 240), (182, 190, 244), + (188, 191, 224), (185, 179, 224), (185, 171, 210), (171, 144, 177), + (175, 129, 92), (225, 138, 1), (234, 140, 1), (240, 146, 4), + (245, 151, 6), (219, 168, 138), (193, 157, 206), (173, 157, 219), + (108, 123, 203), (83, 122, 207), (70, 127, 189), (64, 116, 180), + (61, 113, 168), (56, 97, 158), (30, 89, 142), (35, 90, 128), + (30, 89, 125), (22, 77, 120), (18, 68, 110), (20, 55, 88), + (93, 8, 6), (100, 9, 3), (118, 14, 1), (136, 41, 6), + (217, 113, 3), (227, 137, 1), (223, 132, 3), (165, 99, 20), + (144, 55, 30), (127, 32, 6), (116, 26, 6), (112, 46, 44), + (111, 71, 98), (92, 93, 152), (107, 110, 176), (102, 115, 200), + (110, 118, 213), (146, 142, 222), (173, 163, 224), (182, 175, 229), + (184, 179, 233), (184, 177, 236), (182, 172, 239), (178, 170, 239), + (174, 173, 237), (170, 160, 225), (108, 120, 218), (98, 125, 210), + (84, 119, 218), (81, 121, 217), (71, 123, 218), (72, 115, 212), + (79, 114, 208), (87, 116, 206), (87, 106, 203), (85, 100, 202), + (74, 92, 198), (57, 90, 209), (55, 95, 206), (61, 88, 195), + (61, 79, 186), (51, 83, 194), (33, 80, 195), (32, 87, 198), + (32, 90, 201), (51, 104, 211), (58, 102, 206), (61, 106, 181), + (62, 110, 178), (72, 115, 165), (73, 110, 160), (75, 95, 155), + (75, 96, 145), (68, 91, 149), (39, 96, 148), (31, 81, 143), + (29, 82, 137), (23, 79, 121), (25, 64, 120), (17, 60, 100) +), + +// 81 picasso.jfille-chevre.ppm +( + (24, 0, 0), (84, 2, 2), (184, 46, 0), (195, 61, 5), + (198, 61, 2), (203, 76, 3), (207, 80, 3), (211, 85, 3), + (209, 84, 2), (208, 79, 3), (204, 73, 0), (203, 61, 1), + (201, 59, 4), (199, 62, 3), (202, 76, 3), (205, 77, 7), + (207, 85, 7), (203, 93, 14), (194, 90, 28), (203, 102, 46), + (204, 100, 40), (183, 97, 38), (185, 96, 28), (151, 102, 51), + (196, 102, 41), (206, 119, 51), (225, 142, 78), (222, 148, 77), + (228, 148, 76), (220, 140, 77), (199, 136, 70), (208, 114, 43), + (209, 108, 37), (199, 124, 31), (206, 127, 29), (207, 130, 30), + (205, 135, 30), (208, 137, 32), (214, 146, 36), (218, 154, 55), + (222, 162, 83), (225, 184, 99), (228, 197, 128), (232, 202, 150), + (227, 202, 163), (237, 208, 172), (239, 211, 172), (241, 214, 173), + (246, 218, 175), (248, 219, 178), (249, 220, 178), (247, 223, 185), + (252, 226, 180), (252, 224, 187), (250, 226, 191), (249, 225, 189), + (247, 224, 191), (249, 226, 195), (248, 225, 192), (247, 227, 192), + (247, 224, 193), (245, 222, 193), (244, 220, 186), (243, 221, 184), + (245, 220, 182), (245, 216, 184), (244, 215, 183), (242, 216, 180), + (239, 215, 179), (238, 213, 175), (237, 214, 172), (238, 211, 162), + (236, 206, 152), (236, 204, 140), (232, 199, 128), (229, 179, 113), + (229, 167, 97), (225, 163, 93), (223, 155, 82), (210, 147, 85), + (196, 126, 70), (208, 104, 48), (215, 101, 49), (211, 111, 32), + (205, 125, 18), (214, 133, 14), (214, 142, 15), (215, 153, 44), + (219, 168, 76), (228, 184, 90), (231, 188, 99), (233, 194, 118), + (241, 203, 124), (235, 202, 135), (236, 201, 133), (237, 186, 120), + (237, 176, 107), (231, 171, 102), (231, 168, 94), (227, 167, 101), + (225, 168, 119), (212, 164, 105), (232, 178, 119), (244, 194, 131), + (241, 206, 140), (238, 208, 150), (238, 210, 161), (233, 208, 170), + (233, 211, 169), (237, 215, 173), (241, 217, 177), (243, 217, 181), + (246, 218, 179), (247, 221, 173), (251, 223, 174), (247, 220, 172), + (247, 220, 169), (243, 216, 161), (245, 209, 144), (242, 201, 137), + (241, 201, 116), (232, 187, 99), (227, 160, 80), (225, 145, 73), + (217, 122, 51), (213, 122, 33), (204, 129, 21), (200, 127, 20), + (197, 121, 11), (196, 117, 7), (193, 109, 0), (195, 120, 8), + (197, 132, 18), (209, 137, 27), (218, 145, 31), (220, 163, 56), + (230, 186, 95), (232, 193, 105), (233, 200, 129), (237, 207, 141), + (245, 211, 150), (242, 215, 158), (242, 213, 164), (236, 212, 171), + (235, 211, 172), (234, 212, 176), (236, 214, 177), (238, 213, 183), + (238, 214, 179), (227, 207, 181), (240, 215, 182), (242, 219, 182), + (241, 221, 182), (243, 221, 183), (244, 220, 183), (242, 218, 183), + (240, 216, 190), (242, 218, 191), (246, 219, 195), (245, 224, 198), + (243, 226, 199), (246, 228, 205), (246, 226, 202), (250, 230, 205), + (250, 229, 206), (248, 231, 205), (250, 228, 197), (248, 230, 194), + (248, 228, 196), (246, 227, 195), (244, 224, 196), (239, 223, 197), + (236, 214, 193), (237, 218, 188), (240, 217, 186), (239, 215, 181), + (241, 212, 173), (238, 211, 166), (237, 212, 155), (233, 206, 145), + (235, 201, 134), (220, 179, 120), (212, 170, 121), (206, 175, 108), + (211, 162, 117), (210, 156, 93), (223, 154, 89), (224, 158, 81), + (228, 163, 81), (234, 167, 90), (237, 176, 104), (240, 193, 127), + (237, 204, 141), (237, 206, 152), (237, 208, 159), (238, 212, 165), + (241, 218, 170), (240, 215, 171), (244, 216, 170), (246, 215, 160), + (242, 213, 169), (245, 210, 160), (249, 215, 154), (247, 212, 146), + (251, 213, 137), (245, 211, 137), (239, 207, 146), (235, 203, 151), + (224, 201, 154), (236, 202, 151), (237, 203, 154), (233, 206, 158), + (239, 210, 166), (238, 211, 169), (240, 211, 167), (242, 212, 168), + (239, 212, 164), (241, 211, 157), (236, 208, 150), (236, 205, 142), + (235, 202, 139), (231, 192, 122), (227, 189, 102), (226, 168, 88), + (224, 159, 72), (211, 144, 40), (201, 136, 33), (204, 132, 21), + (205, 133, 16), (208, 132, 14), (205, 131, 10), (204, 130, 9), + (202, 120, 8), (204, 124, 2), (195, 119, 6), (193, 117, 12), + (205, 109, 27), (213, 98, 30), (203, 89, 27), (207, 92, 29), + (212, 95, 23), (203, 90, 24), (201, 89, 25), (203, 90, 23), + (202, 90, 20), (204, 92, 16), (203, 85, 11), (189, 82, 5), + (196, 80, 15), (193, 78, 12), (189, 68, 5), (194, 78, 4), + (183, 70, 2), (182, 65, 9), (147, 49, 11), (42, 1, 3) +), + +// 82 pollock.lavender-mist.ppm +( + (3, 5, 2), (37, 33, 23), (65, 68, 36), (96, 95, 63), + (128, 112, 83), (152, 127, 86), (168, 141, 100), (181, 155, 104), + (183, 157, 111), (179, 157, 119), (175, 157, 121), (175, 159, 122), + (172, 157, 121), (168, 154, 114), (161, 149, 111), (154, 140, 106), + (150, 139, 107), (149, 135, 103), (144, 132, 102), (140, 130, 104), + (137, 128, 103), (140, 124, 102), (136, 126, 102), (133, 124, 97), + (135, 123, 94), (137, 123, 96), (140, 123, 94), (142, 126, 98), + (146, 125, 99), (150, 136, 101), (157, 145, 102), (164, 146, 107), + (172, 150, 121), (172, 156, 126), (180, 156, 123), (196, 164, 119), + (207, 171, 120), (208, 174, 128), (212, 181, 136), (210, 187, 137), + (209, 181, 131), (206, 168, 129), (203, 169, 127), (196, 171, 121), + (184, 166, 122), (177, 156, 117), (164, 146, 105), (156, 131, 93), + (136, 121, 89), (121, 112, 82), (105, 104, 75), (102, 102, 77), + (94, 90, 74), (71, 76, 62), (73, 77, 57), (94, 90, 65), + (108, 96, 66), (111, 98, 71), (110, 99, 81), (115, 111, 86), + (121, 114, 95), (123, 114, 94), (129, 117, 94), (130, 120, 90), + (130, 121, 90), (130, 119, 86), (130, 117, 81), (125, 103, 68), + (107, 88, 56), (96, 84, 53), (74, 62, 40), (55, 48, 36), + (41, 31, 29), (40, 34, 24), (37, 38, 25), (42, 39, 28), + (56, 49, 28), (59, 57, 36), (69, 73, 51), (94, 80, 63), + (99, 95, 79), (106, 99, 80), (118, 111, 85), (126, 113, 92), + (133, 123, 95), (132, 128, 95), (137, 132, 95), (140, 133, 103), + (141, 132, 104), (142, 135, 106), (144, 135, 109), (148, 139, 112), + (148, 142, 113), (151, 146, 118), (151, 144, 121), (156, 145, 124), + (152, 151, 130), (147, 156, 130), (150, 159, 134), (158, 157, 132), + (162, 158, 136), (164, 160, 137), (173, 165, 143), (179, 171, 154), + (189, 179, 155), (194, 187, 161), (192, 186, 164), (188, 186, 158), + (188, 180, 149), (185, 177, 146), (179, 167, 139), (170, 164, 132), + (167, 157, 129), (162, 155, 126), (155, 149, 120), (158, 142, 119), + (156, 142, 115), (157, 147, 114), (159, 148, 115), (164, 152, 115), + (167, 153, 123), (169, 155, 129), (173, 160, 131), (176, 163, 130), + (185, 172, 135), (191, 181, 142), (197, 185, 149), (198, 188, 159), + (202, 187, 160), (207, 190, 156), (212, 196, 152), (212, 194, 155), + (207, 193, 164), (209, 196, 165), (213, 197, 165), (218, 194, 160), + (215, 189, 152), (207, 185, 152), (200, 179, 150), (197, 177, 145), + (188, 170, 137), (174, 160, 131), (169, 157, 127), (166, 162, 119), + (155, 153, 116), (147, 145, 108), (145, 138, 114), (139, 134, 114), + (138, 132, 115), (129, 133, 113), (129, 128, 109), (127, 130, 102), + (119, 118, 93), (119, 112, 87), (114, 101, 77), (114, 102, 72), + (117, 106, 74), (117, 111, 77), (123, 116, 87), (120, 115, 91), + (126, 121, 92), (134, 128, 92), (145, 128, 90), (149, 138, 97), + (154, 140, 104), (162, 138, 103), (163, 137, 102), (167, 143, 108), + (167, 144, 111), (172, 149, 118), (175, 157, 121), (177, 163, 122), + (180, 166, 119), (186, 167, 128), (191, 174, 130), (200, 173, 131), + (201, 173, 132), (192, 176, 136), (188, 174, 141), (189, 177, 143), + (191, 172, 136), (185, 166, 128), (181, 161, 126), (187, 157, 122), + (194, 149, 113), (182, 140, 94), (166, 118, 76), (131, 100, 61), + (101, 81, 56), (74, 70, 52), (71, 56, 38), (66, 55, 35), + (58, 49, 32), (69, 63, 49), (77, 73, 56), (94, 84, 71), + (98, 97, 80), (103, 103, 88), (101, 117, 98), (109, 143, 125), + (138, 142, 122), (138, 142, 121), (145, 143, 123), (155, 152, 128), + (161, 158, 133), (172, 159, 137), (184, 169, 143), (197, 178, 149), + (201, 187, 146), (206, 188, 152), (215, 189, 147), (213, 188, 135), + (222, 181, 123), (213, 181, 124), (203, 163, 112), (192, 153, 110), + (185, 145, 99), (177, 142, 106), (168, 142, 105), (162, 142, 105), + (154, 139, 106), (151, 135, 109), (149, 136, 110), (150, 137, 114), + (151, 143, 120), (158, 146, 122), (167, 155, 130), (181, 168, 134), + (194, 182, 143), (208, 186, 143), (210, 200, 145), (224, 198, 145), + (225, 196, 150), (229, 205, 161), (243, 223, 174), (245, 222, 183), + (232, 211, 177), (225, 208, 171), (224, 219, 189), (224, 217, 200), + (222, 205, 186), (207, 203, 169), (203, 196, 156), (196, 186, 157), + (189, 178, 149), (175, 164, 133), (163, 157, 129), (151, 151, 120), + (141, 141, 112), (132, 129, 104), (121, 128, 106), (100, 110, 94), + (84, 88, 75), (73, 69, 60), (50, 56, 42), (18, 19, 13) +), + +// 83 yngpaint.ppm +( + (20, 15, 10), (52, 47, 45), (20, 105, 104), (63, 130, 123), + (91, 144, 114), (104, 140, 123), (126, 141, 130), (137, 151, 131), + (160, 157, 128), (170, 165, 126), (182, 173, 128), (188, 186, 129), + (190, 192, 144), (200, 204, 157), (204, 205, 163), (211, 209, 166), + (212, 213, 167), (216, 218, 171), (219, 220, 174), (221, 223, 173), + (222, 224, 176), (222, 224, 177), (224, 224, 174), (222, 222, 171), + (221, 221, 167), (220, 220, 164), (219, 220, 160), (217, 219, 154), + (215, 218, 153), (212, 211, 148), (202, 203, 153), (194, 194, 152), + (185, 182, 141), (171, 167, 129), (165, 167, 121), (166, 153, 113), + (162, 134, 98), (158, 140, 102), (171, 158, 105), (172, 163, 116), + (165, 163, 117), (175, 171, 107), (179, 169, 111), (187, 166, 130), + (192, 187, 131), (197, 193, 140), (202, 201, 155), (205, 207, 158), + (210, 214, 155), (211, 223, 162), (220, 222, 163), (226, 224, 166), + (225, 222, 171), (224, 224, 172), (224, 224, 174), (224, 226, 176), + (225, 226, 182), (225, 231, 185), (225, 227, 177), (227, 227, 175), + (228, 227, 180), (229, 231, 184), (228, 234, 188), (226, 232, 188), + (228, 234, 190), (229, 231, 192), (228, 233, 191), (227, 232, 192), + (229, 234, 194), (228, 233, 196), (229, 233, 200), (231, 235, 202), + (233, 242, 214), (244, 247, 219), (236, 241, 210), (238, 235, 204), + (234, 238, 201), (229, 236, 201), (229, 234, 202), (231, 236, 199), + (234, 234, 196), (233, 231, 191), (233, 231, 190), (229, 230, 188), + (229, 229, 188), (220, 224, 189), (218, 222, 189), (219, 223, 190), + (220, 224, 188), (220, 224, 187), (222, 230, 183), (224, 225, 181), + (220, 226, 180), (220, 226, 178), (219, 226, 178), (217, 226, 174), + (218, 226, 172), (220, 222, 172), (221, 221, 171), (223, 221, 169), + (224, 221, 168), (224, 219, 169), (222, 218, 170), (217, 219, 169), + (216, 219, 165), (216, 216, 162), (213, 213, 161), (205, 208, 157), + (201, 199, 146), (184, 184, 129), (165, 164, 109), (152, 146, 97), + (143, 145, 89), (137, 143, 95), (145, 149, 111), (126, 130, 101), + (107, 137, 86), (89, 115, 101), (116, 115, 83), (117, 115, 97), + (122, 131, 115), (115, 122, 105), (108, 124, 125), (133, 143, 104), + (139, 144, 116), (142, 154, 120), (166, 172, 118), (182, 187, 121), + (195, 198, 119), (206, 208, 146), (212, 210, 145), (212, 219, 154), + (214, 218, 157), (215, 217, 157), (216, 217, 157), (216, 217, 159), + (215, 213, 159), (212, 212, 162), (205, 206, 162), (203, 199, 162), + (200, 200, 157), (184, 185, 144), (173, 166, 139), (141, 155, 133), + (114, 148, 132), (99, 147, 140), (90, 142, 146), (110, 149, 142), + (125, 157, 145), (129, 146, 147), (164, 165, 137), (183, 186, 140), + (200, 202, 161), (203, 203, 170), (204, 210, 173), (205, 208, 177), + (211, 210, 180), (212, 215, 184), (212, 214, 190), (217, 217, 189), + (219, 218, 187), (217, 221, 189), (221, 220, 190), (221, 221, 195), + (219, 222, 191), (221, 225, 192), (218, 221, 195), (218, 222, 198), + (218, 222, 197), (215, 226, 194), (218, 224, 190), (218, 223, 183), + (218, 224, 180), (218, 224, 177), (217, 224, 180), (216, 221, 181), + (216, 220, 183), (213, 218, 183), (213, 216, 185), (213, 216, 184), + (214, 213, 183), (213, 210, 180), (209, 213, 175), (213, 215, 168), + (216, 215, 168), (216, 216, 166), (215, 212, 165), (214, 212, 163), + (214, 214, 160), (217, 217, 163), (217, 217, 167), (216, 218, 170), + (218, 220, 173), (221, 220, 174), (222, 221, 175), (221, 222, 179), + (217, 224, 180), (217, 221, 187), (214, 220, 186), (216, 219, 188), + (216, 219, 188), (218, 218, 190), (220, 218, 192), (214, 218, 190), + (216, 219, 188), (215, 218, 187), (217, 216, 185), (216, 215, 184), + (216, 215, 184), (217, 214, 184), (216, 216, 184), (217, 217, 183), + (220, 221, 182), (219, 219, 184), (220, 220, 184), (217, 222, 183), + (217, 223, 179), (215, 221, 176), (213, 219, 175), (215, 221, 173), + (215, 222, 171), (213, 222, 169), (215, 222, 173), (216, 222, 173), + (219, 221, 174), (216, 222, 174), (215, 221, 175), (215, 222, 178), + (215, 220, 180), (219, 219, 181), (217, 216, 183), (215, 214, 183), + (211, 214, 181), (206, 213, 173), (201, 207, 161), (202, 205, 148), + (187, 186, 124), (181, 172, 107), (166, 158, 86), (166, 138, 81), + (162, 142, 87), (150, 140, 75), (136, 133, 68), (132, 123, 66), + (122, 117, 45), (119, 92, 9), (133, 113, 56), (102, 96, 52), + (99, 55, 50), (116, 108, 66), (74, 61, 7), (75, 50, 24), + (55, 41, 51), (46, 43, 20), (84, 9, 8), (32, 3, 5) +), + +// 84 cl-gold-orange-green from classlady1.ugr +((0, 64, 0), (44, 64, 0), (66, 64, 0), (88, 64, 0), + (111, 73, 0), (135, 82, 0), (138, 91, 0), (142, 100, 0), + (157, 137, 0), (163, 153, 0), (170, 170, 0), (184, 184, 3), + (199, 199, 6), (213, 213, 9), (228, 228, 12), (235, 235, 13), + (243, 243, 15), (233, 211, 14), (211, 167, 11), (190, 124, 8), + (168, 80, 5), (146, 36, 2), (137, 18, 1), (128, 0, 0), + (172, 88, 44), (193, 131, 66), (215, 175, 88), (235, 215, 108), + (255, 255, 128), (244, 244, 117), (233, 233, 106), (211, 211, 84), + (190, 190, 62), (128, 128, 0), (138, 138, 0), (148, 148, 0), + (157, 157, 0), (167, 167, 0), (172, 172, 0), (177, 177, 0), + (153, 164, 0), (121, 143, 0), (90, 123, 0), (58, 102, 0), + (26, 81, 0), (13, 72, 0), (0, 64, 0), (44, 97, 24), + (88, 130, 47), (175, 195, 95), (215, 225, 116), (255, 255, 138), + (233, 222, 114), (211, 189, 91), (200, 173, 79), (190, 157, 67), + (146, 91, 19), (134, 80, 9), (123, 70, 0), (118, 76, 0), + (114, 83, 0), (111, 86, 0), (109, 89, 0), (104, 95, 0), + (100, 100, 0), (129, 129, 0), (143, 143, 0), (157, 157, 0), + (170, 170, 0), (183, 183, 0), (183, 183, 0), (183, 183, 0), + (183, 183, 0), (183, 183, 0), (183, 183, 0), (173, 162, 0), + (164, 142, 0), (159, 132, 0), (155, 122, 0), (145, 101, 0), + (136, 81, 0), (150, 97, 24), (171, 129, 47), (193, 162, 71), + (204, 178, 83), (215, 195, 95), (237, 228, 119), (255, 255, 138), + (211, 211, 91), (189, 189, 67), (168, 168, 43), (157, 157, 31), + (146, 146, 19), (128, 128, 0), (150, 150, 22), (172, 172, 44), + (193, 193, 66), (255, 255, 128), (255, 244, 128), (255, 233, 128), + (255, 228, 128), (255, 223, 129), (255, 212, 129), (255, 201, 129), + (255, 203, 108), (255, 213, 85), (255, 224, 63), (255, 229, 52), + (255, 235, 41), (255, 246, 18), (255, 255, 0), (233, 211, 0), + (211, 167, 0), (168, 80, 0), (157, 58, 0), (146, 36, 0), + (128, 0, 0), (106, 11, 0), (84, 22, 0), (62, 33, 0), + (18, 55, 0), (31, 76, 11), (44, 97, 22), (66, 113, 33), + (88, 130, 44), (131, 162, 66), (175, 195, 88), (255, 255, 128), + (233, 222, 106), (190, 157, 62), (179, 140, 51), (168, 124, 40), + (146, 91, 18), (128, 64, 0), (128, 64, 0), (128, 64, 0), + (128, 64, 0), (128, 64, 0), (128, 64, 0), (139, 76, 14), + (150, 89, 28), (172, 114, 56), (193, 139, 85), (215, 164, 113), + (237, 189, 141), (228, 190, 136), (214, 180, 122), (201, 171, 108), + (174, 152, 79), (147, 133, 51), (120, 114, 23), (98, 98, 0), + (152, 152, 38), (165, 165, 47), (179, 179, 57), (206, 206, 76), + (233, 233, 95), (255, 255, 111), (255, 255, 111), (255, 255, 111), + (255, 255, 111), (255, 255, 111), (244, 238, 101), (233, 222, 92), + (211, 189, 73), (190, 157, 54), (168, 124, 35), (146, 91, 16), + (144, 91, 0), (152, 105, 0), (161, 119, 0), (177, 146, 0), + (193, 173, 0), (210, 201, 0), (223, 223, 0), (207, 185, 0), + (190, 146, 0), (174, 108, 0), (158, 70, 0), (141, 31, 0), + (128, 0, 0), (144, 38, 0), (161, 77, 0), (177, 115, 0), + (210, 192, 0), (216, 207, 0), (223, 223, 0), (207, 207, 0), + (190, 190, 0), (174, 174, 0), (158, 158, 0), (128, 128, 0), + (150, 150, 0), (172, 172, 0), (193, 193, 0), (215, 215, 0), + (237, 237, 0), (255, 255, 0), (244, 244, 0), (234, 234, 0), + (223, 223, 0), (212, 212, 0), (202, 202, 0), (193, 193, 0), + (176, 168, 0), (159, 143, 0), (142, 118, 0), (125, 93, 0), + (108, 68, 0), (94, 47, 0), (122, 83, 22), (149, 118, 44), + (177, 154, 66), (205, 190, 88), (232, 226, 110), (255, 255, 128), + (242, 242, 113), (230, 228, 98), (217, 215, 83), (204, 201, 68), + (191, 188, 52), (181, 177, 40), (181, 177, 40), (181, 177, 40), + (181, 177, 40), (181, 177, 40), (181, 177, 40), (150, 158, 33), + (119, 138, 26), (88, 119, 19), (57, 99, 12), (25, 80, 6), + (0, 64, 0), (38, 91, 0), (77, 119, 0), (115, 146, 0), + (153, 173, 0), (192, 201, 0), (223, 223, 0), (207, 196, 0), + (190, 168, 0), (174, 141, 0), (158, 114, 0), (141, 86, 0), + (128, 64, 0), (128, 64, 0), (128, 64, 0), (128, 64, 0), + (128, 64, 0), (128, 64, 0), (128, 64, 0), (144, 91, 0), + (160, 118, 0), (176, 145, 0), (192, 172, 0), (221, 221, 0) + ), + +// 85 cl-gold-rose +((0, 0, 0), (252, 192, 0), (250, 190, 2), (248, 188, 4), + (248, 186, 4), (248, 184, 4), (248, 184, 4), (248, 184, 4), + (244, 180, 4), (244, 178, 6), (244, 176, 8), (242, 174, 8), + (240, 172, 8), (240, 170, 8), (240, 168, 8), (238, 168, 10), + (236, 168, 12), (236, 164, 12), (234, 162, 12), (232, 160, 12), + (232, 158, 14), (232, 156, 16), (232, 156, 16), (232, 156, 16), + (228, 152, 16), (228, 150, 16), (228, 148, 16), (226, 148, 18), + (224, 148, 20), (224, 146, 20), (224, 144, 20), (224, 144, 20), + (220, 140, 20), (220, 140, 24), (218, 138, 24), (216, 136, 24), + (216, 134, 24), (216, 132, 24), (216, 132, 24), (216, 132, 24), + (212, 128, 28), (212, 126, 28), (212, 124, 28), (210, 122, 28), + (208, 120, 28), (208, 120, 30), (208, 120, 32), (208, 116, 32), + (204, 116, 32), (204, 112, 32), (202, 110, 34), (200, 108, 36), + (200, 106, 36), (200, 104, 36), (200, 104, 36), (200, 104, 36), + (196, 100, 36), (196, 98, 38), (196, 96, 40), (194, 96, 40), + (192, 96, 40), (192, 94, 40), (192, 92, 40), (192, 92, 44), + (192, 88, 44), (188, 88, 44), (188, 86, 44), (188, 84, 44), + (186, 82, 46), (184, 80, 48), (184, 80, 48), (184, 80, 48), + (180, 76, 48), (180, 74, 50), (180, 72, 52), (178, 70, 52), + (176, 68, 52), (176, 68, 52), (176, 68, 52), (176, 64, 52), + (176, 64, 52), (172, 60, 56), (172, 58, 56), (172, 56, 56), + (170, 56, 56), (168, 56, 56), (168, 52, 56), (168, 52, 60), + (164, 48, 60), (164, 46, 60), (164, 44, 60), (164, 44, 60), + (164, 44, 60), (160, 44, 64), (160, 40, 64), (160, 40, 64), + (160, 36, 64), (156, 36, 64), (156, 34, 66), (156, 32, 68), + (154, 30, 68), (152, 28, 68), (152, 28, 68), (152, 28, 68), + (148, 24, 72), (148, 22, 72), (148, 20, 72), (148, 18, 72), + (148, 16, 72), (144, 16, 72), (144, 16, 72), (144, 12, 76), + (144, 12, 76), (140, 8, 76), (140, 8, 76), (140, 8, 76), + (140, 4, 76), (136, 4, 80), (136, 0, 80), (136, 0, 80), + (136, 0, 80), (134, 0, 80), (132, 0, 80), (132, 0, 80), + (132, 0, 80), (132, 0, 80), (128, 0, 80), (128, 0, 76), + (128, 0, 76), (124, 0, 76), (124, 0, 76), (124, 0, 76), + (124, 0, 76), (124, 0, 72), (120, 0, 72), (120, 0, 72), + (120, 0, 72), (118, 0, 72), (116, 0, 72), (116, 0, 70), + (116, 0, 68), (116, 0, 68), (112, 0, 68), (112, 0, 68), + (112, 0, 68), (108, 0, 68), (108, 0, 66), (108, 0, 64), + (108, 0, 64), (108, 0, 64), (104, 0, 64), (104, 0, 64), + (104, 0, 60), (102, 0, 60), (100, 0, 60), (100, 0, 60), + (100, 0, 60), (100, 0, 60), (96, 0, 60), (96, 0, 60), + (96, 0, 56), (92, 0, 56), (92, 0, 56), (92, 0, 56), + (92, 0, 56), (92, 0, 56), (88, 0, 52), (88, 0, 52), + (88, 0, 52), (86, 0, 52), (84, 0, 52), (84, 0, 52), + (84, 0, 52), (84, 0, 48), (80, 0, 48), (80, 0, 48), + (80, 0, 48), (80, 0, 48), (76, 0, 48), (76, 0, 48), + (76, 0, 44), (76, 0, 44), (72, 0, 44), (72, 0, 44), + (72, 0, 44), (70, 0, 42), (68, 0, 40), (68, 0, 40), + (68, 0, 40), (68, 0, 40), (64, 0, 40), (64, 0, 40), + (64, 0, 40), (64, 0, 36), (60, 0, 36), (60, 0, 36), + (60, 0, 36), (60, 0, 36), (56, 0, 36), (56, 0, 32), + (56, 0, 32), (56, 0, 32), (52, 0, 32), (52, 0, 32), + (52, 0, 32), (52, 0, 32), (48, 0, 28), (48, 0, 28), + (48, 0, 28), (48, 0, 28), (44, 0, 28), (44, 0, 28), + (44, 0, 28), (44, 0, 24), (40, 0, 24), (40, 0, 24), + (40, 0, 24), (40, 0, 24), (36, 0, 24), (36, 0, 20), + (36, 0, 20), (36, 0, 20), (32, 0, 20), (32, 0, 20), + (32, 0, 20), (32, 0, 20), (28, 0, 16), (28, 0, 16), + (28, 0, 16), (28, 0, 16), (24, 0, 16), (24, 0, 16), + (24, 0, 12), (24, 0, 12), (20, 0, 12), (20, 0, 12), + (20, 0, 12), (20, 0, 12), (16, 0, 12), (16, 0, 8), + (16, 0, 8), (16, 0, 8), (12, 0, 8), (12, 0, 8), + (12, 0, 8), (12, 0, 8), (8, 0, 4), (8, 0, 4), + (8, 0, 4), (8, 0, 4), (4, 0, 4), (4, 0, 4), + (4, 0, 0), (4, 0, 0), (0, 0, 0), (0, 0, 0) + ), + +// 86 cl-lavender-purple-blues-black +((103, 105, 102), (75, 29, 127), (55, 26, 99), (35, 23, 71), + (25, 20, 52), (15, 18, 33), (12, 18, 31), (10, 18, 29), + (29, 41, 31), (41, 54, 44), (54, 67, 57), (81, 71, 66), + (109, 75, 76), (106, 93, 87), (104, 112, 99), (99, 103, 90), + (94, 94, 82), (84, 83, 91), (70, 70, 120), (56, 57, 149), + (54, 55, 146), (53, 53, 143), (52, 52, 142), (52, 52, 142), + (52, 41, 133), (69, 31, 129), (87, 22, 126), (89, 22, 127), + (91, 22, 128), (87, 21, 126), (84, 21, 125), (83, 18, 122), + (80, 18, 119), (76, 44, 81), (54, 44, 61), (32, 44, 42), + (30, 43, 33), (28, 43, 24), (30, 44, 30), (33, 46, 37), + (71, 66, 70), (84, 81, 81), (98, 97, 92), (111, 72, 120), + (125, 47, 148), (127, 44, 147), (129, 42, 147), (125, 39, 146), + (123, 40, 146), (58, 49, 142), (51, 47, 140), (45, 46, 138), + (45, 45, 137), (45, 44, 137), (44, 43, 136), (44, 43, 136), + (47, 46, 139), (47, 46, 139), (48, 47, 140), (51, 44, 136), + (54, 41, 133), (54, 39, 131), (55, 38, 130), (62, 27, 119), + (75, 19, 118), (93, 24, 131), (90, 23, 128), (87, 22, 126), + (81, 21, 122), (75, 21, 119), (45, 29, 78), (38, 25, 69), + (33, 25, 62), (26, 23, 48), (20, 22, 34), (17, 20, 33), + (15, 18, 33), (15, 18, 32), (15, 19, 31), (11, 18, 26), + (8, 17, 22), (4, 11, 17), (3, 11, 18), (3, 12, 19), + (5, 14, 20), (7, 16, 21), (7, 17, 19), (8, 18, 20), + (9, 18, 23), (9, 17, 24), (10, 17, 25), (11, 18, 25), + (12, 19, 25), (10, 19, 26), (10, 19, 28), (9, 18, 27), + (9, 18, 25), (9, 18, 23), (10, 19, 25), (11, 20, 27), + (13, 21, 28), (16, 23, 29), (22, 32, 31), (35, 48, 38), + (58, 66, 51), (64, 71, 59), (71, 77, 67), (72, 78, 66), + (73, 79, 65), (70, 91, 60), (62, 81, 61), (61, 76, 53), + (68, 74, 60), (65, 66, 68), (56, 65, 61), (48, 64, 54), + (33, 51, 39), (29, 43, 30), (23, 36, 29), (22, 30, 33), + (21, 34, 25), (22, 36, 29), (23, 38, 33), (25, 36, 37), + (28, 35, 41), (33, 23, 58), (33, 25, 64), (46, 39, 55), + (56, 57, 49), (49, 72, 52), (50, 73, 50), (51, 74, 48), + (56, 76, 51), (56, 80, 54), (53, 77, 53), (55, 68, 59), + (74, 71, 80), (64, 63, 107), (54, 55, 135), (55, 54, 140), + (57, 54, 145), (59, 60, 150), (81, 62, 152), (90, 65, 156), + (96, 66, 156), (86, 57, 149), (77, 52, 144), (68, 47, 140), + (85, 22, 126), (80, 18, 119), (79, 19, 119), (59, 37, 86), + (50, 60, 49), (47, 59, 47), (44, 58, 45), (36, 47, 43), + (35, 50, 43), (42, 60, 44), (45, 64, 42), (56, 71, 50), + (71, 78, 60), (80, 80, 90), (76, 63, 114), (73, 46, 139), + (80, 54, 145), (80, 57, 148), (58, 63, 154), (57, 62, 153), + (70, 60, 149), (76, 61, 149), (83, 63, 150), (100, 105, 99), + (126, 102, 98), (144, 100, 97), (145, 114, 94), (143, 105, 102), + (139, 103, 103), (130, 43, 147), (128, 43, 147), (114, 52, 135), + (79, 70, 91), (69, 65, 82), (65, 55, 80), (50, 34, 79), + (29, 22, 73), (41, 25, 96), (54, 28, 119), (55, 38, 132), + (50, 45, 135), (46, 37, 130), (55, 32, 123), (57, 45, 81), + (46, 42, 69), (41, 42, 46), (21, 34, 25), (18, 29, 23), + (13, 23, 22), (14, 21, 27), (9, 19, 21), (11, 16, 22), + (11, 16, 22), (9, 18, 23), (8, 17, 26), (10, 19, 26), + (12, 19, 27), (15, 20, 26), (17, 25, 28), (25, 36, 32), + (36, 47, 39), (51, 69, 47), (62, 82, 57), (73, 80, 73), + (74, 78, 77), (87, 87, 85), (81, 77, 91), (86, 34, 134), + (86, 49, 144), (82, 57, 148), (85, 65, 152), (84, 65, 154), + (77, 56, 147), (56, 49, 142), (54, 45, 138), (51, 40, 134), + (76, 22, 120), (86, 21, 123), (92, 23, 129), (98, 27, 133), + (99, 49, 144), (107, 73, 157), (86, 74, 160), (85, 76, 159), + (77, 71, 157), (65, 65, 153), (55, 59, 150), (57, 57, 147), + (77, 56, 147), (82, 62, 151), (92, 55, 148), (116, 48, 147), + (123, 45, 147), (110, 65, 150), (117, 83, 160), (100, 92, 167), + (105, 104, 174), (106, 111, 179), (100, 104, 177), (97, 90, 167), + (85, 86, 166), (75, 75, 161), (65, 74, 151), (83, 91, 93), + (83, 94, 80), (75, 85, 77), (65, 90, 61), (74, 89, 66) + ), + +// 87 cl-yellow_mixed-brown-gold +((193, 128, 100), (245, 177, 128), (248, 183, 128), (251, 189, 128), + (253, 209, 137), (255, 230, 146), (255, 232, 144), (255, 235, 142), + (252, 255, 170), (251, 255, 185), (251, 255, 200), (253, 255, 225), + (255, 255, 250), (255, 255, 252), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 223), (255, 255, 196), (255, 255, 170), + (251, 253, 162), (248, 252, 155), (247, 251, 148), (247, 251, 141), + (255, 243, 89), (255, 217, 74), (255, 192, 60), (240, 167, 85), + (225, 142, 110), (223, 143, 114), (221, 144, 118), (225, 160, 130), + (232, 166, 134), (241, 177, 131), (240, 176, 137), (240, 175, 143), + (231, 168, 140), (223, 161, 138), (214, 154, 134), (206, 147, 131), + (139, 112, 129), (130, 104, 123), (122, 97, 118), (118, 99, 119), + (115, 102, 120), (113, 103, 121), (111, 104, 122), (95, 96, 126), + (90, 93, 126), (73, 87, 124), (41, 62, 97), (9, 38, 70), + (21, 26, 42), (34, 14, 15), (46, 21, 20), (58, 29, 25), + (132, 66, 44), (144, 78, 54), (157, 90, 64), (176, 104, 75), + (195, 119, 87), (192, 120, 92), (189, 121, 98), (153, 118, 125), + (136, 109, 126), (98, 94, 127), (85, 90, 126), (72, 86, 125), + (41, 70, 112), (10, 54, 99), (12, 34, 57), (63, 29, 27), + (140, 79, 61), (160, 94, 73), (180, 110, 85), (192, 120, 94), + (204, 130, 103), (210, 134, 108), (216, 139, 113), (223, 145, 109), + (241, 156, 102), (249, 177, 95), (242, 160, 87), (236, 144, 79), + (225, 137, 84), (215, 130, 89), (213, 128, 89), (225, 142, 112), + (211, 138, 119), (189, 132, 121), (167, 126, 124), (160, 121, 125), + (153, 117, 127), (156, 120, 124), (176, 109, 83), (206, 117, 61), + (220, 161, 33), (255, 222, 65), (255, 235, 100), (255, 248, 136), + (255, 251, 139), (255, 255, 143), (251, 248, 143), (255, 230, 140), + (215, 153, 130), (182, 135, 129), (150, 117, 128), (139, 112, 125), + (128, 107, 122), (107, 101, 129), (94, 95, 126), (87, 90, 125), + (83, 89, 125), (71, 85, 124), (44, 68, 106), (17, 51, 89), + (17, 26, 35), (16, 7, 8), (13, 2, 8), (26, 7, 1), + (78, 47, 27), (104, 59, 35), (131, 71, 43), (144, 76, 47), + (157, 82, 51), (164, 89, 47), (171, 90, 45), (175, 99, 65), + (205, 119, 72), (200, 132, 109), (180, 126, 116), (161, 120, 124), + (144, 108, 120), (138, 88, 77), (123, 61, 46), (77, 39, 36), + (32, 11, 10), (37, 10, 8), (43, 9, 7), (49, 20, 20), + (56, 31, 34), (120, 71, 56), (128, 79, 65), (167, 130, 124), + (211, 149, 124), (254, 238, 142), (253, 246, 161), (253, 255, 180), + (255, 255, 232), (255, 254, 242), (251, 250, 245), (244, 247, 220), + (255, 236, 141), (251, 227, 125), (247, 219, 110), (241, 158, 104), + (214, 124, 72), (182, 99, 47), (172, 85, 32), (162, 74, 11), + (172, 81, 0), (98, 28, 0), (93, 30, 6), (88, 33, 12), + (73, 29, 18), (45, 35, 36), (38, 68, 104), (74, 86, 124), + (76, 89, 124), (77, 89, 124), (79, 89, 125), (79, 89, 124), + (76, 89, 124), (76, 89, 124), (79, 87, 124), (80, 88, 124), + (80, 88, 124), (79, 89, 125), (82, 90, 126), (84, 90, 124), + (85, 89, 126), (100, 97, 124), (111, 80, 60), (115, 104, 118), + (135, 116, 135), (143, 119, 136), (151, 123, 137), (179, 135, 132), + (222, 162, 136), (246, 185, 131), (250, 233, 103), (255, 239, 104), + (255, 255, 125), (255, 255, 144), (254, 255, 157), (255, 255, 169), + (255, 253, 162), (255, 255, 157), (255, 255, 142), (255, 255, 128), + (255, 255, 109), (255, 254, 108), (254, 251, 122), (254, 255, 133), + (255, 252, 140), (255, 253, 143), (255, 255, 152), (252, 255, 154), + (250, 254, 143), (255, 255, 129), (255, 250, 120), (254, 245, 118), + (255, 241, 100), (255, 240, 90), (243, 198, 53), (228, 201, 52), + (201, 131, 105), (165, 123, 125), (138, 113, 132), (131, 113, 129), + (127, 108, 127), (132, 109, 125), (134, 110, 126), (134, 110, 124), + (122, 103, 125), (118, 104, 127), (115, 101, 126), (113, 102, 119), + (109, 99, 126), (102, 103, 124), (109, 101, 124), (115, 103, 127), + (120, 104, 130), (128, 109, 128), (136, 115, 122), (151, 117, 131), + (165, 122, 129), (191, 132, 126), (201, 139, 128), (224, 145, 115), + (213, 139, 110), (201, 124, 96), (169, 105, 80), (160, 84, 52), + (133, 60, 27), (91, 40, 21), (91, 43, 29), (98, 71, 52), + (87, 90, 123), (89, 94, 126), (96, 106, 133), (115, 105, 130), + (135, 112, 130), (155, 122, 131), (240, 176, 138), (202, 146, 133) + ), + +// 88 cl-dark_reds-white-grays +((127, 40, 23), (48, 7, 15), (26, 4, 13), (5, 2, 11), + (2, 1, 11), (0, 0, 12), (0, 2, 12), (0, 5, 13), + (9, 8, 16), (42, 13, 14), (76, 19, 12), (87, 19, 7), + (98, 19, 2), (78, 18, 8), (58, 17, 15), (46, 15, 14), + (35, 14, 13), (52, 38, 35), (75, 29, 21), (99, 21, 8), + (99, 20, 5), (100, 19, 2), (99, 19, 1), (98, 20, 0), + (98, 21, 1), (99, 19, 0), (101, 18, 0), (101, 18, 0), + (101, 18, 0), (101, 18, 0), (101, 18, 0), (101, 18, 0), + (100, 19, 2), (100, 21, 4), (102, 23, 7), (105, 26, 11), + (100, 34, 29), (95, 43, 47), (89, 48, 50), (83, 53, 53), + (75, 66, 71), (74, 66, 72), (73, 66, 73), (71, 62, 70), + (69, 59, 68), (64, 58, 67), (59, 58, 66), (52, 50, 61), + (50, 50, 62), (46, 45, 53), (49, 48, 55), (52, 51, 57), + (62, 51, 55), (72, 52, 53), (79, 49, 49), (87, 47, 45), + (103, 25, 12), (101, 30, 27), (100, 35, 43), (82, 38, 47), + (65, 42, 52), (56, 43, 51), (47, 44, 51), (40, 41, 46), + (52, 45, 39), (96, 19, 9), (98, 20, 6), (100, 21, 4), + (100, 21, 4), (100, 21, 4), (91, 24, 7), (71, 28, 22), + (34, 34, 42), (45, 45, 52), (57, 56, 62), (68, 63, 67), + (79, 70, 73), (84, 72, 75), (90, 74, 77), (106, 81, 76), + (117, 83, 82), (151, 85, 69), (171, 83, 60), (191, 82, 51), + (186, 77, 47), (182, 73, 44), (176, 84, 59), (155, 74, 53), + (138, 61, 45), (134, 41, 22), (130, 22, 0), (121, 23, 2), + (112, 24, 4), (104, 21, 3), (103, 17, 2), (102, 19, 5), + (108, 23, 3), (110, 24, 9), (136, 42, 23), (162, 60, 37), + (172, 72, 46), (182, 84, 55), (213, 116, 74), (243, 243, 243), + (255, 255, 255), (255, 255, 251), (255, 255, 248), (253, 252, 241), + (252, 250, 235), (225, 119, 79), (178, 88, 79), (147, 73, 70), + (110, 72, 69), (90, 65, 68), (85, 58, 60), (80, 51, 53), + (84, 35, 28), (102, 24, 12), (102, 20, 8), (99, 22, 6), + (52, 8, 7), (30, 4, 6), (8, 0, 6), (6, 0, 6), + (5, 0, 7), (6, 0, 6), (27, 1, 10), (58, 13, 10), + (96, 26, 14), (129, 62, 45), (122, 64, 51), (116, 66, 57), + (106, 71, 67), (110, 80, 80), (104, 85, 89), (90, 83, 91), + (100, 79, 86), (104, 79, 82), (108, 80, 79), (109, 81, 79), + (111, 83, 79), (137, 63, 64), (149, 61, 49), (148, 59, 45), + (154, 51, 36), (113, 25, 11), (110, 23, 11), (108, 21, 11), + (106, 27, 12), (120, 46, 37), (110, 56, 56), (101, 63, 74), + (83, 53, 53), (88, 48, 46), (94, 43, 40), (95, 28, 12), + (103, 26, 10), (101, 22, 7), (97, 21, 7), (71, 27, 28), + (58, 46, 46), (58, 52, 56), (60, 52, 55), (63, 53, 54), + (65, 54, 58), (75, 55, 54), (90, 56, 54), (110, 46, 44), + (105, 28, 12), (103, 25, 10), (102, 23, 8), (101, 22, 7), + (103, 24, 9), (104, 26, 14), (91, 57, 55), (88, 73, 68), + (80, 68, 72), (77, 65, 69), (77, 54, 60), (78, 38, 49), + (94, 25, 18), (100, 21, 6), (100, 21, 4), (101, 18, 0), + (101, 18, 0), (101, 18, 0), (101, 18, 0), (101, 18, 0), + (101, 18, 0), (101, 18, 0), (101, 18, 0), (101, 18, 0), + (101, 18, 0), (99, 20, 3), (100, 21, 6), (100, 21, 6), + (101, 24, 8), (105, 28, 12), (116, 39, 29), (109, 64, 59), + (111, 77, 78), (124, 94, 92), (168, 97, 77), (173, 96, 76), + (179, 93, 68), (169, 81, 61), (154, 68, 53), (131, 64, 56), + (107, 73, 71), (91, 71, 70), (81, 64, 72), (76, 56, 57), + (77, 57, 56), (75, 54, 53), (76, 47, 43), (94, 30, 18), + (100, 23, 7), (100, 23, 5), (100, 21, 6), (101, 22, 7), + (102, 22, 11), (106, 27, 12), (128, 51, 33), (147, 59, 39), + (149, 66, 48), (136, 79, 68), (114, 82, 83), (95, 80, 87), + (76, 74, 79), (61, 65, 76), (64, 62, 73), (65, 63, 68), + (59, 58, 64), (53, 58, 64), (53, 57, 68), (55, 52, 71), + (65, 56, 77), (71, 68, 75), (83, 70, 77), (103, 83, 84), + (124, 105, 101), (160, 131, 127), (252, 253, 248), (255, 255, 255), + (255, 255, 255), (255, 254, 249), (255, 250, 247), (226, 120, 81), + (184, 90, 64), (154, 63, 44), (143, 56, 39), (119, 42, 26), + (106, 28, 15), (98, 33, 31), (84, 68, 69), (90, 56, 54) + ), + +// 89 cl-gold-dark_reds-browns-blues +((239, 141, 112), (255, 189, 150), (255, 204, 147), (255, 219, 145), + (255, 235, 160), (255, 252, 175), (254, 253, 179), (254, 254, 184), + (255, 226, 146), (255, 216, 141), (255, 206, 137), (255, 201, 135), + (255, 197, 134), (252, 181, 131), (250, 166, 129), (248, 163, 123), + (247, 160, 117), (160, 97, 106), (130, 70, 80), (100, 44, 55), + (75, 36, 44), (51, 28, 34), (48, 25, 38), (45, 22, 42), + (25, 20, 40), (23, 23, 50), (21, 27, 61), (23, 28, 68), + (26, 30, 75), (28, 31, 77), (30, 32, 80), (29, 32, 83), + (28, 32, 79), (28, 32, 69), (25, 29, 65), (23, 27, 62), + (23, 26, 59), (23, 26, 57), (23, 27, 58), (23, 28, 60), + (33, 36, 81), (54, 46, 83), (75, 56, 86), (118, 75, 97), + (161, 95, 109), (163, 95, 108), (166, 96, 107), (172, 100, 112), + (174, 92, 96), (135, 52, 60), (108, 39, 49), (82, 26, 39), + (79, 27, 37), (76, 29, 35), (75, 25, 32), (74, 21, 29), + (52, 30, 43), (38, 30, 52), (25, 30, 62), (25, 29, 63), + (26, 29, 64), (24, 28, 63), (23, 27, 62), (18, 26, 65), + (18, 26, 63), (24, 26, 49), (32, 31, 48), (40, 37, 48), + (47, 36, 46), (55, 35, 44), (59, 33, 44), (64, 36, 51), + (73, 34, 63), (88, 48, 72), (104, 63, 81), (132, 67, 77), + (161, 71, 73), (165, 72, 69), (170, 73, 66), (162, 60, 56), + (118, 47, 55), (38, 37, 79), (32, 34, 81), (26, 32, 84), + (25, 30, 79), (25, 29, 74), (24, 29, 67), (21, 27, 59), + (15, 20, 49), (18, 24, 45), (22, 28, 42), (27, 29, 43), + (33, 31, 44), (52, 28, 42), (79, 21, 36), (86, 21, 19), + (115, 20, 18), (191, 83, 80), (219, 100, 98), (248, 118, 116), + (235, 108, 120), (222, 98, 124), (156, 84, 106), (111, 57, 71), + (76, 36, 63), (99, 45, 61), (123, 54, 59), (150, 62, 64), + (178, 70, 70), (208, 101, 95), (250, 114, 102), (254, 124, 111), + (253, 123, 109), (177, 93, 93), (149, 76, 80), (122, 59, 67), + (83, 38, 45), (79, 31, 43), (72, 33, 60), (67, 44, 60), + (55, 40, 61), (46, 39, 68), (38, 38, 76), (38, 38, 80), + (38, 39, 85), (36, 38, 89), (33, 36, 91), (32, 35, 86), + (33, 37, 85), (31, 36, 78), (33, 34, 75), (35, 33, 72), + (32, 29, 56), (28, 23, 45), (39, 20, 40), (41, 13, 27), + (24, 20, 34), (22, 22, 39), (20, 25, 44), (19, 24, 46), + (19, 23, 48), (19, 23, 48), (22, 28, 52), (19, 27, 63), + (21, 26, 68), (29, 32, 67), (31, 31, 63), (33, 30, 59), + (50, 42, 55), (62, 34, 57), (65, 38, 55), (57, 33, 47), + (48, 22, 35), (46, 18, 30), (45, 15, 25), (40, 12, 26), + (39, 16, 24), (28, 12, 22), (19, 21, 36), (19, 21, 42), + (18, 20, 45), (25, 24, 40), (32, 22, 38), (39, 21, 37), + (55, 24, 30), (71, 25, 36), (71, 29, 41), (74, 34, 43), + (53, 49, 64), (50, 45, 58), (47, 41, 53), (31, 31, 55), + (26, 28, 51), (31, 33, 46), (39, 33, 47), (47, 26, 41), + (47, 24, 34), (41, 20, 27), (35, 19, 29), (24, 21, 32), + (18, 19, 39), (15, 22, 41), (17, 22, 42), (18, 23, 42), + (20, 27, 46), (24, 28, 48), (28, 29, 50), (48, 34, 51), + (67, 33, 66), (82, 39, 69), (117, 47, 58), (136, 62, 77), + (184, 105, 111), (246, 145, 115), (255, 164, 120), (254, 194, 132), + (255, 198, 134), (255, 183, 128), (242, 153, 123), (176, 111, 119), + (152, 91, 106), (106, 66, 101), (83, 52, 67), (73, 45, 57), + (76, 47, 65), (96, 60, 86), (115, 68, 100), (150, 88, 111), + (177, 100, 106), (200, 110, 99), (254, 119, 115), (246, 146, 114), + (250, 158, 119), (248, 150, 113), (242, 148, 112), (185, 109, 113), + (135, 82, 102), (97, 66, 74), (75, 51, 64), (59, 48, 64), + (38, 38, 76), (36, 38, 89), (30, 35, 90), (26, 34, 96), + (24, 32, 94), (25, 34, 89), (29, 34, 89), (24, 31, 86), + (27, 34, 78), (27, 31, 68), (30, 31, 62), (25, 22, 49), + (22, 18, 35), (22, 10, 20), (14, 4, 12), (25, 4, 13), + (27, 10, 18), (39, 13, 22), (50, 19, 27), (46, 13, 32), + (57, 19, 44), (55, 28, 45), (49, 25, 47), (38, 25, 42), + (28, 25, 42), (32, 20, 40), (35, 14, 23), (36, 13, 21), + (29, 9, 20), (23, 10, 20), (35, 9, 20), (40, 13, 20), + (62, 12, 13), (97, 17, 20), (143, 50, 43), (187, 99, 95) + ), + +// 90 cl-golds-browns +((128, 84, 13), (140, 92, 16), (148, 99, 18), (157, 107, 20), + (169, 121, 29), (182, 136, 38), (190, 144, 34), (199, 153, 31), + (194, 144, 31), (185, 128, 26), (177, 112, 22), (179, 109, 19), + (182, 107, 16), (182, 109, 18), (183, 112, 20), (180, 113, 20), + (177, 114, 21), (194, 146, 38), (189, 132, 31), (184, 118, 24), + (178, 114, 23), (172, 110, 23), (172, 109, 19), (172, 109, 16), + (171, 109, 8), (164, 104, 12), (157, 99, 17), (150, 97, 14), + (144, 96, 12), (145, 98, 12), (146, 100, 12), (158, 112, 16), + (165, 121, 14), (167, 111, 18), (156, 100, 18), (146, 89, 18), + (132, 82, 17), (118, 76, 16), (110, 72, 15), (103, 68, 14), + (90, 59, 15), (100, 63, 12), (110, 68, 10), (114, 73, 13), + (119, 78, 16), (120, 79, 17), (121, 80, 18), (124, 79, 20), + (126, 80, 18), (136, 82, 22), (132, 86, 27), (129, 90, 33), + (123, 84, 31), (117, 79, 30), (110, 74, 27), (103, 70, 25), + (84, 55, 13), (82, 53, 8), (80, 52, 4), (79, 50, 6), + (78, 49, 9), (81, 50, 10), (84, 52, 11), (88, 57, 13), + (95, 59, 11), (113, 73, 14), (115, 74, 13), (117, 76, 12), + (117, 75, 13), (117, 75, 15), (117, 77, 16), (110, 73, 20), + (117, 73, 28), (123, 78, 26), (129, 83, 24), (140, 90, 21), + (151, 98, 18), (160, 100, 18), (169, 103, 19), (175, 110, 20), + (178, 108, 22), (184, 114, 18), (190, 129, 23), (197, 144, 28), + (198, 148, 31), (200, 153, 35), (199, 153, 41), (180, 179, 161), + (135, 98, 45), (127, 87, 34), (120, 77, 24), (115, 73, 22), + (110, 70, 21), (100, 66, 18), (98, 64, 18), (107, 70, 17), + (117, 77, 16), (140, 91, 14), (146, 98, 17), (152, 106, 20), + (155, 109, 19), (159, 113, 19), (155, 105, 18), (152, 99, 19), + (139, 95, 30), (132, 88, 24), (126, 82, 19), (121, 76, 17), + (116, 71, 16), (97, 56, 12), (91, 54, 12), (89, 54, 16), + (91, 58, 15), (108, 66, 16), (106, 66, 15), (104, 67, 14), + (103, 68, 14), (94, 64, 14), (89, 58, 14), (81, 53, 13), + (71, 47, 11), (70, 46, 13), (70, 45, 15), (72, 48, 14), + (74, 52, 13), (81, 57, 21), (84, 56, 19), (79, 53, 16), + (71, 49, 12), (69, 47, 10), (70, 47, 8), (72, 47, 6), + (80, 51, 7), (86, 55, 8), (106, 65, 9), (123, 74, 15), + (142, 89, 23), (140, 89, 27), (139, 90, 31), (134, 91, 38), + (130, 92, 45), (112, 83, 43), (113, 81, 34), (102, 72, 22), + (103, 70, 19), (110, 66, 19), (111, 69, 18), (113, 72, 18), + (118, 76, 16), (123, 77, 17), (126, 81, 16), (129, 84, 17), + (135, 93, 21), (137, 91, 20), (140, 90, 19), (136, 88, 16), + (128, 80, 16), (122, 76, 14), (114, 72, 14), (106, 69, 16), + (100, 66, 18), (95, 60, 20), (97, 60, 21), (100, 61, 22), + (109, 62, 20), (103, 66, 13), (94, 60, 12), (85, 53, 15), + (77, 47, 9), (76, 46, 7), (75, 46, 6), (73, 44, 10), + (71, 42, 8), (67, 43, 9), (68, 44, 8), (68, 44, 6), + (71, 43, 6), (69, 42, 0), (62, 39, 5), (65, 40, 9), + (61, 42, 25), (67, 44, 12), (67, 44, 10), (65, 42, 8), + (68, 44, 10), (70, 45, 10), (72, 46, 11), (80, 51, 9), + (92, 55, 11), (102, 65, 12), (114, 74, 13), (122, 81, 15), + (131, 83, 17), (134, 83, 18), (133, 86, 16), (132, 85, 15), + (133, 79, 15), (129, 79, 16), (126, 81, 16), (126, 81, 16), + (123, 77, 17), (126, 76, 15), (124, 75, 16), (119, 74, 15), + (118, 71, 15), (118, 69, 10), (116, 74, 14), (114, 74, 15), + (114, 74, 13), (113, 75, 12), (110, 69, 3), (103, 66, 11), + (94, 58, 8), (87, 54, 11), (81, 52, 10), (76, 48, 8), + (69, 45, 9), (68, 44, 8), (72, 44, 7), (73, 43, 5), + (73, 45, 6), (77, 45, 6), (76, 47, 7), (81, 52, 8), + (87, 52, 10), (86, 55, 11), (92, 62, 12), (106, 69, 14), + (117, 75, 15), (127, 82, 15), (141, 92, 15), (160, 91, 0), + (163, 102, 9), (172, 108, 18), (163, 111, 27), (146, 100, 40), + (139, 93, 44), (106, 82, 48), (100, 75, 34), (103, 76, 31), + (120, 84, 26), (124, 82, 22), (129, 84, 17), (134, 87, 17), + (135, 87, 15), (135, 87, 15), (133, 88, 7), (132, 86, 8), + (126, 76, 13), (125, 71, 7), (121, 67, 0), (127, 73, 9), + (144, 92, 16), (166, 104, 19), (203, 159, 38), (180, 131, 28) + ), + +// 91 cl-purples-browns-blues-tans +((61, 49, 73), (49, 40, 83), (54, 44, 81), (59, 48, 80), + (54, 43, 72), (49, 39, 64), (49, 36, 62), (50, 34, 61), + (45, 30, 51), (55, 40, 62), (65, 50, 73), (73, 51, 83), + (81, 53, 94), (78, 58, 96), (75, 64, 98), (81, 64, 94), + (87, 64, 90), (67, 51, 77), (75, 48, 73), (84, 46, 69), + (93, 58, 67), (103, 70, 65), (107, 73, 67), (111, 76, 70), + (124, 82, 86), (122, 88, 94), (121, 94, 103), (130, 95, 101), + (139, 97, 99), (147, 101, 103), (155, 105, 108), (172, 112, 111), + (187, 112, 107), (203, 130, 124), (205, 128, 109), (207, 127, 94), + (213, 134, 106), (220, 142, 119), (209, 137, 124), (198, 133, 129), + (154, 86, 101), (121, 72, 97), (88, 58, 94), (66, 42, 67), + (45, 27, 41), (33, 20, 33), (22, 14, 25), (8, 6, 11), + (1, 0, 0), (0, 0, 0), (8, 6, 11), (16, 13, 22), + (38, 28, 46), (60, 44, 71), (67, 51, 86), (75, 58, 102), + (109, 81, 132), (107, 76, 121), (106, 71, 111), (101, 69, 108), + (97, 67, 105), (98, 70, 104), (99, 74, 103), (109, 84, 90), + (118, 84, 85), (139, 93, 96), (145, 94, 95), (152, 96, 95), + (153, 96, 94), (155, 97, 93), (161, 91, 83), (161, 102, 88), + (159, 103, 104), (153, 108, 126), (147, 113, 148), (145, 102, 145), + (144, 91, 143), (150, 91, 126), (156, 92, 109), (152, 100, 102), + (157, 103, 101), (147, 98, 94), (137, 90, 86), (127, 82, 79), + (121, 78, 74), (115, 74, 70), (112, 61, 40), (85, 49, 49), + (64, 44, 79), (73, 50, 91), (82, 56, 104), (85, 61, 103), + (89, 67, 103), (117, 88, 106), (137, 99, 110), (138, 89, 145), + (152, 108, 159), (158, 108, 171), (169, 115, 179), (181, 122, 188), + (188, 128, 196), (195, 134, 204), (197, 138, 202), (196, 136, 198), + (186, 141, 161), (154, 104, 126), (122, 68, 92), (112, 61, 81), + (102, 54, 70), (67, 41, 68), (49, 33, 60), (36, 21, 42), + (33, 24, 41), (50, 31, 53), (62, 37, 60), (75, 43, 67), + (90, 68, 70), (107, 56, 75), (109, 59, 88), (121, 79, 80), + (151, 86, 66), (167, 93, 58), (183, 100, 50), (175, 99, 60), + (168, 99, 70), (172, 110, 99), (182, 117, 141), (191, 134, 166), + (211, 152, 172), (200, 132, 153), (204, 137, 149), (208, 142, 146), + (219, 158, 166), (232, 165, 174), (244, 199, 204), (246, 198, 212), + (255, 255, 255), (249, 254, 222), (243, 253, 190), (246, 240, 173), + (250, 227, 157), (222, 220, 231), (248, 190, 228), (209, 144, 210), + (178, 118, 178), (148, 105, 114), (142, 100, 109), (136, 96, 104), + (132, 95, 102), (137, 99, 110), (151, 100, 105), (155, 105, 108), + (195, 135, 137), (200, 138, 140), (206, 142, 143), (204, 150, 150), + (207, 142, 138), (199, 139, 139), (178, 129, 135), (158, 110, 108), + (134, 102, 107), (136, 89, 97), (137, 89, 91), (139, 90, 85), + (138, 88, 77), (137, 89, 75), (133, 89, 78), (124, 82, 84), + (121, 80, 78), (118, 80, 79), (116, 80, 80), (112, 77, 73), + (110, 79, 76), (105, 78, 85), (94, 73, 104), (97, 70, 105), + (103, 67, 93), (107, 82, 88), (109, 76, 67), (107, 74, 65), + (97, 71, 72), (91, 69, 72), (96, 73, 83), (93, 70, 98), + (126, 96, 106), (144, 105, 113), (162, 115, 121), (191, 138, 156), + (219, 143, 153), (242, 167, 161), (242, 214, 131), (241, 189, 103), + (209, 145, 136), (187, 113, 112), (149, 94, 91), (111, 75, 75), + (77, 55, 57), (59, 46, 40), (54, 35, 39), (36, 23, 40), + (26, 19, 27), (17, 15, 18), (11, 8, 17), (13, 10, 19), + (22, 11, 25), (50, 24, 35), (57, 31, 42), (65, 39, 64), + (74, 46, 69), (67, 41, 68), (63, 40, 69), (67, 48, 67), + (73, 52, 69), (78, 53, 74), (79, 53, 78), (93, 67, 70), + (92, 66, 65), (106, 55, 72), (93, 65, 80), (83, 60, 86), + (73, 52, 71), (55, 38, 56), (46, 33, 42), (48, 27, 44), + (53, 27, 40), (49, 26, 44), (42, 24, 38), (39, 24, 45), + (40, 32, 47), (38, 24, 41), (37, 22, 43), (33, 18, 39), + (24, 14, 25), (23, 14, 15), (23, 13, 22), (21, 18, 27), + (31, 20, 34), (47, 31, 58), (53, 37, 64), (63, 45, 83), + (72, 56, 105), (75, 58, 110), (85, 60, 118), (87, 65, 114), + (78, 59, 105), (72, 49, 93), (75, 47, 87), (64, 48, 74), + (56, 38, 54), (36, 22, 37), (26, 18, 33), (3, 16, 33), + (19, 16, 27), (26, 18, 33), (46, 28, 50), (63, 39, 71) + ), + +// 92 cl-oranges-browns-whites +((255, 147, 57), (255, 123, 61), (254, 126, 61), (254, 129, 62), + (254, 135, 61), (255, 142, 61), (255, 155, 59), (255, 169, 58), + (253, 185, 60), (254, 183, 57), (255, 182, 55), (255, 172, 53), + (255, 163, 52), (254, 161, 55), (253, 159, 59), (253, 160, 58), + (253, 162, 57), (255, 182, 54), (255, 205, 59), (255, 229, 64), + (255, 241, 89), (255, 254, 115), (255, 246, 108), (255, 238, 101), + (254, 185, 58), (254, 163, 56), (255, 141, 55), (255, 129, 57), + (255, 118, 59), (255, 115, 59), (255, 112, 59), (255, 106, 63), + (255, 109, 62), (254, 120, 67), (254, 122, 64), (255, 125, 61), + (254, 122, 58), (253, 120, 55), (254, 124, 56), (255, 128, 57), + (254, 131, 61), (254, 142, 60), (255, 154, 59), (255, 142, 57), + (255, 131, 55), (255, 129, 55), (255, 127, 55), (253, 127, 53), + (250, 152, 43), (255, 190, 54), (255, 214, 75), (255, 239, 97), + (255, 245, 103), (255, 251, 109), (253, 251, 88), (252, 252, 68), + (255, 208, 61), (255, 192, 57), (255, 177, 53), (253, 154, 51), + (251, 132, 50), (250, 123, 53), (250, 115, 57), (244, 103, 57), + (229, 93, 55), (202, 81, 60), (184, 76, 61), (166, 72, 62), + (170, 74, 59), (175, 76, 57), (196, 79, 59), (213, 86, 54), + (241, 103, 56), (245, 105, 58), (249, 107, 61), (242, 101, 60), + (236, 96, 60), (228, 94, 59), (220, 93, 58), (207, 86, 55), + (193, 74, 50), (177, 75, 52), (188, 77, 55), (199, 80, 58), + (209, 86, 57), (219, 92, 57), (235, 103, 54), (252, 119, 52), + (248, 202, 65), (249, 228, 131), (251, 254, 197), (253, 253, 208), + (255, 253, 219), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 246), (255, 255, 232), (255, 255, 218), + (255, 255, 215), (255, 255, 212), (255, 255, 209), (255, 251, 164), + (254, 190, 66), (254, 159, 61), (255, 128, 57), (253, 123, 53), + (252, 119, 50), (255, 114, 42), (254, 115, 50), (254, 108, 57), + (254, 106, 58), (254, 108, 61), (251, 110, 63), (248, 113, 65), + (250, 116, 65), (251, 115, 67), (244, 105, 66), (234, 94, 58), + (212, 87, 57), (192, 79, 56), (173, 71, 56), (163, 70, 57), + (153, 69, 59), (149, 64, 61), (159, 71, 59), (168, 72, 48), + (189, 81, 55), (212, 82, 56), (216, 83, 56), (220, 85, 56), + (222, 92, 56), (234, 94, 59), (242, 96, 57), (239, 102, 58), + (211, 86, 54), (196, 75, 49), (182, 65, 45), (175, 61, 42), + (169, 58, 39), (154, 57, 48), (143, 58, 51), (137, 60, 52), + (137, 65, 51), (166, 75, 57), (175, 82, 58), (185, 90, 60), + (187, 178, 61), (241, 255, 144), (255, 255, 167), (255, 255, 152), + (253, 196, 67), (254, 183, 62), (255, 171, 58), (254, 137, 58), + (248, 114, 61), (238, 100, 64), (219, 92, 60), (203, 82, 51), + (191, 71, 46), (174, 53, 26), (172, 52, 28), (170, 51, 31), + (168, 56, 36), (168, 59, 38), (154, 57, 40), (154, 57, 38), + (132, 44, 32), (129, 49, 36), (126, 54, 40), (136, 65, 43), + (144, 62, 48), (158, 67, 48), (167, 66, 48), (180, 81, 50), + (209, 86, 55), (227, 93, 55), (245, 104, 58), (253, 105, 59), + (255, 109, 58), (255, 115, 56), (252, 116, 54), (253, 117, 55), + (255, 117, 58), (255, 115, 58), (255, 114, 58), (254, 108, 57), + (255, 104, 57), (246, 104, 58), (240, 103, 51), (253, 102, 49), + (247, 111, 51), (247, 112, 44), (248, 123, 39), (255, 156, 47), + (253, 174, 56), (255, 188, 58), (254, 207, 59), (254, 232, 61), + (255, 254, 61), (255, 236, 65), (255, 227, 64), (255, 212, 64), + (255, 191, 61), (255, 182, 54), (240, 171, 34), (221, 168, 36), + (238, 124, 28), (255, 118, 40), (247, 108, 53), (242, 104, 55), + (230, 94, 56), (218, 87, 59), (194, 80, 56), (166, 70, 45), + (137, 63, 50), (127, 63, 61), (117, 67, 60), (106, 52, 66), + (117, 64, 56), (120, 64, 51), (121, 71, 46), (120, 63, 52), + (112, 60, 49), (106, 60, 47), (97, 44, 36), (112, 58, 48), + (117, 62, 42), (129, 62, 53), (155, 62, 45), (174, 57, 39), + (192, 61, 33), (204, 70, 41), (214, 74, 39), (220, 83, 47), + (214, 83, 55), (207, 71, 47), (207, 72, 43), (184, 67, 47), + (178, 60, 46), (156, 69, 52), (143, 69, 60), (132, 69, 64), + (127, 74, 70), (139, 82, 115), (191, 103, 89), (210, 86, 58), + (216, 89, 54), (228, 92, 54), (242, 87, 41), (247, 95, 46), + (253, 92, 48), (237, 86, 59), (223, 89, 60), (195, 78, 58) + ), + +// 93 cl-blues-greens-whites +((255, 255, 255), (190, 208, 248), (163, 186, 237), (136, 164, 227), + (132, 159, 220), (128, 154, 213), (126, 151, 213), (124, 149, 213), + (112, 145, 212), (109, 136, 196), (106, 127, 180), (97, 113, 156), + (89, 100, 132), (94, 98, 108), (100, 96, 85), (99, 102, 82), + (99, 108, 79), (89, 89, 53), (85, 86, 29), (82, 83, 5), + (76, 79, 8), (70, 76, 12), (60, 72, 8), (50, 69, 5), + (44, 59, 0), (41, 59, 5), (38, 60, 11), (51, 67, 35), + (64, 75, 59), (68, 73, 68), (72, 71, 77), (70, 68, 71), + (69, 72, 53), (64, 71, 37), (59, 66, 49), (55, 61, 61), + (38, 48, 67), (21, 35, 74), (28, 41, 79), (35, 47, 85), + (72, 77, 106), (65, 70, 87), (58, 63, 69), (52, 63, 45), + (47, 64, 22), (45, 63, 13), (43, 63, 4), (41, 62, 5), + (43, 61, 13), (73, 82, 55), (82, 86, 63), (91, 90, 72), + (93, 93, 79), (96, 96, 86), (98, 99, 78), (101, 102, 71), + (85, 83, 62), (76, 74, 70), (68, 66, 79), (75, 75, 67), + (82, 85, 56), (81, 86, 51), (81, 88, 46), (78, 77, 31), + (80, 88, 51), (91, 91, 99), (89, 95, 121), (87, 100, 144), + (91, 106, 151), (96, 113, 159), (121, 137, 188), (160, 169, 208), + (232, 239, 249), (243, 247, 252), (255, 255, 255), (232, 243, 255), + (210, 231, 255), (200, 212, 242), (190, 194, 229), (161, 175, 212), + (159, 164, 196), (143, 157, 196), (149, 163, 200), (155, 169, 204), + (151, 162, 199), (147, 156, 195), (139, 153, 192), (117, 135, 175), + (91, 91, 103), (81, 85, 65), (71, 80, 27), (69, 79, 21), + (67, 79, 15), (55, 73, 21), (70, 81, 39), (85, 95, 61), + (109, 109, 85), (101, 111, 147), (100, 116, 164), (100, 122, 182), + (98, 120, 178), (97, 118, 175), (89, 110, 167), (87, 106, 149), + (58, 72, 111), (43, 59, 98), (28, 46, 86), (28, 44, 84), + (29, 43, 82), (27, 45, 85), (36, 53, 99), (47, 64, 110), + (48, 64, 115), (27, 45, 85), (27, 45, 85), (27, 45, 85), + (41, 58, 104), (55, 71, 122), (66, 88, 148), (85, 107, 167), + (124, 149, 213), (134, 159, 221), (144, 170, 229), (149, 175, 234), + (154, 180, 239), (160, 186, 245), (155, 184, 242), (140, 174, 235), + (141, 170, 228), (163, 173, 198), (169, 177, 203), (176, 182, 208), + (174, 179, 211), (157, 170, 212), (139, 151, 189), (106, 122, 173), + (105, 105, 95), (96, 96, 101), (87, 88, 108), (82, 87, 120), + (78, 86, 132), (75, 91, 142), (70, 97, 166), (76, 103, 174), + (80, 110, 182), (92, 125, 202), (95, 129, 203), (99, 133, 204), + (104, 129, 196), (104, 129, 196), (106, 130, 192), (107, 132, 189), + (99, 118, 158), (95, 114, 155), (91, 110, 153), (87, 95, 108), + (104, 103, 98), (119, 118, 90), (116, 124, 83), (126, 128, 106), + (123, 118, 114), (80, 93, 135), (77, 91, 138), (74, 90, 141), + (64, 81, 127), (51, 67, 118), (41, 57, 108), (35, 52, 98), + (53, 52, 66), (54, 53, 64), (56, 55, 63), (65, 63, 76), + (79, 78, 83), (90, 85, 81), (82, 77, 83), (77, 75, 97), + (74, 83, 122), (77, 94, 138), (80, 96, 147), (78, 98, 159), + (64, 89, 153), (65, 86, 143), (63, 79, 130), (58, 67, 110), + (25, 37, 59), (28, 40, 61), (31, 44, 63), (50, 59, 76), + (75, 83, 106), (87, 101, 136), (102, 116, 155), (116, 130, 169), + (118, 135, 179), (132, 149, 193), (150, 168, 208), (151, 168, 212), + (145, 167, 216), (132, 153, 206), (126, 147, 200), (116, 132, 183), + (117, 134, 180), (115, 132, 178), (107, 128, 185), (100, 120, 181), + (96, 116, 177), (80, 106, 180), (81, 105, 175), (80, 105, 172), + (76, 103, 174), (80, 104, 174), (80, 106, 180), (83, 116, 187), + (103, 125, 185), (112, 134, 194), (117, 142, 198), (128, 147, 190), + (132, 150, 190), (129, 151, 200), (131, 151, 204), (124, 146, 206), + (109, 137, 210), (112, 138, 199), (108, 134, 193), (107, 129, 189), + (101, 123, 183), (95, 116, 173), (85, 106, 169), (77, 102, 166), + (75, 102, 171), (65, 92, 161), (63, 88, 152), (67, 89, 149), + (60, 81, 138), (54, 71, 115), (50, 67, 113), (57, 74, 120), + (73, 91, 131), (71, 93, 153), (81, 103, 163), (108, 124, 175), + (119, 135, 186), (140, 157, 203), (160, 172, 210), (181, 186, 215), + (188, 199, 229), (189, 205, 241), (183, 200, 244), (169, 192, 236), + (173, 190, 234), (172, 186, 223), (184, 195, 225), (189, 196, 214), + (188, 199, 229), (206, 212, 234), (220, 227, 243), (227, 231, 243) + ), + +// 94 cl-tans-yellows-browns +((168, 139, 109), (159, 147, 135), (162, 151, 141), (166, 156, 147), + (170, 164, 158), (174, 173, 169), (178, 177, 176), (182, 182, 184), + (199, 198, 196), (211, 208, 207), (223, 219, 218), (235, 234, 228), + (247, 249, 238), (238, 236, 229), (229, 224, 221), (221, 216, 213), + (214, 209, 206), (196, 185, 183), (196, 187, 180), (197, 189, 178), + (202, 193, 185), (207, 198, 193), (216, 203, 190), (225, 208, 188), + (229, 210, 180), (238, 210, 165), (247, 211, 151), (247, 211, 139), + (247, 212, 128), (236, 205, 130), (226, 198, 133), (230, 191, 136), + (224, 198, 141), (205, 191, 165), (221, 205, 180), (238, 220, 196), + (243, 230, 201), (249, 240, 207), (245, 238, 206), (242, 237, 205), + (229, 215, 202), (215, 202, 187), (202, 189, 173), (193, 184, 166), + (184, 179, 160), (181, 176, 165), (179, 174, 170), (178, 173, 169), + (177, 173, 170), (179, 164, 157), (181, 165, 151), (183, 166, 146), + (180, 164, 149), (177, 163, 152), (175, 163, 153), (173, 164, 155), + (184, 179, 176), (192, 187, 183), (200, 195, 191), (216, 206, 194), + (233, 218, 197), (237, 222, 197), (241, 226, 197), (251, 235, 183), + (253, 236, 182), (250, 250, 138), (251, 251, 135), (253, 253, 133), + (253, 253, 132), (253, 253, 131), (252, 252, 130), (252, 252, 120), + (252, 230, 129), (242, 211, 128), (233, 192, 128), (222, 178, 124), + (212, 165, 121), (224, 170, 120), (237, 176, 119), (247, 195, 112), + (247, 213, 123), (227, 217, 164), (213, 200, 163), (199, 184, 163), + (198, 180, 163), (198, 176, 163), (183, 169, 158), (168, 161, 155), + (160, 150, 149), (161, 155, 152), (163, 160, 155), (165, 161, 156), + (168, 163, 157), (173, 171, 172), (187, 183, 182), (199, 198, 196), + (213, 209, 206), (244, 226, 204), (246, 221, 177), (248, 217, 150), + (249, 213, 148), (250, 209, 147), (241, 179, 128), (202, 160, 118), + (184, 163, 136), (180, 156, 134), (176, 150, 133), (175, 150, 129), + (174, 150, 126), (170, 153, 135), (163, 151, 139), (151, 146, 140), + (149, 140, 131), (125, 112, 103), (120, 111, 86), (116, 111, 69), + (111, 97, 84), (109, 102, 96), (122, 114, 103), (150, 144, 128), + (193, 178, 159), (224, 198, 157), (255, 218, 155), (253, 216, 146), + (251, 215, 137), (251, 225, 141), (255, 247, 130), (253, 253, 139), + (253, 251, 148), (244, 223, 180), (238, 220, 180), (232, 218, 181), + (227, 210, 184), (226, 204, 180), (203, 197, 183), (196, 184, 172), + (194, 167, 156), (189, 170, 164), (185, 174, 172), (185, 176, 174), + (186, 178, 176), (181, 177, 178), (186, 182, 179), (190, 180, 171), + (187, 177, 168), (181, 171, 161), (180, 168, 159), (179, 166, 158), + (176, 161, 154), (179, 159, 148), (177, 161, 145), (177, 156, 137), + (169, 151, 131), (171, 159, 129), (173, 168, 128), (173, 164, 107), + (175, 153, 103), (182, 144, 107), (185, 149, 113), (183, 154, 124), + (182, 164, 140), (192, 183, 176), (194, 187, 181), (197, 192, 186), + (206, 192, 189), (208, 195, 187), (223, 204, 174), (217, 192, 135), + (177, 148, 106), (151, 128, 101), (125, 109, 96), (118, 104, 93), + (123, 111, 99), (125, 122, 113), (146, 137, 132), (172, 147, 125), + (198, 151, 107), (208, 163, 124), (235, 189, 114), (249, 203, 105), + (251, 217, 110), (249, 231, 107), (252, 241, 113), (250, 215, 115), + (255, 230, 156), (253, 230, 166), (252, 231, 176), (250, 229, 174), + (247, 219, 156), (251, 222, 142), (253, 242, 126), (248, 247, 129), + (255, 228, 147), (239, 233, 171), (229, 222, 176), (213, 194, 177), + (204, 186, 172), (189, 181, 168), (181, 166, 163), (173, 162, 160), + (174, 164, 155), (174, 161, 153), (174, 162, 150), (168, 156, 142), + (159, 145, 142), (158, 145, 139), (151, 147, 144), (161, 147, 147), + (168, 158, 156), (181, 172, 167), (187, 178, 171), (193, 184, 169), + (198, 185, 168), (206, 190, 174), (202, 195, 176), (201, 191, 181), + (198, 188, 179), (199, 187, 173), (197, 184, 176), (196, 185, 181), + (193, 182, 178), (188, 183, 179), (189, 184, 180), (193, 184, 179), + (192, 187, 183), (193, 190, 183), (196, 192, 189), (198, 193, 190), + (197, 196, 192), (199, 199, 199), (200, 199, 197), (204, 199, 195), + (209, 200, 193), (226, 209, 189), (229, 215, 178), (233, 214, 184), + (230, 208, 195), (217, 208, 203), (210, 205, 201), (204, 200, 199), + (211, 210, 205), (220, 217, 208), (225, 224, 222), (225, 224, 222), + (225, 220, 217), (217, 217, 207), (208, 203, 199), (201, 192, 187), + (187, 183, 180), (182, 172, 170), (171, 167, 164), (169, 159, 157), + (170, 159, 155), (169, 154, 149), (166, 152, 139), (165, 148, 130) + ), + +// 95 cl-golds-browns2 +((166, 81, 24), (131, 73, 25), (126, 72, 30), (121, 71, 36), + (122, 73, 41), (123, 76, 46), (122, 81, 47), (122, 87, 49), + (155, 86, 44), (155, 87, 40), (156, 89, 37), (148, 82, 29), + (140, 75, 21), (136, 72, 14), (133, 69, 7), (130, 66, 8), + (128, 63, 9), (125, 64, 19), (129, 70, 26), (134, 77, 34), + (153, 84, 36), (173, 92, 39), (183, 93, 37), (194, 95, 36), + (208, 109, 42), (222, 114, 45), (236, 119, 49), (233, 122, 60), + (230, 126, 71), (226, 124, 70), (223, 122, 70), (214, 130, 93), + (201, 127, 92), (177, 121, 96), (155, 108, 91), (133, 96, 87), + (137, 95, 78), (142, 95, 69), (137, 93, 64), (133, 92, 60), + (156, 86, 35), (156, 82, 34), (156, 79, 33), (158, 78, 28), + (161, 78, 24), (160, 79, 24), (159, 80, 24), (149, 77, 27), + (147, 77, 17), (162, 78, 18), (176, 88, 19), (191, 98, 20), + (211, 105, 31), (231, 113, 43), (233, 117, 47), (235, 122, 52), + (255, 137, 57), (255, 148, 73), (255, 159, 90), (255, 206, 120), + (255, 254, 151), (255, 254, 168), (255, 255, 185), (255, 254, 207), + (254, 255, 195), (255, 248, 143), (255, 204, 108), (255, 161, 73), + (255, 160, 73), (255, 159, 74), (253, 154, 71), (255, 145, 70), + (226, 115, 43), (195, 103, 40), (165, 92, 37), (147, 83, 35), + (130, 75, 34), (126, 72, 33), (122, 70, 33), (108, 67, 35), + (103, 68, 46), (107, 72, 53), (109, 72, 51), (111, 73, 50), + (114, 72, 43), (117, 71, 37), (118, 72, 38), (122, 77, 48), + (116, 82, 70), (120, 82, 67), (124, 83, 65), (127, 81, 56), + (130, 80, 47), (144, 83, 39), (159, 87, 37), (164, 87, 31), + (172, 87, 32), (190, 88, 22), (209, 95, 29), (228, 103, 36), + (233, 108, 38), (238, 114, 40), (254, 127, 46), (251, 132, 52), + (253, 129, 57), (251, 123, 63), (250, 118, 69), (249, 121, 60), + (248, 124, 52), (255, 116, 47), (254, 113, 44), (255, 115, 43), + (254, 120, 49), (255, 138, 54), (255, 136, 55), (255, 135, 57), + (253, 134, 66), (254, 130, 68), (253, 137, 80), (255, 137, 87), + (241, 134, 78), (235, 124, 73), (229, 114, 69), (221, 116, 68), + (214, 118, 68), (194, 113, 60), (161, 107, 60), (153, 101, 64), + (149, 102, 60), (153, 90, 47), (147, 86, 45), (142, 83, 43), + (127, 77, 42), (116, 70, 34), (111, 65, 32), (103, 64, 33), + (109, 63, 27), (109, 62, 23), (110, 61, 20), (109, 60, 19), + (108, 59, 18), (99, 54, 12), (85, 49, 15), (99, 60, 29), + (103, 64, 23), (111, 82, 42), (119, 86, 47), (128, 90, 53), + (147, 96, 49), (178, 102, 53), (192, 121, 75), (209, 128, 83), + (182, 104, 56), (179, 102, 53), (176, 100, 51), (172, 98, 49), + (178, 107, 55), (195, 124, 78), (211, 133, 97), (215, 139, 107), + (254, 160, 99), (254, 187, 98), (254, 178, 92), (255, 169, 86), + (255, 163, 79), (248, 158, 62), (248, 136, 64), (231, 128, 59), + (200, 106, 44), (192, 103, 43), (185, 100, 43), (165, 93, 53), + (161, 90, 46), (157, 90, 47), (156, 90, 42), (160, 94, 44), + (164, 97, 42), (177, 97, 44), (179, 97, 49), (184, 97, 52), + (173, 96, 52), (168, 96, 46), (162, 90, 40), (153, 92, 37), + (147, 87, 50), (151, 92, 52), (156, 97, 55), (169, 100, 67), + (186, 106, 81), (199, 114, 93), (195, 129, 95), (198, 130, 93), + (203, 129, 92), (222, 121, 65), (219, 117, 53), (213, 110, 44), + (204, 108, 48), (200, 111, 51), (202, 109, 48), (182, 99, 33), + (173, 89, 25), (167, 88, 21), (164, 84, 23), (156, 79, 25), + (148, 78, 27), (145, 78, 23), (145, 78, 26), (141, 77, 29), + (135, 79, 32), (139, 81, 35), (133, 78, 39), (125, 73, 36), + (114, 68, 32), (107, 67, 31), (104, 63, 31), (104, 63, 31), + (106, 66, 31), (115, 65, 28), (115, 66, 25), (112, 62, 25), + (114, 64, 27), (118, 72, 20), (123, 73, 22), (126, 72, 28), + (124, 73, 30), (128, 75, 35), (131, 77, 41), (133, 79, 43), + (129, 82, 38), (127, 80, 36), (122, 70, 33), (114, 64, 29), + (118, 69, 28), (125, 74, 21), (127, 74, 20), (137, 71, 19), + (144, 79, 23), (159, 88, 36), (189, 103, 52), (217, 128, 60), + (254, 154, 92), (255, 178, 112), (254, 218, 132), (255, 210, 125), + (255, 192, 95), (255, 154, 88), (234, 135, 70), (208, 115, 54), + (189, 108, 43), (178, 97, 34), (159, 92, 37), (146, 90, 41), + (132, 93, 54), (126, 94, 56), (127, 86, 64), (133, 87, 61) + ), + +// 96 cl-pastels +((236, 206, 176), (231, 206, 174), (229, 206, 173), (227, 206, 172), + (224, 205, 171), (222, 205, 170), (221, 205, 169), (220, 205, 169), + (215, 205, 167), (212, 205, 166), (210, 205, 165), (207, 204, 164), + (205, 204, 163), (203, 204, 162), (201, 204, 161), (199, 204, 160), + (198, 204, 160), (193, 203, 158), (195, 202, 160), (197, 201, 163), + (199, 200, 165), (201, 200, 168), (202, 199, 169), (203, 199, 170), + (207, 198, 175), (209, 197, 177), (211, 196, 180), (213, 195, 182), + (215, 195, 184), (216, 194, 185), (217, 194, 187), (219, 193, 189), + (221, 192, 192), (225, 191, 196), (227, 190, 199), (230, 189, 202), + (226, 191, 205), (223, 193, 208), (221, 194, 209), (220, 195, 211), + (212, 199, 216), (209, 201, 219), (206, 203, 222), (202, 205, 225), + (198, 207, 228), (196, 208, 229), (195, 209, 231), (192, 211, 234), + (188, 213, 237), (181, 217, 243), (177, 219, 245), (174, 221, 248), + (170, 223, 251), (166, 226, 255), (168, 225, 253), (170, 225, 251), + (177, 223, 242), (181, 222, 237), (185, 221, 233), (189, 219, 229), + (193, 218, 225), (195, 217, 222), (197, 217, 220), (200, 216, 216), + (204, 215, 212), (212, 213, 203), (216, 212, 199), (220, 211, 195), + (221, 210, 192), (223, 210, 190), (227, 208, 186), (231, 207, 182), + (236, 206, 176), (236, 205, 177), (236, 204, 179), (235, 203, 180), + (235, 202, 182), (235, 201, 182), (235, 201, 183), (234, 200, 185), + (234, 199, 186), (233, 197, 189), (233, 196, 190), (233, 195, 192), + (232, 195, 192), (232, 195, 193), (232, 194, 194), (232, 193, 196), + (231, 191, 199), (230, 190, 200), (230, 189, 202), (229, 189, 201), + (228, 190, 200), (226, 190, 197), (224, 191, 195), (222, 192, 192), + (220, 193, 190), (216, 194, 185), (214, 195, 182), (212, 196, 180), + (211, 196, 179), (210, 197, 178), (208, 197, 176), (206, 198, 173), + (202, 200, 168), (200, 200, 166), (198, 201, 164), (197, 201, 162), + (196, 202, 161), (193, 203, 158), (195, 203, 160), (197, 202, 163), + (199, 201, 165), (203, 199, 170), (204, 199, 171), (205, 199, 172), + (207, 198, 175), (209, 197, 177), (211, 196, 180), (213, 196, 182), + (217, 194, 187), (219, 193, 189), (221, 193, 192), (222, 192, 193), + (223, 192, 194), (225, 191, 196), (227, 190, 199), (230, 189, 202), + (226, 191, 205), (220, 195, 211), (218, 196, 212), (216, 197, 214), + (212, 199, 216), (209, 201, 219), (206, 203, 222), (202, 205, 225), + (195, 209, 231), (191, 211, 234), (188, 213, 237), (186, 214, 238), + (184, 215, 240), (181, 217, 243), (178, 219, 245), (174, 221, 248), + (170, 223, 251), (166, 226, 255), (166, 225, 252), (167, 225, 250), + (169, 223, 244), (170, 222, 239), (172, 221, 234), (173, 220, 228), + (176, 217, 218), (177, 216, 215), (178, 216, 213), (179, 215, 207), + (181, 213, 202), (182, 212, 197), (184, 211, 191), (185, 210, 186), + (187, 208, 181), (190, 206, 170), (190, 205, 167), (191, 205, 165), + (193, 203, 158), (195, 203, 159), (198, 203, 160), (200, 203, 161), + (205, 203, 163), (206, 203, 163), (207, 204, 164), (209, 204, 165), + (212, 204, 166), (214, 204, 167), (217, 204, 168), (219, 204, 169), + (221, 205, 170), (224, 205, 171), (226, 205, 172), (228, 205, 173), + (231, 205, 174), (233, 205, 175), (236, 206, 176), (232, 207, 180), + (225, 209, 189), (223, 209, 191), (221, 210, 193), (217, 211, 198), + (213, 213, 202), (209, 214, 206), (205, 215, 211), (202, 216, 215), + (198, 217, 219), (194, 218, 224), (190, 219, 228), (186, 220, 232), + (182, 221, 236), (179, 222, 241), (175, 224, 245), (171, 225, 249), + (167, 226, 254), (166, 226, 255), (167, 225, 250), (169, 223, 244), + (170, 222, 239), (172, 221, 234), (173, 220, 228), (175, 218, 223), + (176, 217, 218), (178, 216, 213), (179, 215, 207), (181, 213, 202), + (182, 212, 197), (184, 211, 191), (185, 210, 186), (187, 208, 181), + (188, 207, 175), (190, 206, 170), (191, 205, 165), (193, 203, 158), + (195, 202, 160), (197, 202, 163), (199, 201, 165), (201, 200, 168), + (203, 199, 170), (205, 198, 172), (207, 198, 175), (209, 197, 177), + (211, 196, 180), (213, 195, 182), (215, 195, 184), (217, 194, 187), + (219, 193, 189), (221, 192, 192), (223, 192, 194), (225, 191, 196), + (227, 190, 199), (230, 189, 202), (230, 190, 201), (230, 191, 199), + (231, 192, 198), (231, 192, 196), (231, 193, 195), (232, 194, 193), + (232, 195, 192), (232, 196, 191), (233, 197, 189), (233, 198, 188), + (233, 199, 186), (234, 200, 185), (234, 201, 184), (234, 202, 182), + (235, 203, 181), (235, 204, 179), (235, 205, 178), (236, 206, 176) + ), + + +// 97 multi_color_1 from ron1.ugr (classylady & ron) +((255, 0, 0), (173, 0, 55), (118, 0, 91), (64, 0, 128), + (50, 55, 155), (36, 110, 183), (29, 137, 196), (23, 164, 210), + (0, 255, 255), (0, 255, 200), (0, 255, 145), (0, 255, 72), + (0, 255, 0), (55, 255, 27), (110, 255, 55), (137, 255, 68), + (164, 255, 82), (255, 255, 128), (255, 227, 155), (255, 200, 183), + (255, 173, 210), (255, 146, 237), (255, 137, 246), (255, 128, 255), + (145, 128, 228), (72, 128, 210), (0, 128, 192), (27, 100, 151), + (55, 73, 110), (68, 59, 89), (82, 46, 68), (110, 18, 27), + (128, 0, 0), (183, 55, 55), (210, 82, 82), (237, 110, 110), + (218, 132, 119), (200, 155, 128), (172, 169, 128), (145, 183, 128), + (0, 255, 128), (55, 227, 114), (110, 200, 100), (164, 173, 86), + (219, 146, 73), (237, 137, 68), (255, 128, 64), (200, 155, 50), + (145, 183, 36), (36, 237, 9), (18, 225, 18), (0, 214, 28), + (0, 173, 55), (0, 132, 82), (0, 98, 105), (0, 64, 128), + (55, 92, 183), (82, 105, 210), (110, 119, 237), (119, 109, 225), + (128, 100, 214), (128, 86, 193), (128, 73, 173), (128, 46, 132), + (128, 18, 91), (155, 0, 78), (182, 0, 91), (210, 0, 105), + (232, 0, 116), (255, 0, 128), (255, 28, 100), (255, 55, 73), + (255, 110, 18), (227, 119, 9), (200, 128, 0), (145, 128, 0), + (91, 128, 0), (63, 128, 0), (36, 128, 0), (0, 128, 0), + (0, 128, 14), (0, 128, 41), (0, 114, 73), (0, 100, 105), + (0, 86, 125), (0, 73, 146), (0, 46, 187), (0, 18, 228), + (0, 0, 235), (0, 0, 214), (0, 0, 194), (0, 0, 183), + (0, 0, 173), (0, 0, 160), (28, 0, 153), (55, 0, 146), + (82, 0, 139), (128, 0, 155), (128, 0, 182), (128, 0, 210), + (128, 0, 223), (128, 0, 237), (128, 0, 255), (128, 28, 200), + (128, 82, 91), (128, 105, 45), (128, 128, 0), (128, 128, 7), + (128, 128, 14), (128, 128, 28), (128, 128, 41), (128, 128, 64), + (155, 128, 105), (210, 128, 187), (223, 128, 207), (237, 128, 228), + (255, 128, 255), (228, 155, 200), (200, 183, 145), (173, 210, 91), + (128, 255, 0), (155, 255, 0), (183, 255, 0), (196, 255, 0), + (210, 255, 0), (255, 255, 0), (200, 228, 28), (145, 200, 55), + (91, 173, 82), (0, 128, 128), (27, 114, 114), (55, 100, 100), + (110, 73, 73), (164, 46, 46), (255, 0, 0), (255, 28, 14), + (255, 82, 41), (255, 105, 52), (255, 128, 64), (227, 141, 64), + (200, 155, 64), (145, 183, 64), (91, 210, 64), (36, 237, 64), + (0, 255, 64), (55, 200, 146), (68, 186, 166), (82, 173, 187), + (128, 128, 255), (155, 100, 228), (183, 73, 200), (210, 46, 173), + (255, 0, 128), (255, 14, 135), (255, 28, 142), (255, 55, 156), + (255, 82, 169), (255, 110, 183), (255, 128, 192), (200, 128, 178), + (145, 128, 164), (0, 128, 128), (14, 141, 141), (28, 155, 155), + (55, 183, 183), (82, 210, 210), (110, 237, 237), (128, 255, 255), + (128, 200, 200), (128, 186, 186), (128, 173, 173), (128, 146, 146), + (128, 128, 128), (100, 155, 100), (73, 183, 73), (46, 210, 46), + (0, 255, 0), (47, 245, 11), (95, 234, 21), (142, 224, 32), + (189, 214, 43), (220, 207, 50), (214, 175, 85), (209, 142, 120), + (198, 77, 191), (196, 66, 202), (194, 56, 214), (206, 91, 198), + (218, 125, 183), (230, 160, 167), (250, 217, 141), (238, 200, 113), + (227, 183, 84), (215, 167, 56), (204, 150, 28), (196, 139, 9), + (186, 159, 35), (176, 179, 61), (166, 199, 87), (156, 219, 113), + (150, 232, 130), (129, 214, 108), (107, 195, 86), (86, 177, 64), + (51, 147, 28), (87, 138, 72), (123, 129, 116), (159, 119, 159), + (195, 110, 203), (219, 104, 232), (210, 88, 224), (202, 72, 217), + (193, 56, 209), (185, 40, 201), (179, 30, 196), (171, 75, 206), + (163, 119, 216), (155, 164, 226), (141, 238, 243), (130, 233, 221), + (120, 229, 199), (109, 224, 177), (98, 220, 155), (91, 217, 141), + (120, 194, 122), (150, 171, 104), (179, 149, 85), (209, 126, 66), + (228, 111, 54), (223, 126, 59), (219, 141, 63), (214, 156, 68), + (207, 181, 75), (194, 184, 77), (180, 188, 80), (167, 191, 82), + (154, 195, 84), (145, 197, 86), (133, 196, 102), (121, 196, 118), + (108, 195, 134), (96, 195, 150), (88, 194, 160), (90, 184, 165), + (92, 174, 171), (94, 164, 176), (98, 148, 185), (100, 131, 192), + (102, 113, 198), (104, 96, 205), (107, 78, 212), (108, 67, 216), + (120, 72, 211), (132, 76, 206), (143, 81, 201), (163, 89, 193) + ), + +// 98 oranges +((255, 0, 0), (253, 10, 2), (251, 15, 3), (250, 20, 4), + (249, 25, 5), (248, 30, 6), (247, 32, 6), (247, 35, 7), + (244, 45, 8), (243, 50, 9), (242, 55, 10), (241, 60, 11), + (240, 65, 12), (238, 70, 13), (237, 75, 14), (236, 77, 14), + (236, 80, 14), (234, 90, 16), (232, 95, 17), (231, 100, 18), + (230, 105, 19), (229, 110, 20), (228, 112, 20), (228, 115, 21), + (225, 125, 22), (224, 130, 23), (223, 135, 24), (222, 140, 25), + (221, 145, 26), (220, 147, 26), (219, 150, 27), (218, 155, 28), + (217, 160, 28), (216, 157, 30), (216, 155, 31), (216, 154, 32), + (215, 152, 32), (215, 151, 33), (215, 150, 33), (215, 150, 34), + (214, 146, 36), (213, 145, 37), (213, 144, 38), (213, 142, 38), + (213, 140, 39), (212, 139, 39), (212, 139, 40), (212, 138, 41), + (212, 136, 42), (211, 133, 44), (210, 131, 44), (210, 130, 45), + (210, 128, 46), (210, 127, 47), (209, 126, 47), (209, 126, 48), + (209, 122, 49), (208, 121, 50), (208, 120, 51), (207, 118, 52), + (207, 116, 53), (207, 115, 53), (207, 115, 54), (206, 114, 55), + (206, 112, 55), (209, 113, 52), (210, 113, 50), (212, 114, 48), + (213, 114, 47), (214, 114, 46), (215, 115, 45), (217, 115, 43), + (220, 116, 40), (221, 116, 38), (223, 117, 36), (224, 117, 34), + (226, 118, 33), (226, 118, 32), (227, 119, 31), (229, 119, 29), + (230, 120, 28), (234, 121, 24), (235, 121, 22), (237, 122, 21), + (237, 122, 20), (238, 122, 19), (240, 123, 17), (241, 123, 15), + (244, 124, 12), (245, 124, 10), (247, 125, 9), (248, 125, 8), + (249, 126, 7), (250, 126, 5), (252, 127, 3), (253, 127, 2), + (255, 128, 0), (250, 126, 0), (247, 124, 0), (245, 123, 0), + (244, 122, 0), (243, 122, 0), (240, 120, 0), (238, 119, 0), + (233, 117, 0), (230, 115, 0), (228, 114, 0), (226, 113, 0), + (225, 113, 0), (223, 112, 0), (220, 110, 0), (218, 109, 0), + (216, 108, 0), (211, 106, 0), (209, 105, 0), (208, 104, 0), + (206, 103, 0), (203, 102, 0), (201, 100, 0), (198, 99, 0), + (193, 97, 0), (190, 95, 0), (188, 94, 0), (187, 93, 0), + (186, 93, 0), (183, 92, 0), (181, 90, 0), (178, 89, 0), + (176, 88, 0), (181, 95, 8), (182, 96, 10), (183, 98, 12), + (186, 101, 16), (188, 104, 21), (191, 108, 25), (193, 111, 29), + (198, 118, 37), (200, 121, 41), (203, 124, 45), (204, 125, 47), + (206, 127, 50), (208, 131, 54), (211, 134, 58), (213, 137, 62), + (216, 140, 66), (220, 147, 74), (221, 148, 76), (223, 150, 78), + (225, 154, 82), (228, 157, 87), (230, 160, 91), (233, 163, 95), + (238, 170, 103), (239, 171, 105), (240, 173, 107), (243, 177, 111), + (245, 180, 116), (248, 183, 120), (250, 186, 124), (253, 190, 128), + (255, 193, 132), (255, 186, 128), (255, 184, 127), (255, 182, 127), + (255, 178, 125), (255, 174, 123), (255, 171, 121), (255, 167, 119), + (255, 160, 116), (255, 158, 115), (255, 156, 114), (255, 152, 112), + (255, 148, 110), (255, 145, 108), (255, 141, 107), (255, 137, 105), + (255, 134, 103), (255, 130, 101), (255, 126, 99), (255, 122, 98), + (255, 119, 96), (255, 115, 94), (255, 111, 92), (255, 107, 90), + (255, 100, 87), (255, 98, 86), (255, 96, 85), (255, 93, 83), + (255, 89, 81), (255, 85, 79), (255, 81, 78), (255, 78, 76), + (255, 74, 74), (254, 77, 75), (252, 79, 76), (251, 82, 76), + (250, 84, 77), (248, 87, 78), (247, 90, 79), (245, 92, 79), + (244, 95, 80), (243, 97, 81), (241, 100, 81), (240, 103, 82), + (238, 105, 83), (237, 108, 84), (236, 110, 84), (234, 113, 85), + (233, 116, 86), (232, 118, 86), (230, 121, 87), (229, 123, 88), + (228, 126, 89), (226, 128, 89), (225, 131, 90), (223, 134, 91), + (222, 136, 91), (221, 139, 92), (219, 141, 93), (218, 144, 94), + (216, 147, 94), (215, 149, 95), (214, 152, 96), (212, 154, 96), + (211, 157, 97), (211, 158, 99), (212, 159, 100), (212, 160, 102), + (213, 161, 104), (213, 162, 105), (214, 163, 107), (214, 164, 108), + (214, 165, 110), (215, 166, 112), (215, 167, 113), (216, 168, 115), + (216, 169, 116), (217, 170, 118), (217, 171, 120), (218, 172, 121), + (218, 173, 123), (218, 174, 125), (219, 175, 126), (219, 176, 128), + (220, 177, 130), (220, 178, 131), (221, 179, 133), (221, 180, 134), + (221, 181, 136), (222, 182, 138), (222, 183, 139), (223, 184, 141), + (223, 185, 142), (224, 186, 144), (224, 187, 146), (225, 189, 149) + ), + +// 99 multi_color_2 +((255, 0, 0), (211, 22, 22), (189, 33, 33), (167, 44, 44), + (145, 55, 55), (124, 66, 66), (113, 71, 71), (102, 77, 77), + (58, 99, 99), (29, 113, 113), (0, 128, 128), (0, 139, 139), + (0, 150, 150), (0, 161, 161), (0, 172, 172), (0, 177, 177), + (0, 183, 183), (0, 204, 204), (0, 215, 215), (0, 226, 226), + (0, 237, 237), (0, 248, 248), (0, 251, 251), (0, 255, 255), + (44, 240, 255), (66, 232, 255), (88, 224, 255), (109, 216, 255), + (131, 209, 255), (142, 205, 255), (153, 201, 255), (175, 194, 255), + (197, 186, 255), (255, 166, 255), (233, 162, 255), (211, 159, 255), + (189, 156, 255), (167, 153, 255), (156, 151, 255), (145, 150, 255), + (102, 143, 255), (80, 140, 255), (58, 137, 255), (36, 133, 255), + (14, 130, 255), (7, 129, 255), (0, 128, 255), (11, 128, 255), + (22, 128, 255), (44, 128, 255), (55, 128, 255), (66, 128, 255), + (77, 128, 255), (88, 128, 255), (93, 128, 255), (99, 128, 255), + (121, 128, 255), (119, 133, 244), (117, 139, 233), (106, 150, 211), + (95, 161, 189), (89, 166, 178), (84, 172, 167), (73, 183, 145), + (62, 193, 124), (40, 215, 80), (29, 226, 58), (18, 237, 36), + (9, 246, 18), (0, 255, 0), (22, 233, 0), (44, 211, 0), + (88, 167, 0), (109, 145, 0), (131, 124, 0), (153, 102, 0), + (175, 80, 0), (186, 69, 0), (197, 58, 0), (219, 36, 0), + (241, 14, 0), (233, 11, 0), (211, 22, 0), (189, 33, 0), + (178, 38, 0), (167, 44, 0), (145, 55, 0), (124, 66, 0), + (80, 88, 0), (58, 99, 0), (36, 110, 0), (25, 115, 0), + (14, 121, 0), (0, 128, 0), (10, 117, 0), (20, 106, 0), + (30, 95, 0), (50, 73, 0), (60, 62, 0), (70, 51, 0), + (75, 45, 0), (80, 40, 0), (90, 29, 0), (101, 18, 0), + (129, 0, 0), (140, 0, 0), (152, 0, 0), (158, 0, 0), + (164, 0, 0), (175, 0, 0), (187, 0, 0), (199, 0, 0), + (210, 0, 0), (234, 0, 0), (240, 0, 0), (246, 0, 0), + (253, 0, 0), (242, 22, 11), (232, 44, 22), (221, 66, 33), + (199, 110, 55), (188, 131, 66), (178, 153, 77), (172, 164, 82), + (167, 175, 88), (156, 197, 99), (146, 219, 110), (135, 241, 121), + (128, 255, 128), (128, 233, 150), (128, 227, 155), (128, 222, 161), + (128, 211, 172), (128, 200, 183), (128, 190, 193), (128, 179, 204), + (128, 157, 226), (128, 142, 240), (128, 128, 255), (122, 128, 244), + (117, 128, 233), (106, 128, 211), (95, 128, 189), (84, 128, 167), + (73, 128, 145), (51, 128, 102), (45, 128, 91), (40, 128, 80), + (29, 128, 58), (18, 128, 36), (7, 128, 14), (0, 128, 0), + (44, 132, 26), (55, 132, 32), (66, 133, 38), (88, 135, 51), + (110, 137, 64), (131, 139, 77), (153, 141, 90), (175, 142, 102), + (197, 144, 115), (255, 149, 149), (255, 147, 147), (255, 146, 146), + (255, 144, 144), (255, 141, 141), (255, 139, 139), (255, 136, 136), + (255, 131, 131), (255, 129, 129), (255, 128, 128), (255, 126, 126), + (255, 123, 123), (255, 121, 121), (255, 119, 119), (255, 119, 131), + (255, 118, 142), (255, 118, 154), (255, 117, 166), (255, 117, 177), + (255, 116, 189), (255, 116, 201), (255, 115, 212), (255, 115, 224), + (255, 114, 248), (255, 113, 251), (255, 113, 255), (255, 107, 237), + (255, 101, 219), (255, 95, 201), (255, 90, 183), (255, 84, 165), + (255, 78, 147), (255, 72, 129), (255, 66, 111), (255, 60, 93), + (255, 55, 75), (255, 45, 45), (250, 41, 58), (246, 37, 72), + (241, 33, 85), (237, 30, 99), (232, 26, 112), (228, 22, 126), + (223, 18, 139), (219, 14, 153), (214, 10, 166), (209, 6, 180), + (205, 2, 193), (202, 0, 202), (204, 0, 185), (206, 0, 167), + (207, 0, 150), (209, 0, 133), (211, 0, 115), (213, 0, 98), + (215, 0, 80), (216, 0, 63), (218, 0, 46), (220, 0, 28), + (222, 0, 11), (223, 0, 0), (217, 12, 6), (212, 24, 12), + (206, 36, 19), (200, 47, 25), (195, 59, 31), (189, 71, 37), + (183, 83, 43), (178, 95, 50), (172, 107, 56), (166, 119, 62), + (157, 138, 72), (157, 126, 66), (158, 114, 60), (158, 102, 53), + (159, 91, 47), (160, 79, 41), (160, 67, 35), (161, 55, 29), + (161, 43, 22), (162, 31, 16), (163, 19, 10), (163, 8, 4), + (164, 0, 0), (160, 0, 0), (156, 0, 0), (152, 0, 0), + (148, 0, 0), (144, 0, 0), (140, 0, 0), (136, 0, 0), + (132, 0, 0), (128, 0, 0), (124, 0, 0), (117, 0, 0) + ), + +// 100 rw-yellow-orange +((255, 128, 0), (255, 134, 0), (255, 137, 0), (255, 140, 0), + (255, 143, 0), (255, 146, 0), (255, 147, 0), (255, 149, 0), + (255, 155, 0), (255, 158, 0), (255, 161, 0), (255, 164, 0), + (255, 167, 0), (255, 170, 0), (255, 173, 0), (255, 174, 0), + (255, 176, 0), (255, 182, 0), (255, 185, 0), (255, 188, 0), + (255, 190, 0), (255, 193, 0), (255, 194, 0), (255, 196, 0), + (255, 202, 0), (255, 205, 0), (255, 208, 0), (255, 211, 0), + (255, 214, 0), (255, 215, 0), (255, 217, 0), (255, 220, 0), + (255, 223, 0), (255, 229, 0), (255, 232, 0), (255, 235, 0), + (255, 238, 0), (255, 241, 0), (255, 242, 0), (255, 244, 0), + (255, 250, 0), (255, 251, 1), (255, 252, 2), (255, 249, 3), + (255, 246, 4), (255, 244, 5), (255, 243, 6), (255, 240, 8), + (255, 237, 9), (255, 231, 12), (255, 228, 13), (255, 225, 15), + (255, 222, 16), (255, 219, 18), (255, 217, 19), (255, 216, 20), + (255, 210, 22), (255, 207, 24), (255, 204, 26), (255, 201, 27), + (255, 198, 28), (255, 196, 29), (255, 195, 30), (255, 192, 32), + (255, 190, 33), (255, 184, 36), (255, 181, 37), (255, 178, 39), + (255, 176, 39), (255, 175, 40), (255, 172, 42), (255, 169, 44), + (255, 163, 46), (255, 160, 48), (255, 157, 50), (255, 154, 51), + (255, 151, 52), (255, 149, 53), (255, 148, 54), (255, 145, 56), + (255, 142, 57), (255, 136, 60), (255, 133, 61), (255, 130, 63), + (255, 129, 63), (255, 128, 64), (255, 131, 66), (255, 134, 67), + (255, 140, 70), (255, 143, 71), (255, 146, 73), (255, 147, 73), + (255, 149, 74), (255, 152, 76), (255, 155, 78), (255, 158, 79), + (255, 161, 80), (255, 167, 84), (255, 170, 85), (255, 173, 86), + (255, 174, 87), (255, 176, 88), (255, 179, 90), (255, 182, 91), + (255, 188, 94), (255, 190, 95), (255, 193, 97), (255, 194, 97), + (255, 196, 98), (255, 199, 100), (255, 202, 102), (255, 205, 103), + (255, 208, 104), (255, 214, 108), (255, 215, 108), (255, 217, 109), + (255, 220, 110), (255, 223, 112), (255, 226, 114), (255, 229, 115), + (255, 235, 118), (255, 238, 119), (255, 241, 121), (255, 242, 121), + (255, 244, 122), (255, 247, 124), (255, 250, 126), (255, 253, 127), + (255, 255, 128), (255, 251, 126), (255, 250, 125), (255, 249, 125), + (255, 247, 124), (255, 245, 123), (255, 243, 122), (255, 241, 121), + (255, 237, 119), (255, 235, 117), (255, 233, 116), (255, 232, 115), + (255, 231, 115), (255, 229, 114), (255, 227, 113), (255, 225, 112), + (255, 223, 111), (255, 219, 109), (255, 218, 108), (255, 217, 108), + (255, 215, 107), (255, 213, 106), (255, 211, 105), (255, 209, 104), + (255, 205, 102), (255, 204, 101), (255, 203, 101), (255, 201, 100), + (255, 199, 98), (255, 197, 97), (255, 195, 96), (255, 193, 95), + (255, 190, 94), (255, 186, 92), (255, 185, 91), (255, 184, 91), + (255, 182, 90), (255, 180, 89), (255, 178, 88), (255, 176, 87), + (255, 172, 85), (255, 170, 84), (255, 169, 83), (254, 170, 81), + (253, 171, 79), (252, 171, 77), (250, 172, 75), (249, 173, 73), + (248, 174, 71), (247, 175, 69), (246, 176, 67), (245, 177, 65), + (244, 177, 64), (242, 178, 62), (241, 179, 60), (240, 180, 58), + (238, 182, 54), (237, 182, 53), (237, 183, 52), (235, 184, 50), + (234, 184, 48), (233, 185, 46), (232, 186, 44), (231, 187, 42), + (230, 188, 40), (229, 189, 38), (227, 190, 36), (226, 190, 34), + (225, 191, 32), (224, 192, 30), (223, 193, 29), (222, 194, 27), + (221, 195, 25), (219, 196, 23), (218, 197, 21), (217, 197, 19), + (216, 198, 17), (215, 199, 15), (214, 200, 13), (213, 201, 11), + (211, 202, 9), (210, 203, 7), (209, 203, 5), (208, 204, 3), + (207, 205, 1), (206, 206, 0), (206, 203, 0), (206, 199, 0), + (206, 196, 0), (206, 193, 0), (205, 189, 0), (205, 186, 0), + (205, 183, 0), (205, 179, 0), (205, 176, 0), (205, 173, 0), + (204, 169, 0), (204, 166, 0), (204, 163, 0), (204, 159, 0), + (204, 156, 0), (203, 153, 0), (203, 149, 0), (203, 146, 0), + (203, 143, 0), (203, 139, 0), (202, 136, 0), (202, 133, 0), + (202, 129, 0), (202, 126, 0), (202, 123, 0), (202, 119, 0), + (201, 116, 0), (201, 113, 0), (201, 109, 0), (201, 106, 0), + (201, 103, 0), (200, 100, 0), (200, 96, 0), (200, 93, 0), + (200, 90, 0), (200, 86, 0), (199, 83, 0), (199, 80, 0), + (199, 76, 0), (199, 73, 0), (199, 70, 0), (198, 64, 0) + ), + +// 101 rw-multi-color-2 +((128, 64, 64), (153, 52, 52), (165, 45, 45), (178, 39, 39), + (190, 32, 32), (202, 26, 26), (208, 23, 23), (215, 20, 20), + (240, 8, 8), (247, 10, 4), (255, 12, 0), (255, 25, 0), + (255, 38, 0), (255, 50, 0), (255, 62, 0), (255, 68, 0), + (255, 75, 0), (255, 100, 0), (255, 114, 0), (255, 128, 0), + (242, 122, 0), (230, 116, 0), (224, 112, 0), (218, 109, 0), + (193, 97, 0), (180, 90, 0), (168, 84, 0), (155, 78, 0), + (143, 72, 0), (135, 68, 0), (128, 64, 0), (116, 70, 0), + (103, 76, 0), (78, 89, 0), (65, 95, 0), (53, 102, 0), + (40, 108, 0), (28, 114, 0), (22, 117, 0), (16, 120, 0), + (0, 128, 12), (0, 128, 25), (0, 128, 38), (0, 128, 50), + (0, 128, 62), (0, 128, 68), (0, 128, 75), (0, 128, 88), + (0, 128, 100), (0, 128, 125), (0, 134, 132), (0, 140, 140), + (0, 152, 152), (0, 165, 165), (0, 171, 171), (0, 178, 178), + (0, 202, 202), (0, 214, 214), (0, 227, 227), (0, 241, 241), + (0, 255, 255), (6, 255, 249), (12, 255, 243), (25, 255, 230), + (38, 255, 218), (62, 255, 193), (75, 255, 180), (88, 255, 168), + (94, 255, 162), (100, 255, 156), (112, 255, 143), (128, 255, 128), + (103, 255, 153), (90, 255, 165), (78, 255, 178), (65, 255, 190), + (53, 255, 202), (46, 255, 208), (40, 255, 215), (28, 255, 227), + (16, 255, 240), (0, 243, 255), (0, 230, 255), (0, 218, 255), + (0, 211, 255), (0, 205, 255), (0, 193, 255), (0, 181, 255), + (0, 156, 255), (0, 143, 255), (0, 131, 255), (0, 129, 255), + (0, 128, 255), (12, 128, 255), (25, 128, 255), (38, 128, 255), + (50, 128, 255), (75, 128, 255), (87, 128, 255), (100, 128, 255), + (106, 128, 255), (112, 128, 255), (128, 128, 255), (128, 116, 236), + (128, 90, 199), (128, 78, 180), (128, 66, 162), (128, 59, 152), + (128, 53, 143), (128, 40, 124), (128, 28, 106), (128, 16, 87), + (128, 0, 64), (153, 25, 89), (159, 31, 95), (165, 38, 102), + (178, 50, 114), (190, 62, 126), (202, 75, 139), (215, 88, 152), + (240, 112, 176), (247, 114, 181), (255, 116, 186), (255, 109, 183), + (255, 103, 180), (255, 90, 173), (255, 78, 167), (255, 66, 161), + (255, 53, 154), (255, 28, 142), (255, 22, 139), (255, 16, 136), + (255, 3, 130), (255, 0, 128), (243, 0, 140), (230, 0, 153), + (205, 0, 178), (193, 0, 190), (181, 0, 202), (174, 0, 208), + (168, 0, 215), (156, 0, 227), (143, 0, 240), (128, 0, 255), + (116, 12, 236), (90, 38, 199), (84, 44, 189), (78, 50, 180), + (66, 62, 162), (53, 75, 143), (40, 88, 124), (28, 100, 106), + (0, 128, 64), (12, 128, 64), (25, 128, 64), (50, 128, 64), + (75, 128, 64), (100, 128, 64), (125, 128, 64), (149, 128, 64), + (174, 128, 64), (224, 128, 64), (239, 128, 64), (255, 128, 64), + (243, 116, 58), (230, 103, 52), (218, 90, 45), (205, 78, 39), + (181, 53, 26), (174, 46, 23), (168, 40, 20), (156, 28, 14), + (143, 16, 8), (131, 3, 2), (128, 0, 0), (140, 25, 25), + (153, 50, 50), (165, 75, 75), (178, 100, 100), (190, 125, 125), + (202, 149, 149), (215, 174, 174), (227, 199, 199), (240, 224, 224), + (250, 250, 250), (247, 247, 247), (245, 245, 245), (241, 241, 241), + (236, 236, 236), (231, 231, 231), (226, 226, 226), (222, 222, 222), + (217, 217, 217), (212, 212, 212), (206, 206, 206), (186, 186, 211), + (166, 166, 216), (146, 146, 220), (126, 126, 225), (105, 105, 230), + (85, 85, 235), (65, 65, 239), (45, 45, 244), (25, 25, 249), + (0, 0, 255), (12, 6, 230), (25, 12, 205), (38, 19, 180), + (50, 25, 155), (62, 31, 130), (75, 38, 106), (88, 44, 81), + (100, 50, 56), (112, 56, 31), (125, 62, 6), (128, 64, 0), + (116, 70, 12), (103, 76, 25), (90, 83, 38), (78, 89, 50), + (66, 95, 62), (53, 102, 75), (40, 108, 88), (28, 114, 100), + (16, 120, 112), (0, 128, 128), (0, 128, 134), (0, 128, 140), + (0, 128, 147), (0, 128, 153), (0, 128, 159), (0, 128, 166), + (0, 128, 172), (0, 128, 178), (0, 128, 184), (0, 128, 192), + (25, 140, 173), (50, 153, 154), (75, 165, 136), (100, 178, 117), + (125, 190, 98), (149, 202, 80), (174, 215, 61), (199, 227, 42), + (224, 240, 23), (255, 255, 0), (255, 243, 12), (255, 230, 25), + (255, 218, 38), (255, 205, 50), (255, 193, 62), (255, 181, 75), + (255, 168, 88), (255, 156, 100), (255, 143, 112), (255, 128, 128) + ), + +// 102 rw-blue-with-red +((0, 0, 255), (0, 0, 243), (0, 0, 237), (0, 0, 231), + (0, 0, 225), (0, 0, 219), (0, 0, 216), (0, 0, 213), + (0, 0, 202), (0, 0, 196), (0, 0, 190), (0, 0, 184), + (0, 0, 178), (0, 0, 172), (0, 0, 166), (0, 0, 163), + (0, 0, 160), (16, 0, 172), (24, 0, 178), (32, 0, 184), + (40, 0, 190), (48, 0, 196), (52, 0, 199), (56, 0, 202), + (72, 0, 213), (80, 0, 219), (88, 0, 225), (96, 0, 231), + (104, 0, 237), (108, 0, 240), (112, 0, 243), (120, 0, 249), + (128, 0, 255), (128, 16, 255), (128, 24, 255), (128, 32, 255), + (128, 40, 255), (128, 48, 255), (128, 52, 255), (128, 56, 255), + (128, 72, 255), (128, 80, 255), (128, 88, 255), (128, 96, 255), + (128, 104, 255), (128, 108, 255), (128, 112, 255), (128, 120, 255), + (128, 128, 255), (112, 128, 247), (104, 128, 243), (96, 128, 239), + (88, 128, 235), (80, 128, 231), (76, 128, 229), (72, 128, 227), + (56, 128, 220), (48, 128, 216), (40, 128, 212), (32, 128, 208), + (24, 128, 204), (20, 128, 202), (16, 128, 200), (8, 128, 196), + (0, 128, 192), (0, 128, 200), (0, 128, 204), (0, 128, 208), + (0, 128, 210), (0, 128, 212), (0, 128, 216), (0, 128, 220), + (0, 128, 227), (0, 128, 231), (0, 128, 235), (0, 128, 239), + (0, 128, 243), (0, 128, 245), (0, 128, 247), (0, 128, 251), + (0, 128, 255), (16, 128, 247), (24, 128, 243), (32, 128, 239), + (36, 128, 237), (40, 128, 235), (48, 128, 231), (56, 128, 227), + (72, 128, 220), (80, 128, 216), (88, 128, 212), (92, 128, 210), + (96, 128, 208), (104, 128, 204), (112, 128, 200), (120, 128, 196), + (128, 128, 192), (144, 128, 192), (152, 128, 192), (160, 128, 192), + (164, 128, 192), (168, 128, 192), (176, 128, 192), (184, 128, 192), + (199, 128, 192), (207, 128, 192), (215, 128, 192), (219, 128, 192), + (223, 128, 192), (231, 128, 192), (239, 128, 192), (247, 128, 192), + (255, 128, 192), (255, 128, 200), (255, 128, 202), (255, 128, 204), + (255, 128, 208), (255, 128, 212), (255, 128, 216), (255, 128, 220), + (255, 128, 227), (255, 128, 231), (255, 128, 235), (255, 128, 237), + (255, 128, 239), (255, 128, 243), (255, 128, 247), (255, 128, 251), + (255, 128, 255), (255, 112, 255), (255, 108, 255), (255, 104, 255), + (255, 96, 255), (255, 88, 255), (255, 80, 255), (255, 72, 255), + (255, 56, 255), (255, 48, 255), (255, 40, 255), (255, 36, 255), + (255, 32, 255), (255, 24, 255), (255, 16, 255), (255, 8, 255), + (255, 0, 255), (255, 0, 239), (255, 0, 235), (255, 0, 231), + (255, 0, 223), (255, 0, 215), (255, 0, 207), (255, 0, 199), + (255, 0, 184), (255, 0, 180), (255, 0, 176), (255, 0, 168), + (255, 0, 160), (255, 0, 152), (255, 0, 144), (255, 0, 136), + (255, 0, 128), (223, 16, 144), (215, 20, 148), (207, 24, 152), + (191, 32, 160), (175, 40, 168), (159, 48, 176), (143, 56, 184), + (112, 72, 199), (104, 76, 203), (96, 80, 207), (80, 88, 215), + (64, 96, 223), (48, 104, 231), (32, 112, 239), (16, 120, 247), + (0, 128, 255), (0, 128, 251), (0, 128, 247), (0, 128, 243), + (0, 128, 239), (0, 128, 235), (0, 128, 231), (0, 128, 227), + (0, 128, 220), (0, 128, 218), (0, 128, 216), (0, 128, 212), + (0, 128, 208), (0, 128, 204), (0, 128, 200), (0, 128, 196), + (0, 128, 192), (8, 128, 196), (16, 128, 200), (24, 128, 204), + (32, 128, 208), (40, 128, 212), (48, 128, 216), (56, 128, 220), + (64, 128, 224), (72, 128, 227), (80, 128, 231), (88, 128, 235), + (96, 128, 239), (104, 128, 243), (112, 128, 247), (120, 128, 251), + (128, 128, 255), (120, 120, 255), (112, 112, 255), (104, 104, 255), + (96, 96, 255), (88, 88, 255), (80, 80, 255), (72, 72, 255), + (64, 64, 255), (56, 56, 255), (48, 48, 255), (40, 40, 255), + (32, 32, 255), (24, 24, 255), (16, 16, 255), (8, 8, 255), + (0, 0, 255), (0, 0, 249), (0, 0, 243), (0, 0, 237), + (0, 0, 231), (0, 0, 225), (0, 0, 219), (0, 0, 213), + (0, 0, 208), (0, 0, 202), (0, 0, 196), (0, 0, 190), + (0, 0, 184), (0, 0, 178), (0, 0, 172), (0, 0, 166), + (0, 0, 160), (8, 0, 166), (16, 0, 172), (24, 0, 178), + (32, 0, 184), (40, 0, 190), (48, 0, 196), (56, 0, 202), + (64, 0, 208), (72, 0, 213), (80, 0, 219), (88, 0, 225), + (96, 0, 231), (104, 0, 237), (112, 0, 243), (128, 0, 255) + ), + +// 103 rw-blue-with-red-2 +((0, 128, 255), (18, 119, 237), (27, 114, 228), (36, 110, 219), + (45, 105, 210), (54, 101, 201), (58, 98, 196), (63, 96, 192), + (81, 88, 174), (90, 83, 165), (99, 78, 156), (108, 74, 147), + (117, 70, 138), (125, 65, 129), (134, 60, 121), (138, 58, 116), + (143, 56, 112), (161, 47, 94), (170, 42, 85), (179, 38, 76), + (188, 33, 67), (197, 29, 58), (201, 26, 53), (206, 24, 49), + (224, 16, 31), (233, 11, 22), (242, 6, 13), (246, 5, 11), + (251, 4, 9), (248, 6, 13), (246, 9, 18), (242, 14, 27), + (237, 18, 36), (228, 27, 54), (223, 31, 63), (219, 36, 72), + (214, 40, 81), (210, 45, 90), (208, 47, 94), (206, 50, 99), + (197, 58, 117), (192, 63, 125), (188, 68, 134), (183, 72, 143), + (179, 76, 152), (177, 78, 156), (175, 81, 161), (170, 86, 170), + (166, 90, 179), (157, 99, 197), (152, 103, 206), (148, 108, 215), + (143, 112, 224), (139, 117, 233), (136, 119, 237), (134, 122, 242), + (132, 128, 251), (136, 128, 246), (141, 128, 242), (145, 128, 237), + (150, 128, 233), (152, 128, 230), (155, 128, 228), (159, 128, 224), + (164, 128, 219), (173, 128, 210), (177, 128, 205), (182, 128, 201), + (184, 128, 199), (186, 128, 197), (191, 128, 192), (195, 128, 188), + (204, 128, 179), (208, 128, 174), (213, 128, 170), (217, 128, 165), + (222, 128, 161), (224, 128, 159), (226, 128, 157), (231, 128, 152), + (235, 128, 148), (244, 128, 139), (248, 128, 134), (253, 128, 130), + (254, 128, 129), (255, 128, 128), (255, 128, 132), (255, 128, 137), + (255, 128, 146), (255, 128, 150), (255, 128, 155), (255, 128, 157), + (255, 128, 159), (255, 128, 164), (255, 128, 168), (255, 128, 173), + (255, 128, 177), (255, 128, 186), (255, 128, 190), (255, 128, 195), + (255, 128, 197), (255, 128, 199), (255, 128, 204), (255, 128, 208), + (255, 128, 217), (255, 128, 221), (255, 128, 226), (255, 128, 228), + (255, 128, 231), (255, 128, 235), (255, 128, 240), (255, 128, 244), + (255, 128, 249), (246, 124, 255), (241, 121, 255), (237, 119, 255), + (228, 114, 255), (219, 110, 255), (210, 106, 255), (201, 101, 255), + (183, 92, 255), (174, 87, 255), (165, 83, 255), (160, 80, 255), + (156, 78, 255), (147, 74, 255), (138, 70, 255), (129, 65, 255), + (121, 60, 255), (103, 52, 255), (98, 49, 255), (94, 47, 255), + (85, 42, 255), (76, 38, 255), (67, 34, 255), (58, 29, 255), + (40, 20, 255), (31, 15, 255), (22, 11, 255), (17, 8, 255), + (13, 6, 255), (4, 2, 255), (0, 0, 255), (9, 0, 251), + (18, 0, 246), (36, 0, 237), (40, 0, 235), (45, 0, 233), + (54, 0, 228), (63, 0, 224), (72, 0, 219), (81, 0, 215), + (99, 0, 206), (103, 0, 203), (108, 0, 201), (117, 0, 197), + (126, 0, 192), (134, 0, 188), (143, 0, 184), (152, 0, 179), + (161, 0, 175), (179, 0, 166), (183, 0, 163), (188, 0, 161), + (197, 0, 157), (206, 0, 152), (215, 0, 148), (224, 0, 143), + (242, 0, 134), (248, 0, 131), (255, 0, 128), (246, 4, 132), + (237, 9, 137), (228, 14, 141), (219, 18, 146), (210, 22, 150), + (201, 27, 155), (192, 32, 159), (183, 36, 164), (174, 40, 168), + (165, 45, 173), (156, 50, 177), (147, 54, 182), (138, 58, 186), + (121, 68, 195), (116, 70, 197), (112, 72, 199), (103, 76, 204), + (94, 81, 208), (85, 86, 213), (76, 90, 217), (67, 94, 222), + (58, 99, 226), (49, 104, 231), (40, 108, 235), (31, 112, 240), + (22, 117, 244), (13, 122, 249), (4, 126, 253), (0, 128, 255), + (9, 129, 251), (18, 130, 248), (27, 131, 244), (36, 132, 241), + (45, 133, 237), (54, 134, 234), (63, 135, 230), (72, 136, 227), + (81, 137, 223), (90, 138, 220), (99, 139, 216), (108, 140, 213), + (117, 141, 209), (126, 142, 206), (134, 143, 202), (143, 144, 199), + (152, 144, 195), (161, 145, 192), (170, 146, 188), (179, 147, 185), + (188, 148, 181), (197, 149, 178), (206, 150, 174), (215, 151, 171), + (224, 152, 167), (233, 153, 164), (242, 154, 160), (255, 155, 155), + (252, 155, 159), (248, 155, 162), (245, 155, 166), (242, 155, 169), + (238, 155, 173), (235, 155, 176), (231, 156, 180), (228, 156, 183), + (225, 156, 187), (221, 156, 190), (218, 156, 194), (214, 156, 197), + (211, 156, 201), (208, 157, 204), (204, 157, 208), (201, 157, 211), + (198, 157, 215), (194, 157, 218), (191, 157, 222), (188, 157, 225), + (184, 158, 229), (181, 158, 232), (177, 158, 236), (174, 158, 239), + (171, 158, 243), (167, 158, 246), (164, 158, 250), (159, 159, 255) + ), + +// 104 rw-blues-3 +((0, 0, 255), (9, 9, 255), (13, 13, 255), (18, 18, 255), + (22, 22, 255), (27, 27, 255), (29, 29, 255), (32, 32, 255), + (40, 40, 255), (45, 45, 255), (50, 50, 255), (54, 54, 255), + (58, 58, 255), (63, 63, 255), (68, 68, 255), (70, 70, 255), + (72, 72, 255), (81, 81, 255), (85, 85, 255), (90, 90, 255), + (94, 94, 255), (99, 99, 255), (101, 101, 255), (104, 104, 255), + (112, 112, 255), (117, 117, 255), (122, 122, 255), (123, 123, 253), + (124, 124, 252), (121, 121, 250), (119, 119, 248), (114, 114, 245), + (110, 110, 242), (101, 101, 235), (96, 96, 231), (92, 92, 228), + (87, 87, 225), (83, 83, 222), (80, 80, 220), (78, 78, 218), + (70, 70, 212), (65, 65, 208), (60, 60, 205), (56, 56, 201), + (52, 52, 198), (49, 49, 196), (47, 47, 195), (42, 42, 192), + (38, 38, 188), (29, 29, 182), (24, 24, 178), (20, 20, 175), + (15, 15, 171), (11, 11, 168), (8, 8, 166), (6, 6, 165), + (0, 9, 163), (0, 18, 166), (0, 27, 170), (0, 36, 173), + (0, 45, 177), (0, 49, 178), (0, 54, 180), (0, 63, 183), + (0, 72, 187), (0, 90, 193), (0, 99, 196), (0, 108, 200), + (0, 112, 201), (0, 117, 203), (0, 126, 207), (0, 134, 210), + (0, 152, 217), (0, 161, 220), (0, 170, 223), (0, 179, 226), + (0, 188, 230), (0, 192, 231), (0, 197, 233), (0, 206, 237), + (0, 215, 240), (0, 233, 247), (0, 242, 250), (0, 251, 254), + (0, 253, 254), (0, 255, 255), (0, 248, 251), (0, 242, 246), + (0, 228, 237), (0, 221, 232), (0, 215, 228), (0, 211, 226), + (0, 208, 224), (0, 201, 219), (0, 195, 215), (0, 188, 210), + (0, 181, 206), (0, 168, 197), (0, 161, 192), (0, 154, 188), + (0, 151, 186), (0, 148, 184), (0, 141, 179), (0, 134, 175), + (0, 121, 166), (0, 114, 161), (0, 107, 157), (0, 104, 154), + (0, 101, 152), (0, 94, 148), (0, 87, 143), (0, 80, 139), + (0, 74, 134), (0, 66, 130), (0, 67, 131), (0, 68, 132), + (0, 71, 135), (0, 73, 137), (0, 75, 139), (0, 78, 142), + (0, 82, 146), (0, 84, 148), (0, 86, 150), (0, 87, 151), + (0, 89, 153), (0, 91, 155), (0, 93, 157), (0, 96, 160), + (0, 98, 162), (0, 102, 166), (0, 103, 167), (0, 104, 168), + (0, 107, 171), (0, 109, 173), (0, 111, 175), (0, 114, 178), + (0, 118, 182), (0, 120, 184), (0, 122, 186), (0, 123, 187), + (0, 125, 189), (0, 127, 191), (0, 128, 192), (0, 128, 194), + (0, 128, 196), (0, 128, 201), (0, 128, 202), (0, 128, 203), + (0, 128, 205), (0, 128, 208), (0, 128, 210), (0, 128, 212), + (0, 128, 216), (0, 128, 217), (0, 128, 219), (0, 128, 221), + (0, 128, 223), (0, 128, 225), (0, 128, 227), (0, 128, 230), + (0, 128, 232), (0, 128, 236), (0, 128, 237), (0, 128, 239), + (0, 128, 241), (0, 128, 243), (0, 128, 245), (0, 128, 247), + (0, 128, 252), (0, 128, 253), (0, 128, 255), (4, 132, 255), + (9, 137, 255), (14, 141, 255), (18, 146, 255), (22, 150, 255), + (27, 155, 255), (32, 159, 255), (36, 164, 255), (40, 168, 255), + (45, 173, 255), (50, 177, 255), (54, 182, 255), (58, 186, 255), + (68, 195, 255), (70, 197, 255), (72, 199, 255), (76, 204, 255), + (81, 208, 255), (86, 213, 255), (90, 217, 255), (94, 222, 255), + (99, 226, 255), (104, 231, 255), (108, 235, 255), (112, 240, 255), + (117, 244, 255), (122, 249, 255), (126, 253, 255), (128, 255, 255), + (128, 246, 255), (128, 237, 255), (128, 228, 255), (128, 219, 255), + (128, 210, 255), (128, 201, 255), (128, 192, 255), (128, 183, 255), + (128, 174, 255), (128, 165, 255), (128, 156, 255), (128, 147, 255), + (128, 138, 255), (128, 129, 255), (128, 121, 255), (128, 112, 255), + (128, 103, 255), (128, 94, 255), (128, 85, 255), (128, 76, 255), + (128, 67, 255), (128, 58, 255), (128, 49, 255), (128, 40, 255), + (128, 31, 255), (128, 22, 255), (128, 13, 255), (128, 0, 255), + (128, 4, 253), (128, 9, 251), (128, 14, 248), (128, 18, 246), + (128, 22, 244), (128, 27, 242), (128, 32, 239), (128, 36, 237), + (128, 40, 235), (128, 45, 233), (128, 50, 231), (128, 54, 228), + (128, 58, 226), (128, 63, 224), (128, 68, 222), (128, 72, 220), + (128, 76, 217), (128, 81, 215), (128, 86, 213), (128, 90, 211), + (128, 94, 208), (128, 99, 206), (128, 104, 204), (128, 108, 202), + (128, 112, 200), (128, 117, 197), (128, 122, 195), (128, 128, 192) + ), + +// 105 rw-reds-pinks-blues +((255, 0, 0), (255, 0, 55), (255, 0, 91), (255, 0, 128), + (255, 27, 142), (255, 55, 156), (255, 68, 162), (255, 82, 169), + (255, 128, 192), (255, 128, 178), (255, 128, 164), (255, 128, 146), + (255, 128, 128), (255, 128, 142), (255, 128, 156), (255, 128, 162), + (255, 128, 169), (255, 128, 192), (200, 155, 151), (145, 183, 110), + (90, 210, 68), (36, 237, 27), (18, 246, 13), (0, 255, 0), + (110, 200, 110), (182, 164, 182), (255, 128, 255), (254, 134, 229), + (253, 140, 203), (252, 143, 189), (252, 146, 176), (251, 152, 150), + (250, 156, 133), (252, 89, 76), (253, 55, 47), (254, 22, 19), + (254, 25, 37), (255, 28, 55), (255, 41, 82), (255, 55, 110), + (255, 128, 255), (255, 128, 227), (255, 128, 200), (255, 128, 173), + (255, 128, 146), (255, 128, 137), (255, 128, 128), (255, 100, 128), + (255, 73, 128), (255, 18, 128), (255, 23, 121), (255, 28, 114), + (255, 55, 100), (255, 82, 87), (255, 105, 75), (255, 128, 64), + (255, 73, 92), (255, 45, 105), (255, 18, 119), (227, 9, 137), + (200, 0, 155), (172, 0, 169), (145, 0, 183), (91, 0, 210), + (36, 0, 237), (55, 28, 228), (109, 55, 200), (164, 82, 173), + (209, 105, 150), (255, 128, 128), (255, 100, 128), (255, 73, 128), + (255, 18, 128), (255, 9, 114), (255, 0, 100), (255, 0, 73), + (255, 0, 46), (255, 0, 32), (255, 0, 18), (255, 0, 0), + (255, 28, 14), (255, 82, 41), (255, 105, 59), (255, 128, 78), + (255, 128, 85), (255, 128, 92), (255, 128, 105), (255, 128, 119), + (255, 128, 155), (255, 128, 182), (255, 128, 210), (255, 128, 223), + (255, 128, 237), (255, 128, 255), (255, 155, 228), (255, 183, 200), + (255, 210, 173), (255, 200, 100), (255, 145, 73), (255, 91, 46), + (255, 63, 32), (255, 36, 18), (255, 0, 0), (255, 28, 55), + (255, 82, 164), (255, 105, 209), (255, 128, 255), (255, 128, 241), + (255, 128, 228), (255, 128, 200), (255, 128, 173), (255, 128, 128), + (255, 100, 128), (255, 46, 128), (255, 32, 128), (255, 18, 128), + (255, 0, 128), (255, 28, 114), (255, 55, 100), (255, 82, 87), + (255, 128, 64), (255, 128, 105), (255, 128, 146), (255, 128, 166), + (255, 128, 187), (255, 128, 255), (200, 155, 255), (145, 183, 255), + (91, 210, 255), (0, 255, 255), (27, 241, 241), (55, 228, 228), + (110, 200, 200), (164, 173, 173), (255, 128, 128), (255, 128, 155), + (255, 128, 210), (255, 128, 232), (255, 128, 255), (255, 114, 241), + (255, 100, 228), (255, 73, 200), (255, 46, 173), (255, 18, 146), + (255, 0, 128), (255, 55, 156), (255, 68, 162), (255, 82, 169), + (255, 128, 192), (255, 128, 178), (255, 128, 164), (255, 128, 151), + (255, 128, 128), (255, 128, 121), (255, 128, 114), (255, 128, 100), + (255, 128, 87), (255, 128, 73), (255, 128, 64), (215, 116, 104), + (174, 104, 145), (67, 71, 252), (87, 77, 232), (107, 83, 212), + (148, 95, 171), (188, 108, 131), (229, 120, 90), (255, 128, 64), + (255, 128, 146), (255, 128, 166), (255, 128, 187), (255, 128, 228), + (255, 128, 255), (255, 100, 228), (255, 73, 200), (255, 46, 173), + (255, 0, 128), (255, 28, 128), (255, 55, 128), (255, 82, 128), + (255, 110, 128), (255, 128, 128), (255, 128, 155), (255, 128, 183), + (255, 128, 237), (255, 128, 246), (255, 128, 255), (255, 128, 241), + (255, 128, 228), (255, 128, 214), (255, 128, 192), (234, 155, 181), + (212, 182, 170), (191, 209, 159), (169, 236, 148), (155, 254, 141), + (176, 199, 111), (198, 145, 80), (219, 90, 50), (241, 36, 20), + (255, 0, 0), (255, 0, 28), (255, 0, 55), (255, 0, 82), + (255, 0, 128), (255, 28, 128), (255, 55, 128), (255, 82, 128), + (255, 110, 128), (255, 128, 128), (255, 128, 155), (255, 128, 183), + (255, 128, 210), (255, 128, 237), (255, 128, 255), (255, 100, 228), + (255, 73, 200), (255, 46, 173), (255, 0, 128), (255, 28, 100), + (255, 55, 73), (255, 82, 46), (255, 110, 18), (255, 128, 0), + (228, 114, 0), (200, 100, 0), (173, 87, 0), (146, 73, 0), + (128, 64, 0), (155, 78, 28), (183, 92, 55), (210, 105, 82), + (255, 128, 128), (255, 100, 128), (255, 73, 128), (255, 46, 128), + (255, 18, 128), (255, 0, 128), (255, 28, 142), (255, 55, 156), + (255, 82, 169), (255, 110, 183), (255, 128, 192), (255, 128, 178), + (255, 128, 164), (255, 128, 151), (255, 128, 128), (255, 100, 100), + (255, 73, 73), (255, 46, 46), (255, 18, 18), (255, 0, 0), + (255, 28, 55), (255, 55, 110), (255, 82, 164), (255, 128, 255) + ), + +// 106 rw-browns-greens-reds-bule +((128, 255, 0), (73, 200, 28), (36, 164, 46), (0, 128, 64), + (55, 141, 91), (110, 155, 119), (137, 162, 132), (164, 169, 146), + (255, 191, 191), (255, 153, 153), (255, 115, 115), (255, 65, 65), + (255, 15, 15), (255, 39, 39), (255, 64, 64), (255, 76, 76), + (255, 88, 88), (255, 128, 128), (200, 128, 114), (145, 128, 100), + (90, 128, 86), (36, 128, 73), (18, 128, 68), (0, 128, 64), + (110, 128, 119), (182, 128, 155), (255, 128, 192), (255, 101, 178), + (255, 75, 165), (255, 61, 158), (255, 48, 152), (255, 21, 139), + (255, 4, 130), (200, 2, 102), (173, 1, 87), (146, 1, 73), + (123, 28, 68), (100, 55, 64), (86, 82, 64), (73, 110, 64), + (0, 255, 64), (32, 200, 66), (64, 145, 68), (96, 90, 70), + (128, 36, 73), (138, 18, 73), (149, 0, 74), (147, 21, 59), + (146, 42, 45), (143, 84, 16), (154, 94, 37), (166, 104, 59), + (190, 110, 112), (215, 117, 166), (235, 122, 210), (255, 128, 255), + (208, 117, 147), (184, 112, 92), (161, 107, 38), (152, 99, 22), + (143, 91, 6), (141, 85, 7), (140, 79, 9), (136, 67, 13), + (133, 55, 16), (128, 56, 21), (125, 64, 23), (123, 73, 26), + (120, 80, 28), (118, 87, 31), (141, 110, 53), (163, 132, 75), + (208, 177, 120), (219, 164, 112), (230, 151, 105), (237, 109, 76), + (244, 68, 48), (247, 47, 33), (250, 27, 19), (255, 0, 0), + (255, 28, 0), (255, 82, 0), (246, 91, 0), (237, 100, 0), + (227, 86, 0), (218, 73, 0), (200, 46, 0), (182, 18, 0), + (188, 5, 5), (206, 10, 10), (225, 15, 15), (234, 17, 17), + (243, 20, 20), (255, 23, 23), (249, 48, 29), (243, 73, 35), + (238, 98, 40), (230, 148, 65), (232, 156, 80), (234, 165, 95), + (235, 169, 102), (236, 173, 110), (237, 179, 120), (220, 159, 99), + (185, 120, 56), (170, 104, 38), (156, 88, 20), (157, 80, 26), + (158, 72, 33), (160, 55, 46), (162, 39, 59), (165, 12, 81), + (183, 41, 104), (218, 98, 151), (226, 112, 163), (235, 126, 175), + (247, 145, 190), (239, 127, 186), (231, 108, 183), (223, 90, 179), + (210, 60, 173), (194, 60, 180), (179, 60, 188), (171, 60, 192), + (164, 60, 196), (139, 61, 209), (157, 70, 175), (174, 80, 140), + (192, 89, 106), (221, 105, 49), (212, 99, 67), (203, 93, 86), + (186, 81, 123), (168, 68, 161), (139, 48, 222), (157, 48, 205), + (192, 48, 171), (206, 48, 157), (221, 49, 143), (224, 52, 148), + (227, 56, 153), (233, 63, 163), (238, 70, 173), (244, 77, 183), + (248, 82, 189), (251, 102, 135), (252, 107, 121), (253, 112, 108), + (255, 128, 64), (255, 142, 85), (255, 156, 107), (255, 170, 128), + (255, 193, 164), (248, 179, 146), (242, 165, 129), (230, 138, 94), + (217, 110, 58), (204, 82, 23), (196, 64, 0), (203, 82, 15), + (211, 101, 29), (230, 149, 68), (232, 146, 74), (235, 144, 81), + (241, 140, 94), (246, 135, 107), (251, 131, 120), (255, 128, 128), + (145, 183, 183), (118, 196, 196), (91, 210, 210), (36, 237, 237), + (0, 255, 255), (55, 255, 228), (110, 255, 200), (164, 255, 173), + (255, 255, 128), (228, 255, 146), (201, 255, 165), (174, 254, 183), + (148, 254, 201), (130, 253, 213), (151, 227, 222), (172, 200, 230), + (214, 147, 247), (221, 138, 250), (228, 130, 253), (207, 157, 232), + (185, 183, 212), (164, 210, 191), (129, 254, 157), (156, 240, 151), + (183, 226, 145), (210, 211, 139), (236, 197, 133), (254, 188, 129), + (250, 202, 129), (246, 216, 129), (242, 231, 129), (238, 245, 129), + (235, 254, 129), (212, 254, 133), (189, 254, 137), (167, 254, 141), + (129, 254, 148), (129, 254, 167), (129, 254, 185), (129, 254, 204), + (129, 254, 223), (129, 254, 235), (155, 244, 213), (182, 235, 190), + (208, 225, 168), (235, 215, 146), (252, 209, 131), (227, 218, 132), + (201, 226, 134), (176, 235, 135), (134, 249, 137), (145, 243, 126), + (157, 237, 115), (168, 231, 103), (180, 225, 92), (187, 221, 85), + (165, 212, 114), (143, 202, 144), (121, 193, 173), (98, 183, 203), + (84, 177, 222), (93, 166, 229), (103, 156, 236), (112, 145, 243), + (128, 128, 255), (121, 149, 211), (114, 170, 168), (107, 191, 124), + (100, 212, 81), (96, 226, 52), (119, 217, 54), (143, 208, 57), + (166, 199, 59), (190, 190, 61), (205, 184, 63), (213, 182, 75), + (222, 179, 88), (230, 177, 100), (244, 173, 121), (192, 191, 109), + (139, 208, 97), (87, 226, 84), (34, 243, 72), (0, 255, 64), + (0, 255, 105), (0, 255, 146), (0, 255, 187), (0, 255, 255) + ), + +// 107 rw-browns-pinks-reds-blues +((128, 0, 0), (147, 0, 0), (156, 0, 0), (166, 0, 0), + (175, 0, 0), (185, 0, 0), (189, 0, 0), (194, 0, 0), + (212, 23, 23), (218, 46, 46), (224, 69, 69), (230, 92, 92), + (236, 116, 116), (242, 139, 139), (248, 162, 162), (251, 176, 176), + (255, 191, 191), (255, 148, 148), (255, 127, 127), (255, 106, 106), + (255, 84, 84), (255, 63, 63), (255, 52, 52), (255, 42, 42), + (255, 29, 29), (255, 42, 42), (255, 56, 56), (255, 69, 69), + (255, 83, 83), (255, 90, 90), (255, 97, 97), (255, 111, 111), + (255, 124, 124), (255, 128, 143), (255, 128, 158), (255, 128, 174), + (255, 128, 189), (255, 128, 205), (255, 128, 212), (255, 128, 220), + (255, 128, 255), (255, 128, 247), (255, 128, 240), (255, 128, 232), + (255, 128, 224), (255, 128, 220), (255, 128, 217), (255, 128, 209), + (255, 128, 202), (255, 113, 184), (255, 98, 176), (255, 83, 169), + (255, 68, 161), (255, 53, 154), (255, 45, 150), (255, 38, 147), + (255, 4, 130), (239, 3, 122), (224, 3, 114), (208, 2, 106), + (193, 2, 98), (185, 2, 94), (178, 2, 90), (163, 2, 82), + (147, 1, 74), (128, 0, 64), (143, 18, 81), (159, 37, 98), + (166, 46, 106), (174, 55, 114), (190, 73, 131), (205, 91, 148), + (236, 128, 182), (239, 130, 184), (242, 133, 187), (229, 114, 171), + (216, 96, 156), (210, 87, 148), (204, 78, 141), (191, 60, 125), + (178, 41, 109), (149, 0, 74), (148, 12, 66), (147, 24, 58), + (147, 30, 53), (147, 36, 49), (146, 47, 41), (145, 59, 33), + (143, 83, 16), (142, 87, 11), (141, 92, 7), (140, 89, 8), + (140, 87, 9), (138, 81, 10), (137, 75, 11), (136, 70, 13), + (135, 64, 14), (132, 52, 17), (133, 54, 16), (134, 57, 15), + (134, 60, 14), (135, 64, 14), (137, 70, 12), (139, 76, 10), + (142, 89, 7), (144, 96, 5), (146, 103, 3), (145, 99, 4), + (144, 96, 5), (142, 89, 7), (141, 83, 8), (139, 76, 10), + (137, 69, 12), (133, 56, 16), (132, 51, 17), (131, 47, 18), + (129, 52, 20), (128, 57, 21), (126, 62, 23), (125, 66, 24), + (122, 76, 27), (120, 81, 29), (118, 87, 31), (124, 93, 37), + (131, 100, 43), (143, 112, 56), (156, 125, 68), (169, 138, 81), + (182, 151, 93), (207, 176, 118), (213, 182, 124), (220, 189, 131), + (223, 192, 134), (227, 169, 118), (231, 146, 102), (235, 122, 85), + (242, 76, 53), (246, 52, 36), (250, 29, 20), (252, 14, 10), + (255, 0, 0), (255, 21, 21), (255, 43, 43), (255, 64, 64), + (255, 85, 85), (255, 128, 128), (255, 138, 138), (255, 149, 149), + (255, 176, 176), (245, 155, 155), (234, 133, 133), (224, 112, 112), + (204, 69, 69), (198, 58, 58), (193, 48, 48), (183, 27, 27), + (170, 0, 0), (180, 3, 3), (191, 6, 6), (201, 8, 8), + (211, 11, 11), (232, 17, 17), (237, 18, 18), (242, 19, 19), + (252, 22, 22), (255, 23, 23), (252, 37, 26), (248, 51, 30), + (242, 79, 36), (240, 86, 37), (239, 93, 39), (235, 107, 43), + (232, 121, 46), (228, 139, 50), (229, 144, 58), (230, 149, 67), + (231, 154, 75), (232, 158, 84), (233, 163, 92), (235, 168, 101), + (236, 173, 109), (237, 179, 120), (227, 168, 108), (217, 157, 96), + (198, 135, 72), (193, 129, 65), (188, 124, 59), (178, 113, 47), + (168, 102, 35), (156, 88, 20), (157, 79, 27), (158, 70, 35), + (159, 60, 42), (160, 51, 50), (161, 42, 57), (163, 33, 64), + (164, 24, 72), (165, 14, 79), (165, 12, 81), (175, 28, 94), + (185, 44, 107), (195, 60, 121), (205, 76, 134), (215, 93, 147), + (225, 109, 160), (235, 125, 173), (247, 145, 190), (243, 135, 188), + (238, 124, 186), (234, 114, 184), (229, 104, 182), (225, 94, 180), + (220, 83, 178), (216, 73, 176), (210, 60, 173), (201, 60, 177), + (193, 60, 182), (184, 60, 186), (176, 60, 190), (167, 60, 195), + (158, 60, 199), (150, 60, 204), (139, 61, 209), (149, 66, 190), + (159, 72, 170), (169, 77, 151), (179, 82, 132), (189, 88, 112), + (199, 93, 93), (209, 98, 73), (218, 104, 54), (221, 105, 49), + (211, 98, 70), (201, 91, 91), (191, 84, 112), (181, 77, 133), + (171, 70, 154), (161, 64, 175), (151, 57, 196), (139, 48, 222), + (149, 48, 212), (159, 48, 203), (169, 48, 193), (179, 48, 184), + (189, 48, 174), (199, 48, 165), (209, 48, 155), (221, 49, 143), + (224, 53, 149), (228, 57, 154), (231, 61, 160), (234, 65, 165), + (237, 69, 171), (241, 73, 176), (244, 77, 182), (248, 82, 189) + ), + +// 108 rw-reds-greens-blues-pinks-yellows-browns +((255, 0, 0), (215, 40, 10), (195, 60, 15), (175, 80, 20), + (155, 100, 25), (135, 120, 30), (125, 129, 32), (116, 139, 35), + (76, 179, 45), (56, 199, 50), (36, 219, 55), (18, 232, 64), + (0, 245, 74), (0, 235, 84), (0, 225, 94), (0, 220, 99), + (0, 215, 104), (0, 195, 124), (0, 185, 134), (0, 176, 144), + (0, 166, 154), (0, 156, 164), (0, 151, 169), (0, 146, 174), + (0, 128, 192), (20, 128, 197), (40, 128, 202), (60, 128, 207), + (80, 128, 212), (90, 128, 214), (100, 128, 217), (120, 128, 222), + (139, 128, 226), (179, 128, 236), (199, 128, 241), (219, 128, 246), + (237, 128, 250), (255, 128, 255), (245, 128, 255), (235, 128, 255), + (195, 128, 255), (175, 128, 255), (155, 128, 255), (135, 128, 255), + (116, 128, 255), (106, 128, 255), (96, 128, 255), (76, 128, 255), + (56, 128, 255), (16, 128, 255), (8, 133, 245), (0, 138, 235), + (0, 148, 215), (0, 158, 195), (0, 163, 185), (0, 168, 175), + (0, 188, 135), (0, 197, 115), (0, 207, 96), (0, 217, 76), + (0, 227, 56), (0, 232, 46), (0, 237, 36), (0, 247, 16), + (0, 255, 0), (40, 255, 20), (60, 255, 30), (80, 255, 40), + (90, 255, 45), (100, 255, 50), (120, 255, 60), (139, 255, 70), + (179, 255, 90), (199, 255, 100), (219, 255, 110), (237, 250, 119), + (255, 245, 128), (255, 240, 128), (255, 235, 128), (255, 225, 128), + (255, 215, 128), (255, 195, 128), (255, 185, 128), (255, 176, 128), + (255, 171, 128), (255, 166, 128), (255, 156, 128), (255, 146, 128), + (255, 128, 128), (235, 128, 123), (215, 128, 118), (205, 128, 115), + (195, 128, 113), (175, 128, 108), (155, 128, 103), (135, 128, 98), + (116, 128, 93), (76, 128, 83), (56, 128, 78), (36, 128, 73), + (26, 128, 70), (16, 128, 68), (0, 128, 64), (10, 123, 59), + (30, 113, 49), (40, 108, 44), (50, 103, 39), (55, 100, 36), + (60, 98, 34), (70, 93, 29), (80, 88, 24), (90, 83, 19), + (100, 78, 14), (120, 68, 4), (124, 66, 2), (128, 64, 0), + (128, 69, 15), (128, 74, 30), (128, 79, 45), (128, 84, 60), + (128, 94, 90), (128, 99, 105), (128, 104, 120), (128, 106, 127), + (128, 109, 135), (128, 114, 150), (128, 119, 165), (128, 124, 185), + (128, 128, 192), (148, 108, 162), (153, 103, 154), (158, 98, 147), + (168, 88, 132), (178, 78, 117), (188, 68, 102), (197, 58, 87), + (217, 38, 57), (227, 28, 42), (237, 18, 27), (246, 9, 13), + (255, 0, 0), (255, 10, 0), (255, 20, 0), (255, 30, 0), + (255, 40, 0), (255, 60, 0), (255, 65, 0), (255, 70, 0), + (255, 80, 0), (255, 90, 0), (255, 100, 0), (255, 110, 0), + (255, 128, 0), (250, 128, 10), (245, 128, 20), (235, 128, 40), + (225, 128, 60), (215, 128, 80), (205, 128, 100), (195, 128, 120), + (186, 128, 139), (166, 128, 179), (161, 128, 189), (156, 128, 199), + (146, 128, 219), (136, 128, 239), (128, 128, 255), (137, 137, 246), + (154, 155, 228), (158, 159, 223), (163, 164, 218), (171, 173, 209), + (180, 182, 200), (189, 191, 191), (197, 200, 182), (206, 210, 173), + (215, 219, 164), (223, 228, 154), (232, 237, 145), (239, 244, 138), + (240, 235, 127), (242, 226, 116), (243, 217, 106), (244, 208, 95), + (246, 190, 73), (247, 185, 68), (248, 181, 63), (249, 172, 52), + (250, 162, 41), (252, 153, 30), (253, 144, 19), (254, 135, 9), + (255, 128, 0), (235, 138, 5), (215, 148, 10), (195, 158, 15), + (175, 168, 20), (155, 178, 25), (135, 188, 30), (116, 197, 35), + (96, 207, 40), (76, 217, 45), (56, 227, 50), (36, 237, 55), + (0, 255, 64), (20, 255, 69), (40, 255, 74), (60, 255, 79), + (80, 255, 84), (100, 255, 89), (120, 255, 94), (139, 255, 99), + (159, 255, 104), (179, 255, 109), (199, 255, 114), (219, 255, 119), + (239, 255, 124), (255, 255, 128), (255, 245, 123), (255, 235, 118), + (255, 225, 113), (255, 215, 108), (255, 205, 103), (255, 195, 98), + (255, 186, 93), (255, 176, 88), (255, 166, 83), (255, 156, 78), + (255, 146, 73), (255, 136, 68), (255, 128, 64), (255, 128, 74), + (255, 128, 84), (255, 128, 94), (255, 128, 104), (255, 128, 114), + (255, 128, 124), (255, 128, 134), (255, 128, 144), (255, 128, 154), + (255, 128, 164), (255, 128, 174), (255, 128, 184), (255, 128, 192), + (255, 118, 187), (255, 108, 182), (255, 98, 177), (255, 88, 172), + (255, 78, 167), (255, 68, 162), (255, 58, 157), (255, 48, 152), + (255, 38, 147), (255, 28, 142), (255, 18, 137), (255, 0, 128) + ), + +// 109 rw-greens-light-to-dark +((0, 255, 0), (0, 237, 18), (0, 228, 27), (0, 219, 36), + (0, 210, 45), (0, 201, 54), (0, 196, 58), (0, 192, 63), + (0, 175, 81), (0, 166, 90), (0, 157, 99), (0, 148, 108), + (0, 139, 117), (4, 138, 118), (9, 137, 119), (13, 141, 114), + (18, 146, 110), (36, 164, 92), (45, 173, 83), (54, 182, 74), + (63, 190, 65), (72, 199, 56), (76, 203, 51), (81, 208, 47), + (99, 226, 29), (108, 235, 20), (117, 244, 11), (118, 245, 7), + (119, 246, 4), (114, 241, 6), (110, 237, 9), (101, 228, 14), + (92, 219, 18), (74, 201, 27), (65, 192, 31), (56, 184, 36), + (47, 175, 40), (38, 166, 45), (33, 161, 47), (29, 157, 50), + (11, 139, 58), (10, 138, 63), (9, 137, 68), (18, 146, 73), + (27, 155, 78), (31, 159, 80), (36, 164, 82), (45, 173, 86), + (54, 182, 91), (72, 199, 100), (81, 208, 104), (90, 217, 109), + (99, 226, 113), (108, 235, 118), (112, 239, 120), (117, 244, 122), + (119, 248, 119), (110, 241, 110), (101, 234, 101), (92, 227, 92), + (83, 221, 83), (78, 217, 78), (74, 214, 74), (65, 207, 65), + (56, 200, 56), (38, 186, 38), (29, 179, 29), (20, 172, 20), + (15, 168, 15), (11, 165, 11), (2, 159, 2), (0, 157, 0), + (19, 167, 5), (29, 172, 7), (39, 178, 10), (48, 183, 12), + (58, 188, 14), (62, 190, 15), (67, 193, 17), (77, 198, 19), + (87, 203, 22), (106, 213, 26), (115, 218, 28), (125, 224, 31), + (131, 227, 32), (137, 230, 34), (137, 227, 37), (138, 224, 40), + (138, 218, 45), (138, 215, 48), (139, 213, 51), (139, 211, 52), + (140, 210, 54), (140, 207, 56), (141, 204, 59), (141, 201, 62), + (141, 198, 65), (142, 193, 71), (139, 192, 71), (136, 192, 71), + (132, 193, 70), (129, 194, 69), (122, 197, 66), (115, 199, 64), + (101, 204, 59), (94, 206, 56), (87, 209, 54), (83, 210, 52), + (80, 212, 51), (73, 214, 49), (66, 217, 46), (59, 219, 44), + (52, 222, 41), (45, 223, 44), (46, 221, 47), (47, 220, 50), + (49, 218, 56), (51, 216, 62), (53, 213, 69), (55, 211, 75), + (59, 206, 87), (61, 204, 93), (63, 202, 99), (64, 200, 102), + (65, 199, 105), (67, 197, 111), (69, 195, 118), (71, 193, 124), + (71, 192, 125), (80, 197, 113), (82, 198, 110), (85, 199, 107), + (89, 201, 101), (94, 204, 94), (98, 206, 88), (103, 208, 82), + (112, 213, 70), (116, 215, 64), (121, 218, 58), (123, 219, 55), + (126, 220, 52), (130, 222, 45), (136, 225, 38), (130, 227, 36), + (124, 229, 35), (112, 232, 31), (108, 233, 30), (105, 234, 30), + (99, 236, 28), (93, 237, 26), (87, 239, 24), (81, 241, 23), + (69, 244, 19), (66, 245, 18), (63, 246, 18), (56, 248, 16), + (49, 250, 14), (52, 245, 23), (55, 239, 32), (58, 234, 41), + (61, 228, 50), (66, 218, 68), (67, 215, 72), (69, 212, 77), + (72, 207, 86), (75, 201, 95), (78, 196, 104), (81, 190, 113), + (86, 180, 131), (88, 176, 136), (90, 173, 142), (84, 170, 137), + (77, 167, 131), (71, 164, 126), (65, 160, 120), (58, 157, 115), + (52, 154, 109), (46, 151, 104), (39, 148, 98), (33, 145, 93), + (27, 141, 87), (20, 138, 82), (14, 135, 76), (8, 132, 71), + (0, 136, 68), (0, 140, 70), (0, 144, 72), (0, 152, 76), + (0, 161, 80), (0, 169, 84), (0, 177, 88), (0, 185, 93), + (0, 193, 97), (0, 201, 101), (0, 210, 105), (0, 218, 109), + (0, 226, 113), (0, 234, 117), (0, 242, 121), (0, 244, 122), + (8, 245, 126), (15, 246, 130), (23, 247, 135), (30, 247, 139), + (38, 248, 143), (46, 249, 147), (53, 250, 152), (61, 250, 156), + (68, 251, 160), (76, 252, 164), (84, 253, 168), (91, 253, 173), + (99, 254, 177), (108, 255, 182), (108, 249, 177), (108, 243, 172), + (108, 237, 167), (108, 231, 162), (108, 225, 157), (108, 219, 152), + (108, 213, 147), (108, 207, 142), (108, 201, 137), (108, 195, 132), + (108, 188, 127), (108, 182, 122), (108, 176, 117), (109, 169, 111), + (114, 174, 106), (119, 178, 102), (123, 183, 97), (128, 187, 92), + (133, 192, 88), (138, 196, 83), (142, 201, 79), (147, 206, 74), + (152, 210, 69), (157, 215, 65), (162, 219, 60), (166, 224, 55), + (171, 228, 51), (177, 234, 45), (165, 235, 42), (152, 237, 39), + (140, 238, 36), (127, 240, 32), (115, 241, 29), (102, 243, 26), + (90, 244, 23), (77, 246, 20), (65, 247, 17), (53, 249, 13), + (40, 250, 10), (28, 252, 7), (15, 253, 4), (0, 255, 0) + ), + +// 110 rw-blues-reds-purples +((0, 128, 255), (32, 144, 255), (53, 154, 255), (74, 165, 255), + (89, 172, 255), (105, 180, 255), (113, 184, 255), (121, 188, 255), + (147, 201, 255), (157, 206, 255), (167, 211, 255), (180, 217, 255), + (193, 224, 255), (151, 203, 241), (110, 183, 228), (89, 172, 221), + (69, 162, 214), (0, 128, 192), (39, 148, 205), (79, 168, 219), + (119, 187, 232), (159, 207, 246), (172, 213, 250), (185, 220, 255), + (165, 210, 255), (151, 203, 255), (138, 197, 255), (129, 192, 255), + (121, 188, 255), (116, 185, 255), (112, 183, 255), (104, 179, 255), + (98, 176, 255), (83, 169, 255), (76, 165, 255), (69, 161, 255), + (63, 158, 255), (58, 156, 255), (55, 154, 255), (52, 153, 255), + (36, 146, 255), (28, 142, 255), (21, 138, 255), (13, 134, 255), + (5, 131, 255), (2, 129, 255), (0, 128, 255), (0, 123, 245), + (0, 118, 236), (0, 108, 216), (0, 104, 209), (0, 101, 202), + (0, 97, 194), (0, 93, 187), (0, 90, 180), (0, 87, 174), + (24, 116, 209), (35, 130, 226), (47, 145, 244), (57, 154, 247), + (68, 163, 251), (75, 167, 249), (82, 172, 247), (95, 180, 243), + (108, 189, 239), (97, 180, 225), (77, 166, 214), (58, 153, 204), + (42, 142, 195), (26, 131, 187), (30, 142, 189), (35, 152, 190), + (43, 173, 193), (50, 179, 196), (58, 186, 199), (69, 191, 204), + (81, 197, 209), (87, 199, 212), (93, 202, 215), (101, 206, 218), + (87, 194, 205), (60, 169, 180), (62, 167, 177), (64, 165, 175), + (77, 173, 183), (90, 181, 191), (117, 198, 207), (143, 214, 223), + (134, 210, 219), (107, 195, 205), (81, 180, 191), (68, 172, 184), + (55, 165, 177), (38, 155, 168), (69, 164, 180), (100, 173, 192), + (131, 182, 204), (159, 179, 214), (135, 160, 203), (112, 142, 193), + (100, 132, 188), (89, 123, 183), (74, 111, 176), (85, 120, 181), + (106, 138, 192), (115, 145, 196), (124, 153, 201), (118, 147, 196), + (112, 142, 192), (99, 131, 183), (87, 119, 174), (66, 101, 159), + (97, 127, 176), (159, 178, 209), (174, 190, 217), (190, 203, 225), + (210, 220, 236), (177, 200, 214), (144, 180, 192), (111, 159, 170), + (57, 126, 134), (82, 145, 152), (107, 165, 171), (119, 174, 180), + (132, 184, 189), (173, 216, 220), (150, 200, 205), (126, 184, 189), + (103, 168, 174), (64, 142, 149), (81, 152, 159), (98, 163, 169), + (133, 184, 189), (167, 205, 208), (224, 240, 241), (185, 208, 209), + (107, 144, 146), (75, 117, 120), (43, 91, 94), (52, 102, 105), + (62, 114, 117), (81, 136, 139), (100, 159, 162), (119, 181, 184), + (131, 196, 199), (114, 156, 215), (110, 146, 219), (106, 136, 223), + (92, 103, 237), (103, 113, 238), (113, 123, 239), (124, 133, 240), + (142, 150, 242), (129, 137, 235), (116, 125, 229), (90, 100, 216), + (64, 75, 203), (38, 49, 190), (21, 33, 181), (51, 56, 189), + (82, 79, 196), (162, 140, 217), (159, 136, 216), (156, 133, 215), + (151, 127, 213), (145, 120, 211), (140, 113, 208), (136, 109, 207), + (113, 85, 186), (107, 78, 180), (101, 72, 175), (90, 60, 165), + (82, 52, 158), (111, 85, 175), (140, 119, 193), (168, 152, 210), + (216, 207, 239), (213, 200, 233), (210, 193, 227), (206, 186, 220), + (203, 179, 214), (201, 174, 210), (186, 154, 197), (171, 134, 183), + (142, 95, 157), (137, 88, 152), (132, 82, 148), (146, 105, 123), + (161, 128, 98), (175, 152, 73), (199, 190, 31), (171, 175, 59), + (142, 161, 88), (114, 146, 116), (86, 132, 144), (67, 122, 163), + (87, 137, 174), (107, 152, 186), (127, 167, 197), (147, 182, 209), + (160, 192, 216), (180, 151, 170), (201, 110, 123), (221, 68, 77), + (255, 0, 0), (233, 6, 49), (211, 12, 98), (189, 18, 146), + (167, 24, 195), (153, 28, 227), (169, 63, 232), (185, 98, 236), + (201, 134, 241), (217, 169, 245), (227, 192, 248), (211, 156, 243), + (195, 121, 239), (179, 85, 234), (152, 26, 227), (155, 39, 210), + (158, 53, 192), (160, 66, 175), (163, 79, 157), (165, 88, 146), + (178, 111, 161), (190, 135, 177), (203, 158, 192), (216, 182, 208), + (224, 197, 218), (212, 204, 226), (200, 211, 233), (188, 218, 241), + (168, 230, 253), (133, 212, 241), (98, 193, 229), (62, 175, 218), + (27, 157, 206), (4, 145, 198), (11, 149, 188), (18, 154, 178), + (25, 158, 168), (32, 162, 158), (37, 165, 152), (31, 171, 141), + (25, 177, 130), (19, 183, 119), (9, 193, 101), (10, 173, 120), + (10, 153, 139), (11, 134, 158), (12, 114, 177), (13, 101, 189), + (65, 107, 190), (117, 113, 190), (169, 118, 191), (255, 128, 192) + ), + +// 111 rw-multi-5 +((0, 255, 128), (0, 200, 128), (0, 164, 128), (0, 128, 128), + (27, 155, 155), (55, 183, 183), (68, 196, 196), (82, 210, 210), + (128, 255, 255), (100, 214, 227), (73, 173, 200), (36, 118, 164), + (0, 64, 128), (55, 78, 142), (110, 92, 156), (137, 98, 162), + (164, 105, 169), (255, 128, 192), (227, 128, 192), (200, 128, 192), + (173, 128, 192), (146, 128, 192), (137, 128, 192), (128, 128, 192), + (183, 128, 219), (219, 128, 237), (255, 128, 255), (255, 100, 227), + (255, 73, 200), (255, 59, 186), (255, 46, 173), (255, 18, 146), + (255, 0, 128), (200, 28, 100), (173, 41, 86), (146, 55, 73), + (137, 80, 61), (128, 105, 50), (128, 125, 43), (128, 146, 36), + (128, 255, 0), (100, 227, 14), (73, 200, 28), (45, 173, 41), + (18, 146, 55), (9, 137, 59), (0, 128, 64), (0, 100, 105), + (0, 73, 146), (0, 18, 228), (14, 16, 214), (28, 14, 200), + (55, 27, 145), (82, 41, 91), (105, 52, 45), (128, 64, 0), + (128, 92, 110), (128, 105, 164), (128, 119, 219), (141, 137, 237), + (155, 155, 255), (169, 169, 255), (183, 183, 255), (210, 210, 255), + (237, 237, 255), (251, 238, 210), (247, 220, 165), (243, 203, 121), + (239, 188, 84), (236, 174, 47), (222, 174, 51), (208, 174, 55), + (179, 174, 62), (165, 178, 79), (151, 183, 96), (131, 190, 127), + (112, 198, 159), (102, 202, 174), (93, 206, 190), (80, 211, 211), + (105, 186, 206), (156, 136, 197), (175, 130, 179), (194, 124, 162), + (192, 138, 148), (190, 153, 134), (186, 183, 106), (183, 213, 78), + (186, 234, 76), (192, 235, 92), (198, 237, 108), (201, 238, 116), + (204, 239, 124), (208, 240, 134), (163, 216, 133), (119, 192, 131), + (74, 168, 130), (55, 130, 130), (109, 131, 131), (164, 133, 133), + (191, 134, 134), (219, 135, 135), (255, 136, 136), (226, 152, 133), + (169, 183, 126), (145, 196, 123), (122, 209, 120), (122, 206, 129), + (122, 203, 139), (122, 197, 157), (122, 190, 176), (122, 180, 207), + (138, 178, 191), (170, 174, 160), (178, 173, 152), (186, 172, 144), + (196, 171, 134), (172, 172, 158), (147, 174, 183), (123, 175, 207), + (82, 177, 248), (89, 189, 215), (97, 201, 183), (101, 207, 167), + (105, 213, 151), (117, 233, 97), (117, 229, 112), (117, 225, 127), + (117, 221, 142), (116, 214, 167), (131, 205, 156), (146, 196, 145), + (176, 177, 123), (206, 159, 101), (255, 128, 64), (245, 135, 73), + (226, 150, 92), (218, 156, 100), (210, 162, 108), (212, 154, 121), + (214, 147, 134), (217, 131, 159), (221, 116, 185), (225, 101, 210), + (227, 91, 227), (209, 65, 209), (204, 58, 204), (199, 52, 199), + (184, 31, 184), (198, 69, 198), (212, 107, 212), (225, 146, 225), + (248, 209, 248), (234, 205, 223), (221, 201, 199), (194, 193, 150), + (167, 185, 101), (140, 176, 52), (122, 171, 20), (105, 159, 47), + (89, 147, 75), (45, 114, 147), (42, 120, 134), (40, 126, 121), + (36, 137, 95), (31, 149, 70), (26, 160, 44), (23, 168, 27), + (23, 110, 88), (23, 95, 103), (23, 81, 119), (23, 52, 149), + (22, 33, 169), (53, 62, 137), (84, 91, 106), (115, 121, 74), + (166, 169, 22), (166, 137, 42), (167, 105, 62), (168, 74, 82), + (169, 42, 102), (170, 21, 115), (138, 53, 127), (106, 85, 138), + (43, 148, 161), (32, 158, 165), (22, 169, 169), (31, 156, 160), + (40, 142, 151), (49, 129, 143), (64, 107, 128), (78, 109, 114), + (92, 110, 100), (105, 112, 87), (119, 113, 73), (128, 114, 64), + (111, 120, 71), (94, 126, 79), (76, 133, 86), (59, 139, 93), + (48, 143, 98), (67, 122, 108), (86, 102, 118), (105, 81, 128), + (137, 47, 145), (110, 72, 153), (83, 97, 160), (56, 122, 168), + (29, 148, 176), (11, 164, 181), (45, 129, 183), (79, 94, 184), + (113, 60, 186), (148, 25, 188), (170, 2, 189), (173, 42, 149), + (177, 83, 108), (180, 123, 68), (186, 190, 1), (186, 188, 2), + (186, 186, 4), (185, 184, 5), (185, 181, 6), (184, 180, 7), + (199, 195, 51), (214, 211, 96), (228, 226, 140), (243, 242, 184), + (253, 252, 213), (244, 252, 222), (236, 252, 230), (227, 252, 239), + (213, 253, 253), (213, 253, 244), (213, 253, 235), (213, 253, 226), + (213, 253, 217), (213, 254, 211), (213, 245, 220), (212, 236, 229), + (212, 226, 239), (212, 217, 248), (211, 211, 254), (220, 213, 245), + (230, 215, 235), (239, 217, 226), (255, 220, 210), (255, 198, 204), + (255, 176, 197), (255, 154, 191), (255, 131, 184), (255, 117, 180), + (226, 129, 196), (197, 141, 211), (167, 152, 227), (119, 172, 253) + ), + +// 112 rw-blues-black-purple +((128, 255, 255), (103, 205, 218), (90, 180, 199), (78, 155, 180), + (65, 130, 161), (53, 106, 143), (46, 93, 133), (40, 81, 124), + (16, 31, 87), (8, 18, 78), (0, 6, 70), (0, 12, 76), + (0, 19, 83), (0, 25, 89), (0, 31, 95), (0, 34, 98), + (0, 38, 102), (0, 50, 114), (0, 57, 121), (0, 64, 128), + (4, 72, 140), (8, 81, 153), (10, 85, 159), (13, 89, 165), + (21, 106, 190), (25, 114, 202), (29, 122, 215), (33, 130, 227), + (38, 139, 240), (40, 144, 247), (43, 149, 255), (39, 134, 255), + (35, 120, 255), (26, 91, 255), (22, 76, 255), (18, 62, 255), + (13, 47, 255), (9, 33, 255), (7, 25, 255), (5, 18, 255), + (12, 12, 255), (25, 25, 255), (38, 38, 255), (50, 50, 255), + (62, 62, 255), (68, 68, 255), (75, 75, 255), (88, 88, 255), + (100, 100, 255), (125, 125, 255), (120, 126, 255), (116, 128, 255), + (103, 128, 255), (90, 128, 255), (84, 128, 255), (78, 128, 255), + (53, 128, 255), (40, 128, 255), (28, 128, 255), (14, 128, 255), + (0, 128, 255), (6, 122, 255), (12, 116, 255), (25, 103, 255), + (38, 90, 255), (62, 66, 255), (75, 53, 255), (88, 40, 255), + (94, 34, 255), (100, 28, 255), (112, 16, 255), (128, 0, 255), + (128, 50, 255), (128, 75, 255), (128, 100, 255), (128, 124, 255), + (128, 149, 255), (128, 161, 255), (128, 174, 255), (128, 199, 255), + (128, 224, 255), (116, 255, 255), (103, 255, 255), (90, 255, 255), + (84, 255, 255), (78, 255, 255), (66, 255, 255), (53, 255, 255), + (28, 255, 255), (15, 255, 255), (3, 255, 255), (1, 255, 255), + (0, 255, 255), (0, 245, 245), (0, 235, 235), (0, 225, 225), + (0, 214, 214), (0, 194, 194), (0, 184, 184), (0, 174, 174), + (0, 169, 169), (0, 164, 164), (0, 151, 151), (0, 157, 157), + (0, 170, 170), (0, 176, 176), (0, 182, 182), (0, 185, 185), + (0, 188, 188), (0, 195, 195), (0, 201, 201), (0, 207, 207), + (0, 215, 215), (0, 195, 195), (0, 190, 190), (0, 185, 185), + (0, 175, 175), (0, 165, 165), (0, 155, 155), (0, 145, 145), + (0, 125, 125), (4, 117, 126), (8, 110, 127), (12, 108, 134), + (16, 107, 141), (24, 104, 155), (32, 101, 168), (41, 98, 182), + (49, 95, 196), (65, 90, 224), (69, 88, 231), (73, 87, 238), + (81, 84, 252), (83, 83, 255), (75, 75, 246), (67, 67, 237), + (51, 51, 219), (42, 42, 210), (34, 34, 202), (30, 30, 197), + (26, 26, 193), (18, 18, 184), (10, 10, 175), (0, 0, 164), + (19, 19, 173), (56, 56, 191), (65, 65, 195), (75, 75, 200), + (93, 93, 208), (112, 112, 217), (131, 131, 226), (149, 149, 235), + (191, 191, 255), (181, 181, 254), (172, 172, 253), (154, 154, 251), + (135, 135, 248), (116, 116, 246), (98, 98, 244), (79, 79, 242), + (60, 60, 239), (23, 23, 235), (11, 11, 233), (0, 0, 232), + (0, 0, 234), (0, 0, 236), (0, 0, 239), (0, 0, 241), + (0, 0, 245), (0, 0, 246), (0, 0, 248), (0, 0, 250), + (0, 0, 252), (0, 0, 254), (0, 0, 255), (0, 0, 246), + (0, 0, 236), (0, 0, 227), (0, 0, 218), (0, 0, 209), + (0, 0, 199), (0, 0, 190), (0, 0, 181), (0, 0, 172), + (0, 6, 157), (0, 9, 155), (0, 12, 154), (0, 19, 151), + (0, 25, 148), (0, 31, 144), (0, 38, 141), (0, 44, 138), + (0, 50, 135), (0, 56, 132), (0, 64, 128), (0, 70, 134), + (0, 76, 140), (0, 83, 147), (0, 89, 153), (0, 95, 159), + (0, 102, 166), (0, 108, 172), (0, 114, 178), (0, 120, 184), + (0, 128, 192), (0, 140, 198), (0, 153, 204), (0, 165, 210), + (0, 178, 217), (0, 190, 223), (0, 202, 229), (0, 215, 235), + (0, 227, 241), (0, 240, 247), (0, 252, 254), (0, 255, 255), + (12, 243, 249), (25, 230, 243), (38, 218, 237), (50, 205, 230), + (62, 193, 224), (75, 181, 218), (88, 168, 212), (100, 156, 206), + (112, 143, 200), (128, 128, 192), (128, 140, 198), (128, 153, 204), + (128, 165, 210), (128, 178, 217), (128, 190, 223), (128, 202, 229), + (128, 215, 235), (128, 227, 241), (128, 240, 247), (128, 255, 255), + (128, 230, 255), (128, 205, 255), (128, 180, 255), (128, 155, 255), + (128, 130, 255), (128, 106, 255), (128, 81, 255), (128, 56, 255), + (128, 31, 255), (128, 0, 255), (122, 0, 243), (116, 0, 230), + (109, 0, 218), (103, 0, 205), (97, 0, 193), (90, 0, 181), + (84, 0, 168), (78, 0, 156), (72, 0, 143), (64, 0, 128) + ), + +// 113 rw-multi-colors-6 +((255, 128, 64), (255, 156, 108), (255, 175, 137), (255, 194, 166), + (227, 166, 144), (200, 138, 122), (186, 124, 111), (173, 110, 100), + (128, 64, 64), (144, 84, 84), (161, 104, 104), (183, 130, 130), + (205, 156, 156), (161, 177, 136), (117, 199, 116), (95, 209, 106), + (73, 220, 97), (0, 255, 64), (37, 255, 92), (75, 255, 120), + (112, 255, 148), (150, 255, 176), (162, 255, 185), (174, 255, 194), + (154, 173, 111), (141, 118, 55), (128, 64, 0), (155, 88, 21), + (183, 113, 43), (196, 125, 53), (210, 137, 64), (237, 161, 86), + (255, 177, 100), (145, 101, 167), (90, 63, 200), (36, 25, 233), + (36, 30, 244), (36, 36, 255), (54, 54, 255), (72, 72, 255), + (168, 168, 255), (186, 159, 255), (205, 151, 255), (224, 142, 255), + (243, 134, 255), (249, 131, 255), (255, 128, 255), (246, 100, 246), + (238, 73, 238), (221, 18, 221), (213, 9, 213), (205, 0, 205), + (195, 0, 195), (185, 0, 185), (176, 0, 176), (168, 0, 168), + (96, 55, 178), (60, 82, 183), (24, 110, 189), (23, 127, 197), + (23, 145, 206), (34, 153, 212), (46, 162, 219), (70, 179, 233), + (93, 196, 246), (85, 183, 230), (61, 158, 205), (38, 134, 180), + (19, 114, 159), (0, 94, 138), (33, 122, 163), (67, 149, 188), + (133, 204, 239), (127, 203, 219), (122, 202, 200), (88, 181, 145), + (55, 161, 91), (38, 151, 63), (22, 141, 36), (0, 128, 0), + (3, 155, 3), (8, 210, 8), (24, 232, 24), (40, 255, 40), + (53, 255, 53), (67, 255, 67), (94, 255, 94), (120, 255, 120), + (108, 226, 108), (78, 197, 78), (49, 169, 49), (34, 154, 34), + (19, 140, 19), (0, 121, 0), (55, 123, 14), (110, 124, 28), + (164, 126, 41), (255, 119, 52), (255, 110, 39), (255, 102, 27), + (255, 97, 20), (255, 93, 14), (255, 87, 6), (255, 109, 38), + (255, 152, 102), (255, 170, 128), (255, 188, 155), (248, 174, 138), + (241, 161, 122), (228, 134, 88), (214, 107, 55), (191, 63, 0), + (205, 97, 43), (232, 164, 130), (239, 180, 152), (246, 197, 174), + (255, 219, 202), (234, 183, 159), (213, 147, 115), (192, 111, 72), + (157, 51, 0), (163, 72, 11), (170, 93, 23), (173, 103, 29), + (177, 114, 35), (188, 148, 54), (194, 156, 68), (200, 164, 82), + (206, 172, 95), (216, 186, 118), (218, 191, 127), (221, 196, 137), + (227, 205, 155), (232, 215, 174), (241, 231, 205), (244, 209, 202), + (250, 165, 197), (252, 146, 194), (255, 128, 192), (255, 122, 189), + (255, 116, 186), (255, 103, 180), (255, 91, 173), (255, 78, 167), + (255, 70, 163), (255, 46, 151), (255, 40, 148), (255, 35, 145), + (255, 15, 135), (244, 12, 128), (233, 9, 121), (222, 5, 114), + (204, 0, 102), (199, 0, 99), (194, 0, 97), (184, 0, 92), + (174, 0, 87), (164, 0, 82), (157, 0, 79), (150, 0, 76), + (143, 0, 72), (125, 0, 63), (139, 27, 70), (153, 55, 77), + (181, 110, 91), (209, 164, 105), (237, 219, 119), (255, 255, 128), + (145, 210, 138), (118, 199, 140), (91, 188, 143), (36, 166, 148), + (0, 151, 151), (0, 146, 173), (0, 141, 196), (0, 136, 218), + (0, 128, 255), (42, 143, 200), (84, 157, 145), (126, 172, 91), + (168, 186, 36), (196, 196, 0), (189, 189, 0), (182, 182, 0), + (168, 168, 0), (166, 166, 0), (164, 164, 0), (155, 155, 0), + (146, 146, 0), (136, 136, 0), (121, 121, 0), (145, 133, 54), + (169, 145, 108), (193, 157, 162), (216, 169, 217), (232, 177, 252), + (223, 150, 251), (215, 122, 250), (206, 94, 249), (198, 67, 248), + (192, 49, 247), (170, 40, 221), (149, 30, 194), (127, 21, 168), + (91, 5, 124), (122, 44, 152), (153, 84, 179), (184, 123, 206), + (215, 162, 234), (235, 188, 252), (185, 183, 215), (134, 178, 179), + (84, 173, 142), (33, 167, 106), (0, 164, 82), (34, 184, 109), + (67, 203, 135), (101, 223, 162), (157, 255, 206), (123, 250, 186), + (90, 244, 167), (56, 239, 147), (22, 234, 128), (0, 230, 115), + (10, 235, 123), (20, 241, 130), (30, 246, 138), (40, 251, 146), + (47, 255, 151), (37, 225, 131), (27, 196, 111), (17, 166, 91), + (0, 117, 58), (41, 147, 94), (83, 176, 129), (124, 206, 165), + (166, 236, 201), (193, 255, 224), (179, 200, 190), (165, 145, 155), + (151, 91, 121), (137, 36, 86), (128, 0, 64), (150, 8, 100), + (173, 15, 136), (195, 23, 172), (232, 36, 232), (229, 39, 210), + (227, 41, 188), (224, 44, 166), (222, 46, 144), (220, 48, 130), + (227, 88, 154), (234, 127, 178), (241, 167, 202), (252, 233, 242) + ), + +// 114 rw-multi-reds-oranges +((255, 0, 0), (255, 55, 55), (255, 91, 91), (255, 128, 128), + (251, 147, 132), (247, 167, 136), (245, 177, 138), (243, 187, 140), + (237, 219, 146), (232, 185, 124), (228, 152, 103), (222, 107, 74), + (216, 63, 46), (219, 77, 61), (222, 92, 77), (223, 99, 85), + (225, 106, 93), (230, 130, 119), (218, 118, 107), (206, 107, 96), + (194, 95, 84), (182, 84, 73), (178, 80, 69), (174, 77, 66), + (181, 111, 59), (186, 133, 54), (191, 156, 49), (200, 124, 48), + (209, 92, 48), (214, 75, 48), (219, 59, 48), (228, 27, 47), + (234, 6, 46), (229, 11, 106), (226, 13, 136), (224, 16, 166), + (221, 18, 166), (219, 21, 166), (217, 23, 156), (215, 25, 147), + (206, 34, 95), (206, 52, 105), (206, 70, 116), (206, 88, 127), + (206, 106, 138), (206, 112, 141), (207, 118, 145), (213, 137, 160), + (220, 155, 175), (233, 193, 205), (233, 177, 203), (233, 162, 202), + (229, 119, 189), (226, 76, 176), (223, 40, 165), (220, 5, 155), + (221, 23, 163), (221, 32, 167), (222, 41, 171), (226, 41, 155), + (230, 41, 140), (233, 37, 123), (237, 34, 107), (244, 28, 73), + (250, 21, 39), (252, 43, 20), (249, 68, 23), (246, 94, 26), + (243, 115, 28), (241, 136, 31), (236, 124, 36), (232, 111, 40), + (222, 86, 50), (218, 90, 53), (215, 95, 57), (210, 112, 61), + (206, 130, 66), (204, 138, 68), (202, 147, 70), (199, 158, 73), + (193, 148, 79), (182, 128, 90), (186, 126, 86), (190, 125, 82), + (198, 132, 73), (207, 139, 65), (225, 154, 47), (242, 168, 30), + (248, 168, 24), (242, 159, 29), (237, 151, 35), (234, 146, 37), + (232, 142, 40), (228, 136, 44), (222, 141, 50), (217, 146, 55), + (211, 151, 61), (198, 161, 74), (194, 163, 78), (190, 165, 82), + (188, 166, 84), (186, 168, 86), (183, 169, 89), (190, 145, 94), + (203, 97, 104), (208, 77, 108), (214, 58, 113), (212, 60, 118), + (210, 62, 123), (205, 67, 133), (201, 71, 143), (194, 78, 159), + (202, 70, 153), (217, 55, 142), (221, 51, 139), (225, 48, 136), + (230, 43, 132), (234, 39, 121), (238, 34, 110), (242, 30, 98), + (249, 23, 80), (234, 37, 88), (220, 52, 96), (213, 59, 100), + (206, 66, 104), (182, 90, 118), (192, 112, 137), (202, 135, 155), + (212, 157, 174), (228, 194, 205), (223, 176, 191), (219, 159, 177), + (210, 123, 149), (201, 88, 121), (186, 29, 75), (196, 44, 89), + (215, 74, 116), (223, 86, 127), (231, 99, 138), (224, 91, 130), + (218, 84, 123), (205, 68, 109), (192, 53, 94), (179, 37, 80), + (171, 27, 70), (139, 22, 57), (131, 20, 53), (123, 19, 50), + (96, 15, 39), (130, 39, 85), (164, 64, 132), (198, 88, 178), + (255, 128, 255), (251, 118, 238), (248, 108, 222), (241, 88, 189), + (234, 69, 156), (228, 49, 124), (223, 36, 102), (221, 62, 90), + (220, 87, 77), (216, 155, 44), (212, 152, 43), (208, 150, 42), + (201, 144, 40), (193, 139, 38), (186, 134, 35), (181, 130, 34), + (190, 110, 25), (192, 105, 22), (195, 100, 20), (200, 90, 15), + (203, 84, 12), (198, 78, 17), (193, 71, 22), (188, 65, 27), + (179, 54, 36), (194, 87, 41), (210, 120, 45), (225, 153, 50), + (241, 185, 54), (251, 207, 57), (244, 196, 64), (236, 186, 72), + (222, 164, 86), (219, 160, 88), (217, 157, 91), (213, 160, 95), + (209, 162, 100), (205, 165, 104), (198, 169, 111), (168, 184, 141), + (137, 200, 171), (107, 215, 201), (77, 231, 231), (57, 241, 251), + (95, 196, 227), (134, 151, 203), (172, 106, 179), (211, 61, 155), + (236, 32, 139), (230, 38, 133), (224, 44, 127), (218, 50, 122), + (208, 60, 112), (207, 61, 131), (207, 61, 150), (206, 62, 169), + (205, 63, 188), (204, 64, 201), (215, 53, 174), (225, 43, 146), + (236, 32, 119), (247, 21, 92), (254, 14, 74), (250, 43, 65), + (246, 72, 56), (242, 101, 48), (235, 149, 33), (228, 131, 40), + (220, 114, 48), (213, 96, 55), (206, 79, 62), (201, 67, 67), + (208, 94, 60), (216, 122, 52), (223, 149, 45), (230, 176, 38), + (235, 194, 33), (239, 185, 29), (242, 176, 26), (246, 167, 22), + (252, 152, 16), (236, 146, 32), (219, 140, 48), (203, 133, 64), + (187, 127, 80), (176, 123, 91), (186, 139, 111), (195, 156, 131), + (205, 172, 152), (215, 188, 172), (221, 199, 185), (222, 179, 176), + (223, 160, 167), (224, 140, 158), (225, 108, 143), (230, 103, 139), + (235, 99, 136), (240, 94, 132), (245, 89, 128), (248, 86, 126), + (250, 122, 154), (251, 159, 181), (253, 195, 209), (255, 255, 255) + ), + +// 115 rw-yellows-browns-goldish +((255, 255, 128), (246, 246, 113), (241, 241, 105), (236, 237, 97), + (231, 232, 89), (227, 228, 82), (224, 226, 78), (222, 224, 74), + (213, 215, 58), (208, 210, 50), (203, 206, 43), (198, 201, 35), + (194, 197, 27), (192, 196, 24), (191, 195, 21), (192, 196, 22), + (194, 198, 24), (201, 205, 31), (204, 208, 34), (207, 211, 37), + (210, 214, 40), (213, 217, 43), (214, 218, 44), (216, 220, 46), + (223, 227, 53), (226, 230, 56), (229, 233, 59), (230, 233, 60), + (231, 233, 62), (230, 231, 62), (229, 230, 62), (228, 226, 61), + (226, 222, 60), (222, 215, 59), (220, 211, 58), (219, 208, 57), + (217, 204, 56), (215, 200, 56), (214, 198, 55), (214, 197, 55), + (210, 189, 54), (207, 185, 53), (205, 182, 53), (202, 179, 53), + (200, 177, 54), (199, 175, 54), (198, 174, 55), (195, 172, 55), + (193, 169, 56), (188, 164, 57), (185, 161, 57), (183, 158, 58), + (180, 155, 58), (178, 153, 59), (176, 151, 59), (175, 150, 59), + (172, 154, 58), (173, 161, 56), (174, 169, 55), (174, 176, 53), + (175, 184, 51), (175, 187, 50), (176, 191, 49), (176, 199, 48), + (177, 206, 46), (179, 221, 42), (179, 228, 40), (180, 236, 39), + (180, 239, 38), (181, 243, 37), (181, 250, 35), (182, 252, 35), + (176, 231, 39), (173, 221, 41), (170, 211, 43), (167, 200, 45), + (165, 190, 48), (163, 185, 49), (162, 180, 50), (159, 169, 52), + (156, 159, 54), (150, 138, 58), (147, 128, 60), (145, 118, 62), + (143, 111, 63), (141, 105, 65), (148, 109, 63), (155, 114, 60), + (168, 122, 56), (175, 126, 53), (182, 131, 51), (185, 133, 50), + (189, 135, 49), (196, 139, 46), (202, 144, 44), (209, 148, 42), + (216, 152, 39), (230, 161, 35), (234, 166, 37), (238, 171, 39), + (238, 173, 43), (238, 176, 47), (238, 181, 54), (237, 187, 62), + (237, 197, 76), (236, 202, 83), (236, 207, 91), (236, 209, 94), + (236, 212, 98), (236, 217, 106), (235, 222, 113), (235, 228, 121), + (235, 233, 128), (230, 235, 133), (227, 232, 131), (225, 230, 130), + (221, 226, 126), (217, 221, 122), (212, 217, 119), (208, 212, 115), + (199, 204, 108), (194, 199, 104), (190, 195, 100), (188, 192, 98), + (186, 190, 97), (182, 186, 93), (177, 181, 89), (173, 177, 86), + (172, 176, 85), (183, 181, 92), (186, 182, 93), (189, 184, 95), + (194, 187, 98), (200, 190, 102), (205, 192, 105), (211, 195, 108), + (222, 201, 115), (227, 203, 118), (233, 206, 121), (236, 207, 123), + (239, 209, 125), (244, 212, 128), (251, 215, 132), (250, 211, 127), + (249, 208, 122), (247, 201, 112), (247, 199, 109), (247, 197, 107), + (246, 193, 102), (245, 190, 97), (244, 186, 92), (243, 183, 87), + (242, 176, 77), (241, 174, 74), (241, 172, 72), (240, 168, 67), + (239, 164, 61), (237, 162, 60), (235, 159, 60), (233, 157, 59), + (231, 155, 58), (227, 150, 56), (226, 149, 56), (225, 148, 56), + (223, 145, 55), (221, 143, 54), (219, 141, 53), (217, 138, 53), + (213, 134, 51), (212, 132, 50), (211, 131, 50), (210, 137, 50), + (208, 143, 50), (207, 148, 50), (206, 154, 50), (204, 160, 50), + (203, 166, 50), (202, 171, 50), (200, 177, 50), (199, 183, 50), + (198, 189, 50), (196, 194, 50), (195, 200, 50), (194, 206, 50), + (195, 216, 46), (197, 217, 45), (199, 218, 44), (202, 221, 41), + (206, 224, 38), (209, 227, 35), (212, 229, 33), (216, 232, 30), + (219, 235, 27), (222, 238, 24), (226, 240, 22), (229, 243, 19), + (232, 246, 16), (236, 249, 13), (239, 251, 11), (240, 252, 10), + (237, 248, 9), (233, 245, 9), (230, 241, 8), (226, 238, 8), + (223, 234, 7), (220, 231, 7), (216, 227, 6), (213, 224, 6), + (210, 220, 5), (206, 217, 4), (203, 213, 4), (200, 210, 3), + (196, 206, 3), (192, 202, 2), (192, 196, 5), (192, 191, 8), + (192, 185, 12), (192, 179, 15), (192, 174, 18), (192, 168, 21), + (193, 162, 25), (193, 156, 28), (193, 151, 31), (193, 145, 34), + (193, 139, 38), (193, 134, 41), (193, 128, 44), (194, 121, 48), + (196, 121, 46), (199, 121, 43), (201, 121, 41), (204, 121, 38), + (206, 121, 36), (208, 121, 34), (211, 121, 31), (213, 121, 29), + (216, 121, 26), (218, 121, 24), (220, 121, 22), (223, 121, 19), + (225, 121, 17), (228, 121, 14), (224, 127, 15), (220, 133, 17), + (217, 140, 18), (213, 146, 19), (209, 152, 21), (205, 158, 22), + (201, 164, 23), (198, 170, 25), (194, 177, 26), (190, 183, 27), + (186, 189, 29), (182, 195, 30), (179, 201, 31), (174, 209, 33) + ), + +// 116 rw-multi-blues-with-gray +((0, 0, 160), (17, 17, 169), (26, 26, 173), (35, 35, 178), + (43, 43, 182), (52, 52, 187), (56, 56, 189), (61, 61, 191), + (78, 78, 200), (86, 86, 204), (95, 95, 209), (104, 104, 213), + (113, 113, 218), (121, 121, 222), (130, 130, 227), (134, 134, 229), + (139, 139, 231), (156, 156, 240), (164, 164, 244), (173, 173, 249), + (174, 177, 250), (176, 182, 252), (172, 181, 250), (168, 180, 249), + (150, 174, 243), (141, 171, 240), (133, 169, 237), (124, 166, 234), + (116, 164, 231), (111, 162, 229), (107, 161, 228), (98, 158, 225), + (90, 156, 223), (72, 150, 217), (63, 147, 214), (55, 145, 211), + (46, 142, 208), (38, 140, 205), (33, 138, 203), (29, 137, 202), + (12, 132, 196), (10, 131, 194), (8, 130, 193), (16, 132, 194), + (24, 134, 195), (28, 135, 195), (32, 136, 196), (39, 137, 197), + (47, 139, 198), (63, 143, 200), (71, 145, 201), (79, 147, 202), + (86, 148, 203), (94, 150, 204), (98, 151, 204), (102, 152, 205), + (118, 156, 207), (126, 158, 208), (134, 160, 209), (142, 162, 210), + (150, 164, 211), (154, 165, 211), (158, 166, 212), (165, 167, 213), + (168, 168, 213), (165, 170, 216), (164, 170, 217), (163, 171, 218), + (162, 171, 218), (161, 172, 219), (160, 173, 221), (159, 174, 222), + (156, 175, 224), (155, 176, 225), (154, 177, 227), (152, 178, 228), + (151, 179, 229), (150, 179, 230), (150, 179, 231), (148, 180, 232), + (147, 181, 233), (144, 183, 236), (143, 183, 237), (142, 184, 238), + (141, 184, 239), (140, 185, 240), (134, 180, 237), (129, 176, 233), + (118, 166, 226), (112, 161, 222), (107, 157, 219), (104, 155, 217), + (101, 153, 216), (95, 148, 212), (90, 143, 209), (84, 139, 205), + (79, 134, 202), (67, 125, 195), (61, 120, 191), (56, 115, 188), + (53, 113, 186), (51, 111, 184), (45, 106, 181), (40, 101, 178), + (28, 92, 171), (25, 91, 168), (23, 90, 166), (24, 92, 166), + (25, 95, 167), (28, 99, 167), (30, 104, 168), (32, 108, 168), + (34, 113, 169), (39, 122, 170), (40, 124, 170), (41, 126, 170), + (43, 131, 171), (45, 135, 171), (47, 139, 172), (50, 144, 172), + (54, 153, 173), (56, 157, 173), (58, 162, 174), (59, 164, 174), + (61, 166, 175), (63, 171, 175), (65, 175, 176), (43, 171, 171), + (68, 181, 177), (74, 174, 181), (75, 172, 182), (77, 170, 183), + (80, 166, 185), (83, 163, 187), (86, 159, 189), (89, 155, 190), + (95, 148, 194), (98, 144, 196), (101, 141, 198), (102, 139, 199), + (104, 137, 200), (107, 133, 202), (110, 130, 204), (113, 126, 206), + (116, 122, 208), (122, 115, 212), (123, 113, 213), (125, 112, 214), + (128, 108, 215), (132, 103, 218), (129, 102, 220), (126, 101, 221), + (120, 99, 224), (118, 98, 225), (117, 98, 226), (114, 97, 228), + (111, 96, 229), (108, 95, 231), (105, 94, 232), (102, 93, 234), + (100, 93, 236), (94, 91, 239), (92, 90, 239), (91, 90, 240), + (88, 89, 242), (85, 88, 244), (82, 87, 245), (79, 86, 247), + (73, 84, 250), (71, 83, 251), (69, 83, 252), (69, 84, 247), + (69, 85, 241), (68, 86, 236), (68, 88, 230), (68, 89, 225), + (67, 90, 219), (67, 91, 214), (66, 92, 208), (66, 93, 203), + (66, 94, 197), (65, 95, 192), (65, 96, 186), (64, 98, 181), + (64, 100, 170), (63, 100, 167), (63, 101, 164), (63, 102, 159), + (63, 103, 153), (62, 104, 148), (62, 106, 142), (61, 107, 137), + (61, 107, 135), (67, 112, 139), (72, 116, 143), (78, 121, 147), + (84, 126, 152), (90, 131, 156), (95, 135, 160), (101, 140, 164), + (107, 145, 168), (112, 150, 172), (118, 154, 176), (124, 159, 180), + (130, 164, 184), (135, 169, 189), (141, 173, 193), (147, 178, 197), + (152, 183, 201), (158, 187, 205), (164, 192, 209), (170, 197, 213), + (175, 202, 218), (183, 208, 223), (176, 207, 220), (169, 206, 218), + (162, 204, 215), (155, 203, 212), (148, 202, 210), (141, 201, 207), + (134, 199, 205), (128, 198, 202), (121, 197, 199), (114, 196, 197), + (107, 195, 194), (100, 193, 192), (93, 192, 189), (86, 191, 186), + (79, 190, 184), (72, 188, 181), (65, 187, 178), (58, 186, 176), + (51, 185, 173), (44, 184, 170), (35, 182, 167), (33, 173, 171), + (32, 165, 175), (30, 156, 179), (28, 148, 184), (27, 139, 188), + (25, 131, 192), (24, 122, 196), (22, 114, 200), (20, 105, 204), + (19, 97, 208), (17, 88, 212), (15, 80, 216), (14, 71, 221), + (12, 63, 225), (10, 54, 229), (9, 46, 233), (7, 37, 237), + (5, 28, 241), (4, 20, 245), (2, 11, 250), (0, 0, 255) + ), + +// 117 rw-greens-multi +((0, 128, 64), (0, 152, 64), (0, 164, 64), (0, 176, 64), + (0, 187, 64), (0, 199, 64), (0, 205, 64), (0, 211, 64), + (0, 235, 64), (6, 239, 61), (12, 243, 58), (24, 231, 52), + (36, 219, 46), (48, 207, 40), (60, 195, 34), (66, 189, 31), + (72, 184, 28), (96, 160, 16), (108, 148, 10), (120, 136, 4), + (118, 138, 8), (116, 140, 12), (110, 146, 18), (104, 152, 24), + (80, 176, 48), (68, 187, 60), (56, 199, 72), (44, 211, 84), + (32, 223, 96), (26, 229, 102), (20, 235, 108), (8, 247, 120), + (0, 255, 128), (21, 255, 138), (31, 255, 143), (42, 255, 149), + (52, 255, 154), (62, 255, 159), (67, 255, 161), (73, 255, 164), + (94, 255, 174), (100, 252, 173), (106, 250, 172), (102, 244, 161), + (98, 239, 150), (95, 236, 144), (93, 234, 139), (88, 229, 128), + (84, 224, 117), (75, 213, 95), (70, 207, 84), (66, 202, 73), + (67, 199, 70), (68, 197, 68), (70, 196, 69), (73, 195, 71), + (82, 192, 75), (87, 190, 77), (92, 188, 80), (96, 186, 82), + (101, 184, 85), (103, 183, 86), (106, 182, 87), (75, 213, 96), + (114, 179, 91), (132, 193, 102), (140, 200, 107), (149, 207, 112), + (153, 210, 114), (158, 214, 117), (167, 221, 122), (176, 228, 128), + (193, 241, 138), (198, 244, 136), (204, 247, 135), (200, 241, 122), + (196, 236, 110), (194, 233, 104), (192, 230, 98), (188, 224, 85), + (184, 218, 73), (176, 206, 48), (172, 200, 35), (168, 195, 23), + (166, 193, 19), (165, 191, 15), (164, 197, 16), (164, 202, 18), + (162, 214, 21), (161, 219, 22), (160, 225, 23), (160, 227, 24), + (160, 230, 25), (159, 236, 26), (158, 242, 28), (157, 247, 29), + (157, 251, 30), (151, 244, 25), (148, 240, 22), (145, 237, 20), + (143, 235, 18), (142, 234, 17), (138, 230, 15), (135, 227, 12), + (129, 220, 7), (125, 215, 5), (122, 210, 3), (121, 208, 3), + (120, 206, 3), (118, 203, 3), (115, 199, 3), (113, 195, 3), + (111, 192, 3), (107, 184, 3), (106, 182, 3), (105, 180, 3), + (102, 176, 3), (101, 174, 2), (98, 169, 2), (95, 164, 2), + (89, 154, 2), (86, 149, 2), (83, 144, 2), (81, 141, 2), + (80, 139, 2), (77, 134, 2), (74, 128, 2), (71, 123, 2), + (69, 120, 1), (87, 139, 12), (91, 143, 14), (96, 148, 17), + (105, 158, 22), (114, 167, 28), (122, 176, 33), (131, 186, 38), + (149, 204, 49), (150, 213, 57), (152, 222, 65), (145, 223, 69), + (139, 224, 73), (127, 226, 80), (114, 228, 87), (102, 230, 95), + (89, 232, 102), (64, 236, 116), (58, 237, 120), (52, 238, 124), + (39, 240, 131), (31, 241, 136), (32, 240, 130), (34, 238, 125), + (36, 236, 114), (37, 235, 111), (38, 234, 108), (39, 233, 103), + (40, 232, 97), (42, 230, 92), (43, 229, 86), (45, 230, 100), + (45, 227, 77), (74, 222, 76), (81, 220, 76), (88, 219, 76), + (102, 217, 75), (116, 214, 75), (130, 212, 74), (145, 209, 74), + (173, 204, 73), (185, 202, 72), (197, 200, 72), (179, 193, 77), + (160, 186, 82), (142, 180, 88), (123, 173, 93), (105, 166, 98), + (86, 160, 104), (68, 153, 109), (49, 146, 114), (31, 139, 119), + (12, 132, 124), (0, 128, 128), (12, 140, 128), (24, 152, 128), + (48, 176, 128), (54, 182, 128), (60, 188, 128), (72, 199, 128), + (84, 211, 128), (96, 223, 128), (108, 235, 128), (128, 255, 128), + (128, 243, 122), (128, 231, 116), (128, 219, 110), (128, 207, 104), + (128, 195, 98), (128, 184, 92), (128, 172, 86), (128, 160, 80), + (128, 148, 74), (128, 136, 68), (128, 128, 64), (137, 137, 77), + (147, 147, 90), (156, 156, 103), (166, 166, 116), (175, 175, 129), + (184, 184, 142), (194, 194, 155), (203, 203, 168), (212, 212, 181), + (222, 222, 194), (228, 228, 203), (207, 224, 184), (185, 220, 165), + (164, 215, 146), (142, 211, 127), (121, 207, 108), (100, 203, 89), + (78, 198, 70), (57, 194, 51), (36, 190, 32), (0, 183, 0), + (0, 190, 0), (0, 196, 0), (0, 203, 0), (0, 209, 0), + (0, 216, 0), (0, 222, 0), (0, 229, 0), (0, 236, 0), + (0, 242, 0), (0, 249, 0), (0, 253, 0), (0, 241, 12), + (0, 230, 24), (0, 218, 36), (0, 206, 48), (0, 194, 60), + (0, 183, 72), (0, 171, 84), (0, 159, 96), (0, 148, 108), + (0, 136, 120), (0, 128, 128), (16, 140, 132), (32, 152, 136), + (47, 164, 139), (63, 176, 143), (79, 188, 147), (94, 199, 150), + (110, 211, 154), (126, 223, 158), (142, 235, 162), (168, 255, 168) + ), + +// 118 rw-browns-orange-yellow-with-blues +((128, 64, 64), (140, 76, 76), (146, 81, 81), (153, 87, 87), + (159, 93, 93), (165, 99, 99), (168, 102, 102), (172, 105, 105), + (187, 119, 119), (194, 120, 113), (201, 121, 107), (208, 122, 101), + (216, 123, 96), (223, 124, 90), (230, 125, 84), (233, 125, 81), + (237, 126, 78), (255, 128, 64), (255, 131, 69), (255, 135, 75), + (255, 138, 80), (255, 142, 86), (255, 144, 89), (255, 146, 92), + (255, 153, 103), (255, 156, 108), (255, 160, 114), (254, 156, 109), + (254, 153, 105), (253, 148, 98), (252, 144, 92), (251, 136, 80), + (250, 127, 68), (247, 109, 43), (245, 100, 30), (244, 92, 18), + (239, 84, 9), (234, 76, 0), (230, 75, 0), (226, 74, 0), + (210, 68, 0), (202, 65, 0), (194, 63, 0), (186, 60, 0), + (178, 58, 0), (174, 56, 0), (170, 55, 0), (166, 54, 0), + (163, 61, 3), (157, 74, 9), (154, 80, 12), (151, 87, 15), + (148, 93, 18), (145, 100, 21), (143, 103, 22), (142, 106, 24), + (144, 121, 29), (149, 125, 30), (155, 130, 31), (160, 134, 32), + (166, 139, 33), (169, 141, 33), (172, 144, 34), (177, 148, 35), + (183, 153, 36), (191, 160, 38), (195, 166, 50), (200, 172, 62), + (202, 175, 68), (205, 178, 74), (210, 184, 86), (214, 191, 98), + (223, 203, 122), (229, 210, 137), (235, 218, 152), (236, 219, 144), + (238, 220, 137), (239, 220, 133), (240, 221, 129), (241, 222, 122), + (243, 223, 114), (246, 225, 99), (247, 226, 91), (249, 227, 84), + (249, 227, 82), (250, 228, 80), (245, 222, 72), (239, 217, 64), + (228, 205, 48), (223, 199, 40), (218, 194, 33), (215, 191, 29), + (212, 188, 25), (207, 182, 17), (199, 174, 5), (205, 156, 5), + (211, 137, 4), (223, 101, 3), (228, 82, 2), (234, 64, 2), + (237, 55, 2), (240, 46, 2), (246, 27, 1), (252, 9, 1), + (240, 0, 0), (225, 0, 0), (211, 0, 0), (204, 0, 0), + (197, 0, 0), (182, 0, 0), (168, 0, 0), (153, 0, 0), + (139, 0, 0), (132, 20, 20), (139, 30, 30), (146, 41, 41), + (161, 61, 61), (175, 81, 81), (190, 102, 102), (204, 122, 122), + (233, 163, 163), (244, 178, 178), (255, 193, 193), (251, 193, 188), + (248, 193, 183), (240, 194, 173), (233, 194, 164), (226, 195, 154), + (219, 196, 144), (204, 197, 124), (200, 197, 119), (197, 197, 115), + (186, 198, 100), (189, 200, 107), (192, 203, 113), (195, 205, 120), + (201, 210, 133), (204, 212, 139), (207, 215, 146), (208, 216, 149), + (210, 217, 152), (213, 220, 159), (214, 221, 162), (218, 209, 172), + (223, 197, 182), (231, 172, 201), (233, 166, 206), (236, 160, 211), + (240, 148, 221), (244, 136, 231), (249, 124, 240), (255, 106, 255), + (237, 121, 242), (232, 124, 238), (227, 128, 235), (218, 135, 229), + (209, 142, 222), (200, 150, 216), (191, 157, 209), (182, 164, 203), + (172, 171, 196), (169, 157, 186), (170, 148, 182), (171, 139, 179), + (172, 121, 172), (173, 103, 166), (175, 85, 159), (176, 67, 152), + (179, 31, 138), (180, 17, 133), (181, 4, 128), (182, 20, 122), + (184, 35, 115), (185, 51, 109), (186, 67, 102), (188, 83, 96), + (189, 98, 89), (191, 114, 83), (192, 130, 77), (193, 145, 70), + (194, 153, 67), (198, 159, 78), (202, 166, 90), (205, 172, 101), + (213, 185, 124), (215, 188, 130), (217, 191, 136), (221, 197, 147), + (224, 204, 159), (230, 213, 176), (224, 208, 167), (219, 203, 157), + (213, 198, 148), (208, 193, 138), (202, 188, 129), (196, 183, 119), + (191, 178, 110), (185, 173, 100), (180, 168, 91), (177, 166, 86), + (184, 157, 77), (190, 147, 68), (197, 138, 59), (204, 129, 50), + (210, 120, 41), (217, 110, 32), (224, 101, 23), (230, 92, 13), + (240, 78, 0), (242, 85, 10), (243, 92, 19), (245, 99, 29), + (246, 106, 38), (248, 113, 48), (249, 120, 58), (251, 127, 67), + (253, 135, 77), (254, 142, 86), (255, 145, 91), (255, 151, 100), + (255, 157, 110), (255, 164, 119), (254, 170, 129), (254, 176, 138), + (254, 182, 148), (254, 189, 157), (254, 195, 167), (253, 204, 181), + (240, 189, 169), (227, 174, 156), (213, 160, 144), (200, 145, 132), + (187, 130, 119), (174, 115, 107), (161, 101, 95), (148, 86, 82), + (134, 71, 70), (128, 64, 64), (135, 71, 71), (141, 78, 78), + (148, 84, 84), (155, 91, 91), (161, 98, 98), (168, 104, 104), + (175, 111, 111), (181, 118, 118), (191, 128, 128), (195, 135, 135), + (198, 143, 143), (202, 150, 150), (206, 158, 158), (209, 165, 165), + (213, 173, 173), (217, 180, 180), (221, 188, 188), (226, 199, 199) + ), + +// 119 rw-reds-blues-greens-pinks +((255, 0, 0), (211, 22, 22), (189, 33, 33), (167, 44, 44), + (145, 55, 55), (124, 66, 66), (113, 71, 71), (102, 77, 77), + (58, 99, 99), (29, 113, 113), (0, 128, 128), (0, 139, 139), + (0, 150, 150), (0, 161, 161), (0, 172, 172), (0, 177, 177), + (0, 183, 183), (0, 204, 204), (0, 215, 215), (0, 226, 226), + (0, 237, 237), (0, 248, 248), (0, 251, 251), (0, 255, 255), + (44, 240, 255), (66, 232, 255), (88, 224, 255), (109, 216, 255), + (131, 209, 255), (142, 205, 255), (153, 201, 255), (175, 194, 255), + (197, 186, 255), (255, 166, 255), (233, 162, 255), (211, 159, 255), + (189, 156, 255), (167, 153, 255), (156, 151, 255), (145, 150, 255), + (102, 143, 255), (80, 140, 255), (58, 137, 255), (36, 133, 255), + (14, 130, 255), (7, 129, 255), (0, 128, 255), (11, 128, 255), + (22, 128, 255), (44, 128, 255), (55, 128, 255), (66, 128, 255), + (77, 128, 255), (88, 128, 255), (93, 128, 255), (99, 128, 255), + (121, 128, 255), (119, 133, 244), (117, 139, 233), (106, 150, 211), + (95, 161, 189), (89, 166, 178), (84, 172, 167), (73, 183, 145), + (62, 193, 124), (40, 215, 80), (29, 226, 58), (18, 237, 36), + (9, 246, 18), (0, 255, 0), (22, 233, 0), (44, 211, 0), + (88, 167, 0), (109, 145, 0), (131, 124, 0), (153, 102, 0), + (175, 80, 0), (186, 69, 0), (197, 58, 0), (219, 36, 0), + (241, 14, 0), (233, 11, 0), (211, 22, 0), (189, 33, 0), + (178, 38, 0), (167, 44, 0), (145, 55, 0), (124, 66, 0), + (80, 88, 0), (58, 99, 0), (36, 110, 0), (25, 115, 0), + (14, 121, 0), (0, 128, 0), (10, 117, 0), (20, 106, 0), + (30, 95, 0), (50, 73, 0), (60, 62, 0), (70, 51, 0), + (75, 45, 0), (80, 40, 0), (90, 29, 0), (101, 18, 0), + (129, 0, 0), (140, 0, 0), (152, 0, 0), (158, 0, 0), + (164, 0, 0), (175, 0, 0), (187, 0, 0), (199, 0, 0), + (210, 0, 0), (234, 0, 0), (240, 0, 0), (246, 0, 0), + (253, 0, 0), (242, 22, 11), (232, 44, 22), (221, 66, 33), + (199, 110, 55), (188, 131, 66), (178, 153, 77), (172, 164, 82), + (167, 175, 88), (156, 197, 99), (146, 219, 110), (135, 241, 121), + (128, 255, 128), (128, 233, 150), (128, 227, 155), (128, 222, 161), + (128, 211, 172), (128, 200, 183), (128, 190, 193), (128, 179, 204), + (128, 157, 226), (128, 142, 240), (128, 128, 255), (122, 128, 244), + (117, 128, 233), (106, 128, 211), (95, 128, 189), (84, 128, 167), + (73, 128, 145), (51, 128, 102), (45, 128, 91), (40, 128, 80), + (29, 128, 58), (18, 128, 36), (7, 128, 14), (0, 128, 0), + (44, 132, 26), (55, 132, 32), (66, 133, 38), (88, 135, 51), + (110, 137, 64), (131, 139, 77), (153, 141, 90), (175, 142, 102), + (197, 144, 115), (255, 149, 149), (255, 147, 147), (255, 146, 146), + (255, 144, 144), (255, 141, 141), (255, 139, 139), (255, 136, 136), + (255, 131, 131), (255, 129, 129), (255, 128, 128), (255, 126, 126), + (255, 123, 123), (255, 121, 121), (255, 119, 119), (255, 119, 131), + (255, 118, 142), (255, 118, 154), (255, 117, 166), (255, 117, 177), + (255, 116, 189), (255, 116, 201), (255, 115, 212), (255, 115, 224), + (255, 114, 248), (255, 113, 251), (255, 113, 255), (255, 107, 237), + (255, 101, 219), (255, 95, 201), (255, 90, 183), (255, 84, 165), + (255, 78, 147), (255, 72, 129), (255, 66, 111), (255, 60, 93), + (255, 55, 75), (255, 45, 45), (250, 41, 58), (246, 37, 72), + (241, 33, 85), (237, 30, 99), (232, 26, 112), (228, 22, 126), + (223, 18, 139), (219, 14, 153), (214, 10, 166), (209, 6, 180), + (205, 2, 193), (202, 0, 202), (204, 0, 185), (206, 0, 167), + (207, 0, 150), (209, 0, 133), (211, 0, 115), (213, 0, 98), + (215, 0, 80), (216, 0, 63), (218, 0, 46), (220, 0, 28), + (222, 0, 11), (223, 0, 0), (217, 12, 6), (212, 24, 12), + (206, 36, 19), (200, 47, 25), (195, 59, 31), (189, 71, 37), + (183, 83, 43), (178, 95, 50), (172, 107, 56), (166, 119, 62), + (157, 138, 72), (157, 126, 66), (158, 114, 60), (158, 102, 53), + (159, 91, 47), (160, 79, 41), (160, 67, 35), (161, 55, 29), + (161, 43, 22), (162, 31, 16), (163, 19, 10), (163, 8, 4), + (164, 0, 0), (160, 0, 0), (156, 0, 0), (152, 0, 0), + (148, 0, 0), (144, 0, 0), (140, 0, 0), (136, 0, 0), + (132, 0, 0), (128, 0, 0), (124, 0, 0), (117, 0, 0) + ), + +// 120 rw-reds-browns-golds-tans +((255, 0, 0), (253, 10, 2), (251, 15, 3), (250, 20, 4), + (249, 25, 5), (248, 30, 6), (247, 32, 6), (247, 35, 7), + (244, 45, 8), (243, 50, 9), (242, 55, 10), (241, 60, 11), + (240, 65, 12), (238, 70, 13), (237, 75, 14), (236, 77, 14), + (236, 80, 14), (234, 90, 16), (232, 95, 17), (231, 100, 18), + (230, 105, 19), (229, 110, 20), (228, 112, 20), (228, 115, 21), + (225, 125, 22), (224, 130, 23), (223, 135, 24), (222, 140, 25), + (221, 145, 26), (220, 147, 26), (219, 150, 27), (218, 155, 28), + (217, 160, 28), (216, 157, 30), (216, 155, 31), (216, 154, 32), + (215, 152, 32), (215, 151, 33), (215, 150, 33), (215, 150, 34), + (214, 146, 36), (213, 145, 37), (213, 144, 38), (213, 142, 38), + (213, 140, 39), (212, 139, 39), (212, 139, 40), (212, 138, 41), + (212, 136, 42), (211, 133, 44), (210, 131, 44), (210, 130, 45), + (210, 128, 46), (210, 127, 47), (209, 126, 47), (209, 126, 48), + (209, 122, 49), (208, 121, 50), (208, 120, 51), (207, 118, 52), + (207, 116, 53), (207, 115, 53), (207, 115, 54), (206, 114, 55), + (206, 112, 55), (209, 113, 52), (210, 113, 50), (212, 114, 48), + (213, 114, 47), (214, 114, 46), (215, 115, 45), (217, 115, 43), + (220, 116, 40), (221, 116, 38), (223, 117, 36), (224, 117, 34), + (226, 118, 33), (226, 118, 32), (227, 119, 31), (229, 119, 29), + (230, 120, 28), (234, 121, 24), (235, 121, 22), (237, 122, 21), + (237, 122, 20), (238, 122, 19), (240, 123, 17), (241, 123, 15), + (244, 124, 12), (245, 124, 10), (247, 125, 9), (248, 125, 8), + (249, 126, 7), (250, 126, 5), (252, 127, 3), (253, 127, 2), + (255, 128, 0), (250, 126, 0), (247, 124, 0), (245, 123, 0), + (244, 122, 0), (243, 122, 0), (240, 120, 0), (238, 119, 0), + (233, 117, 0), (230, 115, 0), (228, 114, 0), (226, 113, 0), + (225, 113, 0), (223, 112, 0), (220, 110, 0), (218, 109, 0), + (216, 108, 0), (211, 106, 0), (209, 105, 0), (208, 104, 0), + (206, 103, 0), (203, 102, 0), (201, 100, 0), (198, 99, 0), + (193, 97, 0), (190, 95, 0), (188, 94, 0), (187, 93, 0), + (186, 93, 0), (183, 92, 0), (181, 90, 0), (178, 89, 0), + (176, 88, 0), (181, 95, 8), (182, 96, 10), (183, 98, 12), + (186, 101, 16), (188, 104, 21), (191, 108, 25), (193, 111, 29), + (198, 118, 37), (200, 121, 41), (203, 124, 45), (204, 125, 47), + (206, 127, 50), (208, 131, 54), (211, 134, 58), (213, 137, 62), + (216, 140, 66), (220, 147, 74), (221, 148, 76), (223, 150, 78), + (225, 154, 82), (228, 157, 87), (230, 160, 91), (233, 163, 95), + (238, 170, 103), (239, 171, 105), (240, 173, 107), (243, 177, 111), + (245, 180, 116), (248, 183, 120), (250, 186, 124), (253, 190, 128), + (255, 193, 132), (255, 186, 128), (255, 184, 127), (255, 182, 127), + (255, 178, 125), (255, 174, 123), (255, 171, 121), (255, 167, 119), + (255, 160, 116), (255, 158, 115), (255, 156, 114), (255, 152, 112), + (255, 148, 110), (255, 145, 108), (255, 141, 107), (255, 137, 105), + (255, 134, 103), (255, 130, 101), (255, 126, 99), (255, 122, 98), + (255, 119, 96), (255, 115, 94), (255, 111, 92), (255, 107, 90), + (255, 100, 87), (255, 98, 86), (255, 96, 85), (255, 93, 83), + (255, 89, 81), (255, 85, 79), (255, 81, 78), (255, 78, 76), + (255, 74, 74), (254, 77, 75), (252, 79, 76), (251, 82, 76), + (250, 84, 77), (248, 87, 78), (247, 90, 79), (245, 92, 79), + (244, 95, 80), (243, 97, 81), (241, 100, 81), (240, 103, 82), + (238, 105, 83), (237, 108, 84), (236, 110, 84), (234, 113, 85), + (233, 116, 86), (232, 118, 86), (230, 121, 87), (229, 123, 88), + (228, 126, 89), (226, 128, 89), (225, 131, 90), (223, 134, 91), + (222, 136, 91), (221, 139, 92), (219, 141, 93), (218, 144, 94), + (216, 147, 94), (215, 149, 95), (214, 152, 96), (212, 154, 96), + (211, 157, 97), (211, 158, 99), (212, 159, 100), (212, 160, 102), + (213, 161, 104), (213, 162, 105), (214, 163, 107), (214, 164, 108), + (214, 165, 110), (215, 166, 112), (215, 167, 113), (216, 168, 115), + (216, 169, 116), (217, 170, 118), (217, 171, 120), (218, 172, 121), + (218, 173, 123), (218, 174, 125), (219, 175, 126), (219, 176, 128), + (220, 177, 130), (220, 178, 131), (221, 179, 133), (221, 180, 134), + (221, 181, 136), (222, 182, 138), (222, 183, 139), (223, 184, 141), + (223, 185, 142), (224, 186, 144), (224, 187, 146), (225, 189, 149) + ), + +// 121 dg009 +((19, 11, 23), (39, 24, 47), (54, 26, 47), (70, 29, 47), + (81, 27, 44), (92, 25, 42), (101, 12, 38), (110, 0, 35), + (113, 28, 49), (93, 28, 45), (74, 28, 41), (72, 33, 50), + (71, 38, 59), (77, 58, 94), (83, 79, 130), (90, 93, 139), + (98, 107, 148), (115, 102, 171), (98, 92, 141), (81, 82, 112), + (78, 79, 108), (75, 76, 104), (74, 75, 103), (73, 74, 102), + (97, 56, 96), (89, 41, 71), (82, 27, 46), (62, 28, 50), + (42, 30, 54), (39, 27, 49), (37, 25, 45), (34, 26, 41), + (29, 25, 40), (25, 27, 40), (23, 27, 40), (21, 27, 41), + (17, 34, 47), (13, 41, 53), (19, 54, 61), (26, 67, 69), + (43, 70, 79), (44, 60, 76), (45, 51, 73), (44, 41, 59), + (43, 32, 46), (51, 29, 43), (60, 26, 40), (53, 25, 40), + (41, 17, 49), (37, 29, 50), (37, 31, 53), (38, 34, 57), + (37, 32, 55), (36, 31, 54), (36, 28, 50), (37, 25, 47), + (37, 26, 43), (37, 25, 42), (38, 25, 42), (37, 25, 41), + (37, 26, 40), (36, 25, 39), (36, 25, 39), (31, 25, 39), + (29, 20, 37), (26, 31, 50), (27, 39, 57), (29, 48, 65), + (34, 47, 70), (40, 47, 75), (49, 48, 90), (49, 62, 94), + (66, 67, 97), (69, 70, 99), (72, 73, 101), (70, 72, 98), + (69, 71, 96), (69, 71, 96), (69, 71, 96), (68, 69, 97), + (65, 63, 103), (67, 74, 116), (70, 78, 122), (74, 82, 129), + (79, 89, 136), (84, 96, 144), (85, 111, 134), (82, 110, 114), + (73, 74, 102), (61, 74, 90), (50, 75, 79), (50, 72, 67), + (51, 69, 55), (38, 41, 58), (44, 41, 70), (50, 49, 81), + (61, 59, 98), (46, 93, 99), (54, 91, 105), (62, 90, 112), + (67, 96, 111), (72, 102, 110), (81, 111, 121), (116, 124, 161), + (112, 123, 169), (95, 100, 145), (78, 77, 121), (73, 77, 120), + (69, 78, 119), (73, 103, 111), (88, 110, 134), (116, 126, 161), + (110, 139, 171), (112, 128, 187), (115, 127, 177), (119, 126, 168), + (123, 111, 161), (145, 98, 152), (139, 92, 146), (98, 72, 135), + (74, 75, 103), (68, 68, 101), (63, 61, 100), (57, 55, 93), + (51, 49, 86), (39, 38, 70), (27, 24, 55), (21, 26, 48), + (16, 22, 48), (21, 27, 43), (22, 30, 44), (23, 33, 45), + (25, 35, 47), (24, 34, 46), (25, 31, 45), (28, 27, 45), + (35, 27, 42), (36, 26, 42), (37, 26, 42), (37, 26, 42), + (37, 26, 42), (37, 26, 42), (37, 26, 42), (37, 26, 42), + (37, 26, 42), (36, 28, 41), (36, 29, 42), (36, 30, 44), + (27, 44, 54), (23, 52, 60), (25, 56, 61), (26, 55, 61), + (34, 40, 62), (25, 41, 62), (17, 42, 62), (10, 39, 53), + (15, 23, 46), (0, 0, 25), (0, 0, 25), (0, 0, 25), + (15, 21, 33), (28, 27, 43), (30, 28, 44), (33, 29, 46), + (32, 30, 51), (26, 31, 50), (19, 34, 53), (20, 33, 42), + (22, 28, 42), (23, 25, 41), (24, 23, 41), (26, 21, 43), + (30, 21, 42), (32, 25, 43), (35, 27, 42), (37, 26, 42), + (38, 25, 42), (43, 20, 38), (50, 18, 31), (76, 1, 32), + (80, 15, 37), (87, 24, 41), (84, 31, 51), (99, 30, 49), + (181, 60, 93), (177, 63, 92), (174, 66, 92), (157, 78, 109), + (197, 102, 142), (201, 125, 155), (126, 137, 159), (119, 124, 154), + (88, 82, 128), (76, 77, 105), (76, 77, 105), (74, 75, 103), + (73, 74, 102), (70, 71, 99), (68, 69, 97), (61, 63, 101), + (60, 62, 100), (63, 61, 100), (68, 69, 97), (68, 70, 95), + (70, 71, 99), (72, 73, 101), (74, 75, 103), (71, 72, 100), + (71, 72, 100), (69, 73, 98), (66, 67, 95), (86, 41, 70), + (118, 33, 56), (140, 30, 39), (149, 38, 55), (132, 28, 65), + (135, 43, 68), (152, 70, 93), (147, 71, 101), (134, 73, 80), + (109, 54, 75), (79, 80, 108), (107, 120, 152), (135, 139, 187), + (141, 140, 197), (214, 220, 255), (202, 214, 255), (136, 147, 203), + (114, 125, 171), (84, 107, 141), (77, 78, 106), (67, 71, 96), + (46, 55, 86), (33, 47, 76), (41, 61, 70), (42, 69, 78), + (49, 68, 82), (63, 64, 92), (66, 67, 97), (63, 63, 97), + (56, 55, 89), (49, 43, 79), (38, 38, 62), (39, 37, 59), + (38, 36, 60), (37, 39, 62), (40, 50, 75), (53, 58, 87), + (58, 58, 94), (61, 49, 97), (53, 40, 83), (42, 43, 74), + (36, 40, 65), (36, 35, 69), (51, 53, 91), (40, 37, 90) + ), + +// 122 dg016 +((25, 30, 34), (51, 61, 70), (46, 53, 62), (42, 45, 54), + (34, 44, 43), (27, 43, 32), (27, 42, 30), (28, 42, 29), + (22, 39, 23), (20, 33, 21), (18, 28, 19), (18, 24, 18), + (18, 20, 17), (17, 19, 16), (16, 18, 15), (16, 18, 15), + (16, 18, 15), (16, 21, 17), (14, 23, 18), (13, 26, 19), + (19, 34, 24), (26, 42, 29), (24, 44, 31), (23, 47, 34), + (11, 46, 42), (11, 53, 40), (12, 60, 38), (6, 61, 44), + (0, 62, 51), (7, 65, 53), (15, 69, 55), (25, 64, 63), + (34, 47, 64), (40, 43, 60), (40, 43, 59), (41, 44, 59), + (41, 44, 59), (42, 45, 60), (41, 44, 59), (41, 44, 59), + (33, 53, 62), (26, 64, 59), (20, 75, 56), (15, 88, 61), + (10, 101, 66), (10, 105, 69), (10, 110, 72), (18, 107, 79), + (13, 90, 58), (38, 59, 62), (39, 51, 58), (40, 44, 55), + (35, 39, 46), (30, 34, 37), (28, 34, 37), (26, 34, 37), + (21, 36, 55), (18, 50, 64), (15, 65, 74), (12, 89, 93), + (10, 114, 113), (9, 121, 98), (9, 129, 83), (13, 104, 71), + (11, 82, 52), (0, 37, 14), (5, 24, 10), (11, 12, 7), + (9, 13, 7), (7, 14, 7), (0, 14, 4), (0, 17, 5), + (19, 22, 27), (22, 28, 37), (26, 34, 47), (33, 38, 53), + (40, 43, 60), (41, 51, 63), (43, 60, 67), (53, 75, 62), + (48, 95, 85), (70, 103, 92), (61, 87, 77), (52, 72, 63), + (47, 65, 55), (42, 58, 47), (36, 54, 38), (33, 45, 31), + (34, 39, 35), (38, 42, 48), (43, 46, 61), (45, 48, 63), + (47, 50, 65), (53, 60, 86), (61, 74, 108), (69, 77, 114), + (69, 76, 105), (35, 44, 75), (20, 37, 65), (5, 31, 56), + (6, 32, 51), (7, 33, 46), (7, 36, 42), (10, 40, 38), + (9, 28, 35), (4, 16, 32), (0, 4, 29), (0, 5, 23), + (0, 6, 18), (2, 18, 18), (6, 23, 17), (11, 21, 13), + (17, 23, 9), (18, 20, 17), (17, 20, 17), (16, 21, 17), + (16, 21, 24), (14, 32, 34), (13, 42, 48), (13, 44, 39), + (15, 59, 32), (16, 66, 35), (18, 74, 39), (15, 76, 43), + (12, 79, 48), (10, 74, 50), (11, 71, 45), (16, 65, 36), + (28, 59, 43), (40, 43, 58), (40, 43, 58), (40, 43, 58), + (41, 44, 59), (41, 44, 59), (40, 43, 58), (40, 43, 58), + (38, 41, 56), (25, 43, 55), (12, 45, 54), (11, 44, 56), + (10, 43, 58), (12, 42, 52), (17, 45, 49), (32, 45, 51), + (39, 42, 57), (41, 44, 59), (41, 44, 59), (42, 45, 60), + (42, 45, 60), (42, 45, 60), (43, 46, 61), (46, 47, 65), + (41, 42, 62), (41, 42, 61), (41, 42, 60), (41, 44, 59), + (42, 45, 60), (42, 45, 60), (42, 45, 60), (44, 47, 62), + (46, 53, 63), (44, 62, 100), (47, 63, 105), (50, 64, 111), + (44, 64, 115), (28, 67, 98), (31, 51, 75), (24, 50, 77), + (14, 47, 56), (22, 44, 58), (30, 41, 61), (38, 41, 58), + (39, 42, 57), (40, 43, 58), (43, 44, 64), (34, 46, 68), + (14, 56, 68), (9, 71, 96), (10, 95, 132), (12, 105, 146), + (9, 117, 179), (15, 156, 173), (51, 198, 146), (56, 166, 129), + (10, 85, 54), (11, 73, 47), (13, 62, 40), (20, 37, 29), + (12, 27, 24), (16, 25, 24), (22, 31, 26), (21, 29, 32), + (28, 33, 36), (26, 37, 41), (23, 34, 40), (20, 28, 47), + (19, 28, 45), (22, 21, 27), (30, 16, 13), (18, 20, 17), + (17, 21, 20), (18, 22, 25), (23, 26, 31), (30, 35, 39), + (37, 36, 44), (41, 43, 55), (40, 43, 58), (40, 43, 58), + (40, 43, 58), (39, 42, 57), (39, 42, 57), (40, 43, 58), + (40, 43, 58), (40, 43, 58), (40, 43, 58), (39, 42, 57), + (38, 41, 56), (35, 41, 53), (31, 36, 40), (21, 42, 37), + (11, 52, 48), (10, 54, 67), (19, 61, 77), (16, 74, 98), + (11, 83, 107), (25, 78, 112), (28, 84, 101), (27, 66, 83), + (26, 53, 70), (42, 48, 62), (42, 45, 60), (43, 46, 61), + (45, 58, 75), (52, 67, 100), (55, 70, 109), (53, 73, 124), + (73, 81, 127), (55, 77, 134), (44, 137, 142), (85, 139, 116), + (94, 118, 104), (87, 97, 96), (67, 76, 85), (53, 66, 85), + (41, 58, 74), (43, 46, 61), (36, 42, 54), (31, 42, 38), + (20, 37, 31), (22, 26, 27), (21, 22, 26), (22, 26, 27), + (26, 33, 26), (30, 39, 36), (45, 63, 51), (40, 53, 46) + ), + +// 123 dg031 +((4, 9, 8), (10, 19, 18), (12, 19, 20), (14, 19, 22), + (14, 21, 22), (14, 23, 22), (15, 22, 23), (16, 21, 24), + (11, 22, 28), (10, 18, 37), (10, 15, 47), (16, 30, 55), + (23, 46, 64), (41, 76, 90), (59, 107, 117), (73, 121, 135), + (88, 135, 153), (117, 169, 190), (121, 167, 191), (126, 166, 192), + (148, 159, 162), (170, 153, 133), (183, 162, 123), (196, 171, 114), + (172, 150, 90), (134, 118, 84), (97, 87, 78), (76, 77, 72), + (55, 67, 67), (71, 65, 65), (87, 63, 63), (124, 92, 54), + (176, 145, 78), (193, 223, 249), (196, 228, 250), (200, 233, 252), + (190, 225, 244), (181, 218, 237), (178, 216, 237), (176, 214, 237), + (83, 152, 167), (56, 109, 120), (29, 66, 74), (27, 59, 66), + (25, 52, 59), (27, 56, 62), (29, 60, 65), (29, 59, 70), + (33, 85, 98), (61, 124, 139), (70, 116, 127), (79, 108, 116), + (99, 100, 84), (120, 92, 53), (132, 102, 62), (145, 112, 71), + (190, 164, 103), (206, 168, 106), (222, 172, 109), (197, 151, 94), + (172, 131, 79), (145, 110, 65), (118, 90, 51), (95, 61, 33), + (67, 31, 33), (36, 22, 37), (31, 32, 43), (26, 43, 50), + (26, 45, 50), (27, 48, 51), (27, 50, 58), (22, 40, 54), + (14, 29, 34), (14, 29, 33), (15, 29, 32), (16, 28, 31), + (17, 28, 30), (17, 29, 30), (18, 30, 30), (43, 33, 21), + (59, 43, 27), (114, 84, 50), (133, 84, 44), (152, 84, 39), + (155, 99, 54), (159, 115, 70), (173, 124, 58), (178, 118, 58), + (177, 143, 79), (179, 148, 83), (182, 153, 87), (185, 155, 86), + (188, 158, 86), (193, 150, 81), (203, 147, 70), (171, 106, 42), + (152, 81, 37), (78, 52, 29), (47, 38, 27), (16, 24, 26), + (14, 21, 22), (12, 18, 18), (13, 17, 18), (10, 16, 16), + (13, 13, 13), (12, 14, 14), (11, 15, 16), (11, 16, 18), + (12, 17, 20), (15, 25, 26), (16, 31, 34), (24, 41, 51), + (26, 55, 59), (30, 61, 82), (26, 64, 85), (23, 68, 89), + (29, 85, 100), (32, 66, 76), (30, 59, 67), (29, 60, 65), + (17, 44, 51), (16, 35, 40), (16, 27, 29), (16, 25, 30), + (17, 24, 32), (16, 29, 35), (17, 36, 42), (27, 51, 55), + (27, 58, 63), (39, 100, 118), (62, 99, 125), (85, 98, 132), + (84, 95, 125), (119, 89, 53), (92, 65, 38), (27, 48, 41), + (14, 22, 24), (11, 15, 15), (9, 8, 6), (4, 5, 3), + (0, 2, 1), (10, 14, 15), (18, 23, 26), (28, 27, 43), + (23, 52, 60), (60, 116, 129), (70, 127, 143), (80, 138, 158), + (82, 143, 162), (62, 129, 146), (55, 105, 114), (46, 105, 119), + (34, 72, 81), (43, 84, 94), (53, 97, 108), (104, 133, 137), + (128, 127, 133), (147, 159, 181), (171, 214, 230), (179, 214, 234), + (137, 183, 206), (88, 145, 164), (70, 126, 146), (53, 108, 129), + (25, 74, 107), (26, 55, 63), (19, 44, 49), (14, 28, 31), + (5, 4, 9), (2, 2, 5), (0, 0, 2), (0, 0, 0), + (1, 1, 1), (8, 0, 0), (11, 0, 0), (23, 10, 0), + (13, 13, 13), (13, 17, 16), (15, 14, 20), (16, 15, 20), + (31, 17, 8), (38, 25, 8), (47, 25, 4), (33, 15, 5), + (17, 23, 23), (16, 25, 25), (15, 27, 27), (16, 31, 34), + (24, 44, 43), (37, 46, 43), (40, 45, 49), (27, 46, 50), + (26, 46, 47), (22, 46, 48), (19, 37, 39), (14, 25, 27), + (15, 19, 20), (25, 13, 15), (46, 18, 17), (70, 26, 39), + (85, 34, 39), (97, 39, 35), (108, 48, 58), (86, 33, 61), + (48, 51, 56), (28, 52, 54), (25, 52, 59), (21, 56, 62), + (25, 58, 67), (26, 78, 92), (58, 120, 135), (89, 152, 170), + (94, 157, 172), (120, 177, 194), (89, 155, 171), (54, 121, 138), + (34, 82, 96), (27, 52, 56), (24, 35, 39), (13, 18, 21), + (8, 7, 5), (1, 1, 1), (0, 0, 0), (0, 0, 2), + (8, 10, 9), (10, 8, 9), (12, 7, 13), (11, 9, 10), + (3, 4, 6), (1, 1, 1), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (10, 0, 0), (11, 10, 8), + (14, 18, 19), (16, 27, 31), (33, 32, 40), (48, 36, 58), + (103, 55, 53), (122, 60, 49), (134, 68, 36), (100, 58, 34), + (69, 47, 24), (56, 37, 20), (39, 25, 14), (28, 18, 8), + (14, 15, 17), (14, 18, 19), (16, 20, 21), (33, 16, 24), + (55, 32, 16), (93, 50, 15), (160, 83, 31), (145, 68, 24) + ), + +// 124 dg085 +((82, 50, 8), (166, 101, 17), (136, 82, 19), (107, 64, 22), + (92, 56, 24), (77, 49, 27), (68, 46, 29), (60, 44, 31), + (59, 43, 30), (58, 42, 29), (58, 42, 29), (57, 41, 29), + (57, 40, 30), (60, 40, 29), (63, 41, 28), (68, 39, 21), + (74, 38, 14), (79, 45, 17), (74, 43, 18), (69, 41, 20), + (65, 40, 23), (62, 40, 26), (60, 40, 26), (59, 41, 27), + (59, 43, 30), (59, 43, 30), (59, 43, 30), (58, 42, 29), + (58, 42, 29), (57, 41, 27), (57, 41, 26), (57, 41, 25), + (57, 30, 11), (49, 28, 9), (52, 34, 18), (56, 40, 27), + (56, 40, 27), (56, 40, 27), (56, 39, 26), (57, 39, 25), + (40, 21, 4), (47, 19, 2), (55, 17, 0), (55, 23, 4), + (56, 29, 8), (58, 31, 9), (61, 33, 11), (72, 38, 13), + (85, 52, 19), (114, 66, 30), (127, 76, 35), (140, 86, 40), + (167, 93, 37), (194, 101, 34), (202, 106, 26), (211, 112, 18), + (182, 98, 26), (167, 96, 32), (153, 94, 38), (146, 85, 31), + (140, 77, 24), (140, 76, 28), (140, 76, 32), (140, 86, 40), + (147, 84, 43), (153, 92, 45), (133, 77, 35), (113, 63, 26), + (110, 61, 26), (108, 59, 26), (88, 56, 31), (63, 47, 34), + (60, 44, 31), (60, 43, 32), (60, 43, 33), (72, 50, 34), + (85, 57, 35), (92, 61, 33), (100, 66, 31), (118, 79, 40), + (157, 95, 56), (228, 151, 83), (241, 173, 84), (255, 195, 85), + (255, 205, 111), (255, 215, 137), (232, 205, 90), (230, 188, 80), + (228, 155, 86), (237, 151, 73), (246, 148, 61), (238, 147, 55), + (230, 146, 50), (210, 138, 66), (204, 126, 60), (192, 107, 42), + (168, 106, 65), (129, 85, 46), (132, 82, 38), (135, 79, 30), + (130, 76, 33), (126, 74, 37), (110, 73, 29), (131, 70, 25), + (146, 82, 21), (162, 84, 27), (178, 87, 34), (173, 90, 24), + (169, 93, 15), (151, 72, 13), (114, 63, 16), (104, 62, 20), + (103, 59, 20), (130, 59, 7), (134, 60, 8), (139, 62, 10), + (153, 88, 20), (165, 115, 30), (186, 116, 21), (207, 119, 19), + (183, 113, 41), (158, 100, 50), (133, 88, 59), (125, 84, 55), + (117, 80, 51), (112, 78, 51), (127, 90, 61), (166, 113, 69), + (198, 149, 90), (207, 172, 144), (186, 148, 117), (165, 125, 90), + (141, 91, 58), (116, 78, 42), (107, 64, 30), (83, 52, 31), + (59, 43, 30), (63, 41, 24), (67, 39, 18), (69, 40, 17), + (72, 42, 16), (77, 44, 0), (72, 40, 0), (67, 36, 15), + (61, 25, 11), (65, 39, 16), (65, 39, 17), (66, 39, 18), + (58, 40, 26), (57, 41, 26), (56, 40, 27), (57, 41, 28), + (58, 41, 33), (58, 41, 32), (59, 42, 32), (59, 42, 32), + (60, 43, 33), (62, 44, 32), (64, 46, 34), (85, 53, 30), + (91, 57, 30), (82, 44, 21), (80, 43, 19), (79, 43, 17), + (75, 29, 14), (72, 33, 0), (103, 37, 0), (121, 40, 0), + (134, 68, 0), (126, 64, 0), (118, 61, 0), (101, 44, 0), + (83, 40, 0), (66, 27, 0), (59, 10, 0), (57, 11, 0), + (60, 20, 0), (77, 41, 9), (94, 55, 16), (130, 69, 6), + (146, 71, 3), (147, 64, 0), (151, 72, 3), (162, 83, 4), + (134, 85, 44), (130, 83, 49), (126, 82, 55), (113, 88, 81), + (103, 87, 72), (110, 84, 67), (100, 73, 62), (97, 64, 45), + (103, 68, 36), (104, 60, 31), (90, 56, 31), (71, 50, 31), + (62, 46, 33), (60, 41, 35), (60, 40, 33), (59, 42, 32), + (60, 43, 33), (58, 44, 33), (56, 44, 32), (57, 48, 31), + (56, 48, 25), (57, 43, 30), (55, 41, 30), (53, 40, 32), + (54, 41, 32), (57, 43, 32), (57, 43, 34), (56, 41, 36), + (54, 44, 34), (60, 46, 35), (63, 46, 36), (64, 43, 40), + (85, 60, 53), (84, 63, 44), (98, 61, 35), (112, 67, 34), + (121, 77, 40), (128, 92, 60), (145, 105, 70), (150, 104, 68), + (149, 112, 85), (150, 117, 82), (164, 115, 82), (167, 123, 76), + (174, 114, 62), (177, 108, 51), (167, 100, 45), (187, 103, 31), + (201, 105, 19), (199, 102, 8), (172, 98, 9), (133, 74, 6), + (122, 66, 5), (108, 54, 10), (85, 46, 7), (77, 37, 11), + (65, 32, 13), (67, 31, 9), (78, 40, 1), (94, 42, 0), + (106, 53, 11), (117, 59, 9), (91, 55, 21), (91, 58, 27), + (75, 48, 19), (63, 44, 29), (60, 44, 31), (61, 42, 27), + (82, 48, 23), (103, 56, 28), (130, 66, 18), (160, 79, 23) + ), + +// 125 dg086 +((108, 104, 99), (218, 209, 200), (224, 212, 207), (230, 216, 215), + (226, 212, 211), (222, 208, 208), (218, 205, 205), (215, 203, 203), + (208, 190, 186), (209, 179, 181), (211, 168, 177), (213, 178, 184), + (215, 189, 192), (215, 195, 196), (215, 201, 200), (216, 204, 201), + (217, 208, 203), (225, 211, 210), (227, 210, 211), (230, 210, 212), + (228, 211, 212), (227, 213, 212), (227, 213, 211), (227, 213, 210), + (223, 219, 208), (224, 211, 207), (226, 204, 207), (224, 199, 202), + (223, 194, 198), (220, 193, 197), (218, 193, 196), (218, 191, 182), + (211, 184, 175), (205, 162, 171), (201, 156, 165), (198, 151, 159), + (189, 122, 134), (180, 93, 109), (171, 83, 101), (163, 74, 94), + (149, 66, 86), (138, 62, 81), (127, 58, 76), (134, 61, 80), + (142, 65, 85), (141, 65, 85), (141, 66, 86), (122, 103, 96), + (122, 114, 103), (133, 123, 111), (132, 121, 115), (131, 119, 119), + (132, 124, 118), (133, 129, 117), (139, 134, 122), (145, 139, 127), + (175, 166, 167), (193, 171, 174), (211, 176, 182), (216, 183, 189), + (222, 191, 196), (223, 194, 198), (224, 198, 201), (224, 204, 205), + (229, 215, 215), (244, 229, 226), (249, 236, 229), (255, 243, 232), + (255, 245, 241), (255, 247, 250), (250, 242, 240), (243, 240, 235), + (237, 223, 222), (238, 229, 227), (240, 236, 233), (241, 230, 228), + (243, 225, 223), (241, 223, 223), (240, 221, 223), (242, 224, 214), + (246, 219, 208), (227, 208, 204), (211, 199, 195), (196, 191, 187), + (192, 185, 180), (189, 180, 173), (179, 171, 160), (159, 151, 138), + (129, 123, 123), (138, 124, 127), (147, 126, 131), (154, 132, 132), + (162, 139, 133), (171, 154, 144), (183, 176, 168), (205, 180, 173), + (216, 189, 180), (217, 197, 190), (216, 198, 195), (216, 200, 201), + (216, 200, 203), (216, 201, 206), (217, 203, 203), (217, 203, 200), + (214, 187, 178), (205, 170, 168), (196, 154, 158), (192, 136, 146), + (189, 118, 134), (173, 82, 100), (168, 71, 90), (170, 74, 88), + (176, 87, 105), (197, 129, 144), (192, 136, 146), (188, 143, 148), + (185, 154, 149), (181, 154, 147), (174, 150, 140), (163, 155, 144), + (146, 138, 127), (151, 135, 127), (157, 132, 128), (163, 129, 128), + (169, 127, 129), (170, 123, 131), (159, 125, 115), (141, 120, 103), + (144, 112, 97), (125, 61, 78), (105, 66, 70), (86, 72, 63), + (87, 88, 80), (105, 93, 93), (113, 108, 102), (125, 117, 104), + (161, 149, 149), (185, 166, 162), (210, 183, 176), (215, 188, 181), + (220, 193, 186), (224, 195, 199), (227, 211, 211), (241, 219, 208), + (238, 214, 204), (226, 199, 190), (222, 196, 188), (218, 193, 186), + (213, 186, 177), (209, 182, 173), (208, 181, 174), (198, 170, 159), + (183, 156, 149), (178, 151, 144), (174, 147, 140), (163, 139, 135), + (164, 134, 132), (163, 136, 129), (165, 143, 119), (166, 158, 147), + (194, 167, 160), (206, 179, 172), (210, 183, 181), (214, 188, 191), + (214, 192, 194), (215, 193, 195), (217, 197, 198), (223, 203, 204), + (228, 210, 210), (228, 212, 211), (228, 214, 213), (228, 214, 213), + (226, 208, 208), (220, 206, 205), (216, 209, 199), (211, 196, 193), + (212, 185, 176), (200, 173, 166), (184, 159, 154), (174, 147, 140), + (167, 138, 134), (176, 141, 122), (172, 160, 138), (185, 171, 158), + (190, 188, 167), (189, 184, 173), (189, 181, 179), (203, 176, 169), + (198, 171, 164), (186, 166, 155), (178, 151, 144), (172, 144, 140), + (162, 134, 130), (163, 135, 131), (174, 143, 140), (198, 153, 160), + (212, 166, 176), (230, 185, 182), (233, 206, 197), (237, 210, 201), + (240, 213, 202), (236, 209, 198), (219, 199, 200), (204, 199, 195), + (198, 198, 190), (197, 187, 178), (183, 174, 165), (184, 157, 150), + (174, 147, 140), (177, 150, 143), (185, 158, 151), (188, 161, 154), + (196, 167, 161), (205, 168, 175), (219, 174, 179), (215, 191, 181), + (203, 201, 188), (200, 199, 181), (172, 163, 156), (155, 133, 135), + (130, 109, 106), (103, 77, 80), (87, 70, 62), (51, 44, 34), + (44, 35, 26), (82, 62, 63), (88, 92, 78), (107, 98, 93), + (118, 104, 95), (121, 111, 101), (122, 112, 111), (115, 103, 103), + (115, 97, 97), (148, 67, 86), (152, 67, 88), (155, 67, 89), + (160, 65, 85), (172, 81, 99), (185, 106, 125), (197, 141, 152), + (201, 154, 164), (199, 156, 163), (196, 149, 155), (185, 132, 140), + (179, 95, 111), (168, 76, 99), (165, 70, 90), (161, 77, 90), + (168, 86, 100), (176, 128, 116), (151, 126, 122), (144, 131, 125), + (135, 121, 118), (136, 128, 117), (140, 136, 124), (142, 132, 120) + ), + +// 126 dg089 +((57, 57, 57), (116, 116, 116), (111, 113, 116), (106, 111, 117), + (99, 106, 120), (93, 101, 124), (88, 98, 119), (83, 96, 115), + (78, 92, 105), (65, 96, 122), (52, 100, 140), (72, 103, 128), + (92, 106, 117), (103, 113, 122), (114, 121, 127), (118, 124, 127), + (123, 127, 128), (130, 133, 140), (133, 133, 134), (137, 134, 129), + (135, 135, 122), (134, 137, 116), (136, 135, 121), (138, 133, 127), + (133, 137, 138), (166, 161, 160), (200, 186, 183), (200, 190, 191), + (200, 195, 199), (204, 195, 202), (208, 195, 205), (212, 197, 200), + (214, 195, 180), (187, 187, 159), (163, 157, 141), (139, 128, 124), + (127, 123, 122), (115, 119, 120), (110, 115, 119), (105, 112, 118), + (95, 102, 118), (90, 97, 112), (85, 93, 106), (84, 88, 97), + (83, 84, 88), (91, 77, 80), (100, 71, 73), (125, 58, 67), + (137, 47, 46), (149, 44, 38), (145, 43, 41), (141, 43, 44), + (114, 59, 59), (87, 76, 74), (85, 83, 87), (84, 91, 101), + (99, 110, 116), (102, 108, 113), (105, 106, 111), (116, 106, 100), + (128, 107, 90), (130, 95, 79), (133, 84, 69), (141, 74, 45), + (135, 52, 46), (129, 40, 36), (91, 44, 40), (53, 48, 45), + (47, 49, 52), (41, 50, 59), (48, 51, 70), (51, 57, 69), + (69, 81, 93), (89, 85, 80), (110, 89, 68), (129, 97, 78), + (149, 106, 89), (163, 112, 98), (178, 118, 107), (195, 171, 145), + (198, 182, 169), (138, 137, 135), (128, 128, 126), (118, 120, 117), + (112, 114, 114), (107, 108, 112), (89, 99, 109), (77, 91, 104), + (59, 72, 80), (39, 58, 83), (20, 45, 86), (19, 38, 65), + (19, 31, 45), (16, 17, 37), (28, 28, 28), (30, 26, 27), + (31, 27, 28), (43, 33, 23), (36, 35, 40), (29, 37, 58), + (33, 43, 56), (38, 49, 55), (38, 50, 66), (38, 54, 79), + (57, 62, 66), (79, 62, 53), (101, 63, 40), (115, 52, 38), + (130, 41, 37), (132, 39, 34), (129, 39, 38), (122, 47, 54), + (90, 46, 59), (62, 71, 80), (70, 79, 88), (78, 88, 97), + (84, 92, 105), (93, 103, 113), (97, 111, 114), (97, 110, 119), + (88, 97, 112), (78, 90, 106), (68, 84, 100), (63, 86, 99), + (58, 88, 99), (45, 68, 100), (53, 79, 96), (70, 86, 99), + (89, 93, 102), (117, 118, 113), (122, 120, 115), (128, 123, 117), + (129, 126, 121), (127, 127, 125), (126, 127, 122), (118, 119, 123), + (102, 112, 121), (112, 119, 127), (122, 127, 133), (132, 132, 135), + (142, 138, 137), (193, 176, 166), (211, 185, 186), (210, 194, 194), + (211, 195, 195), (209, 183, 168), (198, 180, 168), (188, 178, 169), + (140, 141, 136), (136, 135, 131), (133, 130, 125), (128, 129, 123), + (120, 116, 113), (118, 116, 111), (117, 117, 109), (108, 119, 77), + (106, 121, 64), (95, 122, 71), (94, 120, 55), (74, 113, 60), + (81, 92, 98), (97, 98, 103), (98, 103, 101), (99, 109, 100), + (121, 116, 110), (126, 128, 125), (136, 141, 135), (150, 156, 156), + (209, 188, 185), (208, 191, 191), (207, 195, 197), (211, 199, 199), + (213, 201, 201), (214, 204, 205), (208, 200, 211), (196, 185, 199), + (177, 166, 180), (134, 138, 141), (123, 123, 123), (106, 109, 114), + (88, 94, 106), (75, 82, 101), (67, 82, 101), (60, 76, 99), + (67, 79, 93), (70, 84, 97), (73, 89, 102), (94, 91, 98), + (123, 98, 78), (147, 77, 65), (156, 69, 60), (140, 72, 73), + (117, 104, 87), (103, 101, 102), (105, 106, 111), (108, 112, 113), + (116, 111, 115), (108, 107, 113), (103, 106, 111), (89, 98, 107), + (82, 92, 104), (82, 88, 100), (84, 73, 81), (83, 75, 62), + (86, 93, 62), (122, 70, 59), (146, 56, 55), (150, 57, 40), + (155, 61, 62), (145, 75, 73), (156, 131, 127), (191, 165, 178), + (205, 173, 184), (189, 163, 176), (140, 139, 134), (128, 134, 134), + (123, 123, 121), (107, 111, 114), (95, 98, 115), (91, 98, 116), + (87, 93, 109), (84, 91, 107), (85, 92, 108), (86, 98, 112), + (88, 94, 108), (94, 99, 105), (96, 99, 106), (97, 100, 107), + (92, 98, 114), (89, 97, 116), (87, 96, 113), (88, 93, 112), + (89, 97, 110), (97, 102, 106), (111, 112, 114), (123, 123, 121), + (135, 134, 139), (189, 164, 170), (204, 188, 175), (205, 195, 194), + (194, 194, 204), (177, 174, 191), (134, 138, 141), (128, 133, 136), + (117, 129, 127), (110, 119, 118), (106, 115, 120), (108, 113, 117), + (115, 113, 116), (119, 116, 107), (118, 120, 109), (121, 122, 117), + (128, 131, 124), (138, 135, 128), (214, 176, 155), (168, 154, 153) + ), + +// 127 Apophysis-040426-1crabgrass from pat phillips patrx.deviantart.com +((237, 132, 109), (148, 73, 76), (112, 55, 75), (76, 38, 74), + (47, 23, 78), (19, 9, 82), (15, 6, 84), (12, 4, 87), + (0, 5, 84), (0, 37, 71), (0, 70, 58), (0, 98, 41), + (0, 127, 24), (0, 121, 15), (0, 115, 6), (13, 64, 3), + (27, 14, 0), (71, 35, 4), (61, 30, 24), (52, 26, 44), + (26, 71, 29), (0, 116, 14), (0, 119, 9), (0, 123, 5), + (0, 126, 8), (0, 121, 11), (0, 117, 14), (0, 109, 25), + (0, 101, 36), (0, 90, 51), (0, 80, 66), (0, 60, 91), + (34, 17, 86), (98, 50, 55), (119, 60, 47), (140, 70, 39), + (70, 98, 33), (0, 126, 28), (0, 126, 28), (0, 127, 28), + (0, 97, 72), (43, 69, 100), (86, 42, 129), (99, 50, 125), + (113, 58, 122), (123, 63, 127), (133, 68, 132), (149, 74, 132), + (155, 73, 128), (175, 87, 110), (169, 84, 124), (164, 81, 139), + (157, 78, 144), (151, 76, 149), (141, 70, 145), (132, 65, 141), + (87, 42, 79), (73, 36, 71), (60, 30, 63), (63, 31, 47), + (67, 33, 32), (82, 40, 41), (97, 48, 51), (127, 64, 76), + (167, 82, 70), (219, 108, 83), (223, 110, 94), (228, 112, 106), + (228, 112, 106), (228, 113, 107), (236, 117, 105), (253, 111, 105), + (220, 109, 143), (224, 111, 169), (229, 114, 195), (199, 100, 174), + (170, 86, 153), (146, 82, 134), (123, 78, 116), (63, 105, 58), + (0, 121, 47), (73, 115, 43), (123, 100, 45), (173, 85, 47), + (187, 92, 43), (201, 100, 39), (228, 123, 80), (241, 119, 82), + (253, 126, 74), (243, 121, 78), (234, 116, 83), (220, 109, 83), + (206, 102, 84), (179, 91, 79), (136, 68, 87), (100, 48, 82), + (47, 74, 76), (0, 118, 49), (0, 110, 41), (0, 103, 34), + (0, 97, 40), (0, 92, 46), (0, 66, 89), (0, 62, 89), + (46, 53, 62), (78, 54, 89), (110, 55, 117), (129, 64, 130), + (149, 73, 143), (186, 92, 167), (219, 108, 189), (231, 113, 196), + (237, 119, 200), (245, 126, 211), (238, 121, 203), (231, 116, 196), + (211, 105, 183), (201, 99, 142), (205, 84, 138), (185, 91, 151), + (176, 88, 157), (163, 81, 150), (150, 75, 143), (136, 67, 135), + (122, 60, 128), (100, 52, 132), (51, 25, 108), (50, 24, 98), + (45, 20, 59), (19, 8, 42), (17, 8, 48), (16, 8, 54), + (3, 0, 81), (0, 15, 88), (0, 33, 90), (0, 20, 90), + (4, 2, 51), (2, 1, 25), (0, 0, 0), (11, 5, 11), + (23, 11, 23), (34, 17, 22), (20, 9, 32), (0, 32, 70), + (0, 65, 54), (0, 127, 27), (0, 127, 30), (0, 127, 33), + (0, 111, 67), (106, 96, 119), (141, 70, 137), (155, 76, 147), + (183, 91, 164), (184, 91, 163), (186, 92, 163), (164, 81, 152), + (145, 72, 143), (114, 55, 115), (90, 42, 85), (80, 43, 84), + (83, 41, 80), (102, 52, 60), (119, 60, 66), (136, 68, 73), + (177, 88, 80), (185, 92, 108), (182, 90, 122), (180, 90, 158), + (168, 84, 180), (183, 92, 191), (199, 100, 202), (227, 113, 194), + (238, 118, 200), (244, 122, 204), (228, 195, 183), (255, 139, 149), + (255, 139, 104), (255, 141, 92), (253, 126, 86), (253, 126, 69), + (246, 122, 53), (245, 128, 46), (209, 104, 29), (157, 77, 24), + (118, 59, 28), (109, 54, 33), (100, 49, 39), (71, 34, 26), + (90, 44, 35), (99, 48, 58), (130, 63, 76), (154, 76, 94), + (193, 97, 82), (200, 100, 84), (201, 100, 83), (196, 97, 83), + (191, 100, 82), (154, 75, 99), (128, 64, 109), (155, 77, 104), + (163, 81, 141), (160, 79, 161), (165, 82, 165), (159, 78, 161), + (149, 77, 167), (143, 72, 159), (107, 53, 152), (74, 36, 117), + (35, 16, 99), (9, 5, 88), (0, 7, 85), (0, 31, 91), + (0, 47, 91), (0, 51, 91), (0, 70, 92), (0, 82, 84), + (0, 92, 79), (0, 91, 82), (0, 71, 82), (50, 22, 44), + (60, 30, 28), (83, 36, 39), (146, 73, 33), (197, 99, 60), + (216, 96, 90), (210, 105, 98), (209, 104, 101), (199, 100, 138), + (206, 106, 141), (222, 109, 190), (226, 114, 206), (228, 107, 226), + (220, 110, 207), (185, 91, 168), (157, 76, 154), (128, 65, 130), + (107, 53, 100), (102, 51, 90), (103, 51, 83), (122, 60, 101), + (124, 61, 109), (136, 69, 82), (164, 87, 43), (190, 94, 45), + (208, 104, 56), (217, 114, 84), (241, 123, 110), (252, 126, 143), + (253, 126, 152), (243, 121, 202), (252, 126, 210), (251, 125, 208), + (240, 118, 205), (219, 109, 191), (172, 85, 128), (192, 96, 161) + ), + +// 128 Apophysis-040426-12bs1fl +((238, 242, 215), (16, 91, 44), (59, 115, 27), (103, 140, 11), + (123, 162, 22), (144, 184, 33), (148, 191, 39), (152, 199, 45), + (181, 204, 45), (175, 191, 78), (169, 179, 112), (177, 179, 158), + (186, 179, 204), (203, 205, 208), (220, 231, 212), (222, 234, 217), + (224, 238, 222), (244, 237, 233), (239, 240, 228), (235, 243, 223), + (225, 238, 222), (215, 233, 221), (211, 228, 217), (208, 224, 213), + (186, 196, 187), (179, 201, 152), (173, 207, 117), (160, 137, 72), + (148, 67, 27), (133, 68, 23), (119, 69, 19), (96, 46, 1), + (73, 35, 36), (61, 108, 136), (82, 142, 155), (104, 177, 175), + (137, 178, 169), (171, 180, 163), (193, 181, 149), (216, 183, 135), + (244, 208, 136), (247, 225, 127), (250, 243, 119), (250, 244, 120), + (250, 245, 122), (244, 235, 127), (239, 226, 133), (239, 218, 173), + (226, 229, 203), (232, 237, 215), (216, 226, 176), (200, 215, 138), + (168, 204, 161), (137, 193, 185), (142, 187, 188), (148, 181, 192), + (168, 173, 196), (167, 170, 194), (166, 167, 193), (156, 92, 153), + (147, 18, 114), (129, 42, 100), (111, 67, 86), (111, 90, 42), + (101, 103, 34), (95, 101, 109), (102, 126, 139), (110, 151, 169), + (128, 165, 179), (146, 180, 189), (177, 205, 207), (209, 204, 218), + (223, 210, 159), (218, 190, 131), (214, 171, 104), (165, 123, 106), + (116, 75, 108), (101, 64, 104), (86, 54, 100), (54, 42, 86), + (23, 21, 64), (12, 34, 72), (19, 51, 80), (27, 69, 89), + (38, 68, 97), (50, 67, 105), (74, 55, 99), (72, 50, 93), + (120, 139, 109), (155, 161, 116), (191, 184, 123), (195, 175, 120), + (200, 166, 117), (198, 165, 119), (182, 147, 130), (169, 136, 124), + (164, 121, 129), (107, 147, 166), (86, 130, 152), (66, 113, 139), + (57, 111, 128), (49, 110, 118), (56, 102, 131), (80, 121, 146), + (140, 137, 173), (185, 149, 155), (230, 162, 138), (232, 166, 130), + (234, 170, 122), (245, 168, 120), (252, 126, 119), (251, 135, 133), + (251, 170, 128), (236, 216, 167), (232, 224, 173), (228, 233, 180), + (207, 219, 204), (190, 215, 212), (173, 203, 205), (144, 179, 190), + (106, 147, 166), (79, 124, 148), (52, 101, 130), (35, 106, 127), + (19, 112, 125), (12, 107, 119), (7, 105, 117), (18, 104, 119), + (40, 85, 118), (61, 80, 116), (79, 89, 120), (98, 99, 125), + (165, 113, 124), (195, 153, 135), (222, 192, 144), (229, 230, 169), + (252, 242, 206), (239, 227, 171), (227, 213, 137), (236, 222, 135), + (246, 232, 134), (252, 238, 194), (252, 243, 208), (250, 250, 213), + (244, 247, 223), (248, 249, 231), (241, 246, 228), (235, 244, 225), + (232, 242, 224), (222, 237, 224), (205, 229, 213), (194, 217, 215), + (163, 173, 195), (154, 159, 187), (145, 146, 179), (142, 128, 117), + (145, 119, 76), (121, 108, 83), (142, 98, 71), (159, 112, 60), + (163, 116, 64), (192, 195, 129), (200, 205, 163), (208, 215, 197), + (215, 226, 200), (232, 236, 215), (241, 241, 216), (244, 249, 206), + (215, 209, 145), (196, 201, 121), (178, 194, 98), (138, 171, 38), + (147, 147, 35), (162, 134, 13), (127, 79, 28), (98, 99, 31), + (49, 49, 14), (41, 49, 17), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (11, 12, 11), (34, 52, 47), + (89, 128, 153), (108, 147, 167), (128, 167, 181), (157, 190, 197), + (165, 195, 201), (177, 194, 205), (166, 196, 202), (162, 191, 199), + (166, 169, 147), (146, 139, 91), (149, 142, 62), (128, 129, 60), + (102, 103, 64), (48, 45, 84), (12, 24, 41), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (2, 2, 58), (10, 29, 71), + (32, 52, 94), (43, 47, 100), (67, 58, 114), (84, 57, 102), + (75, 60, 84), (49, 60, 77), (71, 87, 39), (106, 97, 32), + (84, 55, 45), (72, 75, 46), (39, 64, 69), (24, 72, 44), + (2, 79, 52), (22, 72, 45), (30, 51, 51), (27, 36, 33), + (29, 36, 49), (18, 17, 59), (13, 12, 59), (5, 3, 55), + (6, 14, 67), (38, 32, 74), (62, 57, 111), (63, 97, 116), + (107, 110, 151), (144, 128, 142), (143, 141, 125), (155, 153, 117), + (159, 172, 108), (200, 220, 61), (228, 234, 77), (240, 246, 96), + (215, 226, 106), (211, 186, 128), (205, 155, 102), (190, 90, 69), + (199, 62, 45), (171, 127, 74), (182, 157, 112), (201, 199, 129), + (215, 227, 138), (238, 244, 120), (247, 242, 113), (249, 248, 113), + (251, 249, 111), (248, 245, 113), (252, 240, 126), (242, 229, 192), + (243, 227, 215), (242, 245, 220), (244, 243, 217), (228, 230, 177) + ), + +// 129 Apophysis-040426-1cometnuc +((205, 7, 18), (205, 7, 18), (201, 9, 19), (198, 11, 21), + (198, 12, 21), (198, 13, 22), (196, 13, 22), (194, 13, 23), + (202, 9, 19), (203, 8, 18), (205, 7, 18), (205, 7, 18), + (205, 7, 18), (176, 21, 27), (148, 36, 36), (126, 47, 38), + (105, 58, 41), (111, 166, 35), (90, 156, 35), (70, 146, 36), + (93, 99, 37), (116, 52, 38), (150, 36, 33), (185, 21, 29), + (202, 9, 19), (203, 8, 18), (205, 7, 18), (203, 9, 19), + (202, 11, 20), (198, 13, 22), (194, 16, 24), (127, 46, 39), + (76, 72, 42), (123, 172, 119), (138, 180, 151), (154, 188, 184), + (112, 167, 152), (71, 146, 121), (88, 154, 77), (105, 163, 34), + (153, 187, 38), (177, 199, 45), (201, 212, 52), (205, 213, 53), + (209, 215, 55), (203, 212, 52), (198, 210, 50), (190, 206, 47), + (168, 195, 42), (111, 166, 35), (78, 150, 35), (46, 134, 36), + (30, 126, 37), (15, 118, 38), (14, 110, 37), (14, 103, 37), + (21, 100, 38), (30, 95, 38), (39, 90, 39), (85, 67, 38), + (132, 44, 37), (163, 28, 30), (194, 13, 23), (198, 11, 21), + (202, 9, 19), (198, 11, 21), (175, 99, 30), (153, 187, 39), + (175, 198, 44), (198, 210, 50), (245, 233, 91), (253, 237, 128), + (213, 217, 178), (183, 202, 181), (154, 188, 185), (94, 158, 152), + (34, 128, 119), (27, 124, 78), (21, 121, 37), (8, 106, 38), + (2, 109, 37), (9, 115, 37), (15, 118, 36), (21, 121, 35), + (24, 109, 36), (27, 97, 37), (39, 90, 41), (70, 75, 41), + (181, 19, 28), (191, 14, 23), (202, 9, 19), (202, 9, 19), + (202, 9, 19), (202, 11, 20), (198, 13, 22), (153, 33, 34), + (93, 63, 40), (27, 97, 39), (17, 101, 38), (8, 106, 38), + (5, 107, 38), (2, 109, 39), (2, 109, 39), (8, 106, 38), + (21, 100, 38), (30, 115, 36), (40, 131, 34), (49, 135, 35), + (58, 140, 36), (76, 149, 35), (127, 175, 35), (133, 178, 120), + (182, 202, 185), (245, 234, 150), (249, 235, 133), (253, 237, 116), + (249, 235, 98), (242, 232, 84), (225, 223, 67), (209, 215, 55), + (158, 190, 39), (134, 178, 36), (111, 166, 34), (96, 159, 35), + (82, 152, 36), (52, 137, 35), (33, 128, 37), (21, 121, 37), + (15, 118, 36), (21, 121, 35), (33, 127, 34), (46, 134, 34), + (70, 146, 34), (111, 166, 35), (138, 180, 36), (153, 187, 38), + (116, 169, 35), (90, 156, 36), (64, 143, 37), (61, 141, 35), + (58, 140, 34), (76, 149, 33), (116, 169, 35), (158, 190, 39), + (206, 214, 102), (219, 221, 176), (225, 223, 173), (231, 226, 170), + (253, 238, 119), (230, 226, 71), (172, 197, 43), (198, 13, 22), + (202, 11, 20), (202, 11, 20), (202, 11, 20), (198, 13, 22), + (158, 40, 44), (105, 58, 39), (70, 75, 39), (33, 93, 38), + (33, 93, 38), (58, 81, 42), (75, 72, 42), (93, 63, 42), + (127, 46, 39), (198, 13, 22), (202, 9, 19), (205, 7, 18), + (205, 7, 18), (205, 7, 18), (205, 7, 18), (198, 13, 22), + (153, 33, 35), (110, 55, 39), (99, 60, 42), (58, 81, 40), + (52, 137, 35), (64, 143, 35), (94, 158, 33), (127, 175, 36), + (158, 190, 40), (194, 208, 49), (219, 220, 62), (242, 232, 84), + (225, 223, 66), (215, 218, 60), (205, 214, 54), (181, 201, 44), + (138, 180, 38), (94, 158, 33), (52, 137, 35), (40, 131, 34), + (33, 128, 35), (21, 121, 37), (21, 121, 37), (28, 125, 129), + (47, 134, 141), (47, 134, 120), (46, 134, 38), (27, 125, 36), + (21, 121, 37), (9, 115, 37), (2, 112, 36), (2, 112, 36), + (2, 109, 37), (8, 106, 38), (21, 100, 40), (33, 93, 40), + (70, 75, 41), (110, 55, 41), (121, 49, 39), (148, 36, 37), + (116, 52, 41), (99, 60, 39), (70, 75, 41), (45, 87, 38), + (51, 84, 41), (87, 66, 41), (148, 36, 36), (198, 13, 22), + (202, 9, 19), (202, 9, 19), (202, 9, 19), (202, 9, 19), + (202, 9, 19), (205, 7, 18), (205, 7, 18), (205, 7, 18), + (205, 7, 18), (205, 7, 18), (205, 7, 18), (205, 7, 18), + (202, 9, 19), (198, 13, 22), (177, 28, 34), (190, 206, 47), + (240, 231, 79), (247, 234, 93), (253, 237, 112), (253, 238, 123), + (249, 236, 142), (249, 236, 144), (250, 236, 141), (247, 234, 147), + (248, 235, 148), (244, 233, 154), (222, 222, 174), (202, 212, 182), + (164, 193, 185), (205, 10, 123), (198, 13, 22), (202, 9, 19), + (205, 7, 18), (205, 7, 18), (205, 7, 18), (205, 7, 18) + ), + +// 130 Apophysis-040426-1passionscross +((52, 125, 24), (172, 93, 164), (141, 59, 144), (110, 25, 125), + (87, 22, 110), (64, 20, 95), (54, 28, 89), (45, 37, 84), + (59, 91, 123), (103, 78, 135), (148, 66, 148), (162, 82, 157), + (177, 99, 166), (181, 104, 169), (185, 109, 172), (185, 109, 172), + (185, 109, 172), (163, 82, 158), (147, 65, 148), (132, 48, 139), + (121, 36, 132), (110, 25, 125), (104, 19, 121), (99, 13, 118), + (87, 2, 110), (81, 5, 106), (76, 8, 103), (73, 11, 101), + (70, 14, 99), (73, 11, 101), (76, 8, 103), (93, 8, 114), + (116, 31, 128), (163, 82, 158), (170, 90, 162), (177, 99, 167), + (181, 104, 169), (185, 109, 172), (187, 111, 173), (190, 114, 174), + (209, 139, 187), (210, 141, 189), (212, 144, 191), (208, 139, 188), + (205, 134, 185), (201, 129, 182), (198, 125, 179), (190, 114, 174), + (185, 109, 172), (163, 82, 158), (147, 65, 148), (132, 48, 138), + (112, 28, 126), (93, 8, 114), (93, 8, 114), (93, 8, 114), + (82, 2, 106), (85, 2, 104), (88, 2, 103), (130, 48, 68), + (173, 94, 34), (189, 114, 43), (206, 135, 52), (253, 144, 57), + (219, 154, 62), (190, 114, 174), (194, 119, 177), (198, 125, 180), + (200, 127, 181), (202, 130, 182), (216, 149, 191), (242, 190, 76), + (248, 237, 83), (247, 218, 81), (247, 200, 79), (218, 157, 126), + (190, 114, 174), (181, 103, 169), (172, 93, 164), (158, 77, 154), + (148, 66, 148), (132, 48, 138), (118, 107, 71), (105, 166, 5), + (102, 164, 3), (99, 162, 2), (76, 144, 10), (33, 109, 35), + (45, 37, 84), (60, 22, 93), (76, 8, 103), (81, 5, 106), + (87, 2, 110), (93, 8, 114), (105, 19, 121), (116, 31, 128), + (127, 43, 135), (148, 66, 148), (164, 85, 158), (181, 104, 169), + (187, 112, 173), (194, 120, 177), (202, 130, 182), (212, 144, 190), + (205, 134, 185), (197, 124, 179), (190, 114, 174), (185, 109, 171), + (181, 104, 169), (181, 104, 169), (185, 109, 172), (185, 109, 172), + (185, 109, 172), (194, 120, 177), (196, 122, 178), (198, 125, 179), + (202, 130, 182), (205, 134, 185), (212, 144, 190), (219, 153, 194), + (231, 171, 201), (240, 188, 190), (249, 206, 180), (225, 217, 160), + (202, 228, 141), (202, 228, 141), (247, 200, 177), (253, 221, 180), + (253, 231, 85), (247, 237, 83), (245, 237, 82), (243, 238, 81), + (240, 239, 80), (219, 235, 69), (185, 219, 50), (163, 206, 38), + (99, 162, 2), (63, 133, 20), (27, 104, 39), (27, 79, 56), + (27, 55, 73), (51, 31, 88), (51, 31, 88), (51, 31, 88), + (39, 43, 80), (2, 83, 54), (2, 83, 54), (2, 83, 54), + (9, 88, 50), (9, 88, 50), (15, 93, 47), (21, 99, 43), + (9, 88, 50), (5, 85, 52), (2, 83, 54), (2, 77, 58), + (33, 49, 77), (58, 26, 92), (70, 14, 99), (99, 13, 118), + (116, 31, 128), (132, 48, 138), (121, 36, 131), (110, 25, 125), + (76, 8, 103), (64, 20, 96), (39, 43, 80), (14, 66, 65), + (40, 115, 32), (61, 132, 19), (82, 149, 7), (94, 158, 0), + (105, 166, 5), (105, 166, 5), (105, 166, 5), (116, 175, 12), + (163, 206, 38), (111, 170, 8), (105, 166, 5), (52, 125, 24), + (21, 99, 43), (33, 49, 77), (51, 31, 88), (58, 26, 92), + (39, 43, 80), (30, 51, 74), (21, 60, 69), (2, 83, 54), + (9, 88, 50), (21, 99, 43), (33, 109, 35), (64, 135, 17), + (88, 153, 3), (105, 166, 5), (122, 178, 15), (186, 220, 51), + (212, 232, 65), (230, 238, 75), (222, 236, 71), (209, 231, 63), + (190, 221, 53), (144, 194, 100), (168, 209, 118), (212, 144, 190), + (216, 149, 191), (222, 158, 195), (222, 158, 196), (216, 149, 191), + (212, 144, 190), (205, 134, 185), (185, 109, 172), (158, 77, 154), + (143, 60, 145), (121, 37, 131), (99, 13, 118), (70, 14, 99), + (58, 26, 92), (39, 43, 80), (21, 60, 69), (28, 88, 4), + (123, 91, 23), (94, 64, 96), (110, 25, 125), (105, 19, 121), + (93, 8, 114), (87, 2, 110), (87, 2, 110), (82, 2, 106), + (82, 2, 106), (82, 2, 106), (76, 8, 103), (70, 14, 99), + (58, 26, 92), (39, 43, 80), (14, 66, 65), (33, 109, 35), + (70, 139, 14), (88, 153, 3), (105, 166, 5), (182, 105, 39), + (158, 77, 154), (172, 93, 164), (177, 99, 167), (185, 109, 172), + (185, 109, 172), (190, 114, 174), (154, 200, 108), (194, 224, 55), + (222, 236, 71), (240, 239, 80), (243, 238, 81), (233, 238, 76), + (209, 231, 63), (163, 206, 38), (111, 170, 8), (8, 71, 62) + ), + +// 131 Apophysis-040426-1butterflyflower +((27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (53, 40, 50), (53, 40, 50), (53, 40, 50), + (53, 40, 50), (53, 40, 50), (53, 40, 49), (54, 41, 49), + (94, 83, 21), (77, 70, 31), (61, 58, 42), (44, 38, 54), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (53, 40, 50), (76, 64, 33), (100, 89, 16), (109, 100, 10), + (118, 112, 4), (128, 117, 8), (138, 122, 13), (132, 117, 35), + (108, 105, 48), (113, 119, 63), (115, 111, 56), (118, 104, 50), + (108, 96, 33), (98, 88, 17), (96, 85, 18), (94, 83, 20), + (94, 83, 20), (95, 85, 19), (97, 87, 18), (103, 91, 15), + (109, 95, 13), (120, 103, 10), (131, 111, 8), (139, 138, 13), + (161, 164, 43), (208, 201, 81), (205, 197, 78), (203, 193, 75), + (202, 195, 73), (201, 197, 71), (179, 168, 67), (120, 117, 36), + (99, 88, 17), (96, 85, 19), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (84, 74, 28), (60, 52, 42), (36, 31, 57), (31, 25, 61), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (33, 22, 64), (57, 46, 49), (81, 71, 35), (87, 77, 28), + (94, 83, 21), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (53, 40, 50), (40, 29, 58), (28, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (33, 37, 57), (80, 68, 30), (87, 75, 25), (94, 83, 21), + (101, 91, 14), (105, 93, 13), (104, 93, 13), (95, 100, 17), + (63, 68, 39), (46, 47, 48), (29, 27, 58), (28, 23, 62), + (27, 19, 66), (27, 19, 66), (53, 40, 50), (60, 48, 46), + (92, 76, 22), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (73, 61, 35), (53, 40, 50), (53, 40, 50), + (53, 40, 50), (83, 68, 45), (92, 99, 41), (113, 91, 42), + (130, 119, 22), (175, 167, 46), (184, 180, 53), (193, 193, 61), + (182, 173, 52), (173, 156, 46), (157, 148, 29), (126, 120, 4), + (111, 100, 6), (110, 97, 7), (110, 95, 8), (114, 101, 5), + (127, 114, 2), (131, 115, 7), (131, 113, 9), (122, 121, 12), + (121, 144, 8), (132, 139, 8), (126, 127, 55), (116, 118, 109), + (102, 109, 77), (85, 76, 55), (54, 41, 50), (53, 40, 50), + (84, 63, 33), (89, 73, 27), (94, 83, 21), (94, 83, 20), + (104, 66, 13), (67, 47, 42), (53, 40, 50), (28, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (29, 19, 66), (53, 40, 50), (67, 52, 43), (94, 83, 21), + (94, 83, 21), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (94, 83, 21), (94, 83, 21), (94, 83, 21), + (94, 83, 21), (77, 67, 37), (53, 40, 50), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (53, 40, 50), (64, 62, 57), + (96, 82, 52), (102, 94, 44), (91, 85, 48), (59, 47, 47), + (53, 40, 50), (53, 40, 50), (53, 40, 50), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66), + (27, 19, 66), (27, 19, 66), (27, 19, 66), (27, 19, 66) + ), + +// 132 Apophysis-040426-1Watcher +((65, 7, 0), (22, 10, 22), (19, 19, 29), (16, 28, 36), + (16, 42, 52), (16, 57, 68), (13, 64, 65), (10, 72, 63), + (46, 87, 61), (76, 73, 46), (106, 60, 31), (124, 56, 22), + (143, 52, 14), (179, 42, 12), (216, 32, 11), (230, 38, 15), + (245, 44, 20), (244, 64, 29), (228, 95, 29), (213, 127, 29), + (168, 156, 30), (123, 185, 32), (111, 139, 25), (100, 94, 19), + (198, 80, 46), (202, 55, 45), (206, 31, 45), (164, 42, 31), + (122, 53, 18), (111, 53, 21), (100, 53, 25), (88, 58, 29), + (58, 58, 39), (28, 75, 66), (21, 87, 72), (15, 99, 79), + (12, 106, 86), (10, 113, 93), (12, 122, 85), (15, 131, 78), + (28, 98, 40), (52, 79, 38), (76, 60, 36), (96, 56, 25), + (117, 52, 15), (130, 50, 14), (144, 48, 13), (201, 66, 14), + (242, 77, 53), (219, 75, 50), (176, 67, 37), (133, 59, 25), + (128, 43, 28), (123, 27, 32), (125, 41, 27), (128, 55, 22), + (117, 62, 31), (103, 63, 47), (89, 64, 63), (55, 57, 71), + (22, 51, 79), (19, 30, 76), (16, 9, 74), (58, 4, 64), + (64, 3, 59), (46, 28, 22), (43, 40, 32), (40, 53, 42), + (37, 57, 47), (34, 62, 52), (34, 84, 72), (33, 107, 83), + (40, 106, 85), (49, 101, 84), (59, 97, 83), (61, 90, 69), + (64, 84, 56), (73, 80, 52), (82, 77, 48), (89, 78, 66), + (100, 72, 69), (71, 80, 35), (97, 71, 32), (123, 62, 29), + (120, 58, 24), (117, 55, 20), (117, 48, 18), (133, 32, 5), + (154, 11, 4), (185, 5, 26), (216, 0, 49), (225, 2, 48), + (235, 5, 48), (247, 5, 41), (253, 3, 54), (253, 1, 55), + (251, 5, 55), (237, 7, 44), (195, 26, 27), (154, 46, 11), + (149, 47, 19), (144, 49, 27), (133, 60, 29), (127, 59, 24), + (122, 40, 4), (122, 29, 4), (122, 19, 4), (122, 17, 6), + (122, 15, 8), (128, 11, 9), (133, 3, 23), (116, 9, 37), + (106, 6, 14), (94, 9, 0), (88, 13, 4), (83, 17, 8), + (65, 15, 11), (41, 16, 8), (34, 7, 13), (28, 13, 23), + (47, 30, 26), (59, 29, 13), (71, 28, 0), (88, 23, 0), + (106, 19, 1), (117, 16, 4), (148, 33, 2), (177, 29, 9), + (212, 37, 0), (237, 10, 1), (224, 8, 7), (212, 6, 13), + (205, 24, 19), (177, 33, 8), (172, 38, 0), (190, 25, 20), + (213, 26, 56), (205, 40, 102), (198, 54, 149), (220, 98, 162), + (243, 142, 176), (168, 183, 198), (99, 176, 174), (77, 158, 114), + (116, 166, 94), (133, 29, 37), (140, 26, 32), (148, 23, 27), + (201, 26, 13), (216, 19, 15), (216, 13, 14), (209, 16, 10), + (177, 37, 1), (177, 35, 3), (177, 34, 6), (201, 23, 9), + (219, 13, 20), (233, 7, 32), (247, 6, 39), (253, 0, 64), + (254, 3, 98), (247, 20, 53), (237, 17, 52), (228, 15, 51), + (184, 34, 47), (138, 57, 28), (128, 29, 21), (172, 8, 28), + (225, 14, 32), (231, 10, 38), (237, 7, 44), (240, 2, 36), + (233, 13, 27), (205, 4, 7), (163, 18, 13), (123, 9, 7), + (106, 14, 1), (112, 3, 11), (139, 3, 23), (185, 1, 37), + (222, 4, 55), (233, 10, 38), (225, 22, 21), (247, 43, 15), + (247, 22, 5), (249, 16, 3), (252, 10, 2), (249, 15, 41), + (240, 34, 52), (248, 53, 52), (249, 72, 52), (249, 78, 54), + (245, 109, 57), (243, 196, 144), (243, 248, 241), (254, 228, 202), + (231, 197, 140), (216, 166, 59), (252, 110, 51), (252, 100, 51), + (250, 76, 35), (250, 67, 52), (248, 66, 53), (248, 63, 54), + (253, 50, 48), (252, 40, 51), (250, 37, 51), (253, 25, 51), + (253, 16, 47), (247, 9, 39), (231, 2, 54), (190, 10, 49), + (149, 6, 28), (144, 20, 37), (117, 51, 44), (83, 81, 54), + (99, 71, 44), (22, 45, 43), (71, 69, 46), (77, 68, 43), + (94, 69, 38), (100, 39, 37), (83, 31, 16), (71, 32, 3), + (83, 34, 4), (112, 57, 26), (117, 65, 34), (148, 138, 42), + (163, 182, 105), (254, 210, 127), (242, 247, 130), (253, 248, 95), + (249, 215, 71), (250, 118, 51), (253, 104, 46), (233, 103, 49), + (213, 102, 52), (146, 98, 87), (106, 71, 85), (89, 82, 55), + (70, 89, 62), (58, 96, 70), (52, 91, 64), (41, 71, 89), + (10, 87, 105), (21, 80, 98), (67, 70, 129), (89, 80, 78), + (89, 70, 70), (83, 58, 52), (64, 43, 53), (53, 49, 48), + (52, 37, 27), (64, 19, 11), (65, 7, 13), (77, 0, 17) + ), + +// 133 Apophysis-040426-1knotted +((151, 44, 78), (136, 52, 74), (136, 52, 73), (136, 53, 73), + (136, 53, 73), (136, 53, 73), (136, 53, 73), (136, 53, 73), + (136, 53, 73), (136, 53, 73), (136, 54, 73), (136, 53, 73), + (136, 53, 73), (136, 52, 72), (136, 51, 71), (136, 51, 71), + (136, 51, 71), (136, 52, 74), (128, 52, 101), (121, 52, 129), + (136, 47, 111), (151, 42, 94), (151, 43, 87), (151, 45, 81), + (136, 49, 71), (130, 53, 41), (125, 57, 12), (130, 55, 42), + (136, 54, 73), (136, 54, 73), (136, 54, 73), (136, 51, 71), + (136, 48, 72), (136, 17, 78), (143, 32, 79), (151, 47, 80), + (165, 44, 86), (179, 41, 93), (196, 79, 65), (213, 117, 38), + (253, 252, 89), (182, 215, 51), (111, 179, 14), (97, 142, 18), + (83, 105, 22), (57, 94, 23), (31, 84, 25), (12, 31, 35), + (10, 76, 10), (33, 106, 0), (41, 99, 14), (49, 92, 28), + (76, 80, 37), (103, 68, 47), (111, 64, 56), (119, 61, 65), + (136, 56, 72), (136, 55, 72), (136, 54, 73), (136, 53, 73), + (136, 53, 73), (136, 53, 73), (136, 53, 73), (136, 53, 73), + (136, 53, 73), (136, 52, 70), (136, 53, 71), (136, 54, 73), + (136, 55, 72), (136, 57, 72), (136, 58, 72), (125, 62, 74), + (85, 83, 50), (61, 113, 91), (37, 143, 133), (64, 111, 97), + (91, 80, 62), (97, 77, 60), (103, 74, 59), (119, 64, 64), + (136, 57, 72), (151, 50, 83), (151, 47, 82), (151, 45, 81), + (158, 44, 85), (166, 43, 90), (166, 40, 91), (179, 36, 97), + (179, 36, 97), (179, 31, 95), (179, 27, 93), (180, 28, 96), + (181, 29, 100), (196, 27, 102), (233, 3, 125), (254, 2, 128), + (254, 0, 131), (227, 9, 121), (203, 22, 109), (179, 36, 97), + (172, 39, 93), (166, 43, 90), (151, 44, 78), (151, 46, 77), + (136, 50, 71), (136, 50, 71), (136, 51, 71), (136, 52, 72), + (136, 53, 73), (136, 53, 70), (119, 60, 66), (91, 71, 79), + (85, 57, 86), (136, 58, 75), (136, 57, 73), (136, 57, 72), + (136, 57, 72), (136, 57, 72), (136, 58, 72), (119, 66, 64), + (85, 82, 40), (76, 80, 37), (67, 79, 35), (58, 86, 29), + (49, 94, 24), (49, 95, 31), (85, 76, 46), (119, 62, 65), + (136, 58, 72), (136, 53, 73), (136, 52, 72), (136, 51, 71), + (136, 49, 71), (136, 49, 71), (136, 49, 71), (151, 50, 72), + (151, 45, 78), (143, 48, 76), (136, 51, 74), (136, 51, 74), + (136, 52, 74), (136, 52, 74), (136, 53, 73), (136, 53, 73), + (136, 54, 73), (136, 54, 73), (136, 54, 73), (136, 54, 73), + (136, 53, 73), (136, 52, 74), (136, 52, 74), (136, 52, 74), + (136, 52, 74), (136, 52, 74), (136, 52, 74), (136, 52, 74), + (136, 53, 73), (136, 53, 73), (136, 53, 73), (136, 53, 73), + (136, 54, 73), (136, 57, 75), (136, 57, 73), (136, 57, 72), + (119, 61, 62), (105, 44, 24), (49, 48, 8), (37, 60, 4), + (70, 75, 37), (86, 69, 44), (103, 63, 52), (136, 52, 70), + (151, 43, 78), (166, 31, 83), (166, 33, 87), (166, 33, 87), + (179, 33, 91), (179, 30, 92), (136, 53, 73), (136, 53, 73), + (136, 53, 73), (136, 53, 73), (136, 53, 73), (136, 53, 73), + (136, 52, 70), (136, 52, 70), (136, 52, 70), (136, 53, 70), + (136, 53, 73), (136, 53, 73), (136, 53, 73), (136, 52, 74), + (136, 52, 74), (136, 52, 74), (136, 52, 74), (136, 52, 74), + (136, 52, 74), (136, 51, 71), (136, 51, 71), (136, 51, 71), + (136, 50, 71), (136, 50, 71), (136, 50, 71), (136, 49, 71), + (136, 50, 71), (136, 51, 71), (136, 53, 70), (136, 57, 72), + (119, 66, 67), (103, 74, 59), (85, 83, 47), (49, 100, 33), + (40, 142, 9), (0, 126, 8), (0, 113, 40), (14, 104, 40), + (31, 108, 17), (37, 106, 27), (67, 88, 36), (85, 72, 47), + (103, 70, 53), (119, 63, 65), (136, 56, 72), (136, 58, 75), + (136, 58, 75), (136, 58, 72), (119, 66, 67), (119, 63, 68), + (136, 58, 72), (136, 58, 75), (136, 57, 75), (136, 54, 73), + (136, 52, 74), (151, 48, 80), (151, 46, 81), (151, 43, 78), + (151, 40, 79), (166, 39, 84), (166, 42, 87), (166, 36, 89), + (166, 33, 87), (167, 36, 93), (179, 36, 93), (179, 36, 93), + (179, 30, 92), (179, 26, 93), (179, 23, 91), (208, 22, 85), + (243, 0, 0), (235, 52, 33), (156, 45, 68), (151, 46, 77), + (151, 45, 78), (151, 44, 78), (151, 43, 78), (151, 44, 78) + ), + +// 134 Apophysis-040426-1artdeco +((158, 142, 17), (249, 60, 97), (251, 61, 132), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (248, 59, 129), + (244, 57, 90), (248, 59, 129), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 213, 226), (253, 213, 226), (253, 213, 226), + (253, 191, 148), (253, 170, 70), (253, 135, 52), (253, 100, 35), + (253, 73, 39), (253, 67, 103), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 213, 226), + (253, 213, 226), (253, 215, 229), (253, 214, 227), (253, 213, 226), + (253, 213, 226), (253, 213, 226), (253, 211, 225), (253, 210, 224), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 109), (240, 119, 85), (228, 177, 61), + (220, 173, 55), (212, 170, 49), (212, 170, 49), (212, 170, 49), + (253, 173, 73), (253, 117, 120), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (185, 28, 121), (70, 27, 86), (84, 20, 91), (99, 13, 97), + (133, 16, 107), (168, 19, 117), (205, 38, 124), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (248, 59, 128), + (244, 57, 88), (228, 49, 71), (213, 42, 54), (168, 76, 20), + (99, 113, 12), (202, 185, 67), (227, 207, 110), (253, 229, 153), + (253, 239, 178), (253, 249, 204), (253, 248, 200), (253, 223, 139), + (153, 140, 14), (142, 135, 8), (132, 130, 3), (147, 137, 11), + (163, 145, 19), (209, 168, 47), (253, 137, 46), (247, 59, 93), + (219, 45, 125), (127, 0, 106), (90, 18, 84), (53, 36, 62), + (47, 39, 65), (41, 42, 69), (46, 40, 77), (58, 33, 82), + (168, 19, 117), (210, 40, 142), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (240, 55, 84), (246, 58, 60), (253, 62, 37), + (253, 62, 37), (253, 70, 39), (236, 79, 43), (117, 119, 18), + (87, 107, 18), (54, 108, 24), (21, 110, 30), (30, 104, 35), + (39, 98, 40), (51, 89, 35), (58, 88, 49), (158, 25, 103), + (190, 30, 121), (198, 35, 4), (203, 37, 2), (209, 40, 1), + (222, 47, 9), (242, 56, 23), (253, 82, 36), (253, 143, 49), + (253, 193, 94), (247, 206, 93), (242, 220, 92), (253, 184, 85), + (228, 177, 61), (219, 173, 54), (253, 90, 36), (222, 47, 65), + (194, 32, 123), (88, 19, 92), (64, 30, 80), (41, 42, 69), + (9, 58, 62), (33, 80, 43), (87, 107, 18), (138, 196, 50), + (253, 243, 182), (253, 248, 204), (253, 253, 226), (253, 253, 233), + (253, 217, 230), (253, 223, 236), (253, 243, 247), (253, 249, 244), + (253, 253, 236), (253, 251, 213), (253, 237, 170), (253, 205, 112), + (228, 177, 61), (209, 168, 48), (105, 116, 10), (76, 101, 24), + (10, 58, 89), (13, 56, 86), (16, 55, 84), (34, 45, 73), + (83, 21, 42), (123, 1, 42), (139, 5, 35), (144, 7, 0), + (139, 5, 2), (123, 1, 15), (123, 1, 42), (89, 18, 37), + (47, 67, 21), (51, 89, 35), (58, 92, 32), (106, 63, 3), + (168, 20, 18), (186, 29, 11), (186, 29, 11), (177, 24, 16), + (164, 17, 23), (154, 12, 28), (154, 12, 28), (173, 22, 22), + (182, 26, 13), (202, 37, 2), (219, 45, 62), (230, 51, 125), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (237, 54, 125), (233, 52, 76), (249, 60, 31), (194, 33, 6), + (106, 111, 11), (64, 95, 29), (41, 64, 24), (34, 58, 28), + (53, 36, 62), (111, 7, 100), (181, 26, 119), (228, 27, 144), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (253, 62, 168), (253, 62, 168), (253, 62, 168), (253, 62, 168), + (219, 20, 139), (185, 5, 119), (138, 4, 108), (94, 15, 55), + (71, 27, 50), (53, 73, 17), (82, 104, 21), (105, 116, 10) + ), + +// 135 Apophysis-040426-1expl_orange2a +((158, 205, 44), (158, 132, 20), (158, 126, 18), (158, 120, 16), + (158, 120, 16), (158, 120, 16), (158, 120, 16), (158, 120, 16), + (158, 126, 18), (158, 124, 17), (158, 123, 17), (158, 123, 17), + (158, 123, 17), (158, 124, 17), (158, 126, 18), (158, 126, 18), + (158, 126, 18), (158, 126, 18), (158, 126, 18), (158, 126, 18), + (158, 129, 19), (158, 132, 20), (158, 133, 20), (158, 135, 21), + (158, 140, 22), (158, 140, 22), (158, 140, 22), (158, 136, 21), + (158, 132, 20), (158, 132, 20), (158, 132, 20), (158, 129, 19), + (158, 123, 17), (158, 117, 15), (158, 109, 12), (158, 102, 10), + (158, 93, 7), (158, 84, 4), (158, 68, 4), (158, 53, 4), + (158, 15, 17), (158, 10, 23), (158, 5, 29), (194, 30, 35), + (231, 55, 42), (233, 72, 32), (235, 90, 23), (185, 117, 21), + (158, 111, 13), (158, 96, 8), (158, 99, 9), (158, 102, 10), + (158, 106, 11), (158, 111, 13), (158, 114, 14), (158, 117, 15), + (158, 120, 16), (158, 121, 16), (158, 123, 17), (158, 123, 17), + (158, 123, 17), (158, 121, 16), (158, 120, 16), (158, 120, 16), + (158, 114, 14), (158, 102, 10), (158, 97, 8), (158, 93, 7), + (158, 91, 6), (158, 90, 6), (158, 93, 7), (158, 93, 7), + (158, 102, 10), (158, 106, 11), (158, 111, 13), (158, 114, 14), + (158, 117, 15), (158, 118, 15), (158, 120, 16), (158, 123, 17), + (158, 129, 19), (158, 140, 22), (158, 157, 28), (158, 174, 34), + (128, 173, 60), (99, 172, 86), (76, 160, 139), (52, 146, 88), + (158, 143, 33), (158, 124, 22), (158, 105, 11), (158, 96, 8), + (158, 87, 5), (158, 62, 2), (158, 39, 35), (158, 29, 41), + (204, 17, 39), (158, 12, 1), (158, 16, 8), (158, 21, 15), + (158, 37, 9), (158, 53, 4), (158, 84, 4), (158, 93, 7), + (158, 108, 12), (158, 111, 13), (158, 114, 14), (158, 112, 13), + (158, 111, 13), (158, 105, 11), (158, 90, 6), (158, 71, 0), + (158, 39, 35), (111, 30, 124), (84, 58, 107), (58, 87, 91), + (156, 139, 62), (158, 143, 32), (158, 138, 22), (158, 138, 22), + (158, 143, 23), (158, 141, 22), (158, 140, 22), (158, 140, 22), + (158, 140, 22), (158, 138, 22), (158, 132, 20), (158, 138, 22), + (158, 138, 22), (158, 132, 20), (158, 132, 20), (158, 132, 20), + (158, 135, 21), (158, 138, 22), (158, 143, 23), (158, 148, 25), + (158, 192, 35), (179, 179, 62), (200, 166, 89), (220, 181, 99), + (240, 197, 109), (243, 217, 214), (253, 219, 230), (247, 65, 134), + (158, 114, 44), (158, 123, 40), (158, 126, 29), (158, 129, 19), + (158, 126, 18), (158, 120, 16), (158, 117, 15), (158, 117, 15), + (158, 117, 15), (158, 115, 14), (158, 114, 14), (158, 114, 14), + (158, 114, 14), (158, 114, 14), (158, 111, 13), (158, 108, 12), + (158, 105, 11), (158, 105, 11), (158, 106, 11), (158, 108, 12), + (158, 114, 14), (158, 117, 15), (158, 123, 17), (158, 126, 18), + (158, 120, 16), (158, 117, 15), (158, 114, 14), (158, 105, 11), + (158, 96, 8), (158, 93, 7), (158, 93, 7), (158, 96, 8), + (158, 96, 8), (158, 99, 9), (158, 105, 11), (158, 114, 14), + (158, 123, 17), (158, 129, 19), (158, 135, 21), (158, 140, 22), + (158, 145, 33), (108, 147, 55), (58, 149, 77), (46, 149, 63), + (33, 135, 58), (37, 62, 35), (8, 29, 64), (33, 7, 86), + (45, 32, 56), (141, 55, 26), (158, 66, 2), (158, 87, 5), + (158, 87, 5), (158, 90, 2), (158, 90, 6), (158, 93, 7), + (158, 96, 8), (158, 102, 10), (158, 105, 11), (158, 108, 12), + (158, 108, 12), (158, 108, 12), (158, 108, 12), (158, 111, 13), + (158, 114, 14), (158, 114, 14), (158, 114, 14), (158, 117, 15), + (158, 120, 16), (158, 123, 17), (158, 126, 18), (158, 132, 20), + (158, 132, 20), (158, 132, 20), (158, 132, 20), (158, 135, 21), + (158, 140, 22), (158, 146, 24), (158, 161, 29), (158, 180, 32), + (158, 195, 33), (158, 191, 34), (158, 174, 34), (158, 156, 27), + (158, 146, 24), (158, 143, 23), (158, 138, 22), (158, 135, 21), + (158, 132, 20), (158, 132, 20), (158, 132, 20), (158, 135, 21), + (158, 135, 21), (158, 135, 21), (158, 132, 20), (158, 132, 20), + (158, 126, 18), (158, 126, 18), (158, 126, 18), (158, 126, 18), + (158, 129, 19), (158, 132, 20), (158, 138, 22), (158, 143, 23), + (158, 146, 24), (158, 148, 25), (158, 148, 25), (158, 148, 25), + (158, 167, 29), (158, 176, 34), (158, 201, 34), (158, 201, 42) + ), + +// 136 Apophysis-040426-1heartFlowers +((98, 160, 76), (207, 247, 44), (212, 249, 50), (218, 251, 56), + (222, 250, 68), (227, 250, 81), (224, 250, 75), (221, 250, 69), + (218, 206, 45), (227, 177, 36), (236, 148, 28), (245, 119, 22), + (255, 90, 17), (240, 89, 8), (226, 89, 0), (221, 87, 0), + (217, 86, 0), (226, 79, 0), (216, 75, 0), (207, 72, 0), + (178, 53, 5), (150, 35, 10), (135, 26, 10), (120, 17, 11), + (84, 27, 3), (82, 46, 20), (81, 65, 37), (82, 61, 21), + (84, 58, 5), (83, 55, 2), (83, 52, 0), (111, 25, 0), + (127, 31, 26), (184, 45, 0), (195, 58, 0), (207, 72, 0), + (193, 124, 13), (179, 176, 27), (159, 186, 26), (140, 197, 25), + (213, 251, 46), (214, 251, 47), (215, 251, 48), (185, 219, 72), + (156, 188, 96), (152, 179, 122), (148, 170, 149), (197, 184, 199), + (245, 206, 215), (245, 221, 202), (221, 233, 157), (198, 246, 113), + (179, 236, 91), (160, 227, 70), (157, 226, 69), (154, 226, 69), + (131, 193, 32), (115, 186, 18), (100, 180, 5), (92, 129, 3), + (84, 79, 2), (116, 73, 8), (149, 67, 14), (166, 68, 0), + (202, 70, 0), (203, 50, 0), (188, 27, 0), (173, 4, 0), + (173, 4, 0), (173, 4, 0), (139, 17, 12), (84, 60, 3), + (36, 127, 3), (38, 137, 6), (40, 148, 10), (44, 117, 5), + (49, 86, 0), (50, 86, 0), (51, 87, 0), (63, 77, 0), + (58, 87, 20), (81, 79, 0), (117, 69, 2), (153, 60, 5), + (159, 64, 2), (166, 68, 0), (164, 65, 0), (135, 60, 15), + (54, 58, 73), (29, 58, 88), (4, 59, 103), (4, 74, 86), + (4, 90, 69), (6, 97, 24), (34, 136, 2), (26, 158, 2), + (25, 168, 21), (70, 136, 119), (105, 138, 129), (141, 140, 140), + (141, 140, 140), (141, 140, 140), (69, 131, 138), (68, 148, 136), + (46, 169, 58), (47, 154, 51), (49, 140, 45), (52, 118, 37), + (56, 97, 30), (81, 65, 37), (97, 55, 42), (119, 29, 24), + (152, 14, 12), (174, 0, 0), (174, 0, 0), (174, 0, 0), + (174, 0, 0), (174, 0, 0), (173, 4, 0), (149, 18, 10), + (81, 65, 37), (77, 70, 46), (73, 75, 56), (69, 86, 59), + (66, 97, 63), (45, 124, 123), (67, 142, 157), (68, 155, 128), + (142, 181, 95), (101, 176, 23), (79, 135, 24), (57, 95, 26), + (81, 65, 37), (107, 72, 12), (153, 65, 12), (173, 74, 0), + (173, 74, 0), (171, 71, 3), (170, 68, 6), (146, 64, 15), + (123, 60, 24), (81, 65, 37), (80, 45, 48), (86, 27, 69), + (101, 11, 88), (229, 0, 74), (242, 8, 70), (255, 17, 66), + (255, 17, 65), (249, 0, 32), (252, 0, 16), (226, 0, 28), + (181, 6, 4), (183, 10, 7), (186, 14, 10), (189, 41, 0), + (185, 67, 0), (173, 74, 0), (152, 98, 73), (151, 140, 116), + (141, 140, 140), (218, 196, 202), (230, 207, 202), (243, 218, 203), + (240, 216, 201), (190, 180, 197), (142, 156, 164), (177, 121, 126), + (164, 41, 34), (147, 57, 31), (131, 73, 29), (106, 178, 24), + (93, 184, 36), (82, 184, 33), (49, 148, 12), (8, 101, 29), + (24, 90, 47), (51, 66, 68), (64, 60, 66), (98, 48, 86), + (104, 27, 113), (96, 51, 127), (71, 105, 135), (69, 131, 147), + (119, 114, 98), (99, 94, 80), (79, 74, 62), (73, 75, 54), + (63, 80, 26), (56, 87, 12), (63, 80, 26), (81, 65, 37), + (122, 35, 26), (159, 39, 33), (164, 41, 34), (164, 41, 34), + (173, 4, 0), (174, 0, 0), (174, 0, 0), (174, 0, 0), + (174, 0, 0), (174, 0, 0), (201, 0, 30), (241, 0, 18), + (255, 35, 17), (255, 45, 14), (249, 65, 0), (244, 55, 0), + (255, 36, 10), (246, 48, 0), (230, 51, 0), (168, 42, 35), + (97, 55, 42), (76, 74, 70), (74, 108, 89), (57, 128, 129), + (67, 133, 165), (67, 141, 165), (66, 134, 166), (71, 110, 135), + (104, 27, 113), (96, 19, 82), (82, 28, 47), (84, 3, 29), + (112, 28, 23), (112, 28, 23), (127, 31, 26), (142, 35, 29), + (164, 41, 34), (168, 42, 35), (169, 42, 35), (169, 42, 35), + (173, 4, 0), (174, 0, 0), (174, 0, 0), (207, 0, 27), + (238, 0, 33), (255, 19, 16), (255, 25, 14), (226, 56, 47), + (199, 85, 82), (203, 130, 128), (220, 128, 128), (229, 68, 89), + (217, 55, 81), (203, 0, 35), (170, 0, 39), (156, 28, 35), + (98, 22, 86), (102, 34, 117), (70, 67, 139), (29, 75, 98), + (4, 94, 75), (64, 95, 55), (63, 100, 59), (59, 100, 86) + ), + +// 137 Apophysis-040426-1H-bird1g +((153, 203, 48), (58, 87, 65), (84, 118, 78), (110, 150, 91), + (139, 125, 63), (168, 100, 36), (176, 98, 28), (185, 97, 20), + (168, 76, 2), (168, 43, 6), (168, 10, 11), (168, 19, 14), + (168, 28, 18), (158, 53, 20), (148, 78, 22), (148, 84, 32), + (148, 91, 42), (185, 122, 53), (193, 129, 53), (201, 136, 54), + (208, 130, 48), (216, 125, 43), (208, 127, 45), (201, 130, 47), + (185, 122, 53), (124, 133, 51), (64, 144, 49), (48, 127, 37), + (33, 110, 26), (33, 101, 28), (33, 92, 30), (33, 64, 24), + (14, 80, 3), (58, 87, 5), (58, 87, 35), (58, 87, 65), + (48, 98, 71), (39, 110, 78), (48, 97, 73), (58, 85, 68), + (105, 55, 95), (129, 39, 109), (153, 23, 123), (142, 20, 126), + (132, 18, 130), (121, 18, 112), (110, 18, 95), (64, 27, 114), + (58, 124, 128), (14, 98, 92), (11, 91, 78), (9, 85, 65), + (9, 103, 32), (9, 121, 0), (24, 134, 0), (39, 147, 0), + (110, 182, 27), (118, 137, 31), (127, 93, 35), (104, 83, 56), + (82, 73, 77), (60, 84, 87), (39, 95, 97), (14, 118, 101), + (39, 140, 74), (132, 191, 25), (152, 202, 38), (172, 213, 51), + (194, 181, 59), (216, 149, 67), (201, 124, 70), (168, 42, 54), + (172, 56, 141), (152, 52, 141), (132, 48, 142), (132, 57, 142), + (132, 67, 143), (132, 82, 141), (132, 98, 140), (110, 81, 134), + (105, 61, 86), (148, 52, 50), (166, 27, 96), (185, 2, 143), + (200, 7, 145), (216, 13, 147), (216, 16, 90), (216, 17, 84), + (201, 18, 19), (201, 26, 12), (201, 34, 5), (201, 63, 10), + (201, 93, 16), (216, 100, 46), (201, 111, 30), (168, 94, 24), + (148, 60, 5), (105, 53, 22), (69, 66, 44), (33, 80, 67), + (36, 86, 78), (39, 93, 89), (64, 127, 80), (87, 156, 61), + (110, 165, 71), (147, 143, 67), (185, 122, 64), (185, 128, 66), + (185, 134, 68), (127, 145, 101), (110, 150, 91), (87, 134, 84), + (64, 138, 65), (39, 140, 33), (39, 139, 27), (39, 139, 21), + (14, 132, 23), (14, 127, 21), (39, 134, 24), (39, 128, 23), + (82, 82, 6), (48, 102, 20), (14, 122, 35), (14, 123, 34), + (14, 125, 33), (9, 119, 28), (9, 101, 41), (9, 97, 53), + (33, 85, 39), (105, 69, 15), (126, 73, 18), (148, 78, 22), + (168, 82, 20), (148, 78, 27), (127, 60, 22), (105, 53, 17), + (105, 26, 31), (107, 15, 32), (110, 5, 33), (107, 6, 38), + (105, 7, 44), (64, 8, 70), (64, 8, 71), (39, 8, 67), + (39, 3, 63), (39, 14, 69), (24, 11, 72), (9, 9, 75), + (33, 2, 73), (39, 4, 66), (39, 8, 62), (33, 2, 72), + (39, 14, 83), (39, 17, 86), (39, 20, 89), (33, 32, 76), + (39, 63, 74), (39, 95, 92), (39, 95, 100), (39, 96, 85), + (64, 85, 74), (168, 100, 46), (176, 114, 50), (185, 128, 55), + (185, 167, 32), (172, 213, 49), (172, 204, 71), (172, 172, 112), + (105, 178, 161), (118, 171, 126), (132, 165, 91), (110, 181, 39), + (110, 181, 39), (87, 170, 32), (64, 147, 50), (64, 144, 55), + (64, 138, 65), (127, 110, 36), (168, 94, 29), (148, 78, 22), + (105, 72, 29), (87, 53, 27), (87, 48, 30), (39, 4, 50), + (39, 17, 48), (39, 20, 38), (39, 24, 29), (39, 15, 1), + (39, 20, 47), (39, 4, 50), (39, 14, 65), (9, 32, 86), + (9, 44, 82), (14, 50, 44), (9, 121, 4), (9, 121, 0), + (14, 125, 32), (39, 129, 48), (64, 141, 60), (110, 158, 81), + (132, 161, 95), (153, 171, 99), (172, 167, 111), (172, 130, 145), + (172, 62, 124), (148, 45, 90), (132, 34, 68), (87, 14, 75), + (64, 20, 69), (39, 38, 65), (39, 53, 64), (64, 51, 117), + (110, 99, 124), (87, 125, 93), (110, 154, 80), (153, 202, 51), + (132, 193, 32), (110, 181, 16), (64, 158, 0), (39, 143, 18), + (39, 139, 21), (39, 142, 28), (39, 140, 33), (39, 140, 33), + (39, 142, 28), (39, 137, 22), (58, 108, 35), (105, 99, 25), + (105, 93, 13), (105, 68, 6), (127, 43, 15), (127, 42, 9), + (148, 43, 4), (127, 43, 8), (105, 68, 6), (105, 56, 12), + (105, 49, 26), (105, 23, 40), (110, 5, 29), (127, 7, 35), + (132, 24, 24), (148, 28, 10), (148, 24, 14), (148, 18, 26), + (153, 11, 88), (185, 7, 145), (185, 11, 148), (201, 24, 157), + (172, 38, 142), (172, 62, 146), (172, 68, 163), (172, 62, 139), + (172, 68, 127), (185, 143, 89), (172, 196, 84), (172, 208, 68) + ), + +// 138 Apophysis-040426-1Emergence2 +((210, 159, 116), (175, 151, 139), (159, 133, 120), (144, 115, 101), + (124, 105, 104), (104, 96, 107), (98, 94, 108), (93, 92, 110), + (99, 84, 107), (101, 70, 105), (103, 57, 104), (122, 65, 117), + (141, 73, 130), (124, 93, 132), (107, 113, 135), (94, 106, 132), + (81, 100, 130), (87, 98, 116), (91, 96, 89), (95, 94, 63), + (60, 57, 32), (26, 21, 2), (26, 21, 2), (26, 21, 2), + (21, 20, 2), (21, 19, 1), (22, 19, 0), (24, 20, 2), + (27, 21, 5), (65, 20, 24), (104, 20, 43), (158, 28, 36), + (197, 21, 34), (199, 26, 32), (142, 25, 33), (86, 24, 35), + (54, 22, 19), (23, 20, 3), (24, 21, 4), (25, 22, 5), + (118, 69, 62), (127, 72, 76), (136, 75, 91), (112, 78, 106), + (89, 81, 122), (46, 73, 138), (4, 65, 154), (47, 112, 142), + (74, 140, 152), (5, 154, 254), (42, 148, 205), (79, 142, 157), + (100, 136, 109), (121, 131, 62), (129, 127, 39), (137, 123, 16), + (179, 171, 2), (200, 186, 5), (222, 202, 9), (221, 200, 9), + (220, 199, 10), (220, 179, 25), (220, 160, 40), (207, 156, 13), + (164, 128, 31), (129, 83, 70), (121, 83, 84), (114, 83, 99), + (108, 100, 86), (102, 118, 73), (115, 122, 44), (136, 115, 48), + (190, 44, 45), (152, 46, 75), (114, 49, 105), (109, 36, 156), + (104, 24, 207), (131, 55, 169), (158, 87, 131), (190, 148, 74), + (207, 156, 15), (208, 155, 13), (206, 179, 13), (204, 203, 14), + (161, 224, 8), (118, 246, 3), (94, 231, 17), (25, 228, 59), + (112, 127, 8), (106, 105, 4), (101, 83, 1), (83, 75, 1), + (66, 67, 1), (26, 21, 2), (26, 21, 2), (26, 21, 2), + (27, 22, 3), (122, 52, 62), (141, 45, 68), (160, 38, 75), + (182, 27, 61), (204, 17, 48), (212, 15, 42), (188, 7, 48), + (79, 23, 32), (52, 22, 17), (26, 21, 2), (26, 21, 2), + (26, 21, 2), (26, 21, 2), (26, 21, 2), (82, 58, 12), + (131, 86, 19), (227, 118, 13), (235, 102, 14), (244, 87, 16), + (246, 84, 19), (254, 85, 20), (247, 84, 17), (246, 85, 17), + (192, 156, 36), (192, 161, 64), (193, 167, 93), (202, 165, 108), + (212, 163, 123), (190, 179, 113), (151, 128, 87), (123, 101, 88), + (99, 85, 82), (123, 76, 92), (123, 82, 96), (124, 88, 100), + (144, 90, 113), (170, 68, 89), (176, 26, 74), (212, 25, 80), + (212, 5, 21), (228, 28, 20), (245, 52, 19), (245, 52, 18), + (245, 53, 17), (233, 36, 20), (225, 26, 21), (208, 22, 45), + (162, 35, 44), (139, 38, 72), (142, 54, 61), (145, 70, 51), + (131, 81, 20), (123, 99, 13), (111, 102, 33), (107, 101, 65), + (104, 90, 81), (110, 96, 85), (117, 103, 90), (179, 174, 118), + (118, 164, 117), (164, 35, 40), (138, 69, 114), (125, 102, 130), + (105, 122, 140), (79, 129, 128), (61, 134, 128), (44, 140, 129), + (56, 143, 124), (78, 140, 125), (101, 140, 75), (136, 117, 22), + (191, 164, 11), (202, 200, 10), (214, 237, 9), (219, 241, 8), + (220, 239, 10), (214, 237, 11), (204, 208, 10), (185, 173, 3), + (154, 139, 14), (98, 169, 67), (0, 161, 93), (15, 233, 175), + (6, 227, 194), (25, 231, 231), (28, 249, 216), (19, 250, 196), + (141, 154, 136), (152, 148, 102), (164, 142, 69), (179, 136, 57), + (188, 118, 30), (172, 97, 29), (104, 79, 15), (26, 21, 2), + (26, 21, 2), (26, 21, 2), (26, 21, 2), (92, 79, 37), + (124, 96, 49), (145, 146, 80), (192, 187, 93), (242, 211, 68), + (230, 222, 61), (206, 188, 52), (172, 139, 36), (141, 143, 78), + (99, 156, 62), (117, 165, 63), (137, 172, 54), (205, 205, 11), + (216, 237, 12), (219, 237, 11), (222, 239, 10), (247, 232, 9), + (249, 231, 11), (248, 227, 12), (241, 226, 11), (229, 224, 2), + (219, 200, 10), (204, 182, 21), (175, 123, 47), (145, 121, 49), + (98, 112, 95), (93, 127, 111), (80, 121, 123), (71, 125, 89), + (59, 113, 89), (30, 29, 8), (26, 21, 2), (26, 21, 2), + (67, 19, 17), (114, 25, 55), (182, 43, 40), (231, 61, 12), + (245, 84, 16), (246, 85, 15), (244, 91, 11), (228, 119, 14), + (228, 119, 14), (227, 122, 17), (225, 123, 15), (210, 153, 12), + (206, 155, 12), (191, 120, 32), (198, 112, 55), (168, 88, 51), + (148, 69, 52), (128, 27, 95), (178, 24, 110), (220, 25, 81), + (225, 67, 32), (227, 120, 14), (208, 156, 11), (221, 203, 9), + (221, 239, 13), (231, 233, 61), (212, 187, 97), (216, 179, 111) + ), + +// 139 Apophysis-040426-1Egg +((116, 47, 60), (111, 50, 25), (113, 48, 42), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (90, 79, 100), (64, 111, 141), (73, 119, 146), + (82, 127, 152), (121, 162, 177), (126, 167, 180), (132, 172, 184), + (170, 191, 198), (209, 211, 213), (176, 194, 201), (143, 178, 189), + (110, 161, 173), (93, 152, 163), (76, 144, 154), (96, 95, 107), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (148, 31, 4), + (133, 39, 7), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (104, 92, 110), (93, 137, 160), (101, 144, 165), (110, 152, 170), + (132, 171, 184), (135, 173, 185), (138, 175, 187), (138, 175, 187), + (138, 175, 187), (138, 175, 187), (138, 175, 187), (138, 168, 185), + (132, 172, 184), (127, 166, 180), (110, 151, 170), (93, 137, 160), + (63, 110, 141), (33, 83, 122), (27, 56, 104), (21, 29, 86), + (52, 0, 65), (58, 5, 61), (64, 11, 57), (55, 8, 63), + (46, 5, 69), (36, 14, 75), (27, 23, 82), (15, 35, 90), + (14, 65, 110), (51, 100, 133), (78, 123, 150), (105, 147, 167), + (105, 147, 167), (105, 147, 167), (93, 137, 160), (70, 116, 145), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (102, 41, 51), (88, 36, 42), + (82, 30, 45), (76, 24, 49), (64, 11, 57), (64, 11, 57), + (40, 11, 74), (21, 32, 88), (2, 53, 102), (11, 62, 108), + (21, 71, 114), (21, 71, 114), (21, 71, 114), (27, 77, 118), + (21, 71, 114), (9, 41, 94), (27, 23, 81), (46, 5, 69), + (55, 8, 63), (64, 11, 57), (70, 18, 53), (82, 30, 45), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (94, 42, 38), (88, 36, 42), (88, 36, 42), + (82, 30, 45), (70, 18, 53), (73, 21, 51), (76, 24, 49), + (40, 85, 78), (64, 111, 141), (93, 137, 160), (116, 157, 174), + (132, 172, 184), (135, 173, 185), (138, 175, 187), (138, 169, 185), + (138, 164, 183), (138, 150, 176), (116, 47, 60), (172, 19, 26), + (190, 10, 43), (219, 2, 74), (236, 10, 104), (253, 19, 135), + (238, 12, 147), (138, 82, 128), (76, 122, 149), (70, 116, 145), + (21, 117, 121), (27, 100, 121), (33, 83, 122), (33, 83, 122), + (39, 88, 126), (58, 105, 137), (70, 116, 145), (76, 122, 149), + (70, 116, 145), (39, 126, 132), (39, 126, 132), (39, 126, 132), + (70, 141, 151), (99, 142, 163), (105, 147, 167), (105, 159, 170), + (70, 141, 151), (54, 133, 141), (39, 126, 132), (14, 113, 116), + (2, 107, 108), (27, 77, 118), (27, 92, 87), (70, 70, 56), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (88, 36, 42), + (82, 30, 45), (70, 18, 53), (33, 17, 78), (9, 41, 94), + (33, 88, 83), (57, 76, 65), (82, 64, 47), (94, 42, 38), + (94, 42, 38), (94, 42, 38), (94, 42, 38), (94, 42, 38), + (88, 36, 42), (82, 30, 45), (76, 24, 49), (70, 18, 53), + (64, 11, 57), (64, 11, 57), (58, 5, 61), (58, 5, 61), + (64, 11, 57), (70, 18, 53), (82, 30, 45), (88, 36, 42), + (94, 42, 38), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (138, 110, 149), (116, 157, 174), (127, 166, 180), (127, 170, 182), + (127, 166, 180), (105, 159, 170), (76, 144, 154), (45, 94, 130), + (52, 79, 70), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60), + (116, 47, 60), (94, 42, 38), (88, 36, 42), (52, 79, 70), + (39, 88, 126), (58, 105, 137), (76, 122, 149), (82, 127, 152), + (76, 122, 149), (64, 111, 141), (51, 100, 133), (71, 70, 81), + (116, 47, 60), (116, 47, 60), (116, 47, 60), (116, 47, 60) + ), + +// 140 Apophysis-040426-1PenEgg +((128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (126, 37, 83), (124, 40, 81), (125, 93, 82), + (127, 147, 83), (158, 173, 99), (189, 199, 115), (172, 187, 131), + (155, 176, 147), (127, 128, 167), (127, 100, 129), (127, 73, 91), + (127, 54, 88), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (127, 36, 67), + (127, 37, 48), (149, 36, 30), (172, 36, 12), (206, 22, 1), + (222, 0, 0), (182, 34, 9), (153, 25, 15), (124, 16, 22), + (116, 22, 37), (109, 29, 52), (109, 28, 52), (110, 27, 53), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (190, 30, 60), (254, 105, 60), (248, 140, 69), (242, 175, 79), + (180, 175, 105), (118, 175, 132), (100, 159, 143), (82, 144, 155), + (127, 36, 87), (127, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (127, 43, 77), (115, 68, 60), (104, 93, 44), (94, 118, 35), + (85, 143, 27), (71, 112, 32), (58, 81, 38), (18, 111, 118), + (24, 115, 122), (6, 99, 85), (8, 51, 70), (10, 3, 55), + (10, 4, 57), (10, 6, 59), (16, 10, 63), (40, 22, 72), + (124, 34, 79), (126, 34, 82), (128, 35, 86), (131, 34, 89), + (134, 33, 93), (210, 0, 114), (245, 67, 187), (229, 0, 127), + (127, 1, 122), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (108, 45, 74), (65, 33, 69), (34, 21, 72), + (22, 13, 66), (31, 17, 69), (45, 23, 70), (59, 29, 72), + (81, 38, 68), (92, 40, 64), (114, 46, 49), (127, 59, 20), + (127, 61, 19), (119, 45, 42), (112, 29, 65), (120, 32, 75), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (124, 37, 86), (55, 12, 71), (55, 10, 56), (56, 9, 42), + (35, 1, 23), (32, 1, 23), (53, 3, 6), (77, 17, 22), + (106, 27, 56), (117, 31, 71), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (127, 66, 118), (26, 120, 132), (25, 118, 127), (25, 116, 123), + (9, 97, 83), (54, 74, 72), (75, 54, 64), (123, 40, 81), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 31, 83), (127, 15, 19), (133, 29, 17), (140, 44, 15), + (160, 44, 2), (165, 43, 18), (130, 46, 57), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (127, 36, 85), (94, 41, 63), (90, 60, 41), + (46, 90, 8), (54, 74, 20), (70, 35, 45), (83, 20, 29), + (89, 62, 32), (94, 97, 32), (91, 145, 20), (99, 154, 26), + (101, 64, 62), (105, 54, 58), (109, 45, 55), (115, 94, 68), + (129, 120, 50), (165, 151, 75), (127, 139, 60), (251, 228, 131), + (241, 180, 78), (227, 215, 74), (212, 212, 81), (210, 214, 82), + (144, 172, 74), (127, 149, 77), (127, 126, 96), (77, 141, 153), + (87, 146, 157), (102, 155, 160), (159, 183, 189), (197, 198, 158), + (234, 222, 199), (217, 213, 147), (252, 230, 133), (240, 179, 79), + (250, 147, 72), (253, 136, 70), (253, 103, 58), (251, 83, 49), + (245, 38, 34), (176, 36, 12), (89, 45, 20), (70, 66, 0), + (29, 62, 27), (13, 39, 32), (16, 4, 47), (18, 0, 66), + (27, 0, 67), (66, 17, 75), (102, 32, 83), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (123, 32, 78), (69, 22, 73), + (47, 24, 72), (33, 18, 69), (44, 24, 51), (83, 20, 31), + (94, 22, 42), (127, 28, 8), (133, 48, 27), (141, 47, 21), + (179, 37, 11), (199, 51, 29), (170, 42, 20), (127, 5, 36), + (127, 4, 41), (127, 3, 57), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86), + (128, 35, 86), (128, 35, 86), (128, 35, 86), (128, 35, 86) + ), + +// 141 Apophysis-040426-1kaosGothic +((153, 26, 22), (233, 221, 164), (171, 190, 134), (110, 160, 104), + (82, 82, 68), (55, 4, 33), (30, 4, 33), (6, 4, 33), + (37, 123, 67), (37, 123, 67), (37, 123, 67), (26, 109, 53), + (16, 96, 40), (31, 88, 32), (47, 80, 25), (47, 80, 25), + (47, 80, 25), (47, 80, 25), (47, 80, 25), (47, 80, 25), + (47, 80, 25), (47, 80, 25), (47, 80, 25), (47, 80, 25), + (94, 56, 1), (70, 68, 13), (47, 80, 25), (47, 80, 25), + (47, 80, 25), (70, 68, 13), (94, 56, 1), (139, 34, 19), + (143, 32, 21), (139, 34, 19), (139, 34, 19), (139, 34, 19), + (116, 45, 10), (94, 56, 1), (103, 52, 3), (112, 48, 5), + (139, 34, 19), (139, 34, 19), (139, 34, 19), (133, 37, 16), + (127, 40, 13), (110, 48, 7), (94, 56, 1), (94, 56, 1), + (94, 56, 1), (94, 56, 1), (94, 56, 1), (94, 56, 1), + (94, 56, 1), (94, 56, 1), (94, 56, 1), (94, 56, 1), + (94, 56, 1), (94, 56, 1), (94, 56, 1), (94, 56, 1), + (94, 56, 1), (116, 45, 10), (139, 34, 19), (139, 34, 19), + (143, 32, 21), (177, 15, 38), (194, 8, 46), (212, 1, 55), + (212, 1, 55), (212, 1, 55), (228, 8, 63), (228, 8, 63), + (249, 19, 73), (230, 10, 64), (212, 1, 55), (175, 17, 37), + (139, 34, 19), (116, 45, 10), (94, 56, 1), (94, 56, 1), + (139, 34, 19), (139, 34, 19), (133, 37, 16), (127, 40, 13), + (110, 48, 7), (94, 56, 1), (94, 56, 1), (139, 34, 19), + (139, 34, 19), (116, 45, 10), (94, 56, 1), (73, 67, 11), + (52, 78, 22), (47, 80, 25), (47, 80, 25), (47, 80, 25), + (47, 80, 25), (37, 123, 67), (87, 148, 92), (138, 173, 117), + (157, 183, 126), (177, 193, 136), (233, 221, 164), (240, 225, 168), + (138, 173, 117), (96, 152, 96), (55, 132, 76), (55, 132, 76), + (55, 132, 76), (93, 78, 57), (139, 34, 19), (181, 13, 40), + (212, 1, 55), (251, 20, 74), (251, 20, 74), (251, 20, 74), + (253, 21, 75), (219, 214, 157), (240, 225, 168), (252, 230, 174), + (240, 225, 168), (246, 123, 121), (253, 21, 75), (251, 20, 74), + (249, 19, 73), (235, 12, 66), (212, 1, 55), (181, 13, 40), + (177, 15, 38), (139, 34, 19), (116, 45, 10), (94, 56, 1), + (94, 56, 1), (47, 80, 25), (47, 80, 25), (47, 80, 25), + (16, 96, 40), (11, 101, 46), (6, 107, 52), (6, 107, 52), + (6, 107, 52), (16, 96, 40), (47, 80, 25), (94, 56, 1), + (94, 56, 1), (94, 56, 1), (94, 56, 1), (94, 56, 1), + (94, 56, 1), (94, 56, 1), (94, 56, 1), (94, 56, 1), + (47, 80, 25), (47, 80, 25), (47, 80, 25), (47, 80, 25), + (47, 80, 25), (65, 71, 16), (94, 56, 1), (139, 34, 19), + (177, 15, 38), (181, 13, 40), (179, 14, 39), (177, 15, 38), + (143, 32, 21), (139, 34, 19), (139, 34, 19), (94, 56, 1), + (139, 34, 19), (158, 24, 28), (177, 15, 38), (181, 13, 40), + (181, 13, 40), (181, 13, 40), (177, 15, 38), (143, 32, 21), + (139, 34, 19), (94, 56, 1), (94, 56, 1), (47, 80, 25), + (47, 80, 25), (47, 80, 25), (94, 56, 1), (112, 48, 5), + (139, 34, 19), (139, 34, 19), (139, 34, 19), (127, 40, 13), + (94, 56, 1), (94, 56, 1), (139, 34, 19), (143, 32, 21), + (177, 15, 38), (181, 13, 40), (212, 1, 55), (212, 1, 55), + (201, 3, 50), (177, 15, 38), (139, 34, 19), (94, 56, 1), + (65, 71, 16), (47, 80, 25), (47, 80, 25), (16, 96, 40), + (14, 112, 56), (6, 107, 52), (16, 96, 40), (47, 80, 25), + (94, 56, 1), (94, 56, 1), (139, 34, 19), (181, 13, 40), + (212, 1, 55), (212, 1, 55), (212, 1, 55), (190, 8, 44), + (181, 13, 40), (181, 13, 40), (177, 15, 38), (143, 32, 21), + (139, 34, 19), (94, 56, 1), (47, 80, 25), (47, 80, 25), + (47, 80, 25), (16, 96, 40), (2, 102, 47), (16, 96, 40), + (16, 96, 40), (47, 80, 25), (94, 56, 1), (139, 34, 19), + (139, 34, 19), (99, 54, 0), (94, 56, 1), (94, 56, 1), + (47, 80, 25), (47, 80, 25), (47, 80, 25), (94, 56, 1), + (139, 34, 19), (143, 32, 21), (168, 20, 33), (177, 15, 38), + (181, 13, 40), (212, 1, 55), (228, 8, 63), (249, 19, 73), + (253, 21, 75), (253, 21, 75), (253, 21, 75), (249, 19, 73), + (235, 12, 66), (219, 4, 58), (181, 13, 40), (139, 34, 19) + ), + +// 142 Apophysis-040426-1KQNova +((82, 83, 39), (198, 92, 96), (200, 91, 77), (203, 90, 58), + (148, 82, 31), (94, 74, 5), (85, 70, 16), (76, 67, 28), + (2, 44, 42), (14, 46, 54), (26, 49, 67), (57, 36, 53), + (88, 24, 40), (91, 35, 43), (95, 47, 47), (86, 48, 44), + (77, 50, 41), (125, 179, 21), (145, 182, 33), (165, 186, 45), + (179, 184, 51), (193, 182, 58), (189, 173, 55), (186, 164, 53), + (167, 153, 48), (185, 138, 36), (204, 124, 25), (229, 87, 23), + (255, 50, 21), (237, 30, 18), (220, 11, 16), (178, 5, 11), + (167, 23, 14), (194, 31, 0), (222, 55, 13), (250, 79, 27), + (244, 99, 50), (238, 120, 74), (239, 117, 73), (241, 114, 73), + (168, 45, 12), (163, 34, 16), (158, 23, 20), (160, 13, 10), + (163, 4, 1), (165, 10, 2), (167, 17, 3), (197, 27, 2), + (216, 13, 9), (153, 18, 24), (151, 28, 55), (149, 39, 86), + (188, 19, 93), (228, 0, 100), (230, 4, 90), (232, 8, 81), + (235, 44, 16), (242, 45, 27), (249, 46, 39), (249, 63, 45), + (249, 80, 51), (251, 92, 91), (254, 104, 131), (236, 121, 124), + (245, 109, 97), (246, 155, 48), (233, 154, 64), (221, 153, 80), + (235, 157, 149), (249, 161, 219), (230, 207, 213), (218, 203, 180), + (222, 220, 199), (222, 224, 215), (223, 228, 231), (236, 238, 225), + (250, 249, 219), (248, 247, 217), (247, 246, 216), (253, 234, 178), + (251, 207, 162), (253, 131, 188), (247, 148, 126), (241, 166, 65), + (242, 178, 63), (244, 191, 61), (251, 238, 82), (252, 253, 115), + (149, 191, 189), (100, 165, 165), (52, 140, 141), (48, 136, 132), + (45, 132, 124), (98, 175, 69), (100, 176, 16), (74, 164, 4), + (52, 138, 13), (32, 100, 51), (48, 107, 64), (64, 114, 77), + (93, 113, 68), (123, 113, 60), (129, 117, 59), (92, 97, 57), + (122, 51, 65), (149, 76, 69), (177, 102, 73), (168, 119, 55), + (160, 136, 38), (153, 87, 0), (128, 83, 0), (138, 62, 0), + (134, 47, 28), (111, 57, 47), (107, 81, 34), (104, 106, 22), + (139, 159, 44), (204, 131, 78), (230, 84, 84), (247, 19, 116), + (229, 11, 150), (188, 34, 117), (147, 57, 85), (117, 72, 97), + (87, 88, 109), (76, 90, 99), (69, 94, 90), (58, 43, 76), + (21, 46, 66), (14, 94, 117), (20, 110, 124), (27, 126, 131), + (26, 135, 132), (74, 109, 89), (52, 95, 76), (86, 65, 74), + (127, 16, 35), (123, 18, 31), (120, 20, 28), (117, 14, 23), + (115, 8, 18), (76, 2, 29), (33, 1, 50), (7, 19, 67), + (26, 59, 90), (152, 72, 157), (171, 72, 162), (190, 72, 168), + (185, 45, 150), (177, 29, 123), (164, 38, 119), (126, 34, 99), + (86, 16, 86), (80, 19, 91), (75, 23, 97), (122, 66, 139), + (154, 77, 159), (133, 112, 145), (141, 163, 176), (168, 199, 193), + (212, 225, 182), (252, 210, 162), (240, 226, 155), (229, 243, 148), + (225, 239, 68), (232, 193, 64), (230, 178, 56), (225, 184, 58), + (209, 195, 73), (195, 206, 112), (181, 218, 151), (226, 237, 177), + (225, 234, 189), (245, 247, 210), (252, 244, 242), (252, 194, 232), + (250, 181, 226), (238, 188, 223), (231, 186, 215), (219, 174, 197), + (171, 161, 169), (126, 141, 122), (132, 137, 43), (105, 108, 21), + (168, 124, 25), (173, 129, 28), (179, 134, 31), (205, 101, 16), + (231, 139, 38), (248, 149, 48), (244, 186, 60), (236, 196, 65), + (246, 219, 80), (247, 246, 78), (236, 205, 65), (248, 171, 53), + (248, 115, 70), (253, 18, 93), (232, 7, 113), (216, 5, 120), + (213, 13, 148), (219, 15, 146), (223, 85, 180), (253, 132, 186), + (253, 145, 207), (243, 165, 205), (204, 158, 195), (145, 173, 174), + (111, 162, 166), (116, 155, 111), (142, 155, 49), (122, 175, 35), + (100, 153, 35), (63, 160, 27), (15, 103, 25), (3, 71, 24), + (3, 58, 39), (26, 84, 25), (51, 88, 19), (41, 68, 1), + (52, 37, 4), (64, 27, 1), (86, 7, 10), (100, 27, 54), + (138, 61, 81), (131, 132, 56), (159, 179, 80), (146, 161, 60), + (98, 112, 51), (39, 79, 68), (9, 54, 47), (2, 45, 36), + (9, 54, 31), (22, 41, 21), (22, 26, 25), (28, 0, 27), + (86, 7, 13), (86, 8, 8), (105, 1, 12), (122, 36, 35), + (132, 54, 52), (112, 20, 67), (92, 2, 53), (93, 9, 25), + (105, 16, 2), (116, 53, 12), (79, 68, 12), (87, 76, 31), + (47, 117, 29), (68, 157, 7), (92, 165, 0), (86, 137, 0), + (47, 109, 34), (30, 87, 44), (76, 59, 65), (152, 140, 40) + ), + +// 143 Apophysis-040426-1kaosframe +((249, 250, 185), (158, 204, 168), (114, 141, 121), (70, 79, 74), + (62, 67, 71), (55, 56, 68), (62, 67, 69), (70, 79, 70), + (93, 167, 144), (104, 174, 148), (116, 182, 152), (155, 203, 158), + (194, 224, 164), (210, 224, 139), (227, 225, 115), (213, 215, 102), + (200, 206, 89), (227, 0, 99), (205, 6, 98), (184, 12, 98), + (205, 118, 106), (227, 225, 115), (232, 229, 121), (237, 233, 127), + (251, 245, 160), (251, 245, 160), (251, 245, 160), (239, 235, 137), + (227, 225, 115), (213, 217, 102), (200, 209, 90), (166, 17, 95), + (166, 17, 95), (177, 35, 4), (177, 35, 4), (177, 35, 4), + (146, 48, 24), (116, 61, 45), (104, 65, 52), (93, 70, 60), + (55, 51, 70), (50, 71, 83), (45, 91, 96), (69, 130, 120), + (93, 169, 144), (93, 168, 146), (93, 167, 148), (116, 180, 156), + (158, 204, 177), (209, 232, 189), (225, 240, 188), (242, 248, 188), + (248, 249, 181), (254, 251, 175), (254, 251, 175), (254, 251, 175), + (253, 250, 174), (247, 249, 175), (242, 248, 176), (225, 240, 174), + (209, 232, 172), (201, 228, 168), (194, 224, 164), (177, 214, 156), + (138, 192, 152), (93, 164, 147), (104, 112, 96), (116, 61, 45), + (116, 61, 45), (116, 61, 45), (116, 61, 45), (93, 70, 56), + (45, 89, 50), (62, 66, 63), (79, 43, 76), (102, 36, 81), + (125, 30, 87), (135, 24, 92), (146, 19, 98), (200, 7, 105), + (237, 1, 97), (233, 9, 43), (221, 15, 31), (209, 21, 20), + (209, 21, 20), (209, 21, 20), (209, 21, 20), (222, 15, 32), + (253, 0, 71), (231, 10, 45), (209, 21, 20), (183, 32, 18), + (158, 43, 17), (200, 206, 89), (227, 225, 115), (237, 233, 127), + (237, 233, 127), (215, 213, 86), (176, 202, 113), (138, 192, 141), + (148, 198, 154), (158, 204, 168), (194, 224, 176), (209, 232, 178), + (233, 244, 178), (243, 247, 176), (253, 250, 174), (253, 251, 175), + (254, 252, 176), (253, 251, 181), (242, 248, 188), (222, 238, 190), + (222, 238, 190), (242, 248, 188), (245, 249, 186), (249, 250, 185), + (253, 251, 181), (253, 251, 181), (253, 251, 181), (253, 251, 181), + (222, 238, 190), (208, 231, 188), (194, 224, 186), (185, 219, 179), + (177, 214, 172), (138, 192, 162), (116, 180, 156), (116, 180, 151), + (116, 180, 156), (158, 205, 173), (176, 214, 174), (194, 224, 176), + (209, 232, 183), (209, 232, 189), (209, 232, 178), (194, 224, 176), + (116, 180, 156), (80, 134, 105), (45, 89, 54), (51, 98, 35), + (58, 108, 16), (70, 79, 9), (93, 70, 56), (93, 70, 56), + (93, 70, 60), (93, 70, 56), (93, 70, 58), (93, 70, 60), + (70, 79, 70), (93, 164, 147), (116, 180, 156), (158, 204, 168), + (222, 238, 190), (227, 241, 190), (233, 244, 190), (242, 248, 188), + (249, 250, 185), (253, 251, 181), (253, 252, 181), (253, 252, 181), + (253, 251, 181), (242, 248, 182), (237, 246, 180), (233, 244, 178), + (222, 238, 178), (222, 238, 178), (222, 238, 178), (233, 244, 178), + (242, 248, 176), (245, 249, 174), (249, 250, 173), (254, 248, 168), + (249, 249, 166), (251, 247, 160), (254, 251, 163), (254, 251, 169), + (254, 248, 168), (251, 245, 160), (254, 248, 156), (245, 242, 139), + (245, 240, 138), (237, 233, 116), (215, 216, 103), (245, 3, 100), + (253, 0, 71), (243, 4, 57), (233, 9, 43), (209, 21, 26), + (242, 200, 73), (237, 233, 121), (245, 240, 138), (245, 240, 150), + (222, 238, 178), (222, 238, 190), (222, 238, 190), (222, 238, 190), + (222, 238, 190), (233, 244, 190), (242, 248, 188), (249, 250, 185), + (253, 251, 181), (253, 251, 181), (254, 251, 175), (254, 248, 168), + (251, 245, 153), (245, 240, 121), (227, 225, 115), (215, 216, 97), + (184, 194, 75), (138, 52, 31), (177, 35, 4), (194, 28, 8), + (194, 28, 8), (209, 21, 20), (209, 21, 20), (222, 15, 32), + (233, 9, 43), (242, 4, 60), (254, 2, 79), (254, 3, 85), + (253, 0, 71), (222, 15, 32), (209, 21, 20), (194, 28, 13), + (158, 43, 17), (116, 61, 41), (116, 61, 45), (116, 61, 45), + (146, 23, 92), (166, 17, 95), (200, 7, 99), (237, 1, 97), + (251, 3, 90), (254, 3, 85), (254, 2, 79), (251, 3, 90), + (251, 3, 96), (237, 1, 97), (184, 12, 98), (166, 17, 95), + (103, 36, 82), (79, 43, 76), (103, 36, 86), (146, 23, 96), + (184, 12, 103), (227, 0, 105), (245, 3, 94), (254, 2, 79), + (254, 3, 91), (237, 1, 97), (184, 12, 98), (125, 30, 87), + (79, 43, 80), (79, 43, 80), (103, 36, 82), (146, 23, 92) + ), + +// 144 Apophysis-040426-147KaosRing +((82, 81, 4), (82, 76, 6), (82, 52, 23), (82, 29, 41), + (82, 30, 41), (82, 32, 42), (82, 48, 47), (82, 65, 53), + (82, 94, 63), (82, 97, 64), (82, 100, 65), (82, 87, 60), + (82, 74, 56), (82, 54, 49), (82, 35, 43), (82, 32, 42), + (82, 29, 41), (82, 29, 41), (82, 27, 40), (82, 26, 40), + (82, 26, 39), (82, 26, 39), (82, 26, 39), (82, 26, 40), + (82, 26, 40), (82, 29, 41), (82, 32, 43), (82, 61, 61), + (82, 90, 79), (82, 87, 70), (82, 85, 61), (82, 41, 45), + (82, 29, 41), (82, 20, 38), (82, 13, 36), (82, 7, 34), + (82, 6, 31), (82, 5, 29), (82, 4, 31), (82, 4, 33), + (82, 10, 35), (82, 11, 35), (82, 12, 35), (82, 14, 30), + (82, 17, 26), (82, 18, 25), (82, 20, 25), (82, 24, 25), + (82, 39, 15), (82, 82, 4), (82, 82, 4), (82, 82, 4), + (82, 74, 7), (82, 66, 10), (82, 49, 26), (82, 32, 42), + (82, 29, 41), (82, 27, 40), (82, 26, 40), (82, 24, 39), + (82, 23, 39), (82, 23, 39), (82, 23, 39), (82, 23, 39), + (82, 23, 39), (82, 21, 38), (82, 22, 38), (82, 23, 39), + (82, 23, 39), (82, 23, 39), (82, 20, 38), (82, 20, 38), + (82, 20, 38), (82, 18, 37), (82, 16, 37), (82, 14, 36), + (82, 13, 36), (82, 13, 36), (82, 13, 36), (82, 10, 35), + (82, 10, 35), (82, 14, 26), (82, 21, 23), (82, 29, 21), + (82, 50, 14), (82, 71, 8), (82, 81, 4), (82, 84, 3), + (82, 85, 3), (82, 85, 3), (82, 85, 3), (82, 85, 3), + (82, 85, 3), (82, 85, 3), (82, 80, 5), (73, 76, 44), + (82, 35, 43), (82, 32, 42), (82, 29, 41), (82, 26, 40), + (82, 26, 40), (82, 26, 40), (82, 29, 41), (82, 32, 42), + (82, 85, 60), (82, 94, 63), (82, 104, 66), (82, 105, 67), + (82, 107, 68), (82, 100, 64), (82, 80, 57), (117, 69, 51), + (82, 35, 43), (82, 23, 39), (82, 21, 38), (82, 20, 38), + (82, 16, 37), (82, 11, 34), (82, 11, 27), (82, 14, 26), + (82, 8, 28), (82, 9, 31), (82, 10, 35), (82, 11, 35), + (82, 13, 36), (82, 13, 36), (82, 13, 36), (82, 13, 36), + (82, 13, 36), (82, 13, 36), (82, 14, 37), (82, 15, 38), + (82, 16, 37), (82, 20, 38), (82, 24, 40), (82, 29, 41), + (82, 78, 5), (82, 73, 7), (82, 68, 9), (82, 50, 25), + (82, 32, 42), (82, 29, 41), (82, 26, 40), (82, 23, 39), + (82, 20, 38), (82, 13, 36), (82, 11, 35), (82, 10, 35), + (82, 7, 34), (82, 4, 33), (82, 1, 32), (82, 0, 31), + (82, 0, 31), (82, 0, 31), (82, 0, 31), (82, 0, 31), + (82, 0, 31), (82, 1, 32), (82, 1, 32), (82, 5, 29), + (82, 8, 28), (82, 20, 25), (72, 24, 12), (63, 29, 0), + (82, 72, 7), (82, 81, 4), (82, 84, 3), (82, 85, 3), + (82, 82, 4), (82, 75, 6), (82, 68, 8), (82, 25, 25), + (82, 17, 26), (82, 11, 27), (82, 5, 29), (82, 5, 29), + (82, 5, 29), (82, 5, 29), (82, 5, 32), (82, 10, 35), + (82, 16, 37), (82, 23, 39), (82, 32, 42), (82, 71, 55), + (82, 119, 71), (82, 122, 71), (82, 125, 72), (82, 147, 80), + (82, 163, 83), (82, 173, 88), (82, 180, 94), (82, 173, 89), + (82, 165, 86), (82, 146, 80), (82, 109, 68), (82, 97, 60), + (82, 70, 55), (82, 32, 42), (82, 29, 41), (82, 29, 41), + (82, 32, 42), (82, 58, 52), (82, 93, 62), (82, 124, 72), + (82, 141, 79), (82, 157, 78), (82, 129, 74), (82, 109, 68), + (94, 87, 21), (82, 83, 4), (82, 85, 3), (82, 85, 3), + (82, 85, 3), (82, 84, 3), (82, 81, 4), (82, 66, 9), + (82, 32, 42), (82, 29, 41), (82, 26, 40), (82, 23, 39), + (82, 20, 38), (82, 16, 37), (82, 10, 35), (82, 4, 33), + (82, 3, 30), (82, 3, 30), (82, 3, 29), (82, 5, 29), + (82, 8, 28), (82, 8, 28), (82, 8, 28), (82, 11, 27), + (82, 14, 26), (82, 14, 26), (82, 11, 27), (82, 8, 28), + (82, 8, 28), (82, 10, 35), (82, 13, 36), (82, 16, 37), + (82, 20, 38), (82, 23, 39), (82, 26, 40), (82, 27, 39), + (82, 41, 20), (82, 71, 8), (82, 78, 5), (82, 78, 5), + (82, 66, 10), (82, 35, 42), (82, 35, 43), (82, 83, 59), + (82, 109, 68), (82, 141, 79), (175, 154, 107), (175, 119, 79) + ), + +// 145 Apophysis-040426-147Fighting_Fish +((172, 212, 200), (212, 226, 92), (212, 211, 72), (212, 197, 53), + (178, 197, 53), (144, 198, 54), (98, 175, 34), (53, 152, 15), + (59, 114, 45), (118, 154, 90), (177, 195, 136), (174, 203, 168), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (192, 220, 152), (212, 228, 104), (212, 222, 88), (212, 216, 73), + (212, 197, 53), (212, 210, 69), (212, 224, 86), (192, 218, 143), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (112, 182, 107), (53, 152, 15), + (53, 152, 14), (53, 152, 13), (53, 152, 13), (53, 152, 13), + (47, 149, 16), (50, 130, 32), (53, 111, 48), (53, 111, 39), + (53, 111, 30), (50, 130, 24), (47, 149, 18), (53, 152, 15), + (212, 190, 49), (212, 190, 49), (212, 190, 49), (212, 190, 49), + (212, 191, 49), (212, 193, 50), (212, 195, 51), (212, 197, 53), + (212, 214, 60), (212, 220, 69), (212, 227, 78), (212, 224, 74), + (212, 221, 71), (212, 220, 68), (212, 219, 65), (212, 211, 58), + (212, 212, 60), (212, 227, 95), (192, 219, 147), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (182, 199, 139), (147, 175, 107), (112, 151, 75), (85, 132, 63), + (59, 114, 51), (71, 122, 52), (144, 173, 93), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (158, 192, 158), (144, 173, 117), (53, 111, 73), (47, 105, 51), + (47, 105, 45), (47, 127, 31), (47, 149, 18), (47, 149, 16), + (47, 149, 15), (47, 149, 15), (47, 149, 16), (47, 149, 17), + (53, 111, 30), (53, 111, 79), (108, 148, 97), (164, 186, 116), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (192, 217, 142), (212, 223, 84), (212, 216, 73), + (212, 209, 63), (212, 199, 55), (212, 193, 50), (212, 193, 50), + (212, 193, 49), (212, 190, 49), (212, 191, 49), (212, 193, 50), + (212, 193, 52), (212, 205, 60), (186, 201, 116), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (206, 226, 173), + (240, 240, 147), (233, 243, 101), (212, 231, 92), (212, 229, 85), + (212, 225, 91), (212, 229, 93), (212, 230, 99), (212, 232, 106), + (228, 231, 152), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (202, 212, 150), (207, 216, 128), (212, 221, 106), (212, 203, 61), + (212, 190, 49), (106, 146, 59), (59, 114, 45), (53, 111, 48), + (59, 114, 51), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (245, 249, 158), (252, 249, 166), + (253, 251, 155), (244, 243, 149), (212, 226, 93), (212, 195, 52), + (94, 138, 65), (73, 124, 60), (53, 111, 55), (53, 111, 48), + (53, 111, 48), (53, 111, 48), (53, 111, 48), (53, 111, 48), + (53, 111, 48), (53, 111, 48), (65, 119, 49), (159, 182, 101), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (53, 111, 96), (53, 111, 73), (53, 111, 55), + (53, 111, 55), (53, 111, 55), (47, 105, 69), (53, 111, 101), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (172, 212, 200), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (243, 248, 163), + (253, 251, 173), (253, 252, 167), (250, 251, 154), (242, 248, 162), + (172, 212, 200), (172, 212, 200), (172, 212, 200), (194, 207, 115), + (123, 158, 63), (71, 122, 23), (47, 105, 20), (53, 111, 8), + (53, 111, 3), (47, 149, 0), (53, 152, 1), (53, 152, 4), + (47, 149, 8), (47, 149, 15), (53, 152, 14), (53, 152, 12), + (53, 152, 4), (53, 152, 12), (53, 152, 12), (53, 152, 13), + (53, 152, 15), (212, 190, 49), (212, 201, 59), (212, 226, 93), + (219, 225, 147), (172, 212, 200), (172, 212, 200), (172, 212, 200) + ), + +// 146 Apophysis-040426-147ReachingMoon +((39, 17, 100), (46, 43, 45), (61, 44, 41), (76, 45, 37), + (67, 47, 38), (58, 49, 40), (45, 43, 44), (33, 37, 49), + (8, 2, 80), (11, 1, 81), (14, 0, 83), (14, 0, 83), + (14, 0, 83), (14, 0, 83), (14, 0, 83), (14, 0, 83), + (14, 0, 83), (14, 0, 83), (14, 0, 83), (14, 0, 83), + (11, 1, 81), (8, 2, 80), (11, 11, 72), (15, 21, 64), + (82, 67, 23), (143, 109, 40), (205, 152, 57), (215, 166, 76), + (225, 181, 95), (231, 187, 102), (237, 193, 109), (237, 193, 109), + (245, 191, 94), (247, 200, 106), (250, 205, 113), (253, 210, 120), + (247, 207, 120), (242, 205, 120), (247, 209, 120), (253, 213, 120), + (253, 248, 246), (223, 229, 201), (194, 211, 157), (178, 168, 93), + (163, 125, 29), (150, 119, 26), (138, 113, 24), (111, 84, 6), + (88, 76, 12), (105, 82, 8), (131, 101, 17), (158, 120, 26), + (174, 136, 39), (190, 153, 53), (204, 163, 68), (219, 173, 83), + (181, 137, 43), (137, 108, 27), (94, 79, 11), (66, 48, 55), + (39, 17, 99), (39, 17, 99), (39, 17, 99), (39, 17, 100), + (39, 17, 100), (39, 17, 99), (26, 8, 91), (14, 0, 83), + (11, 1, 81), (8, 2, 80), (2, 9, 75), (9, 18, 66), + (33, 37, 49), (39, 40, 47), (46, 43, 45), (52, 49, 38), + (58, 55, 32), (55, 50, 37), (52, 46, 42), (46, 43, 45), + (33, 37, 49), (15, 21, 64), (12, 19, 65), (9, 18, 66), + (9, 18, 66), (9, 18, 66), (15, 21, 64), (15, 21, 64), + (40, 40, 47), (33, 33, 53), (27, 27, 59), (21, 24, 61), + (15, 21, 64), (15, 21, 64), (9, 18, 66), (9, 18, 66), + (9, 18, 66), (2, 5, 78), (5, 3, 79), (8, 2, 80), + (8, 2, 80), (8, 2, 80), (2, 5, 78), (9, 18, 66), + (27, 27, 59), (18, 22, 62), (9, 18, 66), (9, 18, 66), + (9, 18, 66), (9, 18, 66), (2, 5, 78), (2, 5, 78), + (2, 9, 75), (27, 27, 58), (36, 35, 51), (46, 43, 45), + (58, 55, 33), (70, 61, 28), (88, 67, 22), (94, 79, 10), + (111, 93, 3), (122, 101, 11), (133, 110, 20), (143, 118, 28), + (153, 126, 36), (123, 175, 109), (172, 150, 159), (117, 182, 180), + (106, 180, 155), (89, 43, 58), (64, 30, 78), (39, 17, 99), + (39, 17, 100), (39, 17, 100), (39, 17, 100), (39, 17, 99), + (14, 0, 83), (26, 8, 91), (39, 17, 99), (39, 17, 99), + (39, 17, 99), (39, 17, 100), (39, 17, 100), (39, 17, 100), + (39, 17, 100), (14, 0, 83), (14, 0, 83), (14, 0, 83), + (8, 2, 80), (15, 21, 64), (33, 37, 49), (52, 40, 45), + (111, 87, 5), (134, 103, 15), (158, 120, 26), (177, 144, 55), + (205, 161, 70), (154, 189, 122), (99, 175, 144), (53, 153, 143), + (16, 135, 116), (27, 27, 58), (30, 32, 53), (33, 37, 49), + (33, 37, 49), (52, 46, 42), (70, 61, 28), (82, 64, 24), + (105, 91, 1), (105, 91, 1), (105, 91, 1), (88, 76, 12), + (88, 67, 22), (58, 49, 40), (40, 40, 47), (33, 30, 56), + (27, 27, 58), (9, 18, 66), (9, 18, 66), (9, 18, 66), + (2, 5, 77), (2, 5, 78), (8, 2, 80), (8, 2, 80), + (14, 0, 83), (14, 0, 83), (14, 0, 83), (14, 0, 83), + (14, 0, 83), (15, 21, 64), (33, 37, 49), (52, 46, 42), + (70, 61, 27), (111, 87, 5), (143, 107, 13), (163, 122, 27), + (194, 104, 19), (222, 100, 22), (242, 119, 35), (249, 151, 58), + (248, 156, 66), (253, 165, 74), (249, 151, 61), (247, 143, 55), + (206, 123, 35), (163, 125, 28), (116, 90, 3), (88, 76, 12), + (70, 61, 28), (65, 18, 22), (15, 21, 64), (8, 2, 80), + (8, 2, 80), (8, 2, 80), (8, 2, 80), (2, 5, 78), + (2, 5, 78), (8, 2, 80), (8, 2, 80), (8, 2, 80), + (8, 2, 80), (8, 2, 80), (8, 2, 80), (8, 2, 80), + (14, 0, 83), (14, 0, 84), (39, 17, 99), (39, 17, 99), + (33, 14, 97), (14, 0, 83), (14, 0, 83), (14, 0, 83), + (14, 0, 83), (14, 0, 83), (8, 2, 80), (8, 2, 80), + (14, 0, 83), (14, 0, 83), (8, 2, 80), (14, 0, 83), + (14, 0, 84), (33, 14, 97), (39, 17, 99), (39, 17, 99), + (39, 17, 99), (39, 17, 99), (33, 0, 70), (27, 27, 59), + (40, 40, 47), (58, 49, 40), (70, 61, 27), (88, 67, 22), + (111, 87, 5), (153, 118, 25), (209, 106, 23), (247, 41, 24) + ), + +// 147 Apophysis-040426-163KaosScepter +((230, 130, 36), (217, 93, 41), (196, 96, 29), (175, 100, 17), + (162, 94, 34), (150, 88, 51), (127, 77, 47), (105, 67, 44), + (105, 67, 44), (105, 67, 43), (105, 68, 42), (138, 84, 30), + (172, 100, 18), (188, 108, 23), (205, 117, 28), (217, 123, 31), + (229, 129, 35), (230, 130, 36), (240, 120, 38), (251, 110, 41), + (250, 109, 36), (250, 108, 32), (251, 109, 35), (253, 111, 39), + (246, 136, 39), (242, 134, 47), (239, 133, 55), (237, 117, 118), + (235, 102, 181), (235, 102, 182), (235, 102, 183), (211, 91, 180), + (139, 82, 99), (57, 46, 44), (32, 33, 33), (7, 21, 22), + (4, 16, 20), (1, 12, 18), (2, 12, 17), (3, 12, 17), + (10, 7, 16), (24, 20, 10), (39, 34, 4), (48, 24, 14), + (57, 14, 24), (58, 13, 23), (59, 13, 23), (53, 11, 12), + (42, 7, 14), (57, 14, 24), (58, 29, 31), (59, 44, 39), + (98, 63, 69), (137, 83, 99), (157, 92, 117), (177, 102, 135), + (234, 129, 188), (235, 131, 122), (236, 133, 56), (226, 113, 49), + (217, 93, 42), (201, 86, 41), (186, 80, 40), (172, 100, 18), + (148, 88, 52), (105, 67, 44), (105, 67, 44), (105, 67, 44), + (105, 67, 44), (105, 67, 44), (105, 67, 44), (105, 67, 44), + (105, 67, 46), (104, 52, 40), (103, 38, 34), (125, 62, 42), + (147, 87, 50), (148, 87, 50), (150, 88, 51), (187, 107, 54), + (178, 103, 136), (235, 132, 205), (242, 135, 208), (249, 139, 212), + (242, 135, 208), (235, 132, 205), (235, 132, 205), (249, 139, 212), + (255, 112, 204), (233, 102, 192), (212, 92, 181), (195, 83, 154), + (179, 75, 128), (142, 54, 96), (93, 61, 62), (51, 90, 37), + (55, 110, 26), (54, 152, 15), (112, 127, 17), (170, 102, 19), + (187, 109, 23), (205, 117, 28), (217, 93, 42), (186, 78, 42), + (148, 88, 51), (126, 77, 47), (105, 67, 44), (127, 77, 48), + (150, 87, 52), (172, 100, 18), (173, 101, 19), (205, 115, 27), + (205, 117, 28), (216, 123, 56), (183, 141, 97), (150, 159, 138), + (230, 225, 187), (238, 241, 196), (252, 252, 202), (252, 251, 203), + (247, 138, 203), (194, 96, 164), (141, 55, 126), (119, 44, 92), + (97, 33, 59), (53, 40, 68), (58, 44, 41), (59, 44, 39), + (46, 37, 22), (61, 44, 37), (83, 55, 40), (105, 67, 44), + (133, 80, 10), (169, 101, 18), (174, 98, 20), (150, 88, 51), + (105, 38, 30), (98, 34, 18), (92, 30, 7), (75, 37, 23), + (59, 44, 39), (53, 68, 45), (52, 91, 36), (105, 67, 44), + (150, 88, 51), (229, 129, 33), (229, 129, 34), (230, 130, 36), + (230, 130, 36), (246, 138, 40), (230, 130, 36), (230, 130, 36), + (211, 90, 157), (212, 105, 173), (213, 120, 190), (235, 132, 205), + (235, 132, 205), (211, 122, 190), (177, 102, 135), (187, 107, 54), + (205, 117, 28), (230, 130, 36), (230, 130, 36), (230, 130, 36), + (247, 137, 42), (247, 138, 47), (250, 138, 52), (251, 139, 53), + (251, 139, 53), (252, 140, 51), (254, 141, 49), (247, 137, 42), + (230, 130, 34), (205, 117, 28), (172, 100, 18), (136, 53, 3), + (136, 53, 1), (88, 57, 0), (53, 36, 18), (53, 36, 20), + (58, 15, 25), (50, 11, 56), (50, 11, 56), (12, 19, 35), + (0, 14, 21), (0, 14, 19), (0, 14, 17), (1, 12, 16), + (3, 12, 17), (12, 18, 30), (37, 28, 59), (39, 28, 62), + (52, 39, 67), (52, 45, 52), (59, 44, 39), (45, 38, 22), + (40, 35, 5), (40, 34, 8), (46, 37, 22), (59, 44, 39), + (95, 61, 62), (144, 86, 137), (211, 120, 190), (235, 132, 205), + (249, 139, 212), (250, 140, 213), (249, 139, 212), (249, 139, 212), + (249, 139, 212), (251, 139, 213), (253, 142, 211), (253, 142, 211), + (255, 141, 211), (253, 142, 211), (251, 138, 204), (249, 110, 193), + (235, 102, 181), (236, 133, 56), (239, 133, 55), (247, 137, 42), + (230, 130, 36), (205, 117, 28), (172, 100, 18), (134, 80, 6), + (89, 58, 3), (59, 44, 39), (51, 41, 68), (101, 63, 104), + (180, 77, 160), (212, 92, 181), (213, 120, 190), (235, 132, 205), + (255, 112, 207), (255, 111, 206), (255, 112, 204), (250, 109, 203), + (236, 103, 196), (211, 91, 180), (179, 76, 131), (137, 83, 99), + (95, 61, 62), (53, 68, 45), (45, 38, 22), (39, 35, 6), + (9, 9, 17), (11, 8, 17), (50, 9, 3), (91, 29, 6), + (89, 58, 1), (88, 58, 0), (87, 58, 0), (52, 37, 18), + (48, 36, 20), (39, 34, 5), (39, 35, 6), (58, 70, 6) + ), + +// 148 Apophysis-040426-163KSphere +((182, 186, 140), (128, 187, 78), (90, 167, 83), (53, 148, 89), + (56, 121, 89), (59, 95, 89), (71, 96, 89), (83, 97, 90), + (149, 95, 87), (124, 83, 77), (100, 71, 67), (91, 69, 55), + (83, 68, 44), (83, 66, 28), (83, 65, 13), (91, 63, 11), + (100, 61, 9), (83, 59, 11), (55, 42, 21), (28, 25, 32), + (28, 23, 24), (28, 22, 17), (28, 28, 9), (28, 34, 1), + (10, 37, 0), (19, 35, 3), (28, 34, 7), (28, 39, 23), + (28, 44, 39), (28, 44, 39), (28, 44, 39), (34, 53, 25), + (10, 61, 30), (10, 66, 38), (10, 60, 27), (10, 55, 16), + (10, 52, 15), (10, 49, 14), (22, 52, 19), (34, 56, 24), + (34, 122, 29), (43, 126, 21), (53, 131, 13), (68, 115, 9), + (83, 100, 6), (91, 94, 19), (100, 89, 33), (128, 78, 62), + (149, 101, 101), (164, 206, 162), (173, 201, 159), (182, 197, 156), + (190, 181, 123), (198, 166, 90), (198, 166, 90), (198, 166, 90), + (198, 160, 89), (149, 141, 81), (100, 122, 74), (76, 110, 71), + (53, 98, 69), (56, 91, 68), (59, 85, 67), (83, 97, 90), + (83, 103, 92), (100, 106, 56), (103, 85, 44), (106, 64, 32), + (94, 66, 41), (83, 68, 50), (83, 68, 44), (77, 83, 29), + (128, 117, 25), (148, 149, 30), (168, 181, 35), (168, 177, 36), + (168, 173, 38), (168, 166, 42), (168, 159, 47), (149, 138, 34), + (128, 111, 28), (123, 72, 6), (114, 65, 18), (106, 58, 30), + (106, 61, 31), (106, 64, 32), (128, 87, 47), (149, 85, 66), + (168, 114, 69), (168, 128, 60), (168, 143, 51), (183, 147, 42), + (198, 152, 33), (182, 120, 17), (182, 111, 32), (198, 104, 25), + (198, 113, 34), (225, 142, 37), (211, 148, 56), (198, 155, 76), + (190, 148, 71), (182, 141, 66), (168, 126, 62), (164, 108, 34), + (123, 69, 3), (103, 79, 2), (83, 89, 2), (91, 111, 1), + (100, 134, 1), (77, 139, 3), (77, 108, 21), (77, 105, 61), + (83, 97, 84), (83, 91, 77), (71, 91, 78), (59, 91, 80), + (59, 85, 73), (83, 74, 69), (59, 56, 26), (59, 56, 26), + (59, 34, 1), (71, 46, 6), (83, 59, 11), (71, 57, 18), + (59, 56, 26), (53, 71, 29), (53, 76, 31), (53, 71, 23), + (53, 71, 29), (34, 104, 69), (34, 101, 77), (34, 99, 86), + (34, 94, 84), (28, 86, 57), (10, 82, 61), (10, 82, 61), + (34, 67, 40), (58, 58, 30), (83, 49, 20), (94, 53, 28), + (106, 58, 36), (128, 72, 60), (149, 101, 95), (149, 107, 109), + (106, 124, 160), (53, 129, 115), (43, 118, 109), (34, 108, 104), + (10, 96, 87), (10, 93, 49), (10, 98, 46), (34, 81, 38), + (59, 80, 59), (59, 82, 63), (59, 85, 67), (53, 93, 55), + (34, 73, 54), (34, 64, 34), (59, 65, 13), (83, 71, 5), + (106, 106, 9), (128, 191, 52), (138, 194, 45), (149, 197, 38), + (164, 196, 81), (168, 210, 77), (225, 201, 71), (225, 163, 77), + (225, 190, 107), (225, 204, 133), (225, 219, 160), (225, 239, 218), + (213, 197, 219), (213, 222, 185), (182, 212, 116), (213, 203, 85), + (213, 199, 83), (213, 168, 85), (225, 145, 54), (168, 131, 58), + (164, 120, 53), (182, 105, 30), (164, 96, 21), (123, 82, 21), + (123, 78, 0), (114, 86, 7), (106, 94, 15), (128, 99, 34), + (149, 104, 54), (164, 126, 60), (144, 128, 66), (168, 111, 117), + (168, 98, 95), (149, 79, 64), (144, 98, 34), (123, 75, 14), + (100, 55, 7), (77, 49, 12), (53, 53, 5), (53, 59, 13), + (28, 70, 33), (34, 73, 54), (34, 89, 77), (59, 101, 89), + (83, 127, 120), (100, 156, 148), (144, 198, 192), (198, 181, 208), + (168, 187, 185), (149, 165, 138), (100, 177, 78), (77, 110, 69), + (83, 74, 52), (106, 67, 45), (128, 72, 54), (182, 28, 67), + (168, 25, 128), (164, 70, 112), (164, 77, 120), (106, 103, 100), + (83, 118, 130), (59, 73, 123), (34, 67, 97), (10, 77, 53), + (10, 34, 40), (10, 16, 36), (10, 16, 36), (28, 28, 15), + (34, 25, 8), (34, 37, 0), (53, 40, 8), (59, 34, 1), + (59, 44, 10), (53, 53, 5), (28, 47, 1), (34, 66, 16), + (28, 70, 33), (28, 75, 41), (28, 103, 38), (34, 104, 69), + (34, 94, 84), (34, 89, 96), (34, 94, 79), (34, 89, 72), + (53, 88, 53), (53, 101, 31), (77, 83, 29), (106, 70, 28), + (106, 76, 31), (128, 99, 34), (128, 111, 28), (149, 127, 40), + (149, 104, 54), (144, 139, 75), (144, 154, 99), (213, 227, 144) + ), + +// 149 Apophysis-040426-163KInterseed +((5, 5, 5), (2, 2, 2), (1, 1, 1), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 1, 1), (1, 1, 1), (2, 2, 2), (2, 2, 2), + (3, 3, 3), (4, 4, 4), (6, 6, 6), (6, 6, 6), + (7, 7, 7), (8, 8, 8), (7, 7, 7), (6, 6, 6), + (4, 4, 4), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (4, 4, 4), (5, 5, 5), (7, 7, 7), + (7, 7, 7), (8, 8, 8), (8, 8, 8), (8, 8, 8), + (6, 6, 6), (4, 4, 4), (3, 3, 3), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (1, 1, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (1, 1, 1), + (2, 2, 2), (4, 4, 4), (5, 5, 5), (7, 7, 7), + (37, 5, 16), (108, 49, 53), (180, 93, 91), (217, 168, 84), + (255, 244, 78), (255, 249, 76), (255, 255, 75), (255, 255, 83), + (255, 255, 91), (226, 225, 89), (143, 240, 64), (61, 255, 39), + (121, 215, 60), (181, 176, 82), (244, 227, 95), (163, 145, 83), + (67, 53, 23), (37, 30, 15), (7, 7, 7), (4, 4, 4), + (2, 2, 2), (1, 1, 1), (1, 1, 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), (1, 1, 1), + (4, 4, 4), (6, 6, 6), (9, 9, 9), (10, 10, 10), + (11, 11, 11), (48, 48, 31), (116, 102, 59), (115, 185, 136), + (255, 255, 180), (213, 204, 67), (119, 188, 42), (25, 172, 17), + (24, 141, 44), (24, 110, 71), (39, 47, 42), (11, 11, 11), + (4, 4, 4), (2, 2, 2), (1, 1, 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), (1, 1, 1), (2, 2, 2), (6, 6, 6), + (11, 11, 11), (163, 7, 156), (172, 79, 147), (181, 151, 138), + (151, 166, 162), (183, 255, 255), (255, 242, 252), (255, 255, 187), + (246, 239, 81), (183, 154, 60), (120, 70, 39), (86, 57, 25), + (52, 44, 12), (10, 10, 10), (6, 6, 6), (3, 3, 3), + (1, 1, 1), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (2, 2, 2), (3, 3, 3), (5, 5, 5), + (6, 16, 0), (9, 68, 5), (12, 121, 10), (21, 172, 17), + (55, 252, 32), (28, 180, 24), (20, 149, 13), (22, 77, 33), + (3, 20, 9), (3, 3, 3), (2, 2, 2), (2, 2, 2), + (1, 1, 1), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (1, 1, 1), + (2, 2, 2), (5, 5, 5), (8, 8, 8), (9, 9, 9), + (17, 10, 35), (41, 76, 70), (66, 114, 81), (18, 135, 104), + (1, 75, 58), (18, 9, 30), (9, 9, 9), (7, 7, 7), + (4, 4, 4), (2, 2, 2), (1, 1, 1), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (1, 1, 1), (2, 2, 2) + ), + +// 150 Apophysis-040426-163XmasFlwers +((220, 253, 46), (254, 142, 34), (253, 97, 17), (252, 53, 0), + (253, 37, 8), (255, 21, 17), (253, 10, 34), (252, 0, 52), + (240, 0, 54), (243, 0, 44), (246, 0, 34), (209, 0, 21), + (172, 0, 9), (113, 18, 23), (55, 36, 38), (66, 41, 44), + (77, 46, 51), (31, 79, 79), (43, 89, 54), (55, 100, 30), + (52, 93, 15), (49, 86, 0), (51, 88, 1), (54, 90, 3), + (78, 64, 38), (109, 62, 27), (140, 61, 17), (180, 49, 8), + (221, 38, 0), (238, 22, 7), (255, 6, 14), (255, 0, 11), + (240, 0, 22), (172, 0, 9), (125, 21, 4), (79, 43, 0), + (79, 62, 2), (79, 81, 5), (79, 78, 9), (80, 76, 13), + (78, 31, 51), (79, 15, 42), (81, 0, 34), (81, 25, 17), + (82, 51, 1), (65, 59, 4), (49, 67, 7), (40, 70, 5), + (0, 88, 19), (68, 160, 16), (52, 165, 31), (37, 171, 47), + (51, 159, 103), (65, 148, 159), (65, 149, 148), (65, 151, 138), + (70, 82, 70), (63, 89, 48), (56, 97, 27), (59, 88, 20), + (63, 80, 13), (72, 66, 11), (81, 52, 10), (80, 13, 15), + (75, 0, 16), (172, 0, 9), (195, 21, 46), (218, 42, 83), + (221, 53, 90), (225, 65, 97), (237, 76, 104), (255, 17, 79), + (239, 0, 57), (211, 0, 69), (183, 0, 82), (148, 15, 73), + (114, 31, 64), (95, 38, 57), (77, 46, 51), (70, 76, 55), + (69, 81, 61), (78, 64, 38), (79, 66, 23), (81, 69, 9), + (95, 67, 11), (110, 66, 13), (171, 66, 0), (171, 66, 0), + (172, 0, 9), (172, 0, 9), (172, 0, 9), (175, 0, 12), + (178, 0, 15), (172, 0, 9), (146, 54, 11), (78, 64, 38), + (78, 67, 37), (56, 97, 27), (40, 129, 13), (24, 161, 0), + (27, 151, 0), (31, 142, 0), (47, 110, 11), (56, 94, 22), + (78, 64, 38), (78, 64, 38), (78, 64, 38), (78, 64, 38), + (78, 64, 38), (78, 64, 38), (65, 79, 43), (56, 96, 29), + (56, 94, 22), (63, 79, 0), (72, 69, 5), (81, 59, 10), + (82, 38, 0), (171, 0, 5), (171, 0, 5), (81, 0, 26), + (81, 0, 34), (115, 29, 17), (149, 58, 0), (167, 50, 0), + (186, 43, 0), (207, 0, 34), (228, 0, 47), (224, 26, 0), + (220, 28, 0), (171, 66, 0), (138, 62, 15), (106, 59, 30), + (75, 72, 60), (45, 56, 81), (0, 55, 78), (2, 77, 79), + (2, 61, 108), (50, 44, 103), (98, 28, 99), (94, 44, 115), + (90, 60, 132), (132, 147, 184), (188, 185, 194), (206, 255, 98), + (224, 243, 95), (228, 255, 58), (221, 250, 58), (214, 246, 58), + (210, 247, 46), (203, 241, 43), (185, 228, 42), (149, 200, 36), + (68, 159, 19), (61, 130, 26), (55, 101, 34), (55, 99, 31), + (55, 99, 31), (68, 104, 76), (87, 150, 95), (91, 160, 72), + (111, 167, 86), (210, 216, 151), (221, 221, 161), (233, 226, 172), + (210, 235, 195), (243, 228, 185), (245, 224, 204), (240, 208, 218), + (177, 176, 198), (167, 169, 195), (157, 163, 192), (122, 141, 179), + (64, 141, 168), (64, 135, 161), (29, 121, 118), (16, 117, 112), + (3, 94, 110), (4, 76, 90), (38, 82, 103), (60, 57, 78), + (68, 79, 55), (83, 78, 41), (140, 61, 18), (171, 66, 0), + (231, 72, 0), (243, 75, 8), (255, 79, 16), (255, 106, 122), + (195, 140, 141), (208, 214, 149), (202, 193, 199), (168, 174, 182), + (104, 121, 129), (73, 75, 73), (75, 74, 66), (75, 69, 59), + (69, 80, 59), (101, 162, 91), (164, 193, 101), (183, 226, 41), + (172, 218, 40), (148, 170, 35), (186, 90, 2), (178, 60, 4), + (166, 24, 41), (103, 0, 97), (66, 69, 142), (64, 134, 163), + (64, 143, 167), (64, 135, 163), (67, 115, 134), (73, 81, 84), + (83, 54, 82), (91, 41, 91), (86, 49, 86), (82, 101, 117), + (67, 135, 132), (67, 137, 138), (68, 125, 116), (72, 86, 85), + (106, 63, 53), (164, 61, 0), (213, 64, 0), (246, 33, 0), + (255, 21, 17), (255, 22, 15), (241, 47, 0), (226, 52, 0), + (209, 64, 0), (171, 66, 0), (112, 59, 25), (88, 50, 46), + (55, 61, 66), (43, 64, 54), (2, 81, 48), (0, 120, 0), + (22, 168, 11), (23, 169, 14), (52, 142, 0), (80, 81, 0), + (147, 60, 0), (171, 66, 0), (184, 80, 0), (155, 163, 25), + (143, 199, 35), (132, 176, 97), (133, 176, 100), (79, 141, 138), + (84, 138, 144), (73, 138, 141), (67, 124, 139), (66, 73, 142), + (99, 25, 100), (139, 17, 57), (194, 0, 36), (172, 0, 9) + ), + +// 151 Apophysis-040426-163Shield +((127, 116, 1), (127, 116, 2), (132, 118, 5), (138, 121, 8), + (161, 119, 15), (184, 118, 22), (211, 95, 22), (239, 72, 22), + (240, 67, 21), (236, 68, 20), (233, 69, 19), (185, 95, 12), + (138, 121, 5), (132, 118, 3), (127, 116, 1), (121, 116, 0), + (116, 116, 0), (116, 116, 0), (116, 110, 3), (116, 105, 6), + (116, 105, 6), (116, 105, 6), (116, 110, 3), (116, 116, 0), + (116, 116, 0), (121, 110, 1), (127, 104, 3), (116, 104, 5), + (105, 105, 8), (99, 105, 9), (93, 105, 10), (93, 93, 17), + (82, 93, 20), (82, 82, 29), (87, 81, 26), (93, 81, 23), + (110, 92, 13), (127, 104, 3), (127, 107, 1), (127, 110, 0), + (138, 115, 3), (138, 115, 3), (138, 115, 3), (138, 115, 3), + (138, 115, 3), (132, 115, 2), (127, 116, 1), (127, 116, 1), + (127, 116, 1), (127, 116, 1), (121, 116, 0), (116, 116, 0), + (116, 116, 0), (116, 116, 0), (116, 116, 0), (116, 116, 0), + (116, 116, 0), (116, 118, 1), (116, 121, 2), (121, 118, 1), + (127, 116, 1), (127, 116, 1), (127, 116, 1), (127, 116, 1), + (127, 116, 1), (127, 116, 1), (127, 113, 0), (127, 110, 0), + (121, 107, 3), (116, 105, 6), (105, 93, 2), (82, 70, 31), + (21, 51, 56), (11, 57, 54), (2, 64, 52), (30, 61, 47), + (58, 58, 43), (72, 65, 36), (87, 72, 29), (93, 81, 69), + (82, 93, 65), (105, 93, 135), (63, 69, 101), (21, 46, 68), + (11, 48, 81), (2, 51, 95), (2, 51, 95), (93, 87, 143), + (250, 61, 178), (251, 70, 184), (253, 79, 190), (245, 81, 189), + (237, 83, 188), (216, 44, 161), (247, 70, 24), (247, 76, 26), + (219, 120, 28), (148, 132, 15), (148, 129, 13), (148, 126, 11), + (148, 126, 11), (148, 126, 11), (148, 126, 11), (148, 126, 11), + (148, 126, 11), (137, 123, 7), (127, 121, 4), (127, 121, 4), + (127, 121, 4), (127, 121, 4), (127, 121, 4), (127, 121, 4), + (127, 121, 6), (138, 132, 11), (138, 132, 12), (138, 132, 13), + (138, 132, 13), (127, 127, 10), (127, 127, 8), (127, 121, 6), + (116, 121, 2), (116, 118, 1), (116, 116, 0), (116, 116, 0), + (116, 116, 0), (105, 116, 1), (105, 116, 1), (116, 116, 0), + (116, 116, 0), (105, 116, 1), (105, 116, 1), (105, 116, 1), + (105, 116, 1), (105, 116, 1), (105, 116, 1), (105, 116, 1), + (127, 116, 1), (132, 115, 2), (138, 115, 3), (138, 115, 3), + (138, 115, 4), (138, 121, 6), (138, 127, 10), (148, 132, 13), + (148, 132, 13), (138, 132, 11), (138, 129, 10), (138, 127, 10), + (127, 127, 8), (127, 121, 4), (127, 121, 3), (127, 121, 3), + (138, 121, 5), (138, 121, 6), (138, 121, 8), (138, 127, 10), + (127, 132, 10), (127, 132, 10), (127, 127, 8), (127, 121, 6), + (138, 121, 5), (127, 127, 8), (127, 127, 9), (127, 127, 10), + (138, 127, 11), (148, 126, 11), (148, 126, 11), (148, 126, 11), + (148, 132, 15), (143, 132, 14), (138, 132, 13), (138, 127, 11), + (138, 127, 10), (138, 127, 10), (138, 121, 6), (138, 115, 4), + (138, 115, 3), (138, 115, 3), (127, 116, 1), (127, 116, 1), + (116, 116, 0), (116, 116, 0), (116, 116, 0), (116, 116, 0), + (116, 116, 0), (116, 116, 0), (116, 116, 0), (116, 116, 0), + (116, 116, 0), (116, 116, 0), (116, 116, 0), (105, 116, 1), + (105, 116, 1), (105, 105, 8), (105, 105, 8), (105, 105, 8), + (105, 110, 5), (105, 116, 1), (116, 116, 0), (127, 116, 1), + (127, 116, 1), (138, 115, 3), (138, 115, 3), (138, 115, 3), + (138, 115, 3), (138, 115, 4), (138, 121, 8), (148, 126, 11), + (148, 126, 11), (148, 126, 11), (148, 126, 11), (138, 121, 6), + (127, 116, 2), (127, 116, 1), (127, 116, 1), (127, 110, 0), + (116, 99, 9), (116, 93, 12), (93, 81, 23), (91, 17, 52), + (70, 17, 62), (93, 5, 109), (97, 1, 46), (151, 22, 21), + (170, 37, 10), (127, 104, 3), (138, 115, 3), (198, 45, 0), + (205, 49, 4), (196, 50, 1), (138, 115, 3), (138, 115, 3), + (127, 116, 1), (127, 116, 1), (127, 116, 1), (127, 116, 1), + (127, 116, 1), (127, 116, 1), (127, 116, 1), (127, 116, 1), + (138, 115, 3), (138, 115, 3), (138, 115, 3), (138, 115, 3), + (138, 115, 3), (138, 115, 4), (138, 121, 6), (148, 126, 11), + (148, 126, 11), (148, 126, 11), (148, 126, 11), (138, 121, 6), + (138, 115, 3), (127, 116, 2), (127, 116, 1), (127, 116, 1) + ), + +// 152 Apophysis-040426-163AlienFlwers +((136, 172, 220), (179, 252, 29), (201, 242, 31), (223, 233, 34), + (197, 227, 50), (172, 221, 67), (159, 215, 70), (147, 210, 74), + (42, 161, 55), (22, 139, 43), (3, 117, 31), (1, 186, 84), + (0, 255, 137), (34, 213, 126), (68, 172, 116), (95, 145, 120), + (123, 119, 124), (166, 111, 82), (180, 96, 65), (194, 81, 49), + (179, 52, 46), (164, 24, 44), (166, 39, 36), (168, 55, 28), + (224, 50, 14), (205, 28, 47), (186, 7, 81), (134, 34, 113), + (82, 61, 146), (68, 65, 158), (55, 70, 171), (33, 71, 194), + (29, 73, 201), (1, 106, 190), (0, 98, 191), (0, 91, 192), + (26, 92, 207), (53, 94, 222), (57, 131, 222), (62, 169, 223), + (127, 202, 227), (107, 190, 226), (87, 178, 226), (79, 116, 236), + (71, 55, 247), (57, 55, 239), (43, 56, 232), (26, 65, 203), + (23, 60, 197), (6, 52, 230), (12, 54, 215), (18, 56, 200), + (29, 72, 201), (41, 88, 203), (45, 110, 208), (50, 133, 214), + (164, 177, 151), (186, 187, 122), (208, 198, 93), (191, 218, 84), + (174, 238, 75), (168, 233, 73), (163, 229, 72), (135, 207, 72), + (149, 217, 72), (147, 206, 190), (73, 227, 222), (0, 249, 255), + (0, 252, 255), (0, 255, 255), (61, 232, 227), (118, 197, 196), + (255, 238, 115), (243, 238, 102), (231, 239, 90), (206, 192, 86), + (182, 146, 82), (176, 178, 67), (170, 210, 52), (153, 230, 32), + (129, 214, 47), (68, 182, 17), (46, 144, 10), (24, 107, 3), + (42, 96, 21), (60, 86, 39), (165, 103, 13), (224, 150, 39), + (255, 234, 0), (255, 244, 0), (255, 255, 0), (255, 255, 0), + (255, 255, 0), (255, 255, 0), (255, 255, 0), (237, 253, 0), + (211, 255, 4), (214, 253, 110), (197, 239, 180), (181, 225, 251), + (164, 204, 245), (148, 183, 240), (63, 132, 233), (47, 73, 226), + (9, 32, 198), (15, 22, 205), (22, 13, 213), (16, 12, 211), + (10, 11, 209), (12, 9, 205), (40, 7, 165), (58, 11, 148), + (95, 13, 117), (135, 75, 95), (192, 92, 109), (249, 110, 123), + (221, 163, 53), (255, 174, 7), (230, 236, 30), (227, 244, 90), + (160, 161, 127), (114, 124, 147), (69, 88, 168), (70, 82, 163), + (71, 76, 159), (56, 74, 172), (36, 74, 194), (34, 75, 196), + (35, 73, 197), (29, 78, 204), (30, 77, 203), (32, 76, 202), + (43, 91, 198), (19, 117, 191), (35, 160, 208), (76, 247, 147), + (141, 214, 77), (155, 222, 84), (170, 230, 91), (160, 210, 107), + (150, 191, 124), (63, 141, 188), (50, 96, 198), (62, 56, 153), + (62, 20, 146), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (55, 82, 77), (111, 109, 132), + (149, 27, 87), (185, 34, 96), (222, 42, 105), (217, 26, 179), + (118, 30, 222), (35, 35, 220), (19, 51, 197), (18, 49, 197), + (28, 28, 179), (69, 10, 136), (34, 5, 68), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (125, 51, 28), (241, 91, 123), + (235, 98, 138), (157, 174, 159), (156, 193, 210), (103, 186, 236), + (85, 134, 203), (60, 99, 192), (34, 79, 201), (22, 69, 205), + (28, 69, 198), (42, 71, 184), (56, 74, 171), (74, 65, 151), + (80, 55, 142), (85, 62, 140), (105, 50, 115), (91, 65, 131), + (67, 72, 161), (32, 44, 215), (34, 11, 249), (0, 0, 255), + (0, 0, 255), (0, 0, 255), (0, 0, 255), (0, 29, 206), + (16, 50, 200), (22, 57, 196), (33, 66, 189), (31, 99, 119), + (60, 85, 39), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 120, 97), (5, 107, 153), (4, 123, 177), (30, 102, 164), + (16, 101, 149), (3, 135, 104), (8, 141, 64), (42, 95, 16), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (59, 2, 147), + (34, 6, 168), (10, 32, 197), (12, 38, 198), (9, 32, 198), + (0, 14, 204), (1, 12, 201), (7, 29, 198), (15, 43, 197), + (25, 60, 196), (17, 81, 185), (26, 97, 132), (31, 125, 72), + (51, 140, 81), (40, 114, 101), (105, 103, 143), (145, 132, 115), + (160, 152, 102), (210, 191, 102), (251, 200, 129), (255, 255, 134), + (253, 240, 216), (255, 245, 223), (228, 247, 224), (184, 230, 234), + (227, 230, 213), (213, 201, 129), (161, 130, 98), (49, 89, 25), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (50, 89, 78), (89, 97, 148), (158, 226, 255) + ), + +// 153 Apophysis-040426-163AlienFlwers4 +((193, 142, 29), (114, 18, 230), (113, 49, 217), (113, 80, 204), + (155, 86, 164), (198, 92, 125), (195, 87, 120), (192, 83, 116), + (196, 142, 48), (219, 159, 59), (243, 177, 70), (225, 204, 122), + (208, 232, 174), (165, 243, 160), (123, 254, 147), (126, 228, 136), + (129, 203, 126), (71, 214, 153), (60, 218, 178), (49, 223, 203), + (86, 239, 197), (124, 255, 192), (136, 244, 193), (149, 234, 195), + (161, 255, 59), (139, 221, 82), (118, 188, 105), (127, 161, 117), + (137, 134, 130), (175, 141, 155), (214, 148, 180), (241, 139, 182), + (255, 141, 148), (255, 131, 88), (226, 140, 53), (197, 149, 19), + (154, 162, 23), (111, 175, 28), (97, 144, 36), (83, 113, 44), + (28, 116, 15), (24, 161, 33), (20, 206, 51), (46, 188, 43), + (72, 170, 36), (94, 177, 26), (116, 184, 17), (184, 149, 2), + (199, 126, 1), (196, 136, 24), (158, 153, 50), (120, 170, 77), + (99, 159, 86), (78, 148, 96), (80, 130, 98), (83, 113, 100), + (168, 36, 79), (206, 26, 89), (244, 17, 100), (239, 50, 86), + (234, 84, 73), (204, 99, 63), (175, 115, 53), (150, 91, 40), + (130, 140, 78), (81, 175, 82), (83, 178, 51), (85, 181, 20), + (92, 179, 17), (99, 178, 15), (128, 195, 13), (155, 195, 67), + (232, 202, 205), (224, 183, 220), (216, 165, 235), (230, 151, 236), + (245, 138, 237), (248, 139, 234), (251, 141, 231), (242, 144, 209), + (220, 133, 211), (210, 54, 133), (214, 64, 137), (218, 74, 141), + (222, 90, 153), (226, 106, 165), (222, 149, 205), (204, 152, 231), + (208, 187, 179), (200, 157, 122), (193, 127, 66), (172, 134, 66), + (152, 141, 66), (129, 132, 103), (128, 100, 141), (147, 88, 208), + (199, 92, 222), (201, 81, 218), (146, 43, 157), (92, 5, 97), + (46, 2, 48), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (34, 61, 43), (68, 122, 86), (87, 113, 95), + (106, 104, 105), (115, 43, 108), (158, 18, 126), (213, 34, 167), + (255, 32, 196), (205, 118, 210), (204, 120, 218), (203, 122, 226), + (186, 152, 217), (179, 165, 193), (198, 194, 180), (152, 191, 179), + (123, 182, 135), (114, 139, 162), (106, 96, 190), (89, 85, 212), + (73, 75, 234), (77, 27, 250), (90, 39, 238), (152, 62, 249), + (201, 126, 255), (192, 125, 255), (161, 122, 253), (131, 119, 252), + (134, 71, 229), (136, 56, 240), (141, 76, 234), (174, 108, 223), + (228, 128, 208), (226, 109, 178), (225, 91, 148), (220, 55, 135), + (216, 20, 123), (224, 0, 113), (252, 17, 101), (243, 11, 93), + (222, 0, 87), (149, 28, 73), (74, 14, 36), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (13, 71, 121), (46, 83, 136), (79, 96, 151), (119, 108, 209), + (199, 128, 226), (214, 130, 252), (216, 133, 240), (194, 152, 224), + (191, 152, 191), (136, 74, 40), (159, 75, 34), (182, 76, 28), + (243, 95, 4), (231, 108, 2), (236, 134, 57), (234, 141, 100), + (149, 121, 235), (118, 99, 227), (88, 78, 219), (49, 6, 251), + (31, 32, 235), (7, 57, 234), (78, 154, 208), (62, 194, 207), + (81, 166, 154), (45, 142, 156), (7, 205, 160), (20, 152, 183), + (45, 131, 225), (3, 23, 194), (20, 3, 160), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 54, 146), + (15, 82, 169), (40, 144, 169), (48, 193, 133), (94, 176, 130), + (91, 179, 93), (117, 182, 97), (205, 149, 49), (246, 149, 67), + (211, 183, 125), (242, 193, 159), (226, 156, 164), (233, 115, 172), + (224, 121, 195), (208, 118, 202), (203, 73, 167), (209, 75, 144), + (202, 47, 136), (212, 36, 127), (200, 50, 139), (184, 32, 152), + (153, 8, 170), (99, 23, 163), (54, 13, 215), (47, 23, 239), + (77, 26, 182), (101, 59, 152), (107, 49, 118), (54, 88, 121), + (55, 92, 88), (76, 121, 103), (121, 94, 169), (139, 75, 203), + (172, 33, 212), (175, 22, 221), (175, 34, 247), (193, 87, 231), + (193, 122, 255), (218, 149, 253), (222, 151, 253), (225, 154, 251), + (232, 150, 250), (233, 159, 247), (229, 166, 249), (240, 171, 252), + (244, 227, 199), (237, 245, 152), (243, 236, 115), (250, 206, 91), + (253, 194, 39), (253, 169, 69), (242, 212, 114), (225, 238, 149), + (237, 245, 152), (235, 246, 152), (221, 253, 170), (213, 235, 208), + (224, 222, 223), (233, 205, 244), (236, 209, 202), (227, 243, 154), + (223, 246, 140), (181, 231, 50), (181, 212, 34), (189, 203, 15) + ), + +// 154 Apophysis-040426-163butterflyflwer1 +((158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 140, 238), (158, 141, 238), (158, 142, 238), + (161, 145, 241), (162, 148, 242), (163, 152, 243), (161, 149, 241), + (159, 146, 239), (159, 145, 239), (160, 144, 240), (159, 143, 239), + (159, 143, 239), (159, 142, 239), (159, 141, 239), (159, 141, 239), + (159, 141, 239), (159, 141, 239), (158, 140, 238), (158, 140, 238), + (158, 140, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (160, 120, 240), (163, 101, 243), (157, 82, 237), + (157, 45, 237), (181, 86, 250), (170, 114, 245), (160, 142, 240), + (159, 141, 239), (158, 140, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 140, 238), + (81, 140, 161), (58, 146, 102), (36, 152, 43), (49, 172, 29), + (63, 193, 16), (63, 198, 15), (64, 204, 15), (112, 244, 32), + (157, 180, 237), (159, 147, 239), (158, 144, 238), (158, 141, 238), + (158, 140, 238), (158, 140, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 140, 238), (159, 142, 239), + (161, 145, 241), (171, 161, 251), (178, 178, 248), (185, 195, 246), + (189, 209, 241), (194, 223, 237), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (206, 216, 225), (191, 188, 240), (165, 157, 245), + (158, 139, 238), (158, 6, 238), (158, 32, 238), (158, 58, 238), + (158, 98, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 140, 238), (158, 141, 238), (159, 142, 239), (160, 145, 240), + (168, 155, 248), (176, 171, 247), (185, 188, 246), (191, 195, 239), + (198, 203, 233), (221, 234, 210), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (191, 225, 240), (180, 210, 245), (170, 196, 250), + (161, 166, 241), (158, 151, 238), (159, 151, 239), (161, 158, 241), + (162, 178, 242), (166, 194, 246), (171, 210, 251), (176, 207, 250), + (182, 205, 249), (182, 200, 249), (175, 202, 255), (166, 187, 246), + (162, 166, 242), (159, 147, 239), (158, 145, 238), (158, 143, 238), + (158, 141, 238), (158, 140, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 141, 238), (158, 142, 238), (159, 144, 239), (159, 148, 239), + (161, 158, 241), (158, 187, 238), (158, 207, 238), (158, 219, 238), + (175, 205, 255), (180, 199, 251), (181, 181, 250), (166, 159, 246), + (160, 144, 240), (158, 122, 238), (121, 71, 201), (86, 32, 166), + (35, 28, 115), (36, 47, 116), (37, 67, 117), (106, 84, 186), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (103, 92, 183), (54, 87, 134), + (32, 49, 112), (37, 41, 117), (97, 71, 177), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 140, 238), (159, 142, 239), + (160, 145, 240), (160, 147, 240), (163, 153, 243), (165, 169, 245), + (174, 197, 254), (180, 208, 251), (186, 237, 245), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (199, 223, 232), (188, 191, 243), + (177, 168, 254), (171, 159, 251), (167, 152, 247), (167, 153, 247), + (171, 172, 251), (179, 191, 252), (180, 198, 251), (183, 195, 248), + (177, 185, 254), (170, 162, 250), (165, 153, 245), (162, 145, 242), + (159, 142, 239), (158, 140, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238), + (158, 139, 238), (158, 139, 238), (158, 139, 238), (158, 139, 238) + ), + +// 155 Apophysis-040426-163ButterflySherbert +((219, 120, 43), (252, 198, 141), (252, 180, 107), (253, 162, 74), + (252, 151, 59), (252, 140, 45), (235, 135, 43), (219, 130, 42), + (185, 113, 35), (112, 79, 26), (40, 46, 17), (20, 23, 8), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (84, 47, 19), (168, 95, 39), + (186, 101, 43), (205, 107, 47), (207, 109, 51), (209, 112, 56), + (205, 110, 45), (210, 113, 46), (216, 116, 47), (217, 119, 55), + (219, 123, 63), (215, 120, 62), (212, 117, 61), (198, 119, 39), + (168, 104, 32), (71, 24, 4), (35, 12, 2), (0, 0, 0), + (32, 72, 17), (65, 144, 35), (109, 157, 48), (154, 170, 62), + (225, 130, 69), (239, 133, 61), (253, 137, 54), (252, 137, 49), + (252, 137, 44), (251, 133, 43), (250, 130, 43), (230, 123, 47), + (201, 115, 41), (94, 88, 6), (47, 44, 3), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (29, 8, 7), (58, 17, 15), (115, 55, 34), + (172, 94, 53), (178, 102, 60), (185, 110, 68), (190, 121, 85), + (181, 117, 89), (100, 176, 154), (114, 182, 143), (128, 189, 133), + (141, 194, 137), (154, 199, 141), (117, 183, 128), (94, 173, 113), + (106, 159, 50), (127, 156, 33), (148, 153, 16), (173, 142, 21), + (198, 132, 26), (194, 123, 31), (190, 115, 36), (172, 119, 27), + (112, 138, 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), + (52, 28, 22), (105, 57, 44), (168, 95, 39), (177, 102, 39), + (94, 70, 23), (47, 35, 11), (0, 0, 0), (29, 10, 8), + (58, 20, 16), (138, 107, 16), (185, 116, 33), (209, 128, 39), + (212, 129, 40), (225, 120, 56), (222, 123, 61), (219, 127, 66), + (212, 136, 89), (228, 196, 106), (238, 210, 136), (252, 212, 156), + (253, 211, 156), (246, 190, 136), (240, 170, 117), (238, 156, 95), + (237, 142, 74), (237, 133, 63), (249, 136, 48), (252, 131, 49), + (242, 126, 51), (222, 116, 52), (222, 119, 48), (222, 122, 45), + (219, 120, 45), (219, 117, 46), (216, 113, 48), (216, 113, 48), + (205, 107, 47), (171, 93, 53), (138, 80, 60), (85, 58, 41), + (33, 37, 22), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (40, 9, 92), (96, 51, 81), (153, 94, 70), + (205, 110, 55), (206, 153, 44), (225, 184, 57), (245, 204, 127), + (253, 233, 208), (253, 237, 218), (253, 241, 228), (249, 249, 226), + (216, 234, 217), (173, 212, 184), (117, 181, 177), (53, 123, 138), + (27, 34, 75), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (9, 52, 12), (94, 146, 30), + (173, 163, 108), (196, 158, 109), (219, 154, 111), (253, 193, 124), + (253, 204, 143), (253, 208, 157), (243, 199, 169), (225, 187, 172), + (177, 160, 175), (77, 125, 150), (64, 46, 67), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (106, 1, 39), (134, 43, 45), (163, 86, 51), (205, 107, 50), + (219, 114, 47), (230, 123, 47), (230, 126, 47), (237, 123, 48), + (237, 127, 55), (237, 133, 62), (240, 137, 67), (253, 147, 61), + (252, 149, 58), (253, 150, 63), (253, 156, 71), (253, 162, 77), + (242, 193, 104), (249, 202, 125), (244, 206, 129), (253, 199, 137), + (245, 209, 138), (253, 249, 142), (233, 218, 154), (253, 213, 169), + (253, 209, 155), (253, 193, 122), (243, 157, 91), (237, 139, 70), + (233, 130, 62), (222, 125, 63), (219, 120, 59), (219, 123, 63), + (222, 128, 68), (222, 143, 93), (228, 152, 102), (247, 193, 148), + (253, 220, 177), (253, 231, 205), (248, 242, 224), (245, 240, 221), + (238, 221, 190), (216, 227, 184), (206, 219, 169), (206, 218, 161), + (209, 206, 129), (209, 213, 144), (173, 191, 181), (213, 173, 208), + (205, 196, 207), (198, 225, 220), (225, 234, 223), (235, 235, 238), + (240, 240, 241), (247, 248, 243), (251, 232, 221), (252, 221, 175), + (251, 198, 122), (248, 165, 96), (252, 152, 62), (253, 138, 46), + (252, 143, 53), (237, 142, 72), (216, 149, 109), (240, 121, 189), + (213, 144, 199), (186, 119, 171), (190, 115, 169), (143, 113, 115), + (163, 102, 76), (181, 98, 43), (205, 114, 43), (230, 132, 45) + ), + +// 156 Apophysis-040426-163BFlyGate4 +((19, 21, 16), (0, 0, 0), (39, 1, 22), (78, 2, 45), + (128, 27, 95), (179, 53, 146), (170, 92, 170), (162, 131, 195), + (150, 152, 150), (106, 108, 127), (63, 65, 104), (46, 49, 83), + (30, 33, 63), (16, 23, 46), (3, 14, 29), (1, 7, 14), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (12, 14, 16), (8, 23, 27), (5, 33, 38), (16, 33, 49), + (27, 33, 60), (31, 33, 64), (36, 33, 68), (61, 33, 29), + (57, 33, 24), (64, 33, 31), (65, 23, 32), (67, 14, 34), + (36, 10, 74), (6, 7, 115), (24, 4, 95), (42, 2, 75), + (31, 18, 63), (19, 25, 44), (7, 33, 25), (10, 33, 21), + (14, 33, 18), (14, 33, 17), (15, 33, 17), (13, 11, 16), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (8, 8, 8), (17, 16, 16), (32, 33, 24), + (48, 50, 33), (66, 68, 33), (84, 86, 33), (140, 138, 75), + (244, 183, 97), (177, 129, 6), (169, 106, 21), (161, 84, 36), + (130, 58, 51), (99, 33, 66), (45, 14, 78), (30, 2, 63), + (1, 2, 16), (0, 1, 8), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (23, 14, 9), (50, 48, 33), (25, 81, 32), (0, 115, 32), + (30, 102, 30), (61, 90, 28), (65, 67, 16), (47, 33, 14), + (45, 33, 12), (59, 52, 14), (73, 71, 16), (101, 58, 14), + (130, 46, 13), (160, 87, 31), (160, 90, 28), (113, 111, 2), + (95, 93, 16), (86, 41, 53), (93, 37, 60), (100, 33, 67), + (100, 33, 67), (101, 33, 68), (105, 33, 72), (106, 33, 73), + (97, 239, 129), (103, 204, 189), (110, 169, 250), (91, 122, 242), + (73, 75, 235), (44, 46, 234), (148, 106, 181), (221, 121, 188), + (239, 164, 206), (232, 230, 246), (230, 230, 231), (228, 230, 217), + (247, 216, 214), (235, 185, 167), (159, 117, 126), (108, 36, 75), + (34, 36, 33), (29, 33, 20), (24, 31, 7), (34, 38, 11), + (44, 46, 16), (60, 75, 27), (84, 82, 16), (103, 101, 2), + (152, 94, 0), (163, 99, 21), (161, 92, 27), (160, 86, 33), + (88, 86, 41), (86, 33, 53), (78, 33, 45), (70, 33, 37), + (54, 33, 21), (38, 33, 38), (22, 33, 55), (27, 33, 64), + (32, 34, 74), (4, 76, 116), (26, 125, 128), (58, 60, 152), + (96, 98, 173), (205, 131, 237), (214, 126, 246), (223, 122, 255), + (223, 208, 255), (248, 250, 207), (28, 30, 16), (45, 47, 16), + (95, 93, 2), (98, 96, 2), (101, 99, 2), (95, 93, 2), + (81, 79, 16), (68, 69, 16), (47, 52, 14), (38, 33, 5), + (26, 28, 2), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (31, 14, 1), (63, 33, 30), + (98, 33, 65), (104, 33, 71), (110, 33, 77), (119, 43, 152), + (132, 106, 165), (111, 90, 143), (88, 90, 105), (69, 71, 62), + (85, 33, 53), (77, 33, 44), (55, 33, 22), (40, 33, 8), + (24, 14, 8), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (38, 14, 5), (77, 33, 44), + (111, 33, 79), (140, 106, 173), (177, 153, 209), (169, 241, 202), + (170, 237, 242), (144, 201, 216), (124, 153, 157), (116, 119, 149), + (123, 125, 137), (116, 118, 121), (73, 119, 106), (73, 119, 106), + (71, 73, 121), (30, 90, 63), (20, 90, 53), (39, 77, 51), + (45, 43, 33), (30, 29, 33), (26, 24, 33), (21, 14, 54), + (21, 14, 54), (9, 11, 33), (2, 4, 16), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (32, 14, 0), (41, 33, 8), + (51, 53, 2), (73, 75, 16), (77, 75, 16), (76, 74, 16), + (72, 70, 16), (70, 33, 37), (43, 33, 76), (44, 33, 77), + (46, 33, 79), (87, 17, 54), (87, 14, 54), (80, 1, 47), + (66, 14, 33), (53, 14, 20), (37, 14, 4), (32, 18, 0), + (32, 33, 0), (31, 33, 2), (24, 33, 7), (17, 33, 15), + (13, 33, 19), (1, 33, 31), (6, 33, 39), (8, 33, 41), + (4, 6, 62), (14, 16, 152), (32, 30, 162), (50, 33, 83), + (98, 33, 65), (105, 33, 72), (106, 33, 73), (100, 33, 67), + (92, 33, 59), (79, 33, 46), (65, 33, 32), (46, 33, 13) + ), + +// 157 Apophysis-040426-163BFlyGate4Inv +((209, 222, 242), (255, 255, 255), (241, 248, 253), (227, 241, 251), + (186, 245, 215), (146, 250, 179), (111, 226, 144), (76, 202, 109), + (70, 68, 105), (111, 109, 119), (152, 150, 134), (178, 186, 153), + (205, 222, 172), (223, 230, 197), (241, 239, 222), (246, 240, 224), + (252, 241, 226), (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, 238, 239), (254, 222, 224), (245, 222, 214), + (237, 222, 204), (232, 222, 199), (228, 222, 195), (219, 222, 187), + (194, 222, 226), (197, 222, 230), (193, 222, 226), (189, 222, 222), + (202, 231, 202), (215, 241, 182), (232, 244, 161), (249, 248, 140), + (217, 241, 184), (225, 231, 192), (234, 222, 201), (237, 222, 219), + (241, 222, 237), (241, 222, 237), (241, 222, 237), (240, 222, 238), + (242, 244, 239), (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), (253, 255, 253), (238, 240, 246), + (224, 226, 239), (215, 215, 230), (207, 205, 222), (171, 169, 222), + (115, 117, 180), (78, 147, 214), (81, 146, 222), (85, 146, 230), + (89, 158, 224), (94, 171, 219), (156, 222, 189), (210, 241, 177), + (241, 241, 208), (248, 248, 231), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (222, 220, 239), (230, 191, 222), (238, 163, 205), + (246, 151, 214), (255, 140, 223), (194, 165, 227), (190, 188, 239), + (212, 222, 245), (204, 210, 248), (197, 199, 252), (189, 191, 245), + (182, 184, 239), (125, 209, 242), (95, 168, 224), (95, 165, 227), + (142, 144, 253), (185, 183, 206), (171, 202, 198), (158, 222, 191), + (156, 222, 189), (155, 222, 188), (154, 222, 187), (150, 222, 183), + (133, 128, 166), (149, 87, 120), (165, 46, 75), (155, 66, 40), + (145, 86, 5), (182, 180, 20), (211, 209, 21), (107, 149, 74), + (34, 134, 67), (0, 41, 32), (11, 33, 20), (23, 25, 9), + (27, 25, 38), (8, 39, 41), (20, 70, 88), (96, 138, 129), + (177, 222, 209), (207, 222, 225), (237, 222, 241), (234, 223, 244), + (231, 224, 248), (211, 209, 239), (195, 180, 228), (171, 173, 239), + (152, 154, 253), (91, 152, 236), (91, 154, 235), (92, 156, 234), + (95, 169, 222), (167, 169, 214), (169, 222, 202), (177, 222, 210), + (198, 222, 231), (210, 221, 226), (222, 220, 222), (227, 221, 211), + (233, 222, 200), (223, 221, 181), (251, 179, 139), (229, 130, 127), + (197, 195, 103), (103, 136, 71), (76, 130, 44), (50, 124, 18), + (32, 133, 0), (32, 47, 0), (7, 5, 48), (227, 225, 239), + (182, 180, 239), (171, 171, 246), (160, 162, 253), (154, 156, 253), + (160, 162, 253), (174, 176, 239), (187, 186, 239), (208, 203, 241), + (217, 222, 250), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (224, 241, 254), + (166, 222, 199), (161, 222, 194), (157, 222, 190), (145, 222, 178), + (136, 212, 103), (123, 149, 90), (144, 165, 112), (167, 165, 150), + (186, 184, 193), (170, 222, 202), (178, 222, 211), (200, 222, 233), + (215, 222, 247), (231, 241, 247), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (217, 241, 250), + (178, 222, 211), (144, 222, 176), (115, 149, 82), (78, 102, 46), + (86, 14, 53), (85, 18, 13), (111, 54, 39), (131, 102, 98), + (139, 136, 106), (132, 130, 118), (139, 137, 134), (182, 136, 149), + (182, 136, 149), (184, 182, 134), (225, 165, 192), (235, 165, 202), + (216, 178, 204), (210, 212, 222), (225, 226, 222), (229, 231, 222), + (234, 241, 201), (234, 241, 201), (246, 244, 222), (253, 251, 239), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (223, 241, 255), + (214, 222, 247), (204, 202, 253), (182, 180, 239), (178, 180, 239), + (179, 181, 239), (183, 185, 239), (185, 222, 218), (212, 222, 179), + (211, 222, 178), (209, 222, 176), (168, 238, 201), (168, 241, 201), + (175, 254, 208), (189, 241, 222), (202, 241, 235), (218, 241, 251), + (223, 237, 255), (223, 222, 255), (224, 222, 253), (231, 222, 248), + (238, 222, 240), (242, 222, 236), (254, 222, 224), (249, 222, 216), + (247, 222, 214), (251, 249, 193), (241, 239, 103), (223, 225, 93), + (205, 222, 172), (157, 222, 190), (150, 222, 183), (149, 222, 182), + (155, 222, 188), (163, 222, 196), (176, 222, 209), (190, 222, 223) + ), + +// 158 Apophysis-040426-163CeltCross +((173, 167, 70), (250, 143, 64), (238, 123, 60), (227, 103, 57), + (181, 57, 33), (136, 11, 9), (68, 5, 4), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (29, 35, 0), (58, 71, 0), (111, 99, 38), + (165, 127, 76), (198, 119, 69), (231, 112, 62), (250, 120, 51), + (241, 130, 66), (195, 159, 64), (162, 142, 58), (130, 125, 53), + (96, 106, 54), (62, 88, 56), (31, 44, 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), (41, 12, 30), (83, 24, 61), + (128, 33, 54), (174, 42, 47), (181, 43, 43), (218, 104, 59), + (210, 180, 62), (193, 189, 48), (177, 199, 34), (100, 156, 39), + (24, 113, 45), (12, 56, 22), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (45, 123, 36), (134, 171, 11), + (198, 208, 55), (184, 195, 50), (171, 182, 45), (142, 159, 26), + (114, 137, 7), (54, 80, 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), (21, 96, 1), + (117, 175, 89), (159, 163, 84), (201, 151, 80), (213, 137, 77), + (226, 123, 75), (196, 80, 67), (168, 46, 54), (96, 51, 67), + (27, 23, 69), (84, 49, 8), (120, 86, 33), (156, 123, 58), + (218, 104, 59), (233, 117, 63), (247, 140, 65), (251, 141, 60), + (252, 146, 62), (252, 149, 62), (253, 153, 63), (251, 156, 57), + (245, 185, 65), (213, 214, 57), (219, 225, 64), (223, 228, 59), + (232, 229, 67), (231, 228, 47), (222, 225, 45), (214, 222, 44), + (225, 210, 50), (245, 185, 65), (245, 182, 64), (245, 186, 65), + (211, 212, 57), (219, 193, 59), (228, 174, 61), (225, 135, 90), + (204, 117, 81), (197, 134, 116), (136, 143, 73), (69, 152, 22), + (31, 95, 3), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (12, 130, 18), (87, 171, 36), (131, 175, 82), + (232, 177, 60), (239, 181, 63), (247, 185, 66), (252, 170, 72), + (250, 180, 91), (230, 207, 98), (236, 195, 122), (212, 180, 102), + (116, 136, 139), (65, 78, 66), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (96, 31, 1), (163, 19, 35), (197, 7, 21), + (197, 7, 21), (142, 0, 1), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (39, 87, 1), (58, 121, 25), (118, 131, 65) + ), + +// 159 Apophysis-040426-163Egg4d +((168, 128, 78), (252, 247, 220), (252, 244, 215), (252, 242, 211), + (251, 238, 205), (251, 235, 200), (250, 235, 200), (250, 235, 201), + (227, 239, 216), (229, 239, 216), (232, 240, 216), (241, 236, 206), + (251, 232, 196), (241, 220, 182), (232, 209, 168), (231, 200, 157), + (230, 191, 147), (201, 153, 106), (196, 142, 94), (192, 131, 83), + (172, 145, 99), (153, 160, 116), (146, 176, 142), (139, 193, 168), + (151, 202, 188), (179, 216, 201), (207, 230, 215), (227, 222, 193), + (247, 214, 172), (247, 207, 163), (247, 200, 155), (228, 185, 139), + (193, 168, 123), (153, 160, 116), (153, 160, 116), (153, 160, 116), + (153, 160, 116), (153, 160, 116), (153, 160, 116), (153, 160, 116), + (153, 160, 116), (155, 141, 94), (158, 122, 72), (160, 107, 58), + (163, 92, 45), (178, 50, 39), (194, 9, 34), (181, 8, 38), + (109, 1, 37), (138, 79, 33), (155, 100, 52), (172, 121, 71), + (190, 151, 103), (208, 181, 135), (216, 189, 145), (225, 197, 155), + (248, 231, 195), (240, 235, 206), (233, 240, 217), (226, 235, 210), + (220, 231, 203), (223, 219, 185), (227, 207, 167), (212, 188, 143), + (185, 156, 110), (111, 71, 24), (75, 39, 30), (40, 8, 36), + (49, 15, 26), (58, 23, 17), (70, 35, 6), (81, 47, 3), + (143, 76, 29), (170, 89, 42), (198, 103, 55), (220, 134, 86), + (243, 165, 117), (247, 173, 125), (252, 182, 134), (247, 201, 153), + (250, 209, 167), (237, 216, 177), (242, 218, 178), (247, 221, 180), + (249, 225, 186), (252, 229, 192), (250, 231, 194), (252, 236, 200), + (247, 249, 226), (241, 245, 230), (235, 242, 234), (228, 239, 228), + (222, 237, 222), (218, 236, 225), (206, 227, 218), (192, 219, 215), + (153, 196, 197), (133, 181, 187), (150, 193, 195), (168, 206, 203), + (180, 213, 209), (193, 221, 216), (202, 227, 216), (202, 227, 216), + (149, 197, 193), (131, 180, 184), (113, 163, 175), (133, 161, 145), + (153, 160, 116), (153, 160, 116), (190, 164, 118), (218, 153, 106), + (239, 148, 98), (212, 141, 91), (201, 149, 100), (190, 158, 110), + (191, 164, 118), (216, 171, 125), (235, 176, 128), (250, 172, 125), + (222, 115, 69), (237, 57, 40), (252, 0, 12), (244, 1, 17), + (236, 2, 22), (222, 2, 25), (211, 1, 30), (185, 5, 30), + (141, 72, 26), (133, 80, 35), (127, 82, 35), (121, 84, 35), + (121, 95, 49), (97, 115, 71), (63, 72, 25), (62, 50, 4), + (121, 71, 22), (107, 110, 66), (93, 149, 111), (70, 148, 117), + (47, 147, 123), (75, 111, 67), (38, 40, 29), (2, 8, 35), + (13, 8, 37), (139, 107, 59), (162, 130, 82), (185, 153, 106), + (208, 176, 130), (224, 197, 154), (235, 216, 177), (247, 232, 196), + (240, 246, 226), (241, 245, 223), (242, 245, 221), (252, 239, 206), + (252, 230, 192), (242, 217, 177), (232, 201, 158), (216, 194, 151), + (205, 182, 137), (153, 160, 116), (123, 162, 125), (94, 164, 135), + (71, 153, 156), (58, 147, 149), (76, 138, 155), (87, 153, 163), + (100, 167, 171), (94, 164, 168), (89, 161, 165), (84, 166, 160), + (107, 162, 126), (153, 160, 116), (185, 164, 118), (205, 182, 137), + (222, 199, 158), (230, 210, 171), (242, 222, 182), (251, 227, 188), + (250, 239, 207), (252, 242, 208), (252, 242, 212), (252, 245, 215), + (252, 242, 213), (252, 242, 212), (252, 242, 211), (252, 240, 208), + (250, 236, 203), (252, 234, 199), (252, 224, 185), (248, 216, 175), + (242, 210, 168), (227, 195, 151), (212, 185, 140), (201, 175, 128), + (198, 170, 125), (190, 164, 118), (190, 156, 108), (201, 133, 83), + (216, 129, 80), (218, 153, 106), (225, 176, 128), (245, 197, 153), + (252, 212, 168), (242, 217, 178), (245, 224, 186), (247, 224, 185), + (250, 218, 176), (250, 211, 167), (251, 187, 138), (242, 179, 130), + (248, 171, 121), (250, 180, 133), (232, 191, 145), (218, 195, 153), + (208, 188, 144), (201, 180, 135), (164, 175, 133), (153, 160, 116), + (153, 160, 116), (172, 138, 91), (185, 125, 75), (181, 116, 71), + (185, 118, 71), (201, 127, 79), (190, 127, 80), (185, 129, 80), + (177, 135, 88), (177, 143, 96), (166, 120, 95), (156, 97, 84), + (143, 107, 59), (116, 84, 37), (105, 66, 19), (116, 66, 20), + (121, 90, 40), (143, 103, 55), (177, 118, 70), (198, 143, 95), + (205, 174, 128), (225, 181, 133), (232, 188, 142), (215, 191, 147), + (205, 184, 141), (144, 184, 151), (89, 165, 138), (46, 149, 136), + (16, 82, 39), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (30, 32, 23), (88, 54, 6), (143, 103, 55), (153, 160, 116) + ), + +// 160 Apophysis-040426-163FlowerFerns +((147, 231, 75), (140, 223, 68), (143, 229, 57), (147, 236, 46), + (150, 244, 40), (154, 253, 35), (155, 252, 39), (156, 251, 44), + (140, 250, 57), (137, 244, 41), (135, 238, 25), (128, 208, 20), + (121, 179, 16), (91, 137, 42), (62, 95, 68), (39, 81, 70), + (17, 68, 73), (1, 76, 119), (6, 68, 142), (12, 61, 166), + (25, 79, 137), (39, 97, 109), (48, 98, 104), (58, 100, 99), + (105, 74, 88), (163, 74, 82), (221, 75, 77), (211, 127, 84), + (202, 179, 92), (199, 189, 95), (196, 200, 99), (149, 232, 77), + (137, 220, 66), (103, 210, 27), (115, 203, 34), (128, 196, 42), + (129, 200, 46), (131, 205, 51), (126, 222, 63), (122, 240, 75), + (120, 202, 49), (91, 152, 57), (62, 103, 65), (57, 93, 69), + (52, 83, 73), (40, 74, 89), (29, 66, 105), (22, 76, 106), + (10, 98, 92), (60, 152, 35), (81, 144, 19), (102, 137, 4), + (108, 101, 21), (114, 66, 38), (127, 53, 39), (140, 41, 40), + (83, 103, 11), (75, 110, 6), (67, 117, 1), (59, 119, 4), + (51, 121, 8), (50, 117, 6), (50, 114, 4), (68, 111, 3), + (53, 86, 16), (55, 76, 40), (63, 50, 22), (71, 24, 4), + (48, 21, 5), (25, 18, 6), (53, 2, 19), (83, 4, 3), + (97, 18, 35), (66, 24, 49), (36, 31, 63), (33, 57, 57), + (30, 84, 51), (32, 103, 47), (35, 122, 43), (63, 168, 50), + (101, 205, 65), (54, 154, 57), (40, 127, 76), (26, 101, 95), + (13, 121, 101), (1, 142, 108), (0, 77, 117), (8, 77, 105), + (8, 62, 95), (11, 47, 90), (14, 32, 86), (8, 34, 79), + (3, 37, 73), (20, 27, 65), (34, 26, 66), (21, 47, 74), + (14, 76, 103), (63, 80, 201), (99, 70, 207), (135, 60, 213), + (128, 56, 220), (122, 52, 228), (126, 16, 221), (73, 39, 210), + (4, 33, 140), (12, 55, 119), (20, 77, 98), (30, 79, 90), + (40, 81, 82), (72, 113, 63), (93, 159, 44), (123, 182, 37), + (146, 206, 51), (111, 190, 18), (106, 197, 13), (102, 205, 9), + (93, 209, 9), (97, 190, 4), (95, 186, 4), (110, 181, 13), + (101, 176, 31), (103, 165, 20), (106, 154, 9), (99, 147, 6), + (92, 141, 3), (80, 138, 16), (113, 142, 18), (107, 173, 19), + (112, 168, 32), (85, 95, 218), (103, 90, 228), (121, 85, 238), + (132, 87, 242), (146, 90, 249), (181, 75, 247), (176, 93, 218), + (143, 203, 152), (139, 222, 119), (136, 241, 87), (159, 227, 102), + (183, 214, 118), (200, 220, 164), (143, 180, 177), (120, 165, 191), + (80, 168, 161), (106, 154, 119), (102, 169, 79), (98, 184, 40), + (133, 201, 47), (148, 220, 65), (175, 177, 102), (190, 174, 114), + (102, 152, 9), (94, 140, 7), (87, 129, 6), (73, 120, 8), + (53, 118, 36), (51, 70, 63), (37, 54, 38), (13, 63, 9), + (7, 46, 37), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (2, 29, 46), (13, 54, 36), (21, 52, 55), (37, 72, 64), + (37, 112, 47), (42, 133, 35), (47, 154, 23), (65, 147, 24), + (118, 181, 47), (126, 201, 48), (140, 197, 43), (137, 220, 65), + (118, 240, 86), (129, 222, 133), (98, 157, 133), (35, 106, 98), + (1, 82, 76), (2, 48, 59), (13, 32, 58), (0, 20, 64), + (22, 10, 54), (25, 11, 48), (28, 12, 43), (25, 0, 26), + (27, 10, 26), (53, 23, 49), (78, 29, 29), (117, 30, 27), + (124, 3, 19), (124, 9, 5), (118, 15, 3), (76, 3, 8), + (25, 2, 17), (22, 0, 25), (5, 6, 31), (4, 4, 31), + (10, 4, 49), (28, 16, 91), (10, 7, 105), (15, 7, 119), + (4, 39, 173), (27, 26, 166), (29, 13, 152), (19, 11, 108), + (15, 23, 76), (12, 12, 44), (5, 5, 43), (16, 16, 53), + (34, 37, 77), (38, 82, 87), (63, 129, 121), (82, 120, 102), + (172, 106, 100), (212, 83, 100), (120, 45, 109), (37, 29, 102), + (35, 26, 92), (31, 64, 71), (65, 93, 72), (123, 107, 74), + (126, 183, 47), (135, 218, 64), (132, 240, 86), (135, 242, 88), + (141, 235, 83), (144, 227, 72), (149, 221, 52), (139, 223, 33), + (131, 244, 58), (135, 252, 96), (128, 226, 130), (135, 183, 172), + (112, 124, 245), (132, 136, 251), (97, 239, 249), (201, 249, 235), + (228, 229, 181), (216, 148, 205), (134, 161, 196), (83, 111, 243), + (46, 75, 185), (38, 23, 154), (56, 3, 75), (90, 0, 54), + (135, 23, 79), (125, 64, 69), (139, 106, 94), (167, 191, 68), + (140, 223, 67), (145, 231, 76), (150, 234, 79), (149, 233, 77) + ), + +// 161 Apophysis-040426-163FlowerFernsInv +((106, 22, 178), (110, 27, 181), (106, 32, 190), (102, 38, 200), + (104, 26, 203), (106, 14, 207), (103, 8, 213), (101, 2, 220), + (111, 3, 191), (112, 4, 205), (113, 6, 219), (119, 18, 225), + (125, 30, 231), (148, 84, 228), (171, 139, 225), (182, 149, 206), + (193, 160, 187), (252, 184, 174), (246, 191, 137), (241, 198, 101), + (222, 180, 115), (203, 162, 130), (209, 160, 138), (216, 158, 146), + (180, 145, 161), (126, 159, 174), (72, 173, 187), (45, 156, 149), + (18, 140, 111), (35, 108, 137), (53, 76, 163), (59, 55, 156), + (106, 23, 178), (149, 16, 223), (148, 32, 232), (148, 49, 242), + (140, 51, 224), (132, 54, 207), (128, 52, 205), (124, 50, 204), + (129, 34, 187), (149, 78, 196), (170, 123, 205), (176, 137, 189), + (183, 151, 173), (193, 161, 177), (203, 172, 182), (226, 189, 150), + (233, 179, 149), (225, 133, 194), (196, 128, 214), (167, 123, 234), + (152, 119, 237), (137, 116, 241), (139, 152, 229), (141, 189, 217), + (146, 190, 238), (157, 167, 245), (169, 145, 252), (180, 139, 248), + (191, 133, 244), (197, 133, 245), (204, 134, 247), (205, 141, 251), + (187, 144, 252), (206, 174, 244), (193, 195, 228), (181, 216, 213), + (182, 223, 232), (184, 231, 251), (230, 237, 249), (202, 253, 236), + (157, 243, 246), (176, 249, 213), (196, 255, 181), (203, 218, 190), + (210, 182, 200), (217, 176, 202), (225, 171, 204), (220, 133, 212), + (192, 87, 205), (164, 72, 216), (176, 113, 198), (189, 155, 181), + (209, 154, 170), (229, 154, 160), (254, 113, 147), (255, 178, 138), + (244, 187, 160), (240, 198, 166), (236, 210, 173), (238, 216, 171), + (241, 223, 169), (252, 218, 182), (235, 228, 190), (221, 229, 189), + (234, 208, 181), (234, 173, 103), (184, 176, 64), (135, 179, 25), + (127, 187, 33), (120, 195, 42), (133, 203, 27), (129, 239, 34), + (226, 215, 96), (238, 203, 120), (250, 192, 144), (242, 185, 150), + (235, 178, 157), (215, 174, 173), (183, 142, 192), (162, 96, 211), + (132, 73, 218), (123, 66, 220), (133, 65, 228), (144, 65, 237), + (153, 50, 246), (162, 46, 246), (158, 65, 251), (160, 69, 251), + (131, 75, 228), (141, 79, 236), (152, 83, 245), (150, 92, 245), + (149, 101, 246), (163, 114, 252), (175, 117, 239), (142, 113, 237), + (148, 82, 236), (141, 129, 139), (155, 144, 88), (170, 160, 37), + (134, 170, 17), (123, 168, 13), (109, 165, 6), (74, 180, 8), + (98, 97, 35), (111, 58, 94), (125, 19, 153), (122, 16, 160), + (119, 14, 168), (72, 41, 137), (55, 35, 91), (112, 75, 78), + (135, 90, 64), (191, 116, 135), (170, 108, 135), (149, 101, 136), + (157, 71, 215), (122, 54, 208), (107, 35, 190), (80, 78, 153), + (76, 78, 161), (114, 90, 203), (153, 103, 246), (168, 126, 249), + (182, 135, 247), (202, 137, 219), (204, 185, 192), (218, 201, 217), + (242, 192, 246), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (253, 226, 209), (242, 201, 219), (234, 203, 200), + (210, 179, 195), (214, 161, 201), (218, 143, 208), (208, 101, 232), + (190, 108, 231), (137, 74, 208), (129, 54, 207), (115, 58, 212), + (118, 35, 190), (137, 15, 169), (126, 33, 122), (157, 98, 122), + (220, 149, 157), (254, 173, 179), (253, 207, 196), (242, 223, 197), + (246, 248, 167), (239, 246, 184), (233, 245, 201), (227, 243, 212), + (230, 255, 229), (228, 245, 229), (202, 232, 206), (177, 226, 226), + (138, 225, 228), (131, 252, 236), (131, 246, 250), (137, 240, 252), + (179, 252, 247), (230, 253, 238), (233, 255, 230), (250, 249, 224), + (251, 251, 224), (245, 251, 206), (227, 239, 164), (245, 248, 150), + (240, 248, 136), (251, 216, 82), (228, 229, 89), (226, 242, 103), + (236, 244, 147), (240, 232, 179), (243, 243, 211), (250, 250, 212), + (239, 239, 202), (221, 218, 178), (217, 173, 168), (192, 126, 134), + (173, 135, 153), (83, 149, 155), (43, 172, 155), (135, 210, 146), + (218, 226, 153), (220, 229, 163), (224, 191, 184), (190, 162, 183), + (132, 148, 181), (129, 72, 208), (120, 37, 191), (123, 15, 169), + (120, 13, 167), (114, 20, 172), (111, 28, 183), (106, 34, 203), + (116, 32, 222), (124, 11, 197), (120, 3, 159), (127, 29, 125), + (120, 72, 83), (143, 131, 10), (123, 119, 4), (158, 16, 6), + (54, 6, 20), (27, 26, 74), (39, 107, 50), (121, 94, 59), + (172, 144, 12), (209, 180, 70), (217, 232, 101), (199, 252, 180), + (165, 255, 201), (120, 232, 176), (130, 191, 186), (116, 149, 161), + (88, 64, 187), (115, 32, 188), (110, 24, 179), (105, 21, 176) + ), + +// 162 Apophysis-040426-163FlwrFernsInv +((132, 26, 36), (154, 62, 23), (148, 90, 33), (142, 119, 43), + (162, 130, 49), (183, 141, 55), (192, 144, 53), (202, 148, 52), + (229, 140, 36), (240, 122, 45), (251, 105, 54), (227, 97, 53), + (203, 89, 53), (123, 84, 77), (44, 80, 102), (23, 87, 107), + (2, 95, 113), (4, 2, 51), (36, 13, 45), (69, 25, 40), + (96, 25, 39), (124, 26, 39), (119, 23, 38), (115, 21, 37), + (97, 7, 45), (93, 6, 46), (90, 5, 47), (107, 13, 41), + (124, 22, 36), (133, 26, 30), (142, 31, 24), (177, 43, 6), + (240, 60, 45), (253, 91, 70), (252, 91, 66), (252, 91, 63), + (244, 82, 50), (236, 73, 38), (225, 85, 44), (215, 97, 51), + (172, 117, 63), (184, 108, 58), (196, 99, 54), (215, 53, 76), + (235, 8, 98), (239, 5, 101), (244, 2, 104), (248, 1, 106), + (240, 14, 114), (159, 11, 99), (138, 38, 58), (117, 65, 18), + (79, 104, 11), (42, 143, 5), (36, 136, 13), (31, 130, 22), + (134, 130, 56), (149, 156, 52), (165, 183, 49), (144, 145, 63), + (123, 108, 77), (75, 106, 102), (28, 104, 127), (20, 107, 126), + (51, 127, 141), (110, 175, 177), (128, 188, 187), (146, 201, 198), + (154, 203, 200), (163, 205, 203), (176, 212, 210), (210, 227, 219), + (252, 232, 146), (252, 210, 105), (252, 188, 65), (228, 193, 78), + (205, 198, 92), (192, 206, 106), (180, 215, 121), (203, 226, 144), + (243, 243, 155), (228, 235, 217), (224, 235, 224), (220, 235, 232), + (214, 209, 215), (208, 184, 198), (177, 150, 143), (183, 123, 97), + (66, 135, 150), (90, 150, 160), (115, 166, 170), (115, 172, 175), + (115, 179, 181), (127, 187, 187), (137, 180, 186), (154, 203, 200), + (162, 208, 206), (176, 180, 165), (165, 144, 123), (154, 108, 82), + (127, 99, 72), (101, 90, 62), (83, 62, 35), (100, 23, 39), + (129, 56, 67), (164, 88, 87), (199, 121, 108), (224, 172, 140), + (250, 224, 173), (253, 247, 233), (245, 242, 237), (242, 227, 170), + (252, 245, 128), (233, 196, 63), (224, 174, 51), (216, 153, 39), + (238, 85, 90), (236, 16, 116), (245, 13, 115), (253, 8, 112), + (252, 9, 115), (251, 10, 115), (250, 11, 115), (243, 13, 114), + (236, 16, 114), (224, 19, 112), (191, 19, 105), (145, 27, 88), + (105, 4, 44), (84, 4, 57), (78, 10, 61), (72, 16, 65), + (76, 14, 61), (76, 21, 40), (86, 8, 48), (121, 14, 44), + (159, 69, 6), (181, 108, 38), (204, 147, 70), (200, 153, 64), + (197, 159, 58), (195, 171, 61), (157, 160, 53), (246, 49, 56), + (236, 7, 98), (252, 2, 110), (252, 1, 110), (252, 0, 111), + (253, 3, 111), (250, 11, 115), (251, 12, 116), (240, 16, 115), + (224, 16, 110), (212, 20, 107), (200, 25, 104), (166, 141, 180), + (172, 211, 208), (210, 231, 226), (223, 198, 201), (189, 150, 109), + (189, 126, 82), (236, 123, 57), (244, 109, 63), (253, 95, 70), + (254, 89, 70), (253, 71, 70), (225, 21, 110), (212, 19, 108), + (182, 26, 99), (184, 23, 100), (186, 20, 102), (200, 10, 108), + (201, 11, 111), (190, 17, 106), (186, 20, 102), (142, 8, 93), + (146, 14, 28), (167, 15, 14), (153, 23, 23), (147, 35, 23), + (163, 42, 13), (177, 26, 7), (197, 40, 7), (227, 52, 33), + (254, 94, 68), (253, 94, 69), (253, 95, 70), (250, 86, 77), + (221, 21, 109), (185, 22, 103), (129, 23, 85), (83, 37, 66), + (62, 14, 64), (31, 39, 26), (10, 47, 3), (22, 53, 55), + (24, 70, 94), (17, 97, 120), (33, 111, 131), (77, 147, 155), + (111, 164, 172), (128, 169, 175), (113, 97, 110), (111, 52, 48), + (109, 23, 50), (139, 6, 33), (177, 22, 100), (209, 15, 112), + (231, 23, 109), (251, 88, 79), (222, 138, 68), (251, 179, 61), + (234, 185, 56), (204, 166, 55), (201, 164, 60), (182, 175, 61), + (178, 207, 53), (174, 196, 88), (206, 228, 127), (196, 224, 137), + (181, 218, 141), (151, 195, 106), (160, 111, 97), (129, 55, 82), + (59, 65, 97), (41, 57, 93), (42, 41, 81), (80, 30, 65), + (121, 28, 83), (185, 22, 103), (203, 21, 106), (239, 5, 102), + (250, 14, 115), (235, 17, 112), (220, 20, 109), (186, 71, 78), + (149, 116, 65), (120, 174, 98), (81, 156, 162), (78, 159, 162), + (52, 132, 139), (55, 105, 130), (104, 94, 41), (159, 82, 2), + (205, 92, 14), (232, 77, 33), (237, 62, 41), (246, 69, 51), + (251, 85, 59), (252, 88, 63), (252, 73, 68), (235, 8, 98), + (239, 5, 102), (204, 14, 110), (160, 30, 92), (132, 27, 84) + ), + +// 163 Apophysis-040426-163FloralCascade2 +((129, 89, 30), (193, 158, 128), (186, 174, 134), (180, 190, 140), + (135, 164, 147), (91, 138, 154), (95, 154, 163), (100, 171, 173), + (172, 201, 197), (202, 222, 213), (233, 244, 230), (237, 219, 206), + (241, 195, 182), (213, 170, 123), (186, 145, 65), (170, 124, 45), + (155, 104, 25), (89, 60, 28), (97, 34, 36), (106, 9, 44), + (105, 9, 44), (104, 10, 44), (101, 9, 45), (99, 9, 47), + (62, 2, 56), (123, 8, 80), (185, 15, 104), (203, 17, 107), + (222, 19, 111), (227, 18, 111), (232, 17, 111), (235, 6, 99), + (205, 9, 31), (150, 49, 19), (192, 87, 27), (234, 126, 35), + (241, 150, 50), (248, 174, 65), (250, 153, 66), (252, 133, 67), + (246, 66, 51), (238, 62, 42), (230, 59, 33), (218, 93, 52), + (207, 128, 71), (208, 142, 63), (209, 157, 55), (240, 198, 62), + (220, 202, 56), (178, 121, 32), (184, 61, 18), (190, 1, 5), + (197, 19, 12), (205, 38, 19), (218, 45, 28), (232, 52, 37), + (167, 64, 67), (144, 44, 55), (121, 24, 44), (96, 39, 63), + (71, 55, 82), (55, 66, 87), (40, 77, 93), (21, 80, 110), + (27, 103, 126), (47, 131, 142), (81, 150, 158), (116, 169, 175), + (127, 179, 181), (139, 189, 188), (209, 212, 193), (240, 241, 207), + (173, 199, 174), (122, 168, 161), (71, 137, 149), (43, 108, 130), + (16, 79, 112), (9, 70, 105), (2, 62, 99), (10, 47, 89), + (30, 56, 9), (39, 146, 8), (56, 112, 29), (73, 79, 51), + (74, 64, 61), (75, 50, 71), (114, 23, 82), (185, 17, 102), + (224, 12, 115), (230, 14, 114), (237, 17, 113), (237, 17, 114), + (237, 17, 115), (244, 15, 116), (244, 12, 114), (243, 3, 104), + (244, 2, 104), (253, 7, 114), (252, 8, 114), (251, 10, 115), + (251, 5, 113), (251, 1, 111), (244, 2, 104), (243, 3, 104), + (232, 39, 66), (232, 50, 51), (233, 62, 36), (242, 69, 48), + (252, 76, 61), (233, 129, 56), (206, 144, 71), (176, 156, 61), + (170, 157, 53), (64, 158, 10), (55, 151, 11), (47, 144, 13), + (71, 72, 38), (53, 55, 42), (52, 26, 73), (40, 42, 81), + (47, 67, 102), (70, 56, 98), (94, 46, 94), (134, 50, 99), + (175, 54, 105), (194, 20, 105), (164, 2, 13), (141, 2, 31), + (125, 22, 41), (100, 114, 127), (98, 124, 138), (97, 134, 150), + (92, 150, 161), (70, 149, 156), (92, 169, 117), (101, 159, 98), + (145, 138, 128), (139, 154, 153), (134, 171, 179), (162, 176, 179), + (190, 182, 180), (224, 194, 158), (203, 155, 132), (188, 95, 88), + (199, 21, 105), (213, 13, 112), (220, 16, 111), (227, 20, 110), + (213, 78, 72), (221, 148, 80), (231, 204, 125), (250, 249, 143), + (204, 227, 123), (190, 210, 102), (176, 193, 81), (102, 149, 55), + (39, 83, 94), (20, 96, 120), (15, 108, 125), (7, 85, 108), + (8, 84, 108), (67, 76, 81), (77, 75, 87), (88, 75, 93), + (125, 89, 103), (128, 115, 109), (153, 105, 91), (117, 107, 56), + (156, 63, 29), (149, 49, 23), (143, 36, 18), (133, 29, 28), + (110, 10, 44), (93, 23, 59), (97, 67, 57), (100, 143, 61), + (160, 164, 44), (173, 183, 71), (230, 237, 108), (252, 252, 118), + (232, 241, 116), (233, 172, 117), (227, 128, 71), (251, 96, 78), + (253, 92, 64), (252, 103, 67), (252, 115, 71), (226, 152, 53), + (251, 176, 57), (233, 208, 63), (223, 217, 69), (182, 202, 91), + (162, 196, 47), (153, 175, 40), (129, 150, 29), (91, 151, 29), + (102, 105, 34), (100, 70, 46), (123, 80, 61), (144, 103, 107), + (158, 110, 74), (176, 117, 49), (201, 117, 70), (247, 100, 80), + (252, 86, 74), (253, 87, 63), (254, 85, 64), (253, 81, 71), + (252, 71, 60), (235, 17, 112), (231, 17, 113), (216, 22, 109), + (190, 17, 106), (109, 21, 81), (54, 23, 64), (44, 48, 86), + (25, 73, 109), (21, 75, 101), (26, 56, 94), (6, 45, 88), + (23, 40, 84), (51, 23, 71), (82, 10, 58), (102, 6, 52), + (80, 3, 57), (54, 9, 64), (44, 5, 52), (16, 19, 72), + (18, 28, 77), (38, 26, 74), (39, 30, 33), (19, 34, 15), + (51, 32, 34), (61, 28, 37), (64, 65, 8), (105, 101, 12), + (123, 137, 52), (175, 171, 48), (184, 150, 52), (177, 127, 42), + (158, 74, 64), (149, 91, 67), (180, 132, 70), (198, 166, 93), + (251, 205, 156), (243, 235, 189), (253, 250, 209), (245, 248, 227), + (249, 246, 239), (248, 248, 214), (214, 176, 199), (209, 91, 125), + (224, 19, 112), (235, 17, 112), (248, 65, 57), (234, 70, 35) + ), + +// 164 Apophysis-040426-163FlowerBurst +((0, 0, 0), (119, 9, 24), (184, 5, 15), (250, 1, 7), + (194, 14, 7), (138, 27, 8), (110, 28, 8), (82, 30, 9), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (88, 15, 3), + (177, 31, 6), (177, 33, 5), (177, 35, 5), (132, 41, 20), + (87, 48, 35), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (58, 63, 41), + (122, 130, 105), (213, 176, 208), (232, 189, 164), (252, 202, 120), + (242, 209, 93), (233, 217, 67), (234, 214, 65), (235, 211, 63), + (232, 219, 108), (232, 210, 167), (232, 202, 227), (242, 205, 231), + (252, 208, 235), (252, 177, 216), (253, 147, 197), (209, 93, 184), + (158, 28, 143), (172, 40, 68), (96, 66, 65), (21, 93, 63), + (10, 46, 31), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (57, 5, 13), (114, 11, 27), (196, 59, 6), + (219, 117, 29), (222, 180, 50), (167, 166, 63), (112, 153, 76), + (72, 144, 50), (33, 135, 25), (28, 122, 31), (18, 120, 34), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (49, 13, 52), (99, 26, 105), + (126, 24, 123), (153, 23, 142), (202, 11, 148), (233, 69, 169), + (231, 123, 187), (138, 99, 129), (45, 75, 71), (22, 37, 35), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (27, 22, 1), (55, 45, 3), (82, 54, 2), + (110, 64, 1), (215, 151, 41), (253, 196, 67), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (58, 40, 6), (116, 56, 0), (212, 98, 19), (254, 110, 38), + (188, 89, 11), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (2, 92, 7), (2, 126, 38), (33, 135, 25), (40, 140, 21), + (88, 152, 31), (127, 150, 32), (151, 162, 41), (163, 166, 39), + (166, 181, 35), (143, 198, 66), (127, 188, 45), (103, 170, 39), + (83, 167, 34), (117, 185, 17), (201, 217, 56), (205, 218, 78), + (208, 188, 52), (185, 162, 41), (128, 133, 68), (52, 103, 14), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (76, 50, 71), + (143, 2, 111), (153, 26, 142), (231, 126, 156), (233, 130, 170), + (185, 63, 163), (93, 34, 103), (27, 88, 61), (0, 0, 0) + ), + +// 165 Apophysis-040426-163MaltesePurple +((154, 94, 148), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (208, 44, 246), (222, 49, 238), (222, 60, 216), + (223, 71, 194), (154, 94, 148), (154, 94, 148), (154, 94, 148), + (155, 93, 149), (157, 93, 150), (175, 87, 162), (193, 81, 174), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (198, 41, 254), + (231, 52, 232), (247, 63, 210), (245, 59, 217), (243, 56, 224), + (231, 52, 232), (219, 48, 240), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (196, 40, 254), (198, 41, 254), + (211, 45, 245), (225, 50, 236), (235, 67, 202), (229, 69, 198), + (241, 65, 206), (231, 57, 222), (222, 49, 238), (208, 44, 246), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (184, 84, 168), (170, 88, 159), (157, 93, 150), + (145, 97, 142), (148, 96, 144), (157, 93, 150), (199, 79, 178), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (210, 45, 246), + (211, 75, 186), (160, 92, 152), (157, 93, 150), (208, 76, 184), + (204, 43, 250), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (195, 40, 255), + (195, 40, 255), (195, 40, 255), (195, 40, 255), (178, 86, 164) + ), + +// 166 Apophysis-040426-163Mycelialg +((236, 164, 209), (49, 2, 28), (24, 1, 14), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 56, 119), (77, 47, 106), (155, 39, 94), (170, 41, 68), + (185, 43, 42), (132, 30, 28), (79, 18, 14), (54, 9, 32), + (30, 0, 50), (0, 0, 85), (5, 14, 66), (11, 29, 47), + (5, 14, 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), (5, 18, 15), + (11, 36, 30), (51, 69, 55), (92, 103, 80), (142, 179, 137), + (197, 211, 212), (255, 198, 255), (255, 179, 255), (255, 160, 255), + (254, 167, 233), (254, 175, 212), (250, 176, 212), (246, 178, 212), + (238, 187, 212), (230, 191, 212), (223, 196, 212), (228, 193, 212), + (233, 190, 212), (244, 199, 214), (255, 208, 216), (255, 219, 181), + (205, 208, 211), (181, 214, 255), (142, 160, 183), (103, 106, 111), + (92, 91, 114), (82, 76, 117), (40, 8, 135), (35, 9, 136), + (120, 63, 179), (167, 98, 199), (215, 134, 220), (184, 119, 196), + (153, 105, 173), (143, 100, 166), (134, 96, 159), (136, 99, 163), + (167, 107, 200), (222, 147, 212), (232, 154, 212), (242, 162, 212), + (248, 166, 212), (254, 170, 212), (248, 166, 212), (231, 146, 240), + (212, 132, 228), (214, 139, 220), (216, 146, 212), (215, 142, 212), + (214, 139, 212), (166, 132, 146), (86, 127, 90), (0, 103, 80), + (0, 44, 49), (0, 0, 0), (5, 10, 0), (11, 21, 0), + (27, 21, 0), (43, 22, 0), (112, 120, 62), (168, 177, 103), + (252, 171, 212), (232, 154, 212), (213, 138, 212), (183, 125, 183), + (154, 113, 155), (95, 82, 123), (49, 62, 81), (0, 55, 36), + (4, 39, 45), (96, 81, 126), (113, 94, 151), (130, 107, 176), + (173, 127, 255), (194, 124, 249), (200, 91, 255), (209, 91, 243), + (69, 40, 145), (34, 20, 142), (0, 0, 140), (0, 1, 112), + (0, 2, 85), (0, 6, 86), (6, 12, 96), (28, 26, 104), + (62, 46, 129), (89, 61, 145), (92, 70, 138), (95, 79, 132), + (60, 72, 82), (44, 57, 80), (0, 41, 38), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (31, 4, 48), (65, 37, 81), (94, 46, 89), + (118, 91, 145), (255, 62, 130), (253, 55, 112), (252, 49, 95), + (251, 21, 0), (197, 47, 0), (138, 19, 12), (88, 31, 14), + (19, 12, 0), (9, 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), (16, 20, 50), + (12, 16, 94), (63, 45, 128), (112, 74, 143), (145, 102, 165), + (222, 150, 212), (227, 153, 212), (233, 157, 212), (242, 163, 212), + (232, 155, 212), (222, 146, 212), (205, 140, 201), (181, 105, 105), + (80, 81, 93), (21, 41, 73), (6, 20, 63), (0, 10, 78), + (10, 8, 88), (48, 59, 86), (122, 91, 105), (175, 129, 163), + (212, 140, 212), (218, 145, 212), (225, 149, 212), (224, 154, 212), + (231, 157, 211), (255, 124, 118), (255, 103, 110), (255, 104, 119), + (255, 91, 153), (227, 150, 212), (245, 135, 242), (255, 151, 255), + (255, 159, 255), (217, 182, 255), (225, 165, 233), (203, 136, 212), + (130, 98, 161), (76, 71, 111), (20, 46, 60), (31, 27, 10), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (29, 3, 56), + (39, 31, 114), (74, 53, 140), (107, 72, 159), (108, 70, 160), + (111, 74, 160), (144, 100, 167), (210, 138, 212), (221, 149, 212), + (245, 169, 212), (255, 198, 212), (255, 227, 213), (255, 255, 255), + (255, 235, 255), (255, 198, 255), (238, 187, 212), (242, 181, 212) + ), + +// 167 Apophysis-040426-163MyceliaInv +((19, 91, 46), (206, 253, 227), (230, 254, 241), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 199, 136), (177, 207, 148), (100, 216, 161), (85, 214, 187), + (70, 212, 213), (123, 224, 227), (176, 237, 241), (200, 246, 223), + (225, 255, 205), (255, 255, 170), (249, 240, 189), (244, 226, 208), + (249, 240, 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), (255, 255, 255), (255, 255, 255), (249, 237, 240), + (244, 219, 225), (203, 185, 200), (163, 152, 175), (113, 76, 118), + (58, 44, 43), (0, 57, 0), (0, 76, 0), (0, 95, 0), + (0, 87, 21), (1, 80, 43), (5, 78, 43), (9, 77, 43), + (17, 68, 43), (24, 63, 43), (32, 59, 43), (27, 62, 43), + (22, 65, 43), (11, 56, 41), (0, 47, 39), (0, 36, 74), + (50, 47, 44), (74, 41, 0), (113, 95, 72), (152, 149, 144), + (162, 164, 141), (173, 179, 138), (215, 247, 120), (220, 246, 119), + (135, 192, 76), (87, 156, 55), (40, 121, 35), (71, 135, 58), + (102, 150, 82), (111, 154, 89), (121, 159, 96), (119, 156, 92), + (88, 148, 55), (33, 108, 43), (23, 100, 43), (13, 93, 43), + (7, 89, 43), (1, 85, 43), (7, 89, 43), (24, 109, 15), + (43, 123, 27), (41, 116, 35), (39, 109, 43), (40, 112, 43), + (41, 116, 43), (89, 123, 109), (169, 128, 165), (255, 152, 175), + (255, 211, 206), (255, 255, 255), (249, 244, 255), (244, 234, 255), + (228, 233, 255), (212, 233, 255), (143, 135, 193), (87, 78, 152), + (3, 84, 43), (22, 100, 43), (42, 117, 43), (71, 129, 71), + (101, 142, 100), (160, 173, 132), (206, 193, 174), (255, 200, 219), + (251, 216, 210), (159, 174, 129), (142, 161, 104), (125, 148, 79), + (82, 128, 0), (61, 131, 6), (55, 164, 0), (46, 164, 12), + (186, 215, 110), (220, 235, 112), (255, 255, 115), (255, 254, 142), + (255, 253, 170), (255, 249, 169), (249, 243, 159), (227, 229, 151), + (193, 209, 126), (166, 194, 110), (163, 185, 116), (160, 176, 123), + (195, 183, 173), (211, 198, 175), (255, 214, 217), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (224, 251, 207), (190, 218, 174), (161, 209, 166), + (137, 164, 110), (0, 193, 125), (1, 199, 142), (3, 206, 160), + (4, 234, 255), (58, 208, 255), (117, 236, 243), (167, 224, 241), + (236, 243, 255), (245, 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), (239, 235, 205), + (243, 239, 161), (192, 210, 127), (143, 181, 112), (110, 153, 90), + (33, 105, 43), (27, 101, 43), (22, 98, 43), (13, 92, 43), + (23, 100, 43), (33, 109, 43), (50, 115, 54), (74, 150, 150), + (175, 174, 162), (234, 214, 182), (249, 235, 192), (255, 245, 177), + (245, 247, 167), (207, 196, 169), (133, 164, 150), (80, 126, 92), + (43, 115, 43), (37, 110, 43), (30, 106, 43), (31, 101, 43), + (24, 98, 44), (0, 131, 137), (0, 152, 145), (0, 151, 136), + (0, 164, 102), (28, 105, 43), (10, 120, 13), (0, 104, 0), + (0, 96, 0), (38, 73, 0), (30, 90, 22), (52, 119, 43), + (125, 157, 94), (179, 184, 144), (235, 209, 195), (224, 228, 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), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (226, 252, 199), + (216, 224, 141), (181, 202, 115), (148, 183, 96), (147, 185, 95), + (144, 181, 95), (111, 155, 88), (45, 117, 43), (34, 106, 43), + (10, 86, 43), (0, 57, 43), (0, 28, 42), (0, 0, 0), + (0, 20, 0), (0, 57, 0), (17, 68, 43), (13, 74, 43) + ), + +// 168 Apophysis-040426-163MrryGRnd +((6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (12, 55, 12), (14, 54, 13), (16, 54, 15), (59, 78, 24), + (102, 103, 33), (132, 100, 30), (162, 98, 27), (154, 87, 22), + (146, 77, 18), (76, 50, 25), (41, 57, 24), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (11, 59, 19), + (16, 54, 15), (16, 54, 15), (16, 54, 15), (25, 42, 10), + (48, 24, 0), (79, 14, 8), (59, 22, 11), (40, 31, 14), + (25, 21, 17), (11, 11, 21), (34, 13, 30), (57, 15, 39), + (146, 31, 98), (174, 15, 85), (203, 0, 72), (214, 21, 39), + (226, 42, 6), (207, 82, 35), (189, 123, 65), (198, 175, 81), + (209, 206, 135), (222, 206, 180), (196, 198, 189), (170, 190, 199), + (175, 188, 151), (181, 186, 104), (164, 120, 111), (99, 85, 84), + (57, 47, 58), (95, 44, 75), (134, 42, 93), (160, 69, 84), + (187, 96, 75), (210, 82, 119), (233, 68, 163), (215, 3, 124), + (162, 40, 91), (44, 34, 7), (30, 44, 9), (16, 55, 11), + (16, 54, 13), (16, 54, 15), (42, 46, 31), (66, 42, 40), + (109, 125, 112), (135, 134, 120), (162, 143, 129), (140, 134, 115), + (118, 126, 102), (103, 109, 83), (58, 90, 103), (20, 89, 68), + (2, 93, 50), (10, 50, 52), (72, 79, 51), (135, 109, 50), + (164, 126, 44), (194, 143, 38), (214, 163, 45), (213, 177, 63), + (122, 154, 31), (72, 137, 29), (22, 121, 28), (11, 118, 35), + (1, 115, 43), (0, 115, 42), (13, 111, 36), (18, 95, 25), + (5, 66, 24), (80, 142, 7), (97, 143, 12), (115, 144, 18), + (124, 154, 24), (153, 88, 22), (198, 51, 70), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (16, 54, 15), (19, 49, 14), (23, 44, 13), + (93, 47, 23), (131, 58, 17), (152, 29, 21), (142, 29, 15), + (94, 36, 24), (81, 18, 20), (68, 0, 17), (69, 2, 10), + (70, 5, 3), (66, 17, 0), (41, 36, 6), (16, 54, 15), + (6, 64, 23), (28, 52, 52), (21, 40, 58), (14, 28, 65), + (28, 50, 61), (73, 58, 37), (128, 111, 33), (201, 155, 43), + (186, 214, 93), (164, 195, 90), (142, 177, 87), (150, 143, 91), + (183, 143, 47), (196, 138, 41), (175, 119, 32), (168, 104, 30), + (192, 65, 50), (149, 61, 86), (150, 72, 80), (151, 84, 75), + (137, 100, 84), (147, 116, 85), (144, 113, 82), (121, 112, 81), + (25, 59, 22), (20, 56, 18), (16, 54, 15), (16, 54, 15), + (16, 54, 15), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (16, 54, 15), (86, 48, 12), + (121, 31, 30), (165, 0, 6), (215, 3, 0), (194, 0, 24), + (158, 20, 20), (106, 31, 8), (53, 25, 4), (17, 47, 9), + (13, 54, 14), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (16, 54, 15), + (16, 54, 15), (16, 54, 15), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (2, 65, 22), (6, 64, 23), (6, 64, 23), + (6, 64, 23), (6, 64, 23), (6, 64, 23), (6, 64, 23) + ), + +// 169 Apophysis-040426-163SprngFlwrs +((177, 132, 82), (186, 78, 167), (160, 77, 143), (135, 76, 119), + (134, 81, 112), (134, 86, 105), (136, 88, 104), (139, 90, 103), + (147, 95, 105), (139, 89, 104), (132, 84, 104), (125, 81, 101), + (118, 78, 98), (105, 75, 89), (93, 72, 81), (89, 70, 80), + (86, 68, 80), (76, 60, 81), (73, 57, 82), (70, 54, 83), + (58, 47, 80), (46, 40, 78), (49, 39, 82), (52, 39, 86), + (83, 48, 99), (86, 58, 91), (90, 69, 83), (107, 75, 91), + (124, 81, 100), (129, 84, 101), (135, 87, 103), (152, 98, 105), + (188, 120, 111), (248, 140, 160), (242, 145, 138), (237, 151, 117), + (212, 145, 99), (187, 140, 81), (183, 137, 81), (179, 134, 81), + (196, 146, 81), (187, 140, 80), (178, 134, 80), (171, 128, 81), + (164, 123, 82), (155, 118, 80), (147, 113, 78), (139, 107, 79), + (126, 96, 81), (120, 92, 81), (119, 91, 81), (119, 91, 82), + (114, 87, 81), (109, 84, 80), (108, 83, 81), (108, 82, 82), + (108, 82, 82), (113, 81, 88), (118, 80, 95), (128, 84, 99), + (138, 89, 103), (143, 92, 104), (149, 96, 105), (171, 91, 135), + (187, 96, 145), (238, 97, 194), (235, 75, 208), (232, 54, 223), + (223, 43, 238), (214, 32, 254), (219, 37, 252), (226, 66, 231), + (255, 104, 201), (233, 112, 168), (212, 121, 135), (190, 111, 125), + (168, 102, 115), (160, 100, 110), (153, 99, 105), (150, 97, 105), + (150, 97, 105), (175, 97, 130), (195, 107, 135), (215, 118, 141), + (224, 119, 149), (233, 120, 157), (254, 129, 170), (254, 111, 192), + (222, 112, 226), (218, 121, 217), (214, 130, 209), (205, 115, 178), + (196, 100, 147), (183, 98, 137), (158, 98, 112), (155, 101, 105), + (151, 98, 104), (146, 94, 105), (136, 94, 93), (126, 95, 82), + (126, 95, 82), (126, 96, 82), (128, 97, 81), (131, 99, 82), + (148, 95, 105), (147, 95, 105), (147, 95, 105), (144, 93, 105), + (142, 91, 105), (135, 88, 102), (126, 84, 98), (122, 84, 94), + (122, 81, 99), (117, 77, 99), (115, 76, 98), (113, 75, 98), + (109, 73, 96), (98, 59, 104), (90, 55, 102), (62, 29, 108), + (55, 20, 113), (74, 38, 109), (94, 56, 105), (105, 64, 105), + (116, 72, 105), (148, 48, 167), (198, 48, 165), (211, 48, 179), + (241, 48, 212), (253, 74, 244), (241, 90, 234), (229, 107, 225), + (191, 135, 225), (200, 148, 199), (200, 150, 195), (218, 147, 182), + (225, 150, 105), (209, 139, 105), (193, 128, 105), (190, 127, 103), + (187, 127, 101), (160, 120, 81), (145, 112, 78), (128, 99, 78), + (122, 94, 80), (120, 93, 79), (122, 93, 80), (124, 94, 82), + (125, 87, 92), (124, 78, 105), (125, 48, 144), (182, 51, 198), + (220, 19, 236), (216, 33, 236), (213, 48, 237), (173, 116, 242), + (149, 147, 252), (127, 139, 227), (143, 151, 252), (160, 139, 251), + (190, 130, 233), (221, 74, 207), (200, 66, 196), (179, 59, 186), + (158, 48, 178), (116, 48, 134), (122, 77, 104), (122, 87, 90), + (127, 97, 81), (129, 98, 81), (132, 100, 82), (140, 106, 82), + (147, 112, 79), (143, 109, 81), (123, 96, 78), (95, 83, 67), + (79, 64, 79), (40, 48, 56), (3, 48, 19), (0, 48, 16), + (31, 48, 47), (69, 55, 79), (81, 63, 82), (92, 72, 81), + (104, 80, 81), (106, 81, 81), (108, 82, 82), (108, 84, 79), + (106, 81, 81), (106, 73, 93), (109, 57, 118), (121, 48, 139), + (179, 53, 193), (216, 48, 240), (255, 66, 252), (255, 60, 252), + (244, 48, 241), (224, 32, 248), (221, 48, 246), (240, 92, 233), + (204, 107, 250), (205, 126, 223), (218, 135, 198), (181, 81, 158), + (139, 69, 132), (115, 73, 103), (111, 81, 88), (100, 77, 81), + (97, 75, 81), (101, 80, 78), (105, 83, 78), (107, 84, 79), + (111, 86, 81), (118, 92, 78), (126, 97, 80), (136, 104, 80), + (152, 114, 81), (176, 104, 122), (220, 117, 148), (240, 112, 176), + (248, 104, 210), (229, 116, 212), (229, 125, 201), (243, 116, 174), + (232, 119, 159), (198, 112, 132), (182, 110, 119), (157, 102, 104), + (146, 95, 103), (126, 95, 82), (119, 91, 82), (114, 87, 82), + (112, 86, 82), (117, 89, 81), (120, 86, 90), (120, 91, 83), + (124, 94, 82), (130, 98, 82), (148, 112, 80), (170, 116, 98), + (188, 127, 102), (190, 127, 103), (191, 110, 129), (186, 109, 125), + (161, 101, 110), (152, 98, 105), (149, 96, 105), (142, 91, 104), + (128, 85, 99), (123, 90, 86), (125, 95, 82), (126, 95, 82), + (127, 98, 80), (132, 102, 78), (149, 115, 79), (200, 148, 81) + ), + +// 170 Apophysis-040426-163SprngFlwersInv +((147, 173, 173), (147, 173, 173), (142, 174, 166), (137, 175, 160), + (127, 170, 156), (117, 166, 152), (111, 162, 151), (106, 159, 150), + (68, 159, 110), (42, 158, 85), (17, 158, 61), (20, 179, 46), + (23, 201, 32), (29, 209, 17), (36, 218, 3), (32, 203, 13), + (29, 189, 24), (0, 151, 54), (21, 142, 87), (43, 134, 120), + (65, 143, 130), (87, 153, 140), (94, 154, 145), (102, 156, 150), + (105, 158, 150), (92, 158, 137), (80, 158, 125), (60, 147, 119), + (40, 137, 114), (31, 136, 106), (22, 135, 98), (1, 126, 85), + (1, 144, 63), (33, 143, 29), (37, 134, 37), (41, 125, 46), + (56, 141, 82), (72, 157, 118), (84, 157, 130), (97, 157, 143), + (104, 157, 151), (106, 159, 150), (109, 161, 150), (119, 160, 161), + (129, 160, 173), (129, 159, 173), (129, 159, 173), (127, 158, 174), + (124, 156, 173), (107, 160, 150), (107, 160, 150), (108, 160, 150), + (114, 163, 151), (120, 167, 153), (124, 169, 155), (129, 171, 157), + (133, 174, 156), (135, 176, 156), (138, 178, 156), (142, 180, 157), + (146, 182, 159), (151, 189, 155), (157, 196, 151), (165, 200, 153), + (193, 226, 147), (200, 235, 142), (180, 217, 146), (161, 199, 150), + (150, 191, 150), (139, 183, 150), (107, 207, 88), (57, 207, 90), + (14, 207, 43), (8, 194, 27), (2, 181, 11), (33, 150, 20), + (64, 120, 30), (59, 113, 43), (55, 107, 56), (55, 105, 60), + (37, 108, 73), (30, 105, 150), (46, 116, 150), (62, 127, 150), + (65, 127, 152), (68, 128, 154), (95, 135, 174), (110, 143, 177), + (133, 161, 175), (134, 161, 175), (135, 162, 176), (133, 161, 174), + (131, 161, 173), (130, 168, 163), (131, 177, 150), (130, 207, 111), + (73, 204, 57), (35, 236, 19), (58, 187, 16), (82, 139, 13), + (94, 123, 8), (106, 108, 3), (128, 116, 28), (112, 104, 3), + (65, 125, 22), (49, 153, 35), (34, 181, 48), (55, 188, 58), + (76, 196, 69), (97, 207, 77), (139, 207, 121), (133, 178, 151), + (133, 168, 165), (128, 158, 174), (125, 156, 173), (123, 155, 173), + (115, 149, 173), (108, 143, 176), (112, 146, 174), (132, 159, 177), + (176, 191, 176), (214, 199, 206), (252, 207, 236), (253, 207, 237), + (255, 207, 239), (224, 207, 208), (186, 200, 176), (174, 192, 173), + (163, 183, 174), (151, 175, 174), (149, 174, 173), (147, 173, 173), + (147, 171, 176), (149, 174, 174), (149, 182, 162), (146, 198, 137), + (76, 202, 62), (38, 195, 32), (0, 189, 3), (0, 192, 3), + (0, 195, 3), (11, 207, 14), (31, 223, 7), (34, 207, 9), + (15, 163, 22), (50, 129, 32), (43, 124, 44), (37, 120, 57), + (74, 174, 97), (116, 186, 123), (140, 182, 152), (144, 174, 167), + (158, 180, 174), (156, 177, 175), (154, 175, 177), (150, 172, 177), + (148, 171, 176), (144, 169, 174), (137, 163, 177), (129, 158, 175), + (119, 151, 175), (79, 151, 133), (57, 144, 120), (35, 138, 107), + (15, 143, 79), (7, 151, 45), (26, 139, 43), (26, 130, 54), + (23, 136, 96), (40, 139, 109), (57, 143, 123), (73, 145, 136), + (98, 153, 151), (109, 160, 152), (129, 160, 173), (136, 164, 173), + (141, 168, 173), (143, 169, 173), (138, 166, 174), (135, 169, 165), + (135, 164, 172), (131, 161, 173), (125, 157, 173), (107, 143, 175), + (67, 128, 153), (66, 128, 152), (65, 128, 152), (64, 145, 126), + (69, 146, 130), (94, 154, 145), (103, 157, 150), (106, 159, 150), + (113, 164, 151), (127, 170, 156), (132, 165, 169), (130, 160, 173), + (129, 160, 173), (128, 157, 175), (123, 153, 177), (106, 140, 176), + (55, 107, 174), (78, 123, 173), (46, 140, 21), (69, 177, 88), + (93, 186, 100), (120, 179, 136), (121, 170, 150), (121, 169, 150), + (116, 165, 152), (113, 164, 150), (108, 160, 150), (109, 161, 150), + (123, 171, 151), (127, 174, 150), (137, 177, 157), (152, 176, 174), + (162, 183, 174), (169, 187, 175), (178, 195, 173), (179, 195, 174), + (180, 199, 171), (185, 201, 172), (196, 208, 173), (209, 215, 177), + (203, 216, 169), (192, 222, 150), (172, 207, 156), (170, 204, 152), + (165, 186, 172), (147, 180, 162), (131, 174, 155), (120, 168, 152), + (103, 157, 150), (67, 135, 144), (29, 120, 127), (7, 115, 95), + (8, 112, 115), (18, 104, 138), (39, 110, 150), (68, 115, 174), + (76, 121, 174), (72, 119, 173), (59, 109, 174), (68, 115, 174), + (77, 121, 175), (83, 126, 174), (91, 132, 173), (108, 142, 177), + (116, 148, 176), (129, 159, 174), (133, 162, 174), (135, 163, 174), + (135, 163, 174), (136, 164, 173), (143, 168, 176), (146, 171, 175) + ), + +// 171 Apophysis-040426-163DemMask +((1, 1, 1), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (5, 7, 4), (63, 74, 49), (121, 142, 95), (166, 145, 116), + (212, 149, 138), (136, 104, 99), (60, 60, 60), (32, 32, 31), + (4, 5, 2), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (6, 5, 3), (12, 11, 7), (49, 38, 23), (87, 65, 40), + (205, 183, 66), (223, 208, 71), (242, 234, 76), (247, 243, 88), + (252, 253, 101), (250, 250, 99), (249, 248, 97), (250, 237, 76), + (242, 223, 70), (250, 170, 94), (232, 201, 107), (214, 233, 120), + (222, 227, 140), (230, 222, 161), (225, 235, 199), (250, 218, 181), + (253, 252, 131), (242, 242, 103), (231, 233, 75), (183, 186, 71), + (135, 139, 68), (104, 104, 48), (73, 69, 29), (10, 10, 5), + (1, 1, 0), (7, 7, 4), (97, 18, 30), (188, 29, 56), + (215, 36, 49), (242, 43, 42), (255, 86, 25), (252, 91, 40), + (176, 173, 54), (178, 173, 94), (181, 173, 134), (181, 159, 143), + (181, 146, 152), (135, 118, 118), (34, 97, 129), (2, 29, 17), + (0, 1, 1), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (3, 1, 2), (193, 25, 48), (217, 31, 52), (242, 38, 56), + (242, 10, 103), (242, 2, 137), (242, 4, 145), (242, 59, 150), + (206, 169, 76), (211, 195, 68), (216, 221, 60), (176, 204, 56), + (136, 187, 52), (89, 89, 48), (33, 33, 18), (3, 3, 2), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 1, 1), (4, 4, 2), (8, 7, 3), (45, 46, 46), + (162, 72, 80), (238, 45, 63), (224, 57, 87), (184, 81, 103), + (143, 83, 94), (51, 38, 26), (4, 3, 2), (14, 0, 5), + (81, 6, 54), (114, 66, 99), (153, 93, 115), (82, 63, 80), + (2, 2, 1), (1, 1, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 1, 0), (6, 6, 4), (48, 50, 70), (15, 91, 118), + (22, 59, 95), (10, 10, 9), (1, 1, 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), (3, 1, 1), (23, 7, 2), (114, 72, 54), + (188, 149, 74), (228, 194, 116), (235, 225, 137), (225, 190, 172), + (216, 129, 152), (252, 98, 152), (238, 57, 168), (233, 1, 149), + (216, 12, 92), (181, 26, 103), (0, 0, 0), (28, 51, 43) + ), + +// 172 Apophysis-040426-163ResurectTree +((103, 134, 255), (95, 126, 248), (89, 120, 242), (83, 114, 236), + (72, 103, 225), (62, 93, 215), (53, 84, 206), (45, 76, 198), + (6, 24, 146), (20, 44, 166), (34, 65, 187), (49, 80, 202), + (65, 96, 218), (91, 122, 229), (118, 149, 240), (127, 158, 231), + (136, 167, 222), (161, 192, 197), (164, 195, 193), (168, 199, 190), + (174, 205, 183), (181, 212, 177), (185, 216, 172), (190, 221, 168), + (206, 237, 152), (228, 233, 130), (250, 230, 108), (248, 223, 101), + (247, 216, 94), (246, 215, 93), (246, 215, 93), (244, 213, 91), + (244, 213, 91), (215, 184, 62), (225, 194, 72), (236, 205, 83), + (239, 221, 99), (242, 238, 116), (236, 243, 121), (231, 249, 127), + (207, 238, 151), (215, 246, 143), (223, 254, 135), (221, 252, 136), + (220, 251, 138), (217, 248, 140), (215, 246, 143), (214, 245, 144), + (199, 230, 159), (188, 219, 170), (184, 215, 174), (180, 211, 178), + (170, 201, 187), (161, 192, 197), (152, 183, 205), (144, 175, 214), + (118, 149, 240), (112, 143, 245), (107, 138, 251), (102, 133, 251), + (98, 129, 251), (101, 132, 252), (105, 136, 253), (114, 145, 244), + (125, 156, 233), (150, 181, 208), (164, 195, 194), (178, 209, 180), + (184, 215, 173), (191, 222, 167), (193, 224, 165), (189, 220, 169), + (178, 209, 180), (167, 198, 190), (157, 188, 201), (152, 183, 205), + (148, 179, 210), (152, 183, 206), (156, 187, 202), (169, 200, 189), + (184, 215, 174), (198, 229, 160), (203, 234, 155), (208, 239, 150), + (204, 235, 153), (201, 232, 157), (199, 230, 159), (198, 229, 160), + (185, 216, 173), (181, 212, 177), (177, 208, 181), (173, 204, 184), + (170, 201, 188), (164, 195, 194), (153, 184, 205), (139, 170, 219), + (128, 159, 230), (109, 140, 249), (92, 123, 239), (76, 107, 229), + (71, 102, 224), (67, 98, 220), (64, 95, 217), (51, 82, 204), + (44, 75, 197), (56, 87, 209), (69, 100, 222), (79, 110, 232), + (89, 120, 242), (118, 149, 240), (140, 171, 218), (164, 195, 194), + (183, 214, 175), (205, 236, 153), (225, 235, 132), (246, 234, 112), + (166, 135, 13), (161, 130, 8), (151, 120, 1), (144, 113, 8), + (85, 54, 67), (60, 60, 128), (36, 67, 189), (41, 72, 194), + (46, 77, 199), (61, 92, 214), (65, 96, 218), (68, 99, 221), + (71, 102, 224), (75, 106, 228), (77, 108, 230), (79, 110, 232), + (80, 111, 233), (86, 117, 239), (87, 118, 240), (90, 121, 243), + (93, 124, 246), (88, 119, 241), (83, 114, 236), (81, 112, 234), + (80, 111, 233), (74, 105, 227), (69, 100, 222), (65, 96, 218), + (54, 85, 207), (51, 82, 204), (55, 86, 208), (60, 91, 213), + (67, 98, 220), (75, 106, 228), (83, 114, 236), (91, 122, 244), + (90, 121, 243), (87, 118, 240), (85, 116, 238), (81, 112, 234), + (80, 111, 233), (79, 110, 232), (80, 111, 233), (85, 116, 238), + (92, 123, 245), (106, 137, 252), (107, 138, 250), (109, 140, 249), + (111, 142, 247), (113, 144, 245), (114, 145, 244), (115, 146, 243), + (118, 149, 240), (119, 150, 239), (120, 151, 238), (125, 156, 233), + (124, 155, 234), (120, 151, 238), (118, 149, 240), (118, 149, 240), + (118, 149, 240), (118, 149, 240), (122, 153, 236), (126, 157, 232), + (128, 159, 230), (138, 169, 220), (151, 182, 207), (158, 189, 200), + (175, 206, 183), (177, 208, 180), (180, 211, 178), (184, 215, 174), + (186, 217, 172), (189, 220, 169), (191, 222, 167), (196, 227, 162), + (199, 230, 159), (205, 236, 153), (219, 250, 139), (231, 249, 127), + (242, 238, 116), (249, 231, 109), (255, 225, 103), (251, 220, 98), + (251, 220, 98), (250, 230, 108), (234, 246, 124), (233, 247, 125), + (230, 250, 128), (206, 237, 152), (194, 225, 164), (180, 211, 178), + (164, 195, 194), (146, 177, 212), (127, 158, 231), (118, 149, 240), + (111, 142, 247), (108, 139, 250), (103, 134, 255), (101, 132, 254), + (103, 134, 255), (105, 136, 253), (106, 137, 252), (107, 138, 251), + (105, 136, 253), (102, 133, 255), (102, 133, 255), (102, 133, 255), + (101, 132, 254), (101, 132, 254), (101, 132, 254), (104, 135, 254), + (107, 138, 251), (110, 141, 248), (114, 145, 244), (117, 148, 241), + (117, 148, 241), (118, 149, 240), (118, 149, 240), (118, 149, 240), + (118, 149, 240), (123, 154, 235), (126, 157, 232), (135, 166, 223), + (142, 173, 216), (145, 176, 213), (150, 181, 208), (143, 174, 215), + (135, 166, 223), (129, 160, 229), (127, 158, 231), (126, 157, 232), + (126, 157, 232), (126, 157, 232), (131, 162, 227), (145, 176, 213), + (160, 191, 198), (168, 199, 190), (208, 239, 150), (186, 217, 172) + ), + +// 173 Apophysis-040426-163GldBlue +((152, 121, 0), (160, 129, 7), (166, 135, 13), (172, 141, 19), + (182, 151, 29), (193, 162, 40), (201, 170, 48), (210, 179, 57), + (249, 231, 109), (235, 210, 88), (221, 190, 68), (205, 174, 52), + (190, 159, 37), (163, 132, 26), (137, 106, 15), (128, 97, 24), + (119, 88, 33), (94, 63, 58), (90, 59, 61), (87, 56, 65), + (80, 49, 71), (74, 43, 78), (69, 38, 82), (65, 34, 87), + (49, 18, 103), (27, 21, 125), (5, 25, 147), (6, 32, 154), + (8, 39, 161), (8, 39, 161), (9, 40, 162), (11, 42, 164), + (11, 42, 164), (40, 71, 193), (29, 60, 182), (19, 50, 172), + (16, 33, 155), (13, 17, 139), (18, 11, 133), (24, 6, 128), + (48, 17, 104), (40, 9, 112), (32, 1, 120), (33, 2, 118), + (35, 4, 117), (37, 6, 114), (40, 9, 112), (41, 10, 111), + (56, 25, 96), (67, 36, 85), (71, 40, 81), (75, 44, 77), + (84, 53, 67), (94, 63, 58), (102, 71, 49), (111, 80, 41), + (137, 106, 15), (142, 111, 9), (148, 117, 4), (152, 121, 4), + (157, 126, 4), (153, 122, 3), (150, 119, 2), (141, 110, 11), + (130, 99, 22), (105, 74, 47), (91, 60, 61), (77, 46, 75), + (70, 39, 81), (64, 33, 88), (62, 31, 90), (66, 35, 86), + (77, 46, 75), (87, 56, 64), (98, 67, 54), (102, 71, 49), + (107, 76, 45), (103, 72, 49), (99, 68, 53), (86, 55, 66), + (71, 40, 81), (57, 26, 95), (52, 21, 100), (47, 16, 105), + (50, 19, 101), (54, 23, 98), (56, 25, 96), (57, 26, 95), + (70, 39, 82), (74, 43, 78), (78, 47, 74), (81, 50, 70), + (85, 54, 67), (91, 60, 61), (102, 71, 50), (116, 85, 36), + (127, 96, 25), (146, 115, 6), (162, 131, 16), (179, 148, 26), + (183, 152, 30), (188, 157, 35), (191, 160, 38), (204, 173, 51), + (211, 180, 58), (198, 167, 45), (186, 155, 33), (176, 145, 23), + (166, 135, 13), (137, 106, 15), (115, 84, 37), (91, 60, 61), + (72, 41, 80), (50, 19, 102), (29, 20, 122), (9, 21, 143), + (89, 120, 242), (94, 125, 247), (104, 135, 254), (111, 142, 247), + (170, 201, 188), (194, 194, 127), (219, 188, 66), (214, 183, 61), + (209, 178, 56), (194, 163, 41), (190, 159, 37), (187, 156, 34), + (184, 153, 31), (180, 149, 27), (178, 147, 25), (176, 145, 23), + (175, 144, 22), (169, 138, 16), (168, 137, 15), (165, 134, 12), + (162, 131, 9), (167, 136, 14), (172, 141, 19), (173, 142, 20), + (175, 144, 22), (181, 150, 28), (186, 155, 33), (190, 159, 37), + (201, 170, 48), (204, 173, 51), (199, 168, 46), (195, 164, 42), + (188, 157, 35), (180, 149, 27), (172, 141, 19), (164, 133, 11), + (165, 134, 12), (167, 136, 14), (170, 139, 17), (174, 143, 21), + (175, 144, 22), (176, 145, 23), (175, 144, 22), (170, 139, 17), + (163, 132, 10), (149, 118, 3), (147, 116, 4), (146, 115, 6), + (144, 113, 8), (142, 111, 10), (141, 110, 11), (140, 109, 12), + (137, 106, 15), (136, 105, 16), (135, 104, 17), (130, 99, 22), + (131, 100, 21), (135, 104, 17), (137, 106, 15), (137, 106, 15), + (137, 106, 15), (137, 106, 15), (133, 102, 19), (129, 98, 23), + (127, 96, 25), (117, 86, 35), (104, 73, 48), (97, 66, 55), + (80, 49, 72), (77, 46, 74), (75, 44, 77), (71, 40, 81), + (69, 38, 83), (66, 35, 86), (64, 33, 88), (59, 28, 93), + (56, 25, 96), (50, 19, 102), (36, 5, 116), (24, 6, 128), + (13, 17, 139), (6, 24, 146), (0, 30, 152), (4, 35, 157), + (4, 35, 157), (5, 25, 147), (21, 9, 131), (22, 8, 130), + (25, 5, 127), (49, 18, 103), (61, 30, 91), (75, 44, 77), + (91, 60, 61), (109, 78, 43), (128, 97, 24), (137, 106, 15), + (144, 113, 8), (147, 116, 5), (152, 121, 0), (154, 123, 1), + (152, 121, 0), (150, 119, 2), (149, 118, 3), (148, 117, 4), + (150, 119, 2), (153, 122, 0), (153, 122, 0), (153, 122, 0), + (154, 123, 1), (154, 123, 1), (154, 123, 1), (151, 120, 1), + (148, 117, 4), (145, 114, 7), (141, 110, 11), (138, 107, 14), + (138, 107, 14), (137, 106, 15), (137, 106, 15), (137, 106, 15), + (137, 106, 15), (132, 101, 20), (129, 98, 23), (120, 89, 32), + (113, 82, 39), (110, 79, 42), (105, 74, 47), (112, 81, 40), + (120, 89, 32), (126, 95, 26), (128, 97, 24), (129, 98, 23), + (129, 98, 23), (129, 98, 23), (124, 93, 28), (110, 79, 42), + (95, 64, 57), (87, 56, 65), (47, 16, 105), (69, 38, 83) + ), + +// 174 Apophysis-040426-163WrldBndr +((232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (55, 12, 9), (54, 11, 9), (54, 11, 10), + (76, 33, 21), (98, 55, 33), (165, 122, 100), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (98, 55, 33), (98, 55, 33), (98, 55, 33), (165, 122, 100), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (98, 55, 33), + (98, 55, 33), (73, 73, 73), (48, 91, 113), (61, 104, 126), + (94, 137, 159), (183, 226, 248), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (98, 55, 33), + (98, 55, 33), (95, 52, 30), (89, 46, 24), (89, 46, 24), + (89, 46, 24), (92, 49, 27), (95, 52, 30), (98, 55, 33), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167), + (232, 189, 167), (232, 189, 167), (232, 189, 167), (232, 189, 167) + ), + +// 175 Apophysis-040426-163GrnPrpl +((85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (77, 19, 74), (69, 11, 66), (61, 3, 58), + (37, 20, 34), (5, 52, 2), (5, 52, 2), (5, 52, 2), + (29, 28, 26), (53, 4, 50), (57, 3, 54), (61, 3, 58), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (133, 75, 130), (133, 75, 130), (133, 75, 130), (109, 51, 106), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (42, 100, 45), + (26, 84, 29), (26, 84, 29), (26, 84, 29), (34, 92, 37), + (42, 100, 45), (42, 100, 45), (42, 100, 45), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (101, 43, 98), (121, 63, 118), (141, 83, 138), + (157, 99, 154), (173, 115, 170), (189, 131, 186), (221, 163, 218), + (146, 204, 149), (122, 180, 125), (98, 156, 101), (90, 148, 93), + (42, 100, 45), (26, 84, 29), (10, 68, 13), (5, 52, 2), + (21, 36, 18), (53, 4, 50), (61, 3, 58), (77, 19, 74), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (77, 19, 74), (61, 3, 58), + (29, 28, 26), (21, 36, 18), (21, 36, 18), (29, 28, 26), + (61, 3, 58), (69, 11, 66), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82), + (85, 27, 82), (85, 27, 82), (85, 27, 82), (85, 27, 82) + ), + +// 176 Apophysis-040426-163SphPart2 +((81, 83, 26), (72, 80, 20), (67, 78, 17), (63, 77, 14), + (61, 76, 13), (60, 76, 12), (60, 76, 12), (60, 76, 12), + (57, 75, 10), (57, 75, 10), (57, 75, 10), (57, 75, 10), + (57, 75, 10), (55, 74, 9), (54, 74, 8), (54, 74, 8), + (54, 74, 8), (54, 74, 8), (58, 75, 11), (63, 77, 14), + (69, 79, 18), (75, 81, 22), (76, 81, 23), (78, 82, 24), + (84, 84, 28), (85, 84, 29), (87, 85, 30), (87, 85, 30), + (87, 85, 30), (85, 84, 29), (84, 84, 28), (78, 82, 24), + (72, 80, 20), (75, 81, 22), (78, 82, 24), (81, 83, 26), + (82, 83, 27), (84, 84, 28), (84, 84, 28), (84, 84, 28), + (84, 84, 28), (81, 83, 26), (78, 82, 24), (75, 81, 22), + (72, 80, 20), (70, 79, 19), (69, 79, 18), (66, 78, 16), + (66, 78, 16), (72, 80, 20), (73, 80, 21), (75, 81, 22), + (76, 81, 23), (78, 82, 24), (78, 82, 24), (78, 82, 24), + (75, 81, 22), (73, 80, 21), (72, 80, 20), (72, 80, 20), + (72, 80, 20), (72, 80, 20), (72, 80, 20), (72, 80, 20), + (72, 80, 20), (72, 80, 20), (72, 80, 20), (72, 80, 20), + (72, 80, 20), (72, 80, 20), (72, 80, 20), (72, 80, 20), + (75, 81, 22), (78, 82, 24), (81, 83, 26), (78, 82, 24), + (75, 81, 22), (75, 81, 22), (75, 81, 22), (78, 82, 24), + (81, 83, 26), (81, 83, 26), (82, 83, 27), (84, 84, 28), + (84, 84, 28), (84, 84, 28), (84, 84, 28), (81, 83, 26), + (81, 83, 26), (82, 83, 27), (84, 84, 28), (87, 85, 30), + (90, 86, 32), (108, 92, 44), (144, 104, 68), (186, 118, 96), + (190, 163, 186), (73, 202, 247), (119, 186, 224), (166, 171, 202), + (175, 168, 196), (184, 165, 190), (208, 157, 174), (253, 142, 144), + (237, 135, 130), (181, 116, 93), (126, 98, 56), (114, 94, 48), + (102, 90, 40), (87, 85, 30), (81, 83, 26), (75, 81, 22), + (72, 80, 20), (72, 80, 20), (72, 80, 20), (72, 80, 20), + (72, 80, 20), (69, 79, 18), (66, 78, 16), (63, 77, 14), + (60, 76, 12), (63, 77, 14), (66, 78, 16), (67, 78, 17), + (69, 79, 18), (69, 79, 18), (69, 79, 18), (72, 80, 20), + (72, 80, 20), (72, 80, 20), (72, 80, 20), (72, 80, 20), + (72, 80, 20), (72, 80, 20), (72, 80, 20), (75, 81, 22), + (81, 83, 26), (87, 85, 30), (93, 87, 34), (106, 91, 43), + (120, 96, 52), (141, 103, 66), (186, 118, 96), (208, 157, 174), + (199, 160, 180), (250, 143, 146), (251, 142, 145), (253, 142, 144), + (241, 146, 152), (193, 162, 184), (172, 169, 198), (163, 172, 204), + (181, 166, 192), (190, 163, 186), (199, 160, 180), (225, 131, 122), + (159, 109, 78), (120, 96, 52), (96, 88, 36), (87, 85, 30), + (87, 85, 30), (99, 89, 38), (109, 92, 45), (120, 96, 52), + (37, 214, 223), (34, 215, 221), (31, 216, 219), (28, 217, 217), + (34, 215, 221), (43, 212, 227), (52, 209, 233), (147, 105, 70), + (129, 99, 58), (174, 114, 88), (219, 129, 118), (240, 136, 132), + (246, 138, 136), (199, 160, 180), (190, 163, 186), (187, 164, 188), + (193, 162, 184), (180, 116, 92), (132, 100, 60), (111, 93, 46), + (93, 87, 34), (100, 89, 39), (108, 92, 44), (135, 101, 62), + (180, 116, 92), (234, 134, 128), (234, 134, 128), (171, 113, 86), + (132, 100, 60), (108, 92, 44), (90, 86, 32), (81, 83, 26), + (72, 80, 20), (66, 78, 16), (60, 76, 12), (60, 76, 12), + (60, 76, 12), (60, 76, 12), (60, 76, 12), (63, 77, 14), + (63, 77, 14), (63, 77, 14), (63, 77, 14), (63, 77, 14), + (66, 78, 16), (69, 79, 18), (72, 80, 20), (72, 80, 20), + (69, 79, 18), (66, 78, 16), (63, 77, 14), (66, 78, 16), + (69, 79, 18), (69, 79, 18), (69, 79, 18), (72, 80, 20), + (72, 80, 20), (72, 80, 20), (72, 80, 20), (72, 80, 20), + (69, 79, 18), (66, 78, 16), (63, 77, 14), (63, 77, 14), + (63, 77, 14), (63, 77, 14), (63, 77, 14), (66, 78, 16), + (69, 79, 18), (69, 79, 18), (69, 79, 18), (69, 79, 18), + (72, 80, 20), (72, 80, 20), (75, 81, 22), (78, 82, 24), + (81, 83, 26), (84, 84, 28), (84, 84, 28), (84, 84, 28), + (81, 83, 26), (78, 82, 24), (75, 81, 22), (72, 80, 20), + (72, 80, 20), (75, 81, 22), (81, 83, 26), (87, 85, 30), + (105, 91, 42), (123, 97, 54), (216, 128, 116), (150, 106, 72) + ), + +// 177 Apophysis-040426-163StAmF +((0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (66, 36, 8), + (133, 72, 16), (115, 96, 84), (98, 121, 152), (100, 132, 158), + (103, 144, 165), (114, 178, 190), (118, 186, 199), (122, 194, 209), + (117, 189, 201), (113, 185, 194), (99, 171, 174), (86, 158, 155), + (121, 133, 30), (125, 125, 20), (130, 118, 10), (130, 108, 21), + (130, 99, 33), (132, 104, 32), (134, 110, 32), (140, 111, 37), + (146, 120, 151), (129, 168, 196), (138, 184, 209), (148, 201, 223), + (119, 170, 187), (90, 139, 151), (107, 127, 93), (124, 116, 36), + (141, 88, 34), (137, 94, 99), (134, 100, 164), (131, 108, 169), + (129, 116, 174), (131, 107, 168), (133, 99, 162), (123, 92, 152), + (138, 75, 36), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (141, 61, 31), (141, 72, 40), + (109, 113, 158), (105, 128, 161), (102, 144, 164), (94, 148, 159), + (87, 152, 154), (89, 157, 158), (91, 163, 163), (89, 166, 163), + (94, 170, 169), (106, 166, 177), (105, 160, 174), (105, 155, 171), + (108, 151, 172), (112, 147, 174), (108, 146, 170), (104, 145, 166), + (88, 140, 150), (48, 113, 75), (9, 87, 0), (4, 43, 0), + (0, 0, 0), (0, 0, 0), (140, 70, 28), (136, 85, 39), + (106, 108, 153), (96, 128, 153), (92, 127, 149), (89, 126, 146), + (130, 102, 39), (135, 81, 31), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (135, 61, 21), (169, 105, 142), (182, 114, 153), (195, 124, 164), + (150, 111, 180), (150, 119, 159), (156, 133, 157), (139, 147, 51), + (134, 78, 22), (67, 39, 11), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (119, 123, 34), (101, 130, 90), (84, 138, 146), + (91, 146, 155), (92, 146, 156), (97, 127, 154), (105, 111, 154), + (139, 66, 26), (69, 33, 13), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (144, 60, 35), (144, 61, 36), + (138, 79, 39), (117, 90, 148), (125, 108, 167), (149, 110, 179), + (166, 122, 196), (170, 121, 192), (184, 143, 190), (185, 158, 183), + (186, 196, 157), (181, 193, 152), (177, 191, 147), (115, 157, 181), + (113, 129, 168), (97, 105, 145), (55, 34, 38), (0, 0, 0), + (0, 0, 0), (85, 103, 20), (116, 115, 19), (127, 125, 30), + (172, 172, 156), (153, 163, 210), (169, 194, 254), (176, 224, 252), + (159, 195, 251), (165, 195, 254), (180, 179, 246), (205, 153, 213), + (187, 152, 196), (180, 156, 177), (181, 173, 169), (181, 183, 163), + (199, 185, 155), (203, 192, 153), (217, 179, 180), (216, 202, 182), + (215, 211, 183), (214, 225, 222), (225, 234, 237), (218, 206, 253), + (213, 203, 253), (216, 162, 222), (182, 138, 191), (140, 115, 180), + (130, 119, 176), (103, 129, 160), (125, 135, 179), (151, 157, 206), + (174, 184, 230), (188, 215, 246), (209, 229, 241), (238, 223, 225), + (241, 182, 244), (253, 177, 254), (228, 157, 243), (211, 150, 223), + (155, 162, 211), (119, 165, 187), (95, 156, 163), (87, 142, 150), + (115, 133, 36), (125, 113, 30), (125, 115, 39), (106, 114, 156), + (122, 103, 162), (122, 91, 151), (141, 69, 39), (144, 60, 35), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (67, 38, 38), (112, 90, 147), (138, 105, 153) + ), + +// 178 Apophysis-040426-163StCosOwl +((90, 143, 129), (43, 93, 69), (45, 69, 77), (48, 45, 86), + (53, 49, 107), (58, 53, 128), (51, 42, 151), (44, 32, 175), + (25, 20, 87), (23, 10, 57), (22, 0, 28), (14, 2, 19), + (6, 5, 11), (21, 12, 8), (37, 20, 5), (45, 19, 2), + (53, 19, 0), (75, 30, 8), (70, 49, 37), (65, 68, 66), + (73, 72, 105), (81, 76, 145), (94, 87, 181), (108, 98, 217), + (184, 172, 255), (214, 200, 255), (244, 228, 255), (241, 225, 255), + (238, 222, 255), (234, 218, 255), (231, 215, 255), (211, 196, 255), + (177, 165, 255), (105, 91, 255), (94, 84, 202), (84, 78, 150), + (98, 91, 175), (113, 105, 201), (130, 120, 223), (147, 135, 246), + (185, 172, 255), (209, 194, 255), (233, 217, 255), (243, 226, 255), + (253, 236, 255), (254, 238, 255), (255, 241, 255), (255, 249, 255), + (255, 254, 255), (255, 255, 255), (255, 253, 255), (255, 251, 255), + (255, 245, 255), (255, 240, 255), (251, 235, 255), (247, 230, 255), + (184, 171, 255), (141, 131, 214), (98, 91, 174), (132, 116, 155), + (167, 141, 137), (191, 158, 144), (215, 176, 152), (245, 196, 162), + (236, 234, 233), (201, 187, 255), (163, 152, 238), (125, 117, 222), + (98, 92, 175), (72, 67, 128), (40, 37, 79), (23, 26, 31), + (4, 4, 7), (24, 10, 7), (45, 17, 7), (76, 34, 12), + (107, 52, 18), (103, 59, 35), (100, 66, 53), (76, 67, 63), + (61, 74, 75), (68, 64, 122), (60, 56, 108), (53, 49, 94), + (44, 41, 78), (35, 33, 63), (25, 23, 45), (15, 14, 26), + (21, 6, 0), (33, 9, 4), (46, 13, 9), (30, 6, 21), + (15, 0, 33), (8, 3, 79), (3, 3, 80), (6, 0, 80), + (12, 6, 80), (37, 26, 28), (66, 31, 34), (95, 37, 41), + (100, 50, 51), (106, 64, 61), (92, 70, 67), (112, 95, 91), + (71, 67, 127), (73, 68, 130), (75, 70, 133), (79, 73, 140), + (83, 77, 147), (197, 24, 173), (208, 30, 187), (153, 138, 255), + (173, 161, 255), (182, 169, 255), (183, 170, 255), (184, 172, 255), + (185, 172, 255), (189, 176, 255), (211, 197, 255), (229, 213, 255), + (225, 215, 255), (194, 185, 252), (164, 156, 250), (129, 122, 209), + (95, 88, 168), (71, 67, 127), (42, 38, 90), (26, 25, 47), + (3, 1, 21), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 1), (4, 0, 19), (9, 0, 38), (19, 0, 57), + (29, 0, 76), (41, 0, 72), (37, 0, 93), (42, 0, 91), + (72, 0, 135), (130, 121, 231), (156, 145, 243), (182, 170, 255), + (220, 205, 255), (236, 219, 255), (237, 221, 255), (223, 220, 231), + (132, 129, 161), (101, 98, 142), (71, 67, 124), (34, 31, 60), + (16, 15, 29), (0, 0, 1), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (3, 2, 1), (29, 21, 17), (54, 39, 32), (59, 49, 48), + (33, 31, 59), (32, 30, 57), (31, 29, 55), (20, 19, 36), + (5, 5, 10), (0, 0, 0), (0, 0, 0), (2, 2, 2), + (3, 11, 8), (7, 23, 27), (25, 71, 51), (47, 98, 19), + (75, 112, 17), (107, 121, 15), (136, 86, 63), (152, 111, 90), + (115, 80, 54), (104, 78, 62), (94, 77, 70), (59, 54, 52), + (27, 27, 27), (1, 9, 3), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 1, 7), (19, 18, 34), (48, 45, 86), + (80, 75, 143), (130, 121, 231), (169, 160, 255), (206, 192, 255), + (236, 220, 255), (255, 238, 255), (255, 247, 255), (255, 254, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 250, 248), (255, 255, 219), + (255, 237, 138), (218, 158, 119), (210, 164, 97), (138, 126, 84), + (118, 106, 65), (126, 98, 39), (76, 77, 31), (74, 54, 47), + (44, 41, 67), (29, 27, 52), (41, 38, 73), (69, 64, 78), + (130, 106, 83), (170, 141, 122), (219, 161, 134), (233, 186, 151), + (255, 253, 214), (220, 255, 255), (237, 234, 255), (222, 222, 231), + (140, 245, 157), (108, 172, 113), (127, 127, 79), (139, 117, 113), + (103, 102, 113), (84, 84, 129), (89, 83, 159), (130, 121, 231), + (161, 150, 255), (189, 176, 255), (208, 194, 255), (242, 226, 255), + (251, 234, 255), (255, 239, 255), (255, 240, 255), (255, 241, 255), + (255, 246, 255), (255, 250, 255), (255, 251, 255), (255, 251, 255), + (255, 243, 255), (245, 228, 255), (222, 207, 255), (183, 171, 255) + ), + +// 179 Apophysis-040426-163StGenie +((64, 50, 36), (23, 82, 142), (13, 68, 124), (3, 55, 107), + (32, 45, 59), (61, 36, 12), (71, 39, 7), (81, 42, 3), + (89, 44, 0), (105, 52, 0), (121, 60, 0), (150, 75, 0), + (179, 90, 0), (201, 101, 1), (224, 113, 2), (230, 116, 3), + (236, 120, 4), (254, 139, 25), (254, 143, 32), (254, 147, 39), + (254, 141, 28), (254, 135, 17), (253, 134, 16), (253, 134, 15), + (245, 136, 28), (233, 142, 52), (221, 149, 77), (228, 161, 95), + (235, 174, 114), (243, 175, 108), (251, 176, 102), (249, 165, 81), + (242, 149, 56), (252, 138, 23), (251, 135, 18), (250, 132, 14), + (252, 129, 7), (254, 127, 0), (252, 126, 0), (251, 125, 0), + (226, 115, 3), (221, 112, 2), (217, 110, 2), (195, 99, 3), + (173, 89, 4), (161, 83, 5), (150, 78, 7), (136, 69, 3), + (135, 68, 0), (149, 77, 5), (173, 88, 2), (198, 99, 0), + (208, 104, 0), (219, 110, 0), (223, 112, 0), (228, 115, 1), + (250, 126, 1), (251, 127, 1), (253, 128, 2), (245, 126, 6), + (237, 124, 10), (231, 120, 8), (225, 116, 7), (204, 107, 10), + (169, 85, 1), (119, 60, 0), (100, 51, 0), (82, 42, 1), + (78, 45, 12), (75, 49, 23), (30, 40, 50), (19, 52, 84), + (49, 111, 173), (63, 89, 115), (78, 68, 58), (133, 82, 32), + (189, 97, 6), (200, 102, 5), (211, 107, 4), (217, 111, 5), + (210, 106, 2), (145, 75, 4), (114, 58, 2), (83, 42, 0), + (75, 43, 10), (68, 45, 21), (19, 39, 59), (5, 48, 92), + (3, 68, 133), (10, 53, 95), (17, 38, 58), (30, 38, 46), + (43, 39, 35), (82, 42, 2), (103, 52, 0), (128, 68, 8), + (146, 85, 24), (211, 173, 135), (206, 169, 132), (201, 166, 130), + (167, 149, 130), (134, 132, 131), (144, 90, 35), (133, 72, 12), + (137, 70, 4), (136, 69, 3), (135, 69, 3), (133, 68, 3), + (132, 67, 3), (128, 66, 3), (121, 61, 2), (118, 59, 0), + (124, 63, 2), (141, 72, 4), (147, 76, 5), (153, 80, 7), + (187, 110, 34), (203, 158, 114), (204, 171, 138), (222, 188, 155), + (251, 202, 153), (249, 188, 127), (247, 175, 102), (231, 155, 79), + (216, 136, 56), (214, 113, 12), (196, 100, 3), (156, 78, 0), + (129, 66, 2), (99, 51, 2), (104, 53, 2), (110, 56, 3), + (127, 65, 3), (149, 75, 1), (187, 94, 0), (202, 101, 0), + (193, 97, 1), (169, 86, 3), (146, 75, 5), (137, 70, 3), + (128, 65, 2), (116, 58, 1), (98, 50, 1), (80, 49, 17), + (73, 71, 69), (90, 152, 213), (78, 155, 231), (67, 158, 249), + (94, 170, 245), (152, 199, 246), (200, 218, 237), (232, 234, 236), + (121, 148, 176), (86, 127, 168), (52, 106, 160), (22, 44, 66), + (90, 70, 49), (98, 58, 17), (118, 60, 1), (152, 76, 0), + (200, 101, 1), (229, 149, 68), (234, 157, 80), (240, 166, 92), + (252, 175, 97), (254, 153, 52), (253, 140, 27), (252, 133, 14), + (236, 119, 2), (228, 115, 1), (221, 111, 0), (207, 103, 0), + (185, 92, 0), (152, 80, 7), (138, 72, 5), (124, 71, 18), + (130, 87, 44), (82, 122, 162), (47, 141, 235), (21, 124, 226), + (8, 110, 213), (1, 122, 244), (1, 127, 253), (55, 147, 239), + (187, 216, 246), (188, 216, 244), (190, 216, 243), (130, 188, 246), + (55, 155, 254), (4, 129, 254), (2, 118, 234), (4, 107, 210), + (5, 105, 205), (6, 105, 204), (0, 89, 177), (0, 87, 173), + (8, 101, 195), (79, 141, 203), (130, 157, 185), (141, 151, 160), + (208, 172, 137), (217, 175, 132), (219, 165, 111), (229, 147, 65), + (229, 127, 25), (229, 118, 7), (225, 113, 1), (231, 117, 4), + (236, 121, 5), (238, 121, 4), (239, 123, 7), (248, 130, 12), + (252, 132, 11), (251, 130, 9), (241, 124, 7), (236, 122, 8), + (223, 114, 4), (222, 111, 1), (198, 100, 2), (161, 82, 4), + (149, 76, 4), (144, 74, 4), (142, 73, 5), (147, 75, 2), + (160, 81, 2), (190, 95, 1), (211, 106, 1), (217, 111, 5), + (215, 109, 3), (198, 99, 0), (160, 81, 2), (150, 77, 3), + (147, 76, 5), (142, 74, 6), (146, 78, 10), (149, 86, 24), + (194, 120, 45), (209, 160, 110), (219, 183, 147), (234, 193, 153), + (254, 217, 181), (225, 211, 197), (227, 225, 222), (252, 222, 192), + (239, 208, 178), (216, 179, 142), (234, 178, 123), (250, 170, 89), + (252, 152, 52), (253, 143, 32), (243, 132, 20), (235, 121, 7), + (229, 119, 8), (215, 132, 50), (196, 148, 101), (174, 138, 102) + ), + +// 180 Apophysis-040426-163St +((79, 122, 116), (102, 152, 145), (90, 137, 130), (78, 122, 116), + (89, 108, 95), (101, 95, 74), (104, 98, 76), (108, 102, 79), + (158, 151, 120), (183, 175, 142), (208, 200, 165), (208, 200, 165), + (209, 201, 166), (195, 188, 153), (182, 175, 140), (166, 159, 127), + (151, 144, 114), (83, 128, 121), (77, 121, 114), (72, 114, 108), + (47, 76, 73), (22, 39, 39), (13, 23, 23), (4, 8, 8), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (16, 17, 12), + (28, 24, 19), (50, 45, 35), (73, 67, 52), (128, 122, 96), + (171, 165, 131), (227, 172, 227), (237, 197, 238), (248, 223, 249), + (245, 231, 245), (242, 239, 241), (236, 238, 238), (254, 240, 223), + (230, 220, 187), (166, 186, 166), (103, 152, 145), (75, 115, 110), + (48, 78, 75), (31, 51, 50), (14, 25, 25), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (2, 4, 5), (2, 5, 3), (2, 6, 2), + (2, 7, 3), (3, 9, 4), (4, 10, 4), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (32, 28, 22), (67, 61, 48), + (156, 149, 118), (184, 176, 143), (212, 204, 169), (212, 204, 169), + (213, 205, 169), (211, 203, 167), (161, 155, 123), (123, 117, 91), + (92, 86, 67), (10, 18, 19), (7, 14, 12), (5, 10, 5), + (11, 20, 21), (40, 36, 28), (47, 78, 74), (66, 99, 93), + (100, 149, 142), (107, 156, 149), (114, 164, 157), (120, 170, 163), + (126, 177, 170), (143, 183, 172), (124, 175, 168), (103, 152, 145), + (127, 121, 94), (46, 41, 32), (31, 27, 21), (17, 14, 11), + (5, 10, 5), (2, 7, 2), (1, 2, 1), (0, 2, 0), + (0, 2, 0), (0, 2, 0), (0, 2, 1), (0, 2, 2), + (2, 4, 4), (3, 6, 7), (5, 10, 5), (4, 8, 9), + (21, 37, 37), (55, 90, 85), (79, 94, 80), (104, 98, 76), + (120, 114, 89), (139, 133, 104), (141, 135, 106), (123, 117, 91), + (97, 91, 71), (96, 90, 70), (96, 90, 70), (72, 83, 70), + (48, 43, 33), (21, 18, 14), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (4, 10, 4), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (11, 9, 7), (46, 41, 32), (85, 79, 61), + (112, 106, 83), (147, 140, 110), (157, 150, 119), (148, 141, 111), + (128, 121, 95), (112, 106, 82), (95, 89, 69), (52, 47, 36), + (23, 19, 15), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (18, 32, 32), (46, 77, 74), (66, 105, 100), (70, 110, 105), + (54, 88, 84), (49, 44, 34), (19, 16, 13), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (5, 10, 5), + (5, 10, 5), (5, 10, 5), (5, 10, 5), (12, 10, 8), + (15, 27, 27), (35, 60, 58), (43, 72, 69), (40, 68, 65), + (27, 46, 45), (15, 26, 27), (5, 10, 5), (5, 10, 5), + (4, 9, 4), (6, 5, 4), (4, 4, 3), (1, 2, 1), + (1, 4, 1), (3, 7, 2), (5, 10, 5), (18, 32, 32), + (16, 48, 112), (61, 99, 94), (82, 126, 120), (95, 89, 69) + ), + +// 181 Apophysis-040426-163StSatAngel +((169, 159, 187), (200, 153, 237), (210, 169, 240), (220, 186, 244), + (228, 185, 237), (237, 184, 231), (244, 184, 216), (252, 184, 201), + (238, 136, 182), (231, 130, 188), (225, 124, 195), (223, 124, 198), + (222, 125, 201), (221, 122, 200), (220, 119, 199), (221, 118, 196), + (223, 118, 194), (241, 126, 165), (242, 128, 140), (243, 131, 116), + (239, 138, 115), (236, 145, 115), (233, 144, 110), (231, 144, 105), + (204, 182, 87), (202, 205, 106), (200, 228, 125), (200, 241, 139), + (200, 255, 153), (200, 252, 157), (201, 249, 161), (207, 241, 152), + (179, 233, 132), (155, 197, 121), (162, 186, 146), (169, 176, 171), + (182, 168, 196), (196, 161, 221), (199, 163, 224), (202, 165, 228), + (219, 170, 253), (230, 183, 245), (241, 197, 237), (242, 192, 229), + (244, 188, 221), (245, 190, 220), (247, 192, 219), (251, 207, 225), + (254, 215, 221), (254, 211, 224), (253, 205, 213), (253, 199, 203), + (253, 182, 192), (253, 166, 181), (253, 161, 175), (254, 157, 170), + (218, 188, 121), (181, 186, 116), (144, 185, 111), (137, 184, 98), + (131, 184, 85), (135, 191, 86), (139, 198, 88), (156, 242, 78), + (160, 254, 74), (167, 225, 56), (171, 218, 57), (175, 211, 59), + (176, 210, 59), (177, 209, 60), (182, 196, 56), (184, 202, 68), + (230, 147, 104), (234, 137, 104), (239, 128, 105), (245, 136, 125), + (251, 145, 145), (250, 157, 157), (250, 170, 169), (255, 190, 198), + (246, 188, 216), (229, 198, 250), (237, 209, 250), (246, 220, 250), + (244, 227, 250), (243, 235, 251), (250, 245, 247), (255, 254, 243), + (224, 217, 239), (221, 208, 233), (218, 199, 227), (223, 209, 228), + (229, 219, 229), (205, 212, 207), (209, 231, 195), (211, 242, 188), + (194, 254, 142), (145, 194, 103), (172, 214, 117), (200, 235, 132), + (206, 234, 143), (212, 233, 155), (212, 255, 176), (230, 246, 222), + (245, 245, 233), (236, 233, 237), (227, 221, 242), (236, 227, 233), + (246, 234, 224), (246, 217, 208), (234, 201, 167), (219, 203, 138), + (214, 205, 130), (202, 238, 140), (194, 229, 150), (187, 220, 161), + (194, 209, 187), (186, 170, 211), (199, 159, 229), (203, 156, 240), + (203, 151, 244), (198, 134, 248), (194, 118, 252), (199, 119, 243), + (204, 121, 234), (210, 119, 221), (222, 121, 198), (246, 134, 164), + (244, 149, 136), (211, 187, 107), (200, 193, 91), (190, 200, 76), + (186, 200, 69), (190, 191, 68), (206, 158, 67), (217, 140, 72), + (231, 137, 97), (231, 145, 106), (232, 153, 115), (231, 155, 116), + (231, 158, 117), (230, 161, 118), (230, 164, 121), (222, 180, 122), + (218, 193, 126), (218, 202, 136), (202, 205, 155), (187, 208, 174), + (206, 205, 215), (210, 182, 227), (210, 170, 239), (203, 154, 241), + (165, 156, 182), (157, 155, 167), (150, 155, 153), (147, 172, 130), + (126, 159, 100), (120, 170, 77), (121, 175, 74), (128, 169, 93), + (121, 168, 80), (120, 201, 45), (138, 219, 46), (156, 238, 47), + (155, 243, 50), (159, 232, 46), (168, 219, 51), (177, 214, 65), + (201, 203, 103), (198, 212, 107), (196, 221, 111), (201, 215, 115), + (207, 210, 121), (214, 198, 123), (215, 194, 121), (223, 184, 128), + (239, 164, 141), (233, 136, 190), (223, 147, 221), (199, 150, 237), + (191, 147, 225), (189, 145, 223), (205, 120, 231), (211, 118, 217), + (237, 128, 175), (236, 128, 178), (235, 129, 181), (157, 157, 165), + (163, 155, 179), (227, 120, 186), (240, 123, 163), (253, 131, 146), + (253, 138, 143), (252, 144, 146), (245, 126, 158), (235, 123, 175), + (230, 120, 181), (218, 119, 203), (208, 119, 225), (204, 121, 235), + (204, 121, 234), (208, 118, 223), (215, 118, 209), (225, 119, 190), + (242, 125, 162), (248, 133, 128), (236, 145, 116), (230, 153, 111), + (228, 161, 115), (227, 173, 124), (235, 181, 149), (245, 164, 195), + (219, 139, 223), (215, 146, 237), (215, 141, 231), (214, 125, 219), + (212, 119, 217), (215, 118, 210), (221, 118, 196), (225, 119, 191), + (231, 120, 179), (255, 151, 159), (251, 155, 174), (249, 182, 178), + (237, 200, 173), (233, 226, 190), (227, 230, 181), (219, 254, 193), + (233, 235, 200), (237, 236, 227), (211, 230, 201), (201, 204, 206), + (168, 189, 155), (146, 184, 115), (136, 196, 84), (131, 220, 49), + (151, 241, 68), (156, 243, 76), (160, 230, 97), (178, 251, 105), + (188, 245, 117), (191, 235, 114), (178, 245, 119), (183, 245, 128), + (169, 205, 141), (171, 184, 166), (242, 142, 179), (248, 135, 160), + (253, 137, 152), (255, 135, 145), (255, 133, 144), (254, 135, 142), + (250, 135, 134), (247, 143, 135), (243, 147, 131), (240, 158, 136) + ), + +// 182 Apophysis-040427-1knotted +((146, 120, 27), (146, 97, 30), (147, 80, 45), (148, 63, 60), + (139, 56, 56), (130, 50, 53), (119, 46, 39), (109, 42, 25), + (95, 56, 17), (80, 53, 28), (65, 51, 40), (91, 74, 47), + (117, 98, 55), (136, 113, 41), (156, 128, 28), (152, 139, 26), + (149, 151, 24), (146, 120, 27), (162, 98, 50), (178, 76, 74), + (190, 45, 111), (202, 15, 148), (219, 12, 179), (237, 9, 210), + (255, 0, 221), (255, 0, 224), (255, 0, 228), (255, 0, 231), + (255, 0, 234), (247, 0, 244), (239, 0, 254), (251, 12, 227), + (246, 3, 219), (219, 15, 172), (187, 19, 154), (156, 24, 136), + (160, 24, 133), (164, 24, 131), (164, 24, 131), (164, 24, 131), + (163, 25, 111), (149, 27, 80), (135, 29, 49), (137, 31, 47), + (139, 33, 45), (134, 33, 42), (129, 34, 40), (127, 37, 37), + (111, 46, 40), (71, 60, 77), (48, 76, 115), (25, 93, 154), + (25, 93, 154), (25, 93, 154), (27, 119, 125), (29, 145, 96), + (44, 125, 84), (65, 85, 76), (87, 45, 69), (107, 37, 59), + (127, 30, 50), (131, 29, 48), (136, 29, 47), (138, 30, 46), + (150, 40, 69), (155, 24, 138), (149, 24, 150), (143, 25, 163), + (145, 26, 159), (148, 27, 156), (148, 28, 136), (163, 26, 132), + (162, 25, 129), (154, 43, 95), (147, 61, 62), (149, 56, 61), + (151, 51, 61), (137, 50, 65), (124, 49, 70), (109, 54, 83), + (106, 55, 74), (64, 154, 102), (92, 157, 65), (121, 161, 28), + (127, 158, 27), (134, 155, 26), (134, 155, 26), (129, 149, 78), + (124, 114, 63), (107, 130, 45), (91, 146, 27), (91, 146, 27), + (91, 146, 27), (96, 111, 42), (75, 88, 60), (78, 46, 85), + (83, 28, 112), (109, 24, 143), (114, 31, 133), (119, 39, 124), + (121, 41, 93), (123, 44, 63), (115, 18, 29), (78, 9, 37), + (59, 9, 12), (42, 48, 31), (26, 88, 51), (28, 115, 64), + (30, 143, 77), (28, 155, 78), (28, 156, 81), (28, 156, 81), + (58, 114, 89), (164, 24, 131), (186, 18, 144), (208, 12, 158), + (223, 16, 192), (238, 8, 202), (214, 9, 176), (175, 20, 148), + (150, 26, 156), (87, 59, 155), (25, 93, 154), (25, 93, 154), + (25, 93, 154), (28, 94, 155), (102, 100, 139), (144, 87, 128), + (152, 53, 120), (185, 22, 69), (169, 43, 61), (154, 64, 53), + (146, 97, 30), (91, 146, 27), (27, 156, 76), (29, 158, 75), + (140, 96, 21), (101, 69, 32), (62, 42, 44), (59, 33, 40), + (57, 25, 36), (59, 63, 74), (66, 73, 79), (74, 87, 96), + (120, 53, 124), (118, 25, 155), (131, 26, 157), (145, 28, 160), + (144, 58, 131), (141, 71, 69), (159, 74, 33), (255, 60, 51), + (190, 24, 74), (183, 19, 84), (176, 15, 95), (147, 56, 63), + (137, 61, 61), (134, 93, 61), (125, 103, 56), (133, 117, 65), + (144, 102, 62), (182, 24, 57), (192, 25, 76), (203, 26, 96), + (216, 68, 152), (249, 199, 211), (202, 147, 168), (128, 126, 137), + (28, 156, 81), (28, 155, 79), (28, 155, 78), (43, 91, 77), + (78, 73, 54), (92, 52, 40), (113, 42, 38), (140, 42, 31), + (155, 53, 30), (155, 73, 33), (159, 88, 46), (160, 86, 49), + (154, 65, 51), (149, 47, 61), (168, 18, 108), (161, 20, 114), + (126, 30, 57), (105, 25, 52), (85, 21, 47), (72, 10, 47), + (38, 21, 27), (31, 15, 0), (1, 10, 27), (39, 26, 35), + (74, 27, 61), (104, 7, 110), (124, 8, 105), (184, 20, 71), + (188, 17, 59), (175, 18, 47), (157, 35, 34), (138, 33, 27), + (130, 11, 5), (117, 1, 22), (119, 10, 3), (109, 41, 4), + (125, 36, 20), (129, 35, 35), (128, 36, 37), (127, 35, 38), + (129, 34, 38), (138, 31, 39), (139, 35, 34), (139, 43, 31), + (159, 54, 22), (156, 71, 30), (157, 100, 31), (188, 117, 29), + (156, 116, 64), (157, 104, 86), (161, 76, 107), (222, 39, 157), + (255, 4, 193), (244, 8, 215), (236, 6, 219), (202, 16, 201), + (150, 31, 159), (153, 29, 141), (150, 46, 123), (131, 53, 75), + (124, 51, 70), (130, 59, 41), (146, 62, 28), (140, 60, 23), + (139, 43, 31), (143, 39, 30), (151, 31, 32), (138, 31, 41), + (140, 32, 45), (138, 31, 41), (138, 31, 41), (138, 31, 41), + (132, 36, 37), (128, 38, 38), (128, 40, 38), (139, 50, 32), + (146, 62, 28), (146, 89, 20), (146, 97, 30), (146, 97, 30), + (157, 100, 31), (146, 120, 27), (146, 120, 27), (146, 120, 27), + (146, 120, 27), (146, 120, 27), (146, 97, 30), (146, 97, 30) + ), + +// 183 Apophysis-040427-4AlngSpder +((88, 35, 3), (69, 26, 7), (67, 25, 6), (65, 24, 6), + (71, 27, 6), (77, 31, 7), (79, 31, 5), (81, 31, 4), + (82, 33, 3), (77, 30, 3), (72, 27, 4), (67, 24, 4), + (63, 22, 4), (62, 22, 6), (62, 23, 8), (67, 24, 6), + (72, 25, 5), (100, 33, 4), (107, 39, 4), (115, 46, 5), + (120, 47, 8), (126, 48, 12), (122, 45, 12), (118, 43, 12), + (100, 40, 16), (92, 38, 11), (85, 36, 6), (86, 35, 3), + (88, 34, 0), (87, 32, 0), (87, 31, 0), (83, 32, 1), + (83, 34, 4), (77, 33, 8), (77, 30, 7), (78, 27, 6), + (80, 28, 7), (82, 30, 8), (82, 31, 8), (83, 33, 8), + (102, 48, 10), (115, 54, 18), (129, 60, 27), (131, 62, 22), + (133, 65, 18), (134, 63, 17), (136, 62, 17), (131, 61, 12), + (121, 57, 11), (113, 46, 0), (116, 44, 0), (119, 43, 0), + (123, 47, 0), (127, 52, 0), (133, 55, 0), (140, 58, 0), + (127, 49, 13), (116, 47, 12), (105, 45, 11), (101, 45, 11), + (98, 45, 11), (96, 41, 7), (94, 38, 3), (102, 36, 0), + (109, 36, 0), (109, 41, 6), (102, 41, 8), (95, 42, 10), + (91, 41, 8), (87, 41, 7), (81, 36, 3), (73, 29, 2), + (60, 23, 5), (59, 21, 3), (58, 19, 2), (61, 20, 3), + (64, 21, 4), (64, 21, 4), (64, 21, 5), (58, 20, 7), + (57, 21, 5), (40, 27, 0), (42, 21, 2), (45, 15, 5), + (47, 14, 2), (49, 13, 0), (56, 17, 2), (61, 21, 11), + (82, 34, 11), (99, 47, 19), (117, 61, 28), (127, 65, 27), + (137, 70, 27), (129, 88, 32), (133, 74, 16), (132, 70, 13), + (133, 60, 7), (124, 57, 4), (124, 57, 7), (125, 57, 10), + (131, 59, 10), (138, 62, 10), (146, 75, 13), (161, 89, 17), + (251, 49, 39), (215, 90, 51), (179, 132, 64), (174, 112, 41), + (170, 92, 18), (145, 91, 17), (147, 76, 14), (154, 68, 7), + (155, 59, 19), (128, 60, 13), (125, 58, 13), (123, 56, 14), + (116, 52, 8), (105, 45, 8), (102, 39, 6), (100, 36, 0), + (87, 27, 0), (79, 27, 3), (72, 27, 6), (71, 27, 6), + (70, 28, 6), (73, 31, 9), (78, 37, 5), (82, 44, 8), + (97, 43, 15), (110, 50, 16), (112, 51, 12), (115, 52, 9), + (115, 47, 10), (107, 48, 8), (99, 46, 2), (86, 40, 0), + (69, 28, 0), (66, 25, 2), (64, 23, 5), (63, 23, 5), + (62, 24, 5), (59, 24, 5), (61, 24, 5), (64, 23, 5), + (70, 21, 4), (72, 15, 4), (71, 19, 6), (71, 23, 9), + (75, 28, 10), (72, 34, 11), (74, 39, 7), (86, 41, 12), + (105, 53, 16), (111, 57, 10), (117, 62, 5), (117, 58, 2), + (122, 53, 11), (124, 50, 11), (116, 46, 10), (103, 44, 10), + (86, 37, 7), (74, 32, 7), (74, 31, 7), (75, 30, 7), + (77, 31, 5), (82, 37, 6), (86, 40, 4), (93, 41, 4), + (97, 35, 0), (93, 34, 0), (89, 33, 0), (74, 28, 5), + (68, 27, 5), (61, 26, 6), (56, 24, 1), (50, 18, 5), + (45, 18, 23), (44, 16, 15), (54, 11, 0), (66, 17, 0), + (75, 29, 3), (93, 41, 4), (110, 51, 9), (126, 50, 14), + (135, 72, 19), (147, 73, 15), (159, 75, 11), (163, 83, 0), + (180, 75, 10), (157, 46, 0), (137, 42, 10), (131, 40, 9), + (124, 50, 11), (120, 54, 2), (117, 54, 0), (117, 50, 7), + (112, 48, 10), (106, 47, 17), (103, 44, 12), (98, 38, 10), + (94, 37, 7), (90, 38, 1), (92, 36, 0), (89, 35, 0), + (82, 36, 0), (76, 32, 3), (72, 25, 0), (71, 25, 2), + (72, 28, 3), (80, 29, 2), (91, 31, 3), (96, 36, 2), + (100, 40, 3), (104, 39, 0), (105, 42, 1), (118, 47, 0), + (111, 46, 4), (104, 45, 5), (96, 35, 7), (89, 33, 6), + (82, 28, 4), (77, 23, 0), (81, 23, 0), (86, 12, 1), + (106, 29, 0), (108, 35, 2), (112, 43, 10), (119, 49, 15), + (115, 47, 28), (118, 54, 16), (126, 58, 21), (121, 53, 16), + (110, 44, 12), (106, 37, 6), (101, 33, 0), (102, 29, 10), + (96, 29, 20), (111, 36, 13), (129, 49, 16), (142, 63, 20), + (150, 65, 26), (159, 82, 36), (158, 79, 20), (158, 85, 16), + (158, 78, 15), (153, 72, 19), (148, 71, 15), (145, 68, 14), + (137, 62, 4), (128, 67, 0), (134, 60, 0), (133, 55, 6), + (127, 52, 12), (131, 47, 13), (165, 48, 30), (172, 68, 13) + ), + +// 184 Apophysis-040427-4AlienFlwerBwl +((155, 136, 68), (138, 97, 53), (135, 105, 52), (133, 113, 52), + (130, 103, 51), (127, 94, 51), (120, 79, 51), (113, 65, 51), + (0, 0, 0), (24, 19, 18), (49, 38, 36), (83, 72, 57), + (118, 107, 79), (120, 103, 75), (123, 99, 71), (127, 95, 77), + (131, 91, 83), (151, 102, 61), (144, 107, 58), (138, 113, 56), + (148, 119, 60), (158, 126, 65), (156, 131, 66), (155, 136, 68), + (144, 137, 85), (150, 134, 91), (157, 131, 98), (163, 129, 95), + (170, 127, 92), (167, 130, 92), (165, 133, 92), (168, 135, 84), + (171, 133, 86), (166, 142, 94), (155, 140, 80), (145, 138, 66), + (137, 125, 72), (129, 113, 79), (135, 111, 75), (141, 109, 71), + (160, 130, 80), (167, 141, 89), (174, 153, 98), (179, 145, 98), + (185, 137, 99), (182, 133, 104), (180, 129, 110), (186, 136, 113), + (175, 144, 113), (173, 147, 112), (172, 139, 106), (172, 131, 101), + (161, 129, 107), (150, 128, 114), (147, 129, 111), (145, 130, 109), + (125, 132, 90), (119, 122, 86), (114, 113, 83), (118, 117, 88), + (123, 122, 94), (129, 123, 103), (136, 124, 112), (156, 139, 113), + (182, 163, 131), (212, 197, 158), (219, 207, 176), (226, 218, 195), + (226, 216, 197), (226, 214, 200), (228, 216, 200), (230, 219, 197), + (227, 219, 196), (226, 217, 191), (226, 215, 187), (221, 205, 176), + (217, 196, 165), (212, 197, 161), (208, 199, 158), (214, 201, 159), + (217, 206, 174), (224, 213, 185), (215, 203, 172), (207, 194, 160), + (207, 191, 153), (208, 189, 147), (193, 179, 134), (191, 162, 118), + (185, 161, 113), (182, 161, 114), (179, 162, 116), (180, 164, 117), + (181, 167, 118), (187, 181, 123), (193, 182, 136), (201, 188, 146), + (210, 184, 151), (207, 188, 156), (208, 191, 155), (209, 194, 155), + (207, 193, 154), (206, 192, 153), (205, 182, 164), (186, 180, 164), + (175, 162, 154), (168, 148, 136), (162, 135, 118), (166, 134, 113), + (170, 134, 108), (171, 135, 109), (189, 145, 108), (188, 149, 116), + (196, 160, 128), (212, 191, 160), (213, 191, 166), (214, 191, 173), + (214, 200, 174), (208, 196, 174), (212, 191, 160), (211, 182, 148), + (207, 177, 143), (201, 170, 139), (195, 164, 135), (189, 164, 134), + (183, 164, 134), (174, 154, 127), (161, 163, 116), (160, 150, 101), + (141, 137, 92), (129, 132, 89), (132, 133, 92), (136, 134, 95), + (143, 135, 96), (152, 133, 103), (165, 152, 117), (175, 156, 114), + (174, 149, 108), (162, 133, 96), (150, 117, 84), (146, 111, 79), + (142, 106, 74), (149, 95, 69), (143, 94, 53), (143, 99, 52), + (141, 97, 50), (142, 86, 63), (135, 82, 59), (129, 79, 56), + (134, 97, 52), (131, 98, 53), (119, 98, 53), (122, 90, 51), + (0, 2, 0), (0, 1, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 2, 1), (113, 64, 32), (132, 75, 46), + (124, 69, 48), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (46, 36, 27), (107, 80, 50), (126, 97, 65), + (136, 106, 70), (140, 110, 64), (144, 115, 59), (147, 122, 68), + (164, 142, 85), (183, 157, 108), (195, 168, 121), (201, 184, 141), + (205, 188, 145), (207, 187, 154), (183, 171, 147), (164, 128, 128), + (150, 128, 114), (130, 110, 111), (133, 119, 93), (148, 121, 78), + (160, 125, 83), (160, 126, 84), (161, 128, 85), (168, 136, 77), + (169, 130, 75), (171, 111, 85), (172, 112, 88), (164, 126, 90), + (157, 130, 83), (146, 126, 89), (140, 142, 105), (149, 153, 120), + (162, 157, 117), (170, 142, 105), (165, 131, 93), (156, 118, 82), + (149, 118, 74), (143, 108, 68), (153, 101, 77), (161, 101, 77), + (175, 114, 93), (179, 130, 100), (188, 150, 114), (195, 172, 128), + (201, 188, 144), (210, 195, 156), (217, 202, 169), (222, 208, 181), + (214, 200, 174), (206, 193, 174), (200, 180, 147), (194, 173, 142), + (192, 173, 130), (192, 164, 125), (195, 158, 129), (190, 161, 129), + (180, 151, 119), (168, 127, 107), (151, 115, 99), (131, 107, 83), + (140, 114, 79), (157, 131, 98), (181, 152, 118), (189, 165, 139), + (207, 195, 157), (216, 211, 181), (228, 218, 191), (220, 212, 191), + (206, 202, 190), (209, 208, 178), (199, 196, 155), (201, 190, 145), + (195, 187, 151), (184, 169, 128), (176, 162, 113), (168, 157, 101), + (157, 130, 77), (140, 104, 54), (114, 79, 41), (27, 22, 18), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 1, 0), (66, 52, 41), + (111, 104, 76), (144, 120, 86), (178, 148, 120), (157, 152, 86) + ), + +// 185 Apophysis-040427-4AlienFlwrBwl_inv +((54, 67, 109), (44, 66, 103), (45, 66, 99), (46, 67, 96), + (47, 65, 99), (49, 63, 102), (49, 68, 96), (50, 73, 91), + (67, 84, 91), (78, 89, 104), (89, 95, 117), (87, 108, 132), + (85, 121, 147), (75, 115, 147), (66, 110, 147), (66, 108, 143), + (67, 106, 139), (50, 90, 116), (45, 77, 99), (41, 64, 82), + (44, 61, 81), (47, 59, 81), (45, 61, 88), (43, 64, 95), + (40, 69, 113), (49, 78, 114), (58, 88, 116), (65, 89, 118), + (72, 91, 121), (76, 96, 124), (81, 101, 128), (94, 92, 139), + (95, 105, 154), (122, 119, 162), (120, 120, 161), (119, 121, 160), + (111, 121, 156), (103, 122, 152), (96, 112, 145), (90, 103, 138), + (80, 103, 145), (87, 113, 150), (94, 123, 155), (103, 136, 168), + (113, 149, 181), (109, 154, 183), (106, 160, 186), (112, 161, 202), + (112, 156, 203), (120, 162, 200), (123, 169, 199), (126, 176, 199), + (125, 166, 200), (124, 157, 202), (130, 157, 202), (136, 157, 202), + (153, 177, 221), (204, 216, 238), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 254, 254), (255, 253, 254), (142, 191, 223), + (123, 180, 209), (174, 211, 238), (214, 233, 246), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (209, 219, 228), (148, 175, 205), + (132, 148, 181), (121, 144, 188), (111, 140, 196), (101, 126, 183), + (91, 113, 170), (81, 105, 158), (72, 98, 147), (60, 87, 134), + (54, 71, 114), (48, 68, 101), (69, 97, 114), (91, 127, 127), + (98, 127, 134), (105, 127, 141), (125, 145, 144), (122, 136, 162), + (101, 135, 172), (97, 131, 171), (94, 127, 170), (90, 123, 174), + (87, 119, 178), (86, 125, 180), (84, 144, 170), (83, 143, 167), + (91, 129, 165), (109, 129, 166), (107, 115, 150), (106, 102, 135), + (99, 100, 136), (93, 98, 138), (85, 113, 150), (90, 124, 162), + (106, 137, 181), (104, 145, 179), (102, 154, 178), (98, 154, 178), + (94, 154, 178), (80, 141, 162), (76, 125, 155), (67, 105, 141), + (60, 83, 127), (45, 60, 99), (41, 56, 92), (38, 53, 86), + (33, 47, 74), (41, 55, 81), (49, 62, 81), (55, 75, 108), + (63, 82, 125), (61, 89, 125), (60, 97, 126), (62, 95, 126), + (65, 94, 126), (75, 104, 136), (87, 128, 148), (104, 140, 156), + (124, 148, 172), (98, 124, 157), (86, 113, 147), (74, 103, 137), + (66, 90, 116), (48, 60, 98), (39, 44, 74), (27, 37, 64), + (49, 53, 65), (52, 56, 82), (56, 59, 100), (55, 62, 105), + (54, 65, 110), (60, 68, 104), (71, 86, 127), (79, 93, 142), + (87, 98, 154), (115, 151, 201), (128, 163, 207), (141, 176, 214), + (228, 233, 237), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 254, 255), + (189, 203, 214), (144, 151, 179), (111, 135, 169), (77, 107, 135), + (98, 103, 169), (115, 151, 201), (116, 154, 201), (117, 158, 202), + (126, 154, 202), (122, 142, 203), (124, 150, 187), (128, 161, 204), + (254, 254, 252), (254, 254, 253), (255, 255, 255), (255, 255, 255), + (206, 217, 219), (148, 176, 179), (137, 148, 176), (127, 148, 175), + (132, 156, 184), (124, 164, 172), (111, 152, 184), (104, 153, 194), + (113, 150, 194), (117, 142, 199), (105, 137, 196), (97, 129, 190), + (105, 108, 179), (108, 113, 174), (111, 118, 170), (99, 122, 172), + (98, 124, 157), (94, 128, 163), (85, 128, 163), (90, 122, 163), + (87, 120, 171), (84, 122, 169), (82, 118, 166), (89, 113, 161), + (97, 114, 168), (110, 117, 189), (123, 136, 189), (126, 142, 176), + (114, 146, 184), (99, 136, 181), (95, 125, 175), (96, 104, 169), + (81, 102, 157), (80, 103, 147), (70, 118, 156), (75, 126, 145), + (69, 119, 142), (80, 111, 142), (82, 102, 139), (82, 108, 143), + (76, 117, 149), (83, 124, 154), (86, 145, 153), (105, 127, 141), + (110, 125, 146), (117, 120, 155), (130, 123, 165), (129, 137, 176), + (141, 142, 172), (134, 144, 171), (132, 133, 161), (119, 131, 143), + (99, 116, 142), (73, 92, 124), (56, 74, 110), (43, 58, 97), + (34, 43, 74), (29, 37, 60), (29, 41, 55), (27, 39, 55), + (25, 36, 58), (25, 36, 58), (28, 36, 59), (26, 36, 61), + (29, 40, 68), (34, 49, 80), (38, 59, 90), (47, 56, 97), + (41, 54, 96), (38, 49, 81), (32, 43, 71), (31, 42, 70), + (34, 45, 75), (48, 61, 95), (47, 66, 108), (62, 76, 121), + (64, 93, 137), (66, 93, 140), (70, 94, 142), (73, 96, 138), + (76, 93, 139), (74, 88, 137), (68, 74, 132), (62, 73, 119) + ), + +// 186 Apophysis-040427-4AmusePrk +((129, 14, 91), (27, 0, 69), (68, 0, 77), (109, 0, 85), + (153, 44, 52), (197, 88, 19), (211, 108, 16), (225, 128, 13), + (243, 189, 41), (248, 211, 45), (254, 234, 49), (254, 234, 48), + (255, 234, 47), (240, 193, 36), (226, 153, 25), (211, 149, 36), + (196, 146, 47), (249, 178, 116), (243, 192, 127), (237, 206, 139), + (239, 207, 109), (242, 209, 80), (243, 227, 86), (244, 245, 92), + (248, 246, 50), (250, 231, 46), (253, 217, 43), (224, 210, 65), + (195, 204, 87), (179, 198, 96), (164, 192, 105), (196, 112, 102), + (252, 67, 46), (162, 40, 1), (130, 20, 13), (99, 0, 25), + (85, 9, 35), (72, 19, 45), (77, 41, 58), (83, 63, 72), + (178, 131, 149), (183, 70, 117), (188, 10, 86), (220, 6, 65), + (252, 3, 45), (251, 1, 36), (250, 0, 27), (238, 0, 0), + (224, 0, 18), (129, 1, 14), (80, 6, 45), (31, 12, 76), + (15, 9, 41), (0, 7, 6), (0, 28, 3), (0, 49, 0), + (117, 167, 6), (170, 160, 13), (223, 153, 21), (230, 132, 38), + (238, 111, 56), (217, 110, 70), (196, 110, 85), (163, 65, 40), + (162, 65, 0), (26, 59, 40), (13, 74, 21), (0, 90, 2), + (0, 89, 2), (1, 89, 2), (2, 49, 31), (0, 13, 44), + (0, 0, 36), (0, 0, 33), (0, 0, 31), (0, 1, 28), + (0, 2, 25), (0, 3, 28), (0, 4, 31), (0, 0, 34), + (1, 0, 36), (0, 9, 44), (0, 20, 47), (0, 31, 51), + (0, 44, 55), (0, 58, 59), (0, 72, 61), (1, 86, 67), + (2, 54, 52), (3, 44, 26), (5, 35, 1), (2, 30, 10), + (0, 25, 19), (0, 34, 36), (2, 42, 54), (0, 54, 56), + (0, 86, 67), (17, 101, 103), (86, 132, 138), (155, 164, 173), + (194, 152, 179), (233, 140, 185), (192, 150, 138), (171, 163, 140), + (138, 184, 138), (119, 170, 96), (100, 157, 54), (108, 162, 43), + (117, 167, 32), (139, 180, 14), (164, 190, 28), (148, 189, 9), + (146, 181, 3), (123, 135, 1), (121, 97, 15), (119, 60, 30), + (99, 42, 31), (45, 39, 17), (27, 17, 51), (1, 10, 43), + (1, 0, 34), (0, 4, 36), (0, 9, 39), (0, 24, 37), + (0, 40, 36), (28, 100, 16), (67, 110, 3), (144, 119, 52), + (218, 148, 96), (218, 195, 128), (213, 193, 129), (208, 192, 130), + (156, 178, 95), (155, 151, 106), (149, 169, 134), (212, 126, 151), + (255, 5, 92), (255, 5, 124), (255, 5, 157), (237, 52, 163), + (220, 99, 170), (236, 119, 146), (243, 164, 157), (244, 165, 158), + (253, 155, 130), (253, 5, 89), (253, 5, 89), (254, 5, 89), + (243, 0, 64), (232, 0, 40), (223, 4, 0), (197, 15, 2), + (69, 0, 35), (49, 27, 26), (30, 54, 18), (2, 92, 2), + (0, 116, 2), (1, 118, 4), (0, 100, 20), (1, 102, 34), + (0, 101, 69), (2, 67, 37), (1, 84, 33), (1, 101, 29), + (42, 131, 3), (74, 136, 3), (47, 130, 0), (0, 117, 2), + (0, 86, 5), (0, 63, 18), (0, 40, 32), (0, 10, 42), + (0, 11, 43), (0, 33, 49), (41, 71, 47), (121, 148, 41), + (146, 182, 32), (197, 189, 29), (254, 235, 45), (253, 251, 55), + (250, 244, 68), (244, 244, 94), (248, 250, 149), (188, 211, 157), + (109, 170, 155), (106, 166, 146), (104, 162, 137), (50, 126, 114), + (3, 96, 86), (2, 85, 69), (2, 53, 56), (45, 27, 49), + (109, 0, 86), (184, 0, 88), (215, 1, 61), (240, 0, 61), + (238, 14, 25), (238, 14, 12), (232, 80, 4), (197, 111, 0), + (158, 170, 12), (177, 182, 66), (196, 164, 51), (252, 116, 64), + (240, 103, 69), (250, 67, 49), (251, 41, 26), (250, 63, 20), + (250, 63, 22), (237, 87, 36), (199, 134, 30), (139, 136, 65), + (137, 144, 92), (137, 103, 78), (88, 49, 54), (64, 68, 7), + (65, 68, 1), (100, 130, 0), (136, 167, 12), (162, 191, 47), + (214, 230, 33), (242, 243, 51), (250, 241, 112), (243, 248, 154), + (219, 223, 190), (209, 220, 180), (176, 205, 175), (183, 194, 188), + (242, 203, 224), (245, 234, 232), (250, 246, 209), (229, 239, 231), + (236, 225, 231), (219, 230, 214), (191, 211, 184), (164, 196, 149), + (130, 158, 136), (110, 163, 153), (110, 167, 158), (106, 151, 144), + (52, 125, 106), (41, 69, 70), (0, 69, 61), (0, 56, 57), + (1, 50, 54), (1, 30, 46), (0, 36, 50), (1, 52, 55), + (15, 62, 44), (1, 84, 16), (43, 72, 14), (64, 53, 8), + (43, 43, 15), (53, 13, 1), (66, 1, 35), (236, 0, 137) + ), + +// 187 Apophysis-040427-4AmusePrkInv +((19, 255, 118), (202, 242, 254), (196, 222, 250), (191, 202, 247), + (222, 186, 243), (254, 171, 239), (247, 182, 225), (240, 193, 211), + (255, 219, 205), (254, 212, 203), (254, 205, 201), (254, 195, 197), + (255, 186, 194), (229, 158, 171), (203, 130, 149), (176, 117, 130), + (149, 104, 111), (145, 92, 102), (118, 75, 104), (91, 59, 106), + (63, 42, 73), (36, 25, 41), (27, 27, 32), (19, 30, 24), + (5, 9, 46), (9, 30, 38), (13, 52, 31), (46, 51, 55), + (79, 50, 80), (62, 42, 77), (46, 35, 75), (36, 32, 65), + (12, 7, 101), (13, 12, 204), (53, 38, 206), (93, 64, 208), + (124, 94, 231), (155, 125, 255), (172, 156, 254), (190, 187, 254), + (167, 206, 201), (142, 158, 182), (118, 111, 163), (87, 116, 194), + (56, 121, 225), (37, 144, 222), (18, 168, 219), (5, 192, 233), + (5, 192, 235), (5, 188, 206), (4, 163, 198), (3, 139, 191), + (40, 106, 190), (78, 73, 189), (87, 79, 216), (97, 85, 243), + (23, 175, 251), (20, 208, 240), (17, 241, 230), (28, 247, 212), + (40, 254, 194), (55, 254, 180), (71, 255, 167), (146, 255, 169), + (210, 228, 206), (253, 170, 186), (229, 149, 163), (205, 129, 141), + (178, 111, 129), (151, 93, 118), (146, 85, 100), (108, 71, 88), + (7, 5, 106), (6, 8, 146), (5, 11, 187), (3, 15, 198), + (1, 20, 210), (29, 43, 218), (58, 66, 226), (109, 73, 223), + (134, 107, 214), (255, 222, 206), (255, 233, 209), (255, 245, 213), + (255, 230, 218), (255, 215, 223), (255, 169, 250), (252, 154, 255), + (208, 125, 255), (210, 124, 253), (213, 124, 252), (233, 139, 239), + (254, 154, 226), (253, 188, 218), (254, 169, 192), (255, 154, 186), + (254, 153, 221), (254, 137, 251), (253, 150, 252), (253, 163, 253), + (239, 182, 245), (225, 201, 237), (186, 255, 220), (113, 248, 254), + (32, 251, 255), (22, 253, 223), (12, 255, 191), (6, 252, 178), + (1, 250, 166), (2, 250, 166), (37, 153, 142), (2, 100, 125), + (11, 90, 97), (19, 136, 109), (27, 146, 97), (35, 156, 85), + (0, 250, 98), (1, 255, 129), (0, 250, 163), (19, 219, 110), + (106, 86, 121), (102, 81, 140), (99, 77, 160), (73, 70, 142), + (47, 63, 125), (37, 60, 127), (20, 42, 151), (37, 107, 159), + (111, 136, 203), (227, 155, 239), (241, 185, 229), (255, 215, 219), + (255, 246, 216), (254, 253, 222), (254, 255, 221), (255, 250, 214), + (228, 238, 204), (192, 225, 214), (156, 213, 224), (146, 204, 224), + (136, 195, 225), (132, 120, 254), (120, 84, 254), (109, 74, 252), + (107, 66, 246), (116, 75, 241), (127, 81, 232), (138, 88, 223), + (155, 98, 201), (151, 88, 131), (117, 71, 117), (102, 92, 116), + (63, 105, 117), (42, 110, 93), (22, 115, 70), (100, 91, 82), + (149, 123, 110), (238, 154, 152), (255, 153, 182), (255, 169, 188), + (255, 201, 199), (255, 221, 219), (255, 225, 227), (255, 230, 236), + (250, 220, 254), (254, 223, 229), (253, 201, 203), (254, 181, 192), + (255, 183, 194), (255, 190, 195), (255, 197, 196), (255, 224, 204), + (255, 244, 212), (255, 246, 211), (255, 255, 211), (254, 255, 219), + (255, 255, 221), (255, 251, 224), (255, 253, 230), (255, 255, 224), + (255, 255, 224), (255, 255, 221), (255, 255, 219), (255, 246, 215), + (253, 206, 224), (253, 186, 238), (254, 166, 253), (255, 165, 253), + (254, 167, 235), (229, 196, 215), (130, 217, 198), (93, 190, 255), + (92, 190, 215), (59, 145, 170), (17, 144, 199), (32, 103, 229), + (32, 102, 234), (45, 92, 230), (138, 88, 249), (213, 151, 248), + (255, 206, 255), (255, 248, 249), (213, 255, 209), (224, 243, 179), + (165, 231, 204), (126, 254, 241), (90, 232, 236), (31, 255, 237), + (17, 255, 255), (5, 255, 228), (3, 252, 210), (36, 251, 207), + (67, 245, 169), (37, 155, 103), (77, 124, 106), (101, 131, 141), + (172, 192, 183), (183, 236, 210), (155, 255, 226), (156, 255, 230), + (140, 230, 254), (93, 215, 254), (30, 238, 250), (3, 188, 209), + (59, 143, 153), (91, 63, 150), (60, 51, 168), (46, 36, 210), + (2, 38, 212), (0, 32, 203), (7, 9, 205), (1, 1, 183), + (11, 10, 163), (13, 46, 175), (2, 35, 148), (18, 49, 116), + (10, 63, 95), (6, 77, 139), (30, 72, 174), (59, 109, 208), + (29, 102, 230), (13, 66, 204), (0, 21, 208), (1, 19, 203), + (1, 21, 206), (2, 38, 212), (12, 66, 214), (32, 103, 231), + (30, 127, 242), (58, 167, 236), (134, 212, 198), (146, 255, 170), + (209, 231, 167), (228, 255, 186), (199, 235, 165), (126, 241, 164) + ), + +// 188 Apophysis-040427-4AmythIceInv +((109, 114, 50), (75, 80, 60), (85, 88, 62), (96, 97, 65), + (116, 116, 67), (136, 135, 70), (141, 145, 71), (147, 156, 73), + (177, 175, 88), (183, 180, 91), (190, 186, 95), (195, 191, 101), + (200, 196, 107), (201, 195, 110), (202, 195, 114), (200, 198, 113), + (199, 202, 113), (199, 195, 104), (194, 191, 100), (189, 188, 96), + (181, 180, 89), (173, 173, 83), (161, 162, 75), (149, 151, 68), + (64, 164, 48), (64, 164, 50), (64, 164, 52), (85, 134, 69), + (106, 105, 87), (107, 109, 76), (108, 114, 66), (128, 134, 62), + (131, 139, 62), (172, 172, 82), (179, 177, 90), (187, 182, 98), + (190, 187, 100), (193, 193, 103), (193, 190, 101), (194, 188, 100), + (187, 188, 94), (172, 172, 83), (157, 156, 73), (136, 136, 61), + (116, 117, 49), (96, 94, 42), (76, 72, 35), (70, 66, 37), + (55, 60, 38), (85, 97, 75), (123, 129, 86), (162, 162, 98), + (177, 176, 100), (192, 190, 103), (197, 194, 106), (202, 198, 109), + (218, 220, 121), (227, 222, 140), (236, 225, 159), (245, 231, 176), + (254, 237, 193), (247, 230, 184), (240, 224, 175), (234, 213, 170), + (225, 213, 131), (204, 200, 111), (210, 205, 118), (217, 211, 125), + (221, 213, 132), (225, 216, 139), (234, 217, 165), (255, 237, 223), + (255, 233, 225), (241, 224, 186), (228, 215, 147), (214, 206, 127), + (201, 197, 108), (193, 189, 101), (185, 181, 94), (155, 158, 77), + (116, 126, 66), (19, 49, 25), (18, 43, 34), (18, 37, 43), + (29, 45, 48), (41, 53, 53), (69, 84, 63), (91, 170, 91), + (148, 219, 141), (169, 204, 122), (190, 190, 104), (193, 192, 103), + (196, 195, 103), (196, 195, 103), (197, 196, 103), (197, 196, 103), + (197, 196, 103), (198, 198, 102), (199, 199, 103), (200, 200, 104), + (199, 200, 103), (199, 201, 102), (199, 199, 103), (199, 199, 103), + (196, 195, 103), (194, 192, 100), (193, 189, 98), (192, 185, 94), + (192, 181, 91), (182, 181, 91), (179, 178, 88), (166, 166, 78), + (151, 153, 69), (158, 157, 74), (166, 165, 81), (174, 174, 88), + (185, 186, 92), (188, 190, 93), (195, 191, 100), (196, 195, 102), + (193, 193, 103), (195, 193, 102), (197, 193, 102), (196, 193, 101), + (195, 194, 101), (196, 195, 103), (196, 195, 103), (197, 196, 103), + (197, 196, 103), (203, 199, 110), (204, 198, 113), (206, 198, 117), + (212, 198, 127), (216, 203, 135), (230, 213, 161), (248, 224, 196), + (242, 247, 253), (248, 251, 250), (255, 255, 247), (254, 255, 245), + (253, 255, 244), (253, 255, 242), (246, 242, 230), (234, 213, 170), + (219, 211, 136), (203, 200, 107), (204, 202, 106), (205, 205, 105), + (205, 207, 108), (190, 219, 109), (216, 241, 121), (222, 229, 123), + (213, 220, 117), (208, 214, 114), (204, 208, 111), (204, 208, 111), + (222, 229, 123), (233, 219, 144), (234, 219, 162), (229, 212, 158), + (226, 209, 139), (206, 196, 127), (206, 195, 124), (207, 195, 121), + (196, 189, 108), (193, 186, 105), (192, 183, 106), (160, 163, 120), + (139, 145, 85), (142, 151, 98), (146, 158, 112), (126, 139, 121), + (101, 193, 106), (92, 191, 109), (82, 179, 72), (65, 168, 51), + (53, 158, 39), (53, 156, 38), (63, 91, 50), (71, 79, 56), + (76, 79, 52), (74, 85, 51), (76, 89, 45), (46, 147, 25), + (57, 158, 40), (62, 162, 45), (67, 167, 51), (145, 152, 72), + (165, 165, 79), (180, 179, 89), (182, 187, 95), (189, 190, 97), + (195, 188, 107), (189, 196, 128), (144, 213, 166), (149, 219, 195), + (173, 230, 224), (197, 221, 171), (183, 198, 155), (203, 194, 129), + (205, 196, 117), (203, 199, 112), (203, 200, 105), (200, 200, 104), + (199, 199, 103), (198, 197, 104), (201, 197, 108), (201, 197, 108), + (206, 197, 118), (208, 196, 122), (216, 197, 129), (217, 206, 144), + (229, 208, 177), (219, 238, 219), (251, 255, 238), (239, 252, 224), + (221, 235, 173), (227, 235, 152), (229, 219, 132), (219, 214, 130), + (212, 206, 122), (204, 195, 116), (172, 168, 123), (151, 156, 124), + (117, 128, 98), (94, 97, 76), (75, 83, 62), (73, 78, 71), + (83, 84, 88), (105, 102, 97), (133, 136, 91), (151, 154, 77), + (163, 162, 79), (168, 173, 73), (148, 188, 89), (72, 179, 65), + (51, 166, 49), (43, 153, 30), (37, 151, 30), (32, 150, 30), + (19, 129, 14), (19, 128, 13), (29, 139, 18), (26, 133, 19), + (54, 77, 35), (61, 75, 40), (44, 49, 45), (31, 44, 34), + (28, 24, 15), (24, 33, 4), (46, 42, 4), (55, 56, 25), + (57, 64, 30), (87, 94, 52), (102, 100, 52), (115, 113, 54) + ), + +// 189 Apophysis-040427-4AmythIce +((146, 141, 205), (180, 175, 195), (169, 166, 192), (159, 158, 190), + (139, 139, 187), (119, 120, 185), (113, 109, 183), (108, 99, 182), + (78, 80, 167), (71, 74, 163), (65, 69, 160), (60, 64, 154), + (55, 59, 148), (54, 59, 144), (53, 60, 141), (54, 56, 141), + (56, 53, 142), (56, 60, 151), (61, 63, 155), (66, 67, 159), + (74, 74, 165), (82, 82, 172), (94, 93, 179), (106, 104, 187), + (191, 91, 207), (191, 91, 205), (191, 91, 203), (170, 120, 185), + (149, 150, 168), (148, 145, 178), (147, 141, 189), (127, 121, 193), + (124, 116, 193), (83, 83, 173), (75, 78, 165), (68, 73, 157), + (65, 67, 154), (62, 62, 152), (61, 64, 153), (61, 67, 155), + (68, 67, 161), (83, 83, 171), (98, 99, 182), (118, 118, 194), + (139, 138, 206), (159, 160, 213), (179, 183, 220), (185, 189, 218), + (200, 195, 217), (170, 158, 180), (131, 125, 168), (93, 93, 157), + (78, 79, 154), (63, 65, 152), (58, 61, 149), (53, 57, 146), + (37, 35, 134), (28, 32, 115), (19, 30, 96), (10, 24, 79), + (1, 18, 62), (8, 24, 71), (15, 31, 80), (21, 42, 85), + (30, 42, 124), (51, 55, 144), (44, 49, 137), (38, 44, 130), + (34, 41, 123), (30, 39, 116), (21, 38, 90), (0, 18, 32), + (0, 22, 30), (13, 31, 69), (27, 40, 108), (40, 49, 127), + (54, 58, 147), (62, 66, 154), (70, 74, 161), (100, 97, 178), + (139, 129, 189), (236, 206, 230), (236, 212, 221), (237, 218, 212), + (225, 210, 207), (214, 202, 202), (186, 171, 192), (164, 85, 164), + (107, 36, 114), (86, 50, 132), (65, 65, 151), (62, 62, 151), + (59, 60, 152), (59, 60, 152), (58, 59, 152), (58, 59, 152), + (58, 59, 152), (57, 57, 153), (56, 56, 152), (55, 55, 151), + (55, 54, 152), (56, 54, 153), (56, 56, 152), (56, 56, 152), + (59, 60, 152), (60, 63, 154), (62, 66, 157), (62, 70, 160), + (63, 74, 164), (73, 74, 164), (76, 77, 167), (89, 89, 177), + (104, 102, 186), (97, 98, 181), (89, 89, 174), (81, 81, 167), + (70, 69, 163), (67, 65, 162), (60, 64, 155), (59, 60, 153), + (62, 62, 152), (60, 62, 152), (58, 62, 153), (59, 61, 153), + (60, 61, 154), (59, 60, 152), (59, 60, 152), (58, 59, 152), + (58, 59, 152), (52, 56, 145), (50, 56, 141), (49, 57, 138), + (43, 57, 128), (39, 52, 120), (25, 42, 94), (7, 31, 59), + (13, 8, 2), (6, 4, 5), (0, 0, 8), (1, 0, 9), + (2, 0, 11), (2, 0, 13), (9, 13, 25), (21, 42, 85), + (36, 44, 119), (52, 55, 148), (51, 52, 149), (50, 50, 150), + (50, 48, 147), (65, 36, 146), (39, 14, 134), (33, 26, 132), + (42, 35, 138), (46, 41, 141), (51, 47, 144), (51, 47, 144), + (33, 26, 132), (22, 36, 111), (21, 36, 93), (26, 43, 97), + (29, 46, 116), (49, 59, 128), (48, 59, 131), (48, 60, 134), + (59, 66, 147), (62, 69, 150), (63, 72, 149), (95, 92, 135), + (116, 110, 170), (112, 103, 156), (109, 97, 143), (129, 116, 134), + (154, 62, 149), (163, 64, 146), (173, 76, 183), (190, 87, 204), + (202, 97, 216), (202, 99, 217), (192, 164, 205), (184, 176, 199), + (179, 176, 203), (181, 170, 204), (179, 166, 210), (209, 108, 230), + (198, 97, 215), (193, 92, 209), (188, 88, 204), (110, 103, 183), + (90, 90, 176), (75, 76, 166), (73, 68, 160), (66, 65, 158), + (60, 67, 148), (66, 59, 127), (111, 42, 89), (106, 36, 60), + (82, 25, 31), (58, 34, 84), (72, 57, 100), (52, 61, 126), + (50, 59, 138), (52, 56, 143), (52, 55, 150), (55, 55, 151), + (56, 56, 152), (57, 58, 151), (54, 58, 147), (54, 58, 147), + (49, 58, 137), (47, 59, 133), (39, 58, 126), (38, 49, 111), + (26, 47, 78), (36, 17, 36), (4, 0, 17), (16, 3, 31), + (34, 20, 82), (28, 20, 103), (26, 36, 123), (36, 41, 125), + (43, 49, 133), (51, 60, 139), (83, 87, 132), (104, 99, 131), + (138, 127, 157), (161, 158, 179), (180, 172, 193), (182, 177, 184), + (172, 171, 167), (150, 153, 158), (122, 119, 164), (104, 101, 178), + (92, 93, 176), (87, 82, 182), (107, 67, 166), (183, 76, 190), + (204, 89, 206), (212, 102, 225), (218, 104, 225), (223, 105, 225), + (236, 126, 241), (236, 127, 242), (226, 116, 237), (229, 122, 236), + (201, 178, 220), (194, 180, 215), (211, 206, 210), (224, 211, 221), + (227, 231, 240), (231, 222, 251), (209, 213, 251), (200, 199, 230), + (198, 191, 225), (168, 161, 203), (153, 155, 203), (140, 142, 201) + ), + +// 190 Apophysis-040427-4AngOrchid +((173, 229, 200), (192, 204, 200), (167, 156, 200), (143, 108, 200), + (122, 88, 172), (101, 69, 144), (101, 67, 145), (101, 66, 146), + (103, 73, 161), (104, 74, 174), (105, 75, 187), (98, 70, 189), + (92, 66, 191), (90, 62, 170), (88, 59, 149), (84, 56, 139), + (81, 53, 130), (91, 65, 188), (89, 70, 201), (87, 76, 215), + (78, 92, 205), (69, 109, 196), (71, 119, 192), (73, 129, 188), + (39, 99, 91), (19, 56, 57), (0, 13, 24), (19, 56, 58), + (39, 100, 92), (40, 100, 93), (41, 100, 94), (41, 102, 94), + (41, 104, 95), (41, 102, 94), (40, 101, 93), (39, 100, 92), + (40, 102, 93), (41, 104, 95), (41, 104, 95), (42, 105, 96), + (43, 113, 102), (49, 134, 110), (56, 156, 118), (56, 158, 123), + (56, 161, 128), (54, 159, 124), (53, 157, 120), (57, 161, 126), + (57, 162, 131), (70, 173, 152), (84, 183, 169), (99, 194, 186), + (130, 209, 199), (162, 224, 213), (163, 224, 213), (164, 224, 214), + (108, 191, 171), (86, 179, 154), (64, 167, 138), (59, 164, 135), + (55, 162, 132), (55, 162, 132), (56, 163, 133), (56, 165, 136), + (64, 176, 154), (107, 184, 192), (137, 198, 197), (167, 213, 203), + (175, 215, 205), (184, 217, 208), (188, 223, 216), (189, 236, 216), + (181, 228, 220), (180, 227, 219), (179, 226, 218), (174, 223, 217), + (169, 221, 217), (163, 212, 214), (157, 204, 212), (120, 185, 177), + (89, 150, 132), (51, 108, 101), (62, 78, 111), (74, 48, 122), + (75, 48, 122), (76, 48, 123), (77, 50, 127), (79, 52, 131), + (102, 92, 191), (107, 88, 203), (112, 85, 216), (119, 101, 219), + (127, 118, 223), (112, 166, 204), (99, 186, 177), (77, 170, 141), + (58, 154, 126), (42, 108, 98), (41, 104, 95), (40, 101, 93), + (39, 100, 92), (39, 100, 92), (39, 100, 92), (41, 102, 94), + (43, 109, 99), (53, 133, 118), (64, 157, 138), (72, 158, 154), + (80, 160, 171), (103, 181, 183), (128, 194, 190), (152, 189, 215), + (156, 166, 225), (116, 89, 218), (109, 83, 219), (103, 78, 221), + (93, 82, 221), (89, 76, 216), (95, 83, 209), (107, 122, 213), + (65, 162, 169), (65, 160, 153), (66, 158, 137), (60, 160, 137), + (55, 163, 137), (57, 169, 145), (65, 172, 152), (66, 175, 156), + (72, 180, 164), (65, 173, 157), (63, 171, 147), (61, 169, 137), + (61, 162, 128), (62, 162, 126), (67, 163, 126), (68, 165, 130), + (58, 163, 132), (57, 163, 134), (57, 164, 136), (56, 164, 137), + (56, 164, 138), (61, 170, 151), (74, 168, 176), (94, 172, 192), + (105, 181, 197), (143, 216, 209), (137, 205, 205), (132, 195, 202), + (118, 189, 173), (88, 171, 163), (55, 150, 144), (48, 121, 110), + (43, 109, 99), (43, 109, 99), (43, 109, 99), (46, 116, 105), + (62, 157, 125), (69, 172, 145), (101, 189, 167), (120, 202, 196), + (143, 204, 189), (169, 227, 177), (161, 218, 187), (153, 209, 198), + (154, 203, 208), (156, 219, 211), (166, 235, 204), (153, 208, 189), + (183, 224, 168), (184, 226, 172), (186, 229, 176), (181, 235, 199), + (182, 239, 206), (181, 221, 213), (190, 220, 212), (198, 239, 205), + (198, 240, 204), (194, 228, 201), (191, 222, 190), (177, 222, 163), + (152, 178, 165), (110, 182, 168), (78, 171, 142), (66, 165, 134), + (92, 185, 166), (101, 189, 172), (111, 193, 179), (134, 201, 184), + (173, 221, 161), (176, 220, 159), (181, 221, 158), (177, 219, 156), + (162, 195, 140), (102, 156, 142), (80, 171, 140), (93, 181, 156), + (127, 195, 172), (159, 208, 163), (173, 221, 159), (175, 219, 158), + (165, 196, 139), (153, 179, 131), (88, 146, 122), (74, 131, 161), + (106, 84, 157), (136, 106, 178), (176, 143, 230), (167, 184, 227), + (181, 214, 219), (195, 230, 224), (208, 244, 216), (212, 243, 225), + (206, 239, 222), (194, 239, 216), (194, 239, 218), (195, 230, 226), + (207, 230, 222), (206, 238, 225), (208, 235, 230), (211, 237, 228), + (210, 237, 228), (202, 228, 225), (186, 216, 218), (174, 188, 225), + (176, 155, 232), (149, 116, 221), (135, 99, 205), (107, 82, 210), + (104, 80, 218), (127, 103, 225), (111, 139, 213), (103, 161, 201), + (84, 152, 191), (64, 136, 151), (45, 117, 106), (43, 109, 99), + (41, 104, 95), (40, 101, 93), (41, 100, 94), (41, 100, 94), + (74, 48, 122), (77, 49, 124), (80, 52, 129), (86, 58, 143), + (87, 57, 131), (52, 109, 102), (42, 105, 96), (41, 104, 95), + (42, 108, 98), (43, 113, 102), (67, 138, 122), (90, 147, 154), + (127, 193, 183), (132, 213, 206), (167, 237, 201), (181, 238, 203) + ), + +// 191 Apophysis-040427-4Leaves +((186, 178, 193), (87, 98, 68), (64, 60, 46), (41, 22, 24), + (49, 22, 23), (57, 23, 22), (77, 40, 24), (98, 57, 27), + (159, 95, 33), (173, 122, 69), (188, 150, 105), (180, 163, 127), + (172, 176, 149), (166, 170, 160), (160, 165, 171), (159, 165, 173), + (159, 166, 176), (188, 198, 187), (193, 200, 187), (198, 202, 187), + (202, 195, 176), (207, 189, 165), (197, 184, 153), (188, 180, 141), + (192, 133, 29), (200, 137, 21), (209, 141, 14), (218, 156, 16), + (227, 172, 19), (227, 182, 19), (228, 192, 20), (228, 172, 25), + (226, 162, 26), (210, 142, 19), (194, 125, 29), (179, 109, 39), + (176, 118, 26), (174, 127, 13), (192, 141, 12), (211, 156, 11), + (221, 189, 90), (217, 196, 132), (214, 203, 175), (207, 212, 200), + (201, 222, 225), (198, 222, 229), (196, 223, 234), (188, 220, 243), + (198, 211, 243), (209, 217, 238), (205, 213, 217), (201, 209, 196), + (196, 191, 177), (192, 173, 158), (192, 172, 133), (192, 172, 109), + (232, 210, 46), (225, 216, 68), (219, 222, 91), (214, 213, 128), + (210, 205, 165), (206, 204, 171), (203, 203, 177), (197, 199, 185), + (179, 189, 181), (148, 141, 113), (125, 103, 67), (103, 66, 21), + (100, 61, 13), (97, 57, 6), (66, 37, 0), (38, 21, 14), + (21, 17, 34), (36, 30, 24), (52, 43, 14), (74, 52, 21), + (97, 61, 29), (107, 66, 34), (117, 72, 39), (132, 108, 74), + (171, 135, 109), (154, 163, 142), (154, 161, 155), (155, 159, 168), + (154, 158, 161), (153, 158, 154), (147, 156, 153), (150, 147, 140), + (168, 164, 129), (168, 182, 154), (168, 200, 179), (175, 208, 183), + (183, 216, 187), (208, 214, 210), (218, 223, 217), (214, 223, 218), + (207, 223, 213), (209, 200, 185), (206, 192, 149), (203, 185, 113), + (200, 183, 105), (198, 182, 97), (200, 190, 95), (210, 178, 91), + (203, 165, 64), (206, 137, 50), (210, 109, 37), (198, 98, 35), + (187, 88, 33), (158, 88, 19), (163, 97, 19), (158, 118, 57), + (176, 125, 98), (163, 168, 188), (168, 168, 197), (173, 169, 206), + (171, 193, 214), (173, 200, 217), (196, 204, 206), (201, 200, 198), + (209, 207, 194), (212, 207, 198), (215, 208, 202), (218, 210, 216), + (222, 213, 230), (231, 221, 219), (221, 215, 199), (217, 185, 170), + (200, 142, 96), (191, 130, 47), (193, 125, 39), (195, 121, 32), + (195, 146, 41), (189, 163, 88), (184, 172, 132), (186, 189, 178), + (187, 202, 197), (182, 195, 195), (177, 188, 194), (175, 188, 187), + (173, 188, 181), (165, 180, 187), (160, 185, 192), (163, 193, 204), + (181, 194, 200), (204, 212, 223), (210, 218, 225), (216, 224, 227), + (222, 231, 240), (227, 233, 233), (228, 232, 218), (222, 226, 212), + (212, 196, 173), (212, 194, 157), (212, 192, 141), (212, 176, 116), + (219, 156, 85), (177, 126, 60), (124, 86, 39), (116, 62, 26), + (82, 19, 27), (18, 18, 6), (14, 17, 6), (11, 17, 7), + (17, 9, 7), (15, 14, 12), (33, 22, 18), (35, 68, 23), + (164, 93, 123), (177, 125, 150), (191, 158, 177), (207, 193, 190), + (207, 205, 210), (210, 213, 220), (216, 220, 223), (205, 224, 222), + (190, 225, 227), (196, 209, 218), (201, 201, 201), (201, 195, 169), + (199, 191, 145), (178, 174, 129), (174, 169, 129), (174, 172, 134), + (175, 167, 165), (179, 176, 182), (184, 186, 199), (196, 200, 209), + (209, 211, 224), (205, 227, 241), (212, 233, 250), (221, 232, 250), + (209, 236, 245), (197, 224, 241), (212, 226, 226), (216, 229, 209), + (228, 233, 213), (236, 235, 171), (238, 208, 156), (217, 205, 119), + (205, 185, 90), (213, 169, 60), (215, 169, 58), (233, 180, 50), + (227, 201, 46), (221, 205, 34), (232, 206, 25), (236, 218, 20), + (231, 203, 34), (239, 187, 23), (232, 181, 30), (234, 177, 26), + (232, 164, 27), (218, 143, 15), (193, 124, 3), (152, 86, 12), + (108, 78, 14), (79, 68, 48), (120, 114, 90), (167, 157, 145), + (185, 187, 186), (212, 208, 223), (221, 209, 231), (213, 210, 229), + (209, 223, 232), (209, 219, 228), (197, 211, 224), (189, 203, 206), + (174, 187, 193), (153, 178, 174), (100, 176, 163), (134, 146, 134), + (120, 133, 141), (98, 122, 132), (111, 120, 135), (140, 141, 101), + (148, 142, 90), (179, 138, 50), (197, 107, 10), (166, 78, 7), + (143, 45, 20), (100, 55, 22), (62, 24, 15), (31, 9, 11), + (28, 4, 17), (50, 12, 11), (74, 38, 6), (115, 76, 0), + (133, 86, 30), (156, 96, 44), (145, 131, 86), (146, 124, 110), + (142, 158, 87), (135, 143, 94), (111, 118, 124), (102, 104, 103) + ), + +// 192 Apophysis-040427-4Bdlnds +((65, 55, 19), (44, 34, 24), (40, 28, 15), (36, 23, 7), + (38, 22, 7), (40, 22, 8), (45, 46, 9), (50, 70, 11), + (63, 89, 26), (78, 97, 52), (93, 106, 78), (110, 111, 99), + (127, 116, 120), (163, 122, 115), (200, 129, 111), (196, 142, 119), + (193, 156, 127), (195, 223, 226), (193, 221, 227), (191, 220, 228), + (185, 192, 183), (180, 164, 139), (183, 161, 134), (186, 159, 129), + (189, 168, 151), (194, 197, 188), (200, 226, 225), (207, 231, 230), + (215, 237, 235), (217, 238, 236), (220, 240, 238), (222, 243, 238), + (220, 238, 238), (220, 232, 230), (220, 232, 229), (221, 232, 228), + (214, 229, 230), (207, 226, 232), (210, 228, 232), (213, 231, 233), + (210, 234, 236), (209, 231, 233), (209, 229, 230), (206, 226, 226), + (204, 224, 222), (203, 196, 190), (203, 169, 159), (175, 151, 141), + (147, 128, 124), (133, 104, 100), (127, 109, 104), (122, 115, 109), + (131, 121, 120), (140, 128, 132), (157, 143, 136), (175, 158, 140), + (180, 223, 230), (184, 223, 227), (189, 223, 225), (179, 184, 179), + (170, 146, 134), (162, 134, 123), (155, 123, 112), (149, 115, 87), + (137, 113, 75), (99, 93, 35), (98, 88, 34), (97, 83, 34), + (98, 91, 39), (100, 99, 45), (111, 105, 81), (119, 104, 97), + (128, 117, 125), (133, 109, 105), (138, 102, 86), (125, 106, 80), + (113, 110, 75), (96, 106, 70), (80, 102, 66), (80, 102, 63), + (85, 101, 56), (80, 87, 36), (85, 85, 32), (90, 83, 28), + (87, 82, 28), (84, 81, 28), (82, 95, 16), (64, 90, 17), + (63, 66, 11), (73, 73, 15), (84, 80, 19), (102, 90, 27), + (121, 100, 35), (159, 100, 42), (147, 106, 74), (157, 99, 77), + (158, 113, 90), (175, 163, 115), (177, 167, 120), (180, 172, 126), + (186, 169, 131), (192, 167, 136), (218, 173, 154), (210, 225, 222), + (222, 238, 238), (226, 240, 239), (230, 242, 240), (230, 242, 240), + (231, 243, 241), (228, 243, 240), (228, 242, 243), (226, 241, 244), + (230, 240, 242), (245, 251, 247), (245, 251, 247), (245, 251, 247), + (241, 252, 246), (236, 248, 244), (230, 245, 242), (223, 239, 239), + (214, 233, 239), (203, 227, 236), (193, 221, 233), (192, 221, 230), + (191, 222, 227), (186, 163, 149), (154, 143, 137), (138, 132, 134), + (124, 113, 129), (105, 121, 121), (114, 128, 116), (123, 135, 111), + (147, 145, 106), (152, 132, 125), (176, 157, 153), (169, 213, 226), + (167, 215, 227), (150, 175, 179), (134, 136, 131), (124, 123, 108), + (115, 111, 86), (95, 93, 55), (102, 88, 41), (130, 100, 76), + (179, 139, 139), (117, 112, 48), (151, 123, 74), (185, 135, 100), + (203, 175, 154), (192, 221, 225), (187, 221, 230), (182, 222, 224), + (151, 134, 108), (137, 123, 100), (123, 112, 92), (96, 87, 58), + (95, 76, 46), (93, 69, 35), (104, 65, 34), (119, 76, 25), + (93, 82, 37), (126, 94, 73), (133, 107, 91), (140, 120, 109), + (180, 147, 132), (203, 169, 157), (207, 222, 225), (223, 234, 236), + (247, 253, 249), (250, 253, 248), (253, 254, 248), (246, 254, 255), + (247, 251, 252), (242, 251, 246), (233, 245, 241), (227, 239, 237), + (216, 232, 231), (202, 225, 219), (203, 183, 150), (193, 173, 122), + (178, 135, 93), (145, 119, 62), (121, 92, 58), (115, 90, 70), + (95, 110, 113), (106, 130, 136), (117, 150, 159), (150, 158, 179), + (163, 205, 229), (183, 218, 240), (194, 227, 236), (213, 232, 238), + (223, 237, 240), (228, 242, 242), (221, 239, 241), (212, 231, 238), + (211, 231, 230), (205, 230, 226), (209, 224, 229), (213, 199, 188), + (201, 154, 144), (177, 140, 132), (144, 122, 111), (138, 109, 79), + (119, 112, 70), (94, 109, 50), (84, 101, 46), (108, 102, 66), + (129, 108, 103), (146, 128, 142), (171, 161, 169), (184, 221, 227), + (186, 223, 231), (189, 224, 230), (198, 229, 231), (198, 230, 229), + (206, 226, 225), (215, 201, 190), (204, 174, 148), (180, 150, 124), + (139, 118, 65), (114, 105, 38), (103, 96, 28), (92, 92, 42), + (94, 94, 58), (114, 110, 98), (151, 158, 127), (176, 191, 188), + (182, 220, 231), (193, 221, 232), (201, 224, 232), (211, 229, 233), + (214, 232, 236), (217, 237, 235), (220, 240, 239), (217, 238, 241), + (213, 238, 243), (217, 236, 242), (217, 236, 242), (211, 233, 244), + (206, 230, 240), (188, 225, 243), (183, 219, 233), (186, 221, 227), + (193, 168, 161), (190, 147, 131), (171, 135, 135), (173, 126, 136), + (153, 119, 135), (148, 121, 138), (142, 126, 136), (145, 119, 132), + (131, 117, 108), (107, 102, 83), (80, 71, 64), (79, 76, 35) + ), + +// 193 Apophysis-040427-4BnnySurp +((246, 152, 80), (121, 73, 209), (160, 91, 174), (200, 109, 140), + (218, 122, 116), (237, 136, 92), (241, 143, 85), (245, 151, 79), + (254, 163, 72), (254, 165, 71), (255, 168, 71), (254, 165, 71), + (254, 163, 72), (254, 165, 71), (254, 167, 70), (254, 167, 70), + (255, 168, 71), (255, 169, 72), (245, 186, 62), (235, 204, 52), + (225, 197, 40), (216, 191, 29), (220, 181, 44), (224, 171, 59), + (223, 144, 103), (219, 137, 103), (215, 131, 103), (204, 126, 117), + (194, 121, 132), (182, 113, 150), (171, 105, 169), (140, 85, 187), + (117, 70, 208), (82, 51, 253), (96, 57, 235), (111, 64, 218), + (139, 82, 194), (168, 101, 170), (173, 105, 167), (179, 110, 165), + (203, 121, 109), (209, 126, 104), (216, 131, 100), (210, 125, 104), + (204, 120, 109), (198, 119, 116), (193, 118, 123), (184, 113, 145), + (132, 87, 154), (96, 73, 83), (149, 96, 65), (202, 120, 47), + (219, 133, 64), (236, 147, 81), (241, 149, 80), (246, 152, 80), + (255, 166, 70), (254, 168, 73), (253, 170, 76), (249, 161, 92), + (246, 153, 109), (230, 149, 119), (215, 146, 130), (219, 117, 128), + (188, 112, 161), (187, 114, 143), (201, 122, 123), (216, 130, 103), + (219, 133, 98), (223, 136, 93), (229, 142, 88), (241, 148, 79), + (253, 162, 71), (252, 159, 73), (251, 156, 76), (245, 152, 77), + (239, 148, 78), (236, 146, 81), (234, 144, 84), (232, 140, 89), + (230, 138, 89), (222, 131, 104), (222, 133, 98), (223, 136, 93), + (220, 136, 92), (217, 136, 91), (220, 136, 92), (226, 137, 95), + (235, 145, 83), (244, 152, 76), (254, 159, 69), (245, 158, 61), + (236, 157, 54), (232, 143, 83), (219, 134, 97), (201, 115, 118), + (182, 112, 149), (172, 106, 170), (176, 107, 162), (180, 108, 154), + (187, 112, 138), (194, 117, 123), (202, 117, 110), (210, 123, 103), + (205, 122, 108), (179, 109, 136), (153, 96, 165), (146, 90, 175), + (139, 84, 185), (106, 46, 180), (79, 36, 203), (62, 26, 238), + (50, 32, 242), (109, 63, 221), (109, 64, 222), (109, 65, 224), + (85, 60, 240), (82, 51, 253), (82, 50, 255), (80, 51, 255), + (81, 49, 255), (84, 49, 253), (87, 50, 252), (97, 56, 238), + (107, 62, 225), (125, 76, 204), (142, 88, 184), (179, 106, 162), + (199, 118, 114), (229, 139, 89), (235, 144, 84), (241, 150, 80), + (248, 155, 77), (255, 169, 69), (253, 187, 64), (248, 202, 20), + (250, 210, 1), (252, 190, 36), (254, 170, 71), (254, 167, 72), + (255, 164, 73), (251, 156, 76), (243, 148, 80), (235, 141, 89), + (220, 139, 94), (195, 119, 121), (182, 114, 134), (169, 109, 147), + (151, 94, 173), (121, 69, 203), (105, 62, 229), (97, 45, 251), + (74, 53, 254), (73, 53, 253), (72, 54, 252), (70, 51, 255), + (74, 51, 255), (75, 50, 253), (76, 51, 255), (80, 51, 255), + (82, 51, 253), (105, 62, 229), (108, 63, 222), (111, 65, 215), + (113, 67, 215), (116, 72, 209), (116, 72, 209), (126, 78, 198), + (115, 70, 212), (119, 72, 207), (124, 75, 203), (116, 76, 191), + (96, 66, 104), (76, 56, 19), (74, 53, 34), (5, 0, 110), + (8, 0, 177), (10, 0, 181), (20, 4, 225), (27, 8, 250), + (34, 14, 253), (53, 44, 255), (65, 46, 252), (63, 33, 251), + (31, 9, 255), (30, 9, 253), (29, 10, 252), (31, 12, 254), + (48, 24, 255), (67, 43, 255), (68, 49, 255), (70, 51, 255), + (73, 52, 255), (74, 53, 254), (74, 51, 255), (83, 51, 255), + (111, 67, 216), (127, 77, 198), (152, 90, 173), (177, 103, 136), + (199, 116, 112), (216, 129, 99), (219, 133, 98), (224, 135, 91), + (233, 142, 85), (235, 145, 83), (239, 145, 81), (235, 147, 84), + (234, 144, 84), (224, 138, 91), (219, 133, 98), (207, 121, 108), + (184, 113, 143), (143, 87, 184), (113, 67, 215), (84, 32, 241), + (38, 17, 255), (26, 7, 247), (27, 7, 244), (34, 7, 182), + (66, 42, 154), (113, 70, 178), (166, 100, 162), (189, 118, 136), + (215, 129, 104), (227, 139, 93), (240, 148, 81), (249, 156, 78), + (254, 163, 72), (255, 164, 71), (254, 164, 68), (255, 164, 71), + (254, 163, 72), (254, 163, 72), (246, 155, 76), (229, 157, 81), + (205, 171, 99), (172, 152, 93), (160, 115, 120), (166, 112, 146), + (180, 109, 149), (195, 116, 119), (202, 118, 107), (211, 128, 98), + (222, 134, 96), (228, 138, 88), (234, 144, 84), (242, 149, 80), + (243, 150, 80), (244, 150, 80), (255, 146, 80), (255, 150, 74), + (253, 157, 73), (255, 161, 71), (251, 156, 74), (243, 150, 80) + ), + +// 194 Apophysis-040427-4BorgEY +((136, 117, 102), (140, 124, 101), (139, 127, 100), (139, 130, 99), + (139, 132, 100), (140, 134, 102), (140, 134, 102), (140, 134, 102), + (139, 135, 100), (140, 137, 99), (141, 139, 98), (140, 138, 97), + (140, 137, 96), (140, 138, 97), (141, 139, 98), (140, 138, 98), + (140, 138, 99), (142, 138, 101), (140, 130, 100), (138, 123, 100), + (138, 125, 100), (139, 127, 101), (138, 123, 101), (137, 120, 102), + (135, 110, 103), (130, 100, 103), (126, 90, 104), (121, 64, 99), + (117, 38, 95), (104, 26, 91), (92, 15, 87), (79, 2, 80), + (29, 0, 80), (2, 0, 1), (38, 8, 21), (74, 16, 41), + (79, 8, 53), (85, 0, 65), (81, 0, 70), (77, 1, 75), + (118, 23, 105), (122, 48, 107), (126, 74, 110), (128, 84, 111), + (131, 94, 112), (132, 96, 112), (134, 98, 112), (135, 104, 112), + (136, 106, 106), (133, 105, 104), (132, 104, 104), (132, 103, 105), + (134, 104, 107), (136, 105, 110), (135, 107, 108), (135, 110, 106), + (140, 115, 110), (139, 117, 107), (138, 119, 104), (137, 122, 103), + (137, 125, 103), (137, 125, 101), (138, 126, 100), (140, 129, 99), + (139, 130, 99), (140, 131, 102), (141, 129, 104), (143, 128, 107), + (143, 129, 107), (143, 131, 107), (143, 132, 104), (142, 133, 104), + (139, 129, 102), (140, 132, 102), (142, 136, 102), (140, 131, 103), + (139, 127, 105), (138, 126, 104), (138, 126, 104), (138, 126, 104), + (140, 125, 104), (138, 123, 104), (138, 119, 104), (138, 116, 105), + (137, 113, 106), (136, 111, 107), (136, 108, 105), (134, 108, 107), + (130, 97, 108), (131, 98, 107), (133, 100, 107), (133, 102, 106), + (134, 104, 106), (135, 107, 104), (136, 111, 106), (136, 113, 107), + (137, 114, 108), (137, 119, 105), (138, 122, 103), (140, 125, 102), + (139, 126, 102), (139, 127, 103), (139, 128, 100), (138, 126, 100), + (139, 124, 101), (138, 122, 102), (138, 121, 103), (137, 120, 102), + (137, 120, 102), (137, 120, 102), (136, 117, 103), (136, 114, 103), + (137, 118, 104), (138, 123, 104), (138, 123, 104), (138, 123, 104), + (139, 124, 105), (139, 124, 105), (137, 125, 103), (135, 123, 99), + (135, 116, 99), (138, 119, 104), (142, 123, 109), (144, 126, 112), + (147, 129, 115), (143, 112, 117), (135, 96, 117), (131, 92, 110), + (128, 83, 112), (123, 77, 106), (120, 70, 105), (118, 63, 105), + (118, 59, 105), (116, 57, 105), (117, 57, 111), (116, 45, 113), + (117, 63, 99), (112, 60, 84), (108, 58, 69), (105, 52, 71), + (103, 47, 74), (96, 22, 85), (89, 8, 85), (90, 20, 83), + (93, 38, 69), (113, 85, 71), (119, 92, 78), (125, 99, 86), + (130, 98, 101), (131, 103, 99), (136, 103, 84), (116, 82, 70), + (112, 80, 67), (117, 76, 78), (123, 72, 89), (130, 91, 94), + (132, 94, 107), (130, 97, 108), (133, 104, 109), (135, 109, 108), + (135, 109, 108), (137, 113, 111), (138, 114, 111), (140, 116, 112), + (140, 117, 109), (143, 126, 110), (146, 124, 113), (160, 141, 111), + (141, 140, 94), (140, 141, 93), (139, 143, 92), (140, 139, 95), + (139, 137, 96), (139, 137, 96), (140, 136, 99), (140, 128, 102), + (138, 123, 100), (137, 115, 104), (134, 105, 109), (131, 92, 113), + (138, 71, 122), (148, 58, 110), (153, 67, 132), (180, 88, 153), + (136, 103, 114), (134, 102, 110), (133, 102, 107), (130, 94, 104), + (120, 68, 106), (111, 45, 106), (103, 14, 104), (100, 25, 90), + (109, 46, 101), (125, 76, 105), (130, 114, 89), (136, 133, 80), + (143, 161, 85), (151, 167, 94), (147, 151, 100), (146, 151, 95), + (143, 142, 94), (140, 137, 92), (139, 136, 93), (138, 129, 98), + (138, 122, 99), (136, 119, 99), (132, 113, 99), (134, 110, 100), + (130, 100, 102), (129, 96, 103), (121, 75, 104), (105, 52, 80), + (72, 29, 48), (72, 27, 47), (72, 25, 35), (90, 59, 38), + (108, 79, 61), (124, 93, 88), (126, 88, 99), (128, 84, 107), + (124, 76, 114), (128, 81, 113), (130, 88, 110), (132, 93, 111), + (136, 106, 108), (138, 126, 100), (143, 146, 91), (144, 172, 85), + (167, 184, 90), (170, 208, 99), (152, 174, 109), (156, 167, 109), + (170, 178, 165), (149, 150, 116), (147, 149, 102), (141, 139, 98), + (138, 132, 96), (138, 132, 96), (137, 132, 94), (133, 124, 91), + (137, 123, 97), (136, 117, 103), (137, 114, 106), (135, 111, 107), + (137, 108, 110), (137, 108, 110), (137, 108, 110), (139, 110, 112), + (138, 115, 107), (137, 117, 106), (137, 117, 106), (137, 118, 104), + (136, 117, 103), (134, 114, 105), (134, 115, 101), (136, 114, 101) + ), + +// 195 Apophysis-040427-4BB4 +((156, 137, 8), (161, 145, 10), (162, 146, 7), (164, 147, 5), + (163, 146, 7), (162, 146, 9), (161, 144, 10), (160, 143, 11), + (157, 143, 12), (158, 143, 12), (160, 143, 13), (161, 144, 13), + (163, 146, 14), (164, 146, 11), (165, 147, 9), (165, 147, 9), + (166, 148, 10), (166, 149, 9), (167, 147, 8), (169, 146, 8), + (166, 147, 10), (164, 148, 13), (164, 147, 14), (164, 147, 15), + (167, 146, 18), (165, 146, 17), (164, 147, 17), (162, 147, 16), + (161, 147, 16), (162, 146, 15), (163, 146, 14), (166, 148, 14), + (171, 153, 15), (184, 166, 8), (217, 202, 7), (250, 238, 6), + (252, 243, 7), (254, 249, 9), (254, 246, 9), (254, 244, 9), + (188, 171, 19), (176, 158, 19), (164, 146, 20), (150, 122, 42), + (137, 98, 65), (166, 79, 64), (196, 60, 64), (194, 41, 46), + (176, 37, 42), (174, 38, 42), (170, 36, 41), (166, 35, 40), + (166, 35, 40), (167, 36, 41), (161, 85, 35), (155, 134, 29), + (188, 172, 24), (220, 200, 17), (253, 228, 11), (254, 227, 10), + (255, 227, 9), (253, 227, 9), (252, 227, 10), (198, 174, 6), + (182, 166, 19), (92, 171, 44), (81, 159, 33), (71, 147, 23), + (69, 143, 23), (67, 140, 23), (117, 101, 6), (145, 109, 31), + (134, 121, 7), (144, 130, 9), (155, 140, 11), (159, 143, 12), + (163, 146, 14), (165, 149, 15), (168, 152, 17), (179, 162, 22), + (184, 169, 26), (195, 181, 58), (197, 183, 59), (200, 186, 61), + (220, 210, 39), (240, 234, 18), (252, 251, 13), (251, 255, 8), + (255, 255, 6), (255, 249, 4), (255, 244, 2), (253, 238, 5), + (251, 233, 9), (241, 214, 19), (183, 168, 17), (169, 151, 13), + (154, 137, 7), (114, 100, 3), (133, 114, 15), (152, 128, 28), + (154, 133, 21), (157, 139, 15), (155, 137, 9), (155, 138, 8), + (159, 141, 13), (160, 141, 18), (162, 141, 24), (162, 134, 40), + (162, 128, 57), (188, 100, 90), (198, 67, 73), (200, 65, 71), + (206, 90, 93), (201, 187, 64), (209, 196, 51), (218, 205, 39), + (254, 231, 13), (255, 250, 14), (255, 243, 22), (253, 226, 12), + (178, 167, 52), (176, 150, 47), (174, 133, 43), (169, 132, 55), + (165, 131, 68), (148, 110, 87), (128, 128, 190), (121, 120, 190), + (100, 98, 181), (74, 83, 174), (70, 74, 166), (66, 65, 159), + (66, 65, 159), (65, 64, 158), (65, 64, 158), (65, 64, 157), + (62, 62, 152), (98, 81, 111), (135, 100, 70), (135, 100, 71), + (135, 100, 72), (63, 63, 153), (64, 63, 156), (58, 56, 140), + (64, 137, 22), (127, 131, 10), (131, 128, 6), (135, 125, 2), + (154, 137, 5), (155, 138, 8), (156, 139, 9), (158, 141, 11), + (161, 147, 16), (162, 147, 16), (164, 147, 17), (170, 152, 18), + (183, 167, 22), (188, 176, 56), (209, 200, 97), (209, 200, 97), + (216, 210, 148), (234, 198, 200), (228, 174, 176), (222, 150, 153), + (204, 191, 76), (183, 172, 56), (170, 158, 36), (154, 135, 33), + (142, 117, 50), (106, 132, 36), (71, 147, 23), (74, 155, 26), + (76, 159, 27), (121, 186, 82), (135, 191, 100), (134, 190, 99), + (92, 171, 46), (75, 161, 26), (73, 154, 25), (71, 150, 25), + (68, 143, 24), (68, 143, 24), (136, 104, 66), (137, 108, 68), + (177, 161, 22), (191, 171, 20), (205, 181, 19), (254, 227, 13), + (255, 248, 9), (255, 254, 9), (255, 255, 14), (255, 251, 9), + (249, 229, 10), (189, 166, 28), (151, 124, 57), (141, 107, 69), + (149, 112, 85), (154, 122, 61), (175, 151, 55), (182, 153, 61), + (188, 152, 56), (167, 149, 23), (165, 151, 20), (167, 153, 18), + (164, 150, 17), (163, 149, 18), (165, 147, 21), (172, 158, 36), + (178, 166, 54), (154, 197, 126), (231, 201, 201), (228, 227, 223), + (199, 216, 184), (144, 191, 111), (157, 186, 106), (145, 165, 54), + (163, 148, 21), (164, 147, 17), (165, 148, 16), (167, 151, 16), + (169, 153, 18), (170, 153, 23), (179, 162, 20), (181, 164, 22), + (175, 157, 21), (168, 152, 17), (162, 148, 17), (162, 148, 15), + (162, 145, 15), (159, 145, 14), (159, 144, 17), (162, 145, 15), + (160, 141, 12), (158, 140, 12), (156, 138, 12), (160, 141, 12), + (160, 142, 16), (161, 143, 19), (162, 144, 18), (163, 146, 16), + (162, 145, 15), (164, 145, 14), (162, 145, 13), (162, 144, 10), + (160, 144, 5), (157, 141, 4), (155, 139, 4), (156, 137, 6), + (156, 139, 7), (156, 139, 9), (159, 142, 12), (159, 142, 12), + (162, 143, 12), (162, 145, 13), (160, 143, 11), (160, 143, 13) + ), + +// 196 Apophysis-040427-4BflyWindw2 +((2, 2, 2), (28, 75, 93), (34, 90, 96), (41, 106, 100), + (61, 80, 100), (81, 55, 100), (100, 61, 117), (120, 68, 134), + (188, 12, 147), (172, 8, 111), (156, 5, 76), (105, 3, 58), + (54, 2, 40), (43, 4, 38), (33, 6, 37), (35, 8, 39), + (37, 10, 41), (96, 19, 99), (125, 34, 121), (154, 49, 144), + (150, 39, 145), (147, 30, 147), (132, 29, 128), (117, 28, 110), + (54, 17, 61), (32, 8, 34), (11, 0, 8), (6, 1, 5), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (16, 21, 17), (44, 35, 15), (73, 49, 13), + (99, 68, 19), (126, 88, 25), (138, 94, 27), (151, 101, 30), + (188, 113, 11), (210, 112, 22), (232, 112, 34), (212, 136, 41), + (192, 160, 49), (216, 188, 58), (241, 217, 67), (228, 220, 145), + (254, 254, 246), (255, 253, 253), (255, 252, 250), (255, 251, 248), + (253, 153, 233), (252, 56, 218), (230, 58, 201), (209, 61, 185), + (146, 41, 134), (96, 26, 89), (46, 12, 45), (30, 8, 26), + (14, 5, 8), (23, 8, 10), (33, 11, 13), (87, 53, 15), + (123, 82, 30), (185, 196, 104), (190, 191, 137), (195, 186, 171), + (175, 166, 140), (155, 147, 110), (142, 139, 122), (116, 76, 128), + (53, 114, 132), (48, 134, 105), (43, 155, 79), (47, 129, 93), + (51, 104, 108), (44, 101, 108), (38, 98, 109), (37, 99, 114), + (45, 102, 129), (65, 108, 115), (109, 131, 141), (153, 155, 168), + (178, 178, 177), (204, 201, 186), (228, 246, 250), (255, 255, 217), + (130, 195, 191), (140, 130, 179), (150, 65, 168), (156, 67, 173), + (162, 70, 179), (241, 44, 209), (254, 15, 222), (255, 4, 247), + (255, 18, 234), (174, 75, 168), (138, 70, 148), (102, 66, 128), + (100, 70, 125), (99, 75, 123), (86, 86, 78), (124, 102, 63), + (117, 147, 113), (119, 115, 120), (121, 84, 128), (113, 67, 122), + (106, 51, 116), (78, 40, 123), (66, 37, 83), (46, 12, 39), + (24, 6, 22), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (1, 2, 4), (12, 10, 24), (23, 19, 44), (31, 22, 46), + (39, 25, 48), (65, 37, 62), (64, 38, 67), (47, 21, 60), + (18, 38, 49), (12, 15, 30), (6, 7, 20), (0, 0, 11), + (2, 2, 2), (1, 3, 0), (2, 2, 2), (2, 2, 2), + (2, 0, 1), (1, 0, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (17, 23, 19), (14, 69, 37), + (68, 156, 10), (75, 168, 10), (82, 181, 10), (57, 219, 11), + (70, 205, 40), (62, 148, 39), (48, 137, 57), (66, 106, 69), + (68, 104, 30), (55, 65, 30), (39, 43, 25), (23, 22, 20), + (6, 14, 1), (2, 2, 2), (17, 21, 0), (65, 78, 9), + (101, 85, 33), (110, 98, 40), (119, 111, 48), (125, 101, 55), + (107, 97, 48), (72, 59, 43), (23, 32, 31), (9, 20, 16), + (2, 2, 2), (2, 2, 2), (25, 14, 0), (48, 34, 5), + (58, 40, 0), (55, 59, 0), (56, 81, 0), (49, 114, 14), + (157, 183, 22), (166, 186, 15), (175, 189, 8), (163, 172, 45), + (149, 126, 32), (93, 85, 72), (100, 23, 79), (84, 14, 50), + (55, 17, 56), (25, 34, 51), (20, 68, 68), (36, 70, 72), + (47, 86, 85), (69, 79, 78), (69, 67, 89), (106, 24, 90), + (181, 12, 113), (219, 13, 148), (255, 8, 208), (247, 26, 219), + (233, 86, 128), (165, 137, 133), (190, 159, 102), (207, 141, 57), + (176, 119, 40), (135, 86, 27), (136, 35, 49), (109, 5, 66), + (78, 29, 94), (35, 50, 73), (42, 67, 89), (46, 63, 83), + (61, 35, 72), (70, 32, 73), (78, 19, 65), (74, 12, 61), + (64, 5, 51), (44, 1, 31), (33, 8, 30), (29, 3, 28), + (26, 2, 24), (23, 10, 30), (15, 28, 37), (17, 44, 35), + (22, 64, 24), (66, 76, 16), (99, 76, 24), (98, 77, 34), + (116, 74, 24), (110, 67, 16), (114, 66, 0), (127, 79, 13), + (138, 76, 29), (159, 108, 77), (132, 45, 90), (144, 43, 135), + (171, 27, 151), (145, 51, 147), (82, 61, 120), (67, 76, 115), + (66, 78, 76), (60, 46, 59), (75, 45, 53), (70, 55, 48), + (53, 54, 38), (14, 37, 43), (12, 35, 41), (16, 13, 22), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2) + ), + +// 197 Apophysis-040427-4BflyWndw3 +((49, 55, 81), (81, 40, 96), (82, 31, 94), (83, 22, 92), + (68, 17, 67), (53, 12, 42), (26, 6, 21), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (1, 1, 0), + (2, 3, 0), (11, 27, 35), (21, 52, 70), (33, 50, 75), + (46, 49, 80), (78, 41, 93), (94, 37, 100), (111, 33, 108), + (117, 28, 111), (123, 24, 114), (126, 23, 115), (129, 22, 116), + (140, 31, 120), (136, 26, 118), (132, 21, 116), (125, 24, 114), + (119, 27, 112), (114, 35, 108), (109, 43, 105), (150, 147, 116), + (192, 187, 183), (249, 243, 209), (251, 235, 172), (253, 228, 135), + (226, 193, 116), (199, 159, 98), (191, 141, 72), (183, 124, 46), + (137, 99, 37), (108, 77, 26), (80, 55, 15), (40, 27, 7), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (50, 26, 3), (100, 53, 7), (156, 103, 41), + (212, 153, 75), (232, 179, 91), (252, 206, 108), (252, 218, 128), + (183, 190, 138), (125, 161, 147), (106, 116, 86), (88, 71, 25), + (92, 70, 22), (96, 70, 19), (94, 80, 15), (100, 99, 17), + (183, 71, 7), (202, 44, 72), (221, 17, 138), (235, 15, 145), + (250, 13, 153), (228, 103, 148), (207, 193, 144), (252, 217, 133), + (252, 219, 122), (187, 144, 31), (138, 107, 20), (90, 70, 9), + (79, 68, 19), (69, 67, 29), (38, 51, 60), (29, 49, 73), + (35, 58, 76), (48, 78, 52), (61, 98, 29), (66, 120, 26), + (71, 142, 24), (67, 161, 47), (84, 158, 45), (109, 172, 67), + (167, 143, 81), (240, 173, 69), (225, 154, 47), (211, 135, 25), + (191, 119, 27), (172, 104, 29), (136, 77, 7), (113, 67, 7), + (28, 62, 48), (28, 59, 60), (28, 57, 73), (33, 54, 75), + (39, 51, 77), (49, 43, 81), (74, 39, 93), (87, 39, 97), + (95, 33, 100), (98, 39, 103), (95, 41, 102), (93, 43, 102), + (91, 39, 101), (74, 44, 94), (69, 53, 90), (62, 58, 85), + (57, 50, 84), (52, 48, 82), (48, 47, 81), (48, 43, 68), + (48, 39, 56), (69, 45, 19), (83, 54, 14), (85, 64, 17), + (95, 103, 18), (96, 126, 2), (95, 119, 6), (95, 113, 11), + (95, 108, 16), (81, 99, 23), (76, 60, 86), (92, 38, 100), + (110, 27, 107), (106, 28, 105), (102, 30, 103), (103, 31, 103), + (104, 33, 103), (117, 33, 111), (128, 30, 117), (132, 27, 119), + (137, 23, 118), (221, 1, 153), (209, 3, 149), (198, 6, 145), + (146, 27, 129), (131, 31, 117), (110, 37, 108), (146, 115, 97), + (169, 199, 237), (204, 224, 238), (239, 249, 240), (255, 254, 253), + (247, 244, 225), (246, 191, 161), (198, 173, 119), (218, 13, 142), + (249, 3, 150), (247, 3, 160), (240, 4, 160), (234, 5, 160), + (198, 6, 145), (138, 19, 119), (141, 5, 113), (134, 1, 106), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 1, 1), (23, 30, 56), (45, 45, 79), (46, 56, 81), + (38, 49, 77), (31, 41, 71), (25, 34, 65), (27, 9, 33), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (29, 41, 39), (54, 79, 40), (65, 109, 20), (69, 132, 2), + (53, 139, 16), (10, 121, 3), (8, 107, 25), (15, 91, 44), + (22, 76, 63), (20, 56, 70), (22, 53, 71), (21, 61, 73), + (22, 62, 70), (6, 80, 55), (1, 102, 36), (29, 133, 12), + (64, 142, 23), (87, 148, 27), (112, 148, 22), (98, 107, 14), + (63, 101, 26), (65, 60, 83), (75, 53, 92), (87, 50, 94), + (83, 53, 91), (130, 161, 101), (135, 190, 106), (114, 174, 148), + (110, 137, 128), (77, 58, 88), (67, 49, 87), (51, 33, 73), + (24, 32, 78), (2, 20, 42), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (57, 37, 10), + (73, 101, 24), (81, 103, 21), (66, 90, 32), (75, 59, 85), + (79, 42, 94), (88, 38, 99), (89, 47, 97), (78, 54, 90), + (67, 58, 85), (64, 60, 83), (52, 60, 81), (47, 67, 74), + (40, 72, 69), (44, 52, 37), (67, 43, 17), (56, 58, 34), + (36, 46, 38), (30, 53, 45), (33, 51, 75), (46, 58, 80) + ), + +// 198 Apophysis-040427-4ChalLghtDrknss +((93, 98, 130), (225, 205, 198), (232, 213, 201), (240, 221, 204), + (241, 221, 200), (243, 221, 197), (244, 221, 196), (246, 222, 196), + (240, 216, 188), (231, 212, 194), (222, 209, 201), (157, 158, 178), + (93, 107, 156), (85, 95, 138), (78, 84, 120), (86, 87, 115), + (94, 91, 110), (238, 214, 180), (241, 219, 188), (245, 224, 197), + (239, 222, 204), (234, 221, 212), (234, 221, 213), (235, 222, 214), + (228, 218, 219), (222, 213, 219), (217, 209, 220), (223, 214, 219), + (230, 220, 218), (230, 220, 218), (230, 220, 218), (235, 222, 214), + (237, 225, 213), (244, 226, 204), (242, 227, 211), (241, 228, 219), + (242, 231, 222), (244, 234, 225), (242, 232, 225), (240, 231, 226), + (240, 228, 216), (232, 221, 211), (225, 215, 206), (157, 152, 185), + (90, 90, 164), (61, 72, 165), (33, 55, 167), (20, 31, 146), + (23, 43, 114), (41, 45, 70), (51, 54, 67), (62, 63, 65), + (68, 71, 83), (74, 79, 101), (76, 83, 113), (79, 87, 126), + (106, 109, 178), (135, 137, 200), (165, 166, 222), (197, 192, 219), + (229, 218, 216), (233, 220, 211), (238, 222, 207), (244, 226, 206), + (247, 226, 205), (240, 216, 188), (239, 207, 167), (238, 198, 146), + (193, 164, 118), (148, 130, 90), (115, 103, 81), (81, 78, 69), + (69, 66, 51), (69, 65, 48), (70, 65, 45), (72, 72, 52), + (75, 80, 60), (81, 85, 66), (88, 91, 72), (119, 99, 46), + (213, 154, 60), (241, 212, 178), (241, 213, 181), (242, 215, 185), + (239, 214, 183), (236, 213, 182), (217, 200, 180), (113, 114, 116), + (71, 70, 68), (67, 65, 60), (63, 60, 53), (62, 60, 50), + (62, 60, 48), (62, 58, 47), (58, 57, 52), (56, 55, 51), + (51, 49, 50), (27, 30, 39), (16, 18, 25), (5, 6, 11), + (3, 3, 10), (2, 1, 9), (0, 3, 36), (10, 22, 48), + (57, 57, 93), (86, 85, 99), (116, 113, 106), (157, 137, 107), + (198, 161, 108), (246, 199, 143), (234, 188, 126), (121, 114, 106), + (83, 79, 78), (17, 26, 31), (14, 21, 26), (11, 16, 22), + (17, 14, 35), (31, 30, 38), (49, 49, 49), (52, 53, 48), + (59, 58, 40), (63, 60, 45), (67, 63, 51), (69, 65, 49), + (72, 67, 47), (76, 69, 50), (75, 68, 50), (72, 69, 60), + (73, 71, 82), (70, 74, 111), (64, 68, 113), (59, 62, 115), + (50, 66, 177), (95, 104, 209), (108, 115, 222), (176, 177, 221), + (228, 220, 217), (214, 210, 217), (201, 200, 218), (181, 180, 219), + (162, 161, 221), (104, 114, 167), (78, 87, 130), (60, 69, 108), + (54, 60, 74), (27, 26, 32), (18, 18, 22), (10, 11, 13), + (10, 4, 4), (11, 11, 11), (24, 28, 29), (33, 33, 45), + (49, 50, 54), (52, 52, 54), (55, 55, 55), (55, 56, 61), + (62, 62, 62), (65, 64, 59), (64, 63, 58), (67, 63, 51), + (66, 62, 50), (55, 52, 61), (51, 50, 61), (47, 49, 61), + (37, 45, 64), (39, 32, 65), (11, 21, 46), (26, 30, 39), + (59, 58, 66), (64, 64, 70), (69, 70, 75), (91, 92, 96), + (133, 126, 120), (216, 192, 158), (240, 211, 177), (241, 215, 180), + (240, 216, 190), (244, 226, 206), (242, 225, 209), (247, 225, 202), + (242, 222, 198), (241, 216, 185), (230, 214, 191), (192, 182, 181), + (88, 93, 131), (82, 87, 122), (77, 82, 114), (72, 79, 108), + (67, 79, 103), (73, 78, 100), (75, 73, 94), (77, 80, 69), + (71, 68, 59), (71, 67, 55), (72, 66, 52), (72, 66, 50), + (68, 66, 54), (72, 68, 56), (71, 61, 69), (67, 67, 67), + (62, 62, 62), (60, 59, 65), (51, 54, 63), (50, 52, 65), + (55, 52, 63), (62, 62, 64), (65, 69, 70), (63, 66, 75), + (69, 73, 85), (72, 76, 101), (69, 75, 101), (68, 70, 82), + (66, 67, 71), (65, 66, 71), (65, 67, 79), (67, 65, 89), + (67, 65, 89), (65, 65, 89), (57, 62, 81), (50, 52, 67), + (52, 52, 60), (53, 55, 54), (53, 55, 50), (52, 52, 50), + (50, 51, 46), (44, 44, 42), (34, 35, 29), (41, 39, 1), + (44, 47, 40), (51, 52, 46), (52, 52, 50), (54, 55, 50), + (61, 61, 53), (63, 63, 63), (69, 69, 67), (71, 75, 74), + (80, 81, 76), (80, 83, 92), (87, 87, 89), (104, 94, 95), + (115, 112, 97), (95, 94, 99), (79, 78, 92), (77, 81, 110), + (78, 83, 115), (98, 97, 111), (120, 130, 122), (204, 191, 183), + (240, 216, 182), (241, 215, 182), (243, 210, 169), (229, 197, 150), + (118, 109, 110), (68, 71, 80), (18, 27, 56), (56, 62, 96) + ), + +// 199 Apophysis-040427-4ChalicDrknsIce +((153, 141, 41), (36, 39, 30), (25, 32, 35), (14, 26, 40), + (12, 28, 49), (11, 31, 58), (11, 33, 62), (12, 35, 67), + (105, 106, 111), (131, 131, 127), (158, 156, 143), (163, 161, 154), + (168, 167, 165), (169, 168, 167), (170, 170, 170), (171, 171, 170), + (173, 172, 170), (168, 168, 168), (167, 168, 176), (166, 169, 184), + (164, 167, 193), (162, 166, 203), (165, 168, 194), (168, 171, 186), + (171, 173, 185), (174, 176, 184), (178, 179, 184), (175, 176, 183), + (173, 173, 183), (169, 167, 182), (166, 161, 181), (158, 164, 180), + (160, 163, 170), (160, 155, 133), (155, 149, 118), (151, 143, 104), + (92, 93, 77), (34, 43, 50), (27, 36, 45), (21, 29, 40), + (10, 24, 35), (9, 25, 40), (9, 26, 46), (10, 30, 56), + (11, 34, 66), (10, 34, 68), (9, 35, 70), (14, 58, 129), + (102, 116, 161), (160, 157, 148), (160, 159, 154), (161, 161, 161), + (162, 161, 164), (163, 162, 167), (164, 164, 166), (166, 166, 166), + (166, 173, 179), (174, 178, 181), (183, 183, 183), (192, 193, 191), + (201, 203, 200), (201, 202, 203), (202, 201, 207), (201, 204, 223), + (198, 203, 225), (179, 180, 184), (157, 155, 160), (135, 130, 136), + (114, 110, 116), (93, 90, 97), (25, 42, 60), (11, 31, 56), + (15, 31, 47), (52, 58, 61), (89, 85, 76), (121, 116, 101), + (153, 148, 126), (156, 154, 136), (159, 161, 147), (164, 177, 149), + (173, 171, 158), (181, 178, 143), (178, 172, 138), (176, 167, 134), + (167, 162, 135), (158, 157, 137), (153, 158, 136), (163, 161, 149), + (174, 178, 163), (186, 189, 175), (199, 201, 187), (201, 199, 185), + (203, 197, 183), (223, 209, 172), (214, 204, 145), (201, 188, 153), + (186, 182, 171), (163, 166, 181), (161, 164, 175), (159, 162, 169), + (159, 160, 165), (159, 159, 161), (148, 156, 145), (142, 143, 129), + (11, 48, 101), (19, 64, 142), (27, 80, 184), (38, 88, 193), + (49, 96, 202), (91, 117, 192), (105, 124, 183), (141, 150, 183), + (150, 155, 161), (144, 145, 150), (114, 120, 143), (84, 96, 136), + (28, 42, 68), (13, 33, 60), (9, 29, 56), (7, 25, 47), + (5, 22, 40), (7, 21, 36), (9, 21, 33), (9, 19, 28), + (10, 17, 23), (8, 15, 21), (14, 19, 25), (18, 26, 28), + (38, 40, 27), (106, 117, 83), (129, 130, 95), (152, 144, 107), + (179, 164, 143), (195, 192, 183), (221, 213, 194), (233, 221, 199), + (241, 226, 193), (226, 217, 209), (212, 208, 225), (208, 209, 228), + (204, 210, 232), (233, 227, 241), (238, 232, 244), (224, 225, 207), + (218, 221, 202), (190, 187, 180), (186, 181, 178), (182, 176, 176), + (168, 168, 166), (162, 158, 146), (146, 143, 128), (116, 116, 106), + (27, 36, 45), (33, 37, 43), (39, 39, 41), (93, 96, 85), + (124, 125, 120), (153, 150, 141), (185, 172, 163), (195, 191, 182), + (206, 202, 201), (212, 206, 218), (208, 202, 214), (205, 199, 211), + (185, 185, 193), (186, 186, 188), (178, 179, 184), (173, 174, 179), + (175, 175, 177), (176, 176, 175), (177, 178, 173), (182, 179, 172), + (185, 177, 175), (191, 181, 171), (190, 181, 172), (186, 185, 181), + (187, 185, 186), (182, 183, 188), (181, 181, 191), (181, 180, 198), + (183, 184, 189), (183, 183, 185), (183, 183, 183), (178, 177, 182), + (173, 173, 181), (172, 172, 180), (171, 171, 179), (173, 173, 173), + (174, 171, 166), (168, 167, 163), (175, 172, 163), (177, 175, 152), + (180, 174, 138), (162, 157, 138), (159, 159, 151), (163, 162, 158), + (167, 168, 163), (172, 172, 164), (167, 167, 159), (167, 164, 155), + (154, 153, 133), (149, 136, 119), (118, 119, 113), (75, 75, 63), + (34, 44, 43), (19, 28, 35), (15, 24, 31), (13, 22, 29), + (13, 22, 29), (8, 18, 30), (7, 17, 27), (4, 16, 28), + (7, 19, 31), (6, 20, 33), (6, 19, 35), (11, 23, 35), + (13, 22, 31), (14, 23, 30), (14, 24, 36), (15, 24, 41), + (7, 24, 42), (11, 26, 45), (8, 30, 54), (7, 30, 61), + (9, 29, 56), (12, 28, 53), (9, 27, 51), (11, 29, 53), + (11, 30, 60), (11, 35, 69), (55, 59, 94), (93, 108, 151), + (134, 146, 188), (151, 158, 186), (162, 159, 150), (154, 143, 115), + (142, 132, 79), (75, 74, 26), (55, 56, 25), (37, 41, 26), + (19, 27, 29), (18, 26, 29), (18, 26, 28), (17, 25, 27), + (15, 24, 29), (17, 24, 30), (18, 26, 29), (24, 33, 40), + (48, 51, 24), (61, 63, 24), (143, 133, 38), (164, 149, 48), + (201, 178, 64), (177, 156, 101), (158, 150, 113), (143, 140, 121) + ), + +// 200 Apophysis-040427-4CactusFlwer +((130, 133, 104), (131, 131, 103), (155, 120, 100), (180, 110, 98), + (191, 135, 116), (202, 160, 135), (189, 164, 134), (177, 169, 133), + (134, 134, 108), (128, 126, 108), (122, 118, 109), (119, 123, 100), + (116, 128, 92), (118, 118, 84), (120, 109, 77), (117, 106, 77), + (114, 104, 77), (123, 97, 84), (129, 99, 78), (135, 101, 73), + (123, 106, 73), (111, 111, 73), (111, 112, 73), (111, 113, 74), + (97, 121, 63), (93, 105, 58), (90, 90, 54), (94, 94, 63), + (99, 99, 73), (101, 101, 78), (104, 103, 83), (124, 106, 104), + (132, 126, 114), (183, 182, 162), (216, 203, 200), (249, 225, 239), + (235, 205, 212), (222, 186, 186), (227, 167, 162), (233, 149, 138), + (151, 133, 97), (133, 124, 89), (115, 116, 82), (122, 120, 91), + (129, 125, 100), (135, 126, 108), (142, 128, 117), (169, 168, 147), + (190, 189, 171), (201, 198, 215), (211, 216, 218), (221, 235, 222), + (215, 231, 215), (210, 227, 208), (207, 216, 200), (205, 206, 192), + (178, 198, 186), (171, 195, 163), (164, 192, 141), (164, 197, 159), + (165, 203, 178), (175, 193, 174), (186, 184, 171), (181, 180, 162), + (170, 171, 153), (124, 132, 134), (108, 117, 107), (93, 102, 81), + (91, 92, 72), (90, 83, 64), (91, 73, 59), (70, 71, 53), + (61, 61, 51), (60, 56, 43), (60, 51, 36), (61, 51, 34), + (63, 52, 32), (66, 58, 32), (70, 65, 33), (77, 74, 41), + (78, 87, 56), (117, 121, 96), (136, 137, 116), (155, 154, 136), + (158, 157, 135), (161, 161, 135), (157, 157, 129), (155, 148, 104), + (115, 130, 73), (104, 105, 60), (94, 81, 47), (86, 78, 45), + (78, 75, 44), (80, 77, 42), (98, 63, 25), (106, 73, 32), + (104, 84, 49), (111, 114, 93), (122, 129, 116), (134, 145, 139), + (149, 154, 139), (164, 164, 140), (172, 172, 148), (176, 175, 154), + (189, 182, 153), (175, 173, 149), (162, 165, 146), (142, 159, 142), + (122, 154, 139), (107, 120, 113), (88, 106, 92), (84, 92, 71), + (78, 82, 55), (79, 100, 59), (87, 98, 62), (95, 96, 65), + (105, 109, 76), (117, 127, 102), (123, 146, 118), (156, 167, 133), + (162, 162, 138), (149, 150, 116), (137, 138, 94), (133, 123, 87), + (130, 109, 80), (134, 89, 60), (146, 72, 69), (123, 74, 60), + (122, 83, 42), (68, 52, 36), (63, 46, 27), (59, 41, 19), + (29, 20, 11), (27, 21, 0), (20, 20, 8), (20, 20, 8), + (24, 24, 12), (36, 35, 19), (49, 47, 26), (52, 46, 25), + (56, 45, 25), (53, 43, 16), (42, 39, 6), (48, 46, 0), + (62, 53, 0), (55, 52, 19), (56, 52, 20), (57, 52, 22), + (54, 56, 34), (63, 64, 32), (66, 68, 31), (66, 65, 37), + (72, 72, 46), (68, 70, 44), (65, 69, 42), (62, 65, 38), + (61, 61, 35), (45, 51, 37), (39, 44, 21), (29, 32, 21), + (24, 28, 11), (43, 59, 32), (50, 61, 36), (58, 63, 41), + (82, 78, 49), (106, 87, 54), (112, 94, 72), (108, 109, 75), + (110, 116, 56), (109, 109, 58), (108, 103, 61), (105, 106, 75), + (114, 97, 67), (129, 111, 49), (131, 97, 33), (136, 105, 59), + (138, 118, 65), (148, 113, 81), (151, 110, 80), (161, 101, 90), + (143, 126, 100), (129, 104, 97), (110, 96, 83), (90, 90, 54), + (64, 74, 37), (62, 69, 32), (61, 65, 28), (65, 63, 22), + (60, 66, 28), (57, 63, 35), (58, 67, 36), (70, 71, 40), + (78, 77, 46), (91, 91, 55), (99, 99, 75), (106, 97, 92), + (128, 109, 102), (133, 130, 115), (161, 161, 137), (194, 177, 147), + (227, 215, 81), (238, 224, 65), (229, 215, 67), (161, 183, 118), + (172, 169, 134), (172, 171, 151), (174, 158, 158), (169, 157, 159), + (134, 154, 189), (163, 163, 175), (186, 184, 169), (186, 187, 173), + (193, 194, 178), (189, 200, 192), (225, 217, 181), (254, 252, 178), + (255, 252, 199), (250, 247, 228), (238, 254, 243), (238, 246, 255), + (224, 230, 252), (233, 244, 250), (254, 255, 197), (255, 244, 144), + (249, 225, 115), (255, 252, 103), (248, 246, 145), (222, 201, 174), + (198, 160, 149), (188, 150, 139), (160, 131, 117), (136, 135, 104), + (130, 131, 100), (130, 125, 96), (128, 114, 85), (106, 100, 78), + (93, 97, 72), (92, 91, 60), (94, 77, 59), (96, 74, 60), + (76, 71, 49), (69, 71, 47), (59, 63, 40), (62, 55, 39), + (45, 54, 33), (46, 49, 20), (43, 43, 15), (50, 51, 17), + (57, 57, 21), (70, 75, 34), (90, 89, 24), (97, 90, 48), + (96, 97, 66), (102, 103, 72), (107, 108, 74), (151, 142, 113) + ), + +// 201 Apophysis-040427-4ChrryBlssmT +((254, 188, 202), (254, 220, 208), (253, 227, 196), (253, 235, 185), + (230, 212, 157), (208, 189, 130), (171, 179, 118), (135, 170, 106), + (31, 109, 83), (62, 136, 109), (94, 164, 136), (152, 177, 136), + (211, 190, 137), (233, 197, 148), (255, 204, 159), (255, 211, 173), + (255, 218, 187), (255, 225, 212), (253, 224, 211), (252, 224, 210), + (240, 212, 192), (228, 201, 174), (223, 199, 159), (218, 198, 145), + (208, 178, 128), (211, 183, 132), (214, 188, 137), (221, 205, 151), + (228, 223, 165), (231, 228, 170), (235, 233, 176), (235, 233, 176), + (233, 233, 179), (235, 235, 181), (233, 230, 174), (231, 226, 168), + (225, 215, 158), (219, 204, 149), (216, 195, 142), (213, 187, 136), + (208, 174, 128), (205, 169, 122), (202, 164, 117), (173, 149, 128), + (145, 134, 140), (124, 135, 130), (103, 137, 120), (47, 101, 75), + (11, 50, 32), (38, 21, 5), (32, 10, 15), (27, 0, 26), + (35, 3, 38), (44, 7, 50), (45, 19, 54), (47, 31, 58), + (103, 114, 84), (163, 165, 119), (223, 217, 155), (238, 224, 183), + (253, 232, 211), (254, 231, 212), (255, 230, 213), (252, 237, 206), + (252, 241, 211), (241, 243, 196), (230, 224, 173), (220, 205, 150), + (214, 190, 143), (209, 175, 137), (220, 139, 148), (228, 122, 145), + (234, 111, 174), (242, 134, 181), (250, 157, 188), (249, 161, 189), + (248, 165, 191), (227, 151, 179), (206, 137, 168), (198, 135, 164), + (198, 147, 144), (202, 164, 117), (202, 166, 120), (203, 169, 123), + (203, 170, 124), (204, 172, 125), (206, 176, 126), (211, 181, 131), + (229, 215, 150), (224, 220, 171), (219, 226, 193), (235, 223, 201), + (252, 220, 209), (255, 207, 203), (254, 197, 203), (248, 186, 191), + (251, 172, 177), (199, 161, 114), (194, 149, 106), (190, 138, 98), + (190, 136, 98), (191, 135, 98), (188, 129, 95), (187, 128, 94), + (180, 120, 86), (184, 113, 76), (188, 106, 66), (176, 88, 51), + (164, 71, 37), (111, 38, 19), (108, 24, 24), (37, 11, 36), + (10, 0, 53), (8, 0, 52), (10, 0, 43), (12, 0, 34), + (18, 16, 21), (0, 19, 38), (10, 59, 64), (62, 113, 57), + (191, 139, 99), (183, 137, 118), (176, 136, 137), (134, 131, 128), + (92, 127, 120), (60, 85, 81), (57, 41, 67), (41, 31, 58), + (28, 7, 48), (15, 39, 77), (32, 53, 76), (49, 68, 75), + (53, 111, 99), (79, 150, 120), (102, 161, 129), (137, 179, 143), + (180, 140, 149), (193, 156, 137), (207, 173, 125), (211, 177, 134), + (215, 181, 143), (237, 195, 181), (230, 194, 198), (246, 194, 206), + (252, 193, 211), (253, 196, 202), (250, 191, 198), (248, 187, 195), + (255, 188, 183), (255, 166, 166), (216, 175, 143), (197, 148, 131), + (102, 76, 89), (77, 58, 77), (53, 41, 65), (40, 13, 48), + (19, 1, 53), (12, 2, 52), (6, 0, 53), (3, 0, 53), + (3, 0, 53), (1, 50, 46), (7, 53, 30), (14, 57, 14), + (8, 96, 38), (56, 82, 17), (45, 111, 37), (109, 112, 93), + (184, 124, 90), (180, 113, 82), (177, 103, 74), (154, 78, 46), + (110, 71, 32), (54, 34, 36), (33, 29, 44), (47, 36, 66), + (71, 64, 72), (171, 113, 75), (224, 99, 93), (214, 140, 91), + (199, 156, 113), (204, 168, 120), (204, 170, 124), (206, 172, 124), + (203, 166, 121), (200, 160, 115), (198, 155, 110), (191, 142, 101), + (191, 139, 99), (187, 128, 94), (185, 132, 92), (162, 164, 81), + (157, 175, 117), (119, 173, 147), (140, 182, 132), (194, 193, 129), + (223, 210, 155), (232, 227, 171), (235, 242, 191), (243, 245, 195), + (248, 247, 203), (253, 245, 206), (251, 243, 207), (250, 239, 207), + (253, 228, 208), (254, 214, 206), (255, 204, 195), (241, 177, 194), + (251, 163, 188), (228, 132, 170), (195, 128, 135), (111, 84, 63), + (70, 40, 52), (41, 48, 17), (56, 74, 16), (142, 101, 49), + (177, 114, 81), (196, 147, 106), (210, 181, 137), (232, 215, 163), + (233, 234, 176), (246, 244, 196), (249, 244, 204), (253, 242, 212), + (255, 242, 207), (254, 240, 203), (236, 236, 182), (228, 222, 164), + (218, 196, 139), (208, 177, 130), (203, 167, 119), (200, 157, 114), + (196, 151, 109), (194, 150, 105), (196, 151, 109), (195, 146, 114), + (197, 152, 113), (198, 155, 112), (216, 156, 122), (225, 169, 122), + (250, 159, 156), (242, 194, 180), (239, 241, 194), (247, 246, 202), + (250, 246, 217), (252, 244, 223), (249, 255, 216), (242, 251, 206), + (245, 247, 200), (245, 247, 197), (241, 243, 193), (235, 235, 181), + (232, 233, 175), (230, 231, 173), (223, 212, 156), (228, 230, 165) + ), + +// 202 Apophysis-040427-4ChrryBlssm2 +((221, 222, 178), (228, 234, 188), (234, 236, 177), (241, 238, 167), + (246, 227, 171), (252, 217, 175), (253, 199, 183), (255, 182, 191), + (253, 202, 207), (254, 210, 220), (255, 219, 234), (255, 220, 223), + (255, 222, 213), (252, 232, 213), (250, 243, 214), (248, 244, 212), + (246, 246, 210), (250, 244, 222), (251, 243, 223), (253, 242, 224), + (246, 244, 214), (239, 246, 205), (238, 245, 202), (237, 244, 200), + (233, 238, 198), (229, 234, 190), (225, 231, 183), (208, 211, 169), + (191, 191, 155), (173, 186, 143), (155, 182, 131), (85, 149, 115), + (0, 88, 106), (0, 44, 75), (35, 73, 99), (70, 102, 123), + (126, 166, 151), (183, 231, 179), (196, 239, 189), (209, 247, 200), + (237, 241, 206), (244, 242, 219), (252, 244, 233), (253, 246, 235), + (255, 249, 238), (255, 246, 232), (255, 243, 227), (251, 241, 214), + (246, 243, 208), (231, 239, 192), (229, 236, 189), (227, 233, 187), + (220, 220, 177), (213, 208, 168), (205, 193, 157), (198, 179, 147), + (165, 111, 101), (94, 72, 59), (23, 34, 17), (11, 53, 8), + (0, 73, 0), (0, 80, 34), (0, 87, 69), (78, 121, 112), + (124, 162, 125), (91, 169, 121), (45, 139, 118), (0, 110, 116), + (27, 118, 129), (55, 127, 142), (129, 141, 139), (180, 152, 130), + (198, 169, 125), (205, 194, 124), (213, 219, 123), (219, 224, 151), + (225, 229, 179), (225, 230, 182), (226, 232, 186), (229, 235, 191), + (230, 236, 190), (228, 236, 189), (226, 232, 186), (225, 228, 183), + (223, 225, 181), (222, 223, 179), (217, 216, 172), (197, 198, 164), + (199, 180, 148), (202, 186, 151), (206, 192, 155), (205, 193, 155), + (204, 195, 156), (227, 203, 159), (228, 189, 150), (216, 160, 133), + (239, 129, 142), (235, 108, 179), (215, 115, 173), (196, 123, 168), + (179, 117, 134), (162, 112, 101), (65, 78, 87), (31, 34, 69), + (0, 0, 64), (0, 3, 64), (1, 7, 65), (0, 14, 66), + (0, 21, 68), (44, 64, 91), (111, 114, 123), (169, 126, 110), + (171, 123, 109), (76, 100, 100), (66, 75, 68), (56, 50, 36), + (36, 15, 46), (0, 3, 48), (1, 1, 51), (0, 0, 52), + (0, 1, 58), (0, 13, 66), (0, 26, 75), (0, 35, 72), + (1, 45, 70), (39, 81, 80), (159, 137, 96), (176, 137, 120), + (185, 153, 132), (195, 172, 141), (194, 169, 140), (193, 167, 140), + (187, 157, 131), (184, 152, 131), (184, 150, 125), (186, 156, 130), + (194, 171, 140), (200, 182, 148), (207, 193, 156), (220, 195, 155), + (234, 197, 155), (249, 217, 170), (253, 207, 207), (253, 203, 214), + (253, 196, 213), (222, 200, 213), (220, 203, 198), (219, 207, 183), + (193, 163, 175), (187, 155, 134), (179, 137, 121), (180, 117, 136), + (118, 21, 30), (95, 18, 22), (72, 16, 15), (34, 16, 2), + (20, 32, 8), (22, 63, 57), (89, 113, 97), (176, 138, 119), + (198, 179, 147), (223, 229, 183), (222, 228, 182), (222, 228, 182), + (207, 203, 158), (196, 173, 142), (180, 142, 123), (176, 96, 109), + (85, 33, 22), (69, 20, 21), (54, 8, 21), (39, 0, 8), + (14, 8, 34), (0, 0, 47), (0, 0, 56), (1, 0, 57), + (1, 1, 55), (0, 0, 52), (0, 1, 47), (0, 26, 11), + (0, 32, 0), (0, 5, 0), (23, 0, 12), (30, 0, 5), + (33, 22, 4), (20, 23, 5), (8, 25, 6), (0, 14, 38), + (0, 28, 61), (0, 34, 83), (4, 67, 98), (59, 127, 146), + (151, 132, 138), (175, 133, 117), (174, 132, 116), (124, 148, 86), + (33, 83, 74), (17, 18, 62), (1, 5, 69), (0, 0, 57), + (0, 0, 56), (0, 0, 56), (1, 1, 61), (2, 1, 71), + (0, 4, 71), (0, 13, 68), (12, 28, 62), (55, 89, 101), + (167, 117, 106), (216, 101, 140), (228, 102, 149), (244, 139, 146), + (253, 144, 186), (255, 144, 193), (247, 131, 194), (255, 141, 215), + (251, 151, 205), (255, 157, 198), (252, 178, 213), (254, 190, 214), + (254, 209, 214), (254, 216, 215), (254, 221, 212), (248, 220, 206), + (238, 210, 198), (227, 210, 194), (218, 217, 173), (211, 203, 164), + (199, 180, 148), (195, 169, 146), (190, 158, 137), (180, 142, 123), + (178, 140, 121), (129, 145, 108), (80, 111, 103), (18, 59, 61), + (0, 53, 56), (0, 74, 88), (17, 127, 128), (107, 157, 132), + (142, 161, 97), (168, 163, 121), (190, 160, 134), (193, 169, 141), + (225, 162, 181), (222, 133, 179), (225, 137, 187), (255, 183, 207), + (251, 211, 212), (253, 224, 216), (251, 243, 206), (240, 237, 204), + (238, 246, 199), (237, 245, 198), (232, 239, 195), (227, 233, 187) + ), + +// 203 Apophysis-040427-4CircAmbr +((40, 17, 1), (38, 16, 2), (40, 16, 2), (43, 17, 2), + (49, 20, 1), (55, 23, 0), (65, 26, 3), (75, 29, 6), + (124, 75, 6), (155, 99, 9), (187, 123, 13), (209, 138, 26), + (231, 154, 40), (215, 142, 29), (200, 130, 18), (197, 123, 13), + (194, 117, 9), (155, 90, 0), (156, 87, 1), (157, 85, 3), + (177, 105, 6), (197, 126, 10), (202, 129, 15), (208, 132, 20), + (222, 145, 29), (212, 138, 18), (202, 131, 7), (176, 109, 3), + (151, 87, 0), (130, 72, 0), (110, 58, 0), (88, 43, 1), + (60, 24, 0), (86, 37, 4), (119, 63, 2), (153, 89, 1), + (198, 127, 27), (243, 165, 54), (248, 173, 63), (253, 181, 73), + (253, 184, 80), (238, 165, 55), (224, 147, 31), (216, 138, 25), + (208, 130, 19), (206, 131, 20), (204, 132, 21), (198, 122, 12), + (172, 98, 3), (114, 89, 49), (91, 61, 25), (69, 33, 1), + (59, 26, 1), (49, 20, 2), (48, 19, 1), (47, 19, 0), + (44, 18, 1), (43, 17, 1), (42, 16, 1), (42, 16, 1), + (42, 16, 1), (42, 16, 1), (42, 16, 1), (42, 16, 1), + (42, 16, 1), (42, 16, 1), (42, 15, 1), (42, 14, 2), + (41, 14, 1), (40, 14, 0), (40, 14, 0), (39, 16, 0), + (38, 15, 0), (38, 15, 0), (38, 15, 1), (38, 15, 0), + (38, 15, 0), (38, 15, 0), (39, 16, 0), (42, 15, 0), + (43, 14, 0), (42, 16, 1), (42, 16, 0), (43, 17, 0), + (43, 18, 0), (44, 19, 0), (44, 19, 0), (45, 18, 1), + (45, 18, 1), (45, 18, 1), (45, 18, 1), (45, 18, 1), + (45, 18, 1), (45, 18, 1), (45, 18, 0), (46, 19, 0), + (49, 21, 0), (68, 29, 0), (93, 46, 1), (118, 64, 2), + (132, 72, 5), (147, 80, 9), (156, 109, 39), (142, 134, 87), + (255, 195, 97), (254, 202, 107), (253, 210, 118), (252, 211, 121), + (252, 212, 125), (234, 211, 131), (252, 225, 158), (251, 218, 123), + (251, 206, 113), (228, 150, 39), (212, 136, 26), (197, 123, 14), + (159, 95, 7), (130, 72, 0), (106, 55, 0), (75, 35, 0), + (47, 18, 0), (43, 17, 0), (39, 16, 0), (38, 15, 0), + (38, 15, 1), (38, 15, 1), (39, 16, 0), (39, 16, 0), + (39, 16, 0), (43, 17, 0), (43, 17, 0), (44, 17, 0), + (44, 17, 0), (44, 18, 1), (45, 18, 1), (45, 18, 1), + (47, 19, 0), (47, 19, 0), (48, 20, 0), (48, 21, 0), + (49, 22, 0), (52, 21, 0), (52, 21, 0), (52, 21, 0), + (52, 21, 0), (48, 20, 0), (47, 19, 0), (46, 19, 0), + (45, 18, 0), (43, 17, 0), (42, 16, 0), (39, 16, 0), + (39, 16, 0), (39, 16, 0), (39, 16, 0), (39, 16, 0), + (39, 16, 0), (42, 16, 0), (43, 17, 0), (44, 17, 0), + (44, 17, 0), (45, 18, 1), (45, 18, 1), (45, 18, 1), + (45, 18, 1), (45, 18, 1), (45, 18, 1), (45, 18, 1), + (47, 18, 0), (47, 18, 0), (48, 19, 1), (50, 22, 1), + (49, 20, 2), (93, 46, 4), (108, 58, 9), (113, 55, 5), + (101, 51, 0), (75, 37, 1), (60, 24, 0), (52, 21, 0), + (52, 21, 0), (48, 20, 0), (45, 18, 0), (45, 18, 1), + (46, 19, 0), (46, 19, 0), (47, 20, 0), (52, 21, 1), + (61, 25, 0), (73, 33, 0), (94, 47, 5), (108, 56, 0), + (110, 58, 0), (111, 56, 0), (97, 49, 0), (72, 28, 0), + (58, 23, 1), (53, 22, 2), (51, 20, 0), (45, 18, 0), + (43, 17, 0), (42, 16, 1), (42, 16, 1), (42, 16, 1), + (43, 16, 0), (43, 17, 0), (43, 17, 0), (43, 17, 0), + (42, 16, 1), (41, 15, 0), (39, 16, 0), (39, 16, 0), + (39, 16, 0), (39, 16, 0), (41, 15, 0), (44, 15, 0), + (49, 13, 0), (52, 18, 0), (53, 21, 0), (60, 24, 0), + (82, 38, 0), (101, 50, 3), (109, 58, 1), (119, 65, 3), + (137, 78, 0), (147, 81, 3), (160, 90, 2), (142, 84, 2), + (133, 74, 0), (132, 74, 1), (119, 83, 9), (125, 71, 0), + (123, 68, 1), (114, 67, 0), (87, 54, 0), (70, 31, 0), + (56, 26, 2), (51, 20, 0), (47, 18, 0), (44, 17, 0), + (42, 16, 0), (39, 16, 0), (38, 15, 1), (37, 15, 1), + (37, 15, 1), (37, 15, 1), (35, 14, 0), (28, 8, 0), + (36, 12, 0), (37, 15, 1), (37, 15, 1), (37, 15, 1), + (38, 15, 1), (38, 17, 0), (39, 18, 1), (41, 20, 3) + ), + +// 204 Apophysis-040427-4CsmcOwl +((63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (52, 37, 138), (36, 20, 87), (21, 4, 36), (10, 2, 18), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 1, 1), (4, 0, 22), (7, 0, 44), + (5, 0, 57), (4, 1, 70), (12, 4, 83), (20, 7, 97), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (67, 52, 157), (116, 104, 187), (166, 156, 217), (140, 130, 208), + (115, 104, 200), (89, 76, 177), (64, 49, 154), (63, 47, 154), + (63, 47, 154), (85, 82, 113), (115, 100, 92), (145, 118, 71), + (167, 114, 74), (190, 110, 77), (178, 108, 87), (166, 106, 98), + (66, 55, 147), (64, 51, 150), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (69, 51, 171), + (134, 121, 211), (203, 197, 211), (209, 201, 206), (216, 205, 201), + (211, 203, 206), (207, 201, 211), (204, 185, 205), (179, 171, 220), + (36, 191, 193), (48, 214, 164), (61, 237, 136), (62, 170, 136), + (63, 104, 136), (63, 75, 145), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 44, 152), + (23, 17, 63), (11, 11, 31), (0, 5, 0), (0, 4, 0), + (1, 3, 0), (3, 0, 28), (28, 10, 60), (22, 9, 97), + (59, 43, 152), (63, 47, 154), (62, 46, 153), (61, 45, 152), + (50, 35, 137), (40, 26, 123), (36, 0, 68), (32, 19, 26), + (4, 29, 0), (45, 30, 1), (87, 32, 2), (96, 30, 1), + (106, 29, 0), (104, 29, 8), (133, 11, 32), (120, 9, 41), + (105, 3, 68), (61, 45, 154), (53, 36, 147), (45, 28, 140), + (17, 4, 92), (5, 0, 64), (0, 0, 44), (3, 3, 31), + (21, 0, 63), (29, 14, 97), (37, 29, 132), (49, 37, 142), + (62, 46, 153), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (138, 115, 187), (157, 130, 174), (177, 146, 161), + (215, 185, 177), (164, 160, 174), (94, 158, 170), (80, 160, 151), + (128, 104, 78), (145, 91, 59), (162, 78, 41), (148, 73, 33), + (135, 68, 26), (69, 72, 65), (58, 65, 109), (63, 47, 154), + (63, 47, 154), (57, 65, 114), (72, 73, 97), (87, 81, 81), + (121, 98, 56), (168, 136, 51), (214, 133, 42), (228, 114, 17), + (190, 110, 75), (192, 112, 80), (194, 115, 85), (185, 182, 103), + (225, 183, 169), (211, 197, 196), (215, 186, 178), (216, 167, 153), + (213, 154, 136), (192, 113, 82), (170, 110, 82), (149, 107, 83), + (88, 86, 63), (77, 95, 99), (87, 127, 126), (108, 108, 198), + (100, 83, 195), (81, 66, 176), (62, 49, 157), (63, 47, 154), + (63, 47, 154), (70, 48, 95), (60, 48, 148), (63, 47, 154), + (69, 50, 142), (114, 84, 56), (142, 57, 37), (136, 52, 16), + (136, 52, 15), (128, 40, 2), (111, 32, 2), (105, 37, 2), + (81, 18, 45), (73, 9, 66), (66, 0, 87), (61, 46, 151), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (67, 55, 103), (76, 43, 62), + (101, 44, 24), (111, 18, 62), (62, 47, 152), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (61, 46, 149), (44, 42, 63), (62, 56, 4), (68, 40, 0), + (65, 36, 4), (37, 22, 27), (29, 0, 2), (6, 0, 4), + (33, 2, 0), (70, 7, 0), (88, 1, 0), (118, 32, 0), + (132, 48, 4), (134, 49, 12), (132, 57, 28), (94, 56, 81), + (70, 48, 149), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154), + (63, 47, 154), (63, 47, 154), (63, 47, 154), (63, 47, 154) + ), + +// 205 Apophysis-040427-4DblBeetle +((174, 77, 26), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (177, 80, 29), (174, 77, 26), + (174, 77, 26), (175, 77, 25), (177, 77, 25), (179, 80, 29), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (174, 77, 26), + (171, 74, 23), (68, 29, 92), (37, 22, 118), (7, 16, 145), + (20, 31, 164), (33, 46, 184), (43, 56, 181), (54, 66, 178), + (40, 48, 157), (56, 40, 122), (72, 33, 88), (123, 55, 57), + (174, 77, 26), (177, 80, 29), (181, 84, 33), (181, 84, 33), + (188, 93, 35), (192, 92, 40), (200, 100, 47), (208, 109, 54), + (158, 108, 120), (109, 108, 186), (110, 117, 202), (111, 126, 219), + (204, 176, 190), (224, 171, 137), (245, 167, 84), (227, 138, 68), + (209, 110, 53), (200, 101, 46), (192, 92, 40), (173, 76, 25), + (140, 48, 0), (55, 0, 58), (67, 5, 47), (80, 10, 36), + (108, 27, 18), (136, 45, 1), (173, 76, 25), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (183, 84, 33), + (192, 92, 40), (200, 100, 47), (208, 109, 54), (216, 117, 60), + (231, 132, 75), (240, 167, 122), (245, 156, 107), (250, 146, 93), + (247, 146, 91), (245, 146, 89), (228, 129, 72), (223, 123, 71), + (201, 106, 48), (196, 98, 43), (191, 91, 39), (186, 87, 36), + (181, 84, 33), (174, 77, 26), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (130, 100, 110), (128, 109, 120), (127, 119, 130), + (147, 118, 113), (168, 117, 96), (200, 100, 48), (192, 92, 40), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (147, 52, 4), (83, 26, 43), (19, 0, 82), (11, 1, 97), + (3, 3, 113), (0, 8, 132), (5, 14, 131), (20, 23, 94), + (67, 2, 45), (171, 74, 23), (172, 75, 24), (174, 77, 26), + (180, 87, 26), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (211, 98, 32), (204, 98, 37), (197, 98, 43), (198, 99, 45), + (200, 100, 48), (199, 99, 47), (192, 92, 40), (192, 92, 40), + (192, 92, 40), (192, 92, 40), (192, 92, 40), (192, 92, 40), + (191, 91, 39), (191, 91, 39), (186, 89, 36), (181, 84, 33), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (181, 84, 33), (181, 84, 33), (174, 77, 26), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (173, 76, 25), + (94, 22, 7), (73, 13, 33), (52, 5, 59), (18, 9, 88), + (5, 13, 94), (1, 14, 108), (16, 26, 95), (40, 8, 73), + (118, 47, 45), (174, 77, 26), (174, 77, 26), (173, 75, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (181, 84, 33), (181, 84, 33), (181, 84, 33), (181, 84, 33), + (184, 87, 34), (192, 92, 40), (200, 100, 48), (208, 109, 52), + (234, 147, 70), (238, 191, 135), (253, 245, 164), (255, 248, 178), + (212, 211, 219), (203, 216, 233), (164, 160, 211), (153, 181, 202), + (182, 178, 141), (174, 110, 64), (195, 98, 45), (192, 92, 40), + (181, 84, 33), (179, 82, 29), (174, 77, 26), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (174, 77, 26), (174, 77, 26), (174, 77, 26), (174, 77, 26), + (181, 84, 33), (109, 97, 111), (63, 76, 190), (48, 72, 198), + (66, 81, 226), (67, 80, 236), (115, 124, 251), (134, 135, 251), + (132, 147, 240), (107, 122, 249), (74, 85, 201), (66, 78, 196), + (65, 76, 194), (84, 91, 179), (119, 88, 147), (90, 75, 94) + ), + +// 206 Apophysis-040427-4DrkMantis +((45, 96, 1), (96, 132, 0), (69, 113, 0), (43, 94, 1), + (37, 90, 0), (31, 87, 0), (31, 77, 0), (31, 68, 0), + (27, 66, 0), (28, 75, 0), (29, 84, 0), (39, 90, 0), + (49, 96, 0), (86, 97, 0), (123, 99, 0), (116, 99, 0), + (109, 100, 0), (44, 95, 0), (39, 84, 0), (34, 74, 1), + (58, 81, 0), (82, 88, 0), (86, 91, 0), (90, 94, 0), + (144, 107, 0), (158, 126, 0), (173, 145, 0), (166, 155, 0), + (160, 165, 0), (159, 164, 0), (158, 163, 0), (143, 145, 0), + (125, 147, 2), (90, 129, 0), (63, 128, 1), (36, 128, 3), + (31, 106, 1), (26, 84, 0), (21, 77, 0), (17, 70, 0), + (9, 51, 3), (8, 40, 2), (7, 30, 1), (8, 37, 1), + (9, 45, 1), (13, 48, 1), (18, 52, 1), (21, 51, 1), + (28, 50, 1), (44, 41, 0), (58, 33, 1), (72, 26, 3), + (91, 46, 1), (110, 67, 0), (113, 72, 0), (116, 77, 0), + (168, 74, 0), (145, 82, 0), (122, 91, 0), (129, 100, 0), + (136, 110, 0), (136, 116, 0), (137, 123, 0), (163, 140, 2), + (183, 161, 0), (205, 168, 1), (194, 163, 0), (183, 159, 0), + (176, 151, 0), (169, 144, 0), (155, 135, 2), (125, 115, 0), + (50, 73, 1), (42, 64, 0), (35, 56, 0), (33, 58, 0), + (31, 61, 1), (32, 62, 1), (33, 63, 1), (43, 68, 0), + (53, 66, 0), (96, 84, 0), (93, 72, 0), (91, 61, 0), + (74, 57, 0), (57, 54, 0), (36, 60, 0), (31, 61, 1), + (21, 67, 2), (18, 68, 1), (16, 69, 1), (15, 69, 0), + (14, 70, 0), (14, 62, 0), (15, 53, 6), (17, 54, 0), + (21, 54, 1), (27, 58, 0), (28, 72, 0), (30, 86, 0), + (30, 88, 0), (31, 90, 0), (36, 93, 0), (35, 90, 0), + (33, 68, 0), (33, 66, 0), (33, 65, 0), (32, 63, 0), + (32, 62, 0), (39, 59, 0), (53, 50, 0), (62, 55, 3), + (78, 67, 5), (98, 75, 0), (87, 72, 0), (77, 69, 0), + (42, 69, 0), (29, 57, 0), (19, 52, 0), (7, 32, 3), + (6, 17, 3), (6, 19, 1), (6, 21, 0), (8, 26, 0), + (10, 31, 0), (24, 37, 7), (41, 44, 1), (52, 45, 0), + (56, 38, 0), (52, 52, 0), (49, 57, 0), (46, 62, 0), + (42, 67, 1), (43, 81, 0), (66, 108, 0), (97, 147, 0), + (123, 161, 0), (151, 159, 0), (180, 157, 1), (183, 148, 16), + (187, 140, 32), (218, 129, 0), (229, 100, 0), (229, 101, 0), + (195, 136, 0), (131, 87, 0), (124, 81, 0), (118, 76, 0), + (96, 60, 0), (80, 60, 1), (76, 55, 2), (53, 49, 1), + (30, 60, 0), (27, 62, 0), (24, 64, 1), (24, 66, 0), + (26, 67, 0), (29, 68, 1), (33, 75, 1), (29, 87, 0), + (20, 78, 1), (15, 71, 0), (17, 68, 0), (20, 66, 1), + (24, 64, 1), (26, 53, 0), (35, 42, 1), (44, 18, 3), + (62, 4, 0), (75, 8, 0), (89, 13, 0), (106, 0, 2), + (87, 19, 0), (77, 19, 0), (60, 38, 0), (43, 51, 0), + (31, 54, 0), (29, 53, 1), (26, 50, 0), (22, 45, 0), + (31, 42, 0), (32, 33, 1), (36, 38, 0), (32, 50, 0), + (39, 59, 0), (42, 59, 0), (45, 59, 0), (54, 54, 0), + (76, 60, 1), (93, 75, 0), (108, 86, 3), (123, 116, 0), + (121, 127, 1), (129, 132, 1), (119, 129, 0), (106, 140, 1), + (74, 110, 0), (46, 96, 0), (40, 94, 0), (36, 93, 0), + (34, 88, 0), (33, 68, 0), (41, 63, 0), (50, 53, 0), + (61, 51, 0), (92, 75, 0), (121, 91, 1), (125, 108, 0), + (133, 116, 0), (135, 124, 0), (126, 114, 2), (123, 97, 0), + (107, 82, 0), (81, 72, 7), (46, 65, 1), (35, 64, 0), + (32, 60, 1), (32, 57, 0), (40, 62, 0), (43, 65, 0), + (49, 54, 0), (49, 47, 0), (40, 46, 0), (39, 52, 6), + (28, 51, 0), (23, 53, 1), (23, 53, 1), (22, 55, 2), + (20, 53, 0), (18, 53, 0), (17, 61, 0), (16, 62, 0), + (20, 62, 0), (19, 57, 0), (22, 55, 0), (27, 58, 1), + (21, 63, 0), (21, 61, 0), (23, 58, 0), (28, 57, 0), + (24, 54, 0), (18, 52, 1), (11, 47, 3), (7, 32, 0), + (4, 30, 0), (5, 25, 0), (5, 23, 0), (8, 28, 0), + (9, 28, 0), (23, 27, 0), (22, 9, 0), (31, 15, 0), + (36, 21, 0), (26, 33, 0), (35, 59, 0), (99, 123, 1) + ), + +// 207 Apophysis-040427-4HolidyBull +((13, 0, 193), (12, 0, 68), (20, 0, 47), (29, 0, 27), + (21, 5, 29), (13, 11, 32), (10, 12, 36), (7, 14, 40), + (0, 18, 49), (4, 20, 55), (8, 22, 61), (11, 16, 61), + (15, 11, 62), (13, 9, 47), (11, 7, 32), (12, 3, 28), + (14, 0, 25), (14, 8, 8), (20, 20, 13), (26, 32, 18), + (26, 16, 20), (26, 0, 23), (22, 6, 19), (18, 12, 16), + (4, 7, 24), (23, 20, 26), (42, 33, 28), (51, 62, 38), + (61, 92, 48), (30, 73, 65), (0, 54, 83), (30, 82, 157), + (25, 82, 234), (27, 6, 133), (21, 5, 84), (16, 5, 35), + (8, 3, 22), (0, 1, 9), (3, 7, 16), (6, 13, 23), + (35, 33, 57), (33, 113, 99), (31, 194, 141), (15, 133, 188), + (0, 73, 235), (4, 50, 235), (8, 28, 236), (27, 14, 215), + (34, 5, 121), (32, 0, 31), (29, 0, 15), (26, 1, 0), + (35, 0, 0), (44, 0, 0), (51, 6, 0), (59, 13, 0), + (156, 5, 10), (184, 14, 5), (213, 23, 0), (217, 19, 6), + (221, 16, 13), (201, 24, 6), (182, 33, 0), (124, 43, 16), + (97, 43, 0), (58, 13, 0), (44, 14, 0), (30, 15, 0), + (29, 13, 0), (28, 11, 0), (21, 0, 0), (14, 0, 0), + (0, 29, 0), (8, 27, 0), (16, 26, 0), (16, 18, 9), + (17, 10, 18), (15, 12, 32), (14, 15, 46), (8, 11, 80), + (18, 19, 112), (15, 12, 215), (12, 15, 235), (10, 19, 255), + (14, 19, 255), (19, 20, 255), (40, 5, 255), (17, 13, 255), + (10, 10, 255), (11, 6, 252), (12, 3, 250), (11, 4, 251), + (11, 5, 253), (13, 13, 255), (29, 0, 246), (50, 1, 232), + (60, 16, 237), (157, 10, 255), (179, 98, 248), (202, 187, 242), + (225, 210, 240), (249, 234, 239), (255, 221, 201), (255, 255, 159), + (255, 193, 125), (247, 157, 75), (239, 121, 25), (235, 123, 12), + (231, 126, 0), (234, 128, 10), (254, 200, 12), (255, 221, 17), + (255, 230, 21), (255, 238, 32), (255, 246, 45), (255, 255, 59), + (255, 238, 50), (236, 212, 54), (250, 206, 37), (254, 182, 35), + (255, 119, 26), (237, 106, 34), (219, 93, 42), (212, 90, 34), + (206, 88, 26), (203, 125, 14), (152, 100, 63), (85, 39, 114), + (56, 12, 195), (1, 19, 243), (2, 26, 249), (3, 34, 255), + (9, 71, 242), (38, 77, 255), (44, 94, 251), (0, 206, 254), + (20, 255, 238), (28, 243, 235), (37, 231, 233), (31, 216, 244), + (26, 201, 255), (5, 74, 255), (15, 71, 244), (0, 38, 229), + (2, 10, 155), (3, 0, 89), (1, 0, 68), (0, 0, 48), + (0, 9, 23), (0, 12, 5), (0, 15, 0), (6, 9, 0), + (30, 16, 0), (35, 20, 1), (40, 25, 2), (68, 52, 1), + (106, 50, 3), (134, 95, 18), (169, 152, 22), (224, 197, 0), + (244, 203, 0), (255, 186, 62), (225, 158, 64), (195, 130, 66), + (109, 90, 50), (35, 64, 124), (34, 60, 153), (16, 52, 234), + (8, 17, 246), (11, 13, 246), (14, 10, 247), (12, 15, 255), + (5, 19, 255), (0, 23, 255), (6, 12, 244), (4, 0, 254), + (0, 2, 251), (1, 8, 246), (6, 1, 218), (9, 17, 190), + (0, 0, 144), (0, 3, 106), (23, 0, 131), (2, 2, 212), + (0, 0, 249), (0, 1, 246), (0, 2, 243), (0, 4, 213), + (11, 14, 145), (0, 74, 44), (0, 144, 0), (8, 228, 40), + (106, 197, 102), (115, 194, 189), (139, 175, 201), (168, 145, 153), + (187, 163, 75), (128, 118, 5), (107, 66, 12), (112, 41, 0), + (158, 17, 0), (210, 25, 0), (216, 47, 0), (255, 73, 15), + (248, 81, 10), (195, 90, 7), (128, 63, 0), (119, 47, 9), + (80, 35, 56), (60, 16, 39), (60, 39, 34), (76, 35, 0), + (90, 22, 1), (150, 86, 12), (184, 144, 33), (207, 170, 27), + (229, 202, 35), (241, 229, 23), (255, 235, 22), (255, 248, 36), + (255, 251, 41), (245, 239, 39), (247, 244, 43), (216, 205, 123), + (127, 245, 149), (145, 158, 175), (157, 146, 178), (162, 62, 132), + (117, 44, 237), (151, 149, 188), (200, 155, 196), (195, 155, 145), + (161, 173, 127), (177, 209, 64), (130, 174, 37), (118, 68, 7), + (144, 26, 0), (204, 6, 19), (254, 8, 29), (237, 38, 97), + (176, 0, 165), (45, 11, 134), (7, 9, 96), (0, 0, 78), + (3, 3, 41), (0, 0, 18), (3, 2, 0), (7, 1, 1), + (14, 0, 0), (6, 3, 0), (4, 6, 0), (0, 8, 0), + (0, 3, 30), (0, 14, 46), (1, 9, 94), (6, 18, 78) + ), + +// 208 Apophysis-040427-4DrkFlorCnpy +((107, 203, 67), (111, 205, 69), (110, 204, 66), (110, 203, 63), + (109, 201, 62), (109, 200, 61), (109, 201, 61), (109, 202, 62), + (116, 213, 71), (120, 217, 74), (124, 222, 77), (129, 229, 81), + (134, 237, 86), (127, 229, 79), (121, 221, 73), (119, 218, 71), + (117, 215, 70), (90, 168, 49), (92, 165, 48), (94, 163, 47), + (88, 156, 45), (83, 150, 44), (80, 140, 40), (77, 131, 37), + (50, 77, 24), (49, 69, 22), (49, 61, 21), (47, 55, 19), + (46, 49, 18), (45, 50, 18), (44, 51, 18), (46, 61, 22), + (49, 64, 21), (48, 67, 21), (46, 74, 21), (44, 82, 21), + (43, 74, 20), (43, 66, 20), (39, 58, 17), (36, 50, 15), + (21, 25, 11), (15, 16, 7), (9, 8, 4), (10, 13, 5), + (11, 19, 6), (13, 27, 7), (15, 35, 8), (29, 65, 17), + (37, 94, 26), (77, 142, 40), (89, 162, 47), (101, 183, 55), + (103, 188, 57), (106, 193, 60), (105, 192, 59), (105, 191, 58), + (99, 184, 57), (98, 176, 53), (97, 168, 50), (95, 164, 48), + (94, 161, 46), (87, 159, 45), (80, 157, 45), (85, 143, 41), + (71, 137, 39), (58, 107, 28), (54, 101, 27), (51, 96, 27), + (50, 95, 26), (49, 94, 25), (50, 95, 26), (52, 99, 27), + (68, 134, 37), (80, 148, 41), (92, 162, 46), (94, 166, 47), + (96, 170, 49), (94, 170, 50), (93, 171, 51), (86, 158, 46), + (74, 145, 41), (71, 114, 34), (59, 95, 28), (47, 77, 23), + (44, 70, 21), (42, 63, 20), (28, 45, 13), (16, 31, 8), + (16, 36, 9), (25, 54, 13), (34, 73, 18), (41, 83, 21), + (48, 93, 24), (50, 95, 26), (47, 77, 23), (45, 50, 20), + (44, 2, 48), (47, 3, 52), (46, 27, 35), (46, 51, 19), + (50, 63, 21), (55, 75, 24), (77, 128, 36), (101, 177, 53), + (158, 251, 108), (166, 243, 116), (174, 236, 125), (145, 216, 98), + (117, 197, 72), (98, 172, 51), (82, 140, 40), (57, 103, 28), + (47, 81, 21), (29, 51, 13), (23, 44, 11), (18, 37, 9), + (19, 35, 9), (23, 29, 15), (22, 22, 10), (21, 21, 11), + (19, 10, 13), (26, 5, 25), (34, 0, 37), (36, 0, 40), + (38, 1, 44), (41, 2, 47), (36, 0, 44), (29, 0, 31), + (26, 0, 29), (14, 0, 13), (13, 1, 9), (12, 3, 6), + (10, 6, 5), (12, 8, 7), (18, 18, 8), (23, 23, 13), + (52, 69, 24), (66, 104, 31), (81, 139, 39), (87, 148, 42), + (94, 158, 46), (97, 176, 51), (102, 181, 54), (96, 181, 54), + (85, 159, 46), (65, 130, 36), (58, 114, 31), (51, 98, 26), + (41, 74, 19), (24, 50, 15), (16, 34, 8), (14, 32, 8), + (15, 21, 7), (16, 19, 7), (18, 18, 8), (19, 23, 9), + (19, 23, 9), (27, 23, 12), (27, 30, 13), (43, 50, 19), + (50, 67, 22), (66, 122, 33), (69, 134, 37), (73, 146, 41), + (81, 178, 63), (102, 193, 62), (109, 201, 64), (116, 213, 71), + (140, 245, 90), (145, 247, 97), (150, 249, 104), (166, 252, 119), + (161, 252, 113), (152, 252, 100), (142, 247, 85), (128, 224, 72), + (123, 223, 75), (116, 217, 75), (113, 210, 68), (110, 198, 60), + (104, 185, 56), (92, 159, 46), (72, 140, 41), (54, 102, 28), + (34, 47, 19), (30, 41, 15), (27, 35, 12), (16, 31, 8), + (16, 31, 8), (19, 39, 11), (36, 68, 18), (51, 98, 26), + (64, 129, 35), (80, 152, 44), (93, 163, 47), (103, 184, 55), + (101, 191, 59), (97, 186, 60), (96, 176, 53), (91, 169, 50), + (92, 162, 48), (91, 171, 50), (93, 171, 51), (101, 180, 53), + (103, 186, 56), (106, 193, 60), (110, 198, 60), (111, 202, 62), + (114, 207, 66), (114, 208, 68), (115, 210, 68), (113, 210, 68), + (112, 209, 68), (114, 207, 66), (112, 203, 64), (114, 198, 58), + (109, 197, 59), (105, 192, 59), (97, 182, 55), (88, 167, 50), + (74, 140, 40), (55, 101, 28), (47, 76, 22), (45, 63, 21), + (38, 40, 16), (20, 12, 10), (19, 2, 21), (25, 1, 27), + (23, 1, 24), (19, 0, 20), (19, 0, 20), (14, 0, 15), + (13, 0, 10), (8, 2, 4), (10, 6, 5), (12, 18, 6), + (14, 18, 4), (12, 18, 6), (14, 13, 9), (17, 6, 10), + (22, 0, 21), (31, 0, 36), (41, 2, 47), (50, 6, 59), + (61, 10, 69), (75, 18, 87), (63, 11, 73), (54, 4, 65), + (48, 4, 55), (53, 64, 24), (57, 89, 26), (77, 123, 35), + (87, 152, 50), (99, 178, 53), (108, 194, 59), (108, 199, 62) + ), + +// 209 Apophysis-040427-4DethstrDemis +((189, 180, 171), (110, 91, 84), (110, 75, 55), (110, 60, 27), + (97, 45, 13), (84, 31, 0), (72, 17, 0), (61, 3, 1), + (2, 10, 23), (16, 26, 40), (30, 42, 58), (48, 60, 77), + (66, 79, 96), (72, 82, 98), (78, 85, 101), (74, 82, 99), + (71, 79, 98), (49, 59, 71), (55, 50, 53), (61, 42, 35), + (89, 61, 48), (118, 81, 62), (122, 89, 78), (126, 98, 94), + (153, 150, 157), (164, 170, 183), (176, 191, 210), (186, 199, 220), + (196, 208, 230), (193, 208, 229), (191, 208, 228), (168, 194, 219), + (172, 185, 201), (169, 180, 198), (163, 175, 191), (158, 170, 184), + (148, 157, 170), (139, 145, 157), (142, 143, 151), (146, 141, 145), + (152, 133, 116), (164, 132, 111), (177, 131, 107), (179, 122, 86), + (181, 113, 66), (176, 94, 45), (171, 75, 25), (143, 49, 11), + (77, 28, 14), (1, 11, 23), (0, 7, 19), (0, 3, 15), + (13, 14, 27), (27, 25, 39), (56, 35, 38), (86, 46, 38), + (153, 80, 45), (157, 90, 53), (162, 100, 61), (157, 109, 81), + (152, 119, 102), (147, 119, 105), (142, 120, 109), (125, 129, 141), + (123, 130, 146), (117, 123, 139), (113, 119, 134), (110, 116, 130), + (106, 112, 127), (102, 109, 125), (93, 99, 115), (93, 99, 115), + (112, 118, 132), (118, 125, 141), (124, 133, 150), (134, 144, 162), + (145, 156, 174), (149, 161, 180), (154, 167, 186), (159, 170, 188), + (148, 156, 175), (128, 131, 146), (118, 125, 142), (109, 120, 138), + (97, 110, 132), (86, 100, 126), (87, 94, 110), (92, 92, 100), + (93, 99, 115), (108, 114, 130), (123, 130, 146), (134, 143, 159), + (145, 157, 173), (161, 172, 190), (176, 191, 210), (194, 212, 234), + (202, 222, 247), (206, 227, 248), (205, 225, 248), (204, 224, 248), + (203, 223, 248), (203, 223, 248), (191, 218, 239), (193, 209, 232), + (196, 196, 196), (188, 171, 158), (180, 146, 121), (168, 139, 121), + (156, 132, 122), (127, 129, 141), (122, 130, 143), (123, 130, 146), + (123, 130, 146), (124, 128, 139), (128, 128, 137), (132, 129, 136), + (124, 130, 144), (131, 140, 155), (128, 146, 170), (140, 156, 181), + (159, 172, 189), (152, 163, 182), (146, 154, 175), (145, 152, 172), + (144, 151, 169), (135, 144, 159), (137, 147, 159), (144, 153, 170), + (145, 155, 180), (169, 180, 198), (170, 181, 199), (171, 182, 200), + (158, 171, 188), (141, 141, 151), (130, 126, 127), (142, 118, 108), + (95, 92, 87), (79, 81, 85), (63, 71, 84), (53, 66, 81), + (44, 61, 79), (28, 38, 65), (25, 41, 64), (23, 40, 58), + (28, 41, 57), (32, 45, 64), (36, 48, 66), (40, 52, 68), + (58, 65, 81), (65, 74, 89), (72, 76, 87), (87, 80, 87), + (135, 90, 61), (143, 89, 61), (152, 88, 61), (132, 97, 78), + (121, 98, 90), (95, 95, 105), (93, 99, 115), (93, 99, 115), + (93, 99, 115), (83, 85, 98), (82, 80, 89), (81, 76, 80), + (84, 83, 89), (79, 88, 103), (73, 94, 113), (80, 89, 122), + (93, 99, 115), (93, 99, 115), (93, 99, 115), (100, 106, 122), + (105, 114, 129), (95, 101, 115), (93, 99, 115), (85, 94, 109), + (81, 76, 80), (63, 52, 60), (46, 35, 31), (61, 21, 9), + (57, 19, 8), (31, 29, 34), (33, 42, 57), (53, 52, 58), + (102, 70, 55), (104, 83, 73), (107, 96, 92), (100, 108, 119), + (120, 120, 128), (140, 129, 125), (152, 129, 115), (152, 124, 110), + (146, 118, 106), (134, 107, 98), (125, 97, 83), (115, 98, 90), + (121, 117, 114), (116, 125, 142), (120, 131, 149), (135, 144, 159), + (154, 166, 182), (168, 181, 198), (174, 190, 206), (186, 201, 222), + (194, 212, 234), (221, 234, 227), (249, 233, 234), (209, 227, 249), + (197, 218, 239), (189, 211, 232), (179, 191, 213), (175, 186, 204), + (169, 180, 198), (158, 169, 187), (141, 152, 170), (123, 130, 146), + (117, 119, 131), (101, 109, 122), (94, 100, 114), (99, 102, 109), + (128, 100, 89), (148, 107, 85), (194, 121, 80), (232, 139, 78), + (249, 172, 104), (221, 186, 154), (197, 171, 154), (189, 171, 169), + (159, 168, 183), (145, 152, 168), (129, 138, 153), (105, 121, 144), + (93, 99, 115), (81, 87, 101), (64, 70, 84), (38, 42, 54), + (20, 33, 49), (4, 19, 38), (11, 31, 42), (18, 34, 50), + (34, 41, 59), (52, 61, 76), (64, 71, 87), (77, 84, 100), + (93, 99, 115), (105, 111, 125), (122, 130, 149), (145, 154, 171), + (163, 174, 192), (168, 179, 199), (168, 181, 200), (171, 182, 200), + (178, 188, 200), (188, 187, 193), (189, 180, 175), (202, 178, 166) + ), + +// 210 Apophysis-040427-4DethstrDems +((46, 26, 0), (52, 32, 7), (57, 39, 15), (62, 46, 23), + (60, 52, 41), (59, 59, 59), (54, 76, 89), (49, 93, 120), + (99, 123, 133), (116, 124, 122), (133, 125, 112), (132, 125, 110), + (132, 125, 109), (131, 126, 112), (131, 127, 116), (127, 126, 117), + (123, 126, 119), (124, 115, 100), (119, 107, 87), (115, 99, 74), + (105, 91, 70), (96, 83, 66), (97, 85, 67), (98, 87, 69), + (111, 104, 86), (114, 106, 91), (118, 108, 96), (114, 104, 85), + (110, 100, 75), (103, 92, 71), (96, 85, 67), (86, 75, 57), + (84, 73, 55), (114, 114, 104), (113, 125, 125), (113, 137, 147), + (136, 150, 157), (160, 163, 168), (165, 167, 167), (171, 172, 166), + (211, 194, 176), (220, 204, 183), (230, 214, 191), (228, 214, 194), + (227, 214, 198), (227, 212, 195), (227, 210, 192), (223, 210, 191), + (215, 203, 187), (190, 181, 166), (179, 178, 167), (168, 175, 168), + (144, 170, 181), (120, 165, 194), (111, 166, 194), (103, 167, 194), + (134, 157, 165), (148, 156, 152), (162, 156, 140), (162, 156, 140), + (162, 156, 140), (166, 162, 142), (170, 168, 145), (172, 170, 157), + (174, 179, 175), (176, 167, 152), (175, 166, 142), (175, 166, 133), + (168, 161, 136), (162, 156, 140), (162, 156, 140), (162, 156, 140), + (150, 141, 126), (156, 148, 133), (162, 156, 140), (168, 167, 157), + (174, 179, 175), (183, 191, 185), (192, 203, 195), (209, 220, 224), + (194, 234, 246), (224, 226, 221), (213, 214, 209), (202, 203, 197), + (190, 197, 185), (178, 191, 173), (153, 185, 200), (148, 159, 163), + (135, 135, 127), (119, 130, 133), (103, 126, 140), (103, 128, 142), + (103, 131, 145), (109, 137, 149), (121, 148, 157), (130, 158, 172), + (140, 157, 165), (139, 130, 113), (129, 120, 104), (120, 111, 96), + (110, 100, 84), (101, 89, 73), (87, 74, 57), (81, 65, 49), + (61, 43, 21), (33, 32, 21), (6, 22, 21), (26, 25, 13), + (46, 28, 6), (58, 37, 16), (66, 44, 23), (76, 64, 42), + (80, 69, 51), (97, 86, 68), (105, 94, 76), (114, 103, 85), + (132, 125, 109), (138, 136, 124), (154, 146, 133), (161, 155, 141), + (127, 155, 166), (94, 144, 170), (61, 134, 175), (42, 125, 176), + (23, 116, 177), (6, 83, 151), (34, 69, 101), (58, 84, 101), + (66, 84, 86), (110, 103, 87), (118, 110, 94), (126, 117, 102), + (150, 134, 111), (162, 156, 140), (174, 168, 154), (191, 185, 171), + (235, 222, 206), (239, 223, 209), (244, 224, 213), (240, 222, 209), + (237, 221, 205), (221, 214, 196), (203, 194, 179), (191, 184, 168), + (178, 171, 155), (150, 144, 130), (141, 134, 118), (133, 125, 106), + (110, 101, 84), (92, 81, 63), (87, 76, 56), (87, 74, 55), + (77, 67, 55), (72, 67, 58), (67, 68, 62), (66, 75, 80), + (53, 77, 89), (66, 75, 84), (153, 147, 131), (145, 164, 171), + (147, 185, 204), (160, 233, 252), (165, 228, 253), (171, 224, 255), + (194, 252, 254), (247, 255, 253), (253, 245, 232), (255, 238, 222), + (198, 189, 174), (193, 182, 166), (189, 176, 159), (183, 173, 148), + (177, 170, 154), (184, 176, 157), (198, 187, 169), (206, 196, 184), + (198, 209, 215), (194, 213, 220), (153, 196, 215), (137, 174, 193), + (129, 157, 161), (123, 126, 119), (102, 105, 98), (93, 80, 63), + (66, 53, 34), (62, 50, 29), (59, 47, 25), (64, 47, 27), + (87, 61, 36), (83, 70, 54), (86, 73, 56), (86, 75, 57), + (90, 77, 58), (97, 85, 71), (108, 99, 82), (116, 110, 98), + (109, 114, 110), (108, 122, 122), (103, 122, 139), (81, 118, 144), + (78, 124, 148), (72, 136, 182), (74, 142, 189), (84, 180, 230), + (112, 206, 244), (178, 227, 241), (247, 239, 226), (254, 244, 232), + (255, 243, 237), (255, 252, 240), (247, 244, 237), (228, 230, 216), + (169, 209, 217), (108, 191, 233), (102, 175, 210), (92, 161, 200), + (93, 155, 194), (93, 146, 178), (103, 136, 153), (113, 135, 146), + (130, 126, 114), (132, 125, 109), (132, 125, 109), (138, 132, 116), + (144, 133, 115), (145, 139, 125), (153, 146, 130), (162, 156, 140), + (162, 156, 140), (152, 146, 132), (143, 137, 123), (132, 125, 109), + (131, 122, 105), (121, 112, 97), (110, 99, 81), (101, 88, 69), + (96, 85, 67), (107, 99, 80), (119, 112, 96), (127, 124, 109), + (132, 125, 109), (146, 135, 117), (169, 155, 129), (168, 161, 145), + (163, 163, 155), (162, 156, 140), (162, 156, 140), (153, 144, 129), + (132, 125, 109), (110, 98, 82), (94, 83, 65), (79, 64, 45), + (61, 43, 21), (53, 33, 8), (51, 31, 7), (49, 28, 7) + ), + +// 211 Apophysis-040427-4DeerDemMsk +((164, 151, 181), (1, 5, 16), (1, 2, 10), (1, 0, 4), + (0, 0, 2), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 1, 0), (0, 1, 0), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 1), (0, 0, 2), (0, 0, 2), (2, 0, 1), + (3, 4, 6), (21, 25, 22), (39, 46, 39), (115, 101, 68), + (192, 156, 98), (216, 184, 100), (240, 212, 102), (225, 244, 118), + (253, 253, 131), (252, 188, 78), (225, 139, 47), (199, 91, 16), + (120, 63, 20), (42, 36, 24), (8, 8, 8), (3, 3, 3), + (1, 1, 1), (0, 1, 1), (0, 2, 1), (0, 2, 0), + (0, 2, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 1, 0), (1, 1, 0), (1, 1, 0), (1, 1, 1), + (5, 6, 0), (28, 35, 4), (52, 65, 9), (94, 120, 16), + (136, 175, 24), (226, 214, 66), (243, 238, 82), (243, 222, 69), + (249, 195, 73), (39, 143, 46), (23, 97, 32), (7, 52, 19), + (7, 7, 5), (3, 3, 3), (2, 2, 2), (3, 1, 2), + (0, 1, 6), (0, 0, 4), (1, 0, 2), (1, 1, 2), + (2, 2, 2), (5, 5, 5), (11, 12, 7), (73, 61, 21), + (179, 156, 28), (255, 249, 89), (253, 250, 96), (252, 252, 104), + (245, 254, 101), (216, 235, 83), (157, 195, 56), (118, 98, 65), + (8, 7, 5), (5, 4, 6), (3, 2, 7), (0, 4, 7), + (1, 1, 1), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 1, 1), (1, 1, 1), (2, 2, 2), + (5, 5, 5), (11, 11, 9), (70, 56, 30), (150, 146, 55), + (171, 168, 127), (179, 151, 150), (187, 135, 173), (168, 111, 146), + (226, 143, 103), (251, 161, 98), (236, 131, 112), (224, 102, 81), + (146, 127, 59), (39, 43, 29), (11, 11, 9), (4, 4, 2), + (2, 3, 0), (3, 2, 0), (3, 3, 3), (7, 6, 4), + (159, 40, 18), (185, 56, 28), (212, 72, 39), (190, 69, 104), + (92, 62, 54), (16, 12, 9), (5, 5, 5), (3, 3, 3), + (4, 4, 4), (9, 9, 9), (41, 30, 28), (108, 104, 93), + (176, 206, 146), (242, 218, 172), (241, 207, 179), (213, 163, 128), + (211, 161, 100), (141, 117, 71), (80, 51, 82), (134, 56, 140), + (218, 46, 122), (242, 183, 203), (251, 194, 201), (254, 237, 247), + (218, 236, 214), (194, 224, 160), (130, 135, 69), (36, 77, 59), + (15, 17, 12), (6, 6, 6), (2, 2, 2), (1, 1, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (1, 0, 0), + (1, 0, 0), (3, 0, 0), (8, 0, 0), (6, 5, 3), + (14, 11, 4), (170, 36, 25), (243, 31, 56), (247, 10, 62), + (242, 15, 84), (247, 1, 146), (239, 3, 147), (248, 71, 152), + (223, 134, 118), (167, 210, 33), (126, 184, 22), (63, 143, 8), + (19, 20, 14), (8, 8, 6), (3, 3, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (3, 3, 3), (8, 3, 7), + (16, 7, 12), (121, 28, 72), (240, 3, 143), (243, 0, 156), + (204, 185, 213), (238, 225, 235), (250, 250, 212), (195, 223, 182) + ), + +// 212 Apophysis-040427-4CrouchDragn +((172, 5, 83), (177, 6, 84), (176, 6, 84), (175, 7, 85), + (168, 52, 89), (162, 97, 93), (175, 114, 68), (189, 132, 43), + (233, 166, 13), (236, 193, 6), (240, 220, 0), (241, 221, 0), + (242, 222, 1), (238, 215, 14), (234, 209, 28), (239, 212, 41), + (244, 216, 55), (254, 213, 63), (242, 196, 67), (230, 179, 72), + (228, 173, 53), (227, 167, 35), (221, 165, 38), (215, 163, 41), + (158, 133, 30), (153, 106, 37), (149, 79, 45), (157, 42, 62), + (166, 6, 80), (169, 5, 81), (172, 5, 83), (176, 5, 84), + (178, 5, 85), (178, 5, 85), (178, 5, 85), (178, 5, 85), + (177, 5, 85), (177, 6, 85), (176, 5, 84), (176, 5, 84), + (177, 4, 84), (177, 4, 84), (177, 4, 84), (176, 4, 84), + (176, 5, 84), (175, 5, 84), (174, 6, 84), (172, 6, 82), + (166, 6, 80), (151, 4, 72), (141, 4, 67), (132, 4, 63), + (122, 4, 58), (112, 4, 53), (115, 48, 27), (118, 93, 1), + (136, 111, 21), (132, 64, 43), (128, 18, 65), (135, 10, 66), + (142, 3, 68), (146, 3, 70), (151, 4, 72), (159, 3, 74), + (161, 3, 77), (172, 6, 82), (169, 5, 81), (167, 5, 80), + (164, 4, 79), (162, 4, 78), (159, 5, 77), (158, 4, 74), + (140, 4, 68), (137, 4, 66), (134, 4, 64), (127, 4, 61), + (121, 4, 59), (111, 4, 54), (101, 4, 49), (105, 79, 5), + (128, 100, 0), (173, 116, 11), (178, 115, 16), (184, 115, 22), + (172, 98, 52), (160, 82, 82), (150, 38, 84), (170, 15, 83), + (174, 6, 83), (175, 5, 83), (176, 5, 83), (176, 4, 83), + (177, 4, 84), (176, 5, 83), (173, 5, 82), (170, 5, 81), + (167, 5, 80), (162, 4, 78), (164, 4, 79), (167, 5, 80), + (167, 5, 80), (167, 5, 80), (172, 5, 83), (177, 6, 85), + (174, 113, 108), (189, 144, 114), (205, 175, 121), (228, 208, 168), + (251, 241, 216), (254, 248, 234), (243, 207, 123), (234, 191, 97), + (255, 211, 60), (242, 222, 3), (242, 222, 6), (242, 223, 9), + (233, 207, 32), (205, 186, 66), (192, 145, 65), (173, 110, 101), + (147, 88, 48), (164, 101, 43), (181, 115, 39), (190, 130, 38), + (199, 145, 37), (206, 140, 27), (209, 145, 19), (214, 148, 8), + (200, 124, 2), (196, 137, 19), (205, 137, 24), (214, 137, 29), + (225, 155, 33), (216, 156, 32), (205, 146, 30), (186, 135, 46), + (166, 48, 100), (170, 27, 92), (174, 6, 84), (175, 6, 84), + (177, 6, 85), (179, 6, 86), (180, 4, 85), (178, 5, 84), + (177, 4, 83), (173, 5, 82), (173, 5, 82), (173, 5, 82), + (173, 5, 82), (174, 6, 83), (174, 6, 83), (174, 6, 83), + (152, 72, 73), (159, 89, 45), (166, 107, 17), (186, 126, 12), + (189, 127, 8), (185, 125, 5), (162, 127, 1), (172, 112, 0), + (152, 100, 16), (145, 9, 71), (152, 7, 73), (159, 5, 75), + (160, 6, 76), (165, 5, 79), (167, 5, 80), (172, 6, 82), + (172, 19, 86), (175, 51, 97), (178, 84, 108), (186, 141, 60), + (204, 145, 43), (221, 162, 36), (229, 170, 40), (227, 171, 48), + (219, 168, 61), (232, 179, 67), (234, 180, 54), (242, 189, 31), + (239, 186, 12), (240, 185, 6), (241, 187, 1), (224, 174, 1), + (180, 121, 19), (164, 103, 13), (148, 85, 8), (135, 12, 66), + (145, 5, 68), (159, 5, 75), (161, 5, 76), (165, 5, 79), + (166, 6, 80), (167, 5, 80), (167, 5, 80), (170, 5, 81), + (172, 6, 82), (173, 5, 82), (173, 5, 82), (173, 5, 82), + (172, 5, 83), (172, 5, 83), (169, 4, 80), (165, 5, 79), + (160, 4, 77), (152, 5, 73), (140, 4, 68), (122, 3, 59), + (107, 4, 51), (111, 64, 10), (117, 92, 0), (129, 101, 1), + (145, 93, 9), (160, 94, 7), (144, 94, 21), (136, 84, 45), + (153, 21, 78), (159, 8, 77), (166, 6, 80), (172, 6, 82), + (176, 5, 83), (177, 4, 84), (177, 4, 84), (178, 5, 85), + (178, 5, 85), (178, 5, 85), (178, 5, 85), (178, 5, 85), + (178, 5, 85), (178, 5, 85), (176, 5, 84), (173, 5, 82), + (166, 4, 79), (158, 4, 74), (142, 2, 65), (125, 4, 58), + (110, 4, 53), (101, 4, 49), (101, 4, 49), (111, 3, 53), + (129, 8, 62), (148, 88, 15), (184, 128, 33), (206, 153, 41), + (212, 191, 38), (224, 204, 19), (239, 216, 0), (242, 188, 0), + (227, 175, 1), (226, 160, 20), (197, 136, 21), (155, 61, 87), + (153, 24, 81), (162, 8, 78), (166, 6, 80), (176, 5, 84) + ), + +// 213 Apophysis-040427-4CopprMapleleaf +((24, 5, 0), (33, 1, 4), (45, 10, 7), (57, 20, 11), + (65, 28, 18), (74, 36, 25), (74, 36, 24), (74, 36, 23), + (68, 30, 19), (57, 26, 15), (47, 23, 11), (44, 19, 7), + (42, 16, 3), (35, 10, 7), (28, 5, 11), (26, 7, 12), + (24, 9, 14), (53, 15, 12), (82, 41, 33), (112, 68, 55), + (145, 96, 82), (178, 125, 109), (193, 138, 120), (208, 151, 132), + (242, 196, 160), (244, 197, 164), (246, 199, 169), (239, 186, 162), + (232, 173, 155), (225, 167, 149), (219, 162, 143), (208, 151, 132), + (195, 139, 122), (170, 119, 102), (152, 103, 87), (135, 88, 72), + (116, 71, 56), (97, 55, 41), (92, 51, 38), (87, 47, 35), + (85, 45, 33), (99, 57, 44), (113, 69, 56), (141, 99, 78), + (169, 130, 101), (182, 141, 111), (196, 153, 121), (227, 182, 149), + (243, 188, 168), (253, 203, 180), (251, 205, 176), (250, 207, 172), + (245, 193, 166), (240, 179, 160), (224, 165, 147), (209, 152, 135), + (168, 117, 100), (144, 96, 81), (121, 75, 62), (111, 67, 53), + (101, 59, 45), (99, 57, 43), (98, 56, 42), (96, 54, 42), + (91, 49, 37), (102, 58, 45), (103, 59, 46), (104, 60, 47), + (102, 59, 45), (100, 58, 44), (87, 56, 35), (79, 41, 30), + (79, 39, 29), (91, 49, 38), (104, 60, 47), (112, 67, 54), + (120, 74, 61), (182, 129, 113), (245, 184, 165), (208, 151, 132), + (171, 118, 102), (141, 94, 78), (132, 85, 70), (123, 77, 62), + (124, 78, 63), (125, 79, 64), (142, 95, 79), (156, 107, 92), + (175, 122, 106), (178, 125, 109), (181, 128, 112), (175, 123, 107), + (170, 119, 102), (151, 102, 87), (135, 88, 72), (124, 78, 63), + (112, 69, 52), (110, 66, 53), (117, 72, 58), (124, 78, 63), + (134, 87, 72), (145, 96, 81), (163, 111, 97), (186, 133, 115), + (227, 168, 150), (232, 185, 165), (238, 202, 180), (237, 203, 185), + (237, 205, 190), (233, 210, 192), (235, 209, 194), (240, 204, 188), + (243, 200, 181), (241, 195, 161), (238, 192, 158), (235, 189, 155), + (211, 166, 135), (209, 166, 132), (203, 164, 133), (207, 163, 134), + (237, 179, 159), (237, 192, 173), (238, 205, 188), (235, 207, 189), + (232, 209, 191), (235, 206, 190), (237, 202, 180), (242, 185, 165), + (223, 164, 146), (187, 131, 114), (172, 118, 103), (158, 106, 92), + (138, 91, 75), (123, 77, 64), (107, 69, 56), (105, 61, 48), + (112, 69, 53), (123, 84, 62), (135, 100, 72), (144, 108, 81), + (154, 117, 90), (169, 130, 101), (197, 141, 124), (216, 159, 140), + (246, 185, 166), (247, 190, 171), (242, 191, 164), (238, 192, 158), + (211, 168, 134), (187, 146, 114), (176, 123, 107), (173, 122, 105), + (178, 137, 107), (187, 138, 115), (196, 140, 123), (202, 146, 129), + (203, 147, 130), (200, 153, 133), (204, 148, 131), (192, 136, 119), + (173, 120, 104), (152, 103, 88), (151, 102, 87), (151, 102, 87), + (147, 98, 83), (149, 100, 85), (155, 106, 91), (158, 109, 94), + (167, 116, 99), (163, 113, 97), (160, 111, 96), (154, 105, 90), + (145, 96, 81), (144, 95, 80), (135, 87, 73), (124, 78, 63), + (124, 78, 63), (123, 77, 62), (113, 70, 54), (112, 69, 53), + (104, 70, 45), (113, 79, 54), (132, 96, 70), (152, 103, 88), + (183, 130, 112), (186, 133, 115), (190, 137, 119), (199, 143, 126), + (206, 149, 130), (206, 161, 130), (223, 164, 146), (235, 177, 157), + (240, 182, 162), (250, 189, 170), (251, 198, 180), (250, 202, 182), + (248, 206, 192), (246, 215, 195), (239, 212, 193), (238, 205, 190), + (243, 201, 187), (250, 202, 182), (253, 199, 187), (251, 206, 187), + (249, 206, 187), (249, 206, 190), (236, 208, 194), (231, 214, 196), + (234, 221, 205), (232, 225, 207), (240, 240, 216), (245, 239, 223), + (233, 224, 207), (231, 222, 205), (229, 224, 205), (227, 220, 204), + (227, 220, 204), (226, 220, 204), (225, 218, 202), (224, 221, 204), + (202, 240, 219), (222, 231, 204), (225, 223, 200), (227, 220, 202), + (227, 218, 203), (229, 217, 203), (227, 214, 198), (235, 209, 196), + (247, 200, 192), (250, 200, 193), (248, 213, 194), (238, 216, 195), + (233, 216, 198), (232, 220, 204), (232, 213, 206), (231, 214, 198), + (235, 206, 190), (231, 187, 152), (195, 143, 122), (157, 108, 93), + (123, 77, 64), (73, 61, 49), (48, 20, 9), (21, 10, 8), + (16, 21, 17), (30, 24, 10), (60, 23, 14), (75, 37, 26), + (87, 47, 35), (91, 49, 37), (104, 60, 47), (95, 53, 39), + (83, 43, 31), (72, 34, 23), (51, 17, 7), (31, 5, 8) + ), + +// 214 Apophysis-040427-4Circulations +((243, 231, 189), (255, 250, 221), (253, 248, 226), (252, 246, 232), + (252, 244, 236), (253, 243, 241), (254, 243, 241), (255, 244, 242), + (253, 245, 242), (253, 247, 241), (253, 249, 240), (254, 248, 239), + (255, 248, 238), (253, 250, 240), (251, 253, 242), (251, 254, 246), + (252, 255, 251), (254, 254, 254), (254, 254, 254), (255, 255, 255), + (254, 254, 254), (254, 254, 254), (254, 254, 254), (254, 254, 254), + (255, 245, 253), (254, 249, 253), (254, 254, 254), (254, 254, 254), + (254, 254, 254), (252, 250, 252), (251, 246, 250), (252, 244, 241), + (251, 243, 222), (242, 220, 171), (228, 198, 124), (214, 176, 77), + (164, 129, 42), (115, 83, 8), (83, 61, 4), (52, 40, 0), + (11, 3, 0), (13, 7, 1), (15, 11, 2), (29, 20, 1), + (43, 30, 0), (57, 40, 0), (71, 51, 1), (105, 75, 2), + (150, 109, 4), (187, 144, 32), (204, 163, 54), (221, 183, 76), + (230, 202, 118), (240, 222, 160), (243, 224, 170), (247, 226, 181), + (250, 242, 221), (250, 242, 221), (250, 242, 221), (248, 237, 208), + (246, 232, 195), (241, 226, 178), (236, 220, 161), (237, 202, 118), + (217, 182, 82), (164, 121, 9), (126, 93, 4), (88, 65, 0), + (81, 58, 0), (74, 51, 0), (71, 51, 1), (73, 52, 0), + (94, 65, 0), (116, 83, 2), (139, 101, 4), (149, 107, 3), + (160, 114, 2), (160, 116, 4), (160, 118, 6), (163, 120, 5), + (160, 117, 2), (166, 121, 6), (177, 133, 19), (188, 145, 32), + (203, 161, 57), (218, 178, 82), (233, 203, 130), (242, 223, 167), + (248, 233, 210), (250, 239, 219), (253, 246, 228), (252, 244, 225), + (251, 243, 222), (250, 234, 211), (248, 234, 205), (246, 232, 193), + (244, 227, 181), (246, 232, 193), (248, 233, 203), (250, 235, 214), + (249, 240, 222), (248, 245, 230), (245, 244, 242), (249, 247, 250), + (252, 255, 255), (252, 252, 248), (252, 249, 242), (252, 248, 235), + (252, 247, 228), (247, 244, 213), (244, 231, 199), (235, 207, 160), + (219, 189, 116), (148, 106, 8), (119, 86, 5), (91, 67, 3), + (50, 38, 0), (29, 15, 2), (23, 18, 0), (33, 20, 12), + (65, 48, 2), (88, 61, 1), (111, 75, 0), (120, 84, 0), + (130, 94, 0), (146, 105, 0), (157, 113, 4), (151, 109, 1), + (139, 98, 6), (68, 50, 0), (52, 39, 0), (36, 29, 1), + (32, 21, 1), (43, 32, 2), (76, 55, 0), (112, 91, 38), + (228, 209, 167), (236, 219, 185), (245, 229, 203), (248, 234, 216), + (252, 239, 230), (251, 243, 240), (252, 244, 241), (253, 245, 243), + (253, 245, 243), (253, 245, 243), (253, 245, 243), (254, 246, 244), + (254, 246, 244), (254, 243, 247), (255, 244, 248), (255, 246, 251), + (253, 242, 248), (251, 244, 247), (250, 246, 247), (253, 245, 243), + (255, 248, 246), (255, 249, 247), (255, 245, 244), (253, 245, 243), + (253, 245, 243), (252, 248, 237), (252, 247, 233), (252, 246, 230), + (253, 246, 228), (250, 243, 224), (250, 231, 214), (247, 230, 210), + (251, 246, 226), (251, 248, 225), (252, 250, 225), (255, 250, 226), + (252, 247, 228), (252, 246, 232), (251, 247, 238), (252, 244, 241), + (253, 243, 241), (253, 243, 241), (252, 248, 237), (253, 246, 228), + (251, 236, 215), (248, 234, 199), (246, 227, 185), (242, 220, 163), + (217, 181, 87), (212, 177, 81), (208, 174, 76), (189, 147, 35), + (174, 131, 18), (169, 124, 9), (161, 118, 3), (143, 102, 0), + (120, 88, 3), (104, 72, 0), (84, 60, 0), (78, 57, 0), + (86, 56, 2), (109, 80, 20), (172, 130, 20), (208, 166, 68), + (223, 189, 102), (239, 210, 154), (248, 219, 163), (244, 226, 178), + (246, 232, 193), (247, 234, 199), (247, 234, 199), (248, 234, 205), + (248, 234, 205), (242, 229, 210), (248, 225, 209), (248, 226, 205), + (247, 226, 205), (245, 231, 205), (247, 234, 199), (247, 233, 198), + (255, 235, 182), (254, 211, 143), (222, 182, 94), (212, 174, 75), + (187, 148, 47), (181, 138, 23), (197, 155, 43), (214, 176, 77), + (232, 200, 123), (243, 216, 169), (248, 226, 189), (247, 235, 209), + (251, 246, 227), (253, 247, 233), (252, 244, 241), (253, 245, 243), + (253, 248, 242), (251, 249, 237), (252, 246, 230), (253, 246, 228), + (253, 246, 228), (253, 246, 230), (252, 248, 237), (251, 249, 237), + (251, 249, 236), (252, 246, 230), (253, 246, 230), (253, 246, 228), + (253, 246, 228), (251, 246, 226), (251, 244, 226), (251, 236, 213), + (248, 232, 209), (245, 227, 203), (245, 225, 188), (244, 221, 179), + (239, 215, 155), (237, 213, 143), (230, 195, 114), (222, 192, 102) + ), + +// 215 Apophysis-040427-4DmnContaind +((245, 179, 83), (251, 216, 174), (253, 207, 146), (255, 199, 119), + (251, 196, 107), (248, 194, 96), (251, 193, 92), (255, 193, 89), + (255, 170, 87), (252, 179, 95), (250, 188, 103), (252, 198, 124), + (254, 208, 146), (251, 213, 165), (248, 218, 184), (231, 214, 203), + (214, 211, 222), (177, 148, 254), (163, 141, 184), (149, 134, 115), + (162, 121, 68), (175, 108, 21), (182, 108, 10), (190, 108, 0), + (236, 132, 1), (245, 146, 20), (255, 160, 39), (253, 177, 82), + (251, 194, 125), (240, 201, 154), (229, 209, 184), (175, 164, 204), + (99, 81, 131), (79, 56, 24), (79, 51, 16), (79, 47, 9), + (56, 39, 23), (33, 32, 38), (32, 19, 68), (31, 6, 98), + (63, 9, 217), (86, 32, 236), (109, 55, 255), (118, 68, 255), + (128, 81, 255), (132, 86, 253), (137, 91, 251), (143, 103, 254), + (146, 106, 254), (180, 152, 254), (192, 177, 234), (205, 203, 214), + (229, 197, 162), (254, 191, 111), (254, 182, 90), (255, 174, 69), + (255, 145, 4), (255, 141, 2), (255, 138, 0), (235, 129, 0), + (215, 121, 0), (211, 119, 0), (207, 117, 0), (202, 115, 0), + (194, 109, 0), (192, 107, 0), (179, 100, 0), (167, 94, 0), + (164, 90, 1), (161, 87, 2), (147, 83, 0), (132, 72, 0), + (89, 55, 10), (60, 28, 65), (32, 1, 121), (47, 0, 177), + (62, 0, 233), (66, 2, 244), (71, 4, 255), (72, 19, 245), + (74, 29, 194), (64, 59, 81), (95, 66, 42), (127, 74, 4), + (136, 77, 2), (145, 80, 0), (157, 90, 1), (143, 94, 35), + (172, 147, 241), (177, 151, 248), (182, 156, 255), (181, 155, 254), + (180, 154, 253), (179, 152, 255), (168, 137, 254), (155, 119, 255), + (141, 100, 254), (113, 60, 255), (86, 37, 212), (59, 15, 170), + (45, 7, 146), (32, 0, 123), (22, 0, 79), (13, 0, 48), + (7, 5, 19), (11, 2, 39), (15, 0, 59), (20, 0, 79), + (26, 0, 99), (39, 0, 143), (57, 1, 212), (85, 23, 254), + (108, 53, 255), (130, 84, 255), (135, 92, 255), (141, 100, 255), + (145, 105, 255), (154, 118, 254), (145, 123, 205), (160, 115, 60), + (241, 141, 4), (248, 143, 4), (255, 145, 4), (255, 145, 4), + (255, 145, 4), (254, 148, 10), (255, 160, 40), (247, 175, 93), + (241, 192, 116), (177, 148, 254), (161, 127, 254), (146, 106, 254), + (142, 102, 250), (139, 98, 255), (132, 91, 247), (124, 84, 232), + (136, 94, 255), (134, 90, 255), (132, 86, 255), (132, 86, 255), + (132, 86, 255), (122, 74, 255), (110, 56, 254), (88, 53, 197), + (62, 26, 160), (18, 3, 58), (15, 1, 52), (12, 0, 46), + (2, 4, 17), (2, 0, 3), (3, 0, 0), (2, 2, 2), + (21, 5, 68), (28, 2, 100), (36, 0, 132), (59, 0, 214), + (87, 25, 255), (96, 39, 255), (100, 44, 255), (95, 38, 255), + (80, 17, 254), (41, 2, 127), (33, 1, 113), (26, 0, 99), + (17, 1, 66), (11, 0, 51), (15, 0, 55), (21, 0, 77), + (52, 22, 136), (65, 25, 166), (78, 29, 196), (105, 54, 245), + (112, 60, 255), (120, 72, 255), (122, 74, 255), (127, 80, 255), + (128, 81, 255), (132, 86, 255), (136, 94, 254), (140, 99, 255), + (144, 103, 255), (150, 111, 255), (154, 117, 255), (160, 129, 255), + (188, 163, 255), (192, 168, 255), (196, 174, 255), (204, 184, 255), + (242, 220, 196), (255, 215, 164), (255, 206, 140), (255, 192, 112), + (255, 190, 108), (254, 198, 123), (251, 214, 169), (210, 206, 223), + (189, 164, 255), (178, 149, 255), (169, 139, 253), (157, 121, 255), + (176, 147, 255), (184, 159, 253), (194, 178, 240), (198, 197, 211), + (254, 208, 146), (255, 193, 106), (255, 162, 48), (222, 127, 1), + (166, 97, 20), (84, 83, 91), (76, 65, 107), (72, 41, 160), + (99, 58, 216), (129, 83, 254), (155, 119, 255), (156, 120, 255), + (161, 129, 255), (161, 129, 252), (157, 121, 255), (146, 106, 255), + (132, 86, 255), (117, 66, 255), (107, 58, 255), (104, 49, 254), + (96, 39, 255), (95, 38, 255), (78, 15, 255), (63, 1, 236), + (69, 37, 162), (66, 55, 97), (112, 63, 23), (165, 95, 0), + (208, 124, 2), (236, 134, 0), (255, 144, 2), (255, 160, 0), + (255, 152, 17), (254, 173, 68), (255, 186, 83), (255, 174, 69), + (253, 167, 64), (228, 158, 44), (170, 117, 49), (104, 81, 65), + (101, 79, 65), (137, 93, 32), (148, 87, 6), (183, 104, 3), + (194, 109, 3), (199, 129, 43), (182, 141, 75), (147, 141, 167), + (177, 151, 252), (201, 180, 255), (222, 217, 213), (246, 195, 129) + ), + +// 216 Apophysis-040427-4DmnCntndWP +((116, 190, 251), (121, 191, 251), (123, 192, 249), (126, 193, 248), + (131, 196, 250), (137, 200, 253), (138, 200, 253), (140, 200, 254), + (171, 216, 255), (172, 215, 252), (174, 214, 249), (197, 215, 230), + (220, 217, 212), (228, 214, 201), (237, 212, 190), (231, 212, 197), + (226, 213, 204), (161, 205, 240), (149, 201, 246), (137, 198, 252), + (133, 193, 245), (130, 188, 238), (130, 188, 238), (130, 188, 238), + (132, 185, 229), (141, 167, 194), (150, 150, 160), (201, 150, 114), + (253, 151, 69), (252, 137, 46), (252, 124, 23), (245, 127, 40), + (255, 155, 77), (208, 171, 142), (177, 162, 151), (146, 153, 161), + (115, 132, 144), (84, 111, 128), (71, 103, 128), (59, 95, 129), + (84, 138, 184), (90, 156, 211), (96, 174, 238), (83, 171, 244), + (70, 169, 250), (59, 163, 248), (48, 158, 247), (35, 154, 254), + (21, 148, 253), (5, 135, 245), (2, 133, 243), (0, 132, 241), + (2, 129, 235), (4, 127, 230), (2, 121, 220), (0, 115, 210), + (1, 68, 123), (0, 59, 108), (0, 51, 94), (2, 47, 86), + (4, 44, 79), (8, 46, 80), (13, 49, 81), (8, 61, 105), + (4, 67, 121), (17, 126, 217), (75, 152, 217), (133, 178, 217), + (149, 183, 215), (165, 189, 213), (201, 201, 201), (244, 189, 148), + (212, 169, 137), (186, 178, 174), (160, 188, 212), (147, 189, 226), + (135, 191, 240), (133, 194, 245), (132, 197, 251), (127, 196, 255), + (124, 193, 252), (130, 197, 252), (150, 195, 234), (171, 193, 216), + (192, 192, 194), (213, 192, 173), (217, 164, 122), (238, 147, 76), + (183, 82, 0), (169, 83, 16), (155, 85, 33), (162, 88, 30), + (170, 92, 28), (198, 90, 2), (235, 106, 4), (253, 113, 0), + (204, 121, 53), (128, 81, 35), (100, 96, 89), (72, 111, 144), + (60, 105, 144), (48, 99, 144), (41, 97, 144), (31, 110, 177), + (15, 122, 218), (24, 137, 234), (34, 152, 250), (53, 161, 252), + (72, 171, 254), (89, 180, 253), (102, 185, 255), (105, 186, 252), + (106, 185, 251), (54, 160, 248), (46, 158, 251), (38, 156, 254), + (28, 151, 254), (24, 147, 250), (10, 133, 236), (0, 130, 236), + (11, 80, 137), (25, 60, 90), (39, 40, 44), (56, 47, 43), + (73, 55, 43), (142, 66, 6), (143, 60, 0), (126, 55, 1), + (54, 24, 0), (22, 18, 15), (11, 19, 26), (1, 20, 37), + (3, 33, 59), (1, 20, 35), (4, 5, 7), (18, 6, 0), + (8, 17, 24), (10, 36, 59), (12, 56, 95), (26, 68, 105), + (41, 81, 116), (50, 94, 133), (63, 98, 128), (55, 100, 141), + (56, 107, 150), (61, 126, 180), (66, 138, 198), (72, 150, 216), + (93, 163, 223), (132, 174, 216), (171, 169, 170), (127, 192, 248), + (135, 200, 254), (137, 200, 254), (140, 200, 254), (145, 199, 246), + (172, 200, 224), (211, 206, 202), (240, 203, 174), (245, 205, 170), + (252, 207, 168), (224, 214, 205), (203, 205, 207), (183, 197, 210), + (158, 202, 239), (150, 204, 250), (153, 202, 243), (180, 202, 223), + (254, 202, 162), (254, 190, 140), (254, 178, 118), (236, 165, 109), + (255, 169, 98), (250, 158, 85), (188, 134, 96), (143, 95, 57), + (137, 70, 18), (76, 42, 15), (52, 61, 70), (54, 94, 129), + (28, 116, 190), (39, 147, 237), (70, 166, 250), (91, 179, 253), + (113, 188, 253), (115, 190, 253), (118, 192, 253), (108, 186, 252), + (77, 173, 250), (49, 159, 254), (34, 152, 252), (29, 145, 244), + (10, 127, 223), (7, 115, 205), (36, 89, 133), (31, 66, 96), + (39, 31, 28), (47, 33, 24), (30, 60, 88), (47, 91, 128), + (63, 114, 157), (36, 114, 180), (26, 130, 217), (21, 130, 223), + (32, 146, 242), (27, 149, 255), (25, 151, 253), (16, 144, 251), + (11, 132, 236), (10, 121, 213), (31, 109, 175), (25, 78, 122), + (9, 65, 114), (5, 65, 117), (19, 78, 138), (10, 109, 190), + (7, 116, 209), (9, 119, 208), (19, 110, 189), (24, 91, 146), + (34, 81, 123), (36, 64, 88), (120, 74, 38), (143, 65, 1), + (171, 77, 3), (186, 94, 21), (216, 116, 30), (154, 108, 82), + (127, 122, 119), (122, 153, 181), (102, 149, 191), (34, 136, 221), + (32, 145, 239), (37, 145, 235), (66, 168, 253), (84, 176, 253), + (91, 179, 253), (100, 183, 251), (101, 180, 247), (88, 175, 246), + (78, 173, 253), (72, 171, 255), (65, 166, 254), (68, 168, 253), + (91, 179, 253), (98, 181, 251), (105, 183, 249), (109, 178, 237), + (106, 172, 230), (109, 179, 238), (113, 187, 250), (112, 187, 252), + (106, 184, 248), (111, 187, 249), (115, 185, 245), (115, 190, 248) + ), + +// 217 Apophysis-040427-4DmnDimensn +((139, 118, 97), (129, 113, 124), (123, 110, 111), (118, 108, 98), + (92, 91, 95), (67, 74, 93), (72, 55, 56), (78, 37, 19), + (77, 36, 18), (86, 40, 44), (95, 45, 70), (99, 45, 84), + (104, 45, 99), (112, 52, 97), (120, 60, 96), (124, 56, 87), + (129, 53, 79), (161, 45, 84), (145, 68, 101), (130, 91, 118), + (119, 90, 115), (108, 90, 112), (99, 77, 105), (91, 64, 99), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (98, 55, 47), + (120, 74, 77), (146, 93, 103), (173, 112, 130), (228, 158, 166), + (230, 182, 196), (228, 166, 181), (190, 153, 118), (153, 141, 55), + (149, 143, 55), (145, 145, 55), (139, 135, 57), (134, 125, 60), + (164, 111, 61), (166, 78, 64), (168, 46, 67), (169, 50, 72), + (171, 55, 78), (172, 48, 77), (173, 42, 76), (162, 29, 58), + (166, 28, 51), (162, 4, 19), (134, 3, 22), (107, 3, 26), + (92, 19, 22), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (78, 37, 19), (102, 74, 54), + (126, 111, 90), (142, 117, 104), (159, 124, 118), (214, 117, 128), + (224, 107, 133), (190, 123, 141), (157, 118, 136), (125, 114, 131), + (112, 116, 131), (100, 118, 132), (94, 120, 121), (114, 117, 126), + (138, 94, 119), (152, 64, 87), (167, 34, 55), (163, 18, 37), + (159, 2, 19), (153, 1, 14), (148, 0, 10), (142, 0, 43), + (99, 0, 108), (101, 15, 106), (117, 7, 70), (133, 0, 34), + (128, 0, 28), (124, 0, 23), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (78, 49, 56), (80, 63, 95), (89, 79, 109), + (99, 96, 123), (113, 118, 114), (111, 116, 96), (102, 110, 97), + (106, 78, 93), (78, 37, 19), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (78, 37, 19), + (127, 55, 59), (132, 101, 55), (143, 105, 79), (155, 110, 104), + (151, 129, 106), (143, 122, 93), (114, 142, 83), (37, 158, 79), + (85, 123, 136), (100, 126, 120), (116, 130, 104), (126, 155, 108), + (136, 181, 112), (156, 219, 78), (165, 157, 85), (178, 141, 112), + (239, 174, 180), (249, 220, 240), (252, 232, 247), (255, 244, 255), + (230, 227, 234), (222, 220, 242), (245, 211, 236), (224, 195, 215), + (142, 105, 139), (91, 61, 118), (41, 18, 98), (46, 12, 96), + (52, 6, 94), (63, 37, 66), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (99, 30, 59), + (135, 39, 67), (157, 36, 71), (162, 18, 45), (137, 7, 33), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (76, 38, 2), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (50, 68, 56), (55, 93, 80), (92, 95, 88), + (141, 135, 57), (20, 13, 106), (25, 13, 111), (44, 13, 107), + (71, 0, 101), (104, 64, 153), (140, 125, 132), (167, 119, 143), + (230, 138, 159), (224, 134, 153), (218, 131, 147), (225, 110, 125), + (210, 100, 111), (207, 86, 101), (187, 47, 94), (174, 44, 92), + (164, 41, 72), (152, 30, 55), (150, 28, 41), (143, 38, 53), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (77, 36, 18), (77, 36, 18), (77, 36, 18), + (77, 36, 18), (128, 5, 23), (140, 0, 35), (156, 3, 21), + (146, 18, 33), (144, 19, 49), (139, 31, 65), (120, 24, 98), + (97, 41, 90), (87, 59, 100), (81, 71, 98), (88, 84, 111), + (82, 65, 120), (52, 43, 126), (48, 24, 136), (0, 73, 143), + (38, 99, 156), (75, 100, 120), (84, 125, 111), (82, 139, 133), + (99, 134, 140), (118, 139, 170), (133, 156, 172), (224, 153, 171), + (230, 159, 173), (217, 132, 151), (183, 92, 109), (163, 58, 73), + (149, 53, 64), (78, 37, 19), (77, 36, 18), (77, 36, 18), + (79, 38, 20), (137, 92, 59), (122, 108, 79), (164, 70, 96), + (191, 59, 70), (199, 83, 94), (179, 88, 105), (167, 73, 99), + (166, 71, 95), (153, 58, 102), (134, 44, 98), (135, 21, 106), + (118, 51, 105), (109, 72, 105), (114, 91, 120), (100, 107, 117), + (85, 97, 135), (95, 110, 139), (121, 101, 128), (139, 103, 117) + ), + +// 218 Apophysis-040427-4SatnFlorlSwag +((115, 96, 79), (58, 30, 44), (42, 31, 43), (26, 33, 43), + (13, 47, 45), (0, 62, 48), (15, 63, 53), (30, 65, 59), + (120, 89, 71), (146, 108, 87), (172, 127, 104), (190, 142, 121), + (209, 158, 139), (215, 158, 152), (221, 158, 166), (229, 157, 172), + (238, 156, 178), (227, 181, 168), (209, 196, 154), (191, 211, 140), + (163, 201, 135), (136, 192, 131), (133, 190, 130), (131, 189, 130), + (127, 190, 143), (143, 193, 153), (159, 196, 163), (151, 195, 153), + (144, 194, 143), (145, 197, 137), (147, 200, 132), (187, 158, 118), + (174, 129, 106), (170, 128, 104), (181, 155, 115), (193, 182, 126), + (205, 188, 138), (218, 195, 151), (220, 198, 152), (223, 201, 154), + (224, 168, 169), (212, 154, 153), (200, 141, 137), (181, 122, 116), + (163, 104, 96), (159, 100, 93), (156, 97, 91), (140, 113, 86), + (116, 130, 105), (28, 102, 129), (20, 82, 122), (12, 62, 115), + (6, 45, 102), (0, 29, 89), (5, 17, 84), (10, 6, 80), + (46, 40, 88), (76, 60, 78), (107, 80, 69), (107, 73, 65), + (108, 67, 61), (111, 66, 57), (114, 66, 54), (111, 65, 52), + (110, 61, 57), (119, 65, 63), (122, 64, 67), (126, 63, 72), + (124, 62, 70), (122, 61, 68), (119, 57, 68), (108, 55, 63), + (50, 26, 50), (25, 14, 25), (1, 3, 0), (1, 2, 0), + (2, 2, 0), (11, 14, 13), (21, 27, 27), (55, 29, 38), + (81, 39, 49), (109, 60, 56), (114, 71, 64), (119, 82, 73), + (126, 86, 78), (134, 91, 84), (149, 94, 87), (153, 94, 90), + (167, 98, 103), (185, 128, 119), (203, 158, 135), (194, 175, 140), + (185, 193, 146), (189, 189, 189), (146, 170, 172), (127, 127, 127), + (111, 92, 78), (62, 40, 52), (52, 29, 47), (43, 19, 43), + (45, 21, 43), (48, 23, 44), (70, 38, 49), (99, 57, 59), + (102, 75, 68), (92, 66, 60), (82, 57, 52), (65, 55, 44), + (49, 53, 36), (32, 46, 29), (47, 31, 32), (79, 44, 48), + (105, 56, 62), (131, 66, 74), (130, 66, 74), (130, 67, 75), + (124, 75, 68), (122, 82, 70), (109, 79, 68), (90, 74, 77), + (37, 56, 96), (25, 43, 94), (14, 30, 92), (14, 21, 87), + (15, 12, 83), (36, 25, 68), (56, 21, 61), (53, 30, 56), + (55, 28, 47), (49, 103, 105), (62, 130, 125), (75, 157, 145), + (76, 154, 164), (67, 156, 160), (50, 109, 123), (52, 84, 122), + (70, 117, 111), (83, 131, 112), (96, 145, 113), (103, 154, 115), + (110, 163, 117), (115, 184, 155), (105, 181, 169), (108, 178, 154), + (109, 156, 136), (94, 81, 75), (97, 78, 71), (100, 75, 68), + (86, 50, 64), (65, 39, 76), (56, 34, 55), (46, 22, 48), + (14, 17, 50), (13, 14, 55), (13, 11, 60), (24, 12, 62), + (56, 33, 53), (84, 53, 51), (102, 56, 56), (105, 54, 59), + (108, 58, 57), (120, 60, 68), (124, 62, 71), (128, 65, 74), + (141, 81, 80), (150, 89, 88), (152, 100, 89), (145, 90, 83), + (113, 61, 63), (101, 58, 59), (89, 55, 56), (50, 60, 36), + (9, 74, 40), (6, 84, 42), (0, 90, 68), (70, 78, 91), + (80, 81, 99), (81, 114, 97), (105, 139, 123), (105, 145, 144), + (114, 162, 148), (142, 173, 168), (185, 185, 185), (190, 190, 190), + (193, 193, 193), (198, 199, 200), (204, 205, 207), (224, 224, 224), + (225, 225, 217), (195, 195, 195), (194, 194, 184), (189, 194, 188), + (191, 191, 191), (196, 192, 191), (214, 181, 146), (207, 163, 150), + (195, 142, 128), (184, 113, 121), (164, 90, 107), (169, 105, 105), + (192, 128, 128), (205, 138, 145), (203, 143, 143), (198, 150, 130), + (184, 138, 115), (183, 126, 115), (184, 145, 116), (199, 152, 132), + (206, 158, 138), (209, 152, 135), (185, 121, 121), (170, 94, 107), + (246, 39, 49), (154, 83, 89), (149, 82, 89), (137, 70, 79), + (130, 70, 72), (135, 77, 75), (139, 96, 79), (142, 100, 84), + (137, 99, 80), (137, 99, 80), (133, 90, 74), (120, 73, 65), + (119, 63, 62), (119, 65, 63), (112, 75, 66), (113, 81, 70), + (108, 81, 70), (110, 76, 66), (115, 75, 65), (109, 66, 59), + (103, 62, 56), (99, 61, 52), (95, 45, 46), (66, 32, 48), + (40, 13, 44), (5, 3, 8), (0, 0, 0), (0, 0, 0), + (10, 12, 60), (0, 0, 69), (0, 0, 74), (2, 19, 89), + (0, 35, 128), (0, 67, 136), (0, 69, 137), (12, 99, 118), + (29, 101, 126), (59, 118, 116), (91, 138, 120), (125, 125, 125), + (162, 131, 102), (165, 130, 102), (152, 122, 94), (147, 117, 83) + ), + +// 219 Apophysis-040427-4DDragHeart +((114, 84, 22), (131, 106, 50), (178, 143, 91), (225, 181, 132), + (225, 181, 132), (225, 181, 132), (200, 168, 113), (175, 155, 94), + (114, 88, 29), (114, 86, 26), (114, 84, 24), (114, 83, 23), + (115, 83, 22), (115, 82, 21), (116, 82, 21), (116, 82, 21), + (116, 82, 21), (113, 83, 19), (111, 80, 19), (110, 78, 19), + (106, 77, 20), (103, 76, 21), (89, 61, 28), (75, 47, 35), + (99, 73, 22), (103, 75, 22), (107, 78, 22), (108, 78, 23), + (109, 78, 24), (109, 79, 24), (110, 81, 25), (109, 83, 24), + (109, 83, 22), (110, 86, 24), (111, 86, 26), (113, 87, 28), + (124, 99, 37), (136, 111, 47), (154, 133, 69), (173, 155, 91), + (189, 174, 115), (153, 127, 88), (118, 81, 62), (115, 82, 44), + (112, 83, 27), (111, 82, 26), (111, 82, 26), (112, 81, 24), + (111, 80, 25), (110, 81, 25), (110, 81, 25), (111, 82, 26), + (111, 82, 24), (112, 83, 23), (112, 83, 23), (113, 83, 23), + (113, 84, 26), (113, 85, 27), (113, 87, 28), (112, 86, 26), + (111, 85, 24), (111, 85, 24), (111, 85, 24), (112, 83, 23), + (113, 83, 23), (113, 81, 24), (112, 81, 24), (112, 81, 24), + (112, 81, 24), (112, 81, 24), (112, 82, 22), (112, 82, 20), + (111, 83, 20), (111, 82, 20), (111, 81, 21), (110, 80, 20), + (110, 80, 20), (110, 80, 20), (111, 81, 21), (112, 81, 24), + (112, 83, 25), (112, 83, 25), (112, 82, 23), (113, 81, 22), + (113, 81, 22), (113, 81, 22), (112, 82, 20), (110, 82, 17), + (113, 81, 22), (112, 81, 22), (112, 82, 22), (111, 82, 22), + (111, 82, 22), (109, 83, 22), (110, 84, 23), (111, 85, 24), + (111, 85, 26), (113, 87, 28), (115, 88, 30), (118, 89, 33), + (179, 75, 49), (240, 61, 65), (255, 82, 86), (252, 210, 62), + (253, 246, 77), (254, 235, 41), (255, 225, 5), (250, 222, 5), + (246, 219, 5), (221, 197, 3), (215, 192, 2), (237, 211, 2), + (255, 220, 4), (255, 255, 85), (255, 255, 84), (255, 255, 83), + (255, 227, 71), (254, 110, 102), (255, 83, 87), (255, 112, 116), + (208, 199, 166), (224, 210, 181), (241, 221, 197), (241, 221, 197), + (241, 221, 197), (216, 209, 183), (225, 181, 134), (225, 181, 134), + (254, 98, 99), (255, 78, 84), (254, 76, 81), (254, 75, 78), + (255, 73, 75), (247, 62, 67), (214, 37, 47), (119, 85, 22), + (113, 83, 23), (113, 84, 24), (114, 85, 25), (114, 84, 25), + (114, 83, 26), (113, 84, 26), (112, 83, 25), (112, 83, 23), + (111, 82, 22), (109, 78, 23), (108, 77, 23), (108, 77, 23), + (105, 80, 26), (104, 79, 23), (105, 76, 18), (101, 72, 16), + (95, 5, 7), (101, 24, 3), (107, 44, 0), (100, 74, 17), + (107, 77, 17), (108, 77, 20), (107, 78, 18), (108, 80, 17), + (109, 79, 15), (109, 77, 16), (109, 77, 17), (109, 77, 18), + (110, 78, 19), (111, 79, 20), (112, 80, 19), (113, 83, 19), + (117, 83, 20), (117, 83, 20), (118, 84, 21), (118, 84, 23), + (207, 40, 47), (241, 60, 65), (254, 68, 73), (254, 73, 78), + (255, 72, 76), (255, 66, 70), (240, 61, 65), (120, 86, 25), + (118, 87, 23), (117, 86, 22), (117, 85, 24), (116, 86, 24), + (124, 94, 34), (157, 123, 28), (191, 152, 23), (227, 165, 32), + (234, 179, 37), (184, 165, 1), (154, 126, 17), (118, 89, 23), + (119, 88, 23), (117, 86, 21), (116, 85, 21), (115, 86, 20), + (114, 84, 22), (113, 83, 21), (113, 83, 21), (112, 82, 20), + (112, 80, 19), (113, 79, 18), (114, 80, 19), (113, 78, 20), + (112, 80, 21), (113, 81, 22), (113, 81, 22), (115, 83, 22), + (116, 81, 23), (207, 35, 47), (237, 41, 55), (247, 64, 68), + (254, 69, 74), (251, 64, 59), (119, 90, 24), (118, 89, 23), + (117, 86, 22), (113, 87, 26), (110, 86, 24), (110, 84, 23), + (109, 83, 22), (109, 83, 22), (109, 83, 22), (109, 80, 22), + (110, 79, 22), (109, 78, 21), (110, 78, 19), (109, 77, 18), + (109, 79, 17), (111, 79, 18), (111, 79, 18), (110, 78, 19), + (110, 78, 19), (111, 79, 20), (111, 79, 20), (112, 80, 21), + (112, 80, 21), (113, 81, 22), (113, 81, 22), (113, 81, 22), + (114, 82, 21), (115, 83, 22), (116, 84, 23), (116, 82, 21), + (117, 83, 20), (116, 85, 21), (117, 86, 22), (118, 89, 23), + (120, 89, 25), (138, 103, 13), (196, 103, 25), (253, 79, 81), + (254, 84, 87), (224, 180, 133), (196, 184, 124), (173, 154, 96) + ), + +// 220 Apophysis-040427-4DimesPathsE +((212, 252, 226), (139, 125, 160), (98, 90, 114), (57, 55, 69), + (35, 28, 42), (13, 1, 15), (9, 1, 8), (6, 2, 1), + (2, 2, 2), (5, 1, 2), (8, 0, 2), (11, 0, 3), + (14, 0, 5), (32, 0, 18), (50, 0, 32), (67, 13, 50), + (84, 27, 68), (140, 63, 71), (148, 74, 65), (156, 86, 60), + (117, 66, 58), (78, 46, 57), (66, 42, 39), (55, 38, 22), + (39, 86, 92), (39, 88, 111), (39, 91, 131), (85, 101, 142), + (132, 111, 154), (137, 104, 160), (143, 98, 167), (144, 96, 144), + (96, 88, 112), (80, 45, 109), (91, 63, 123), (102, 81, 137), + (149, 107, 122), (197, 133, 108), (213, 144, 114), (230, 156, 121), + (233, 217, 217), (224, 235, 225), (216, 254, 233), (199, 242, 226), + (183, 231, 219), (173, 222, 210), (163, 213, 202), (166, 195, 190), + (168, 188, 176), (208, 231, 202), (230, 243, 228), (252, 255, 255), + (253, 252, 253), (254, 250, 251), (254, 241, 253), (255, 232, 255), + (248, 250, 249), (235, 242, 249), (222, 234, 250), (158, 217, 252), + (94, 200, 255), (109, 186, 202), (125, 173, 149), (112, 86, 111), + (110, 45, 88), (159, 67, 130), (167, 64, 185), (176, 61, 240), + (196, 85, 247), (216, 109, 255), (200, 147, 237), (193, 196, 239), + (219, 143, 241), (227, 132, 234), (235, 122, 228), (224, 129, 231), + (213, 137, 235), (213, 151, 223), (213, 166, 212), (192, 230, 121), + (184, 208, 34), (87, 164, 0), (105, 156, 58), (124, 149, 117), + (154, 139, 117), (184, 130, 118), (198, 167, 185), (254, 187, 196), + (186, 222, 72), (134, 162, 39), (83, 103, 6), (58, 70, 10), + (34, 38, 15), (17, 6, 10), (6, 9, 0), (0, 17, 0), + (0, 30, 18), (17, 135, 47), (8, 163, 23), (0, 191, 0), + (56, 182, 58), (113, 174, 117), (163, 185, 164), (158, 213, 158), + (133, 212, 103), (117, 195, 93), (101, 178, 84), (94, 174, 58), + (88, 170, 33), (57, 245, 46), (170, 255, 30), (247, 255, 43), + (254, 253, 38), (245, 244, 226), (248, 239, 239), (252, 235, 253), + (255, 221, 252), (226, 208, 208), (192, 178, 165), (193, 161, 84), + (207, 190, 12), (204, 104, 7), (202, 19, 3), (184, 14, 1), + (167, 9, 0), (111, 18, 1), (66, 111, 6), (41, 141, 71), + (15, 93, 41), (12, 38, 55), (17, 33, 58), (22, 28, 62), + (37, 0, 75), (43, 0, 76), (42, 9, 90), (18, 1, 116), + (27, 13, 186), (24, 6, 127), (21, 0, 68), (13, 1, 58), + (5, 2, 49), (0, 0, 26), (11, 0, 23), (28, 6, 19), + (45, 16, 0), (95, 69, 80), (115, 74, 87), (136, 79, 94), + (178, 114, 166), (175, 132, 185), (189, 130, 188), (162, 55, 219), + (110, 76, 173), (115, 61, 167), (120, 46, 161), (118, 40, 150), + (114, 40, 153), (91, 21, 154), (70, 20, 153), (45, 0, 101), + (50, 0, 83), (91, 33, 118), (94, 40, 117), (98, 47, 116), + (73, 50, 79), (95, 19, 57), (122, 13, 81), (130, 56, 135), + (145, 36, 225), (159, 40, 238), (173, 45, 252), (147, 52, 198), + (103, 24, 149), (59, 2, 97), (53, 3, 66), (19, 0, 55), + (13, 4, 31), (0, 12, 20), (0, 18, 24), (7, 22, 45), + (4, 45, 99), (17, 29, 131), (62, 32, 118), (72, 90, 90), + (96, 148, 125), (126, 127, 111), (156, 106, 97), (164, 69, 67), + (181, 149, 90), (202, 142, 108), (196, 175, 172), (190, 186, 209), + (208, 186, 209), (221, 215, 217), (200, 209, 208), (186, 177, 232), + (193, 126, 170), (240, 79, 129), (169, 77, 40), (179, 28, 0), + (152, 15, 9), (116, 1, 4), (48, 5, 0), (18, 0, 12), + (8, 7, 3), (2, 14, 0), (0, 21, 0), (25, 25, 13), + (43, 18, 40), (60, 23, 64), (68, 39, 95), (50, 76, 150), + (14, 104, 201), (39, 237, 240), (31, 192, 174), (72, 177, 120), + (38, 95, 89), (17, 53, 67), (24, 34, 61), (20, 18, 32), + (6, 7, 11), (3, 3, 3), (4, 9, 3), (4, 10, 6), + (5, 6, 10), (0, 11, 17), (0, 1, 15), (0, 0, 2), + (1, 1, 1), (0, 2, 1), (0, 5, 0), (0, 7, 3), + (7, 3, 17), (39, 4, 46), (63, 0, 80), (63, 10, 142), + (81, 65, 164), (71, 82, 148), (70, 55, 112), (48, 35, 78), + (56, 18, 77), (36, 22, 57), (25, 0, 35), (18, 0, 26), + (3, 0, 17), (3, 3, 15), (2, 1, 19), (0, 2, 23), + (0, 0, 43), (11, 0, 58), (32, 2, 76), (61, 36, 101), + (110, 68, 144), (145, 107, 182), (202, 237, 207), (176, 153, 205) + ), + +// 221 Apophysis-040427-4DimensPathsE2 +((255, 234, 255), (204, 132, 244), (181, 127, 233), (158, 123, 223), + (148, 116, 203), (139, 109, 183), (137, 119, 161), (136, 130, 140), + (81, 135, 51), (72, 112, 68), (63, 89, 86), (39, 65, 68), + (15, 42, 51), (9, 29, 38), (3, 16, 25), (1, 12, 20), + (0, 8, 15), (1, 1, 1), (2, 2, 6), (4, 4, 12), + (9, 21, 14), (14, 38, 16), (22, 41, 20), (30, 45, 24), + (61, 99, 14), (100, 85, 35), (140, 71, 56), (133, 69, 87), + (126, 68, 119), (110, 80, 153), (94, 93, 187), (107, 64, 197), + (103, 26, 180), (57, 22, 102), (57, 37, 106), (57, 52, 110), + (72, 71, 140), (87, 90, 171), (123, 114, 187), (160, 139, 204), + (192, 224, 235), (154, 192, 230), (116, 161, 226), (106, 112, 201), + (96, 63, 176), (77, 45, 145), (58, 28, 114), (33, 2, 80), + (25, 0, 81), (24, 0, 57), (24, 0, 47), (25, 0, 37), + (21, 0, 29), (17, 0, 21), (15, 4, 17), (13, 8, 14), + (17, 0, 38), (14, 0, 42), (12, 0, 47), (6, 2, 30), + (0, 4, 14), (0, 2, 10), (1, 0, 7), (1, 1, 1), + (0, 2, 0), (1, 1, 1), (0, 2, 0), (0, 3, 0), + (0, 8, 0), (0, 14, 0), (9, 36, 3), (17, 69, 21), + (67, 141, 54), (103, 138, 36), (140, 135, 18), (122, 115, 22), + (105, 95, 26), (84, 95, 34), (63, 96, 43), (56, 34, 36), + (65, 22, 41), (128, 54, 107), (124, 51, 149), (121, 48, 191), + (115, 45, 187), (110, 43, 184), (132, 13, 181), (108, 17, 200), + (84, 0, 174), (56, 0, 126), (29, 0, 78), (33, 0, 68), + (37, 0, 58), (29, 0, 43), (15, 1, 24), (8, 1, 17), + (0, 0, 12), (7, 2, 9), (9, 1, 11), (11, 0, 14), + (8, 0, 16), (5, 1, 18), (20, 0, 27), (29, 2, 21), + (37, 5, 28), (39, 19, 24), (42, 34, 21), (31, 33, 16), + (20, 32, 12), (16, 11, 34), (1, 17, 43), (26, 35, 50), + (61, 47, 64), (137, 108, 138), (156, 122, 151), (176, 137, 164), + (211, 164, 232), (255, 191, 230), (235, 186, 171), (236, 179, 160), + (165, 205, 57), (142, 189, 70), (119, 174, 83), (143, 173, 78), + (167, 173, 73), (181, 80, 24), (181, 27, 77), (167, 70, 165), + (145, 76, 143), (141, 73, 50), (164, 84, 40), (187, 95, 30), + (217, 69, 5), (195, 67, 0), (179, 91, 4), (144, 79, 21), + (67, 19, 0), (39, 9, 0), (11, 0, 0), (8, 6, 1), + (5, 13, 2), (9, 43, 0), (43, 106, 0), (64, 173, 0), + (19, 242, 11), (99, 222, 95), (124, 210, 128), (149, 199, 162), + (186, 239, 197), (210, 197, 188), (220, 196, 170), (198, 177, 114), + (205, 187, 17), (185, 186, 11), (166, 185, 5), (139, 186, 30), + (129, 112, 84), (77, 72, 79), (81, 47, 84), (67, 25, 91), + (63, 0, 77), (20, 14, 16), (16, 8, 13), (13, 2, 10), + (9, 0, 0), (3, 0, 0), (4, 0, 0), (18, 5, 0), + (50, 0, 0), (67, 11, 3), (85, 22, 7), (115, 5, 0), + (132, 59, 16), (151, 62, 30), (134, 58, 44), (123, 52, 30), + (59, 38, 55), (39, 31, 70), (0, 64, 133), (20, 96, 112), + (69, 141, 104), (107, 157, 122), (109, 165, 154), (126, 117, 144), + (29, 88, 86), (25, 86, 70), (21, 84, 55), (0, 26, 0), + (8, 0, 38), (11, 4, 37), (11, 0, 22), (10, 8, 21), + (0, 29, 19), (16, 43, 24), (43, 34, 37), (58, 49, 66), + (65, 64, 106), (66, 87, 150), (81, 135, 101), (68, 129, 87), + (75, 134, 90), (80, 151, 93), (116, 174, 87), (144, 160, 121), + (206, 157, 160), (241, 233, 187), (241, 255, 215), (231, 255, 218), + (244, 255, 246), (255, 241, 255), (216, 213, 240), (207, 179, 168), + (147, 142, 113), (97, 86, 103), (77, 72, 79), (140, 69, 47), + (158, 84, 35), (173, 107, 21), (196, 140, 105), (154, 119, 143), + (142, 110, 121), (86, 65, 106), (43, 48, 70), (38, 25, 53), + (41, 14, 31), (28, 8, 20), (22, 0, 18), (24, 1, 11), + (15, 0, 8), (6, 0, 0), (1, 0, 4), (5, 2, 13), + (8, 5, 16), (11, 0, 23), (22, 0, 35), (34, 7, 50), + (49, 18, 60), (58, 8, 45), (59, 4, 43), (68, 22, 25), + (59, 10, 6), (39, 0, 0), (25, 0, 0), (28, 0, 13), + (46, 26, 28), (79, 56, 66), (86, 89, 104), (135, 130, 137), + (134, 169, 188), (135, 238, 235), (129, 238, 241), (90, 187, 168), + (98, 211, 149), (164, 221, 214), (238, 246, 225), (255, 252, 255) + ), + +// 222 Apophysis-040427-4DimensPathE2 +((224, 151, 145), (12, 8, 7), (12, 6, 4), (13, 5, 2), + (16, 6, 1), (20, 8, 0), (19, 4, 0), (19, 0, 0), + (28, 0, 0), (30, 3, 0), (32, 7, 0), (39, 7, 0), + (47, 7, 0), (52, 3, 12), (58, 0, 24), (66, 4, 24), + (75, 8, 25), (73, 44, 46), (58, 132, 126), (44, 220, 207), + (50, 224, 204), (56, 228, 202), (76, 238, 165), (96, 248, 129), + (154, 200, 200), (195, 227, 220), (237, 255, 241), (246, 238, 247), + (255, 222, 254), (255, 211, 227), (255, 200, 201), (250, 185, 103), + (251, 239, 5), (180, 250, 14), (196, 208, 17), (212, 166, 21), + (184, 169, 21), (156, 172, 21), (169, 197, 31), (183, 222, 41), + (124, 180, 0), (124, 153, 30), (124, 126, 61), (161, 106, 30), + (198, 86, 0), (202, 85, 16), (206, 85, 32), (187, 58, 36), + (189, 43, 54), (100, 0, 16), (103, 23, 8), (107, 46, 0), + (98, 110, 0), (90, 174, 0), (100, 214, 36), (111, 255, 72), + (144, 197, 81), (195, 142, 90), (247, 87, 99), (228, 58, 100), + (209, 29, 102), (220, 35, 89), (231, 41, 77), (189, 69, 44), + (182, 70, 33), (81, 24, 4), (77, 23, 2), (74, 22, 0), + (68, 24, 0), (62, 26, 0), (72, 37, 7), (72, 60, 48), + (144, 112, 117), (164, 136, 126), (185, 161, 135), (186, 176, 139), + (188, 191, 144), (183, 182, 131), (178, 173, 118), (183, 148, 118), + (182, 156, 105), (218, 144, 55), (208, 105, 61), (199, 66, 67), + (212, 74, 71), (225, 82, 76), (221, 59, 108), (211, 84, 135), + (168, 21, 189), (114, 33, 179), (61, 45, 169), (70, 42, 108), + (80, 40, 48), (65, 23, 35), (36, 29, 36), (41, 32, 25), + (49, 10, 13), (16, 7, 0), (8, 4, 0), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (8, 0, 5), (18, 0, 0), + (51, 9, 10), (86, 23, 39), (122, 37, 68), (138, 59, 83), + (155, 81, 98), (167, 114, 130), (201, 147, 173), (241, 211, 211), + (255, 224, 219), (240, 163, 145), (216, 146, 145), (192, 129, 146), + (143, 103, 91), (96, 79, 72), (96, 67, 59), (112, 80, 81), + (130, 116, 113), (133, 118, 112), (137, 120, 112), (134, 127, 114), + (132, 135, 116), (152, 138, 129), (174, 154, 153), (181, 157, 155), + (177, 166, 144), (148, 138, 102), (155, 138, 98), (163, 139, 95), + (215, 171, 46), (202, 199, 10), (174, 245, 17), (126, 234, 9), + (25, 191, 3), (27, 154, 1), (29, 118, 0), (24, 101, 0), + (19, 85, 0), (16, 38, 0), (56, 29, 2), (82, 137, 0), + (22, 158, 0), (61, 183, 0), (77, 162, 7), (93, 142, 14), + (134, 66, 27), (109, 47, 52), (103, 48, 41), (92, 49, 43), + (157, 110, 82), (167, 138, 100), (177, 167, 118), (193, 187, 171), + (255, 224, 241), (255, 251, 234), (255, 255, 242), (255, 246, 243), + (255, 224, 255), (213, 224, 182), (192, 212, 179), (172, 200, 177), + (159, 152, 142), (114, 117, 132), (66, 78, 74), (43, 90, 70), + (55, 25, 0), (53, 16, 0), (51, 8, 1), (44, 0, 0), + (49, 0, 17), (45, 0, 44), (43, 7, 55), (56, 0, 114), + (75, 35, 167), (94, 78, 200), (89, 127, 202), (85, 160, 189), + (137, 167, 103), (147, 133, 94), (133, 108, 101), (138, 95, 89), + (133, 52, 49), (135, 30, 51), (138, 8, 54), (129, 0, 71), + (144, 0, 71), (158, 43, 138), (159, 65, 149), (165, 106, 124), + (196, 128, 119), (161, 114, 108), (171, 72, 90), (183, 66, 110), + (230, 79, 72), (252, 102, 17), (238, 31, 15), (232, 21, 28), + (218, 33, 38), (219, 32, 23), (193, 13, 14), (101, 1, 0), + (96, 0, 0), (83, 18, 0), (82, 2, 3), (81, 0, 8), + (80, 0, 0), (75, 0, 1), (52, 1, 0), (29, 5, 3), + (27, 0, 0), (29, 0, 0), (41, 0, 0), (67, 0, 8), + (93, 1, 2), (123, 10, 40), (178, 61, 70), (216, 141, 164), + (221, 194, 199), (255, 240, 241), (255, 252, 228), (223, 234, 191), + (198, 171, 160), (168, 117, 88), (144, 76, 41), (109, 55, 27), + (80, 20, 22), (77, 20, 11), (61, 13, 9), (61, 10, 7), + (51, 7, 8), (57, 0, 0), (55, 0, 0), (50, 0, 0), + (42, 8, 0), (28, 9, 0), (19, 16, 0), (14, 6, 3), + (10, 1, 0), (0, 6, 0), (0, 6, 2), (1, 1, 1), + (14, 0, 0), (17, 0, 0), (18, 2, 3), (14, 0, 0), + (5, 0, 4), (0, 0, 7), (1, 5, 6), (7, 7, 7), + (24, 25, 0), (59, 58, 37), (142, 102, 90), (255, 175, 156) + ), + +// 223 Apophysis-040427-4Doodles +((145, 106, 3), (181, 151, 125), (169, 173, 151), (157, 196, 177), + (154, 193, 174), (152, 191, 172), (158, 189, 173), (165, 187, 175), + (161, 161, 161), (154, 154, 154), (148, 148, 148), (148, 141, 144), + (149, 134, 141), (105, 114, 124), (61, 95, 107), (51, 84, 113), + (41, 73, 120), (17, 28, 134), (8, 30, 94), (0, 32, 54), + (15, 33, 54), (30, 35, 54), (38, 41, 51), (46, 47, 49), + (185, 150, 120), (219, 193, 125), (254, 237, 131), (210, 177, 72), + (166, 117, 14), (158, 112, 8), (150, 107, 2), (148, 91, 22), + (152, 56, 16), (145, 141, 96), (166, 164, 140), (187, 187, 185), + (195, 194, 192), (203, 202, 200), (202, 202, 201), (202, 202, 202), + (193, 193, 193), (176, 197, 187), (160, 202, 182), (98, 205, 180), + (36, 209, 179), (35, 174, 148), (34, 140, 117), (11, 72, 73), + (38, 50, 62), (88, 64, 28), (103, 75, 59), (119, 87, 90), + (137, 122, 127), (155, 158, 165), (172, 173, 176), (189, 189, 187), + (233, 237, 240), (241, 245, 247), (250, 253, 255), (252, 254, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (242, 253, 249), + (232, 232, 208), (159, 159, 159), (124, 124, 124), (89, 89, 89), + (82, 81, 82), (76, 74, 75), (64, 65, 57), (73, 55, 31), + (69, 40, 6), (58, 37, 9), (47, 35, 13), (46, 23, 7), + (46, 12, 2), (54, 18, 5), (63, 24, 9), (71, 14, 5), + (60, 13, 3), (31, 7, 43), (37, 18, 31), (44, 30, 19), + (53, 39, 19), (63, 48, 19), (78, 55, 13), (114, 85, 27), + (168, 153, 84), (162, 174, 130), (156, 195, 176), (145, 205, 205), + (134, 215, 234), (173, 255, 253), (217, 255, 250), (230, 255, 255), + (231, 255, 253), (198, 198, 196), (165, 165, 163), (133, 133, 131), + (117, 114, 108), (102, 95, 85), (82, 77, 74), (61, 79, 83), + (138, 137, 142), (156, 156, 158), (175, 175, 175), (182, 182, 182), + (189, 189, 189), (191, 191, 189), (176, 174, 175), (151, 151, 151), + (119, 119, 119), (62, 95, 4), (58, 70, 14), (54, 46, 25), + (45, 45, 45), (45, 45, 45), (41, 52, 56), (52, 59, 140), + (178, 81, 249), (162, 115, 223), (146, 150, 197), (125, 142, 183), + (105, 135, 169), (48, 165, 95), (4, 139, 34), (5, 48, 38), + (15, 15, 15), (37, 29, 6), (35, 32, 17), (34, 35, 29), + (45, 45, 45), (49, 55, 67), (60, 86, 99), (128, 128, 128), + (243, 162, 254), (241, 193, 254), (240, 225, 254), (235, 228, 242), + (231, 231, 231), (226, 215, 211), (212, 203, 206), (208, 208, 206), + (206, 206, 204), (203, 203, 201), (202, 202, 200), (202, 202, 200), + (198, 198, 198), (194, 194, 192), (190, 190, 188), (185, 185, 185), + (148, 146, 151), (154, 147, 151), (160, 148, 152), (183, 168, 173), + (193, 193, 191), (208, 214, 210), (219, 251, 240), (236, 255, 255), + (247, 255, 253), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (254, 255, 247), (254, 255, 191), + (252, 246, 148), (253, 247, 126), (255, 249, 105), (211, 255, 95), + (229, 223, 87), (237, 93, 56), (227, 4, 97), (173, 0, 72), + (160, 28, 23), (105, 118, 124), (126, 70, 69), (0, 6, 0), + (11, 9, 10), (27, 26, 24), (48, 35, 29), (47, 25, 64), + (78, 10, 121), (97, 31, 78), (116, 53, 35), (162, 44, 18), + (205, 61, 53), (242, 85, 94), (218, 112, 70), (190, 165, 85), + (204, 186, 114), (193, 186, 178), (210, 193, 201), (222, 220, 208), + (247, 247, 245), (254, 249, 253), (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, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (251, 253, 252), (255, 236, 222), + (255, 250, 189), (252, 247, 183), (247, 231, 146), (251, 222, 142), + (209, 177, 192), (187, 187, 185), (179, 179, 179), (160, 160, 160), + (154, 154, 154), (141, 147, 145), (141, 141, 141), (141, 141, 141), + (140, 140, 140), (133, 149, 139), (130, 164, 148), (129, 171, 196), + (130, 205, 224), (160, 174, 235), (179, 131, 230), (201, 134, 250), + (206, 156, 229), (191, 191, 191), (160, 199, 180), (161, 181, 170), + (145, 145, 145), (120, 120, 120), (121, 89, 51), (90, 71, 57), + (101, 70, 39), (113, 48, 28), (118, 33, 13), (144, 55, 11) + ), + +// 224 Apophysis-040427-4Doodles2 +((191, 182, 107), (176, 142, 19), (182, 145, 11), (189, 148, 4), + (188, 147, 3), (188, 146, 2), (183, 142, 3), (179, 139, 5), + (150, 128, 42), (131, 120, 76), (113, 112, 110), (89, 89, 89), + (66, 67, 69), (43, 47, 39), (20, 27, 9), (25, 26, 13), + (30, 26, 17), (56, 61, 21), (101, 88, 12), (147, 115, 4), + (172, 134, 4), (197, 153, 5), (208, 161, 5), (219, 170, 5), + (239, 187, 5), (243, 191, 4), (248, 195, 3), (249, 195, 4), + (250, 195, 6), (250, 195, 6), (250, 195, 6), (250, 195, 6), + (250, 195, 6), (250, 195, 6), (250, 195, 6), (250, 195, 6), + (240, 187, 5), (230, 180, 5), (221, 172, 5), (213, 165, 5), + (170, 92, 82), (144, 75, 71), (119, 59, 61), (101, 66, 62), + (83, 73, 64), (80, 68, 67), (77, 64, 71), (90, 75, 80), + (115, 98, 91), (178, 172, 156), (202, 192, 182), (227, 212, 209), + (207, 176, 185), (188, 141, 161), (159, 128, 137), (130, 116, 113), + (163, 127, 65), (185, 144, 35), (207, 161, 5), (221, 172, 5), + (235, 184, 5), (240, 188, 4), (246, 192, 4), (251, 193, 5), + (245, 191, 7), (219, 170, 5), (207, 161, 5), (195, 153, 5), + (186, 146, 5), (178, 140, 5), (167, 132, 4), (163, 128, 2), + (165, 130, 2), (174, 137, 3), (183, 144, 4), (199, 156, 4), + (216, 169, 5), (219, 171, 4), (222, 174, 4), (230, 180, 5), + (236, 186, 5), (229, 179, 6), (219, 172, 5), (210, 165, 4), + (206, 161, 4), (202, 157, 4), (195, 151, 2), (180, 141, 4), + (167, 129, 4), (168, 130, 4), (169, 131, 4), (174, 135, 4), + (179, 139, 5), (191, 149, 3), (208, 162, 4), (222, 174, 4), + (231, 180, 3), (246, 192, 6), (248, 193, 6), (250, 195, 6), + (250, 195, 6), (250, 195, 6), (250, 195, 6), (250, 195, 6), + (250, 195, 6), (244, 190, 6), (238, 186, 6), (233, 181, 5), + (228, 176, 4), (210, 162, 4), (185, 143, 5), (156, 121, 3), + (123, 94, 2), (57, 25, 2), (43, 22, 5), (30, 20, 8), + (21, 15, 3), (0, 18, 6), (5, 28, 8), (0, 41, 9), + (17, 71, 21), (72, 44, 11), (127, 17, 2), (151, 21, 5), + (175, 25, 8), (193, 13, 24), (153, 31, 26), (140, 108, 5), + (146, 112, 4), (139, 49, 38), (135, 50, 39), (131, 51, 40), + (127, 77, 6), (137, 105, 4), (147, 115, 4), (163, 127, 4), + (201, 158, 4), (211, 166, 4), (222, 174, 4), (224, 174, 5), + (226, 175, 6), (226, 179, 5), (228, 177, 6), (231, 179, 5), + (238, 186, 4), (250, 195, 6), (250, 195, 6), (250, 195, 6), + (250, 195, 6), (252, 194, 6), (252, 194, 6), (51, 0, 9), + (26, 45, 13), (24, 65, 19), (22, 86, 26), (18, 90, 27), + (12, 90, 28), (17, 85, 28), (15, 55, 20), (19, 34, 11), + (24, 11, 2), (44, 5, 8), (38, 3, 8), (32, 1, 9), + (12, 4, 1), (5, 4, 2), (0, 1, 0), (0, 2, 1), + (50, 34, 44), (54, 57, 54), (59, 80, 65), (105, 101, 98), + (120, 116, 113), (124, 121, 116), (135, 128, 120), (161, 160, 158), + (169, 103, 105), (205, 107, 94), (182, 90, 79), (180, 78, 64), + (115, 92, 60), (110, 85, 54), (107, 93, 93), (115, 106, 107), + (175, 147, 37), (186, 150, 21), (198, 154, 6), (214, 166, 4), + (226, 179, 3), (238, 186, 4), (248, 193, 5), (249, 194, 5), + (248, 193, 5), (247, 193, 5), (239, 187, 5), (224, 176, 4), + (200, 156, 5), (175, 160, 93), (129, 123, 109), (112, 108, 105), + (82, 68, 83), (64, 57, 65), (53, 49, 24), (79, 48, 4), + (75, 58, 2), (103, 80, 2), (124, 100, 2), (144, 112, 1), + (157, 122, 2), (160, 119, 5), (160, 119, 5), (162, 119, 6), + (163, 122, 6), (160, 124, 4), (162, 126, 3), (165, 130, 4), + (172, 133, 2), (187, 146, 2), (199, 155, 4), (214, 166, 4), + (222, 174, 4), (224, 176, 4), (222, 174, 4), (220, 172, 4), + (209, 164, 3), (193, 148, 5), (172, 133, 2), (159, 125, 2), + (139, 107, 4), (87, 81, 5), (48, 56, 5), (24, 18, 2), + (3, 0, 0), (0, 0, 0), (11, 6, 2), (41, 18, 2), + (85, 19, 3), (78, 23, 26), (117, 51, 39), (162, 115, 7), + (169, 125, 2), (177, 139, 4), (190, 148, 4), (198, 154, 5), + (202, 159, 3), (204, 159, 4), (208, 162, 4), (208, 162, 4), + (210, 165, 4), (216, 166, 5), (224, 173, 4), (226, 174, 3), + (224, 176, 4), (217, 167, 6), (194, 173, 82), (204, 191, 112) + ), + +// 225 Apophysis-040427-4doodles3 +((255, 255, 253), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (254, 254, 253), (254, 253, 251), (246, 245, 244), (238, 238, 238), + (132, 129, 206), (73, 79, 156), (14, 30, 107), (16, 24, 62), + (19, 19, 17), (9, 9, 9), (0, 0, 2), (0, 0, 11), + (0, 0, 21), (7, 22, 105), (73, 11, 63), (140, 1, 22), + (140, 0, 16), (141, 0, 11), (133, 0, 36), (125, 1, 61), + (8, 0, 135), (15, 5, 158), (23, 11, 181), (33, 38, 166), + (43, 65, 151), (23, 97, 156), (3, 130, 162), (8, 149, 231), + (9, 147, 235), (91, 118, 231), (146, 116, 166), (201, 115, 102), + (206, 100, 82), (212, 86, 63), (212, 126, 103), (212, 167, 144), + (244, 244, 244), (249, 249, 249), (255, 255, 255), (254, 254, 254), + (254, 254, 254), (248, 248, 248), (243, 243, 243), (210, 210, 210), + (174, 174, 174), (167, 63, 38), (151, 33, 19), (135, 3, 1), + (95, 5, 0), (56, 7, 0), (28, 3, 0), (1, 0, 0), + (15, 15, 15), (29, 39, 27), (44, 64, 39), (71, 92, 75), + (98, 121, 111), (126, 147, 138), (154, 174, 165), (203, 203, 203), + (246, 246, 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), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (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, 254, 254), + (239, 243, 255), (156, 175, 169), (99, 121, 168), (42, 67, 168), + (29, 33, 171), (17, 0, 174), (11, 0, 178), (10, 0, 175), + (6, 0, 110), (3, 0, 56), (0, 0, 2), (0, 0, 1), + (0, 0, 0), (5, 6, 8), (48, 24, 24), (100, 51, 55), + (161, 109, 95), (243, 224, 220), (247, 238, 236), (252, 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), (248, 248, 248), (230, 230, 230), (213, 213, 213), + (201, 185, 185), (209, 153, 138), (182, 92, 68), (132, 53, 49), + (84, 31, 13), (80, 32, 15), (76, 33, 17), (81, 31, 15), + (87, 30, 13), (110, 13, 24), (120, 43, 23), (129, 46, 40), + (142, 37, 31), (207, 15, 0), (200, 32, 0), (193, 49, 0), + (184, 43, 23), (173, 56, 39), (183, 77, 51), (186, 86, 60), + (214, 73, 46), (220, 69, 32), (227, 65, 19), (223, 74, 50), + (218, 105, 87), (220, 161, 145), (238, 205, 196), (206, 206, 206), + (207, 193, 192), (176, 176, 176), (153, 153, 153), (130, 130, 130), + (100, 100, 100), (67, 97, 85), (43, 109, 73), (34, 95, 61), + (19, 130, 61), (46, 136, 81), (74, 142, 101), (167, 166, 164), + (196, 196, 196), (240, 240, 240), (254, 254, 254), (255, 255, 255), + (255, 255, 255), (252, 255, 255), (242, 241, 239), (200, 198, 199), + (171, 171, 171), (124, 124, 124), (126, 95, 66), (160, 67, 60), + (178, 97, 54), (188, 103, 71), (198, 110, 88), (213, 175, 166), + (229, 220, 221), (251, 251, 251), (254, 255, 255), (255, 255, 255), + (255, 255, 255), (254, 255, 255), (253, 253, 253), (229, 229, 229), + (180, 184, 211), (120, 116, 203), (68, 107, 226), (6, 144, 180), + (68, 82, 143), (135, 43, 130), (128, 87, 91), (117, 77, 65), + (102, 60, 48), (95, 51, 42), (88, 31, 37), (92, 31, 36), + (117, 49, 30), (102, 54, 50), (114, 69, 72), (113, 112, 108), + (177, 177, 177), (222, 222, 224), (245, 245, 245), (254, 254, 254), + (255, 255, 255), (250, 250, 250), (223, 223, 223), (191, 193, 192), + (138, 146, 185), (97, 103, 153), (40, 73, 124), (5, 22, 104), + (4, 32, 69), (14, 14, 16), (1, 0, 0), (1, 0, 0), + (0, 0, 0), (1, 1, 1), (40, 15, 18), (52, 52, 52), + (116, 84, 73), (131, 101, 91), (161, 161, 161), (178, 178, 180), + (180, 181, 183), (182, 182, 182), (183, 182, 180), (179, 179, 179), + (158, 158, 158), (106, 132, 119), (73, 128, 96), (52, 116, 81), + (64, 90, 79), (32, 46, 117), (10, 26, 121), (43, 60, 142), + (63, 84, 89), (104, 103, 101), (151, 143, 141), (186, 186, 188), + (230, 228, 229), (250, 250, 250), (255, 255, 253), (255, 255, 255) + ), + +// 226 Apophysis-040427-4Doodle3inv +((124, 154, 164), (77, 77, 75), (75, 75, 74), (73, 73, 73), + (74, 74, 74), (76, 76, 76), (86, 86, 86), (97, 97, 97), + (182, 127, 159), (186, 146, 167), (191, 165, 176), (218, 197, 155), + (245, 229, 134), (218, 200, 150), (192, 171, 166), (171, 161, 160), + (151, 152, 154), (69, 69, 67), (37, 37, 36), (5, 5, 5), + (2, 2, 2), (0, 0, 0), (0, 0, 1), (0, 0, 2), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 1, 2), + (1, 2, 4), (9, 9, 10), (17, 17, 17), (61, 57, 56), + (123, 126, 49), (241, 225, 148), (238, 230, 193), (236, 236, 238), + (245, 245, 245), (255, 255, 253), (255, 255, 243), (255, 255, 234), + (248, 233, 150), (181, 243, 191), (115, 254, 233), (114, 254, 238), + (114, 255, 244), (122, 254, 219), (130, 254, 194), (188, 250, 113), + (247, 255, 120), (232, 244, 74), (222, 217, 89), (212, 190, 104), + (229, 148, 64), (247, 106, 24), (246, 107, 22), (246, 108, 20), + (164, 137, 24), (109, 138, 88), (54, 140, 153), (48, 154, 172), + (43, 169, 192), (43, 128, 151), (43, 88, 111), (28, 47, 53), + (11, 11, 11), (0, 0, 0), (0, 0, 0), (1, 1, 1), + (6, 6, 6), (12, 12, 12), (45, 45, 45), (81, 81, 81), + (88, 192, 217), (104, 222, 235), (120, 252, 254), (159, 250, 254), + (199, 248, 255), (226, 251, 255), (254, 255, 255), (255, 254, 255), + (240, 240, 240), (211, 191, 216), (184, 162, 180), (157, 134, 144), + (129, 107, 117), (101, 81, 90), (52, 52, 52), (9, 9, 9), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 0, 0), (1, 1, 1), (16, 12, 0), + (99, 80, 86), (156, 134, 86), (213, 188, 87), (225, 221, 84), + (238, 255, 81), (244, 255, 77), (245, 255, 80), (244, 255, 81), + (249, 255, 145), (255, 255, 253), (255, 255, 254), (255, 255, 255), + (250, 249, 247), (207, 231, 231), (155, 204, 200), (94, 146, 160), + (12, 31, 35), (6, 15, 17), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (7, 7, 7), (24, 24, 24), (42, 42, 42), (54, 70, 70), + (46, 102, 117), (73, 163, 187), (123, 202, 206), (138, 211, 230), + (171, 224, 242), (179, 222, 238), (173, 223, 240), (168, 225, 242), + (145, 242, 231), (135, 212, 232), (126, 209, 215), (113, 218, 224), + (48, 240, 255), (55, 223, 255), (62, 206, 255), (71, 212, 232), + (82, 199, 216), (72, 178, 204), (69, 169, 195), (45, 184, 205), + (41, 182, 209), (28, 190, 236), (32, 181, 205), (37, 150, 168), + (35, 94, 110), (17, 50, 59), (49, 49, 49), (48, 62, 63), + (79, 79, 79), (102, 102, 102), (125, 125, 125), (155, 155, 155), + (188, 158, 170), (212, 146, 182), (221, 160, 194), (246, 171, 194), + (236, 125, 194), (181, 113, 154), (88, 89, 91), (59, 59, 59), + (15, 15, 15), (1, 1, 1), (0, 0, 0), (0, 0, 0), + (3, 0, 0), (13, 14, 16), (55, 57, 56), (84, 84, 84), + (131, 131, 131), (129, 160, 189), (95, 188, 195), (79, 158, 199), + (77, 158, 201), (57, 145, 167), (42, 80, 89), (26, 35, 34), + (4, 4, 4), (1, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 0, 0), (2, 2, 2), (26, 26, 26), (75, 71, 44), + (135, 139, 52), (187, 148, 29), (249, 111, 75), (187, 173, 112), + (120, 212, 125), (127, 168, 164), (138, 178, 190), (153, 195, 207), + (160, 204, 213), (167, 224, 218), (163, 224, 219), (138, 206, 225), + (153, 201, 205), (141, 186, 183), (142, 143, 147), (78, 78, 78), + (33, 33, 31), (10, 10, 10), (1, 1, 1), (0, 0, 0), + (5, 5, 5), (32, 32, 32), (64, 62, 63), (117, 109, 70), + (158, 152, 102), (215, 182, 131), (250, 233, 151), (251, 223, 186), + (241, 241, 239), (254, 255, 255), (254, 255, 255), (255, 255, 255), + (254, 254, 254), (215, 240, 237), (203, 203, 203), (139, 171, 182) + ), + +// 227 Apophysis-040427-6DoublEagles2 +((127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (126, 50, 0), (126, 50, 0), (112, 44, 0), + (1, 5, 50), (1, 5, 50), (21, 27, 83), (42, 49, 117), + (58, 65, 128), (75, 81, 139), (75, 81, 139), (75, 81, 139), + (127, 35, 108), (100, 44, 55), (73, 53, 2), (37, 29, 26), + (1, 5, 50), (1, 5, 50), (1, 5, 50), (1, 5, 50), + (1, 5, 50), (1, 5, 50), (1, 5, 53), (2, 5, 56), + (22, 27, 86), (42, 49, 117), (18, 70, 172), (32, 93, 156), + (196, 197, 181), (213, 185, 110), (230, 173, 40), (216, 158, 20), + (202, 144, 0), (195, 138, 0), (189, 132, 0), (167, 80, 1), + (149, 59, 0), (127, 51, 1), (127, 52, 2), (127, 54, 3), + (115, 63, 15), (104, 73, 27), (77, 84, 77), (75, 81, 139), + (75, 81, 139), (75, 81, 139), (75, 81, 139), (88, 86, 101), + (102, 91, 63), (134, 68, 16), (122, 50, 0), (88, 30, 6), + (1, 0, 42), (1, 5, 50), (21, 27, 83), (42, 49, 117), + (42, 49, 117), (42, 49, 117), (42, 49, 117), (143, 15, 98), + (162, 108, 38), (154, 82, 19), (146, 57, 1), (139, 55, 0), + (133, 53, 0), (128, 52, 2), (127, 51, 1), (127, 51, 1), + (229, 175, 27), (163, 111, 35), (151, 102, 17), (140, 94, 0), + (135, 54, 1), (128, 50, 1), (128, 50, 1), (133, 53, 0), + (178, 80, 9), (199, 123, 26), (221, 167, 43), (232, 193, 95), + (243, 219, 147), (232, 219, 184), (234, 246, 246), (225, 250, 255), + (208, 211, 200), (232, 165, 76), (224, 150, 62), (217, 135, 49), + (232, 93, 2), (183, 72, 0), (130, 54, 4), (98, 64, 27), + (1, 5, 50), (1, 7, 70), (1, 9, 90), (21, 29, 103), + (42, 49, 117), (42, 49, 117), (42, 49, 117), (16, 13, 90), + (1, 5, 50), (1, 5, 50), (1, 5, 50), (1, 5, 50), + (1, 5, 50), (1, 5, 50), (1, 5, 50), (1, 5, 50), + (1, 5, 50), (1, 5, 50), (1, 5, 50), (0, 11, 85), + (42, 49, 117), (75, 81, 139), (75, 81, 139), (76, 81, 139), + (145, 155, 165), (211, 226, 229), (200, 225, 230), (190, 225, 231), + (150, 212, 253), (97, 187, 250), (75, 81, 139), (75, 81, 139), + (120, 193, 244), (140, 207, 247), (161, 222, 250), (172, 219, 247), + (170, 216, 232), (125, 110, 105), (167, 116, 59), (136, 60, 10), + (127, 54, 3), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (134, 53, 0), (148, 58, 0), (163, 64, 0), (193, 3, 89), + (221, 5, 102), (246, 40, 122), (233, 49, 119), (168, 117, 60), + (158, 99, 29), (145, 66, 7), (128, 50, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (125, 52, 1), + (118, 47, 1), (39, 28, 0), (1, 0, 42), (1, 5, 50), + (1, 5, 50), (1, 5, 50), (100, 41, 1), (126, 50, 0), + (126, 50, 0), (124, 50, 1), (118, 14, 93), (79, 33, 141), + (75, 81, 139), (75, 81, 139), (33, 117, 190), (59, 167, 240), + (72, 120, 184), (137, 142, 146), (175, 149, 74), (170, 118, 43), + (154, 100, 0), (138, 55, 1), (133, 53, 0), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1), + (127, 51, 1), (127, 51, 1), (127, 51, 1), (127, 51, 1) + ), + +// 228 Apophysis-040427-6Equinox +((114, 110, 231), (112, 110, 233), (113, 110, 231), (115, 110, 230), + (116, 110, 227), (118, 111, 225), (119, 112, 225), (120, 113, 225), + (120, 114, 224), (120, 114, 224), (120, 114, 224), (120, 114, 224), + (120, 114, 224), (120, 114, 223), (121, 115, 223), (122, 115, 222), + (123, 116, 222), (130, 123, 219), (139, 132, 216), (149, 141, 214), + (164, 148, 193), (180, 156, 172), (176, 155, 177), (173, 154, 182), + (140, 127, 206), (139, 125, 207), (138, 124, 209), (154, 135, 191), + (171, 147, 173), (181, 150, 154), (192, 153, 136), (219, 153, 69), + (199, 128, 46), (176, 95, 29), (163, 96, 70), (150, 98, 111), + (142, 110, 160), (135, 123, 209), (132, 121, 208), (130, 120, 207), + (119, 115, 200), (116, 78, 120), (113, 42, 40), (148, 74, 34), + (183, 106, 28), (203, 133, 51), (223, 161, 74), (251, 202, 100), + (254, 231, 101), (255, 235, 102), (254, 241, 109), (254, 247, 117), + (254, 241, 116), (254, 235, 115), (243, 222, 116), (233, 210, 117), + (202, 187, 158), (200, 184, 159), (199, 181, 161), (214, 175, 128), + (229, 169, 96), (228, 169, 87), (228, 169, 79), (237, 176, 83), + (237, 183, 87), (200, 183, 153), (181, 163, 173), (163, 143, 194), + (150, 133, 201), (138, 124, 209), (122, 117, 219), (111, 110, 230), + (99, 100, 242), (98, 100, 243), (98, 101, 244), (99, 99, 244), + (101, 97, 244), (102, 99, 241), (103, 102, 238), (107, 106, 236), + (108, 105, 236), (108, 105, 234), (111, 107, 232), (114, 110, 231), + (117, 111, 228), (120, 113, 225), (124, 116, 219), (134, 121, 211), + (170, 148, 187), (177, 155, 180), (184, 162, 174), (183, 157, 167), + (183, 152, 160), (161, 127, 154), (170, 151, 155), (178, 159, 153), + (196, 176, 167), (206, 184, 147), (209, 191, 149), (212, 198, 151), + (211, 192, 153), (210, 187, 155), (195, 170, 174), (174, 155, 183), + (136, 124, 210), (132, 121, 212), (128, 118, 215), (125, 116, 218), + (123, 114, 221), (120, 113, 225), (115, 110, 230), (109, 107, 234), + (108, 105, 234), (107, 106, 236), (107, 106, 236), (107, 106, 236), + (103, 102, 240), (102, 101, 239), (96, 93, 242), (80, 97, 247), + (89, 96, 255), (104, 105, 239), (120, 114, 224), (127, 119, 218), + (135, 125, 212), (155, 136, 200), (183, 160, 178), (195, 175, 166), + (197, 178, 163), (168, 151, 187), (155, 141, 197), (142, 131, 207), + (130, 129, 207), (130, 121, 214), (125, 117, 218), (122, 115, 221), + (123, 114, 221), (122, 114, 221), (122, 115, 221), (121, 114, 222), + (120, 114, 224), (120, 112, 223), (120, 113, 225), (120, 113, 225), + (116, 111, 229), (112, 110, 233), (110, 108, 233), (109, 107, 234), + (108, 105, 234), (109, 106, 235), (112, 110, 233), (114, 115, 241), + (118, 119, 237), (119, 121, 230), (121, 123, 224), (125, 117, 218), + (128, 118, 215), (128, 118, 215), (124, 116, 219), (122, 115, 219), + (113, 105, 214), (102, 101, 237), (78, 76, 222), (55, 51, 208), + (22, 39, 189), (0, 24, 151), (49, 11, 72), (69, 14, 53), + (126, 40, 5), (139, 53, 6), (153, 67, 8), (168, 84, 20), + (168, 85, 19), (171, 90, 24), (176, 100, 84), (162, 128, 119), + (153, 115, 164), (134, 122, 204), (134, 121, 209), (135, 122, 212), + (133, 120, 212), (130, 121, 214), (129, 118, 212), (132, 118, 213), + (128, 118, 215), (128, 118, 215), (128, 118, 215), (124, 116, 219), + (122, 115, 221), (120, 114, 224), (120, 113, 225), (116, 111, 227), + (114, 110, 230), (110, 108, 231), (109, 107, 234), (106, 106, 238), + (108, 110, 247), (108, 113, 243), (114, 113, 240), (113, 112, 232), + (120, 113, 225), (123, 114, 221), (130, 121, 214), (136, 124, 210), + (154, 128, 189), (181, 149, 124), (221, 152, 75), (227, 169, 62), + (207, 136, 54), (198, 121, 49), (203, 132, 50), (210, 142, 61), + (218, 156, 69), (182, 154, 132), (172, 135, 143), (145, 129, 200), + (111, 112, 218), (99, 100, 240), (84, 90, 236), (56, 56, 188), + (3, 26, 156), (0, 7, 88), (38, 8, 72), (53, 16, 59), + (125, 49, 15), (161, 77, 13), (177, 95, 37), (199, 126, 49), + (184, 151, 136), (166, 149, 181), (146, 134, 200), (135, 122, 210), + (133, 120, 210), (129, 119, 216), (124, 116, 219), (122, 115, 221), + (121, 115, 223), (120, 113, 225), (116, 111, 227), (112, 111, 231), + (109, 107, 234), (108, 105, 234), (107, 106, 234), (103, 103, 233), + (102, 104, 227), (107, 104, 233), (108, 105, 234), (108, 105, 234), + (109, 107, 234), (114, 110, 231), (120, 113, 225), (121, 115, 223), + (126, 119, 225), (122, 116, 222), (124, 118, 216), (122, 115, 221) + ), + +// 229 Apophysis-040427-6Equinox2 +((46, 5, 49), (137, 106, 112), (140, 156, 106), (144, 207, 100), + (141, 207, 99), (139, 207, 98), (140, 206, 100), (141, 206, 102), + (152, 194, 94), (158, 142, 115), (164, 91, 137), (140, 130, 132), + (116, 169, 127), (129, 187, 116), (143, 205, 106), (140, 206, 103), + (138, 207, 100), (132, 212, 99), (135, 208, 103), (138, 204, 107), + (142, 191, 123), (146, 178, 139), (161, 164, 146), (177, 151, 154), + (193, 152, 156), (194, 154, 153), (195, 156, 151), (175, 179, 129), + (156, 203, 107), (150, 208, 102), (145, 214, 97), (147, 223, 91), + (151, 234, 84), (154, 255, 69), (155, 250, 70), (156, 246, 71), + (150, 240, 77), (145, 234, 84), (142, 227, 81), (139, 220, 79), + (146, 221, 92), (146, 218, 93), (146, 216, 94), (145, 215, 93), + (144, 215, 93), (144, 215, 93), (145, 216, 94), (146, 216, 94), + (145, 214, 97), (144, 215, 95), (145, 217, 94), (147, 219, 94), + (147, 219, 94), (148, 220, 94), (148, 220, 94), (148, 220, 94), + (151, 233, 87), (153, 235, 86), (155, 238, 86), (153, 236, 85), + (152, 235, 85), (152, 233, 85), (152, 231, 86), (149, 227, 89), + (146, 222, 90), (154, 196, 94), (191, 175, 91), (229, 154, 89), + (242, 160, 78), (255, 167, 68), (249, 122, 43), (238, 116, 69), + (211, 126, 62), (213, 107, 53), (216, 89, 44), (221, 100, 55), + (226, 111, 66), (230, 129, 83), (234, 148, 101), (205, 159, 135), + (200, 159, 137), (172, 69, 72), (179, 50, 43), (187, 32, 14), + (177, 30, 15), (167, 29, 16), (160, 19, 9), (140, 8, 0), + (19, 4, 23), (84, 27, 41), (150, 50, 60), (177, 60, 46), + (205, 71, 33), (241, 110, 68), (247, 160, 80), (255, 167, 93), + (230, 189, 110), (143, 225, 99), (172, 207, 122), (202, 189, 145), + (213, 184, 146), (225, 180, 147), (209, 168, 138), (147, 208, 104), + (139, 215, 55), (144, 228, 62), (149, 241, 70), (151, 241, 73), + (153, 241, 77), (152, 240, 78), (152, 235, 85), (152, 235, 85), + (152, 235, 85), (155, 238, 86), (155, 238, 86), (155, 238, 86), + (155, 238, 86), (154, 239, 86), (154, 239, 84), (153, 246, 80), + (146, 255, 71), (149, 249, 74), (152, 243, 77), (152, 239, 81), + (152, 235, 85), (151, 237, 88), (151, 233, 87), (148, 229, 90), + (147, 223, 91), (149, 221, 95), (155, 213, 103), (161, 206, 111), + (200, 168, 145), (199, 157, 141), (146, 189, 118), (141, 198, 101), + (144, 196, 113), (163, 176, 135), (183, 157, 158), (188, 154, 156), + (194, 152, 154), (211, 165, 142), (241, 172, 107), (253, 187, 91), + (255, 199, 89), (157, 218, 89), (154, 223, 91), (152, 228, 93), + (153, 230, 90), (153, 232, 89), (156, 230, 91), (153, 230, 90), + (148, 220, 94), (145, 215, 96), (143, 211, 98), (141, 207, 101), + (142, 198, 107), (147, 170, 128), (167, 146, 165), (162, 137, 166), + (143, 171, 172), (181, 180, 185), (176, 181, 179), (172, 182, 174), + (157, 195, 148), (143, 184, 142), (142, 200, 116), (143, 205, 106), + (147, 219, 94), (148, 220, 91), (149, 222, 89), (149, 227, 89), + (149, 227, 89), (155, 229, 92), (163, 234, 102), (232, 210, 124), + (251, 201, 128), (240, 193, 115), (223, 175, 111), (204, 158, 143), + (196, 155, 149), (194, 153, 149), (187, 153, 154), (146, 188, 124), + (143, 209, 99), (143, 211, 97), (144, 213, 96), (147, 219, 94), + (147, 223, 91), (150, 228, 90), (151, 229, 91), (149, 227, 91), + (146, 221, 92), (144, 215, 93), (142, 208, 98), (143, 200, 95), + (142, 195, 103), (169, 87, 76), (192, 62, 28), (195, 52, 20), + (169, 27, 15), (108, 8, 18), (22, 56, 5), (23, 67, 4), + (30, 82, 18), (57, 98, 0), (68, 113, 18), (99, 152, 64), + (130, 214, 90), (141, 216, 89), (144, 215, 93), (144, 215, 95), + (144, 213, 97), (144, 213, 97), (145, 214, 97), (144, 219, 92), + (146, 221, 92), (147, 225, 89), (147, 229, 82), (151, 230, 85), + (150, 232, 85), (152, 235, 85), (152, 235, 85), (152, 235, 85), + (153, 232, 89), (149, 227, 89), (147, 223, 91), (147, 223, 91), + (146, 221, 92), (146, 217, 87), (154, 216, 71), (149, 224, 69), + (149, 232, 64), (133, 233, 72), (142, 236, 86), (148, 233, 90), + (151, 229, 91), (149, 227, 89), (147, 223, 91), (147, 223, 91), + (147, 223, 91), (147, 223, 91), (147, 223, 91), (148, 220, 92), + (146, 216, 94), (143, 211, 98), (144, 200, 109), (141, 185, 126), + (140, 181, 147), (139, 175, 171), (169, 143, 168), (186, 147, 168), + (182, 152, 160), (195, 148, 154), (198, 155, 146), (195, 152, 146) + ), + +// 230 Apophysis-040427-6BluBrd +((254, 169, 16), (252, 167, 16), (252, 161, 15), (252, 155, 14), + (245, 143, 14), (238, 132, 14), (238, 132, 14), (238, 132, 14), + (112, 170, 8), (106, 149, 35), (100, 129, 63), (105, 139, 73), + (110, 149, 84), (117, 117, 85), (125, 86, 87), (117, 89, 112), + (110, 93, 137), (20, 70, 195), (27, 102, 225), (35, 135, 255), + (19, 93, 227), (4, 51, 199), (9, 42, 166), (15, 33, 133), + (7, 4, 61), (20, 11, 43), (33, 18, 25), (17, 17, 37), + (1, 17, 50), (8, 13, 33), (16, 9, 17), (40, 17, 0), + (33, 35, 0), (65, 49, 33), (92, 81, 49), (119, 113, 65), + (142, 137, 79), (166, 161, 93), (209, 167, 68), (253, 174, 43), + (255, 182, 27), (255, 176, 23), (255, 170, 19), (253, 162, 16), + (252, 155, 14), (245, 143, 14), (238, 132, 14), (238, 124, 12), + (246, 113, 10), (238, 111, 14), (237, 115, 14), (236, 119, 14), + (237, 123, 13), (239, 128, 13), (239, 128, 13), (239, 129, 14), + (253, 153, 15), (253, 157, 14), (253, 161, 14), (253, 157, 14), + (253, 153, 15), (250, 146, 14), (248, 140, 14), (244, 130, 16), + (240, 129, 14), (240, 129, 14), (239, 126, 13), (238, 124, 12), + (238, 124, 12), (238, 124, 12), (225, 122, 17), (204, 143, 60), + (141, 151, 88), (141, 177, 97), (141, 203, 106), (148, 182, 100), + (155, 162, 94), (149, 150, 88), (143, 138, 82), (124, 147, 91), + (118, 113, 94), (85, 158, 165), (46, 103, 169), (8, 49, 173), + (9, 41, 152), (10, 34, 132), (0, 20, 81), (48, 54, 40), + (38, 25, 35), (19, 25, 73), (0, 25, 112), (10, 26, 123), + (20, 27, 134), (13, 19, 117), (90, 47, 56), (94, 51, 6), + (69, 46, 12), (85, 52, 7), (96, 80, 3), (107, 108, 0), + (160, 98, 4), (213, 88, 8), (222, 91, 11), (221, 90, 10), + (163, 81, 7), (141, 82, 35), (120, 83, 64), (140, 89, 69), + (160, 95, 75), (220, 89, 11), (221, 100, 11), (233, 111, 12), + (232, 114, 14), (217, 92, 10), (168, 100, 40), (120, 108, 70), + (101, 65, 93), (69, 24, 177), (5, 31, 152), (0, 33, 186), + (107, 104, 113), (174, 138, 72), (241, 172, 32), (246, 176, 34), + (252, 180, 36), (251, 169, 43), (171, 141, 91), (139, 110, 80), + (123, 93, 67), (42, 90, 30), (48, 77, 33), (54, 64, 37), + (91, 53, 34), (101, 47, 83), (132, 78, 101), (180, 117, 86), + (231, 115, 12), (231, 110, 19), (232, 105, 26), (230, 81, 50), + (228, 57, 75), (186, 84, 147), (133, 30, 199), (95, 29, 225), + (63, 67, 236), (55, 141, 216), (49, 143, 212), (44, 146, 208), + (41, 191, 218), (134, 172, 195), (92, 60, 255), (142, 0, 242), + (123, 12, 194), (167, 33, 132), (211, 54, 71), (227, 96, 14), + (233, 111, 12), (231, 115, 12), (232, 116, 13), (233, 118, 11), + (234, 119, 12), (239, 128, 13), (243, 134, 13), (248, 140, 14), + (253, 153, 15), (255, 163, 16), (255, 170, 19), (255, 170, 19), + (252, 182, 24), (250, 190, 24), (249, 199, 24), (249, 204, 25), + (253, 201, 29), (254, 196, 27), (255, 183, 23), (254, 170, 19), + (248, 147, 15), (207, 132, 15), (172, 128, 89), (140, 123, 80), + (205, 101, 12), (230, 114, 11), (240, 129, 14), (253, 152, 20), + (255, 192, 29), (254, 202, 29), (253, 213, 29), (197, 254, 19), + (111, 255, 11), (138, 249, 20), (235, 237, 52), (255, 200, 41), + (255, 201, 30), (255, 201, 30), (255, 202, 28), (255, 201, 30), + (255, 190, 26), (255, 183, 23), (255, 183, 23), (255, 183, 23), + (255, 183, 23), (255, 183, 23), (255, 183, 23), (255, 182, 27), + (255, 185, 28), (254, 190, 30), (255, 192, 29), (255, 187, 26), + (255, 182, 27), (255, 173, 27), (255, 171, 20), (255, 170, 19), + (255, 171, 20), (255, 181, 24), (255, 183, 23), (255, 183, 28), + (255, 185, 30), (254, 183, 29), (255, 182, 27), (255, 178, 22), + (255, 170, 19), (255, 170, 19), (252, 163, 17), (249, 148, 14), + (232, 116, 13), (177, 108, 67), (138, 94, 91), (103, 15, 177), + (128, 11, 203), (146, 21, 226), (151, 23, 224), (176, 83, 190), + (169, 164, 132), (227, 173, 41), (248, 184, 26), (253, 183, 25), + (255, 183, 23), (255, 196, 17), (253, 198, 17), (255, 191, 5), + (245, 183, 14), (254, 177, 19), (255, 177, 19), (255, 182, 23), + (244, 185, 21), (235, 192, 27), (213, 209, 22), (169, 213, 16), + (150, 204, 28), (129, 228, 41), (60, 176, 49), (101, 152, 73), + (112, 153, 85), (134, 160, 89), (150, 124, 37), (231, 125, 5) + ), + +// 231 Apophysis-040427-6BluBrdInv +((231, 125, 5), (134, 160, 89), (117, 156, 81), (101, 152, 73), + (115, 190, 57), (129, 228, 41), (139, 216, 34), (150, 204, 28), + (213, 209, 22), (228, 197, 21), (244, 185, 21), (249, 181, 20), + (255, 177, 19), (250, 180, 16), (245, 183, 14), (250, 187, 9), + (255, 191, 5), (255, 196, 17), (254, 189, 21), (253, 183, 25), + (240, 178, 33), (227, 173, 41), (198, 168, 86), (169, 164, 132), + (151, 23, 224), (139, 17, 213), (128, 11, 203), (133, 52, 147), + (138, 94, 91), (157, 101, 79), (177, 108, 67), (232, 116, 13), + (249, 148, 14), (255, 170, 19), (255, 174, 20), (255, 178, 22), + (254, 180, 25), (254, 183, 29), (254, 184, 29), (255, 185, 30), + (255, 183, 23), (255, 177, 21), (255, 171, 20), (255, 171, 20), + (255, 171, 20), (255, 172, 23), (255, 173, 27), (255, 182, 27), + (255, 187, 26), (254, 190, 30), (254, 186, 28), (255, 182, 27), + (255, 182, 25), (255, 183, 23), (255, 183, 23), (255, 183, 23), + (255, 183, 23), (255, 186, 24), (255, 190, 26), (255, 196, 27), + (255, 202, 28), (255, 201, 29), (255, 201, 30), (255, 201, 30), + (255, 200, 41), (138, 249, 20), (167, 251, 19), (197, 254, 19), + (225, 233, 24), (253, 213, 29), (255, 192, 29), (255, 173, 25), + (240, 129, 14), (222, 115, 13), (205, 101, 12), (188, 114, 50), + (172, 128, 89), (189, 130, 52), (207, 132, 15), (248, 147, 15), + (254, 170, 19), (254, 196, 27), (251, 200, 26), (249, 204, 25), + (249, 201, 24), (249, 199, 24), (252, 182, 24), (255, 172, 18), + (255, 170, 19), (254, 161, 17), (253, 153, 15), (250, 146, 14), + (248, 140, 14), (239, 128, 13), (238, 124, 12), (234, 119, 12), + (233, 118, 11), (231, 115, 12), (229, 105, 13), (227, 96, 14), + (219, 75, 42), (211, 54, 71), (123, 12, 194), (146, 15, 231), + (92, 60, 255), (66, 125, 236), (41, 191, 218), (42, 168, 213), + (44, 146, 208), (55, 141, 216), (61, 94, 199), (63, 67, 236), + (95, 29, 225), (186, 84, 147), (207, 70, 111), (228, 57, 75), + (232, 105, 26), (231, 115, 12), (231, 115, 12), (224, 115, 14), + (132, 78, 101), (111, 65, 67), (91, 53, 34), (72, 58, 35), + (54, 64, 37), (42, 90, 30), (70, 71, 53), (123, 93, 67), + (139, 110, 80), (251, 169, 43), (251, 174, 39), (252, 180, 36), + (241, 172, 32), (165, 136, 94), (107, 104, 113), (25, 43, 171), + (5, 31, 152), (53, 48, 122), (101, 65, 93), (110, 86, 81), + (120, 108, 70), (217, 92, 10), (227, 109, 13), (232, 114, 14), + (233, 111, 12), (220, 89, 11), (190, 92, 43), (160, 95, 75), + (120, 83, 64), (94, 67, 56), (163, 81, 7), (215, 81, 8), + (222, 91, 11), (217, 89, 9), (213, 88, 8), (107, 108, 0), + (107, 76, 12), (85, 52, 7), (60, 41, 1), (69, 46, 12), + (94, 51, 6), (13, 19, 117), (16, 23, 125), (20, 27, 134), + (0, 25, 112), (3, 18, 75), (38, 25, 35), (56, 42, 29), + (0, 20, 81), (5, 27, 106), (10, 34, 132), (8, 49, 173), + (41, 152, 182), (85, 158, 165), (132, 108, 140), (118, 113, 94), + (124, 147, 91), (143, 138, 82), (155, 162, 94), (143, 182, 103), + (141, 203, 106), (113, 163, 94), (141, 151, 88), (173, 133, 84), + (225, 122, 17), (231, 123, 14), (238, 124, 12), (238, 124, 12), + (238, 126, 14), (240, 129, 14), (239, 128, 13), (240, 129, 14), + (244, 130, 16), (248, 140, 14), (253, 153, 15), (252, 155, 14), + (253, 161, 14), (255, 161, 17), (253, 153, 15), (249, 141, 15), + (239, 129, 14), (239, 128, 13), (238, 124, 12), (236, 119, 14), + (235, 113, 14), (238, 111, 14), (252, 111, 6), (246, 113, 10), + (238, 124, 12), (238, 132, 14), (252, 155, 14), (254, 164, 16), + (255, 170, 19), (255, 171, 20), (255, 182, 27), (255, 176, 29), + (253, 174, 43), (166, 161, 93), (137, 117, 80), (119, 113, 65), + (88, 72, 59), (65, 49, 33), (42, 27, 4), (33, 35, 0), + (40, 17, 0), (16, 9, 17), (1, 17, 50), (8, 17, 60), + (33, 18, 25), (4, 14, 49), (7, 4, 61), (16, 11, 69), + (15, 33, 133), (4, 51, 199), (11, 132, 255), (35, 135, 255), + (41, 101, 223), (20, 70, 195), (55, 78, 145), (110, 93, 137), + (125, 86, 87), (134, 105, 75), (110, 149, 84), (107, 152, 87), + (100, 129, 63), (96, 138, 0), (112, 170, 8), (183, 172, 22), + (238, 132, 14), (238, 132, 14), (249, 148, 14), (252, 155, 14), + (253, 163, 17), (252, 167, 16), (255, 170, 19), (254, 169, 16) + ), + +// 232 Apophysis-040427-6FaerieKng +((1, 1, 1), (76, 14, 63), (84, 18, 80), (93, 22, 98), + (95, 31, 68), (98, 40, 39), (95, 35, 36), (93, 31, 34), + (3, 3, 3), (3, 5, 7), (3, 8, 12), (44, 26, 18), + (85, 44, 24), (108, 71, 39), (132, 99, 54), (134, 109, 71), + (136, 119, 89), (155, 162, 180), (128, 119, 200), (102, 77, 221), + (95, 48, 163), (89, 19, 105), (89, 17, 99), (90, 16, 93), + (103, 50, 56), (120, 62, 28), (138, 75, 0), (163, 93, 0), + (189, 112, 0), (194, 108, 0), (199, 104, 0), (162, 94, 47), + (141, 62, 57), (71, 20, 97), (35, 27, 120), (0, 34, 144), + (48, 26, 119), (97, 19, 95), (91, 31, 103), (85, 44, 112), + (71, 23, 97), (55, 13, 71), (39, 4, 46), (20, 2, 23), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (0, 3, 0), + (5, 21, 0), (8, 112, 0), (44, 120, 27), (81, 129, 55), + (109, 120, 77), (138, 111, 100), (125, 107, 116), (112, 103, 132), + (69, 137, 184), (154, 178, 184), (239, 219, 184), (219, 207, 170), + (200, 195, 157), (172, 167, 147), (145, 140, 137), (94, 86, 99), + (65, 42, 96), (24, 20, 47), (22, 36, 46), (21, 52, 46), + (15, 55, 53), (10, 58, 60), (8, 91, 71), (22, 98, 86), + (145, 64, 159), (150, 103, 170), (155, 143, 181), (157, 117, 162), + (159, 92, 143), (147, 106, 125), (135, 121, 108), (153, 145, 108), + (204, 189, 122), (127, 172, 115), (111, 137, 82), (96, 103, 49), + (66, 69, 42), (37, 35, 36), (12, 12, 12), (3, 3, 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), (25, 11, 44), (40, 22, 67), (55, 34, 91), + (37, 33, 88), (19, 32, 85), (0, 23, 83), (0, 43, 78), + (4, 89, 68), (5, 52, 41), (7, 16, 15), (4, 8, 10), + (2, 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), + (5, 7, 2), (33, 30, 17), (62, 54, 33), (74, 42, 49), + (86, 30, 65), (120, 43, 95), (176, 68, 128), (177, 70, 150), + (150, 48, 157), (140, 42, 117), (142, 50, 107), (145, 59, 98), + (134, 58, 68), (104, 58, 45), (107, 98, 67), (151, 121, 61), + (109, 164, 96), (114, 108, 100), (119, 52, 105), (117, 35, 105), + (115, 19, 106), (106, 11, 101), (131, 8, 71), (139, 58, 73), + (177, 91, 76), (177, 108, 5), (172, 110, 8), (167, 112, 11), + (155, 119, 43), (148, 142, 58), (149, 151, 67), (161, 136, 72), + (201, 121, 194), (209, 106, 212), (218, 91, 230), (204, 111, 202), + (122, 95, 140), (42, 86, 121), (14, 86, 85), (31, 100, 115), + (85, 101, 152), (247, 88, 234), (251, 97, 244), (255, 107, 255), + (255, 108, 206), (210, 120, 158), (203, 156, 100), (185, 135, 82), + (134, 53, 85), (135, 55, 100), (136, 58, 116), (155, 67, 128), + (189, 63, 145), (189, 63, 147), (194, 65, 157), (178, 45, 188), + (180, 67, 183), (168, 77, 157), (100, 65, 129), (96, 77, 99), + (52, 47, 54), (21, 22, 24), (4, 4, 6), (1, 1, 1), + (5, 1, 2), (23, 8, 1), (41, 15, 0), (82, 41, 19), + (94, 35, 41), (61, 42, 44), (32, 17, 48), (9, 4, 24), + (4, 4, 4), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (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, 0, 1), + (7, 2, 8), (13, 5, 46), (32, 20, 56), (18, 14, 51), + (6, 1, 68), (8, 1, 43), (0, 0, 30), (0, 0, 4), + (0, 0, 2), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (0, 0, 0), (1, 0, 0), (1, 0, 0), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (0, 1, 3), (0, 8, 14), (0, 35, 30), (11, 80, 49), + (5, 103, 28), (22, 112, 42), (87, 63, 25), (118, 56, 41), + (144, 78, 46), (136, 88, 12), (132, 79, 25), (92, 43, 28), + (36, 28, 26), (6, 9, 0), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (2, 2, 0), (9, 10, 0), + (41, 59, 33), (89, 45, 32), (132, 57, 28), (154, 87, 6) + ), + +// 233 Apophysis-040427-6FireDemnOrch +((42, 230, 232), (8, 250, 199), (4, 218, 181), (1, 187, 164), + (0, 140, 149), (0, 93, 135), (0, 84, 119), (0, 75, 104), + (5, 13, 85), (8, 15, 96), (11, 18, 108), (6, 35, 106), + (2, 52, 105), (1, 71, 101), (1, 90, 98), (8, 80, 86), + (16, 71, 74), (24, 10, 87), (68, 46, 77), (112, 83, 67), + (132, 131, 74), (153, 179, 82), (181, 195, 65), (210, 212, 49), + (225, 211, 150), (232, 224, 111), (239, 238, 72), (221, 222, 60), + (203, 207, 48), (183, 184, 65), (163, 162, 82), (134, 111, 70), + (114, 80, 68), (15, 14, 131), (34, 33, 161), (53, 52, 192), + (68, 63, 201), (83, 75, 210), (81, 72, 221), (80, 69, 233), + (76, 61, 252), (109, 61, 253), (143, 62, 255), (175, 74, 234), + (208, 87, 214), (204, 80, 214), (201, 74, 215), (184, 55, 218), + (173, 38, 228), (124, 66, 226), (148, 57, 226), (173, 48, 226), + (141, 26, 191), (110, 5, 157), (81, 6, 135), (53, 8, 113), + (12, 4, 87), (17, 5, 82), (22, 6, 77), (56, 14, 64), + (91, 22, 51), (89, 18, 44), (87, 15, 37), (95, 16, 35), + (100, 26, 51), (110, 30, 39), (125, 36, 36), (140, 42, 33), + (153, 66, 40), (167, 90, 48), (171, 96, 65), (211, 111, 85), + (187, 58, 96), (182, 31, 77), (178, 5, 59), (165, 6, 39), + (153, 7, 20), (150, 10, 21), (148, 14, 23), (147, 21, 6), + (147, 6, 15), (139, 23, 0), (135, 45, 0), (132, 68, 0), + (138, 65, 3), (144, 63, 7), (133, 55, 55), (137, 70, 64), + (134, 127, 37), (80, 148, 53), (27, 169, 69), (31, 156, 98), + (36, 143, 127), (4, 147, 145), (3, 156, 151), (0, 182, 164), + (36, 165, 187), (169, 166, 209), (197, 127, 183), (226, 89, 157), + (235, 103, 147), (244, 117, 138), (224, 136, 134), (204, 165, 126), + (210, 207, 76), (175, 175, 78), (141, 143, 80), (137, 134, 88), + (134, 125, 96), (108, 65, 144), (100, 67, 208), (120, 63, 194), + (184, 57, 164), (137, 68, 97), (94, 68, 116), (51, 69, 135), + (45, 78, 121), (24, 70, 119), (4, 62, 162), (27, 69, 177), + (174, 77, 192), (197, 83, 200), (221, 89, 209), (182, 126, 213), + (143, 164, 217), (70, 205, 198), (25, 238, 190), (10, 241, 197), + (5, 239, 190), (102, 169, 188), (105, 152, 165), (108, 135, 142), + (157, 68, 150), (180, 56, 178), (200, 38, 175), (196, 42, 172), + (198, 51, 121), (197, 86, 118), (196, 121, 115), (203, 129, 120), + (210, 138, 126), (222, 126, 137), (245, 103, 125), (239, 130, 99), + (246, 179, 88), (254, 83, 31), (220, 76, 40), (187, 70, 50), + (112, 84, 73), (47, 95, 141), (32, 87, 154), (98, 145, 139), + (223, 136, 170), (223, 157, 161), (223, 179, 152), (239, 213, 176), + (207, 170, 178), (101, 187, 212), (75, 213, 252), (43, 206, 213), + (3, 163, 185), (0, 70, 129), (15, 48, 125), (30, 26, 121), + (57, 1, 108), (104, 0, 75), (119, 11, 43), (117, 14, 15), + (129, 24, 0), (147, 26, 4), (165, 28, 9), (187, 49, 20), + (216, 79, 37), (211, 83, 74), (194, 90, 77), (193, 65, 80), + (213, 61, 100), (209, 70, 159), (188, 70, 193), (197, 50, 200), + (153, 55, 200), (91, 53, 214), (68, 53, 204), (32, 49, 155), + (16, 8, 94), (24, 9, 101), (32, 10, 108), (36, 18, 118), + (36, 53, 161), (63, 82, 187), (89, 84, 202), (72, 188, 229), + (49, 227, 237), (23, 242, 210), (13, 231, 183), (4, 219, 152), + (93, 149, 76), (164, 92, 44), (224, 34, 0), (225, 23, 1), + (215, 8, 0), (204, 7, 1), (190, 13, 0), (177, 15, 4), + (152, 16, 28), (133, 43, 42), (169, 13, 112), (180, 35, 176), + (200, 39, 203), (187, 58, 213), (159, 53, 211), (117, 60, 201), + (89, 55, 191), (69, 26, 115), (72, 8, 92), (102, 3, 70), + (100, 11, 41), (150, 2, 26), (160, 9, 24), (181, 13, 10), + (230, 4, 5), (243, 7, 19), (254, 68, 17), (255, 93, 0), + (188, 170, 2), (158, 166, 55), (131, 196, 30), (86, 147, 43), + (70, 138, 35), (16, 82, 78), (1, 47, 73), (8, 4, 89), + (42, 4, 91), (84, 12, 86), (155, 9, 92), (193, 47, 148), + (177, 56, 187), (164, 66, 211), (129, 69, 217), (97, 68, 236), + (104, 94, 245), (62, 169, 223), (52, 180, 217), (14, 201, 180), + (6, 195, 163), (7, 201, 177), (0, 208, 184), (1, 228, 185), + (1, 233, 185), (16, 225, 170), (20, 212, 161), (90, 180, 116), + (107, 130, 52), (133, 60, 51), (120, 59, 4), (133, 41, 30) + ), + +// 234 Apophysis-040427-6CsmcLottoWhl +((110, 68, 10), (206, 107, 22), (230, 139, 25), (255, 172, 28), + (255, 212, 33), (255, 252, 39), (255, 253, 38), (255, 255, 38), + (250, 242, 9), (221, 204, 9), (193, 167, 10), (189, 148, 5), + (186, 129, 0), (190, 125, 7), (194, 122, 14), (203, 123, 10), + (213, 124, 6), (217, 131, 18), (220, 133, 9), (223, 136, 0), + (239, 155, 10), (255, 174, 20), (255, 174, 22), (255, 175, 24), + (254, 215, 14), (254, 203, 21), (255, 192, 29), (231, 153, 30), + (207, 115, 32), (181, 101, 36), (155, 87, 40), (116, 75, 29), + (80, 51, 19), (17, 10, 17), (12, 9, 12), (8, 8, 8), + (27, 15, 4), (47, 23, 0), (61, 32, 0), (75, 42, 1), + (145, 74, 28), (158, 84, 28), (172, 94, 28), (152, 94, 16), + (132, 95, 4), (119, 89, 2), (107, 84, 0), (104, 69, 5), + (87, 54, 11), (20, 6, 0), (14, 7, 4), (8, 8, 8), + (9, 9, 9), (10, 10, 10), (23, 15, 5), (36, 20, 0), + (87, 52, 14), (92, 46, 9), (97, 41, 4), (100, 42, 5), + (104, 44, 7), (110, 50, 3), (116, 57, 0), (116, 70, 10), + (114, 79, 11), (171, 102, 1), (165, 86, 3), (160, 71, 5), + (147, 71, 2), (135, 72, 0), (116, 56, 0), (86, 36, 0), + (11, 7, 6), (7, 5, 4), (3, 3, 3), (2, 2, 2), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (2, 2, 2), + (2, 2, 2), (4, 16, 6), (5, 16, 13), (7, 16, 21), + (36, 33, 26), (66, 51, 32), (97, 84, 32), (134, 85, 19), + (172, 104, 5), (148, 90, 2), (125, 76, 0), (118, 68, 0), + (112, 61, 0), (79, 46, 13), (49, 28, 9), (12, 12, 10), + (9, 9, 9), (40, 30, 0), (67, 33, 0), (94, 36, 0), + (106, 47, 4), (118, 58, 8), (127, 56, 10), (114, 52, 5), + (63, 24, 0), (36, 16, 4), (9, 9, 9), (8, 8, 8), + (8, 8, 8), (6, 6, 6), (4, 4, 4), (3, 3, 3), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (3, 3, 3), + (4, 4, 4), (6, 6, 6), (7, 7, 7), (7, 7, 7), + (3, 3, 3), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (2, 2, 2), (2, 2, 2), (1, 1, 3), (1, 0, 5), + (2, 2, 2), (2, 2, 2), (2, 2, 2), (2, 2, 2), + (3, 3, 3), (3, 3, 3), (3, 3, 3), (3, 3, 3), + (3, 3, 3), (3, 3, 3), (3, 3, 3), (5, 5, 5), + (9, 9, 9), (69, 39, 11), (86, 51, 21), (104, 63, 31), + (126, 96, 34), (181, 132, 39), (197, 189, 202), (255, 250, 192), + (210, 182, 0), (215, 180, 0), (221, 179, 0), (241, 186, 0), + (255, 177, 19), (254, 176, 28), (255, 173, 28), (255, 165, 33), + (219, 155, 21), (144, 87, 18), (128, 73, 12), (112, 59, 7), + (83, 35, 0), (36, 20, 0), (9, 9, 9), (4, 4, 4), + (1, 1, 1), (2, 0, 0), (3, 0, 0), (5, 1, 0), + (3, 3, 1), (2, 2, 2), (2, 2, 2), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (0, 0, 0), + (0, 0, 0), (1, 1, 1), (2, 2, 2), (4, 4, 4), + (8, 8, 8), (7, 7, 6), (7, 7, 5), (12, 0, 0), + (8, 7, 3), (6, 6, 6), (5, 10, 6), (9, 9, 9), + (9, 9, 9), (21, 7, 7), (54, 31, 0), (82, 44, 0), + (104, 64, 5), (103, 67, 7), (103, 58, 16), (77, 41, 7), + (64, 29, 0), (23, 9, 0), (16, 5, 1), (22, 14, 0), + (53, 43, 7), (81, 61, 24), (123, 96, 25), (157, 125, 22), + (191, 119, 11), (221, 105, 0), (234, 116, 18), (253, 120, 15), + (255, 139, 23), (254, 162, 25), (232, 146, 35), (193, 120, 18), + (162, 118, 0), (146, 104, 6), (122, 77, 12), (116, 72, 11), + (132, 76, 29), (167, 74, 15), (179, 83, 9), (188, 94, 4), + (192, 93, 12), (186, 111, 10), (171, 93, 18), (148, 86, 9), + (144, 87, 6), (131, 76, 0), (137, 96, 0), (135, 117, 0), + (142, 118, 0), (159, 129, 0), (184, 150, 0), (199, 177, 3), + (240, 179, 10), (253, 175, 17), (239, 141, 6), (245, 112, 11), + (212, 104, 16), (161, 115, 30), (121, 91, 31), (114, 81, 30), + (117, 72, 7), (128, 48, 0), (131, 24, 0), (153, 37, 0), + (129, 52, 0), (128, 55, 10), (143, 60, 18), (138, 67, 0), + (156, 62, 0), (169, 76, 7), (245, 109, 23), (209, 86, 8) + ), + +// 235 Apophysis-040427-6DreamFaeriRlm +((3, 0, 0), (1, 1, 1), (19, 10, 6), (38, 19, 12), + (62, 34, 17), (87, 50, 23), (106, 60, 30), (125, 71, 37), + (155, 92, 77), (157, 111, 89), (160, 131, 101), (161, 126, 102), + (162, 121, 103), (151, 120, 98), (141, 120, 93), (135, 114, 90), + (130, 109, 88), (94, 66, 52), (87, 58, 39), (81, 51, 27), + (79, 50, 28), (78, 50, 29), (78, 52, 26), (78, 55, 24), + (124, 83, 51), (138, 93, 46), (153, 103, 42), (156, 95, 48), + (160, 87, 54), (165, 85, 43), (170, 84, 33), (156, 83, 42), + (146, 88, 42), (104, 58, 32), (97, 51, 30), (90, 44, 28), + (81, 44, 26), (73, 45, 24), (77, 46, 21), (81, 47, 19), + (88, 43, 1), (88, 45, 9), (88, 47, 17), (94, 58, 38), + (100, 70, 60), (114, 76, 64), (128, 82, 69), (155, 112, 80), + (165, 122, 80), (198, 146, 89), (209, 178, 128), (220, 211, 168), + (229, 216, 187), (239, 222, 206), (237, 238, 199), (235, 255, 192), + (231, 205, 144), (220, 182, 130), (209, 160, 117), (204, 171, 142), + (200, 183, 167), (203, 180, 156), (206, 177, 145), (210, 176, 139), + (210, 173, 131), (218, 203, 148), (236, 228, 158), (254, 254, 168), + (254, 254, 174), (255, 255, 180), (246, 255, 196), (252, 235, 241), + (222, 196, 183), (202, 165, 147), (182, 134, 111), (180, 131, 100), + (178, 129, 89), (176, 127, 89), (175, 125, 90), (154, 119, 77), + (155, 109, 75), (134, 72, 35), (112, 56, 27), (91, 40, 19), + (85, 37, 11), (79, 34, 3), (78, 33, 2), (78, 33, 2), + (78, 34, 0), (78, 34, 0), (79, 35, 0), (79, 35, 0), + (79, 35, 0), (78, 33, 2), (79, 34, 3), (85, 33, 0), + (84, 35, 3), (93, 42, 21), (106, 54, 33), (119, 67, 46), + (125, 77, 48), (132, 88, 51), (156, 104, 64), (167, 114, 64), + (180, 121, 81), (191, 129, 83), (203, 137, 85), (198, 143, 78), + (193, 150, 72), (176, 125, 68), (189, 148, 8), (187, 130, 15), + (150, 97, 3), (105, 53, 39), (95, 45, 37), (86, 38, 36), + (67, 38, 32), (60, 36, 26), (54, 35, 20), (52, 38, 29), + (87, 58, 52), (108, 86, 72), (129, 114, 93), (144, 122, 103), + (160, 131, 113), (188, 145, 128), (182, 149, 140), (184, 156, 142), + (179, 158, 131), (182, 165, 135), (184, 158, 146), (186, 151, 158), + (175, 145, 157), (154, 135, 131), (158, 117, 121), (141, 122, 108), + (66, 80, 63), (54, 56, 46), (42, 32, 30), (38, 32, 29), + (34, 33, 28), (53, 31, 18), (70, 27, 11), (77, 32, 3), + (77, 32, 3), (78, 33, 2), (78, 33, 2), (78, 33, 2), + (77, 34, 2), (75, 34, 2), (53, 25, 11), (49, 12, 0), + (9, 0, 0), (4, 0, 3), (0, 1, 7), (0, 5, 11), + (23, 18, 15), (55, 37, 17), (82, 52, 26), (115, 71, 32), + (128, 95, 44), (129, 83, 67), (121, 82, 59), (113, 82, 51), + (93, 58, 38), (71, 38, 23), (41, 24, 17), (33, 19, 19), + (31, 30, 25), (46, 35, 30), (61, 40, 35), (80, 56, 32), + (109, 69, 43), (112, 77, 49), (124, 71, 40), (105, 63, 39), + (88, 58, 30), (79, 57, 34), (71, 61, 52), (85, 66, 52), + (124, 85, 68), (149, 111, 88), (173, 133, 107), (182, 153, 119), + (164, 153, 135), (171, 149, 132), (179, 146, 129), (173, 134, 105), + (169, 116, 84), (153, 109, 84), (147, 113, 86), (152, 112, 86), + (154, 119, 81), (147, 113, 76), (139, 98, 66), (103, 92, 60), + (94, 62, 37), (93, 52, 30), (80, 42, 23), (62, 34, 13), + (54, 27, 8), (42, 20, 9), (37, 11, 0), (26, 0, 0), + (7, 0, 0), (1, 1, 1), (0, 0, 0), (0, 0, 0), + (1, 1, 1), (0, 2, 2), (0, 4, 8), (2, 7, 10), + (27, 12, 7), (40, 7, 0), (61, 9, 13), (76, 13, 4), + (71, 32, 1), (75, 34, 2), (77, 32, 1), (77, 32, 1), + (78, 33, 2), (79, 32, 2), (79, 32, 2), (78, 33, 2), + (78, 33, 2), (78, 33, 2), (78, 33, 2), (78, 32, 6), + (83, 46, 20), (82, 44, 23), (78, 40, 19), (70, 35, 16), + (58, 29, 21), (52, 30, 17), (40, 21, 14), (32, 17, 12), + (33, 16, 8), (22, 11, 0), (4, 4, 4), (1, 1, 1), + (1, 1, 1), (4, 4, 2), (22, 19, 2), (40, 22, 10), + (56, 29, 18), (71, 35, 19), (76, 41, 22), (75, 37, 26), + (75, 37, 26), (78, 42, 28), (79, 44, 24), (86, 44, 20), + (95, 53, 29), (114, 75, 46), (145, 108, 100), (132, 90, 65) + ), + +// 236 Apophysis-040427-6EyeUniv +((236, 112, 100), (209, 107, 103), (206, 102, 97), (204, 97, 91), + (203, 90, 83), (202, 83, 75), (201, 83, 74), (201, 84, 74), + (197, 79, 75), (197, 79, 73), (198, 79, 71), (194, 76, 69), + (191, 74, 67), (193, 75, 68), (195, 76, 70), (197, 77, 69), + (199, 78, 69), (238, 94, 60), (234, 91, 57), (231, 88, 54), + (211, 76, 53), (191, 65, 53), (187, 60, 50), (183, 56, 47), + (181, 57, 47), (184, 60, 52), (187, 64, 57), (190, 70, 62), + (194, 77, 68), (194, 78, 70), (194, 79, 72), (192, 73, 65), + (190, 71, 63), (187, 66, 58), (186, 64, 56), (186, 63, 55), + (186, 64, 56), (187, 66, 58), (188, 69, 62), (190, 73, 66), + (198, 83, 76), (203, 88, 77), (209, 93, 78), (205, 87, 74), + (202, 81, 70), (200, 79, 69), (199, 78, 69), (191, 70, 61), + (189, 68, 59), (187, 64, 56), (189, 71, 64), (191, 78, 72), + (197, 89, 82), (204, 101, 92), (208, 107, 100), (213, 114, 109), + (221, 133, 119), (218, 129, 122), (216, 126, 125), (194, 114, 127), + (173, 103, 129), (179, 98, 118), (186, 94, 107), (187, 101, 86), + (196, 84, 80), (134, 154, 152), (117, 139, 137), (100, 125, 122), + (109, 104, 120), (118, 84, 119), (36, 53, 61), (9, 26, 69), + (43, 2, 18), (111, 22, 25), (180, 43, 33), (187, 59, 50), + (194, 75, 67), (199, 85, 77), (204, 95, 88), (215, 114, 104), + (222, 136, 123), (219, 160, 118), (177, 167, 96), (136, 174, 75), + (131, 170, 72), (126, 166, 69), (121, 139, 53), (84, 80, 53), + (15, 31, 18), (27, 15, 22), (39, 0, 27), (39, 0, 27), + (40, 0, 27), (40, 1, 22), (38, 3, 9), (47, 5, 7), + (81, 50, 19), (183, 56, 47), (190, 70, 64), (197, 85, 81), + (199, 92, 88), (202, 100, 96), (209, 112, 103), (210, 125, 122), + (226, 169, 139), (232, 188, 162), (238, 207, 186), (239, 211, 189), + (240, 215, 193), (227, 240, 187), (216, 242, 181), (213, 226, 173), + (230, 178, 156), (227, 154, 147), (223, 150, 142), (220, 147, 138), + (223, 148, 129), (214, 183, 136), (194, 178, 119), (169, 166, 97), + (209, 111, 102), (155, 93, 79), (102, 75, 56), (72, 39, 44), + (43, 4, 33), (36, 4, 5), (15, 5, 6), (15, 0, 9), + (37, 2, 6), (76, 33, 14), (127, 37, 23), (179, 42, 32), + (182, 48, 37), (180, 52, 43), (184, 60, 52), (190, 72, 62), + (204, 100, 91), (212, 116, 105), (221, 133, 119), (225, 143, 120), + (229, 154, 122), (230, 178, 139), (236, 210, 177), (243, 229, 190), + (238, 207, 187), (228, 168, 158), (225, 156, 149), (222, 144, 140), + (215, 129, 128), (209, 110, 104), (203, 98, 92), (198, 86, 82), + (185, 62, 54), (183, 58, 50), (182, 55, 46), (187, 53, 42), + (185, 51, 40), (167, 77, 24), (134, 88, 29), (108, 99, 30), + (125, 119, 45), (196, 84, 80), (200, 89, 85), (204, 95, 90), + (214, 108, 92), (217, 115, 100), (214, 117, 108), (210, 115, 113), + (214, 126, 124), (214, 123, 122), (214, 120, 120), (212, 119, 112), + (210, 106, 103), (207, 98, 91), (200, 91, 84), (200, 89, 82), + (199, 87, 83), (196, 85, 78), (193, 80, 74), (148, 120, 55), + (102, 105, 78), (86, 52, 77), (76, 32, 65), (83, 49, 22), + (98, 89, 32), (102, 92, 33), (106, 96, 34), (125, 132, 55), + (147, 151, 75), (152, 159, 82), (145, 179, 85), (202, 190, 132), + (211, 229, 169), (205, 230, 164), (186, 213, 142), (171, 215, 126), + (164, 211, 119), (201, 184, 132), (203, 187, 136), (213, 203, 154), + (215, 226, 170), (230, 229, 183), (234, 197, 178), (229, 184, 145), + (219, 186, 141), (220, 182, 137), (224, 165, 125), (220, 137, 131), + (216, 128, 124), (213, 114, 109), (205, 107, 106), (211, 113, 110), + (216, 128, 116), (218, 136, 124), (219, 135, 125), (218, 131, 121), + (216, 119, 110), (207, 102, 98), (200, 91, 84), (198, 79, 71), + (194, 70, 60), (187, 64, 56), (185, 62, 54), (190, 59, 49), + (190, 57, 48), (192, 61, 51), (193, 66, 57), (194, 77, 70), + (200, 86, 76), (200, 87, 79), (201, 92, 85), (204, 93, 86), + (204, 93, 84), (204, 96, 84), (206, 95, 84), (209, 99, 86), + (216, 116, 93), (238, 129, 46), (235, 124, 43), (214, 95, 37), + (203, 94, 29), (190, 86, 31), (180, 71, 50), (184, 63, 54), + (189, 61, 50), (192, 64, 53), (199, 76, 61), (230, 92, 55), + (238, 110, 47), (246, 114, 49), (250, 105, 61), (239, 95, 61), + (225, 90, 61), (214, 86, 73), (210, 100, 87), (224, 112, 101) + ), + +// 237 Apophysis-040427-6FaeriRob +((156, 68, 4), (118, 44, 0), (119, 47, 1), (121, 51, 2), + (111, 74, 52), (102, 97, 103), (90, 85, 117), (79, 74, 132), + (71, 77, 161), (71, 76, 180), (72, 76, 199), (86, 101, 219), + (100, 127, 240), (104, 113, 244), (109, 99, 248), (86, 81, 229), + (64, 64, 210), (102, 88, 165), (110, 106, 173), (118, 124, 182), + (128, 137, 187), (138, 150, 192), (143, 160, 193), (149, 171, 194), + (179, 207, 132), (192, 229, 117), (206, 252, 102), (210, 252, 96), + (215, 253, 90), (223, 254, 81), (231, 255, 73), (242, 255, 80), + (255, 250, 79), (250, 212, 65), (237, 181, 53), (224, 150, 41), + (208, 123, 24), (192, 97, 7), (183, 88, 5), (175, 79, 3), + (173, 90, 0), (175, 125, 23), (178, 161, 47), (215, 177, 53), + (253, 193, 60), (253, 191, 59), (254, 190, 58), (249, 166, 38), + (234, 149, 42), (178, 98, 9), (168, 78, 11), (159, 58, 14), + (147, 57, 7), (135, 56, 0), (136, 56, 6), (138, 57, 12), + (150, 68, 12), (162, 78, 12), (174, 88, 13), (186, 101, 11), + (198, 115, 9), (203, 132, 14), (209, 149, 19), (254, 175, 48), + (247, 185, 50), (191, 150, 70), (175, 135, 97), (160, 121, 124), + (150, 126, 133), (141, 131, 142), (123, 135, 157), (111, 108, 75), + (112, 60, 0), (112, 50, 0), (113, 41, 1), (106, 38, 0), + (100, 35, 0), (98, 34, 0), (97, 34, 1), (103, 38, 0), + (105, 40, 0), (113, 46, 1), (108, 42, 0), (104, 39, 0), + (100, 37, 0), (97, 35, 0), (90, 29, 0), (96, 22, 0), + (96, 33, 0), (96, 33, 0), (97, 34, 1), (97, 36, 0), + (97, 38, 0), (99, 37, 0), (107, 42, 0), (107, 43, 0), + (100, 37, 0), (20, 9, 17), (12, 8, 37), (5, 7, 58), + (9, 8, 60), (13, 10, 63), (19, 8, 77), (30, 7, 61), + (42, 25, 61), (40, 29, 77), (38, 34, 93), (35, 33, 104), + (32, 33, 116), (43, 48, 140), (32, 36, 123), (53, 40, 93), + (75, 42, 69), (114, 49, 11), (123, 49, 14), (132, 49, 17), + (126, 53, 2), (125, 54, 2), (121, 49, 0), (100, 37, 6), + (44, 21, 67), (43, 24, 81), (42, 27, 96), (47, 29, 108), + (52, 32, 121), (43, 30, 122), (32, 31, 124), (50, 37, 145), + (69, 49, 162), (43, 39, 150), (42, 40, 159), (42, 41, 168), + (49, 57, 181), (36, 50, 208), (58, 52, 224), (93, 97, 207), + (149, 149, 211), (147, 162, 184), (145, 176, 158), (140, 163, 162), + (135, 151, 166), (141, 167, 166), (160, 175, 170), (154, 159, 179), + (140, 149, 188), (111, 120, 199), (102, 98, 194), (94, 77, 189), + (78, 79, 161), (96, 107, 137), (147, 110, 127), (168, 116, 69), + (206, 142, 55), (223, 142, 56), (241, 142, 57), (254, 179, 52), + (255, 194, 56), (255, 193, 60), (255, 193, 69), (242, 179, 84), + (192, 162, 110), (176, 139, 112), (186, 127, 86), (196, 115, 60), + (195, 117, 32), (202, 108, 12), (207, 110, 13), (210, 114, 14), + (227, 133, 17), (230, 136, 21), (234, 140, 26), (225, 127, 20), + (213, 116, 22), (210, 126, 30), (185, 135, 64), (192, 182, 113), + (197, 200, 93), (195, 233, 120), (192, 254, 111), (193, 248, 95), + (222, 227, 72), (203, 188, 63), (171, 146, 54), (155, 131, 59), + (177, 169, 107), (155, 160, 125), (134, 151, 143), (139, 163, 149), + (164, 154, 165), (175, 153, 139), (196, 186, 125), (207, 250, 100), + (244, 250, 102), (241, 250, 79), (252, 241, 87), (255, 212, 73), + (255, 211, 63), (255, 188, 57), (255, 159, 34), (255, 168, 27), + (248, 213, 61), (246, 225, 48), (244, 224, 51), (218, 232, 95), + (173, 205, 122), (136, 154, 178), (101, 98, 203), (80, 73, 166), + (52, 49, 164), (57, 57, 143), (64, 44, 115), (112, 85, 100), + (161, 103, 57), (196, 104, 21), (195, 100, 18), (203, 105, 18), + (204, 94, 33), (200, 103, 60), (144, 108, 96), (106, 87, 142), + (106, 89, 143), (115, 116, 102), (139, 103, 41), (167, 74, 30), + (169, 75, 5), (161, 66, 0), (170, 77, 0), (181, 79, 5), + (188, 92, 8), (198, 103, 11), (206, 114, 13), (213, 126, 11), + (236, 142, 26), (239, 145, 31), (243, 153, 31), (250, 154, 33), + (248, 152, 31), (242, 149, 28), (234, 140, 24), (212, 116, 16), + (189, 86, 7), (174, 79, 0), (163, 72, 1), (155, 70, 6), + (157, 72, 7), (166, 89, 21), (166, 98, 13), (162, 84, 10), + (153, 78, 0), (145, 61, 1), (144, 62, 4), (119, 70, 0), + (128, 53, 0), (145, 55, 0), (150, 60, 0), (164, 73, 2) + ), + +// 238 Apophysis-040427-6FaeriRob2 +((174, 71, 2), (128, 50, 2), (118, 46, 1), (109, 42, 0), + (104, 38, 0), (100, 34, 0), (96, 33, 0), (92, 33, 1), + (91, 32, 0), (87, 30, 0), (83, 28, 0), (80, 22, 5), + (77, 16, 11), (40, 16, 47), (3, 16, 84), (7, 14, 97), + (12, 12, 110), (25, 1, 51), (51, 12, 25), (78, 24, 0), + (79, 24, 0), (81, 25, 0), (82, 26, 0), (83, 27, 0), + (76, 25, 0), (77, 24, 0), (79, 23, 0), (82, 24, 0), + (86, 26, 0), (89, 29, 0), (92, 32, 0), (92, 33, 1), + (89, 30, 0), (74, 44, 52), (50, 35, 86), (26, 27, 120), + (44, 15, 76), (62, 3, 33), (68, 15, 22), (75, 28, 12), + (35, 31, 92), (35, 31, 86), (35, 31, 81), (59, 30, 43), + (83, 29, 5), (88, 32, 4), (94, 35, 3), (102, 31, 9), + (105, 31, 0), (128, 50, 1), (141, 56, 0), (155, 63, 0), + (172, 75, 5), (190, 87, 10), (190, 89, 12), (191, 91, 15), + (231, 125, 23), (240, 134, 23), (249, 143, 23), (252, 172, 39), + (255, 201, 56), (253, 212, 59), (252, 224, 62), (255, 206, 60), + (255, 184, 53), (224, 165, 63), (196, 142, 76), (168, 119, 89), + (151, 115, 105), (134, 111, 121), (84, 93, 132), (68, 70, 111), + (95, 51, 64), (127, 98, 71), (160, 145, 78), (184, 182, 83), + (208, 219, 89), (219, 230, 93), (230, 242, 98), (229, 255, 97), + (211, 251, 93), (246, 234, 52), (248, 229, 47), (250, 224, 43), + (248, 223, 46), (246, 223, 49), (226, 225, 83), (166, 215, 90), + (141, 158, 186), (118, 128, 209), (95, 99, 232), (77, 79, 228), + (60, 59, 225), (65, 69, 220), (97, 106, 235), (125, 119, 219), + (136, 147, 192), (185, 204, 148), (168, 194, 138), (151, 184, 129), + (147, 177, 113), (144, 170, 97), (134, 129, 97), (150, 79, 27), + (128, 52, 3), (140, 54, 3), (152, 57, 3), (158, 64, 1), + (165, 71, 0), (175, 78, 7), (174, 77, 9), (166, 72, 2), + (155, 60, 6), (132, 52, 1), (134, 54, 2), (137, 56, 3), + (158, 66, 1), (173, 66, 0), (184, 81, 6), (186, 93, 0), + (180, 89, 10), (169, 106, 8), (159, 124, 6), (170, 126, 14), + (181, 128, 22), (185, 153, 66), (145, 143, 128), (142, 147, 187), + (141, 127, 214), (65, 78, 208), (60, 66, 199), (55, 54, 190), + (83, 76, 169), (63, 49, 124), (54, 40, 127), (40, 38, 148), + (78, 72, 255), (92, 87, 246), (106, 102, 238), (92, 100, 233), + (79, 98, 229), (82, 85, 180), (82, 91, 106), (102, 90, 42), + (130, 65, 0), (162, 71, 1), (160, 72, 9), (159, 74, 17), + (164, 89, 31), (158, 98, 64), (121, 127, 65), (103, 118, 111), + (74, 87, 155), (85, 88, 141), (97, 89, 128), (131, 117, 117), + (134, 146, 122), (151, 194, 104), (191, 209, 89), (212, 229, 71), + (247, 224, 66), (244, 243, 65), (242, 244, 58), (240, 246, 52), + (240, 253, 60), (211, 255, 80), (189, 255, 78), (218, 248, 74), + (246, 195, 54), (238, 181, 51), (230, 168, 49), (234, 148, 49), + (246, 167, 64), (222, 167, 87), (219, 174, 141), (168, 197, 117), + (183, 230, 114), (168, 245, 163), (184, 236, 128), (208, 247, 104), + (249, 226, 110), (252, 218, 67), (247, 189, 55), (255, 160, 34), + (244, 141, 23), (247, 138, 25), (250, 135, 28), (236, 131, 24), + (226, 109, 16), (210, 97, 3), (198, 98, 12), (192, 94, 19), + (203, 106, 12), (198, 109, 19), (193, 114, 22), (182, 121, 40), + (198, 129, 62), (194, 157, 86), (167, 176, 113), (136, 159, 143), + (164, 145, 167), (158, 94, 131), (139, 93, 78), (158, 85, 42), + (148, 84, 22), (129, 55, 8), (123, 36, 6), (122, 31, 0), + (112, 44, 0), (111, 48, 17), (119, 81, 36), (100, 82, 58), + (74, 70, 129), (87, 93, 169), (115, 131, 182), (122, 152, 163), + (133, 149, 164), (157, 122, 126), (139, 108, 103), (119, 72, 42), + (98, 57, 13), (64, 24, 0), (47, 11, 15), (32, 0, 1), + (27, 5, 8), (23, 3, 15), (15, 2, 22), (8, 3, 44), + (11, 16, 74), (37, 0, 51), (73, 19, 7), (97, 37, 9), + (119, 46, 11), (141, 65, 7), (162, 94, 21), (181, 106, 38), + (184, 109, 44), (196, 98, 27), (177, 88, 20), (170, 78, 11), + (152, 69, 3), (130, 53, 1), (110, 46, 0), (103, 41, 4), + (99, 42, 0), (101, 36, 4), (115, 44, 12), (108, 60, 37), + (45, 57, 97), (35, 42, 149), (39, 38, 176), (48, 46, 205), + (58, 72, 203), (104, 108, 208), (175, 175, 147), (229, 244, 99) + ), + +// 239 Apophysis-040427-6FaeriRobDet +((4, 7, 84), (0, 0, 93), (19, 12, 150), (38, 24, 208), + (49, 40, 222), (60, 56, 237), (73, 71, 246), (86, 86, 255), + (21, 47, 206), (11, 23, 142), (1, 0, 78), (0, 0, 70), + (0, 1, 62), (3, 6, 90), (7, 11, 119), (19, 26, 126), + (32, 41, 134), (31, 29, 162), (58, 21, 94), (85, 13, 27), + (91, 21, 15), (97, 30, 3), (97, 27, 1), (97, 25, 0), + (97, 25, 1), (106, 31, 2), (116, 37, 4), (143, 53, 2), + (170, 69, 1), (182, 80, 0), (194, 91, 0), (206, 99, 3), + (255, 123, 27), (255, 174, 43), (248, 167, 42), (241, 160, 42), + (217, 125, 22), (194, 90, 3), (177, 75, 1), (160, 61, 0), + (113, 37, 1), (112, 35, 0), (112, 33, 0), (112, 51, 0), + (112, 70, 0), (123, 101, 40), (134, 132, 81), (164, 162, 150), + (154, 164, 163), (79, 87, 186), (40, 45, 133), (2, 4, 81), + (12, 4, 56), (23, 5, 31), (31, 5, 18), (39, 5, 6), + (77, 9, 6), (78, 9, 3), (80, 10, 0), (81, 13, 0), + (82, 17, 0), (83, 16, 0), (84, 15, 0), (85, 16, 1), + (86, 17, 1), (85, 16, 0), (91, 20, 0), (97, 25, 0), + (106, 30, 0), (115, 35, 0), (139, 48, 0), (172, 69, 2), + (203, 106, 3), (216, 120, 1), (230, 134, 0), (241, 148, 2), + (252, 162, 4), (253, 168, 14), (255, 175, 24), (245, 168, 26), + (216, 143, 30), (205, 98, 0), (204, 96, 0), (204, 95, 0), + (200, 91, 0), (196, 88, 0), (172, 68, 0), (144, 46, 0), + (107, 30, 2), (96, 23, 1), (86, 17, 1), (91, 11, 0), + (96, 5, 0), (103, 26, 0), (115, 35, 0), (135, 44, 0), + (171, 68, 0), (216, 110, 0), (217, 121, 2), (218, 133, 4), + (207, 136, 18), (197, 140, 33), (187, 121, 25), (175, 89, 4), + (119, 42, 0), (104, 30, 3), (90, 18, 6), (85, 15, 3), + (81, 13, 0), (79, 11, 0), (77, 9, 0), (70, 9, 0), + (41, 2, 3), (52, 0, 5), (64, 4, 3), (77, 8, 1), + (84, 15, 0), (95, 23, 0), (108, 37, 0), (117, 39, 1), + (156, 62, 0), (167, 67, 0), (179, 72, 0), (179, 73, 0), + (180, 74, 0), (178, 75, 0), (180, 77, 2), (182, 76, 2), + (194, 97, 3), (233, 155, 5), (239, 170, 12), (246, 185, 19), + (253, 173, 24), (227, 164, 51), (177, 144, 31), (138, 141, 62), + (149, 176, 157), (142, 167, 164), (136, 158, 171), (125, 142, 179), + (115, 127, 187), (86, 91, 209), (67, 68, 161), (93, 72, 53), + (90, 40, 5), (86, 18, 0), (89, 21, 2), (93, 25, 4), + (110, 31, 0), (122, 40, 0), (135, 53, 0), (147, 67, 0), + (201, 97, 0), (214, 110, 0), (227, 124, 0), (235, 153, 27), + (254, 181, 42), (255, 201, 48), (255, 224, 68), (251, 231, 58), + (244, 236, 63), (246, 253, 61), (249, 254, 62), (253, 255, 63), + (254, 244, 61), (249, 249, 57), (228, 255, 56), (218, 255, 90), + (184, 254, 129), (193, 234, 108), (202, 214, 88), (231, 211, 52), + (246, 194, 46), (243, 192, 41), (255, 174, 38), (255, 172, 34), + (255, 158, 21), (255, 159, 18), (254, 171, 33), (249, 188, 38), + (246, 208, 49), (237, 202, 72), (201, 199, 124), (172, 188, 143), + (149, 166, 192), (130, 146, 223), (112, 127, 255), (104, 113, 244), + (101, 109, 244), (104, 117, 213), (106, 88, 126), (128, 59, 17), + (130, 38, 1), (132, 33, 2), (120, 30, 3), (116, 36, 1), + (134, 43, 0), (131, 51, 0), (147, 65, 0), (164, 76, 0), + (195, 92, 0), (209, 97, 0), (219, 113, 3), (234, 142, 19), + (250, 148, 14), (255, 142, 4), (247, 139, 13), (239, 135, 10), + (228, 133, 3), (202, 134, 37), (198, 122, 46), (164, 128, 92), + (157, 140, 148), (107, 117, 166), (47, 42, 145), (89, 39, 42), + (78, 31, 23), (105, 34, 2), (124, 47, 1), (139, 63, 14), + (104, 110, 98), (149, 195, 120), (167, 216, 125), (170, 226, 101), + (183, 247, 91), (199, 220, 89), (195, 197, 124), (173, 197, 119), + (162, 181, 162), (140, 158, 162), (153, 113, 173), (122, 103, 228), + (92, 101, 255), (65, 68, 209), (53, 53, 141), (129, 73, 50), + (132, 51, 4), (127, 46, 0), (123, 41, 1), (129, 35, 0), + (136, 43, 0), (146, 44, 4), (155, 28, 0), (162, 56, 4), + (172, 67, 1), (173, 73, 0), (177, 70, 0), (180, 66, 0), + (163, 61, 0), (154, 54, 0), (154, 53, 1), (151, 57, 3), + (158, 92, 14), (178, 114, 27), (203, 255, 108), (189, 176, 80) + ), + +// 240 Apophysis-040427-6FlakWhorls +((114, 150, 80), (61, 59, 44), (34, 33, 22), (8, 8, 0), + (4, 4, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (11, 8, 1), + (23, 17, 3), (63, 45, 24), (104, 73, 45), (122, 89, 65), + (141, 106, 86), (183, 136, 80), (168, 151, 68), (153, 167, 56), + (134, 123, 57), (116, 80, 58), (111, 69, 61), (107, 58, 64), + (105, 52, 38), (107, 63, 44), (110, 74, 50), (129, 87, 42), + (149, 100, 34), (158, 113, 31), (168, 126, 28), (202, 138, 38), + (244, 128, 45), (255, 205, 93), (255, 220, 144), (255, 235, 195), + (232, 214, 150), (209, 193, 105), (192, 193, 77), (176, 194, 50), + (109, 171, 44), (70, 144, 38), (32, 117, 32), (33, 108, 21), + (34, 100, 10), (35, 101, 20), (36, 102, 30), (46, 79, 52), + (52, 61, 66), (67, 68, 73), (77, 66, 92), (87, 65, 112), + (104, 68, 97), (122, 72, 83), (118, 74, 81), (115, 76, 79), + (97, 91, 75), (99, 78, 74), (102, 65, 73), (92, 72, 69), + (83, 80, 65), (86, 73, 67), (89, 67, 69), (74, 58, 61), + (87, 73, 60), (81, 77, 52), (83, 76, 48), (86, 75, 45), + (88, 73, 41), (90, 71, 38), (85, 67, 43), (82, 66, 43), + (78, 62, 36), (72, 69, 40), (66, 77, 45), (60, 79, 47), + (54, 81, 50), (61, 76, 50), (69, 71, 50), (71, 58, 49), + (66, 58, 47), (61, 59, 0), (52, 65, 11), (44, 72, 23), + (44, 70, 40), (45, 68, 58), (50, 75, 54), (56, 89, 42), + (109, 57, 36), (127, 41, 28), (145, 26, 20), (161, 26, 20), + (178, 26, 21), (173, 72, 42), (172, 95, 51), (158, 104, 78), + (147, 97, 98), (163, 130, 139), (158, 127, 133), (154, 125, 127), + (136, 108, 121), (119, 91, 116), (88, 54, 81), (54, 31, 41), + (2, 0, 5), (1, 0, 2), (0, 0, 0), (2, 2, 0), + (4, 5, 0), (17, 15, 2), (43, 57, 42), (63, 97, 62), + (83, 120, 66), (138, 120, 98), (136, 114, 104), (134, 108, 111), + (138, 108, 108), (142, 108, 99), (137, 128, 95), (133, 144, 84), + (130, 158, 39), (159, 169, 44), (189, 180, 49), (188, 181, 52), + (188, 183, 55), (231, 187, 92), (249, 209, 75), (199, 192, 52), + (184, 194, 43), (124, 143, 54), (118, 140, 68), (113, 138, 83), + (111, 117, 73), (124, 92, 81), (143, 94, 90), (174, 95, 90), + (228, 149, 80), (240, 178, 76), (253, 207, 72), (250, 209, 76), + (248, 211, 81), (233, 202, 158), (228, 193, 135), (194, 155, 100), + (146, 132, 83), (94, 101, 49), (91, 95, 47), (89, 90, 46), + (39, 87, 37), (42, 102, 28), (41, 134, 17), (70, 143, 12), + (54, 106, 23), (68, 100, 32), (82, 95, 42), (79, 131, 31), + (109, 134, 50), (114, 127, 48), (124, 106, 34), (148, 126, 43), + (178, 145, 40), (159, 131, 24), (157, 129, 39), (156, 128, 55), + (141, 111, 73), (109, 99, 74), (89, 94, 64), (89, 83, 59), + (108, 93, 38), (108, 108, 39), (108, 123, 40), (114, 120, 48), + (113, 81, 68), (109, 73, 75), (102, 68, 84), (97, 68, 90), + (119, 77, 99), (135, 84, 99), (170, 108, 85), (183, 119, 94), + (189, 135, 99), (185, 135, 112), (195, 142, 108), (216, 173, 104), + (233, 157, 95), (225, 147, 87), (217, 138, 79), (235, 121, 48), + (219, 151, 50), (194, 135, 33), (188, 107, 44), (186, 83, 24), + (201, 47, 37), (194, 42, 41), (179, 46, 37), (153, 55, 46), + (152, 73, 58), (119, 67, 71), (98, 62, 74), (88, 63, 69), + (88, 58, 68), (85, 55, 53), (94, 45, 41), (90, 37, 33), + (88, 43, 20), (93, 43, 34), (87, 60, 53), (94, 61, 78), + (88, 70, 86), (84, 63, 82), (70, 54, 81), (69, 51, 77), + (65, 60, 66), (57, 53, 42), (22, 22, 22), (2, 4, 3), + (0, 0, 0), (3, 0, 0), (13, 7, 7), (62, 26, 38), + (80, 14, 41), (124, 42, 44), (146, 49, 66), (157, 89, 40), + (185, 104, 49), (161, 102, 44), (127, 82, 53), (88, 74, 61), + (73, 78, 58), (61, 79, 53), (62, 81, 51), (83, 90, 48), + (115, 91, 43), (139, 82, 29), (180, 86, 35), (206, 107, 26), + (238, 95, 25), (228, 98, 38), (207, 112, 32), (208, 116, 39), + (219, 137, 35), (209, 123, 62), (180, 126, 66), (115, 89, 64), + (92, 74, 50), (68, 45, 31), (58, 22, 6), (15, 12, 5), + (1, 0, 2), (5, 6, 10), (30, 24, 34), (46, 49, 104), + (82, 69, 115), (83, 76, 120), (104, 90, 141), (144, 192, 46) + ), + +// 241 Apophysis-040427-11FlarCelebrat +((218, 193, 173), (217, 187, 163), (212, 177, 148), (208, 168, 133), + (124, 193, 73), (41, 218, 14), (40, 227, 8), (39, 237, 2), + (55, 197, 49), (131, 168, 73), (207, 140, 98), (135, 197, 50), + (64, 255, 2), (58, 255, 2), (52, 255, 3), (51, 255, 1), + (50, 255, 0), (48, 243, 1), (123, 184, 38), (199, 125, 76), + (197, 103, 51), (196, 81, 26), (221, 73, 13), (247, 65, 0), + (255, 79, 1), (255, 87, 1), (255, 95, 1), (255, 112, 21), + (255, 129, 42), (228, 128, 61), (202, 128, 81), (203, 129, 84), + (201, 128, 83), (61, 255, 0), (31, 234, 24), (1, 213, 49), + (38, 144, 100), (76, 75, 151), (79, 51, 194), (82, 28, 238), + (98, 22, 255), (90, 24, 250), (83, 26, 245), (87, 62, 217), + (91, 98, 189), (151, 132, 163), (211, 166, 137), (214, 187, 160), + (218, 191, 170), (219, 208, 190), (218, 202, 182), (217, 196, 175), + (216, 189, 165), (216, 182, 155), (215, 177, 149), (214, 173, 143), + (208, 146, 105), (205, 137, 93), (202, 128, 81), (198, 103, 52), + (195, 78, 24), (193, 72, 17), (192, 67, 11), (241, 38, 0), + (246, 13, 0), (219, 0, 95), (190, 0, 119), (162, 1, 143), + (130, 1, 137), (98, 1, 132), (159, 1, 140), (174, 18, 127), + (211, 144, 102), (211, 153, 116), (212, 163, 131), (214, 177, 151), + (217, 192, 172), (218, 197, 180), (219, 203, 188), (220, 219, 214), + (232, 255, 242), (221, 231, 223), (218, 212, 197), (215, 193, 172), + (212, 177, 148), (209, 161, 125), (203, 129, 84), (200, 108, 57), + (244, 65, 0), (243, 32, 0), (242, 0, 1), (241, 0, 0), + (241, 1, 0), (165, 1, 0), (162, 0, 0), (158, 0, 27), + (117, 1, 76), (114, 27, 253), (117, 13, 254), (121, 0, 255), + (123, 0, 254), (126, 0, 254), (174, 0, 185), (193, 0, 132), + (203, 129, 84), (207, 141, 100), (211, 153, 116), (214, 164, 132), + (217, 176, 148), (216, 188, 164), (218, 192, 169), (255, 218, 145), + (255, 185, 116), (212, 173, 140), (212, 170, 137), (213, 168, 135), + (210, 161, 129), (90, 111, 178), (93, 78, 203), (95, 68, 211), + (1, 146, 237), (0, 167, 201), (0, 188, 166), (0, 186, 139), + (1, 185, 113), (0, 193, 88), (0, 202, 58), (0, 200, 65), + (76, 167, 98), (215, 181, 153), (216, 186, 161), (217, 192, 170), + (218, 196, 175), (222, 199, 181), (255, 226, 156), (254, 216, 143), + (208, 146, 105), (209, 155, 117), (210, 164, 130), (212, 172, 141), + (215, 181, 153), (216, 194, 171), (233, 235, 195), (234, 255, 224), + (246, 253, 211), (255, 241, 172), (255, 238, 171), (255, 236, 170), + (254, 231, 163), (215, 182, 151), (239, 206, 163), (225, 134, 87), + (94, 64, 214), (100, 45, 233), (107, 26, 253), (117, 21, 255), + (99, 23, 255), (83, 26, 242), (116, 47, 112), (200, 114, 67), + (201, 109, 58), (141, 130, 48), (94, 170, 38), (47, 211, 28), + (34, 231, 1), (1, 255, 1), (0, 255, 7), (0, 226, 38), + (39, 173, 172), (128, 191, 183), (218, 209, 194), (223, 231, 207), + (233, 255, 234), (237, 243, 207), (219, 203, 187), (212, 177, 147), + (80, 159, 112), (1, 172, 200), (0, 159, 219), (31, 112, 255), + (39, 64, 255), (34, 46, 252), (33, 37, 250), (41, 6, 220), + (91, 1, 148), (125, 0, 154), (160, 0, 160), (175, 0, 136), + (167, 0, 134), (164, 56, 90), (200, 118, 68), (206, 135, 91), + (206, 135, 91), (209, 140, 98), (255, 151, 66), (255, 138, 50), + (254, 112, 14), (255, 108, 12), (254, 110, 14), (202, 108, 56), + (201, 109, 58), (199, 105, 54), (199, 105, 53), (197, 96, 42), + (197, 82, 27), (255, 78, 2), (254, 79, 0), (255, 88, 0), + (255, 98, 3), (254, 127, 34), (255, 164, 87), (213, 167, 133), + (212, 175, 146), (157, 168, 186), (92, 83, 202), (86, 26, 244), + (109, 26, 254), (118, 1, 255), (86, 17, 255), (37, 0, 219), + (39, 0, 213), (39, 0, 205), (57, 1, 188), (67, 0, 175), + (108, 2, 103), (149, 0, 56), (172, 31, 1), (186, 44, 0), + (196, 75, 22), (195, 84, 28), (198, 95, 37), (197, 94, 36), + (194, 79, 24), (195, 78, 24), (192, 71, 16), (191, 64, 9), + (188, 54, 1), (179, 35, 0), (180, 33, 0), (236, 0, 2), + (230, 0, 36), (225, 0, 63), (226, 0, 76), (200, 0, 122), + (167, 0, 157), (137, 0, 238), (132, 0, 247), (161, 0, 156), + (183, 0, 140), (203, 0, 120), (219, 0, 94), (203, 112, 65), + (208, 137, 95), (210, 160, 125), (214, 177, 148), (217, 190, 169) + ), + +// 242 Apophysis-040427-11SpacTrees +((83, 77, 3), (38, 15, 33), (56, 10, 57), (74, 6, 81), + (93, 6, 87), (112, 6, 94), (111, 3, 89), (110, 1, 84), + (135, 6, 70), (156, 23, 61), (178, 40, 53), (199, 67, 79), + (220, 94, 106), (221, 85, 94), (222, 77, 82), (219, 77, 62), + (216, 78, 42), (192, 59, 40), (194, 60, 41), (196, 61, 42), + (200, 61, 45), (204, 62, 48), (214, 59, 49), (224, 57, 51), + (241, 59, 46), (243, 62, 55), (246, 66, 65), (245, 68, 72), + (244, 70, 80), (241, 71, 81), (239, 73, 83), (235, 78, 87), + (233, 76, 85), (189, 58, 40), (144, 45, 23), (99, 32, 6), + (89, 31, 29), (79, 30, 52), (103, 20, 66), (127, 10, 80), + (140, 7, 62), (141, 6, 43), (143, 6, 24), (116, 17, 14), + (90, 28, 5), (87, 26, 4), (85, 24, 3), (36, 29, 13), + (23, 8, 11), (53, 2, 61), (92, 5, 63), (132, 9, 66), + (138, 7, 45), (145, 6, 25), (144, 6, 24), (143, 6, 24), + (90, 23, 4), (94, 25, 34), (99, 27, 64), (112, 34, 82), + (126, 42, 101), (147, 74, 95), (169, 106, 89), (199, 138, 31), + (218, 163, 46), (164, 255, 22), (168, 249, 23), (173, 243, 25), + (205, 237, 18), (238, 232, 12), (246, 197, 16), (236, 189, 15), + (216, 119, 16), (206, 103, 12), (197, 87, 8), (182, 93, 8), + (167, 100, 9), (164, 99, 8), (162, 98, 8), (160, 94, 8), + (148, 82, 8), (120, 85, 43), (104, 70, 30), (88, 56, 17), + (86, 51, 10), (85, 46, 3), (86, 35, 0), (107, 45, 6), + (157, 47, 22), (183, 51, 21), (210, 56, 20), (215, 54, 16), + (220, 52, 13), (211, 79, 4), (231, 91, 14), (208, 135, 24), + (197, 130, 17), (183, 120, 49), (163, 71, 48), (144, 22, 47), + (140, 19, 54), (136, 16, 61), (135, 48, 80), (121, 109, 121), + (124, 206, 106), (124, 193, 112), (125, 181, 118), (121, 169, 104), + (118, 157, 90), (177, 81, 95), (160, 52, 50), (156, 32, 22), + (138, 37, 9), (45, 29, 6), (33, 19, 8), (22, 10, 10), + (22, 8, 8), (17, 10, 18), (20, 25, 19), (7, 51, 28), + (5, 59, 35), (7, 60, 30), (9, 61, 25), (8, 67, 26), + (7, 73, 27), (7, 62, 23), (11, 52, 12), (7, 51, 2), + (7, 49, 1), (70, 57, 5), (94, 55, 7), (118, 54, 10), + (148, 39, 6), (158, 50, 47), (166, 76, 39), (163, 97, 10), + (196, 86, 7), (202, 73, 12), (208, 61, 17), (206, 63, 31), + (205, 66, 45), (215, 63, 52), (213, 65, 29), (196, 57, 14), + (200, 45, 27), (166, 54, 30), (155, 56, 17), (145, 58, 5), + (124, 54, 5), (117, 51, 3), (93, 54, 0), (71, 85, 0), + (21, 68, 14), (17, 56, 9), (13, 45, 4), (24, 37, 9), + (22, 11, 9), (19, 8, 12), (22, 6, 16), (20, 3, 13), + (16, 4, 16), (11, 5, 9), (14, 5, 11), (18, 5, 14), + (19, 6, 15), (22, 6, 17), (22, 8, 33), (40, 2, 53), + (93, 12, 91), (103, 9, 93), (113, 7, 95), (168, 7, 147), + (161, 45, 142), (161, 110, 167), (156, 115, 119), (159, 162, 119), + (183, 188, 122), (162, 139, 98), (161, 116, 93), (155, 111, 110), + (179, 100, 93), (190, 113, 85), (204, 126, 106), (202, 109, 140), + (255, 255, 251), (252, 249, 250), (249, 244, 250), (247, 87, 157), + (246, 84, 105), (243, 108, 76), (231, 106, 86), (213, 113, 90), + (170, 144, 95), (151, 175, 115), (129, 178, 157), (125, 181, 156), + (130, 193, 172), (121, 196, 155), (122, 201, 122), (123, 213, 90), + (147, 244, 27), (120, 230, 35), (191, 120, 12), (159, 93, 7), + (118, 50, 5), (113, 38, 9), (96, 31, 3), (103, 37, 5), + (128, 54, 15), (143, 68, 10), (150, 96, 6), (159, 107, 5), + (167, 102, 10), (187, 118, 14), (215, 148, 17), (226, 173, 17), + (238, 196, 22), (230, 153, 25), (219, 151, 18), (219, 106, 48), + (240, 84, 43), (231, 77, 41), (222, 61, 53), (212, 82, 46), + (223, 103, 53), (235, 111, 75), (218, 134, 46), (231, 143, 79), + (171, 131, 96), (130, 98, 113), (71, 52, 54), (31, 27, 16), + (31, 35, 8), (69, 77, 18), (132, 117, 22), (159, 145, 57), + (229, 150, 84), (235, 123, 85), (224, 83, 91), (197, 60, 76), + (175, 30, 45), (145, 21, 55), (137, 40, 59), (141, 87, 27), + (157, 150, 43), (131, 233, 35), (170, 246, 36), (148, 245, 26), + (123, 228, 50), (103, 212, 85), (82, 202, 104), (103, 208, 113), + (163, 206, 88), (152, 177, 86), (123, 168, 73), (126, 136, 40) + ), + +// 243 Apophysis-040427-11FloralQult +((88, 3, 68), (62, 75, 83), (59, 87, 68), (57, 100, 54), + (58, 114, 59), (60, 129, 64), (58, 120, 73), (57, 112, 83), + (116, 92, 116), (139, 105, 148), (162, 118, 181), (159, 147, 177), + (157, 176, 174), (162, 185, 170), (168, 194, 167), (147, 204, 154), + (127, 215, 141), (124, 201, 99), (133, 183, 124), (143, 166, 150), + (144, 147, 156), (145, 128, 162), (124, 133, 159), (103, 138, 157), + (58, 117, 113), (43, 83, 95), (29, 50, 77), (19, 36, 62), + (10, 22, 48), (5, 15, 48), (0, 8, 49), (1, 21, 71), + (21, 37, 71), (88, 84, 119), (129, 125, 143), (170, 166, 167), + (181, 172, 172), (193, 179, 178), (187, 169, 175), (181, 159, 172), + (151, 136, 131), (112, 83, 100), (73, 31, 69), (55, 22, 62), + (37, 14, 56), (20, 8, 54), (3, 3, 53), (4, 0, 51), + (2, 4, 53), (1, 5, 50), (0, 5, 46), (0, 6, 42), + (14, 3, 40), (28, 0, 38), (37, 0, 49), (46, 0, 61), + (23, 14, 77), (11, 10, 66), (0, 6, 56), (6, 16, 62), + (13, 26, 68), (16, 31, 73), (19, 36, 79), (77, 58, 88), + (94, 68, 93), (186, 147, 166), (200, 171, 165), (214, 195, 165), + (222, 207, 171), (231, 219, 177), (225, 235, 162), (188, 223, 159), + (180, 224, 173), (191, 229, 181), (202, 235, 190), (206, 217, 199), + (211, 200, 208), (209, 198, 193), (207, 196, 178), (211, 212, 180), + (207, 216, 151), (196, 184, 172), (169, 141, 165), (142, 98, 159), + (142, 71, 143), (143, 44, 127), (116, 6, 55), (116, 2, 51), + (112, 2, 51), (126, 33, 79), (141, 64, 108), (163, 86, 101), + (186, 108, 95), (177, 127, 104), (167, 137, 101), (166, 124, 108), + (125, 109, 75), (59, 48, 52), (46, 47, 35), (34, 47, 19), + (45, 64, 31), (56, 82, 43), (67, 138, 44), (103, 173, 57), + (126, 236, 87), (156, 227, 99), (186, 218, 111), (195, 219, 112), + (204, 220, 113), (197, 168, 126), (185, 147, 100), (170, 99, 77), + (140, 37, 66), (113, 2, 45), (109, 5, 42), (105, 8, 39), + (112, 26, 51), (128, 49, 45), (147, 67, 56), (177, 100, 72), + (183, 111, 87), (159, 76, 73), (135, 41, 59), (124, 22, 63), + (114, 4, 67), (106, 4, 43), (106, 12, 48), (81, 23, 45), + (82, 40, 52), (136, 173, 80), (143, 172, 86), (151, 172, 93), + (150, 137, 118), (168, 142, 117), (167, 128, 147), (153, 123, 157), + (134, 103, 101), (137, 61, 81), (141, 20, 61), (139, 26, 67), + (138, 33, 73), (181, 88, 80), (195, 114, 95), (225, 154, 126), + (245, 224, 131), (220, 212, 139), (215, 192, 140), (211, 172, 141), + (198, 157, 139), (164, 148, 112), (183, 131, 110), (200, 141, 147), + (205, 184, 155), (208, 185, 159), (211, 187, 163), (218, 193, 162), + (227, 198, 164), (230, 208, 167), (222, 203, 170), (214, 206, 170), + (204, 192, 176), (158, 169, 175), (146, 155, 168), (135, 142, 161), + (81, 159, 117), (82, 165, 111), (51, 109, 68), (59, 77, 53), + (47, 31, 18), (54, 16, 22), (62, 2, 27), (78, 0, 47), + (104, 1, 54), (96, 0, 46), (90, 0, 35), (54, 0, 18), + (44, 1, 18), (25, 2, 22), (7, 2, 43), (4, 8, 45), + (15, 15, 23), (31, 21, 30), (81, 19, 40), (77, 39, 26), + (103, 97, 61), (103, 139, 67), (104, 182, 73), (127, 220, 79), + (157, 246, 102), (193, 217, 103), (234, 231, 124), (220, 219, 136), + (202, 197, 129), (173, 161, 119), (137, 108, 90), (84, 84, 86), + (94, 109, 88), (128, 131, 150), (145, 132, 158), (165, 167, 164), + (155, 178, 168), (138, 200, 101), (129, 238, 97), (119, 240, 101), + (109, 222, 90), (86, 218, 96), (89, 201, 101), (79, 176, 73), + (93, 155, 92), (80, 73, 55), (65, 14, 71), (77, 5, 69), + (62, 16, 45), (50, 29, 48), (76, 59, 33), (64, 56, 45), + (45, 41, 56), (32, 47, 54), (11, 31, 38), (14, 37, 53), + (12, 32, 65), (29, 45, 68), (64, 53, 67), (87, 50, 102), + (123, 37, 82), (123, 14, 105), (82, 2, 91), (81, 5, 69), + (110, 0, 48), (120, 4, 49), (129, 33, 60), (152, 48, 71), + (175, 101, 102), (184, 154, 128), (198, 166, 128), (176, 173, 132), + (135, 172, 105), (112, 149, 106), (92, 77, 72), (89, 45, 72), + (99, 35, 59), (121, 42, 48), (142, 41, 59), (181, 95, 82), + (194, 121, 106), (196, 140, 149), (201, 164, 171), (193, 152, 166), + (173, 125, 177), (156, 130, 157), (120, 124, 151), (89, 154, 132), + (90, 207, 137), (106, 219, 139), (174, 225, 156), (196, 213, 168) + ), + +// 244 Apophysis-040427-20FlwrFrnsBFly +((238, 199, 80), (204, 175, 73), (201, 168, 80), (199, 161, 88), + (167, 149, 79), (136, 137, 71), (120, 120, 62), (104, 104, 54), + (105, 89, 29), (124, 96, 26), (144, 103, 23), (138, 101, 21), + (133, 100, 19), (115, 98, 30), (98, 97, 41), (72, 91, 40), + (47, 86, 39), (53, 64, 50), (36, 66, 53), (20, 68, 56), + (27, 85, 49), (35, 103, 42), (17, 132, 40), (0, 161, 38), + (26, 64, 13), (43, 55, 6), (61, 46, 0), (76, 50, 0), + (91, 55, 0), (95, 48, 7), (99, 42, 15), (121, 50, 6), + (122, 74, 10), (89, 67, 30), (81, 62, 17), (73, 57, 5), + (81, 34, 2), (90, 11, 0), (79, 9, 11), (69, 7, 22), + (111, 46, 68), (144, 40, 74), (177, 35, 81), (165, 30, 80), + (154, 25, 79), (135, 32, 64), (116, 40, 50), (115, 80, 22), + (133, 92, 26), (161, 120, 41), (172, 129, 48), (183, 138, 55), + (181, 136, 62), (179, 135, 70), (179, 132, 72), (179, 130, 74), + (167, 148, 80), (164, 144, 91), (162, 140, 103), (138, 156, 144), + (114, 172, 186), (86, 211, 214), (59, 250, 243), (93, 183, 194), + (106, 152, 168), (136, 192, 117), (166, 182, 103), (197, 172, 90), + (199, 159, 87), (201, 147, 85), (177, 139, 76), (156, 133, 81), + (101, 101, 101), (91, 106, 93), (82, 112, 86), (89, 123, 90), + (97, 135, 94), (123, 133, 72), (149, 132, 50), (150, 122, 25), + (154, 118, 0), (151, 117, 17), (160, 133, 26), (169, 149, 36), + (178, 159, 43), (188, 169, 51), (199, 174, 71), (208, 174, 85), + (251, 235, 100), (251, 241, 96), (252, 247, 93), (253, 245, 88), + (255, 243, 83), (255, 236, 70), (250, 234, 61), (255, 205, 69), + (222, 158, 48), (155, 62, 73), (130, 52, 70), (106, 42, 68), + (101, 34, 69), (97, 26, 70), (72, 18, 41), (77, 20, 29), + (75, 3, 43), (48, 13, 40), (22, 24, 37), (16, 24, 40), + (10, 25, 44), (16, 38, 17), (39, 46, 38), (53, 50, 31), + (61, 57, 32), (86, 50, 52), (83, 49, 58), (81, 48, 65), + (102, 33, 87), (86, 29, 124), (51, 32, 122), (20, 47, 102), + (33, 73, 98), (49, 88, 133), (66, 104, 169), (77, 127, 169), + (89, 150, 169), (140, 196, 219), (174, 217, 234), (197, 216, 150), + (223, 200, 107), (255, 255, 216), (255, 237, 235), (255, 220, 255), + (255, 136, 250), (189, 160, 152), (182, 114, 129), (172, 70, 120), + (120, 38, 74), (118, 24, 73), (116, 10, 72), (121, 11, 67), + (126, 12, 63), (126, 27, 73), (162, 60, 84), (158, 78, 105), + (125, 67, 92), (53, 97, 74), (52, 98, 78), (52, 99, 83), + (27, 92, 72), (3, 68, 48), (21, 46, 42), (44, 49, 29), + (99, 82, 12), (122, 97, 6), (146, 113, 0), (189, 133, 12), + (195, 159, 45), (196, 197, 57), (182, 223, 33), (190, 161, 43), + (183, 144, 23), (172, 122, 25), (164, 110, 25), (157, 99, 26), + (142, 85, 16), (135, 88, 0), (122, 86, 2), (133, 101, 0), + (146, 88, 4), (143, 84, 6), (140, 80, 8), (130, 100, 36), + (126, 115, 83), (131, 133, 111), (128, 177, 130), (125, 187, 138), + (132, 255, 180), (164, 214, 143), (185, 196, 136), (196, 199, 118), + (182, 189, 83), (167, 184, 72), (167, 124, 55), (147, 107, 46), + (69, 127, 77), (65, 127, 78), (62, 128, 80), (60, 126, 64), + (40, 75, 51), (34, 43, 16), (22, 21, 1), (18, 8, 0), + (0, 18, 0), (2, 3, 7), (3, 26, 44), (0, 15, 53), + (14, 10, 45), (18, 12, 40), (22, 27, 5), (47, 44, 13), + (70, 79, 14), (83, 103, 14), (89, 104, 49), (73, 93, 68), + (65, 88, 46), (79, 74, 32), (97, 75, 0), (120, 84, 0), + (134, 111, 0), (147, 138, 33), (157, 144, 50), (155, 159, 48), + (177, 154, 58), (183, 144, 41), (173, 127, 29), (162, 127, 33), + (164, 112, 36), (164, 119, 28), (151, 118, 23), (158, 115, 2), + (163, 116, 0), (178, 151, 12), (184, 176, 67), (178, 154, 126), + (127, 152, 252), (113, 128, 247), (44, 41, 158), (14, 45, 128), + (6, 31, 95), (21, 55, 65), (39, 38, 54), (31, 27, 44), + (51, 38, 56), (107, 37, 73), (165, 73, 114), (253, 18, 207), + (192, 51, 117), (182, 84, 83), (177, 110, 104), (113, 119, 85), + (83, 107, 83), (79, 103, 79), (71, 102, 68), (49, 72, 43), + (39, 65, 26), (38, 55, 23), (2, 35, 6), (12, 24, 0), + (40, 55, 0), (43, 55, 0), (57, 41, 18), (68, 28, 26), + (74, 31, 38), (72, 61, 65), (96, 103, 69), (105, 139, 104) + ), + +// 245 Apophysis-040427-24FracrameE +((255, 255, 253), (254, 255, 253), (253, 255, 253), (253, 255, 254), + (249, 255, 253), (245, 255, 252), (246, 252, 252), (248, 249, 253), + (213, 215, 212), (174, 175, 175), (135, 136, 138), (105, 104, 103), + (76, 73, 68), (59, 51, 43), (43, 29, 18), (38, 28, 19), + (34, 27, 21), (44, 22, 9), (34, 20, 11), (24, 19, 13), + (19, 15, 16), (14, 11, 20), (12, 9, 20), (10, 8, 21), + (6, 13, 21), (6, 14, 21), (6, 15, 22), (3, 12, 14), + (0, 9, 6), (2, 5, 4), (5, 1, 2), (13, 6, 0), + (25, 15, 5), (21, 21, 21), (20, 19, 26), (20, 18, 32), + (19, 29, 46), (18, 40, 61), (22, 43, 62), (27, 46, 63), + (39, 44, 50), (45, 49, 55), (51, 54, 61), (62, 65, 78), + (74, 77, 96), (82, 86, 98), (91, 96, 100), (116, 112, 111), + (128, 120, 109), (126, 128, 141), (145, 148, 156), (165, 169, 172), + (184, 193, 198), (204, 217, 225), (210, 225, 234), (216, 233, 243), + (235, 246, 252), (243, 248, 253), (252, 250, 255), (253, 252, 255), + (254, 255, 255), (254, 255, 255), (254, 255, 255), (255, 254, 255), + (255, 254, 251), (252, 250, 238), (214, 217, 212), (176, 184, 187), + (153, 159, 162), (130, 135, 138), (95, 103, 106), (62, 72, 73), + (36, 41, 47), (33, 33, 32), (30, 26, 17), (21, 16, 8), + (13, 6, 0), (12, 3, 0), (12, 1, 0), (7, 10, 15), + (4, 22, 26), (22, 41, 74), (35, 47, 70), (48, 54, 66), + (47, 55, 64), (47, 56, 63), (50, 60, 70), (55, 59, 68), + (65, 62, 55), (74, 73, 68), (84, 84, 82), (94, 94, 91), + (105, 104, 100), (140, 143, 158), (124, 124, 126), (219, 211, 198), + (182, 180, 181), (126, 134, 136), (104, 114, 118), (83, 94, 100), + (80, 87, 93), (77, 80, 87), (86, 81, 75), (82, 87, 91), + (79, 86, 96), (85, 93, 99), (91, 101, 103), (91, 103, 109), + (91, 105, 116), (104, 111, 129), (124, 131, 141), (144, 167, 183), + (156, 182, 209), (174, 179, 182), (168, 167, 164), (163, 156, 146), + (150, 129, 110), (125, 104, 85), (103, 78, 58), (75, 53, 39), + (62, 53, 36), (54, 48, 35), (47, 44, 35), (43, 42, 40), + (40, 41, 45), (40, 37, 54), (42, 46, 55), (43, 55, 69), + (43, 74, 95), (74, 79, 85), (81, 86, 94), (89, 93, 104), + (84, 98, 109), (97, 98, 103), (110, 106, 94), (114, 105, 96), + (123, 115, 104), (118, 120, 120), (113, 125, 137), (119, 128, 143), + (125, 132, 150), (177, 184, 192), (224, 219, 213), (244, 241, 222), + (255, 240, 228), (195, 183, 169), (177, 159, 152), (159, 135, 135), + (117, 108, 101), (86, 79, 73), (63, 58, 54), (60, 47, 31), + (57, 35, 22), (53, 33, 19), (50, 31, 16), (45, 36, 27), + (50, 45, 39), (48, 44, 45), (55, 60, 66), (60, 77, 97), + (61, 88, 115), (95, 119, 147), (107, 131, 162), (120, 143, 177), + (163, 168, 187), (172, 185, 191), (168, 178, 188), (158, 162, 171), + (136, 129, 121), (141, 133, 124), (146, 137, 128), (159, 167, 169), + (175, 179, 182), (203, 180, 166), (201, 177, 165), (183, 176, 157), + (168, 150, 130), (142, 128, 117), (139, 126, 107), (109, 102, 92), + (80, 77, 70), (60, 59, 54), (36, 41, 44), (16, 25, 34), + (9, 12, 29), (14, 16, 28), (20, 20, 28), (35, 40, 46), + (41, 43, 42), (55, 54, 52), (77, 70, 64), (100, 77, 59), + (102, 80, 57), (99, 85, 74), (107, 90, 74), (99, 87, 75), + (86, 83, 68), (84, 70, 59), (83, 67, 54), (77, 70, 64), + (76, 67, 58), (76, 75, 70), (71, 72, 77), (84, 89, 95), + (89, 98, 107), (91, 100, 107), (108, 103, 97), (109, 99, 89), + (97, 84, 67), (78, 67, 49), (62, 53, 46), (53, 48, 44), + (56, 52, 53), (67, 60, 54), (74, 61, 52), (57, 66, 63), + (48, 57, 66), (41, 54, 63), (25, 45, 69), (29, 36, 52), + (25, 18, 34), (19, 11, 26), (11, 0, 6), (8, 0, 0), + (3, 0, 0), (6, 1, 5), (0, 4, 10), (5, 4, 12), + (2, 4, 16), (4, 8, 19), (1, 7, 23), (2, 7, 26), + (6, 11, 31), (10, 17, 33), (19, 38, 55), (49, 62, 70), + (83, 99, 114), (130, 139, 146), (203, 209, 207), (226, 234, 237), + (226, 233, 249), (227, 231, 232), (219, 211, 198), (214, 191, 160), + (176, 162, 151), (182, 156, 139), (217, 178, 145), (220, 198, 184), + (247, 230, 214), (255, 253, 225), (255, 251, 239), (253, 248, 242), + (251, 254, 247), (255, 254, 251), (255, 255, 253), (255, 255, 253) + ), + +// 246 Apophysis-040427-24FNouveau +((157, 97, 97), (100, 75, 115), (135, 65, 69), (170, 55, 24), + (173, 49, 12), (177, 44, 1), (181, 47, 4), (186, 50, 8), + (164, 97, 29), (130, 113, 67), (97, 129, 106), (104, 122, 133), + (112, 115, 160), (97, 93, 129), (82, 72, 99), (83, 50, 81), + (85, 28, 63), (81, 22, 50), (94, 48, 30), (108, 74, 11), + (127, 81, 13), (147, 89, 16), (159, 104, 17), (171, 119, 18), + (171, 158, 28), (184, 161, 15), (198, 165, 2), (226, 188, 16), + (255, 211, 30), (255, 210, 41), (255, 209, 52), (240, 202, 69), + (255, 183, 94), (231, 203, 226), (231, 167, 212), (232, 131, 199), + (242, 130, 149), (253, 130, 99), (248, 138, 72), (244, 146, 45), + (245, 162, 30), (222, 163, 37), (200, 164, 44), (174, 127, 33), + (149, 90, 22), (130, 84, 16), (111, 78, 11), (111, 77, 6), + (105, 69, 9), (131, 78, 60), (124, 97, 109), (118, 117, 159), + (118, 116, 162), (118, 116, 165), (118, 115, 161), (118, 115, 158), + (161, 44, 60), (193, 37, 62), (226, 31, 65), (197, 45, 59), + (168, 59, 54), (163, 74, 60), (158, 90, 67), (131, 94, 50), + (161, 97, 69), (200, 129, 87), (203, 98, 57), (207, 68, 27), + (209, 82, 34), (211, 96, 42), (218, 123, 75), (239, 123, 84), + (247, 87, 95), (212, 113, 104), (177, 140, 114), (147, 128, 139), + (118, 116, 165), (118, 116, 165), (118, 116, 165), (118, 116, 165), + (118, 116, 165), (118, 116, 165), (149, 130, 158), (181, 144, 152), + (189, 148, 135), (197, 153, 118), (215, 151, 126), (209, 162, 118), + (195, 179, 68), (177, 163, 53), (159, 147, 39), (153, 129, 33), + (147, 111, 27), (150, 94, 20), (163, 86, 0), (174, 45, 3), + (176, 45, 1), (178, 100, 26), (163, 106, 56), (149, 113, 87), + (144, 115, 115), (140, 117, 143), (119, 116, 163), (118, 116, 165), + (123, 113, 166), (149, 130, 177), (176, 148, 189), (196, 166, 207), + (216, 185, 226), (194, 186, 233), (185, 212, 233), (154, 197, 213), + (133, 134, 201), (118, 116, 165), (118, 116, 165), (118, 116, 165), + (118, 116, 165), (118, 116, 165), (118, 116, 165), (118, 116, 165), + (118, 116, 165), (131, 114, 151), (145, 113, 137), (166, 115, 116), + (188, 117, 95), (192, 128, 100), (208, 144, 116), (212, 148, 139), + (149, 122, 141), (131, 126, 166), (170, 143, 156), (210, 161, 147), + (251, 174, 118), (255, 160, 103), (237, 190, 72), (231, 205, 58), + (173, 133, 11), (141, 100, 5), (110, 68, 0), (93, 59, 5), + (76, 51, 10), (73, 53, 3), (72, 60, 10), (76, 66, 17), + (114, 55, 23), (185, 19, 21), (195, 19, 31), (206, 20, 41), + (174, 45, 14), (172, 94, 32), (179, 132, 40), (183, 145, 74), + (200, 136, 100), (174, 129, 109), (148, 123, 118), (111, 105, 153), + (84, 83, 114), (59, 94, 62), (68, 51, 41), (53, 7, 18), + (48, 32, 6), (84, 40, 11), (104, 56, 40), (124, 73, 69), + (123, 50, 70), (98, 14, 48), (64, 1, 71), (41, 0, 68), + (30, 0, 28), (28, 0, 19), (27, 0, 11), (19, 0, 36), + (17, 8, 51), (24, 0, 36), (33, 21, 21), (30, 32, 29), + (28, 34, 32), (14, 1, 73), (0, 43, 95), (83, 84, 128), + (112, 105, 159), (113, 112, 170), (118, 116, 165), (118, 116, 165), + (118, 116, 165), (122, 125, 173), (127, 135, 182), (190, 173, 130), + (210, 217, 139), (203, 194, 165), (222, 159, 170), (182, 151, 149), + (119, 116, 163), (118, 116, 165), (118, 116, 165), (118, 116, 165), + (118, 116, 165), (118, 116, 165), (118, 116, 165), (118, 116, 165), + (118, 116, 165), (131, 109, 147), (161, 112, 107), (167, 146, 63), + (193, 138, 48), (191, 114, 8), (171, 91, 2), (188, 100, 11), + (199, 111, 22), (210, 130, 33), (187, 120, 31), (184, 111, 42), + (175, 113, 40), (175, 106, 37), (156, 107, 40), (156, 96, 42), + (127, 105, 82), (116, 113, 156), (118, 116, 165), (118, 116, 165), + (118, 116, 165), (118, 116, 165), (118, 116, 165), (140, 107, 136), + (148, 101, 85), (148, 102, 40), (156, 112, 23), (184, 130, 0), + (197, 106, 0), (170, 96, 1), (134, 108, 34), (62, 108, 69), + (84, 85, 115), (89, 83, 129), (103, 93, 145), (109, 107, 156), + (92, 89, 120), (82, 67, 106), (47, 10, 64), (30, 6, 68), + (8, 0, 58), (8, 4, 41), (15, 34, 14), (10, 38, 15), + (11, 40, 9), (67, 54, 1), (74, 59, 2), (102, 84, 18), + (103, 84, 16), (114, 97, 7), (126, 101, 0), (145, 130, 15), + (159, 134, 15), (175, 111, 21), (181, 108, 57), (138, 106, 145) + ), + +// 247 Apophysis-040427-24GuardFaeriR +((224, 121, 86), (96, 113, 68), (48, 103, 70), (0, 94, 73), + (43, 131, 112), (87, 168, 151), (86, 147, 129), (85, 127, 107), + (188, 117, 11), (199, 120, 7), (210, 124, 3), (167, 83, 49), + (125, 42, 96), (112, 36, 85), (99, 30, 75), (92, 32, 53), + (85, 34, 31), (9, 29, 17), (5, 15, 9), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (3, 3, 0), + (5, 5, 0), (9, 10, 5), (14, 15, 10), (62, 54, 17), + (101, 89, 63), (122, 143, 100), (155, 150, 98), (188, 158, 96), + (211, 177, 58), (234, 197, 20), (228, 184, 10), (223, 171, 0), + (103, 43, 32), (60, 25, 21), (17, 8, 11), (10, 4, 6), + (4, 0, 1), (2, 0, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (0, 4, 8), (25, 12, 32), (51, 21, 57), + (76, 25, 67), (102, 30, 78), (100, 25, 85), (98, 21, 93), + (89, 42, 26), (111, 58, 15), (134, 75, 5), (134, 74, 8), + (134, 74, 12), (109, 55, 18), (84, 36, 24), (37, 8, 2), + (11, 0, 7), (0, 34, 68), (27, 36, 72), (55, 39, 76), + (74, 37, 55), (93, 35, 34), (103, 28, 22), (104, 24, 0), + (31, 3, 0), (16, 2, 0), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (0, 3, 4), + (6, 4, 17), (18, 0, 96), (15, 1, 57), (13, 2, 19), + (7, 2, 11), (2, 2, 4), (1, 1, 1), (1, 1, 1), + (0, 2, 2), (6, 13, 18), (12, 25, 34), (32, 25, 46), + (52, 25, 58), (85, 55, 81), (75, 71, 85), (64, 78, 53), + (87, 39, 35), (90, 41, 26), (110, 48, 69), (131, 56, 112), + (144, 59, 137), (158, 63, 163), (200, 70, 178), (205, 84, 190), + (138, 51, 130), (117, 41, 107), (96, 32, 84), (93, 29, 91), + (90, 27, 98), (57, 45, 93), (9, 40, 120), (17, 12, 141), + (44, 44, 144), (68, 47, 104), (72, 34, 99), (77, 21, 94), + (52, 14, 75), (35, 1, 75), (20, 0, 19), (5, 3, 4), + (1, 1, 1), (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, 0, 21), (9, 0, 45), (15, 0, 69), + (12, 10, 107), (102, 28, 115), (127, 42, 143), (150, 58, 169), + (183, 25, 171), (153, 24, 157), (124, 23, 143), (122, 24, 130), + (121, 26, 118), (111, 26, 111), (137, 28, 119), (152, 49, 130), + (151, 68, 146), (122, 108, 47), (109, 99, 50), (96, 91, 53), + (77, 59, 21), (27, 19, 0), (7, 6, 1), (2, 3, 0), + (4, 5, 0), (2, 16, 8), (0, 27, 17), (0, 63, 13), + (0, 80, 3), (15, 77, 14), (88, 41, 25), (173, 42, 0), + (231, 49, 1), (156, 100, 53), (154, 111, 73), (152, 122, 94), + (167, 110, 153), (182, 133, 119), (236, 116, 125), (216, 137, 96), + (154, 70, 46), (147, 57, 27), (141, 44, 9), (83, 38, 19), + (15, 6, 0), (6, 2, 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), (2, 3, 0), + (4, 86, 2), (12, 103, 14), (21, 120, 27), (50, 85, 29), + (96, 71, 17), (146, 113, 20), (170, 102, 3), (191, 94, 0), + (197, 117, 2), (194, 119, 2), (196, 108, 0), (175, 75, 0), + (166, 49, 0), (120, 36, 0), (83, 38, 19), (15, 23, 26), + (6, 21, 28), (29, 35, 67), (63, 44, 76), (108, 61, 105), + (119, 65, 117), (131, 100, 131), (137, 118, 148), (152, 115, 148), + (143, 139, 166), (125, 131, 147), (117, 102, 131), (84, 55, 103), + (6, 62, 85), (3, 78, 81), (6, 69, 60), (0, 84, 19), + (6, 78, 15), (33, 43, 18), (83, 42, 24), (92, 36, 37), + (145, 78, 85), (145, 90, 119), (168, 155, 199), (195, 184, 178), + (200, 213, 144), (175, 188, 132), (119, 117, 102), (68, 65, 84), + (13, 61, 73), (7, 42, 22), (14, 5, 6), (35, 4, 1), + (94, 21, 2), (116, 32, 0), (139, 47, 0), (131, 60, 30), + (139, 70, 63), (136, 46, 108), (171, 41, 137), (191, 40, 145), + (228, 73, 201), (223, 159, 183), (209, 199, 200), (198, 193, 213), + (165, 200, 222), (186, 210, 176), (200, 202, 178), (212, 202, 200), + (241, 119, 238), (243, 100, 214), (202, 97, 225), (180, 162, 204), + (136, 136, 134), (127, 149, 113), (143, 170, 129), (185, 154, 100) + ), + +// 248 Apophysis-040427-24GoldenRays +((0, 0, 0), (0, 0, 0), (1, 0, 0), (3, 0, 0), + (36, 30, 25), (70, 60, 50), (86, 72, 61), (102, 84, 72), + (139, 121, 85), (151, 133, 105), (164, 146, 126), (173, 154, 132), + (183, 163, 138), (177, 158, 142), (171, 154, 146), (172, 151, 138), + (174, 148, 131), (167, 146, 119), (146, 129, 119), (126, 113, 120), + (120, 114, 120), (115, 116, 120), (112, 111, 122), (110, 107, 124), + (99, 102, 121), (88, 96, 119), (77, 91, 118), (67, 72, 87), + (58, 53, 57), (36, 33, 35), (14, 14, 14), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (22, 17, 13), (45, 35, 26), (57, 46, 34), + (69, 57, 43), (68, 54, 39), (67, 51, 35), (47, 28, 21), + (1, 0, 0), (0, 0, 0), (28, 23, 24), (57, 47, 48), + (67, 66, 78), (78, 86, 109), (80, 94, 119), (82, 102, 129), + (92, 112, 147), (91, 113, 145), (91, 115, 143), (78, 86, 104), + (65, 58, 66), (65, 49, 51), (65, 41, 37), (1, 1, 1), + (0, 0, 0), (0, 1, 0), (40, 34, 28), (81, 67, 56), + (99, 84, 72), (117, 101, 88), (165, 147, 133), (207, 190, 170), + (249, 248, 246), (251, 251, 250), (254, 254, 254), (252, 248, 243), + (251, 242, 233), (237, 226, 218), (224, 211, 203), (223, 200, 168), + (204, 177, 166), (181, 164, 144), (187, 175, 158), (194, 186, 173), + (202, 186, 169), (211, 186, 166), (244, 231, 212), (253, 253, 251), + (254, 254, 254), (254, 254, 254), (254, 254, 254), (251, 251, 251), + (249, 249, 249), (219, 203, 187), (172, 161, 143), (141, 122, 108), + (91, 82, 73), (1, 1, 1), (0, 0, 0), (0, 0, 0), + (3, 3, 3), (7, 7, 7), (58, 46, 46), (61, 65, 77), + (82, 83, 103), (70, 63, 73), (58, 44, 44), (31, 24, 24), + (5, 5, 5), (0, 0, 0), (0, 0, 0), (1, 1, 1), + (51, 39, 27), (98, 81, 65), (107, 87, 67), (116, 94, 70), + (137, 106, 77), (139, 112, 83), (132, 116, 82), (130, 102, 78), + (87, 65, 51), (44, 32, 25), (1, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (35, 16, 22), (65, 47, 43), + (89, 77, 65), (143, 112, 91), (147, 118, 94), (151, 124, 97), + (164, 133, 102), (171, 144, 114), (171, 145, 120), (145, 133, 121), + (116, 112, 137), (116, 116, 142), (116, 120, 147), (143, 140, 157), + (171, 160, 168), (235, 221, 212), (251, 250, 246), (255, 254, 252), + (246, 240, 224), (166, 156, 164), (158, 147, 155), (150, 139, 147), + (152, 138, 138), (150, 135, 138), (143, 127, 128), (144, 130, 121), + (149, 126, 94), (146, 123, 91), (144, 121, 89), (132, 105, 78), + (112, 90, 77), (105, 89, 74), (92, 82, 81), (80, 78, 91), + (77, 88, 110), (104, 92, 94), (108, 97, 91), (112, 103, 88), + (109, 107, 108), (142, 124, 104), (141, 121, 96), (120, 101, 87), + (92, 81, 75), (83, 69, 66), (74, 58, 58), (66, 47, 41), + (36, 20, 5), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (1, 0, 0), + (48, 32, 19), (70, 58, 44), (93, 85, 64), (112, 99, 83), + (143, 121, 98), (155, 123, 110), (144, 124, 100), (147, 120, 90), + (146, 119, 98), (137, 120, 100), (123, 123, 125), (131, 131, 131), + (158, 138, 137), (167, 153, 140), (181, 166, 147), (198, 169, 135), + (255, 255, 6), (209, 185, 151), (215, 178, 151), (188, 161, 132), + (183, 162, 131), (180, 160, 135), (160, 138, 115), (111, 94, 87), + (74, 65, 56), (55, 38, 28), (3, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (5, 4, 9), (50, 48, 61), (86, 100, 126) + ), + +// 249 Apophysis-040427-24HunterSunset +((255, 217, 0), (220, 148, 38), (141, 118, 40), (62, 88, 43), + (35, 71, 25), (8, 54, 7), (10, 50, 4), (13, 46, 1), + (54, 65, 0), (85, 85, 26), (117, 106, 52), (180, 120, 40), + (243, 134, 29), (190, 147, 23), (137, 160, 17), (110, 146, 27), + (83, 133, 38), (44, 91, 0), (37, 89, 3), (31, 88, 7), + (24, 83, 3), (18, 78, 0), (20, 82, 6), (23, 87, 13), + (27, 133, 32), (23, 132, 40), (19, 131, 49), (19, 130, 53), + (20, 130, 57), (22, 125, 66), (25, 120, 76), (43, 116, 96), + (29, 104, 107), (37, 87, 112), (56, 93, 82), (76, 99, 53), + (114, 141, 46), (152, 184, 39), (180, 207, 36), (208, 230, 33), + (253, 240, 3), (254, 237, 3), (255, 234, 3), (255, 231, 2), + (255, 229, 2), (255, 230, 1), (255, 232, 0), (254, 234, 0), + (255, 240, 0), (255, 240, 1), (253, 240, 1), (252, 241, 1), + (252, 240, 0), (252, 239, 0), (252, 237, 0), (253, 236, 0), + (253, 223, 3), (254, 213, 29), (255, 203, 55), (201, 170, 81), + (148, 137, 107), (139, 126, 94), (130, 115, 82), (78, 110, 47), + (45, 94, 3), (27, 63, 0), (20, 51, 0), (13, 39, 0), + (26, 39, 2), (39, 39, 5), (81, 32, 0), (100, 30, 0), + (108, 35, 3), (113, 41, 18), (119, 47, 33), (183, 88, 20), + (248, 130, 7), (251, 141, 7), (254, 152, 7), (253, 159, 1), + (236, 164, 2), (231, 150, 0), (242, 135, 1), (253, 120, 2), + (254, 117, 7), (255, 115, 12), (220, 112, 24), (98, 97, 30), + (90, 140, 67), (112, 155, 93), (134, 171, 120), (129, 164, 108), + (124, 158, 97), (82, 136, 50), (50, 122, 22), (34, 116, 6), + (11, 91, 0), (0, 52, 4), (0, 68, 5), (0, 84, 6), + (0, 86, 3), (0, 88, 1), (1, 98, 1), (31, 105, 8), + (135, 115, 0), (187, 152, 0), (239, 190, 0), (246, 204, 1), + (254, 219, 3), (252, 229, 3), (247, 242, 26), (239, 233, 49), + (168, 165, 88), (24, 128, 65), (21, 127, 53), (19, 127, 42), + (31, 123, 36), (18, 106, 28), (2, 88, 13), (2, 81, 2), + (1, 69, 0), (2, 72, 1), (3, 76, 3), (4, 80, 3), + (5, 84, 3), (20, 93, 14), (45, 128, 36), (124, 179, 85), + (192, 215, 111), (249, 249, 63), (252, 248, 40), (255, 248, 17), + (253, 244, 3), (249, 243, 0), (255, 246, 0), (254, 249, 0), + (255, 248, 0), (255, 246, 0), (255, 244, 0), (254, 246, 0), + (254, 249, 0), (254, 249, 0), (254, 249, 0), (254, 249, 0), + (254, 249, 0), (254, 249, 0), (254, 244, 0), (255, 240, 0), + (254, 227, 0), (245, 204, 0), (236, 178, 19), (175, 163, 43), + (70, 95, 12), (60, 87, 6), (51, 80, 0), (53, 69, 0), + (58, 77, 0), (70, 84, 7), (83, 102, 36), (126, 132, 98), + (158, 188, 98), (233, 204, 148), (192, 182, 172), (152, 160, 196), + (110, 135, 155), (61, 107, 141), (42, 104, 81), (28, 104, 32), + (6, 70, 10), (8, 66, 9), (10, 63, 9), (13, 85, 21), + (40, 92, 53), (39, 91, 78), (77, 109, 98), (71, 96, 75), + (50, 81, 49), (42, 84, 8), (44, 74, 0), (51, 48, 0), + (75, 47, 0), (88, 79, 12), (81, 101, 4), (132, 149, 0), + (243, 198, 7), (247, 210, 4), (252, 222, 2), (255, 228, 0), + (255, 235, 1), (254, 239, 0), (253, 242, 0), (255, 240, 1), + (255, 234, 1), (255, 228, 0), (255, 223, 1), (255, 214, 0), + (250, 189, 0), (253, 171, 1), (255, 169, 8), (245, 190, 2), + (255, 221, 2), (254, 225, 1), (254, 227, 0), (254, 225, 1), + (255, 221, 0), (237, 181, 0), (149, 165, 32), (84, 146, 47), + (78, 129, 52), (74, 118, 43), (74, 119, 36), (81, 112, 19), + (82, 86, 2), (89, 78, 0), (114, 76, 1), (221, 123, 26), + (245, 132, 12), (129, 72, 3), (91, 72, 6), (69, 78, 0), + (32, 75, 4), (28, 85, 6), (19, 77, 3), (8, 44, 0), + (13, 22, 0), (20, 33, 5), (32, 34, 0), (41, 52, 10), + (47, 80, 35), (83, 131, 71), (95, 122, 89), (88, 131, 138), + (96, 106, 141), (51, 100, 114), (33, 96, 101), (34, 87, 61), + (30, 96, 25), (22, 84, 11), (48, 72, 0), (63, 75, 9), + (88, 82, 50), (99, 100, 58), (118, 98, 87), (105, 91, 78), + (73, 96, 78), (37, 119, 35), (8, 107, 16), (6, 102, 12), + (0, 103, 1), (19, 104, 0), (46, 114, 15), (85, 127, 19), + (163, 168, 4), (240, 201, 2), (253, 249, 0), (253, 224, 0) + ), + +// 250 Apophysis-040427-25IntoWeave +((0, 32, 174), (0, 0, 30), (5, 1, 20), (10, 3, 10), + (52, 42, 20), (94, 82, 30), (100, 93, 64), (107, 104, 99), + (172, 158, 85), (183, 157, 48), (194, 156, 11), (191, 190, 74), + (188, 224, 137), (187, 226, 160), (186, 229, 183), (181, 227, 174), + (177, 225, 165), (238, 228, 97), (246, 216, 50), (255, 205, 4), + (253, 169, 3), (251, 134, 2), (216, 109, 1), (182, 85, 0), + (185, 128, 0), (206, 146, 0), (227, 164, 1), (240, 192, 0), + (253, 220, 0), (249, 224, 0), (246, 228, 0), (253, 226, 0), + (255, 215, 1), (246, 171, 28), (239, 165, 95), (232, 160, 163), + (211, 191, 155), (191, 223, 148), (201, 227, 142), (212, 232, 137), + (254, 219, 0), (219, 221, 49), (184, 224, 99), (174, 224, 130), + (165, 225, 161), (171, 224, 174), (178, 224, 187), (181, 223, 211), + (197, 228, 210), (198, 235, 191), (181, 228, 186), (165, 222, 181), + (145, 204, 193), (126, 187, 205), (116, 157, 188), (107, 128, 171), + (17, 31, 94), (10, 15, 53), (4, 0, 12), (3, 0, 8), + (3, 0, 4), (3, 0, 3), (3, 0, 2), (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, 0, 9), + (55, 55, 107), (96, 101, 132), (138, 148, 158), (130, 128, 143), + (122, 109, 129), (99, 98, 104), (76, 87, 79), (82, 42, 50), + (18, 4, 0), (6, 0, 7), (3, 0, 4), (1, 1, 1), + (0, 0, 1), (0, 0, 2), (1, 1, 9), (0, 0, 22), + (5, 48, 142), (23, 73, 178), (41, 98, 214), (39, 101, 226), + (37, 105, 238), (48, 119, 223), (23, 158, 216), (57, 154, 251), + (98, 176, 225), (119, 180, 209), (68, 105, 155), (18, 30, 102), + (10, 18, 78), (3, 7, 55), (1, 0, 10), (1, 0, 5), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (0, 1, 0), (0, 2, 0), (0, 2, 0), + (0, 1, 0), (0, 0, 0), (0, 0, 0), (1, 1, 0), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (0, 2, 8), + (0, 8, 9), (72, 84, 98), (91, 99, 128), (110, 114, 159), + (141, 159, 205), (133, 191, 202), (129, 192, 201), (139, 207, 226), + (129, 195, 230), (133, 198, 220), (138, 202, 211), (136, 199, 203), + (134, 196, 195), (160, 203, 186), (156, 118, 159), (116, 99, 143), + (73, 75, 116), (3, 1, 14), (1, 2, 10), (0, 3, 6), + (0, 3, 4), (0, 2, 7), (0, 0, 7), (0, 1, 15), + (3, 49, 127), (13, 53, 154), (24, 58, 182), (41, 105, 205), + (113, 111, 160), (196, 154, 130), (242, 207, 89), (251, 191, 5), + (251, 178, 14), (171, 129, 0), (94, 178, 5), (18, 227, 11), + (23, 47, 73), (46, 60, 133), (82, 105, 149), (99, 140, 184), + (63, 104, 230), (54, 106, 224), (46, 108, 219), (12, 28, 165), + (0, 13, 70), (0, 4, 23), (1, 0, 9), (0, 0, 2), + (0, 0, 2), (1, 1, 1), (1, 1, 1), (1, 0, 0), + (1, 0, 0), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (0, 2, 0), (0, 2, 0), (0, 2, 0), (0, 5, 0), + (0, 5, 0), (0, 6, 0), (0, 6, 0), (0, 6, 0), + (0, 4, 1), (1, 1, 1), (3, 0, 0), (11, 0, 0), + (17, 8, 13), (73, 25, 67), (110, 99, 131), (153, 160, 168), + (140, 205, 199), (136, 206, 206), (136, 196, 230), (143, 166, 244), + (111, 159, 221), (60, 97, 141), (47, 35, 71), (50, 21, 26), + (50, 8, 0), (90, 45, 3), (85, 64, 0), (69, 38, 0), + (39, 11, 0), (15, 3, 3), (10, 0, 0), (3, 0, 0), + (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (6, 0, 2), (8, 0, 0), (12, 0, 0), + (20, 0, 0), (38, 2, 0), (91, 42, 1), (123, 55, 0), + (150, 81, 3), (206, 148, 5), (251, 191, 5), (255, 217, 0), + (255, 226, 0), (253, 231, 0), (255, 225, 0), (255, 214, 1), + (250, 211, 0), (253, 160, 0), (245, 152, 0), (229, 153, 15), + (230, 188, 52), (251, 202, 136), (245, 215, 204), (223, 213, 203), + (169, 216, 182), (137, 204, 171), (62, 109, 135), (36, 63, 84), + (0, 7, 23), (13, 0, 9), (40, 21, 14), (94, 35, 0), + (173, 61, 0), (181, 107, 0), (255, 219, 0), (223, 149, 0) + ), + +// 251 Apophysis-040427-26AlienMind +((82, 105, 198), (62, 83, 166), (52, 71, 149), (42, 60, 132), + (33, 49, 116), (25, 39, 100), (23, 36, 97), (22, 34, 94), + (15, 27, 79), (15, 27, 79), (15, 27, 79), (15, 26, 79), + (15, 26, 80), (17, 28, 84), (19, 31, 89), (21, 33, 93), + (24, 35, 97), (36, 53, 123), (39, 57, 128), (43, 61, 133), + (43, 61, 134), (43, 61, 135), (40, 58, 130), (37, 56, 125), + (28, 42, 105), (22, 35, 93), (17, 28, 82), (14, 24, 77), + (11, 21, 72), (9, 18, 67), (8, 16, 62), (21, 20, 26), + (65, 46, 6), (43, 27, 2), (23, 18, 25), (4, 9, 49), + (8, 16, 61), (12, 24, 74), (13, 25, 75), (14, 26, 76), + (77, 62, 31), (94, 74, 30), (111, 86, 29), (97, 83, 45), + (84, 81, 62), (93, 89, 72), (103, 97, 83), (103, 99, 87), + (107, 111, 136), (97, 121, 219), (119, 140, 223), (142, 159, 228), + (130, 147, 210), (119, 136, 192), (101, 121, 195), (83, 106, 199), + (99, 103, 114), (149, 133, 98), (199, 164, 83), (192, 160, 90), + (186, 157, 97), (156, 135, 93), (126, 114, 90), (85, 86, 104), + (61, 70, 113), (28, 44, 106), (22, 35, 93), (16, 27, 81), + (14, 26, 78), (13, 25, 75), (10, 18, 65), (26, 31, 37), + (65, 53, 31), (105, 80, 29), (146, 108, 27), (168, 131, 51), + (190, 154, 76), (181, 143, 61), (173, 133, 46), (125, 99, 38), + (97, 86, 58), (19, 32, 87), (17, 29, 84), (16, 27, 81), + (18, 30, 87), (21, 33, 93), (23, 38, 97), (27, 46, 105), + (34, 51, 120), (34, 51, 120), (34, 51, 120), (33, 50, 118), + (32, 50, 116), (26, 41, 106), (21, 36, 95), (16, 27, 81), + (15, 26, 80), (14, 26, 78), (13, 25, 76), (13, 25, 75), + (13, 25, 76), (14, 26, 78), (14, 26, 78), (15, 26, 80), + (26, 40, 101), (35, 51, 118), (44, 62, 136), (51, 71, 148), + (59, 80, 161), (72, 96, 184), (90, 113, 209), (100, 125, 218), + (138, 157, 234), (131, 156, 240), (142, 161, 226), (154, 167, 212), + (167, 172, 194), (172, 173, 193), (185, 180, 184), (191, 184, 178), + (244, 204, 134), (240, 202, 120), (236, 200, 106), (227, 197, 129), + (218, 195, 153), (202, 186, 170), (196, 183, 174), (183, 178, 185), + (135, 140, 169), (59, 80, 159), (54, 74, 151), (49, 68, 144), + (70, 73, 92), (80, 80, 82), (86, 94, 115), (62, 83, 166), + (86, 112, 205), (79, 104, 195), (72, 96, 186), (68, 91, 178), + (64, 86, 171), (56, 75, 154), (55, 74, 153), (51, 70, 147), + (52, 71, 148), (62, 83, 166), (67, 88, 173), (72, 94, 180), + (82, 105, 198), (91, 115, 211), (97, 123, 220), (123, 150, 253), + (116, 144, 243), (104, 131, 228), (92, 118, 213), (75, 99, 189), + (61, 82, 165), (46, 64, 140), (35, 52, 121), (25, 36, 100), + (17, 28, 82), (7, 15, 62), (6, 15, 60), (6, 15, 58), + (4, 9, 28), (1, 8, 52), (9, 15, 65), (10, 18, 65), + (10, 20, 69), (10, 20, 69), (10, 20, 69), (10, 20, 69), + (10, 20, 69), (10, 20, 69), (12, 24, 74), (13, 25, 75), + (14, 26, 76), (14, 26, 78), (15, 26, 80), (15, 26, 80), + (20, 32, 90), (23, 37, 98), (30, 48, 112), (34, 52, 118), + (40, 58, 130), (42, 60, 133), (44, 62, 136), (57, 75, 157), + (68, 92, 180), (76, 100, 190), (90, 114, 210), (98, 122, 220), + (143, 161, 223), (170, 172, 197), (188, 183, 179), (192, 187, 167), + (206, 181, 127), (186, 165, 134), (110, 99, 81), (69, 69, 69), + (21, 36, 95), (19, 31, 89), (21, 36, 95), (29, 44, 109), + (39, 58, 127), (56, 75, 154), (101, 110, 143), (123, 124, 128), + (147, 160, 202), (138, 156, 228), (93, 119, 216), (81, 104, 197), + (66, 90, 176), (61, 82, 165), (54, 75, 154), (50, 69, 146), + (49, 67, 143), (49, 68, 144), (52, 71, 148), (54, 75, 154), + (51, 70, 147), (47, 66, 142), (42, 60, 132), (33, 51, 117), + (29, 44, 109), (23, 37, 98), (19, 31, 89), (18, 28, 87), + (19, 31, 89), (20, 32, 90), (21, 36, 95), (25, 36, 98), + (31, 45, 110), (35, 52, 121), (43, 61, 133), (48, 66, 142), + (60, 81, 162), (69, 93, 179), (71, 95, 183), (65, 87, 172), + (59, 80, 161), (49, 68, 145), (37, 56, 125), (29, 47, 111), + (21, 36, 95), (16, 29, 84), (15, 26, 80), (14, 26, 78), + (13, 25, 75), (13, 25, 75), (12, 24, 74), (14, 24, 75), + (29, 32, 47), (62, 56, 40), (178, 146, 69), (106, 90, 54) + ), + +// 252 Apophysis-040427-26ISpher4 +((33, 87, 0), (60, 100, 29), (78, 109, 54), (96, 118, 80), + (100, 118, 85), (104, 119, 90), (105, 122, 90), (106, 126, 91), + (100, 143, 90), (85, 125, 64), (71, 108, 39), (54, 99, 23), + (38, 90, 7), (32, 80, 3), (27, 70, 0), (26, 69, 0), + (26, 69, 0), (27, 68, 0), (27, 71, 0), (28, 74, 1), + (31, 81, 1), (35, 89, 1), (39, 93, 5), (43, 97, 9), + (72, 126, 38), (96, 145, 63), (120, 164, 89), (125, 168, 96), + (131, 172, 104), (132, 173, 105), (133, 174, 106), (132, 171, 104), + (128, 169, 101), (86, 127, 59), (63, 116, 42), (40, 105, 25), + (40, 100, 17), (41, 95, 9), (40, 94, 7), (40, 94, 6), + (34, 88, 0), (36, 90, 2), (38, 92, 4), (48, 95, 15), + (58, 98, 27), (62, 100, 36), (67, 102, 46), (91, 91, 91), + (99, 101, 100), (110, 109, 107), (115, 128, 108), (120, 148, 110), + (129, 163, 112), (139, 178, 115), (141, 179, 117), (143, 181, 120), + (153, 166, 138), (156, 169, 141), (159, 172, 144), (155, 179, 137), + (152, 187, 131), (148, 185, 127), (145, 183, 124), (142, 170, 121), + (137, 175, 116), (133, 174, 108), (118, 158, 102), (104, 143, 96), + (100, 138, 89), (97, 134, 82), (77, 127, 64), (70, 113, 42), + (62, 116, 28), (80, 133, 48), (99, 151, 68), (114, 161, 85), + (130, 171, 103), (131, 172, 105), (133, 174, 108), (133, 174, 108), + (133, 174, 108), (131, 172, 104), (130, 171, 103), (130, 171, 103), + (129, 170, 102), (128, 169, 101), (121, 149, 108), (123, 123, 115), + (109, 108, 106), (118, 138, 103), (128, 169, 101), (129, 170, 102), + (130, 171, 103), (130, 171, 103), (124, 167, 96), (108, 157, 78), + (86, 135, 53), (71, 110, 47), (84, 114, 66), (97, 118, 85), + (99, 120, 87), (102, 123, 90), (84, 124, 62), (71, 110, 45), + (45, 99, 11), (38, 91, 6), (32, 84, 1), (30, 79, 0), + (29, 75, 0), (26, 65, 2), (25, 60, 2), (23, 56, 1), + (24, 59, 1), (23, 61, 0), (24, 63, 1), (26, 65, 2), + (27, 70, 0), (27, 73, 0), (31, 72, 4), (30, 79, 0), + (31, 80, 1), (32, 84, 0), (34, 88, 0), (35, 89, 1), + (36, 90, 2), (38, 90, 7), (45, 78, 25), (58, 58, 50), + (67, 69, 55), (76, 102, 54), (73, 104, 50), (71, 107, 46), + (66, 107, 41), (66, 107, 41), (66, 107, 39), (62, 108, 35), + (46, 98, 13), (43, 96, 10), (41, 95, 7), (43, 97, 9), + (45, 99, 11), (51, 103, 20), (60, 114, 26), (72, 126, 38), + (86, 129, 58), (103, 141, 90), (103, 132, 90), (103, 124, 91), + (105, 125, 90), (111, 133, 95), (116, 149, 92), (127, 168, 100), + (114, 160, 85), (106, 155, 76), (99, 151, 68), (78, 132, 44), + (72, 115, 44), (68, 117, 51), (94, 146, 61), (109, 158, 79), + (124, 167, 96), (130, 171, 103), (129, 170, 102), (128, 169, 101), + (124, 167, 96), (106, 144, 95), (107, 141, 91), (108, 137, 89), + (95, 132, 65), (91, 122, 64), (88, 112, 64), (74, 110, 48), + (72, 105, 48), (68, 109, 43), (66, 107, 39), (70, 109, 44), + (79, 112, 55), (92, 112, 77), (110, 108, 96), (107, 106, 104), + (102, 102, 102), (97, 97, 97), (87, 87, 87), (69, 69, 57), + (46, 75, 21), (40, 71, 14), (34, 68, 8), (29, 70, 4), + (26, 69, 0), (26, 69, 0), (29, 75, 2), (32, 84, 1), + (39, 93, 5), (51, 105, 17), (61, 115, 27), (72, 126, 38), + (104, 153, 72), (123, 166, 95), (129, 170, 102), (126, 169, 100), + (109, 149, 99), (103, 135, 86), (83, 104, 65), (58, 58, 50), + (46, 45, 41), (43, 42, 38), (28, 64, 3), (30, 76, 1), + (33, 87, 1), (39, 93, 7), (52, 95, 23), (60, 91, 32), + (76, 94, 56), (89, 89, 89), (94, 92, 95), (91, 91, 91), + (72, 99, 58), (67, 93, 48), (54, 83, 27), (53, 82, 26), + (51, 85, 24), (40, 89, 8), (36, 85, 6), (33, 74, 4), + (47, 80, 25), (63, 82, 36), (77, 93, 56), (93, 93, 93), + (100, 100, 100), (87, 87, 87), (67, 89, 50), (58, 93, 27), + (44, 93, 12), (40, 94, 6), (37, 91, 3), (36, 90, 2), + (35, 89, 1), (35, 89, 1), (37, 91, 3), (39, 93, 5), + (42, 96, 8), (50, 102, 19), (65, 109, 34), (99, 148, 67), + (114, 160, 88), (133, 174, 108), (155, 185, 133), (195, 209, 184), + (204, 216, 196), (220, 231, 217), (222, 230, 217), (206, 218, 198), + (201, 213, 193), (164, 179, 150), (139, 164, 135), (126, 144, 104) + ), + +// 253 Apophysis-040427-26ISph2 +((153, 146, 180), (163, 169, 195), (165, 170, 198), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (166, 164, 199), (164, 158, 196), + (144, 139, 169), (135, 134, 158), (127, 130, 147), (133, 136, 147), + (139, 142, 147), (156, 159, 168), (174, 176, 189), (174, 178, 195), + (175, 180, 202), (180, 187, 205), (181, 182, 206), (182, 177, 207), + (177, 177, 207), (173, 178, 207), (173, 177, 207), (173, 176, 207), + (169, 172, 205), (168, 171, 203), (167, 170, 201), (160, 157, 190), + (154, 144, 179), (150, 144, 173), (146, 144, 168), (136, 140, 149), + (125, 128, 143), (120, 126, 138), (115, 116, 138), (110, 106, 139), + (116, 110, 145), (123, 115, 152), (128, 119, 161), (133, 124, 171), + (154, 147, 189), (159, 157, 194), (165, 168, 199), (166, 169, 200), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (170, 173, 204), + (173, 177, 206), (175, 179, 204), (173, 178, 203), (172, 178, 202), + (173, 177, 200), (174, 176, 199), (172, 176, 198), (170, 176, 198), + (168, 173, 202), (167, 172, 201), (167, 171, 200), (163, 168, 192), + (160, 165, 185), (158, 159, 174), (157, 154, 163), (146, 150, 153), + (130, 133, 148), (129, 116, 38), (165, 149, 36), (202, 182, 35), + (207, 210, 32), (212, 238, 29), (161, 201, 42), (113, 166, 60), + (110, 106, 133), (109, 103, 148), (109, 100, 163), (119, 112, 160), + (130, 124, 158), (132, 125, 159), (134, 127, 160), (145, 140, 170), + (157, 161, 188), (173, 168, 191), (170, 171, 193), (168, 174, 196), + (167, 173, 196), (167, 173, 197), (165, 170, 200), (167, 172, 202), + (160, 164, 193), (158, 162, 189), (156, 160, 185), (148, 149, 179), + (140, 139, 173), (128, 134, 150), (129, 132, 149), (135, 136, 154), + (144, 139, 179), (155, 155, 189), (158, 161, 188), (161, 168, 187), + (162, 169, 188), (164, 171, 190), (162, 169, 187), (160, 167, 185), + (162, 169, 187), (168, 173, 195), (174, 178, 203), (179, 179, 209), + (185, 181, 216), (194, 199, 219), (203, 206, 223), (203, 206, 225), + (203, 206, 225), (205, 208, 227), (210, 210, 226), (216, 212, 226), + (226, 229, 236), (232, 231, 236), (233, 230, 239), (233, 232, 238), + (230, 236, 236), (223, 229, 229), (216, 222, 222), (208, 213, 220), + (201, 204, 219), (196, 199, 216), (175, 179, 208), (171, 175, 204), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 204), + (168, 171, 204), (168, 171, 204), (168, 171, 204), (168, 171, 203), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (167, 172, 202), + (167, 172, 202), (171, 177, 203), (171, 177, 201), (171, 177, 199), + (170, 177, 196), (168, 175, 193), (168, 174, 186), (159, 166, 185), + (132, 134, 155), (129, 133, 149), (126, 132, 144), (125, 129, 141), + (125, 126, 144), (130, 125, 157), (129, 124, 156), (115, 107, 167), + (113, 103, 166), (124, 123, 181), (131, 127, 182), (139, 132, 183), + (148, 145, 190), (158, 161, 196), (167, 170, 201), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 202), + (168, 171, 202), (168, 171, 202), (168, 171, 202), (168, 171, 202), + (168, 171, 202), (168, 172, 201), (171, 171, 199), (170, 176, 198), + (169, 175, 197), (166, 172, 198), (160, 164, 191), (150, 143, 187), + (127, 120, 164), (100, 90, 159), (82, 68, 127), (48, 33, 92), + (30, 37, 83), (26, 28, 79), (35, 29, 91), (89, 75, 128), + (116, 109, 153), (141, 136, 176), (159, 165, 187), (175, 181, 205), + (189, 188, 219), (198, 203, 223), (198, 205, 221), (197, 200, 215), + (184, 186, 201), (171, 165, 201), (142, 136, 196), (134, 125, 178), + (113, 103, 164), (100, 88, 138), (100, 88, 138), (99, 87, 135), + (97, 88, 135), (92, 80, 130), (77, 85, 134), (86, 80, 126), + (61, 57, 107), (48, 33, 92), (68, 61, 141), (71, 62, 141), + (89, 85, 159), (102, 108, 170), (136, 134, 173), (157, 162, 191), + (165, 168, 199), (172, 172, 200), (180, 178, 200), (178, 180, 201), + (180, 181, 201), (190, 185, 208), (200, 196, 213), (202, 199, 220), + (208, 204, 221), (210, 207, 228), (222, 217, 224), (209, 213, 214), + (205, 208, 223), (202, 205, 222), (196, 192, 215), (183, 177, 203), + (178, 171, 202), (165, 172, 191), (160, 166, 188), (163, 172, 189) + ), + +// 254 Apophysis-040427-26ISph11 +((146, 62, 86), (85, 25, 95), (86, 20, 83), (87, 16, 72), + (84, 16, 64), (82, 17, 57), (76, 20, 66), (70, 23, 75), + (72, 28, 113), (83, 40, 107), (95, 53, 101), (111, 70, 98), + (127, 87, 95), (154, 94, 107), (182, 101, 120), (197, 109, 119), + (212, 118, 118), (206, 155, 170), (191, 151, 165), (176, 148, 160), + (153, 121, 155), (130, 95, 151), (119, 88, 151), (109, 82, 151), + (128, 78, 147), (135, 100, 151), (143, 122, 155), (145, 145, 177), + (148, 169, 200), (151, 179, 218), (155, 189, 237), (156, 204, 242), + (140, 174, 202), (74, 189, 172), (100, 175, 156), (126, 161, 141), + (138, 148, 148), (150, 135, 156), (150, 133, 153), (150, 131, 151), + (114, 139, 133), (98, 149, 145), (83, 159, 157), (126, 166, 180), + (170, 173, 204), (172, 170, 202), (174, 167, 201), (179, 179, 205), + (191, 180, 220), (200, 212, 228), (180, 201, 219), (160, 191, 211), + (154, 166, 202), (148, 141, 193), (151, 132, 176), (154, 124, 160), + (152, 112, 138), (150, 121, 132), (149, 130, 126), (167, 130, 134), + (186, 130, 143), (201, 122, 133), (216, 115, 123), (222, 142, 145), + (219, 173, 175), (216, 178, 193), (202, 179, 204), (188, 181, 215), + (174, 174, 213), (160, 167, 211), (141, 142, 196), (131, 133, 184), + (108, 86, 132), (98, 77, 104), (89, 68, 77), (61, 96, 79), + (34, 125, 82), (54, 152, 110), (75, 180, 139), (62, 181, 175), + (67, 179, 191), (106, 77, 144), (102, 60, 134), (98, 43, 124), + (93, 46, 120), (88, 49, 116), (91, 54, 108), (102, 66, 112), + (134, 93, 123), (150, 94, 113), (167, 96, 104), (165, 101, 99), + (163, 107, 94), (134, 94, 95), (130, 89, 95), (120, 86, 100), + (115, 83, 94), (125, 59, 73), (108, 41, 77), (92, 24, 81), + (88, 20, 77), (85, 16, 73), (84, 31, 99), (69, 42, 113), + (88, 113, 135), (99, 119, 139), (110, 125, 144), (118, 128, 137), + (126, 132, 130), (131, 121, 129), (105, 95, 145), (103, 77, 124), + (90, 65, 97), (91, 65, 66), (107, 74, 73), (124, 83, 81), + (125, 82, 89), (128, 87, 93), (124, 87, 94), (123, 85, 106), + (108, 69, 100), (88, 54, 100), (68, 40, 101), (67, 40, 105), + (66, 41, 109), (27, 69, 127), (29, 71, 131), (57, 19, 130), + (66, 43, 147), (105, 60, 155), (137, 65, 171), (170, 71, 187), + (224, 95, 149), (217, 154, 165), (226, 180, 180), (237, 195, 197), + (246, 230, 230), (246, 231, 231), (246, 232, 232), (245, 230, 230), + (245, 229, 229), (222, 216, 226), (175, 180, 209), (135, 150, 189), + (130, 138, 157), (123, 101, 139), (115, 100, 144), (107, 99, 150), + (96, 90, 160), (47, 80, 173), (87, 97, 184), (107, 109, 186), + (167, 142, 161), (184, 149, 166), (201, 157, 172), (212, 167, 164), + (195, 186, 181), (183, 178, 175), (174, 164, 162), (175, 132, 160), + (197, 139, 153), (229, 187, 189), (230, 201, 204), (231, 216, 219), + (244, 228, 229), (241, 211, 211), (230, 196, 197), (217, 156, 171), + (187, 138, 71), (182, 130, 80), (178, 122, 89), (143, 104, 109), + (131, 92, 113), (120, 105, 108), (85, 142, 99), (58, 153, 72), + (56, 158, 56), (44, 123, 44), (76, 115, 62), (76, 53, 61), + (53, 38, 41), (53, 26, 61), (54, 32, 68), (70, 55, 86), + (112, 79, 134), (127, 83, 140), (142, 88, 146), (156, 108, 124), + (142, 121, 116), (165, 130, 111), (186, 129, 118), (173, 120, 136), + (161, 113, 129), (142, 113, 118), (131, 123, 120), (123, 142, 120), + (90, 157, 103), (82, 177, 119), (76, 181, 140), (56, 139, 109), + (85, 86, 107), (118, 91, 100), (112, 81, 122), (129, 96, 127), + (138, 107, 148), (139, 127, 151), (137, 127, 164), (138, 121, 165), + (127, 117, 169), (112, 114, 189), (110, 113, 164), (112, 103, 156), + (103, 96, 148), (100, 71, 129), (94, 65, 129), (107, 71, 117), + (120, 69, 112), (157, 61, 98), (165, 59, 79), (159, 80, 85), + (126, 79, 85), (124, 87, 94), (125, 89, 93), (128, 88, 96), + (147, 103, 116), (175, 105, 133), (192, 134, 149), (197, 139, 153), + (173, 137, 137), (169, 116, 134), (140, 95, 126), (113, 70, 115), + (101, 62, 107), (95, 36, 100), (85, 34, 101), (73, 47, 86), + (76, 53, 61), (70, 49, 54), (78, 20, 45), (77, 19, 41), + (77, 19, 41), (81, 18, 49), (57, 27, 61), (64, 37, 68), + (69, 45, 77), (77, 53, 85), (101, 62, 109), (116, 66, 125), + (158, 75, 147), (182, 101, 120), (219, 114, 119), (223, 113, 116), + (184, 109, 113), (152, 112, 113), (123, 107, 120), (74, 115, 117) + ), + +// 255 Apophysis-040427-43HeartFlwr +((65, 126, 131), (77, 88, 58), (78, 81, 46), (79, 74, 34), + (78, 75, 28), (78, 77, 23), (101, 75, 22), (124, 74, 21), + (173, 66, 12), (169, 54, 23), (166, 43, 35), (157, 37, 31), + (149, 31, 27), (119, 46, 33), (89, 61, 40), (71, 63, 32), + (53, 65, 25), (49, 81, 31), (32, 75, 38), (16, 70, 46), + (33, 80, 37), (51, 91, 28), (49, 78, 25), (47, 65, 23), + (22, 44, 58), (24, 76, 61), (27, 108, 65), (92, 159, 66), + (157, 210, 68), (177, 209, 71), (198, 208, 75), (232, 157, 42), + (222, 131, 52), (209, 52, 9), (197, 40, 17), (186, 28, 25), + (162, 20, 44), (139, 12, 63), (130, 31, 61), (121, 51, 59), + (117, 115, 103), (126, 135, 130), (136, 156, 157), (173, 167, 196), + (211, 178, 235), (188, 172, 214), (165, 166, 194), (133, 123, 134), + (72, 102, 113), (0, 95, 41), (12, 83, 21), (25, 72, 2), + (28, 92, 7), (31, 113, 13), (30, 122, 6), (29, 131, 0), + (23, 107, 19), (35, 82, 9), (47, 57, 0), (38, 52, 30), + (29, 47, 61), (14, 55, 80), (0, 63, 99), (0, 78, 80), + (13, 78, 84), (72, 97, 119), (75, 87, 91), (79, 77, 64), + (87, 70, 58), (95, 63, 52), (165, 67, 58), (224, 56, 55), + (247, 77, 104), (223, 71, 83), (199, 65, 62), (182, 45, 58), + (166, 26, 55), (173, 13, 55), (181, 0, 55), (216, 0, 15), + (255, 12, 28), (255, 11, 42), (246, 36, 21), (238, 61, 0), + (238, 115, 0), (239, 170, 0), (246, 199, 61), (222, 247, 57), + (229, 205, 73), (237, 212, 134), (245, 219, 196), (250, 208, 210), + (255, 197, 225), (222, 223, 218), (218, 196, 219), (138, 150, 190), + (89, 120, 151), (74, 141, 150), (93, 143, 138), (112, 145, 126), + (126, 144, 129), (141, 144, 133), (161, 171, 163), (210, 152, 202), + (236, 91, 108), (225, 66, 76), (215, 42, 44), (193, 37, 37), + (172, 33, 30), (149, 31, 27), (123, 34, 28), (86, 50, 50), + (77, 53, 51), (60, 56, 73), (55, 59, 63), (50, 63, 54), + (60, 44, 31), (68, 39, 43), (79, 53, 38), (81, 65, 39), + (71, 65, 49), (70, 75, 50), (69, 86, 52), (80, 85, 57), + (92, 84, 63), (83, 119, 58), (146, 112, 85), (141, 136, 80), + (140, 149, 102), (194, 241, 125), (202, 238, 133), (211, 235, 141), + (227, 255, 96), (247, 244, 105), (234, 226, 151), (218, 237, 158), + (232, 199, 208), (146, 176, 175), (60, 153, 142), (66, 131, 127), + (72, 110, 113), (78, 87, 66), (69, 71, 57), (84, 82, 43), + (139, 90, 49), (210, 88, 37), (215, 73, 42), (220, 58, 47), + (198, 42, 20), (175, 9, 47), (194, 0, 32), (193, 0, 12), + (174, 0, 1), (170, 0, 0), (166, 0, 0), (173, 8, 6), + (193, 0, 10), (184, 11, 5), (166, 14, 11), (169, 57, 9), + (178, 69, 2), (164, 69, 3), (159, 68, 9), (155, 68, 15), + (155, 67, 19), (169, 40, 34), (154, 29, 37), (132, 38, 39), + (90, 57, 38), (92, 56, 30), (94, 55, 22), (96, 33, 0), + (77, 7, 17), (85, 23, 38), (102, 44, 56), (104, 14, 78), + (78, 45, 92), (79, 59, 71), (118, 71, 55), (136, 86, 75), + (150, 89, 71), (179, 71, 33), (222, 41, 0), (239, 47, 0), + (199, 58, 12), (183, 63, 10), (168, 68, 8), (143, 79, 5), + (85, 79, 1), (73, 89, 0), (73, 86, 4), (63, 85, 13), + (85, 83, 24), (137, 79, 33), (172, 45, 38), (179, 30, 26), + (182, 13, 10), (183, 14, 11), (189, 15, 14), (200, 44, 0), + (219, 32, 0), (214, 12, 10), (252, 5, 0), (255, 28, 0), + (223, 51, 1), (179, 65, 2), (148, 74, 13), (99, 48, 0), + (79, 42, 15), (50, 43, 1), (13, 54, 0), (43, 41, 0), + (83, 23, 15), (115, 29, 16), (117, 20, 31), (117, 34, 28), + (99, 48, 17), (85, 59, 2), (72, 69, 14), (72, 66, 32), + (79, 68, 40), (75, 93, 41), (79, 135, 48), (78, 136, 77), + (69, 135, 107), (68, 129, 121), (64, 109, 76), (70, 92, 56), + (42, 105, 35), (31, 135, 58), (70, 145, 42), (129, 216, 24), + (173, 239, 17), (171, 213, 51), (88, 152, 66), (64, 161, 80), + (101, 183, 39), (113, 220, 2), (120, 178, 14), (103, 170, 29), + (80, 165, 0), (43, 126, 10), (57, 84, 15), (53, 84, 25), + (62, 88, 23), (73, 77, 26), (83, 68, 27), (131, 65, 17), + (159, 32, 0), (194, 31, 0), (204, 48, 0), (189, 52, 8), + (170, 36, 27), (127, 30, 24), (90, 49, 45), (68, 76, 63) + ), + +// 256 Apophysis-040427-43JunglThron +((59, 170, 52), (18, 118, 46), (18, 105, 52), (18, 92, 59), + (19, 94, 62), (20, 97, 65), (19, 100, 66), (19, 103, 67), + (33, 138, 54), (25, 124, 55), (17, 110, 57), (14, 97, 57), + (11, 85, 58), (15, 76, 54), (19, 67, 51), (25, 61, 56), + (31, 56, 61), (31, 77, 51), (25, 91, 55), (20, 106, 59), + (16, 106, 65), (13, 107, 71), (13, 104, 74), (13, 101, 77), + (14, 103, 81), (25, 112, 79), (36, 122, 77), (46, 142, 74), + (57, 163, 71), (71, 173, 77), (86, 184, 83), (115, 206, 113), + (154, 208, 150), (225, 189, 199), (207, 197, 156), (190, 205, 114), + (132, 179, 90), (74, 154, 67), (69, 146, 64), (64, 138, 61), + (24, 104, 79), (23, 97, 77), (23, 91, 76), (17, 86, 67), + (12, 82, 58), (14, 83, 49), (16, 85, 41), (10, 91, 35), + (25, 94, 40), (33, 142, 37), (49, 148, 46), (65, 155, 55), + (50, 153, 56), (36, 151, 58), (34, 148, 59), (32, 146, 61), + (36, 139, 56), (31, 127, 60), (27, 115, 64), (26, 101, 67), + (25, 88, 71), (22, 78, 70), (19, 69, 70), (19, 69, 70), + (16, 79, 71), (16, 120, 67), (32, 139, 73), (49, 158, 79), + (50, 162, 93), (52, 167, 108), (67, 158, 78), (67, 164, 71), + (49, 157, 72), (38, 144, 66), (28, 131, 60), (18, 121, 59), + (8, 112, 59), (7, 111, 58), (7, 110, 57), (2, 106, 55), + (11, 98, 66), (16, 75, 57), (12, 73, 59), (8, 71, 62), + (8, 70, 62), (9, 70, 62), (20, 64, 65), (43, 73, 73), + (97, 71, 100), (84, 55, 90), (71, 40, 81), (64, 57, 69), + (58, 75, 57), (61, 75, 50), (38, 67, 65), (21, 67, 67), + (10, 95, 66), (12, 114, 67), (13, 116, 60), (14, 119, 53), + (14, 117, 45), (15, 116, 38), (20, 118, 31), (18, 100, 26), + (0, 37, 20), (13, 28, 45), (27, 20, 71), (28, 28, 68), + (29, 36, 65), (20, 46, 59), (25, 67, 63), (28, 107, 60), + (51, 139, 79), (103, 183, 110), (99, 185, 105), (95, 187, 100), + (82, 164, 82), (61, 142, 76), (46, 124, 76), (29, 110, 77), + (0, 96, 81), (3, 87, 65), (6, 79, 50), (5, 83, 44), + (5, 87, 38), (14, 73, 19), (1, 69, 44), (7, 74, 67), + (6, 80, 65), (11, 81, 73), (15, 84, 73), (19, 87, 74), + (30, 85, 88), (20, 85, 81), (14, 87, 70), (8, 78, 50), + (0, 31, 0), (3, 18, 7), (7, 6, 14), (20, 24, 24), + (33, 43, 34), (110, 60, 59), (126, 77, 81), (127, 102, 105), + (161, 112, 82), (189, 137, 80), (190, 169, 96), (192, 202, 113), + (157, 211, 115), (169, 210, 150), (179, 212, 157), (198, 217, 136), + (239, 250, 130), (247, 229, 122), (255, 208, 115), (217, 180, 162), + (228, 186, 200), (232, 177, 200), (238, 176, 197), (238, 180, 205), + (230, 183, 201), (219, 212, 170), (195, 212, 162), (172, 213, 155), + (118, 199, 123), (108, 156, 82), (43, 130, 95), (26, 99, 80), + (36, 90, 77), (43, 85, 78), (50, 80, 80), (90, 89, 103), + (119, 91, 79), (126, 118, 131), (142, 122, 123), (117, 187, 98), + (107, 190, 82), (136, 209, 104), (143, 211, 98), (154, 210, 135), + (146, 206, 144), (130, 205, 123), (117, 203, 102), (128, 207, 79), + (71, 168, 65), (64, 164, 63), (57, 161, 62), (52, 155, 64), + (44, 148, 71), (36, 133, 82), (27, 116, 68), (24, 107, 63), + (16, 110, 57), (13, 110, 57), (13, 99, 60), (12, 98, 73), + (6, 99, 72), (4, 100, 72), (9, 99, 74), (12, 99, 83), + (12, 98, 87), (10, 93, 73), (6, 95, 73), (2, 86, 63), + (0, 86, 61), (10, 82, 58), (3, 90, 55), (8, 100, 53), + (10, 106, 43), (15, 113, 40), (16, 117, 39), (30, 141, 47), + (49, 161, 51), (58, 176, 53), (65, 186, 59), (69, 185, 60), + (72, 189, 57), (80, 181, 59), (107, 182, 79), (155, 193, 108), + (174, 139, 97), (231, 154, 62), (226, 153, 59), (188, 94, 42), + (178, 125, 75), (131, 189, 104), (132, 208, 118), (145, 208, 153), + (150, 206, 167), (192, 220, 205), (217, 197, 190), (217, 195, 182), + (184, 213, 165), (141, 203, 162), (131, 203, 140), (129, 211, 101), + (111, 207, 84), (79, 189, 68), (68, 173, 55), (64, 155, 62), + (41, 136, 70), (26, 125, 79), (18, 116, 75), (21, 111, 76), + (17, 108, 75), (18, 110, 85), (28, 113, 84), (23, 117, 83), + (30, 138, 86), (63, 161, 74), (100, 191, 88), (98, 204, 93), + (84, 192, 72), (61, 174, 58), (21, 124, 41), (42, 151, 60) + ), + +// 257 Apophysis-040427-44jawa +((121, 90, 72), (121, 91, 83), (130, 101, 92), (139, 112, 101), + (148, 117, 112), (157, 123, 124), (161, 130, 125), (166, 138, 127), + (156, 122, 123), (151, 117, 117), (146, 112, 111), (129, 95, 91), + (112, 79, 72), (100, 69, 62), (89, 60, 52), (86, 57, 49), + (83, 54, 46), (76, 51, 46), (81, 54, 48), (87, 58, 50), + (99, 68, 61), (112, 79, 72), (120, 88, 80), (128, 98, 88), + (175, 151, 139), (198, 182, 162), (221, 214, 185), (224, 209, 201), + (227, 205, 217), (223, 200, 208), (220, 195, 199), (195, 163, 176), + (179, 144, 151), (142, 108, 107), (127, 97, 92), (113, 86, 77), + (104, 76, 69), (95, 66, 62), (93, 63, 57), (91, 61, 53), + (79, 52, 43), (75, 47, 41), (71, 43, 39), (68, 42, 36), + (65, 42, 34), (63, 42, 33), (62, 42, 33), (62, 39, 31), + (62, 39, 31), (60, 37, 29), (57, 37, 24), (55, 38, 20), + (59, 40, 22), (63, 42, 25), (63, 43, 25), (63, 45, 25), + (88, 59, 51), (103, 74, 69), (119, 89, 87), (147, 115, 117), + (176, 141, 148), (185, 151, 161), (195, 161, 175), (216, 185, 203), + (228, 196, 207), (212, 181, 199), (190, 157, 169), (168, 133, 139), + (156, 122, 124), (145, 111, 109), (131, 101, 91), (122, 91, 86), + (113, 80, 73), (105, 74, 66), (98, 68, 60), (92, 62, 54), + (87, 57, 49), (83, 55, 46), (80, 53, 44), (77, 50, 41), + (72, 45, 36), (64, 41, 33), (63, 40, 32), (62, 39, 31), + (61, 38, 30), (60, 37, 29), (53, 33, 26), (50, 31, 24), + (50, 31, 24), (55, 34, 27), (60, 37, 31), (61, 38, 31), + (62, 39, 31), (62, 39, 31), (67, 43, 33), (73, 46, 37), + (79, 52, 43), (101, 69, 56), (108, 76, 66), (116, 83, 76), + (116, 83, 76), (117, 84, 77), (115, 82, 75), (115, 82, 75), + (97, 68, 60), (92, 63, 55), (87, 58, 50), (83, 55, 46), + (79, 52, 43), (76, 49, 40), (72, 45, 36), (72, 45, 36), + (74, 47, 38), (78, 51, 42), (78, 51, 42), (78, 51, 42), + (77, 50, 43), (75, 48, 41), (70, 45, 38), (71, 44, 35), + (71, 44, 35), (69, 44, 34), (68, 44, 34), (67, 43, 33), + (67, 43, 33), (64, 41, 33), (60, 37, 31), (55, 35, 28), + (49, 30, 23), (40, 26, 17), (38, 24, 16), (37, 22, 15), + (36, 15, 10), (28, 9, 2), (40, 17, 9), (39, 22, 15), + (56, 33, 27), (61, 37, 29), (66, 42, 32), (66, 42, 32), + (67, 43, 33), (70, 43, 34), (72, 44, 33), (71, 44, 35), + (69, 45, 35), (75, 48, 39), (76, 49, 40), (78, 51, 42), + (81, 54, 45), (87, 58, 50), (92, 62, 54), (93, 63, 55), + (90, 61, 53), (87, 58, 50), (84, 55, 47), (79, 52, 43), + (76, 49, 40), (72, 45, 36), (68, 44, 34), (67, 43, 33), + (66, 44, 33), (64, 41, 33), (63, 40, 32), (63, 40, 32), + (62, 39, 31), (62, 39, 31), (62, 39, 31), (65, 38, 29), + (60, 37, 29), (57, 36, 28), (55, 35, 28), (53, 33, 26), + (52, 33, 26), (51, 31, 24), (57, 27, 25), (60, 37, 29), + (61, 37, 33), (62, 39, 33), (65, 42, 34), (69, 44, 37), + (78, 51, 42), (83, 56, 47), (92, 62, 54), (94, 64, 56), + (111, 78, 71), (111, 78, 71), (112, 79, 72), (110, 77, 70), + (101, 71, 63), (96, 67, 59), (94, 64, 56), (98, 68, 60), + (106, 76, 74), (114, 86, 82), (132, 99, 94), (153, 119, 118), + (174, 139, 146), (189, 156, 167), (201, 169, 184), (213, 187, 200), + (204, 173, 188), (201, 169, 184), (209, 178, 196), (225, 192, 209), + (228, 203, 224), (227, 214, 208), (249, 243, 227), (255, 232, 254), + (242, 223, 245), (224, 193, 208), (187, 153, 167), (167, 131, 133), + (148, 114, 115), (134, 100, 98), (122, 89, 84), (112, 79, 72), + (100, 70, 62), (93, 63, 55), (88, 58, 50), (86, 57, 49), + (83, 56, 49), (86, 57, 49), (92, 63, 55), (94, 64, 56), + (103, 78, 47), (106, 80, 67), (113, 83, 72), (117, 84, 79), + (127, 94, 89), (136, 107, 101), (138, 117, 114), (156, 122, 123), + (165, 130, 134), (172, 137, 143), (172, 140, 145), (171, 136, 142), + (163, 128, 134), (153, 119, 118), (146, 116, 108), (137, 114, 98), + (123, 97, 82), (128, 101, 84), (139, 117, 93), (145, 122, 108), + (173, 162, 116), (153, 140, 121), (139, 118, 75), (107, 87, 50), + (96, 80, 46), (90, 61, 53), (82, 55, 46), (79, 52, 43), + (79, 52, 43), (81, 59, 35), (88, 59, 51), (95, 65, 57) + ), + +// 258 Apophysis-040427-51KaosGrn +((241, 232, 227), (155, 72, 56), (137, 55, 41), (120, 38, 26), + (109, 31, 18), (98, 24, 11), (98, 22, 9), (98, 20, 8), + (99, 17, 5), (98, 19, 6), (97, 21, 8), (95, 26, 12), + (94, 32, 17), (81, 61, 35), (69, 91, 53), (64, 96, 53), + (59, 101, 53), (68, 84, 47), (80, 57, 31), (93, 31, 16), + (93, 22, 11), (93, 13, 6), (92, 10, 6), (91, 7, 7), + (79, 6, 0), (79, 6, 0), (79, 6, 0), (80, 4, 0), + (81, 3, 1), (81, 2, 0), (81, 1, 0), (82, 2, 1), + (83, 2, 0), (90, 6, 4), (91, 21, 12), (93, 37, 20), + (86, 78, 12), (79, 119, 5), (97, 133, 3), (115, 147, 2), + (125, 221, 147), (140, 230, 163), (155, 239, 179), (117, 204, 139), + (80, 170, 100), (70, 162, 96), (60, 154, 92), (71, 113, 67), + (81, 85, 48), (93, 36, 19), (80, 63, 11), (67, 91, 3), + (68, 90, 1), (70, 90, 0), (83, 65, 2), (96, 40, 5), + (100, 13, 3), (94, 6, 2), (89, 0, 1), (88, 2, 1), + (88, 5, 1), (90, 5, 0), (92, 5, 0), (94, 7, 0), + (97, 8, 0), (96, 9, 0), (95, 8, 0), (94, 7, 0), + (94, 7, 0), (94, 7, 0), (94, 7, 0), (94, 7, 0), + (84, 11, 5), (87, 14, 2), (90, 17, 0), (92, 24, 7), + (94, 31, 14), (94, 36, 18), (94, 41, 23), (62, 87, 45), + (58, 120, 69), (49, 139, 75), (59, 130, 44), (69, 121, 13), + (83, 113, 8), (98, 106, 3), (105, 67, 2), (98, 34, 6), + (96, 19, 1), (95, 20, 4), (95, 22, 7), (94, 20, 6), + (94, 18, 5), (93, 17, 1), (96, 12, 1), (95, 10, 3), + (98, 10, 0), (103, 15, 3), (100, 18, 5), (97, 21, 8), + (98, 24, 10), (100, 28, 13), (99, 33, 17), (99, 30, 15), + (113, 21, 10), (106, 20, 9), (99, 19, 8), (98, 19, 7), + (97, 19, 7), (97, 15, 3), (92, 13, 0), (85, 6, 1), + (85, 4, 1), (84, 3, 0), (85, 3, 0), (87, 4, 0), + (93, 5, 1), (94, 6, 2), (91, 6, 1), (86, 6, 0), + (85, 6, 1), (90, 15, 0), (96, 24, 0), (97, 40, 3), + (98, 56, 6), (62, 90, 3), (57, 89, 6), (52, 88, 0), + (48, 88, 0), (46, 86, 0), (46, 86, 0), (46, 86, 0), + (46, 86, 0), (45, 83, 0), (45, 84, 3), (46, 85, 2), + (60, 86, 0), (79, 60, 9), (98, 35, 18), (96, 34, 18), + (95, 33, 18), (97, 30, 14), (95, 29, 13), (95, 33, 18), + (94, 41, 23), (72, 105, 0), (70, 97, 0), (69, 89, 0), + (95, 38, 19), (93, 34, 18), (92, 27, 9), (97, 21, 8), + (96, 24, 0), (96, 24, 0), (96, 24, 0), (96, 23, 8), + (95, 29, 15), (90, 29, 24), (93, 40, 22), (62, 88, 1), + (66, 93, 0), (100, 66, 3), (97, 50, 11), (94, 35, 19), + (97, 25, 11), (100, 18, 6), (105, 5, 3), (113, 5, 2), + (128, 25, 0), (135, 26, 6), (143, 27, 12), (152, 34, 22), + (155, 62, 31), (116, 114, 63), (141, 191, 106), (195, 200, 142), + (220, 226, 120), (248, 246, 159), (231, 186, 157), (232, 195, 177), + (226, 227, 209), (230, 241, 185), (190, 228, 189), (173, 222, 167), + (165, 180, 139), (145, 141, 106), (126, 102, 74), (107, 78, 48), + (102, 37, 19), (107, 68, 3), (129, 114, 13), (80, 131, 12), + (69, 140, 74), (63, 170, 114), (61, 182, 115), (51, 175, 112), + (56, 152, 89), (58, 120, 53), (69, 111, 9), (66, 89, 0), + (95, 40, 20), (95, 28, 12), (97, 21, 7), (92, 16, 0), + (90, 17, 0), (86, 23, 6), (93, 35, 13), (66, 87, 0), + (56, 92, 0), (54, 92, 0), (56, 85, 1), (63, 85, 0), + (94, 35, 17), (94, 27, 11), (96, 24, 2), (96, 24, 0), + (96, 24, 0), (100, 35, 3), (128, 86, 10), (137, 113, 27), + (156, 134, 14), (168, 175, 131), (192, 203, 163), (196, 225, 220), + (231, 251, 223), (255, 251, 252), (241, 236, 240), (241, 230, 208), + (164, 192, 151), (121, 138, 94), (132, 97, 57), (110, 55, 34), + (96, 40, 23), (94, 41, 23), (60, 86, 0), (51, 85, 0), + (49, 85, 0), (47, 85, 0), (48, 88, 0), (49, 89, 3), + (59, 99, 2), (55, 102, 48), (53, 137, 75), (52, 151, 87), + (54, 134, 73), (96, 101, 61), (96, 44, 23), (109, 37, 22), + (137, 54, 38), (164, 64, 48), (162, 52, 39), (163, 29, 28), + (158, 0, 0), (134, 26, 13), (116, 27, 13), (109, 42, 25) + ), + +// 259 Apophysis-040427-51KaosFish +((75, 31, 90), (79, 34, 89), (77, 32, 89), (75, 31, 90), + (75, 31, 90), (75, 31, 90), (77, 32, 89), (79, 34, 89), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (77, 32, 89), + (75, 31, 90), (75, 31, 90), (75, 31, 90), (75, 31, 90), + (75, 31, 90), (75, 31, 90), (75, 31, 90), (75, 31, 90), + (77, 32, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (80, 33, 90), (82, 32, 91), (128, 73, 80), + (175, 114, 70), (199, 135, 70), (224, 157, 70), (225, 158, 71), + (224, 157, 70), (198, 125, 46), (194, 127, 33), (190, 130, 20), + (184, 137, 25), (178, 145, 30), (176, 145, 33), (174, 146, 36), + (163, 146, 38), (122, 92, 64), (81, 38, 91), (80, 36, 90), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (79, 34, 89), (77, 32, 89), (75, 31, 90), + (65, 39, 54), (56, 47, 18), (62, 51, 15), (69, 56, 12), + (104, 75, 0), (144, 107, 16), (184, 140, 33), (205, 149, 51), + (226, 159, 70), (225, 159, 71), (225, 159, 72), (227, 161, 74), + (231, 164, 73), (225, 189, 49), (205, 169, 41), (186, 149, 34), + (199, 157, 53), (212, 165, 73), (226, 167, 75), (216, 157, 101), + (192, 169, 137), (196, 146, 167), (200, 124, 198), (188, 116, 206), + (177, 108, 214), (127, 104, 179), (78, 101, 145), (81, 33, 93), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (77, 32, 89), (75, 31, 90), (75, 31, 90), (78, 28, 91), + (80, 32, 90), (114, 48, 109), (149, 64, 129), (158, 93, 121), + (167, 123, 114), (178, 137, 115), (190, 148, 110), (195, 153, 113), + (215, 156, 100), (224, 157, 70), (202, 130, 45), (181, 103, 20), + (179, 98, 19), (177, 94, 18), (133, 84, 15), (84, 49, 17), + (75, 31, 90), (77, 32, 89), (79, 34, 89), (53, 25, 52), + (28, 16, 16), (13, 0, 17), (37, 31, 19), (51, 11, 61), + (80, 35, 90), (177, 112, 90), (184, 127, 88), (192, 143, 87), + (195, 153, 113), (193, 159, 122), (200, 171, 129), (199, 165, 127), + (178, 137, 115), (152, 117, 104), (127, 98, 94), (103, 66, 91), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (81, 34, 88), (177, 113, 75), (197, 123, 76), (218, 133, 78), + (224, 158, 71), (226, 165, 72), (231, 168, 75), (226, 169, 82), + (190, 155, 115), (185, 145, 112), (181, 135, 109), (184, 126, 88), + (170, 114, 79), (169, 142, 61), (166, 144, 43), (167, 145, 46), + (158, 117, 99), (77, 139, 196), (75, 139, 181), (74, 140, 166), + (64, 115, 119), (87, 127, 54), (137, 107, 45), (177, 95, 19), + (182, 110, 8), (179, 105, 10), (177, 101, 13), (124, 90, 3), + (79, 65, 20), (71, 29, 79), (75, 31, 90), (79, 34, 89), + (98, 102, 51), (113, 118, 36), (116, 103, 50), (71, 88, 43), + (71, 29, 77), (78, 33, 88), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (76, 33, 67), (74, 32, 46), (68, 43, 13), + (69, 43, 10), (52, 28, 2), (52, 48, 10), (36, 61, 19), + (39, 78, 11), (56, 108, 10), (91, 86, 22), (134, 98, 24), + (175, 93, 17), (169, 80, 0), (142, 26, 3), (69, 57, 17), + (35, 84, 28), (29, 66, 58), (48, 78, 28), (87, 71, 12), + (140, 88, 13), (177, 94, 18), (182, 102, 17), (178, 96, 20), + (136, 59, 49), (84, 36, 84), (79, 34, 89), (79, 34, 89), + (75, 31, 90), (75, 31, 90), (75, 31, 90), (75, 31, 90), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (81, 37, 70), (92, 80, 20), (141, 92, 23), (170, 123, 19), + (186, 128, 18), (193, 114, 19), (179, 121, 21), (162, 123, 32), + (116, 110, 26), (69, 60, 17), (17, 44, 0), (23, 27, 4), + (0, 5, 4), (17, 0, 26), (34, 1, 46), (58, 16, 54), + (71, 29, 79), (75, 31, 90), (74, 33, 93), (37, 68, 115), + (26, 93, 109), (51, 119, 104), (62, 107, 126), (50, 89, 122), + (39, 69, 121), (78, 34, 95), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (79, 34, 89), (79, 34, 89), (79, 34, 89), + (79, 34, 89), (75, 31, 90), (75, 31, 90), (75, 31, 90) + ), + +// 260 Apophysis-040427-51KKlown +((41, 23, 105), (134, 59, 141), (137, 63, 125), (140, 67, 110), + (182, 109, 89), (224, 152, 68), (237, 165, 81), (250, 178, 94), + (252, 211, 61), (240, 232, 50), (229, 254, 39), (221, 219, 46), + (213, 184, 54), (158, 175, 67), (103, 167, 81), (86, 153, 94), + (70, 139, 108), (78, 106, 120), (133, 76, 126), (189, 47, 133), + (205, 25, 133), (222, 3, 133), (202, 1, 127), (182, 0, 121), + (62, 28, 44), (42, 37, 38), (23, 47, 33), (74, 74, 38), + (126, 101, 44), (158, 128, 38), (191, 155, 33), (226, 159, 46), + (255, 136, 63), (226, 146, 95), (217, 138, 120), (208, 130, 146), + (159, 103, 144), (111, 76, 142), (70, 65, 139), (30, 55, 137), + (47, 50, 57), (30, 83, 72), (13, 116, 87), (62, 113, 116), + (111, 111, 145), (130, 115, 138), (149, 119, 131), (213, 170, 115), + (255, 190, 121), (255, 240, 76), (254, 222, 109), (253, 205, 143), + (222, 191, 164), (191, 178, 185), (156, 162, 177), (122, 146, 170), + (151, 198, 143), (126, 187, 129), (102, 176, 115), (75, 113, 111), + (48, 50, 107), (35, 42, 102), (23, 34, 98), (4, 95, 100), + (23, 92, 61), (33, 111, 27), (84, 120, 22), (136, 130, 18), + (147, 124, 9), (159, 118, 0), (236, 118, 31), (220, 91, 23), + (95, 113, 5), (64, 96, 27), (33, 79, 50), (33, 107, 60), + (34, 136, 71), (39, 136, 62), (44, 136, 53), (61, 160, 17), + (50, 144, 8), (113, 98, 7), (146, 115, 56), (179, 132, 106), + (189, 144, 90), (199, 157, 75), (145, 180, 64), (135, 160, 43), + (132, 94, 45), (153, 65, 35), (174, 36, 26), (202, 22, 13), + (231, 8, 0), (251, 8, 12), (214, 20, 44), (204, 22, 11), + (188, 64, 13), (147, 33, 58), (107, 34, 37), (67, 36, 16), + (59, 53, 12), (52, 70, 8), (37, 132, 2), (41, 134, 2), + (117, 191, 6), (139, 189, 24), (162, 187, 43), (171, 202, 48), + (180, 218, 53), (194, 226, 67), (195, 200, 106), (173, 187, 151), + (202, 178, 174), (214, 174, 87), (211, 166, 93), (208, 159, 100), + (211, 136, 141), (188, 134, 186), (220, 115, 197), (254, 110, 208), + (222, 51, 117), (230, 44, 85), (239, 38, 54), (197, 35, 44), + (155, 32, 34), (107, 35, 23), (76, 36, 24), (53, 29, 27), + (92, 19, 26), (165, 11, 81), (167, 7, 88), (169, 4, 96), + (168, 10, 133), (185, 21, 136), (184, 26, 121), (218, 18, 117), + (222, 5, 60), (223, 2, 47), (224, 0, 34), (224, 0, 19), + (224, 0, 4), (184, 2, 17), (121, 11, 0), (97, 39, 17), + (72, 54, 30), (16, 92, 17), (14, 106, 9), (13, 121, 2), + (18, 136, 58), (46, 146, 74), (67, 136, 92), (126, 169, 115), + (215, 231, 70), (234, 240, 94), (253, 250, 119), (245, 251, 155), + (255, 246, 185), (255, 240, 188), (254, 243, 213), (242, 197, 220), + (226, 185, 203), (227, 132, 176), (237, 124, 182), (248, 116, 189), + (237, 72, 176), (255, 49, 169), (253, 14, 157), (229, 25, 94), + (254, 4, 14), (253, 3, 11), (252, 3, 9), (241, 5, 5), + (223, 1, 0), (186, 20, 0), (125, 20, 1), (122, 54, 9), + (101, 53, 33), (99, 96, 55), (121, 122, 114), (96, 148, 112), + (49, 141, 130), (0, 128, 109), (0, 133, 76), (0, 123, 75), + (21, 111, 60), (16, 106, 61), (11, 101, 63), (1, 62, 54), + (7, 32, 52), (61, 28, 57), (61, 6, 61), (155, 2, 82), + (206, 12, 47), (219, 34, 75), (180, 43, 125), (170, 25, 128), + (150, 82, 165), (146, 129, 165), (164, 149, 214), (198, 230, 225), + (224, 217, 211), (239, 193, 196), (255, 206, 173), (242, 213, 135), + (218, 237, 60), (186, 222, 38), (195, 170, 18), (171, 162, 5), + (69, 140, 10), (46, 107, 27), (52, 69, 0), (99, 58, 14), + (147, 47, 21), (188, 87, 77), (207, 95, 49), (217, 92, 72), + (234, 106, 95), (239, 75, 102), (210, 92, 108), (185, 82, 109), + (146, 68, 144), (140, 121, 140), (156, 208, 134), (169, 220, 117), + (163, 230, 124), (177, 209, 168), (250, 252, 187), (249, 242, 200), + (255, 241, 222), (255, 253, 243), (232, 228, 255), (241, 234, 228), + (255, 237, 204), (255, 206, 173), (179, 185, 113), (102, 169, 66), + (64, 158, 10), (62, 141, 0), (100, 79, 22), (149, 21, 20), + (170, 11, 31), (209, 0, 41), (234, 0, 61), (255, 11, 129), + (239, 3, 148), (248, 0, 140), (255, 0, 75), (241, 0, 26), + (255, 5, 17), (242, 8, 7), (237, 11, 0), (242, 7, 3), + (228, 0, 0), (215, 40, 9), (210, 42, 0), (219, 63, 4) + ), + +// 261 Apophysis-040427-51KaosEgg +((113, 89, 87), (97, 73, 69), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (98, 73, 69), + (110, 89, 86), (129, 130, 114), (138, 137, 125), (148, 145, 136), + (132, 121, 112), (116, 98, 88), (114, 91, 84), (113, 85, 81), + (100, 75, 71), (112, 85, 80), (125, 96, 90), (148, 124, 110), + (171, 153, 131), (183, 167, 152), (195, 182, 173), (216, 213, 208), + (245, 241, 242), (214, 211, 204), (188, 184, 179), (163, 158, 155), + (155, 150, 146), (148, 143, 137), (136, 122, 122), (125, 108, 92), + (112, 114, 101), (130, 134, 116), (149, 154, 132), (162, 157, 134), + (176, 160, 137), (177, 161, 138), (178, 162, 139), (178, 168, 143), + (175, 170, 148), (184, 175, 166), (191, 177, 169), (198, 179, 173), + (192, 169, 162), (186, 159, 152), (170, 150, 125), (138, 104, 95), + (106, 83, 75), (101, 77, 71), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (96, 71, 67), (82, 63, 66), (69, 56, 65), (63, 50, 60), + (58, 45, 55), (63, 43, 45), (55, 48, 42), (60, 42, 38), + (59, 41, 37), (53, 46, 40), (50, 44, 39), (47, 42, 39), + (39, 30, 31), (38, 24, 21), (43, 24, 28), (52, 32, 33), + (78, 54, 52), (84, 60, 58), (90, 66, 64), (89, 66, 63), + (88, 67, 62), (84, 65, 61), (80, 56, 54), (72, 46, 47), + (63, 42, 41), (78, 54, 52), (81, 55, 52), (85, 57, 53), + (89, 61, 57), (96, 68, 65), (95, 70, 66), (90, 66, 62), + (70, 50, 49), (56, 37, 39), (43, 24, 30), (37, 23, 26), + (32, 22, 23), (39, 26, 20), (39, 35, 26), (47, 43, 32), + (61, 59, 47), (94, 70, 66), (95, 70, 66), (96, 71, 67), + (97, 72, 68), (97, 72, 68), (96, 72, 70), (100, 81, 74), + (133, 116, 124), (145, 127, 134), (158, 139, 145), (164, 154, 153), + (163, 158, 154), (159, 146, 153), (149, 130, 124), (138, 104, 95), + (122, 100, 102), (112, 94, 106), (115, 97, 108), (118, 101, 111), + (130, 114, 124), (142, 139, 130), (159, 154, 148), (162, 157, 151), + (150, 140, 141), (143, 131, 139), (136, 122, 137), (137, 122, 129), + (134, 117, 125), (117, 112, 108), (117, 115, 103), (110, 102, 100), + (104, 86, 82), (91, 75, 88), (81, 63, 77), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (98, 80, 70), + (105, 109, 94), (106, 106, 94), (107, 104, 95), (106, 99, 91), + (97, 99, 85), (95, 95, 83), (96, 75, 70), (97, 72, 68), + (98, 76, 65), (99, 80, 65), (113, 90, 76), (126, 102, 90), + (137, 123, 114), (146, 150, 133), (160, 155, 149), (156, 161, 141), + (152, 157, 135), (141, 130, 124), (118, 111, 103), (111, 93, 89), + (98, 78, 71), (94, 75, 69), (89, 73, 60), (79, 66, 50), + (69, 52, 45), (59, 41, 37), (50, 31, 37), (47, 28, 34), + (56, 31, 34), (53, 32, 39), (63, 45, 45), (72, 72, 62), + (73, 73, 65), (78, 78, 66), (81, 82, 68), (93, 75, 63), + (96, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (95, 71, 67), (90, 65, 60), (85, 60, 53), + (75, 54, 51), (60, 42, 38), (44, 25, 31), (38, 18, 27), + (31, 17, 17), (30, 16, 15), (24, 12, 12), (23, 11, 11), + (30, 16, 15), (35, 20, 17), (38, 21, 29), (44, 39, 33), + (56, 46, 44), (71, 52, 48), (81, 60, 59), (94, 70, 66), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68), + (97, 72, 68), (97, 72, 68), (97, 72, 68), (97, 72, 68) + ), + +// 262 Apophysis-040427-51LavLace +((253, 226, 233), (255, 184, 235), (246, 195, 223), (238, 206, 211), + (229, 208, 210), (221, 211, 210), (210, 202, 198), (200, 193, 187), + (212, 212, 210), (226, 214, 223), (241, 216, 237), (243, 202, 235), + (245, 188, 233), (247, 208, 230), (249, 229, 228), (247, 236, 237), + (246, 244, 247), (255, 229, 246), (252, 238, 249), (249, 247, 252), + (235, 248, 234), (222, 249, 216), (225, 239, 218), (228, 229, 221), + (230, 227, 210), (236, 229, 218), (242, 231, 227), (241, 221, 229), + (240, 211, 231), (244, 195, 232), (248, 179, 234), (255, 175, 231), + (255, 181, 222), (240, 171, 225), (234, 176, 219), (229, 182, 214), + (215, 171, 192), (202, 160, 170), (192, 137, 165), (183, 114, 161), + (180, 139, 153), (205, 190, 161), (230, 242, 170), (218, 243, 201), + (207, 245, 232), (191, 241, 210), (175, 237, 188), (185, 204, 172), + (165, 160, 214), (137, 100, 133), (105, 63, 103), (74, 26, 74), + (67, 25, 64), (60, 25, 55), (60, 23, 51), (61, 21, 47), + (47, 10, 41), (51, 13, 39), (55, 16, 37), (69, 22, 44), + (83, 29, 52), (80, 31, 62), (78, 33, 72), (76, 36, 73), + (76, 36, 73), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (95, 41, 77), + (151, 88, 135), (174, 121, 158), (197, 154, 182), (212, 147, 188), + (227, 140, 195), (212, 148, 183), (198, 157, 171), (179, 134, 137), + (145, 84, 128), (80, 35, 74), (82, 37, 78), (85, 40, 83), + (109, 57, 99), (133, 75, 116), (160, 88, 154), (171, 105, 151), + (127, 65, 114), (102, 51, 94), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (81, 43, 80), + (152, 81, 147), (163, 103, 155), (175, 125, 163), (180, 152, 167), + (186, 179, 171), (187, 197, 173), (171, 184, 167), (176, 165, 159), + (168, 152, 129), (128, 109, 103), (113, 88, 89), (99, 68, 76), + (76, 38, 75), (75, 37, 74), (75, 37, 74), (75, 37, 74), + (77, 36, 76), (116, 65, 105), (156, 94, 135), (174, 129, 158), + (193, 164, 182), (226, 221, 201), (244, 238, 216), (255, 254, 227), + (255, 243, 222), (221, 212, 183), (206, 201, 180), (192, 190, 178), + (163, 155, 134), (138, 111, 128), (116, 58, 96), (82, 30, 76), + (126, 83, 110), (156, 121, 136), (186, 160, 163), (193, 162, 167), + (200, 165, 172), (204, 165, 186), (202, 157, 177), (202, 141, 174), + (174, 107, 158), (83, 38, 81), (79, 36, 76), (75, 35, 72), + (71, 26, 69), (66, 26, 63), (61, 25, 63), (68, 23, 62), + (66, 27, 71), (71, 28, 72), (76, 29, 73), (76, 36, 73), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (74, 36, 75), (75, 37, 78), (83, 44, 91), (138, 62, 126), + (178, 0, 122), (93, 37, 86), (80, 35, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 72), (87, 31, 66), + (102, 44, 68), (145, 84, 81), (166, 97, 115), (145, 96, 118), + (88, 50, 87), (75, 40, 80), (75, 37, 76), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (77, 37, 74), (77, 37, 74), (77, 37, 74), (77, 37, 74), + (117, 75, 85), (149, 126, 120), (188, 156, 169), (229, 171, 193), + (240, 193, 213), (255, 186, 223), (240, 165, 221), (235, 170, 224), + (222, 168, 202), (207, 172, 204), (195, 177, 199), (203, 180, 188), + (212, 191, 190), (229, 190, 195), (233, 192, 210), (224, 189, 211), + (213, 184, 176), (179, 178, 160), (167, 164, 145), (181, 155, 138), + (195, 148, 156), (219, 183, 149), (245, 210, 180), (255, 235, 219), + (251, 251, 241), (254, 255, 244), (252, 255, 250), (252, 254, 251), + (252, 247, 254), (255, 248, 255), (255, 254, 255), (248, 255, 253), + (244, 255, 253), (243, 253, 252), (229, 255, 235), (246, 255, 248) + ), + +// 263 Apophysis-040427-51mudding +((171, 134, 128), (227, 182, 163), (227, 197, 170), (227, 213, 178), + (205, 187, 161), (183, 162, 145), (174, 156, 134), (166, 150, 124), + (135, 112, 78), (123, 94, 64), (111, 77, 50), (123, 80, 44), + (136, 83, 39), (140, 90, 51), (144, 98, 64), (144, 98, 78), + (145, 98, 92), (132, 121, 137), (151, 132, 141), (170, 144, 145), + (170, 150, 153), (171, 156, 161), (169, 157, 165), (168, 158, 169), + (181, 157, 145), (186, 160, 134), (191, 163, 123), (195, 169, 134), + (199, 176, 145), (198, 181, 143), (198, 187, 141), (200, 185, 146), + (217, 193, 165), (188, 184, 136), (192, 179, 112), (196, 174, 89), + (187, 166, 99), (179, 159, 109), (174, 155, 94), (170, 152, 80), + (170, 140, 104), (181, 141, 105), (193, 143, 106), (200, 148, 122), + (207, 154, 138), (220, 166, 153), (233, 179, 169), (230, 216, 203), + (248, 232, 235), (255, 255, 255), (252, 253, 253), (250, 252, 251), + (237, 244, 244), (225, 236, 238), (216, 218, 214), (207, 200, 190), + (162, 157, 153), (143, 139, 141), (125, 122, 129), (107, 103, 110), + (90, 85, 92), (88, 75, 83), (87, 66, 75), (90, 62, 40), + (75, 55, 30), (62, 33, 19), (54, 33, 13), (46, 34, 8), + (50, 37, 9), (55, 40, 11), (59, 50, 9), (59, 48, 18), + (65, 49, 15), (68, 53, 19), (71, 58, 24), (95, 81, 42), + (119, 104, 61), (130, 115, 72), (141, 126, 83), (161, 152, 113), + (199, 194, 154), (255, 244, 229), (251, 248, 227), (247, 253, 225), + (238, 242, 228), (230, 232, 231), (213, 195, 183), (222, 188, 160), + (151, 167, 190), (157, 161, 181), (164, 155, 172), (166, 147, 151), + (168, 139, 131), (156, 130, 113), (146, 110, 88), (138, 108, 72), + (129, 99, 63), (133, 107, 84), (141, 129, 106), (150, 152, 128), + (156, 168, 145), (163, 185, 162), (179, 213, 197), (175, 197, 236), + (188, 218, 180), (194, 210, 160), (201, 203, 140), (187, 200, 129), + (174, 197, 119), (171, 161, 92), (179, 128, 97), (173, 101, 87), + (177, 91, 68), (131, 117, 90), (123, 115, 89), (115, 113, 88), + (105, 97, 94), (100, 99, 81), (100, 92, 73), (92, 71, 68), + (71, 48, 34), (60, 41, 28), (49, 35, 22), (51, 35, 21), + (53, 35, 21), (62, 35, 16), (65, 41, 3), (67, 39, 2), + (93, 39, 13), (106, 76, 38), (117, 81, 44), (129, 86, 51), + (134, 100, 62), (151, 119, 72), (157, 117, 68), (160, 128, 67), + (166, 137, 93), (165, 132, 97), (165, 128, 101), (160, 124, 93), + (155, 121, 86), (145, 113, 102), (125, 109, 86), (123, 87, 71), + (112, 75, 59), (93, 52, 34), (91, 57, 29), (90, 62, 25), + (93, 63, 27), (98, 66, 27), (109, 55, 17), (117, 69, 20), + (110, 71, 30), (112, 77, 34), (114, 83, 39), (119, 94, 53), + (109, 97, 49), (112, 88, 44), (104, 80, 46), (97, 69, 30), + (83, 65, 19), (58, 41, 0), (56, 38, 5), (55, 35, 10), + (45, 29, 0), (37, 27, 0), (34, 15, 1), (26, 23, 6), + (36, 28, 15), (40, 32, 15), (45, 37, 16), (55, 46, 17), + (76, 47, 13), (74, 60, 23), (81, 68, 26), (86, 70, 36), + (97, 79, 55), (111, 87, 77), (122, 101, 116), (130, 135, 155), + (166, 169, 212), (192, 180, 226), (174, 169, 175), (195, 179, 146), + (202, 170, 145), (197, 165, 143), (193, 160, 141), (197, 164, 133), + (179, 143, 107), (153, 121, 100), (135, 100, 72), (124, 84, 59), + (106, 80, 53), (95, 76, 43), (90, 73, 47), (94, 70, 42), + (98, 69, 39), (98, 74, 36), (93, 71, 32), (93, 69, 35), + (88, 57, 36), (78, 56, 33), (84, 55, 25), (86, 60, 27), + (97, 66, 37), (99, 72, 51), (109, 93, 67), (119, 97, 73), + (114, 125, 95), (124, 131, 98), (136, 124, 100), (147, 135, 119), + (138, 138, 126), (130, 116, 107), (137, 116, 95), (134, 109, 79), + (132, 106, 73), (122, 90, 69), (123, 102, 75), (123, 108, 89), + (129, 116, 107), (143, 130, 114), (167, 140, 121), (171, 140, 119), + (150, 134, 101), (146, 127, 85), (137, 113, 77), (123, 94, 64), + (118, 95, 61), (110, 93, 65), (99, 86, 67), (91, 84, 76), + (79, 88, 87), (100, 92, 79), (114, 96, 76), (117, 92, 72), + (118, 94, 70), (112, 92, 65), (115, 88, 59), (105, 83, 60), + (115, 80, 58), (121, 90, 61), (127, 100, 55), (145, 93, 56), + (149, 76, 67), (141, 76, 48), (143, 72, 40), (104, 73, 45), + (79, 71, 50), (50, 62, 58), (76, 63, 55), (85, 58, 37), + (86, 65, 36), (92, 74, 54), (99, 85, 74), (94, 74, 65) + ), + +// 264 Apophysis-040427-51pane; +((154, 121, 5), (154, 121, 5), (154, 121, 5), (154, 121, 5), + (152, 120, 5), (151, 119, 6), (149, 117, 6), (147, 115, 6), + (135, 113, 37), (131, 118, 32), (127, 124, 27), (121, 118, 34), + (115, 112, 41), (96, 94, 59), (77, 77, 77), (76, 76, 76), + (76, 76, 76), (42, 54, 14), (36, 42, 10), (31, 31, 7), + (38, 37, 7), (46, 43, 8), (64, 61, 11), (83, 79, 15), + (142, 115, 70), (149, 127, 97), (156, 140, 125), (163, 154, 132), + (170, 169, 139), (172, 172, 139), (175, 175, 139), (169, 168, 137), + (147, 172, 140), (178, 144, 98), (171, 140, 63), (164, 136, 29), + (157, 127, 17), (150, 118, 5), (146, 114, 5), (142, 111, 5), + (120, 95, 5), (105, 83, 4), (90, 71, 3), (66, 51, 4), + (42, 32, 5), (37, 30, 4), (33, 29, 4), (28, 30, 6), + (33, 28, 6), (58, 55, 10), (76, 65, 10), (94, 76, 10), + (88, 78, 12), (82, 81, 14), (83, 82, 15), (84, 83, 16), + (129, 119, 24), (142, 124, 25), (156, 129, 26), (149, 123, 44), + (142, 117, 63), (134, 116, 58), (127, 116, 54), (123, 121, 46), + (129, 126, 29), (115, 113, 30), (99, 98, 23), (84, 83, 16), + (75, 73, 14), (66, 64, 13), (41, 41, 7), (31, 31, 7), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (8, 6, 3), + (16, 13, 6), (32, 16, 6), (49, 20, 6), (82, 34, 12), + (100, 59, 15), (113, 88, 4), (125, 96, 17), (138, 104, 30), + (139, 112, 38), (140, 120, 47), (143, 139, 68), (141, 128, 83), + (158, 160, 155), (178, 165, 155), (198, 170, 156), (199, 179, 163), + (201, 188, 171), (190, 184, 150), (181, 177, 140), (173, 172, 128), + (163, 162, 118), (163, 142, 53), (175, 130, 69), (187, 118, 85), + (173, 124, 79), (159, 130, 74), (148, 126, 68), (131, 123, 50), + (152, 121, 5), (153, 121, 5), (154, 121, 5), (154, 121, 5), + (154, 121, 5), (153, 120, 5), (150, 118, 5), (135, 106, 4), + (123, 97, 4), (93, 99, 27), (97, 99, 28), (102, 99, 30), + (108, 98, 26), (117, 99, 27), (134, 105, 5), (148, 116, 5), + (151, 119, 6), (147, 102, 12), (143, 86, 19), (157, 76, 19), + (172, 67, 19), (136, 87, 18), (137, 108, 6), (150, 118, 5), + (152, 121, 5), (154, 121, 5), (154, 121, 5), (154, 121, 5), + (154, 121, 5), (154, 121, 5), (154, 121, 5), (153, 120, 4), + (151, 118, 5), (141, 111, 4), (132, 104, 4), (128, 101, 4), + (124, 98, 5), (123, 97, 4), (123, 96, 5), (106, 94, 18), + (113, 111, 24), (130, 127, 24), (148, 134, 32), (166, 141, 41), + (172, 148, 42), (164, 134, 24), (159, 127, 14), (156, 120, 6), + (154, 121, 5), (154, 121, 5), (154, 121, 5), (154, 121, 5), + (153, 120, 5), (150, 118, 5), (139, 110, 6), (130, 102, 3), + (117, 91, 4), (79, 77, 16), (72, 70, 14), (66, 64, 13), + (73, 36, 9), (86, 51, 13), (102, 73, 15), (95, 76, 10), + (104, 83, 2), (100, 80, 8), (96, 78, 14), (105, 88, 18), + (101, 95, 19), (102, 96, 18), (101, 98, 17), (112, 108, 19), + (135, 106, 6), (149, 117, 4), (153, 120, 4), (154, 121, 5), + (154, 121, 5), (154, 121, 5), (154, 121, 5), (154, 121, 5), + (150, 122, 15), (146, 129, 20), (142, 136, 26), (134, 131, 24), + (128, 125, 22), (127, 123, 23), (128, 125, 22), (149, 117, 6), + (142, 111, 5), (134, 105, 3), (121, 96, 4), (104, 82, 6), + (92, 72, 3), (53, 48, 10), (39, 32, 6), (31, 29, 6), + (32, 30, 7), (46, 43, 8), (79, 75, 14), (82, 81, 14), + (73, 71, 12), (48, 46, 8), (34, 30, 5), (27, 26, 6), + (2, 7, 3), (0, 0, 0), (0, 0, 0), (3, 3, 3), + (25, 29, 6), (46, 40, 8), (94, 74, 3), (108, 86, 3), + (132, 104, 4), (150, 118, 5), (153, 120, 4), (154, 121, 5), + (154, 121, 5), (154, 121, 5), (154, 121, 5), (154, 121, 5), + (154, 121, 5), (153, 120, 5), (150, 118, 5), (148, 116, 5), + (138, 109, 5), (133, 104, 4), (134, 105, 3), (148, 116, 5), + (153, 120, 4), (151, 120, 4), (145, 115, 5), (131, 103, 4), + (116, 92, 4), (95, 75, 4), (55, 54, 10), (36, 35, 5), + (31, 31, 7), (36, 35, 5), (47, 45, 7), (93, 73, 2), + (115, 91, 3), (131, 103, 4), (145, 115, 5), (152, 119, 4), + (153, 120, 4), (154, 121, 5), (154, 121, 5), (154, 121, 5), + (154, 121, 5), (154, 121, 5), (154, 121, 5), (154, 121, 5) + ), + +// 265 Apophysis-040427-51RiftAO +((172, 134, 37), (141, 80, 23), (110, 58, 23), (80, 36, 23), + (60, 40, 22), (41, 45, 22), (40, 45, 21), (40, 46, 20), + (52, 23, 19), (49, 21, 12), (47, 19, 5), (46, 16, 8), + (45, 14, 11), (48, 16, 11), (51, 18, 11), (53, 19, 12), + (55, 20, 14), (61, 24, 16), (67, 29, 19), (74, 34, 22), + (78, 34, 13), (82, 35, 5), (92, 42, 7), (102, 49, 9), + (98, 70, 20), (85, 64, 31), (72, 59, 42), (54, 50, 47), + (37, 41, 53), (36, 40, 52), (36, 40, 52), (33, 47, 21), + (28, 54, 17), (38, 44, 18), (36, 41, 13), (35, 38, 9), + (42, 28, 9), (49, 19, 9), (50, 21, 8), (52, 23, 7), + (68, 28, 18), (66, 27, 17), (65, 27, 16), (58, 23, 14), + (52, 19, 12), (48, 16, 11), (44, 13, 10), (27, 7, 8), + (21, 3, 3), (8, 5, 0), (8, 3, 0), (8, 1, 0), + (16, 6, 1), (25, 11, 2), (31, 13, 3), (37, 15, 4), + (36, 36, 8), (33, 38, 8), (31, 40, 9), (33, 39, 9), + (35, 38, 9), (37, 38, 11), (39, 39, 13), (53, 35, 23), + (69, 32, 26), (102, 70, 31), (123, 88, 57), (145, 107, 84), + (145, 112, 92), (146, 117, 101), (161, 124, 72), (164, 141, 73), + (131, 79, 81), (124, 79, 59), (117, 80, 38), (98, 58, 29), + (80, 37, 20), (84, 45, 23), (89, 54, 26), (76, 65, 37), + (56, 65, 34), (35, 38, 55), (29, 32, 45), (24, 27, 36), + (21, 22, 31), (18, 18, 26), (16, 11, 5), (10, 7, 2), + (15, 7, 4), (16, 12, 15), (18, 18, 26), (21, 22, 31), + (24, 27, 36), (24, 27, 36), (24, 27, 36), (18, 18, 26), + (0, 1, 32), (0, 1, 0), (7, 4, 0), (14, 7, 1), + (22, 10, 2), (30, 13, 3), (53, 24, 8), (72, 37, 15), + (124, 62, 13), (154, 73, 26), (185, 84, 40), (187, 105, 47), + (190, 126, 54), (148, 108, 116), (94, 106, 158), (82, 94, 146), + (70, 80, 133), (50, 54, 66), (55, 59, 53), (60, 64, 41), + (80, 70, 35), (115, 88, 77), (166, 137, 129), (154, 160, 150), + (231, 199, 238), (233, 214, 198), (236, 229, 159), (217, 201, 148), + (199, 173, 138), (183, 148, 118), (173, 133, 107), (167, 126, 94), + (154, 111, 79), (140, 88, 64), (141, 96, 63), (143, 104, 63), + (150, 105, 86), (124, 94, 86), (84, 82, 96), (64, 62, 73), + (46, 49, 64), (41, 44, 58), (36, 40, 52), (32, 36, 49), + (29, 32, 47), (25, 27, 40), (22, 25, 42), (24, 28, 37), + (24, 27, 36), (24, 27, 36), (24, 27, 36), (24, 27, 36), + (22, 26, 35), (17, 17, 25), (19, 5, 4), (25, 0, 0), + (45, 12, 7), (51, 12, 5), (57, 13, 4), (71, 23, 0), + (75, 24, 3), (74, 6, 0), (41, 5, 0), (36, 8, 5), + (30, 12, 2), (23, 3, 2), (22, 3, 2), (21, 3, 3), + (21, 2, 0), (13, 0, 0), (9, 6, 0), (12, 9, 0), + (38, 16, 3), (36, 27, 6), (35, 38, 9), (39, 45, 19), + (52, 55, 24), (45, 54, 27), (37, 46, 19), (36, 42, 16), + (35, 38, 9), (35, 38, 9), (35, 38, 9), (35, 38, 9), + (36, 16, 5), (29, 11, 1), (18, 9, 0), (16, 9, 0), + (31, 11, 0), (33, 12, 0), (36, 14, 1), (37, 15, 2), + (38, 16, 3), (38, 18, 7), (35, 38, 9), (35, 38, 9), + (47, 19, 7), (44, 18, 5), (44, 18, 5), (44, 18, 5), + (41, 17, 5), (40, 16, 4), (40, 16, 4), (41, 17, 5), + (44, 18, 5), (59, 22, 14), (71, 32, 17), (94, 48, 24), + (122, 88, 42), (150, 107, 75), (171, 136, 106), (215, 190, 149), + (229, 211, 173), (251, 216, 194), (203, 200, 207), (173, 175, 196), + (143, 144, 172), (179, 186, 194), (204, 231, 226), (204, 208, 211), + (222, 208, 159), (167, 171, 136), (146, 158, 118), (137, 135, 114), + (100, 100, 126), (71, 74, 89), (48, 49, 69), (54, 56, 34), + (39, 45, 19), (35, 38, 9), (31, 16, 11), (18, 18, 26), + (24, 27, 36), (24, 27, 36), (24, 27, 36), (24, 27, 36), + (24, 27, 36), (25, 28, 37), (25, 28, 37), (34, 32, 35), + (46, 14, 15), (48, 19, 13), (47, 20, 13), (24, 27, 34), + (24, 27, 36), (24, 27, 36), (24, 27, 36), (24, 27, 36), + (24, 28, 37), (26, 29, 44), (32, 36, 48), (34, 37, 54), + (29, 31, 52), (22, 23, 71), (30, 38, 61), (46, 49, 66), + (57, 58, 76), (84, 75, 94), (158, 138, 105), (139, 128, 110) + ), + +// 266 Apophysis-040427-51ylwAlien +((6, 7, 2), (0, 1, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 1, 1), (13, 0, 0), (96, 38, 2), (180, 76, 5), + (194, 110, 25), (208, 144, 46), (213, 146, 45), (219, 148, 44), + (234, 179, 50), (224, 176, 55), (214, 174, 60), (199, 173, 52), + (184, 173, 45), (169, 159, 38), (155, 145, 32), (69, 120, 0), + (60, 107, 11), (202, 105, 26), (224, 113, 40), (247, 122, 55), + (218, 95, 35), (190, 69, 16), (138, 59, 17), (86, 50, 18), + (2, 2, 4), (1, 1, 2), (0, 0, 0), (0, 0, 1), + (0, 0, 2), (0, 0, 3), (0, 1, 4), (0, 0, 7), + (0, 2, 8), (46, 105, 23), (137, 147, 40), (228, 190, 57), + (232, 201, 58), (237, 212, 60), (239, 219, 68), (244, 218, 69), + (240, 204, 64), (241, 187, 58), (242, 170, 52), (240, 166, 48), + (239, 162, 44), (239, 173, 48), (239, 185, 53), (245, 217, 58), + (247, 221, 64), (255, 242, 77), (253, 243, 69), (251, 245, 61), + (252, 235, 66), (254, 225, 71), (243, 218, 74), (244, 212, 161), + (245, 218, 225), (248, 229, 235), (252, 241, 245), (252, 245, 241), + (252, 250, 238), (245, 246, 238), (243, 212, 207), (246, 223, 81), + (249, 224, 72), (230, 182, 54), (174, 128, 38), (118, 75, 22), + (79, 46, 16), (41, 18, 10), (5, 2, 9), (1, 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, 0, 0), (0, 0, 0), (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, 2, 2), + (101, 129, 52), (148, 153, 47), (196, 178, 42), (200, 181, 45), + (204, 184, 49), (217, 150, 46), (177, 134, 39), (81, 54, 11), + (9, 5, 4), (15, 1, 0), (40, 17, 3), (65, 34, 6), + (114, 71, 36), (185, 134, 45), (222, 151, 45), (248, 174, 51), + (250, 185, 57), (237, 169, 48), (225, 154, 40), (202, 105, 26), + (133, 33, 17), (45, 8, 0), (3, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (10, 0, 0), + (45, 18, 7), (113, 44, 5), (191, 113, 41), (218, 151, 47), + (234, 205, 209), (235, 210, 221), (237, 216, 233), (241, 222, 242), + (230, 233, 224), (240, 229, 207), (211, 220, 173), (234, 213, 70), + (241, 216, 72), (246, 222, 64), (247, 224, 66), (248, 222, 65), + (247, 220, 67), (243, 216, 63), (234, 187, 55), (235, 184, 56), + (235, 184, 57), (209, 188, 69), (170, 170, 100), (91, 119, 35), + (55, 51, 26), (5, 3, 8), (0, 0, 2), (2, 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, 2, 0), (7, 3, 0), (66, 35, 15), (125, 143, 83), + (172, 172, 148), (195, 204, 175), (211, 220, 193), (213, 191, 116), + (235, 211, 75), (232, 211, 68), (228, 199, 71), (213, 193, 46), + (175, 154, 11), (104, 83, 30), (30, 20, 18), (3, 3, 1), + (1, 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), (1, 1, 1), (11, 1, 0), (77, 57, 0), + (144, 158, 13), (185, 187, 24), (206, 148, 51), (165, 117, 45), + (61, 42, 36), (15, 11, 10), (1, 1, 1), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (3, 0, 0) + ), + +// 267 Apophysis-040427-51elecforest +((0, 0, 0), (0, 0, 0), (0, 1, 0), (0, 2, 1), + (7, 6, 10), (14, 11, 20), (32, 30, 33), (50, 49, 47), + (130, 35, 129), (92, 45, 86), (54, 56, 43), (65, 64, 44), + (77, 73, 46), (100, 74, 63), (124, 75, 81), (143, 61, 100), + (162, 48, 120), (223, 15, 163), (231, 57, 141), (239, 100, 119), + (221, 139, 102), (204, 179, 86), (197, 172, 86), (191, 166, 86), + (142, 159, 166), (130, 117, 149), (119, 76, 132), (77, 58, 81), + (35, 41, 31), (18, 22, 19), (2, 3, 8), (0, 0, 5), + (0, 0, 5), (0, 0, 4), (1, 4, 4), (3, 9, 5), + (44, 45, 31), (86, 82, 57), (110, 96, 80), (135, 110, 103), + (223, 204, 200), (238, 225, 219), (253, 246, 238), (199, 218, 182), + (145, 191, 126), (149, 197, 109), (153, 203, 92), (160, 189, 73), + (142, 168, 95), (85, 117, 78), (45, 76, 53), (5, 36, 28), + (2, 21, 14), (0, 6, 0), (0, 4, 0), (0, 2, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 1, 1), (7, 3, 4), (33, 20, 0), + (121, 45, 11), (129, 49, 14), (138, 54, 18), (117, 58, 26), + (97, 62, 34), (82, 50, 29), (68, 39, 25), (12, 7, 4), + (13, 0, 2), (3, 0, 4), (10, 10, 15), (17, 20, 27), + (38, 47, 23), (59, 74, 19), (98, 104, 66), (121, 148, 81), + (186, 199, 119), (204, 210, 113), (222, 222, 108), (213, 198, 106), + (204, 175, 105), (243, 136, 56), (171, 99, 74), (169, 35, 86), + (138, 17, 112), (105, 49, 26), (52, 31, 13), (0, 14, 0), + (0, 10, 0), (0, 6, 0), (3, 3, 11), (11, 50, 55), + (8, 109, 105), (89, 122, 99), (170, 135, 93), (188, 125, 104), + (207, 116, 115), (220, 138, 124), (220, 130, 165), (255, 211, 214), + (255, 222, 208), (224, 135, 67), (199, 102, 37), (174, 70, 7), + (164, 54, 17), (131, 50, 5), (85, 64, 0), (43, 33, 0), + (0, 3, 0), (0, 2, 0), (0, 1, 0), (0, 1, 0), + (0, 1, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (3, 3, 3), (6, 3, 7), (10, 3, 11), (50, 43, 35), + (82, 76, 54), (76, 123, 69), (42, 136, 22), (43, 113, 14), + (38, 97, 3), (10, 30, 2), (1, 3, 0), (1, 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), + (1, 0, 0), (3, 0, 0), (7, 7, 0), (32, 36, 3), + (92, 112, 15), (109, 138, 56), (162, 129, 58), (170, 150, 1), + (150, 89, 22), (149, 67, 56), (89, 30, 24), (31, 0, 2), + (5, 0, 3), (1, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 1, 0), (9, 7, 0), (65, 37, 15), (107, 74, 41), + (170, 120, 61), (186, 163, 67), (173, 160, 82), (131, 118, 84), + (79, 75, 74), (14, 25, 29), (3, 0, 11), (1, 0, 8), + (0, 0, 4), (0, 0, 4), (0, 0, 2), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (3, 0, 0), + (8, 3, 0), (25, 0, 0), (91, 22, 25), (154, 32, 81), + (157, 7, 45), (147, 24, 6), (171, 25, 12), (177, 38, 7), + (245, 0, 0), (209, 14, 12), (185, 24, 58), (233, 4, 107), + (244, 23, 152), (253, 79, 166), (246, 94, 155), (249, 74, 81), + (249, 76, 72), (240, 95, 90), (199, 112, 69), (163, 124, 85), + (81, 94, 76), (27, 76, 93), (16, 82, 96), (60, 71, 54) + ), + +// 268 Apophysis-040427-51ReachMoon +((140, 144, 33), (114, 88, 29), (73, 79, 38), (32, 70, 47), + (32, 51, 34), (32, 32, 22), (42, 32, 20), (52, 33, 19), + (103, 76, 29), (141, 113, 28), (180, 150, 28), (191, 164, 32), + (203, 178, 36), (191, 169, 35), (180, 160, 35), (166, 143, 34), + (152, 127, 34), (76, 35, 53), (83, 52, 43), (90, 70, 33), + (110, 92, 34), (131, 114, 36), (146, 124, 38), (161, 135, 40), + (192, 143, 41), (205, 142, 39), (218, 141, 37), (181, 130, 33), + (144, 119, 29), (136, 109, 30), (129, 100, 32), (115, 80, 22), + (108, 77, 22), (52, 35, 27), (56, 29, 34), (60, 23, 41), + (64, 24, 47), (69, 26, 54), (68, 27, 55), (67, 28, 57), + (66, 29, 60), (62, 20, 59), (58, 12, 59), (58, 11, 58), + (59, 10, 57), (59, 10, 57), (60, 11, 58), (60, 11, 58), + (60, 11, 58), (59, 13, 60), (59, 29, 47), (59, 45, 34), + (95, 74, 26), (131, 103, 19), (141, 119, 28), (152, 136, 38), + (183, 163, 38), (176, 156, 36), (169, 149, 34), (142, 122, 33), + (116, 96, 33), (103, 85, 34), (90, 75, 36), (39, 78, 51), + (33, 97, 125), (103, 143, 93), (66, 100, 91), (29, 58, 90), + (29, 53, 86), (29, 49, 82), (25, 39, 68), (47, 14, 59), + (46, 13, 58), (51, 14, 45), (56, 15, 33), (51, 14, 21), + (47, 14, 9), (47, 14, 9), (47, 14, 9), (56, 31, 9), + (54, 31, 17), (59, 34, 14), (60, 41, 22), (61, 48, 31), + (66, 53, 34), (71, 59, 37), (96, 87, 48), (126, 117, 60), + (122, 115, 60), (104, 87, 38), (87, 60, 17), (78, 53, 14), + (70, 46, 12), (55, 36, 22), (57, 24, 45), (66, 27, 54), + (69, 26, 54), (69, 26, 54), (63, 24, 54), (57, 22, 55), + (58, 16, 55), (60, 11, 56), (59, 10, 57), (55, 11, 60), + (54, 12, 60), (56, 11, 57), (59, 10, 55), (57, 11, 48), + (56, 13, 41), (55, 14, 30), (55, 14, 30), (53, 15, 30), + (54, 15, 33), (47, 14, 59), (39, 18, 67), (31, 22, 75), + (28, 32, 95), (26, 43, 87), (36, 36, 88), (50, 35, 78), + (71, 24, 70), (68, 26, 65), (66, 29, 60), (66, 29, 60), + (66, 29, 60), (69, 26, 54), (69, 26, 54), (69, 26, 54), + (69, 26, 54), (55, 27, 52), (55, 27, 52), (55, 27, 52), + (50, 27, 53), (52, 31, 40), (57, 41, 28), (68, 47, 20), + (108, 94, 49), (135, 113, 74), (162, 133, 99), (163, 133, 87), + (164, 133, 76), (147, 136, 54), (168, 144, 36), (186, 156, 32), + (203, 163, 39), (227, 178, 120), (226, 199, 116), (225, 221, 113), + (225, 191, 153), (240, 212, 175), (250, 240, 230), (179, 181, 202), + (163, 157, 133), (150, 140, 141), (137, 123, 149), (123, 109, 98), + (89, 55, 69), (68, 29, 58), (69, 26, 54), (69, 26, 54), + (69, 26, 54), (69, 26, 54), (70, 29, 52), (72, 33, 51), + (87, 71, 48), (123, 118, 54), (165, 152, 40), (191, 184, 34), + (211, 196, 45), (210, 203, 47), (210, 210, 50), (216, 191, 49), + (216, 186, 40), (203, 176, 33), (182, 156, 33), (143, 127, 39), + (104, 93, 47), (74, 35, 53), (69, 26, 54), (69, 26, 54), + (69, 26, 54), (69, 26, 54), (72, 33, 51), (101, 73, 23), + (116, 96, 33), (114, 101, 44), (112, 106, 56), (36, 142, 42), + (30, 98, 97), (23, 61, 100), (36, 56, 81), (53, 36, 80), + (65, 28, 61), (66, 29, 60), (68, 33, 65), (66, 29, 60), + (67, 28, 57), (69, 26, 54), (69, 26, 54), (66, 27, 54), + (56, 27, 55), (51, 14, 58), (47, 9, 58), (53, 11, 59), + (54, 12, 60), (55, 11, 60), (55, 11, 60), (59, 10, 57), + (59, 12, 54), (67, 22, 51), (69, 26, 54), (66, 27, 54), + (56, 26, 52), (51, 14, 58), (55, 25, 51), (53, 30, 50), + (44, 33, 29), (24, 26, 47), (19, 25, 51), (23, 24, 44), + (50, 28, 49), (67, 28, 57), (76, 35, 53), (71, 53, 29), + (76, 50, 13), (64, 40, 12), (53, 23, 31), (60, 12, 52), + (59, 10, 55), (59, 10, 55), (59, 10, 55), (59, 10, 57), + (59, 10, 57), (59, 10, 55), (59, 12, 54), (57, 25, 49), + (57, 22, 44), (57, 22, 44), (57, 24, 45), (51, 31, 42), + (27, 24, 45), (18, 25, 53), (14, 41, 84), (15, 58, 77), + (20, 61, 105), (37, 40, 95), (36, 35, 93), (36, 37, 91), + (37, 38, 92), (48, 35, 89), (53, 30, 74), (52, 30, 51), + (53, 32, 47), (49, 29, 38), (52, 29, 35), (53, 24, 29) + ), + +// 269 Apophysis-040427-51satPhlox +((137, 75, 14), (98, 74, 46), (91, 85, 80), (84, 97, 114), + (64, 79, 96), (44, 61, 79), (36, 57, 78), (28, 54, 77), + (81, 64, 46), (95, 67, 39), (110, 71, 32), (155, 89, 23), + (200, 107, 14), (186, 123, 59), (173, 140, 105), (170, 145, 116), + (168, 150, 128), (179, 219, 255), (164, 205, 244), (150, 192, 234), + (130, 187, 244), (111, 183, 255), (106, 184, 255), (102, 186, 255), + (35, 157, 255), (29, 150, 255), (23, 144, 255), (40, 152, 255), + (57, 160, 255), (61, 156, 248), (65, 153, 242), (55, 158, 253), + (40, 164, 254), (19, 152, 255), (22, 152, 255), (25, 152, 255), + (49, 163, 255), (73, 175, 255), (86, 180, 255), (99, 186, 255), + (137, 207, 255), (144, 207, 254), (151, 207, 254), (131, 203, 253), + (112, 199, 253), (108, 192, 254), (105, 185, 255), (80, 158, 233), + (17, 111, 201), (1, 78, 150), (1, 67, 133), (2, 56, 116), + (25, 97, 169), (49, 138, 222), (79, 154, 228), (110, 171, 234), + (210, 232, 253), (232, 243, 253), (255, 255, 253), (249, 251, 254), + (244, 247, 255), (224, 242, 255), (205, 238, 255), (203, 243, 251), + (197, 241, 254), (198, 235, 254), (169, 212, 248), (140, 190, 243), + (129, 175, 222), (119, 161, 201), (110, 118, 131), (96, 80, 65), + (17, 18, 22), (9, 37, 67), (1, 56, 112), (1, 79, 160), + (1, 102, 208), (0, 110, 224), (0, 118, 241), (0, 137, 255), + (2, 125, 254), (1, 100, 202), (1, 74, 152), (2, 49, 103), + (7, 36, 71), (12, 24, 40), (0, 10, 22), (1, 9, 22), + (33, 23, 13), (47, 30, 13), (62, 38, 14), (71, 45, 19), + (80, 53, 24), (110, 67, 25), (112, 67, 25), (114, 67, 23), + (121, 68, 16), (119, 75, 30), (124, 83, 38), (129, 91, 46), + (139, 115, 87), (149, 139, 129), (118, 136, 150), (109, 144, 174), + (71, 114, 156), (76, 107, 138), (82, 100, 120), (89, 92, 96), + (97, 85, 73), (94, 70, 42), (106, 68, 23), (77, 51, 24), + (61, 30, 1), (31, 15, 0), (24, 11, 0), (17, 8, 1), + (9, 4, 0), (0, 0, 0), (0, 0, 0), (1, 1, 1), + (0, 17, 43), (8, 44, 84), (16, 71, 125), (15, 85, 154), + (15, 100, 183), (10, 111, 215), (9, 133, 255), (35, 133, 232), + (68, 150, 234), (85, 145, 207), (88, 136, 185), (92, 128, 164), + (92, 117, 139), (55, 63, 74), (37, 36, 34), (18, 15, 10), + (2, 1, 0), (1, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (7, 4, 0), (12, 8, 0), (34, 17, 1), + (50, 26, 0), (89, 60, 30), (93, 70, 45), (98, 80, 60), + (113, 102, 98), (98, 112, 123), (94, 110, 125), (99, 98, 96), + (64, 51, 42), (56, 46, 37), (49, 42, 32), (30, 26, 25), + (31, 32, 34), (1, 35, 73), (0, 60, 118), (0, 82, 168), + (0, 105, 214), (0, 139, 255), (18, 145, 255), (36, 152, 255), + (47, 162, 255), (58, 168, 255), (64, 170, 254), (70, 160, 248), + (38, 130, 217), (31, 118, 198), (24, 106, 180), (48, 101, 153), + (62, 97, 129), (60, 65, 69), (77, 51, 24), (66, 31, 1), + (62, 28, 0), (58, 26, 1), (53, 25, 1), (44, 23, 2), + (36, 17, 0), (39, 18, 1), (40, 26, 13), (53, 40, 23), + (58, 63, 69), (58, 67, 78), (58, 71, 87), (43, 82, 123), + (20, 70, 119), (1, 75, 150), (6, 87, 168), (0, 91, 186), + (13, 106, 202), (37, 135, 232), (73, 161, 250), (112, 198, 255), + (144, 216, 254), (181, 225, 254), (187, 236, 253), (189, 234, 253), + (191, 233, 255), (195, 226, 255), (201, 240, 255), (225, 248, 254), + (250, 254, 255), (224, 240, 255), (206, 231, 253), (183, 222, 255), + (146, 208, 255), (102, 169, 237), (33, 127, 223), (0, 102, 205), + (3, 82, 161), (14, 56, 98), (30, 47, 63), (14, 17, 22), + (0, 8, 21), (1, 4, 13), (1, 4, 13), (0, 7, 15), + (10, 20, 30), (19, 52, 85), (35, 92, 147), (35, 107, 181), + (100, 161, 218), (119, 169, 220), (112, 165, 219), (111, 147, 183), + (129, 115, 104), (99, 83, 68), (106, 66, 31), (70, 41, 11), + (64, 30, 2), (59, 28, 0), (64, 31, 0), (83, 45, 6), + (113, 66, 22), (115, 67, 18), (110, 66, 17), (70, 34, 0), + (49, 23, 0), (23, 11, 0), (8, 3, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (7, 3, 0), + (11, 6, 2), (35, 28, 20), (50, 43, 35), (87, 77, 67), + (102, 106, 109), (119, 152, 187), (190, 214, 238), (150, 185, 223) + ), + +// 270 Apophysis-040427-51SnikRchg +((234, 180, 156), (154, 82, 60), (130, 60, 45), (107, 39, 30), + (82, 29, 32), (57, 19, 34), (58, 19, 36), (59, 20, 38), + (102, 56, 66), (146, 87, 75), (191, 118, 85), (191, 119, 87), + (191, 120, 90), (177, 106, 83), (164, 92, 77), (161, 70, 64), + (158, 49, 52), (184, 18, 56), (191, 22, 75), (198, 27, 95), + (206, 64, 130), (215, 102, 166), (202, 122, 153), (190, 142, 140), + (145, 99, 101), (105, 65, 76), (66, 31, 51), (49, 20, 35), + (32, 9, 19), (43, 12, 28), (54, 16, 37), (82, 44, 59), + (133, 75, 74), (209, 131, 95), (226, 154, 104), (243, 178, 114), + (246, 201, 114), (250, 224, 114), (250, 227, 125), (251, 231, 136), + (244, 225, 166), (244, 228, 202), (245, 232, 239), (249, 243, 242), + (254, 255, 245), (252, 250, 228), (250, 246, 211), (243, 238, 182), + (231, 207, 147), (203, 142, 113), (197, 130, 103), (191, 119, 94), + (169, 68, 76), (148, 17, 59), (128, 24, 53), (108, 31, 47), + (42, 11, 17), (38, 9, 14), (34, 7, 12), (67, 9, 26), + (101, 12, 40), (119, 28, 33), (137, 44, 27), (142, 45, 28), + (137, 54, 84), (154, 118, 118), (187, 130, 152), (221, 142, 187), + (221, 134, 185), (222, 127, 183), (242, 129, 149), (204, 112, 125), + (212, 18, 55), (208, 15, 54), (204, 13, 54), (201, 13, 54), + (199, 14, 55), (201, 14, 54), (203, 14, 54), (200, 26, 51), + (173, 84, 52), (161, 66, 48), (172, 45, 50), (183, 24, 52), + (180, 19, 41), (177, 14, 31), (185, 15, 44), (188, 17, 69), + (172, 141, 149), (187, 146, 145), (202, 152, 141), (198, 142, 127), + (194, 133, 114), (196, 120, 96), (185, 88, 79), (161, 31, 69), + (103, 26, 78), (25, 60, 64), (26, 34, 42), (27, 9, 21), + (26, 9, 19), (25, 10, 17), (15, 5, 16), (2, 6, 7), + (4, 13, 22), (12, 11, 21), (20, 10, 21), (20, 8, 22), + (21, 7, 24), (15, 9, 23), (11, 8, 25), (20, 5, 34), + (41, 8, 55), (98, 66, 89), (113, 85, 105), (129, 105, 121), + (155, 125, 135), (99, 129, 181), (88, 142, 170), (100, 155, 176), + (190, 225, 159), (206, 211, 147), (222, 198, 136), (229, 199, 137), + (236, 200, 138), (235, 171, 123), (206, 150, 123), (190, 195, 129), + (197, 233, 161), (168, 218, 241), (163, 217, 240), (159, 217, 239), + (155, 221, 233), (154, 215, 199), (192, 227, 171), (169, 212, 140), + (200, 140, 112), (197, 126, 99), (194, 113, 86), (197, 69, 72), + (200, 25, 58), (201, 16, 47), (198, 16, 41), (192, 15, 35), + (191, 8, 39), (195, 17, 49), (199, 16, 49), (203, 15, 50), + (202, 14, 49), (201, 14, 45), (202, 16, 39), (208, 13, 43), + (220, 24, 62), (218, 29, 68), (217, 35, 75), (209, 96, 82), + (216, 135, 79), (219, 121, 82), (234, 80, 88), (222, 31, 82), + (222, 25, 78), (228, 90, 88), (233, 119, 93), (238, 148, 98), + (246, 163, 111), (243, 157, 122), (238, 195, 140), (252, 214, 165), + (233, 157, 203), (226, 166, 187), (220, 175, 172), (218, 166, 168), + (200, 172, 171), (194, 162, 163), (162, 185, 133), (170, 211, 132), + (183, 218, 150), (210, 232, 167), (231, 202, 222), (224, 240, 253), + (238, 224, 224), (228, 238, 177), (237, 212, 156), (252, 195, 128), + (241, 165, 105), (239, 160, 102), (238, 156, 100), (235, 154, 99), + (233, 147, 98), (203, 126, 100), (160, 97, 90), (107, 72, 78), + (88, 56, 80), (96, 61, 94), (80, 114, 162), (98, 173, 196), + (159, 211, 233), (169, 215, 239), (194, 237, 194), (192, 231, 166), + (204, 228, 152), (192, 227, 171), (187, 225, 244), (176, 227, 246), + (180, 217, 243), (170, 202, 227), (185, 158, 167), (178, 152, 155), + (123, 159, 123), (130, 197, 104), (109, 185, 110), (106, 152, 123), + (99, 172, 187), (109, 213, 206), (133, 216, 234), (142, 217, 238), + (148, 215, 232), (138, 215, 233), (130, 215, 235), (116, 205, 223), + (115, 196, 217), (109, 153, 188), (171, 148, 156), (176, 156, 167), + (163, 211, 163), (151, 216, 186), (154, 224, 232), (154, 225, 243), + (167, 230, 248), (161, 226, 244), (155, 223, 242), (153, 224, 242), + (152, 223, 225), (163, 225, 184), (161, 216, 132), (143, 192, 110), + (116, 140, 104), (108, 77, 83), (111, 54, 61), (96, 47, 32), + (109, 22, 28), (106, 54, 41), (98, 47, 64), (100, 32, 73), + (100, 69, 84), (120, 82, 103), (163, 103, 115), (180, 113, 105), + (180, 130, 97), (198, 131, 102), (204, 139, 101), (205, 131, 94), + (211, 130, 100), (230, 141, 101), (245, 139, 125), (233, 191, 166) + ), + +// 271 Apophysis-040427-51SmwhrDream +((40, 44, 29), (132, 60, 64), (142, 89, 47), (153, 119, 30), + (173, 136, 35), (193, 153, 40), (186, 153, 59), (179, 153, 78), + (193, 153, 118), (188, 139, 90), (183, 125, 62), (173, 91, 31), + (163, 58, 0), (170, 100, 47), (177, 143, 95), (184, 152, 111), + (192, 162, 128), (189, 164, 142), (177, 166, 141), (166, 169, 140), + (159, 167, 144), (153, 166, 148), (157, 162, 143), (161, 158, 139), + (169, 160, 93), (134, 144, 59), (100, 128, 26), (91, 107, 14), + (82, 86, 2), (89, 76, 1), (96, 67, 1), (75, 64, 2), + (64, 64, 2), (63, 49, 2), (71, 48, 1), (79, 47, 0), + (75, 43, 0), (71, 39, 0), (72, 35, 3), (73, 31, 6), + (13, 10, 5), (7, 5, 3), (1, 1, 1), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (1, 0, 0), + (2, 1, 0), (26, 19, 1), (52, 45, 1), (78, 71, 1), + (108, 104, 55), (138, 138, 110), (160, 158, 138), (182, 178, 166), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (252, 230, 204), + (249, 206, 153), (239, 189, 149), (229, 173, 146), (215, 195, 160), + (212, 193, 160), (173, 163, 101), (145, 137, 55), (117, 112, 10), + (124, 104, 5), (131, 97, 0), (140, 103, 12), (143, 124, 32), + (143, 105, 68), (122, 108, 41), (101, 111, 15), (96, 103, 8), + (92, 96, 1), (97, 91, 4), (103, 86, 8), (124, 81, 2), + (136, 67, 0), (171, 73, 2), (161, 88, 11), (151, 103, 21), + (161, 127, 27), (172, 151, 34), (177, 151, 76), (143, 146, 93), + (137, 60, 70), (125, 55, 60), (114, 50, 51), (104, 47, 27), + (94, 45, 4), (69, 51, 5), (46, 34, 12), (27, 39, 1), + (40, 48, 1), (74, 76, 1), (68, 80, 0), (63, 85, 0), + (53, 80, 0), (44, 75, 0), (35, 84, 3), (15, 79, 1), + (28, 46, 0), (31, 61, 6), (34, 76, 12), (39, 78, 10), + (45, 81, 9), (58, 80, 7), (65, 84, 3), (65, 104, 21), + (71, 109, 26), (70, 70, 0), (71, 75, 1), (73, 80, 2), + (137, 125, 25), (102, 104, 7), (72, 86, 0), (47, 61, 0), + (54, 53, 0), (67, 50, 1), (80, 47, 2), (84, 50, 2), + (89, 53, 3), (97, 49, 0), (100, 50, 0), (95, 56, 0), + (80, 64, 5), (83, 77, 0), (85, 88, 0), (87, 99, 1), + (94, 87, 0), (105, 79, 4), (121, 94, 3), (126, 84, 2), + (81, 56, 0), (67, 57, 2), (54, 59, 5), (47, 64, 7), + (41, 69, 10), (40, 80, 9), (39, 95, 30), (24, 98, 73), + (4, 89, 58), (63, 80, 10), (72, 87, 7), (81, 94, 4), + (100, 94, 0), (125, 95, 0), (131, 117, 8), (170, 159, 5), + (195, 173, 12), (199, 176, 39), (203, 180, 66), (185, 167, 85), + (169, 155, 58), (139, 129, 32), (91, 114, 24), (86, 109, 19), + (101, 121, 22), (206, 143, 4), (222, 162, 6), (239, 181, 9), + (219, 203, 6), (180, 167, 9), (129, 124, 4), (97, 100, 0), + (63, 110, 32), (54, 108, 53), (45, 106, 75), (85, 135, 100), + (116, 129, 76), (132, 128, 81), (141, 120, 31), (130, 101, 1), + (163, 111, 2), (190, 121, 0), (201, 117, 1), (221, 102, 0), + (194, 102, 1), (158, 86, 1), (134, 74, 1), (121, 84, 31), + (136, 46, 58), (138, 58, 29), (140, 70, 1), (143, 85, 1), + (179, 106, 1), (228, 153, 10), (255, 181, 20), (253, 197, 22), + (255, 234, 45), (250, 234, 60), (208, 180, 141), (215, 168, 152), + (240, 183, 114), (240, 200, 25), (245, 180, 14), (218, 116, 15), + (175, 99, 3), (141, 97, 2), (140, 97, 5), (148, 105, 1), + (185, 103, 1), (228, 112, 3), (234, 108, 6), (252, 142, 17), + (228, 132, 12), (197, 141, 28), (183, 168, 87), (170, 150, 123), + (163, 156, 138), (139, 152, 124), (140, 134, 72), (161, 131, 19), + (176, 137, 10), (166, 118, 7), (147, 113, 3), (141, 90, 1), + (127, 91, 3), (118, 81, 1), (104, 59, 2), (78, 55, 1), + (31, 38, 0), (7, 30, 1), (0, 4, 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), (1, 3, 0), + (7, 10, 0), (18, 25, 7), (64, 35, 5), (97, 39, 2), + (135, 56, 0), (146, 48, 3), (127, 44, 0), (80, 37, 2), + (60, 7, 13), (24, 12, 0), (8, 1, 0), (2, 1, 0), + (1, 1, 1), (0, 0, 0), (0, 0, 0), (0, 0, 2), + (1, 0, 2), (1, 1, 1), (7, 15, 2), (16, 30, 4) + ), + +// 272 Apophysis-040427-51eyepuzzl +((68, 193, 221), (51, 242, 255), (48, 241, 208), (46, 241, 162), + (43, 246, 96), (41, 251, 30), (25, 223, 32), (9, 195, 34), + (0, 226, 97), (0, 228, 159), (0, 231, 221), (0, 199, 201), + (0, 168, 181), (58, 109, 130), (117, 51, 79), (127, 32, 61), + (137, 14, 43), (198, 7, 50), (217, 19, 46), (237, 31, 43), + (195, 51, 21), (153, 71, 0), (127, 53, 18), (101, 35, 36), + (47, 112, 130), (59, 137, 153), (71, 163, 176), (35, 153, 165), + (0, 143, 154), (2, 123, 144), (5, 104, 135), (45, 68, 112), + (126, 8, 157), (204, 4, 190), (223, 18, 206), (242, 33, 222), + (219, 32, 205), (197, 31, 189), (184, 22, 205), (172, 14, 221), + (138, 11, 216), (144, 7, 187), (151, 3, 159), (155, 23, 110), + (159, 44, 61), (141, 65, 40), (124, 87, 19), (134, 103, 39), + (143, 121, 20), (150, 133, 17), (151, 135, 16), (153, 137, 16), + (149, 133, 15), (146, 129, 15), (144, 127, 15), (143, 125, 15), + (116, 107, 12), (112, 99, 13), (108, 92, 14), (102, 88, 9), + (96, 85, 5), (98, 85, 6), (101, 85, 7), (101, 90, 10), + (107, 92, 7), (107, 90, 12), (115, 93, 12), (123, 97, 13), + (118, 97, 11), (113, 97, 9), (114, 102, 4), (115, 94, 3), + (110, 96, 8), (120, 105, 8), (131, 114, 8), (150, 139, 8), + (169, 164, 8), (163, 174, 4), (158, 184, 0), (135, 221, 28), + (154, 207, 15), (168, 155, 0), (143, 130, 4), (118, 105, 9), + (113, 102, 6), (109, 99, 4), (93, 112, 0), (44, 108, 21), + (11, 174, 121), (26, 159, 109), (42, 145, 98), (61, 137, 68), + (80, 129, 38), (131, 124, 56), (159, 127, 44), (220, 150, 36), + (212, 207, 45), (223, 187, 31), (195, 164, 29), (168, 141, 28), + (164, 142, 32), (161, 144, 36), (158, 137, 20), (158, 138, 17), + (152, 133, 15), (147, 128, 14), (142, 124, 14), (134, 117, 14), + (127, 111, 15), (113, 97, 9), (97, 101, 17), (63, 109, 44), + (16, 136, 74), (0, 136, 103), (1, 138, 74), (3, 141, 46), + (12, 152, 21), (61, 135, 0), (71, 151, 2), (51, 144, 14), + (12, 141, 121), (26, 128, 102), (40, 115, 84), (56, 94, 61), + (72, 73, 39), (99, 90, 11), (102, 87, 6), (103, 88, 5), + (103, 88, 5), (105, 91, 3), (109, 92, 1), (114, 93, 0), + (128, 101, 0), (138, 119, 0), (143, 123, 11), (142, 124, 12), + (124, 104, 15), (107, 125, 31), (90, 146, 47), (87, 150, 64), + (84, 154, 82), (51, 228, 62), (13, 235, 10), (28, 203, 2), + (74, 158, 8), (140, 116, 20), (142, 122, 17), (145, 128, 14), + (149, 129, 14), (144, 127, 13), (142, 124, 14), (122, 101, 18), + (92, 93, 15), (68, 91, 20), (44, 90, 26), (16, 114, 65), + (19, 172, 108), (0, 204, 135), (1, 251, 162), (16, 227, 174), + (17, 211, 138), (56, 212, 17), (53, 189, 8), (51, 166, 0), + (103, 167, 0), (116, 179, 4), (129, 144, 0), (126, 107, 4), + (117, 105, 0), (128, 113, 5), (140, 122, 10), (143, 125, 15), + (144, 127, 13), (144, 126, 16), (137, 118, 15), (125, 104, 21), + (126, 87, 30), (152, 21, 26), (136, 20, 20), (113, 39, 36), + (108, 69, 26), (105, 87, 13), (103, 92, 10), (106, 91, 8), + (105, 86, 9), (105, 86, 8), (105, 86, 7), (106, 91, 6), + (117, 86, 3), (113, 84, 18), (111, 44, 2), (89, 70, 2), + (80, 70, 0), (89, 74, 5), (94, 80, 0), (98, 86, 10), + (80, 80, 6), (50, 80, 8), (12, 125, 0), (29, 137, 17), + (42, 131, 23), (74, 130, 29), (77, 123, 15), (96, 96, 10), + (101, 93, 10), (116, 100, 13), (122, 112, 50), (121, 118, 63), + (88, 129, 147), (55, 165, 192), (95, 153, 255), (44, 77, 193), + (106, 40, 200), (135, 28, 220), (193, 9, 243), (231, 36, 254), + (229, 18, 221), (249, 7, 154), (191, 0, 100), (244, 107, 39), + (251, 138, 42), (250, 226, 12), (250, 255, 38), (219, 255, 51), + (170, 238, 41), (156, 230, 13), (174, 156, 18), (163, 149, 14), + (158, 138, 17), (156, 135, 16), (155, 136, 16), (152, 133, 15), + (150, 135, 10), (146, 141, 15), (150, 133, 15), (135, 124, 9), + (124, 129, 9), (101, 154, 50), (68, 181, 91), (50, 243, 124), + (85, 238, 121), (71, 203, 83), (131, 218, 28), (176, 191, 38), + (209, 185, 37), (195, 185, 113), (200, 188, 114), (225, 126, 157), + (247, 23, 122), (192, 100, 37), (166, 114, 31), (163, 103, 0), + (154, 114, 29), (128, 123, 42), (159, 147, 75), (87, 221, 255) + ), + +// 273 Apophysis-040427-51SpherInBlm +((144, 139, 107), (30, 25, 29), (38, 32, 37), (46, 39, 46), + (44, 43, 51), (43, 47, 56), (41, 50, 56), (39, 54, 57), + (47, 54, 62), (44, 58, 62), (42, 62, 63), (49, 80, 70), + (57, 99, 77), (79, 130, 119), (101, 161, 161), (111, 176, 177), + (121, 192, 194), (139, 224, 219), (132, 218, 207), (125, 212, 195), + (122, 200, 160), (119, 188, 125), (110, 167, 108), (102, 147, 92), + (82, 64, 62), (69, 42, 54), (57, 21, 47), (42, 26, 32), + (28, 32, 17), (28, 31, 17), (29, 31, 17), (27, 21, 9), + (29, 21, 8), (31, 29, 16), (41, 34, 16), (51, 39, 17), + (60, 47, 23), (70, 56, 29), (91, 67, 35), (113, 79, 41), + (130, 113, 85), (167, 119, 86), (205, 126, 87), (197, 137, 85), + (189, 148, 84), (164, 139, 89), (140, 130, 95), (106, 106, 108), + (113, 119, 91), (152, 148, 100), (177, 156, 101), (202, 164, 102), + (206, 156, 101), (211, 149, 100), (197, 144, 99), (184, 139, 98), + (122, 114, 125), (117, 118, 121), (113, 122, 117), (122, 143, 142), + (131, 165, 167), (142, 179, 179), (154, 193, 192), (212, 199, 191), + (229, 237, 213), (138, 218, 215), (128, 192, 198), (119, 167, 181), + (108, 160, 167), (98, 154, 153), (86, 150, 126), (81, 139, 115), + (96, 149, 155), (111, 169, 174), (126, 189, 194), (125, 194, 194), + (125, 200, 195), (125, 203, 189), (125, 207, 184), (177, 217, 154), + (211, 198, 145), (231, 201, 149), (209, 211, 154), (187, 221, 160), + (169, 216, 160), (152, 212, 161), (122, 207, 188), (121, 204, 184), + (76, 117, 119), (56, 89, 80), (37, 62, 41), (34, 49, 30), + (32, 36, 19), (24, 28, 14), (16, 22, 12), (12, 10, 11), + (15, 11, 12), (24, 22, 25), (30, 28, 33), (37, 34, 41), + (37, 35, 42), (38, 37, 43), (36, 36, 38), (23, 23, 25), + (16, 21, 15), (14, 18, 13), (13, 15, 12), (13, 14, 12), + (13, 13, 13), (13, 12, 8), (22, 18, 7), (22, 18, 7), + (17, 17, 7), (12, 11, 7), (12, 11, 7), (12, 11, 7), + (10, 10, 8), (9, 9, 7), (10, 10, 8), (11, 11, 9), + (11, 12, 7), (10, 10, 7), (10, 9, 7), (11, 8, 7), + (12, 8, 7), (12, 8, 7), (14, 8, 8), (14, 8, 8), + (13, 11, 12), (34, 39, 45), (47, 46, 54), (61, 53, 64), + (125, 83, 107), (169, 124, 105), (221, 115, 129), (212, 131, 137), + (199, 178, 125), (174, 192, 141), (150, 206, 157), (141, 216, 179), + (133, 227, 201), (141, 233, 220), (137, 227, 215), (126, 205, 199), + (126, 187, 188), (85, 91, 107), (77, 90, 103), (69, 89, 100), + (54, 80, 81), (56, 73, 81), (56, 66, 76), (54, 64, 74), + (48, 63, 70), (51, 60, 69), (55, 57, 69), (45, 55, 64), + (58, 48, 56), (68, 75, 44), (80, 80, 46), (68, 67, 37), + (64, 64, 36), (55, 53, 64), (51, 58, 67), (47, 64, 71), + (47, 64, 71), (50, 65, 72), (53, 77, 77), (71, 80, 89), + (123, 121, 83), (153, 139, 90), (184, 158, 97), (170, 182, 108), + (142, 196, 147), (107, 178, 148), (82, 128, 126), (69, 102, 109), + (50, 71, 76), (43, 40, 47), (22, 26, 25), (19, 21, 18), + (20, 30, 21), (21, 31, 23), (24, 35, 29), (31, 47, 46), + (61, 75, 86), (69, 95, 104), (77, 116, 123), (102, 161, 159), + (118, 177, 171), (128, 190, 187), (141, 196, 164), (177, 219, 156), + (202, 218, 156), (215, 189, 138), (220, 188, 137), (216, 186, 134), + (209, 182, 135), (200, 176, 116), (204, 170, 98), (196, 172, 112), + (165, 145, 147), (124, 165, 133), (109, 167, 129), (90, 137, 103), + (71, 113, 77), (64, 110, 84), (72, 113, 81), (79, 116, 83), + (85, 131, 105), (100, 160, 160), (112, 194, 171), (118, 191, 162), + (104, 177, 147), (88, 135, 101), (56, 85, 83), (47, 57, 66), + (31, 41, 43), (21, 31, 20), (18, 28, 19), (15, 15, 7), + (13, 12, 8), (16, 12, 13), (22, 18, 19), (23, 29, 17), + (27, 44, 28), (30, 51, 36), (31, 50, 44), (39, 48, 55), + (47, 46, 54), (51, 42, 47), (52, 52, 40), (67, 60, 32), + (49, 51, 30), (33, 50, 44), (37, 61, 48), (39, 70, 52), + (50, 78, 55), (57, 80, 86), (95, 96, 98), (94, 102, 104), + (97, 90, 108), (65, 79, 90), (59, 56, 67), (48, 61, 70), + (44, 69, 63), (51, 80, 75), (62, 94, 93), (80, 133, 115), + (116, 173, 164), (147, 196, 175), (186, 231, 172), (213, 213, 201), + (200, 226, 187), (179, 224, 169), (124, 200, 162), (112, 182, 146) + ), + +// 274 Apophysis-040427-51SunrisSpacTim +((13, 63, 152), (76, 120, 215), (111, 148, 198), (147, 176, 182), + (169, 191, 176), (191, 207, 171), (193, 215, 166), (195, 223, 162), + (205, 235, 149), (219, 242, 138), (233, 249, 127), (234, 232, 119), + (235, 216, 111), (236, 235, 115), (237, 255, 119), (241, 246, 115), + (246, 238, 111), (236, 169, 64), (219, 158, 63), (202, 148, 62), + (177, 131, 68), (153, 114, 75), (138, 113, 100), (123, 112, 126), + (120, 159, 224), (123, 161, 231), (126, 164, 239), (128, 160, 213), + (131, 156, 187), (112, 139, 177), (94, 123, 167), (135, 110, 79), + (154, 129, 62), (176, 159, 115), (173, 181, 150), (170, 203, 186), + (154, 187, 199), (139, 171, 212), (140, 174, 208), (142, 177, 205), + (169, 201, 212), (161, 198, 199), (154, 195, 187), (155, 176, 170), + (157, 158, 153), (166, 144, 124), (175, 131, 96), (170, 120, 59), + (186, 122, 24), (128, 76, 0), (119, 67, 0), (111, 59, 1), + (100, 53, 16), (90, 47, 31), (84, 65, 58), (79, 83, 86), + (43, 87, 182), (62, 111, 212), (82, 136, 242), (96, 144, 239), + (110, 152, 236), (114, 153, 235), (118, 155, 235), (125, 164, 223), + (127, 167, 218), (161, 195, 207), (186, 195, 165), (212, 195, 123), + (221, 189, 94), (230, 183, 65), (227, 169, 59), (221, 154, 47), + (195, 132, 26), (181, 119, 13), (168, 107, 0), (167, 105, 0), + (167, 103, 0), (157, 97, 7), (148, 92, 15), (131, 104, 61), + (168, 133, 93), (189, 221, 154), (204, 236, 138), (219, 252, 122), + (233, 251, 118), (248, 250, 115), (243, 230, 90), (245, 193, 84), + (229, 167, 56), (207, 154, 60), (185, 142, 64), (163, 133, 63), + (141, 125, 63), (128, 112, 96), (93, 105, 155), (49, 99, 184), + (60, 104, 199), (77, 121, 216), (79, 123, 218), (81, 125, 220), + (78, 122, 217), (75, 119, 214), (74, 118, 213), (72, 118, 212), + (53, 94, 184), (65, 84, 137), (78, 74, 91), (82, 59, 68), + (87, 45, 46), (66, 27, 58), (56, 14, 54), (47, 12, 52), + (38, 16, 98), (106, 91, 88), (114, 94, 89), (123, 98, 91), + (130, 125, 106), (143, 151, 153), (147, 169, 180), (143, 169, 184), + (145, 124, 105), (162, 133, 91), (180, 142, 77), (194, 161, 72), + (208, 181, 68), (211, 195, 120), (191, 209, 151), (183, 206, 164), + (142, 194, 172), (159, 171, 69), (171, 166, 64), (183, 161, 60), + (210, 163, 55), (205, 141, 33), (187, 125, 14), (177, 114, 9), + (124, 77, 9), (94, 53, 34), (64, 29, 59), (49, 18, 67), + (34, 7, 76), (2, 30, 93), (7, 14, 105), (0, 32, 130), + (4, 47, 141), (44, 88, 183), (55, 99, 194), (67, 111, 206), + (82, 124, 208), (94, 139, 240), (111, 153, 239), (81, 129, 205), + (107, 97, 85), (110, 96, 69), (114, 95, 53), (126, 75, 18), + (110, 60, 1), (96, 47, 0), (81, 29, 18), (81, 38, 29), + (72, 43, 29), (93, 42, 21), (97, 47, 15), (102, 53, 10), + (111, 61, 10), (123, 73, 4), (141, 85, 0), (161, 99, 0), + (150, 93, 3), (146, 85, 4), (142, 78, 6), (120, 68, 10), + (83, 43, 33), (57, 38, 60), (9, 34, 116), (17, 61, 156), + (16, 64, 162), (21, 65, 160), (22, 66, 161), (20, 64, 159), + (19, 56, 136), (29, 36, 106), (47, 45, 82), (56, 46, 83), + (85, 46, 31), (95, 53, 21), (106, 60, 11), (130, 77, 7), + (144, 87, 6), (147, 97, 2), (156, 99, 0), (162, 102, 0), + (156, 97, 0), (153, 97, 2), (142, 92, 3), (136, 103, 10), + (145, 95, 46), (135, 101, 73), (105, 96, 79), (84, 98, 124), + (67, 102, 170), (54, 101, 193), (49, 102, 208), (49, 93, 188), + (43, 87, 182), (21, 83, 202), (14, 78, 214), (2, 58, 181), + (22, 66, 161), (24, 71, 163), (41, 75, 165), (75, 73, 122), + (102, 83, 85), (104, 75, 57), (112, 80, 29), (94, 71, 19), + (91, 47, 22), (84, 42, 26), (81, 44, 26), (84, 46, 27), + (98, 53, 32), (127, 74, 58), (138, 103, 81), (132, 115, 97), + (132, 127, 89), (130, 117, 82), (117, 110, 82), (119, 100, 44), + (128, 72, 25), (103, 49, 15), (78, 41, 35), (62, 27, 57), + (61, 55, 69), (110, 66, 57), (124, 85, 54), (133, 104, 88), + (118, 105, 123), (100, 134, 198), (101, 143, 225), (111, 155, 228), + (127, 164, 190), (145, 166, 161), (179, 149, 87), (206, 160, 62), + (216, 152, 44), (202, 138, 30), (192, 128, 18), (183, 125, 17), + (192, 128, 30), (201, 137, 31), (212, 148, 42), (219, 151, 42), + (214, 146, 35), (204, 141, 10), (162, 124, 41), (186, 134, 25) + ), + +// 275 Apophysis-040427-51synaps +((170, 150, 97), (201, 224, 56), (223, 239, 55), (246, 255, 54), + (246, 255, 66), (246, 255, 78), (231, 247, 70), (216, 239, 63), + (185, 180, 54), (202, 193, 60), (219, 206, 66), (229, 220, 87), + (239, 235, 109), (241, 222, 90), (243, 210, 71), (217, 192, 65), + (192, 175, 59), (204, 51, 71), (210, 27, 107), (216, 3, 143), + (206, 43, 105), (197, 84, 68), (193, 125, 77), (190, 167, 87), + (184, 195, 65), (200, 208, 79), (217, 222, 93), (234, 234, 111), + (252, 247, 129), (247, 242, 133), (242, 237, 137), (204, 209, 83), + (154, 202, 6), (78, 168, 55), (87, 146, 38), (97, 124, 21), + (109, 125, 27), (121, 126, 34), (124, 122, 33), (128, 118, 33), + (150, 167, 65), (188, 193, 83), (226, 219, 102), (237, 236, 164), + (248, 254, 226), (249, 254, 240), (251, 255, 255), (255, 251, 255), + (250, 253, 244), (209, 200, 193), (178, 177, 175), (147, 155, 158), + (153, 114, 118), (159, 74, 79), (159, 80, 82), (160, 86, 85), + (112, 68, 93), (133, 34, 104), (155, 0, 116), (182, 0, 140), + (210, 0, 164), (223, 5, 172), (236, 10, 180), (252, 20, 228), + (246, 8, 241), (238, 7, 173), (246, 17, 123), (254, 27, 73), + (248, 17, 50), (243, 7, 27), (235, 6, 37), (229, 36, 91), + (225, 183, 219), (230, 210, 227), (236, 238, 235), (224, 192, 236), + (213, 147, 237), (217, 118, 219), (221, 90, 202), (202, 33, 186), + (189, 52, 158), (167, 156, 170), (172, 171, 183), (177, 187, 197), + (191, 192, 202), (205, 197, 208), (218, 164, 213), (193, 168, 163), + (200, 119, 125), (195, 76, 144), (190, 33, 164), (197, 18, 163), + (205, 4, 162), (217, 0, 145), (198, 0, 149), (197, 0, 134), + (192, 9, 65), (132, 21, 2), (94, 19, 20), (57, 18, 39), + (51, 14, 40), (46, 11, 41), (22, 13, 34), (47, 28, 50), + (32, 37, 75), (32, 31, 76), (33, 26, 77), (40, 21, 87), + (48, 17, 97), (90, 22, 83), (79, 48, 66), (47, 82, 62), + (33, 97, 73), (135, 101, 76), (157, 99, 78), (179, 98, 81), + (184, 155, 95), (203, 154, 122), (174, 151, 97), (130, 109, 54), + (71, 42, 34), (52, 26, 31), (33, 10, 28), (26, 5, 26), + (20, 0, 25), (42, 11, 0), (52, 36, 13), (94, 57, 5), + (68, 72, 13), (58, 86, 2), (56, 75, 15), (54, 64, 29), + (24, 81, 0), (32, 113, 8), (22, 81, 0), (15, 58, 30), + (71, 41, 77), (98, 48, 101), (126, 55, 125), (148, 43, 136), + (171, 32, 147), (176, 10, 144), (169, 18, 125), (139, 71, 94), + (154, 73, 70), (169, 40, 35), (152, 26, 55), (135, 12, 75), + (177, 0, 129), (211, 8, 188), (241, 32, 211), (255, 41, 249), + (255, 46, 234), (242, 34, 215), (229, 23, 196), (231, 1, 161), + (222, 10, 146), (248, 11, 57), (251, 5, 26), (249, 29, 15), + (212, 18, 27), (183, 0, 107), (191, 0, 135), (199, 0, 164), + (198, 9, 171), (203, 23, 172), (175, 41, 166), (152, 66, 127), + (90, 69, 52), (66, 55, 52), (42, 42, 52), (36, 60, 60), + (64, 72, 85), (71, 48, 94), (99, 51, 99), (110, 31, 96), + (113, 28, 147), (127, 23, 122), (150, 4, 105), (163, 0, 116), + (171, 0, 101), (209, 9, 48), (215, 1, 25), (179, 16, 35), + (110, 77, 68), (109, 83, 66), (109, 89, 64), (161, 94, 39), + (172, 142, 18), (145, 126, 57), (141, 86, 83), (170, 13, 120), + (200, 11, 140), (211, 8, 159), (240, 34, 179), (240, 29, 184), + (231, 30, 188), (193, 51, 173), (152, 102, 139), (132, 138, 102), + (80, 162, 122), (43, 120, 150), (45, 108, 97), (37, 79, 93), + (68, 50, 74), (89, 44, 64), (129, 13, 52), (163, 0, 15), + (168, 1, 8), (161, 7, 7), (158, 1, 30), (136, 0, 81), + (140, 22, 116), (148, 76, 140), (123, 123, 161), (93, 181, 185), + (140, 219, 214), (82, 245, 242), (66, 173, 229), (94, 185, 176), + (113, 153, 82), (180, 154, 93), (198, 167, 100), (199, 186, 94), + (213, 187, 126), (240, 217, 147), (211, 155, 138), (151, 125, 134), + (112, 113, 97), (97, 97, 97), (89, 92, 107), (138, 103, 127), + (185, 101, 134), (201, 124, 144), (240, 85, 189), (222, 30, 193), + (189, 20, 171), (174, 0, 156), (151, 0, 118), (112, 4, 105), + (92, 28, 65), (65, 28, 36), (53, 34, 66), (67, 81, 46), + (92, 83, 54), (107, 70, 62), (113, 28, 93), (104, 17, 86), + (76, 6, 69), (53, 22, 56), (66, 47, 33), (80, 56, 30), + (93, 72, 53), (117, 94, 78), (154, 115, 58), (196, 125, 93) + ), + +// 276 Apophysis-040427-51StPeacocl +((18, 8, 193), (33, 37, 48), (45, 21, 35), (58, 5, 23), + (101, 9, 34), (144, 13, 45), (161, 6, 52), (179, 0, 60), + (230, 13, 21), (235, 6, 11), (241, 0, 2), (237, 3, 4), + (234, 6, 7), (237, 46, 13), (241, 86, 20), (232, 95, 37), + (224, 104, 54), (194, 162, 79), (169, 188, 42), (144, 214, 6), + (110, 159, 9), (76, 105, 13), (57, 79, 13), (39, 54, 13), + (10, 4, 0), (5, 2, 0), (0, 1, 0), (0, 2, 0), + (0, 4, 0), (8, 6, 0), (16, 9, 1), (41, 17, 33), + (38, 9, 149), (27, 68, 192), (39, 55, 118), (52, 43, 44), + (49, 58, 33), (46, 73, 22), (53, 70, 20), (61, 67, 19), + (109, 80, 14), (131, 95, 35), (154, 111, 56), (125, 103, 80), + (97, 96, 104), (101, 94, 125), (106, 93, 147), (127, 44, 134), + (74, 4, 137), (0, 16, 224), (28, 13, 223), (56, 10, 222), + (65, 54, 234), (75, 99, 247), (75, 78, 205), (76, 57, 164), + (82, 30, 69), (120, 26, 47), (158, 22, 26), (185, 16, 20), + (213, 10, 14), (220, 7, 13), (228, 4, 12), (228, 3, 9), + (248, 1, 9), (245, 1, 3), (238, 6, 8), (232, 12, 14), + (227, 35, 19), (222, 59, 24), (239, 96, 40), (242, 116, 66), + (218, 166, 212), (193, 116, 189), (169, 67, 167), (147, 79, 114), + (126, 91, 61), (103, 75, 48), (81, 59, 36), (60, 54, 38), + (57, 61, 11), (17, 40, 0), (10, 21, 0), (3, 3, 0), + (2, 2, 0), (1, 1, 1), (8, 0, 0), (31, 0, 0), + (79, 0, 4), (123, 0, 2), (167, 0, 0), (173, 2, 4), + (179, 4, 9), (213, 10, 16), (202, 52, 15), (201, 98, 55), + (169, 146, 50), (221, 85, 71), (238, 135, 65), (255, 185, 60), + (254, 192, 53), (253, 199, 47), (247, 140, 12), (229, 95, 22), + (131, 58, 26), (88, 45, 14), (46, 32, 3), (43, 40, 1), + (41, 48, 0), (22, 52, 0), (36, 80, 5), (52, 137, 80), + (54, 205, 108), (53, 235, 186), (61, 173, 171), (70, 111, 157), + (98, 95, 90), (126, 31, 71), (168, 5, 52), (181, 1, 64), + (198, 5, 10), (206, 2, 5), (214, 0, 0), (201, 15, 0), + (188, 30, 0), (162, 50, 10), (169, 94, 0), (168, 131, 17), + (158, 125, 22), (89, 153, 41), (61, 160, 20), (34, 167, 0), + (59, 181, 60), (101, 184, 92), (70, 181, 113), (75, 220, 187), + (123, 150, 117), (141, 120, 83), (160, 91, 50), (152, 90, 57), + (144, 90, 64), (132, 89, 54), (95, 87, 51), (82, 109, 64), + (54, 109, 70), (96, 102, 0), (121, 94, 3), (147, 86, 6), + (177, 32, 5), (206, 10, 0), (215, 2, 0), (225, 0, 1), + (227, 0, 9), (224, 3, 7), (221, 7, 5), (199, 29, 0), + (220, 61, 5), (240, 74, 0), (239, 74, 29), (255, 82, 14), + (255, 108, 14), (224, 82, 10), (221, 86, 15), (218, 91, 20), + (192, 107, 26), (181, 70, 24), (160, 83, 27), (152, 58, 33), + (76, 5, 11), (70, 5, 5), (65, 6, 0), (47, 0, 0), + (41, 14, 0), (38, 16, 3), (28, 16, 0), (36, 26, 14), + (26, 37, 23), (53, 55, 5), (52, 52, 0), (59, 47, 5), + (56, 46, 11), (68, 24, 25), (81, 55, 40), (121, 59, 36), + (210, 30, 104), (212, 17, 142), (215, 4, 181), (144, 18, 153), + (105, 32, 166), (120, 0, 156), (92, 2, 125), (57, 20, 74), + (53, 4, 25), (106, 0, 14), (138, 0, 7), (158, 0, 0), + (170, 8, 19), (151, 6, 9), (135, 12, 15), (122, 60, 13), + (109, 51, 14), (101, 49, 0), (69, 34, 0), (74, 66, 4), + (76, 77, 11), (60, 109, 30), (52, 107, 68), (54, 83, 61), + (42, 78, 42), (60, 87, 20), (56, 61, 5), (19, 31, 21), + (7, 0, 7), (1, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 1, 0), (1, 0, 0), + (3, 0, 0), (20, 0, 0), (45, 2, 11), (59, 32, 73), + (124, 19, 75), (118, 0, 109), (92, 6, 117), (96, 19, 101), + (102, 42, 104), (99, 77, 63), (131, 88, 45), (112, 97, 38), + (91, 88, 37), (53, 80, 61), (72, 70, 58), (113, 79, 44), + (137, 62, 22), (200, 84, 25), (207, 69, 7), (219, 68, 0), + (216, 80, 22), (205, 82, 48), (222, 60, 81), (182, 81, 63), + (162, 106, 69), (148, 83, 61), (174, 53, 70), (185, 14, 23), + (190, 3, 10), (193, 5, 6), (181, 0, 7), (175, 0, 0), + (171, 0, 0), (147, 0, 0), (87, 16, 34), (131, 5, 27) + ), + +// 277 Apophysis-040427-51TmplWatrs2 +((58, 31, 10), (30, 12, 2), (33, 29, 15), (37, 46, 29), + (47, 48, 28), (58, 50, 27), (60, 55, 26), (63, 60, 25), + (104, 56, 16), (139, 64, 20), (175, 73, 25), (199, 39, 12), + (224, 5, 0), (182, 26, 3), (141, 48, 7), (125, 57, 10), + (110, 67, 14), (102, 61, 29), (83, 40, 15), (65, 20, 1), + (61, 10, 7), (57, 0, 13), (54, 2, 8), (52, 4, 4), + (23, 0, 8), (25, 5, 4), (28, 11, 1), (43, 16, 2), + (59, 22, 4), (75, 36, 7), (92, 50, 10), (127, 51, 15), + (132, 70, 29), (133, 89, 40), (133, 95, 47), (133, 102, 55), + (139, 119, 63), (145, 137, 72), (148, 145, 78), (152, 153, 85), + (189, 154, 88), (213, 145, 83), (237, 137, 78), (201, 132, 80), + (165, 127, 82), (156, 119, 79), (147, 111, 77), (120, 91, 61), + (98, 81, 63), (98, 59, 28), (102, 52, 18), (106, 46, 9), + (117, 64, 21), (128, 82, 33), (132, 84, 34), (137, 87, 36), + (144, 105, 50), (137, 115, 60), (131, 126, 70), (140, 124, 67), + (149, 123, 64), (155, 124, 63), (161, 125, 63), (150, 110, 49), + (153, 98, 44), (167, 104, 51), (168, 104, 47), (169, 105, 44), + (165, 98, 41), (161, 91, 39), (148, 67, 14), (133, 44, 2), + (110, 0, 5), (91, 0, 3), (72, 0, 1), (61, 6, 1), + (50, 12, 1), (52, 20, 4), (55, 28, 7), (61, 39, 16), + (85, 49, 23), (134, 100, 55), (158, 126, 70), (183, 152, 85), + (203, 160, 96), (223, 169, 107), (239, 179, 129), (250, 213, 142), + (236, 166, 107), (213, 136, 80), (190, 107, 53), (181, 100, 46), + (173, 93, 40), (161, 94, 42), (153, 94, 38), (145, 98, 46), + (135, 88, 36), (135, 73, 24), (142, 55, 12), (149, 37, 0), + (142, 22, 2), (135, 7, 4), (130, 8, 3), (131, 47, 13), + (155, 102, 48), (161, 113, 55), (168, 124, 63), (162, 120, 59), + (157, 117, 56), (156, 93, 39), (161, 62, 20), (145, 30, 1), + (108, 3, 0), (81, 31, 20), (78, 43, 24), (76, 56, 29), + (77, 66, 38), (88, 82, 48), (121, 89, 51), (130, 86, 37), + (167, 76, 31), (165, 66, 21), (164, 57, 11), (161, 44, 5), + (159, 32, 0), (155, 52, 9), (157, 61, 19), (158, 62, 20), + (149, 59, 22), (100, 55, 16), (91, 50, 18), (82, 46, 20), + (68, 55, 21), (60, 43, 27), (56, 41, 20), (50, 16, 40), + (15, 0, 55), (31, 0, 30), (47, 0, 6), (59, 0, 4), + (72, 0, 3), (98, 3, 1), (120, 0, 2), (123, 1, 0), + (124, 2, 25), (80, 58, 34), (79, 70, 42), (79, 82, 51), + (87, 90, 59), (113, 99, 54), (126, 104, 54), (141, 102, 43), + (133, 86, 34), (126, 79, 33), (120, 72, 32), (116, 75, 29), + (127, 84, 31), (136, 91, 36), (144, 106, 44), (154, 105, 47), + (173, 109, 47), (198, 146, 73), (190, 127, 62), (183, 108, 51), + (179, 89, 36), (145, 67, 18), (111, 46, 4), (89, 23, 1), + (90, 0, 0), (88, 1, 0), (86, 2, 0), (79, 0, 0), + (76, 12, 2), (71, 13, 1), (70, 14, 1), (85, 39, 5), + (96, 53, 19), (100, 70, 34), (106, 92, 43), (105, 107, 60), + (126, 120, 70), (133, 129, 65), (136, 135, 78), (136, 137, 79), + (124, 127, 70), (122, 123, 69), (121, 119, 68), (95, 88, 78), + (73, 74, 56), (69, 66, 31), (52, 67, 36), (62, 61, 33), + (77, 56, 27), (104, 60, 21), (121, 74, 28), (156, 90, 40), + (179, 102, 46), (223, 127, 77), (240, 168, 110), (227, 204, 186), + (235, 236, 222), (238, 237, 235), (235, 236, 230), (236, 237, 221), + (200, 200, 202), (210, 189, 124), (193, 139, 105), (153, 136, 126), + (130, 101, 85), (123, 99, 87), (122, 102, 75), (111, 103, 64), + (107, 94, 60), (89, 83, 59), (84, 70, 44), (84, 55, 25), + (94, 44, 7), (78, 20, 0), (71, 23, 0), (94, 45, 13), + (116, 74, 26), (133, 93, 57), (139, 118, 75), (172, 142, 106), + (185, 180, 124), (207, 198, 123), (226, 227, 159), (235, 236, 218), + (236, 237, 231), (244, 243, 223), (237, 238, 194), (238, 235, 166), + (234, 235, 159), (236, 217, 149), (232, 199, 132), (221, 172, 105), + (163, 129, 68), (132, 96, 48), (101, 78, 36), (68, 44, 18), + (50, 21, 3), (55, 18, 0), (67, 37, 13), (94, 51, 19), + (124, 97, 50), (149, 150, 92), (156, 176, 105), (186, 199, 130), + (190, 186, 113), (182, 171, 105), (159, 154, 88), (150, 151, 83), + (157, 132, 68), (167, 141, 80), (172, 175, 104), (168, 148, 89) + ), + +// 278 Apophysis-040427-51TeddyScare +((176, 153, 163), (59, 219, 255), (48, 197, 238), (37, 175, 222), + (39, 134, 230), (42, 93, 238), (38, 73, 228), (35, 54, 219), + (38, 111, 216), (41, 137, 215), (44, 164, 214), (38, 181, 212), + (32, 198, 210), (37, 209, 205), (42, 221, 200), (45, 216, 199), + (49, 211, 198), (23, 157, 186), (11, 114, 121), (0, 71, 56), + (0, 40, 32), (0, 10, 8), (0, 9, 8), (0, 9, 8), + (20, 63, 53), (20, 94, 86), (21, 126, 119), (18, 101, 94), + (16, 77, 70), (14, 60, 55), (13, 43, 41), (0, 0, 14), + (1, 3, 2), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 1, 0), (0, 3, 0), (0, 8, 3), (0, 13, 6), + (18, 87, 84), (24, 107, 133), (31, 128, 183), (101, 147, 172), + (171, 166, 162), (184, 161, 103), (198, 156, 44), (201, 181, 32), + (158, 133, 32), (39, 145, 135), (41, 153, 157), (44, 161, 179), + (45, 178, 197), (47, 196, 216), (69, 196, 222), (92, 197, 229), + (179, 183, 218), (117, 173, 227), (55, 163, 236), (45, 190, 224), + (36, 217, 212), (37, 218, 208), (39, 220, 205), (39, 220, 205), + (36, 211, 194), (39, 180, 226), (39, 149, 220), (40, 119, 214), + (37, 89, 216), (35, 59, 219), (42, 37, 228), (35, 54, 219), + (39, 76, 217), (35, 107, 223), (31, 139, 229), (31, 175, 224), + (31, 212, 219), (38, 227, 216), (46, 243, 213), (36, 223, 206), + (37, 215, 201), (38, 175, 217), (34, 165, 201), (30, 155, 185), + (28, 165, 182), (26, 175, 179), (28, 174, 174), (29, 145, 136), + (30, 147, 131), (21, 111, 99), (13, 76, 68), (10, 60, 60), + (7, 44, 53), (19, 7, 17), (3, 1, 4), (0, 0, 2), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (1, 0, 2), + (24, 0, 22), (29, 16, 67), (35, 32, 113), (28, 34, 160), + (22, 36, 207), (35, 54, 219), (31, 58, 211), (35, 61, 208), + (51, 24, 139), (19, 0, 21), (10, 0, 13), (1, 0, 5), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 1, 0), + (0, 2, 0), (0, 6, 3), (0, 10, 9), (0, 45, 45), + (19, 80, 75), (17, 173, 162), (23, 189, 175), (30, 205, 188), + (36, 199, 196), (29, 167, 154), (29, 133, 126), (16, 69, 61), + (1, 5, 4), (0, 2, 2), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 2, 4), (0, 1, 10), (0, 0, 16), + (0, 35, 51), (26, 62, 136), (18, 80, 203), (45, 112, 219), + (145, 130, 135), (166, 92, 150), (188, 54, 165), (195, 34, 189), + (192, 38, 210), (174, 36, 183), (142, 20, 141), (56, 3, 59), + (32, 0, 36), (22, 5, 23), (5, 3, 8), (1, 1, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 2), (0, 1, 4), (0, 2, 6), (4, 14, 13), + (7, 52, 55), (33, 114, 141), (24, 135, 191), (28, 109, 198), + (28, 51, 189), (54, 59, 140), (53, 17, 61), (53, 1, 47), + (32, 4, 26), (11, 0, 0), (3, 1, 2), (2, 12, 11), + (9, 51, 47), (21, 115, 89), (27, 151, 125), (19, 160, 144), + (20, 173, 155), (25, 161, 151), (20, 137, 119), (17, 59, 57), + (7, 18, 22), (1, 5, 4), (0, 2, 2), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 2), (0, 4, 7), + (0, 22, 20), (0, 51, 47), (0, 85, 96), (27, 103, 163), + (28, 143, 200), (33, 153, 188), (25, 153, 202), (32, 169, 215), + (36, 161, 215), (26, 150, 212), (26, 134, 222), (25, 123, 212), + (34, 95, 210), (28, 75, 213), (70, 80, 203), (105, 116, 232), + (161, 130, 210), (218, 222, 231), (226, 235, 250), (250, 224, 237), + (193, 79, 255), (203, 27, 222), (199, 28, 218), (191, 33, 214), + (170, 33, 183), (75, 47, 124), (47, 50, 101), (39, 25, 58), + (29, 5, 31), (16, 4, 14), (3, 7, 10), (7, 22, 17), + (8, 61, 53), (19, 123, 114), (32, 163, 158), (33, 202, 181), + (27, 218, 187), (23, 214, 183), (15, 187, 165), (15, 168, 150) + ), + +// 279 Apophysis-040427-51kaosGardenr +((59, 0, 80), (4, 81, 87), (27, 106, 102), (50, 132, 118), + (42, 172, 97), (34, 212, 76), (44, 226, 89), (55, 240, 103), + (83, 241, 94), (128, 244, 117), (174, 247, 140), (209, 242, 72), + (244, 238, 4), (211, 197, 51), (178, 156, 99), (168, 168, 105), + (159, 180, 111), (118, 201, 121), (133, 196, 120), (148, 191, 119), + (159, 164, 109), (171, 137, 99), (175, 120, 94), (179, 103, 89), + (187, 51, 53), (201, 27, 56), (216, 3, 59), (196, 8, 40), + (177, 13, 22), (161, 17, 34), (145, 21, 47), (83, 48, 72), + (4, 0, 173), (0, 5, 40), (0, 2, 20), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 1, 6), (0, 1, 5), (0, 1, 4), (0, 0, 2), + (0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 43, 34), + (0, 111, 17), (39, 201, 79), (75, 203, 97), (112, 205, 116), + (77, 225, 110), (42, 245, 104), (29, 246, 95), (17, 247, 87), + (32, 208, 136), (21, 210, 161), (11, 213, 187), (32, 178, 139), + (53, 143, 91), (85, 136, 82), (118, 129, 73), (126, 120, 60), + (134, 111, 69), (126, 90, 78), (135, 100, 75), (144, 110, 73), + (154, 116, 78), (165, 123, 83), (181, 144, 102), (229, 132, 149), + (249, 161, 235), (249, 148, 224), (249, 136, 214), (204, 153, 164), + (160, 171, 115), (148, 176, 116), (137, 181, 118), (108, 187, 106), + (100, 181, 89), (139, 159, 8), (150, 132, 41), (162, 105, 75), + (182, 128, 71), (202, 152, 67), (255, 137, 109), (232, 145, 138), + (243, 120, 166), (239, 109, 157), (236, 98, 149), (222, 99, 147), + (208, 101, 145), (177, 119, 134), (157, 113, 166), (121, 27, 177), + (137, 4, 181), (116, 27, 45), (131, 13, 22), (147, 0, 0), + (126, 12, 22), (106, 25, 44), (70, 48, 50), (73, 44, 40), + (147, 57, 23), (154, 48, 19), (162, 40, 16), (143, 49, 14), + (125, 58, 13), (85, 91, 5), (22, 64, 0), (55, 111, 20), + (92, 114, 31), (149, 85, 73), (166, 93, 80), (184, 102, 88), + (241, 102, 121), (247, 93, 127), (230, 104, 125), (234, 163, 131), + (200, 184, 133), (157, 190, 118), (115, 196, 103), (103, 205, 89), + (92, 215, 75), (112, 196, 111), (141, 207, 120), (181, 199, 141), + (207, 217, 156), (241, 236, 180), (243, 226, 178), (246, 217, 177), + (233, 174, 156), (243, 120, 166), (255, 114, 164), (243, 102, 154), + (227, 137, 146), (192, 156, 131), (157, 175, 117), (151, 189, 121), + (146, 203, 126), (153, 204, 127), (177, 188, 122), (202, 182, 123), + (216, 152, 142), (196, 124, 102), (174, 113, 86), (152, 103, 70), + (94, 109, 44), (80, 114, 19), (27, 206, 78), (6, 233, 64), + (0, 239, 67), (9, 240, 77), (18, 241, 88), (50, 231, 92), + (68, 200, 81), (81, 205, 81), (99, 176, 82), (120, 178, 93), + (136, 133, 92), (146, 125, 80), (142, 133, 87), (139, 142, 95), + (124, 166, 103), (120, 196, 106), (131, 185, 109), (128, 172, 113), + (121, 107, 106), (119, 91, 95), (117, 76, 84), (175, 47, 36), + (177, 42, 38), (189, 55, 52), (161, 55, 59), (102, 71, 68), + (66, 84, 94), (28, 2, 161), (92, 0, 217), (134, 78, 227), + (120, 106, 193), (175, 125, 137), (177, 140, 134), (154, 100, 98), + (134, 61, 20), (134, 61, 18), (135, 61, 16), (139, 53, 18), + (162, 33, 27), (157, 54, 19), (183, 98, 0), (126, 91, 0), + (42, 40, 0), (8, 10, 9), (0, 3, 0), (3, 0, 2), + (18, 6, 0), (57, 57, 59), (94, 84, 75), (133, 110, 78), + (167, 161, 109), (186, 186, 126), (189, 196, 129), (190, 204, 142), + (232, 198, 153), (231, 189, 165), (209, 171, 126), (173, 155, 115), + (164, 132, 109), (181, 124, 107), (199, 102, 111), (183, 106, 114), + (148, 128, 104), (145, 175, 105), (147, 183, 121), (142, 212, 126), + (152, 233, 141), (159, 255, 154), (174, 252, 153), (155, 247, 120), + (125, 202, 106), (85, 186, 92), (105, 157, 93), (74, 102, 87), + (118, 100, 100), (150, 98, 76), (199, 102, 57), (241, 76, 70), + (222, 42, 43), (186, 8, 84), (202, 12, 164), (137, 110, 103), + (69, 189, 92), (15, 226, 69), (2, 235, 66), (2, 236, 63), + (3, 235, 63), (25, 218, 73), (55, 202, 87), (113, 218, 125), + (179, 232, 160), (222, 247, 153), (242, 240, 165), (243, 236, 168), + (234, 223, 169), (233, 188, 165), (234, 200, 172), (243, 221, 182), + (244, 240, 166), (241, 224, 178), (237, 182, 161), (236, 133, 154), + (232, 94, 143), (221, 100, 141), (190, 132, 131), (179, 157, 107) + ), + +// 280 Apophysis-040427-51Thatway4 +((108, 55, 21), (208, 161, 89), (219, 198, 105), (231, 235, 122), + (235, 215, 156), (240, 195, 190), (236, 177, 193), (233, 159, 196), + (162, 127, 229), (154, 120, 227), (146, 113, 226), (175, 154, 204), + (204, 196, 183), (222, 194, 141), (241, 192, 99), (223, 163, 90), + (206, 135, 81), (134, 91, 46), (129, 75, 39), (124, 60, 33), + (126, 64, 19), (129, 69, 6), (129, 67, 5), (130, 66, 4), + (126, 55, 13), (118, 67, 15), (110, 80, 18), (114, 73, 22), + (118, 66, 27), (131, 78, 32), (144, 91, 37), (166, 96, 34), + (205, 123, 37), (197, 148, 71), (216, 189, 79), (236, 231, 88), + (228, 193, 73), (221, 155, 59), (209, 137, 54), (198, 119, 50), + (135, 65, 29), (109, 51, 16), (83, 37, 4), (48, 24, 10), + (13, 11, 16), (8, 14, 19), (4, 17, 23), (19, 37, 47), + (102, 68, 41), (144, 106, 33), (178, 105, 40), (213, 104, 47), + (196, 100, 34), (179, 97, 21), (166, 84, 13), (153, 72, 6), + (131, 55, 0), (140, 56, 5), (149, 57, 10), (135, 64, 19), + (122, 71, 28), (128, 71, 25), (135, 71, 23), (141, 77, 15), + (136, 68, 3), (145, 65, 0), (140, 49, 0), (136, 34, 0), + (130, 34, 0), (124, 34, 0), (93, 34, 2), (72, 28, 0), + (16, 22, 0), (12, 14, 5), (9, 7, 10), (16, 9, 14), + (24, 11, 18), (32, 15, 14), (40, 20, 11), (88, 37, 0), + (124, 54, 0), (151, 66, 35), (141, 76, 43), (131, 87, 52), + (138, 83, 52), (146, 79, 52), (155, 78, 50), (154, 81, 48), + (118, 68, 35), (119, 62, 32), (120, 56, 29), (125, 49, 24), + (130, 42, 20), (147, 46, 18), (133, 45, 7), (121, 39, 0), + (107, 40, 0), (70, 10, 0), (46, 5, 0), (23, 0, 0), + (22, 0, 5), (21, 0, 10), (2, 0, 19), (4, 6, 21), + (9, 0, 36), (16, 2, 49), (23, 5, 63), (21, 10, 59), + (20, 15, 55), (22, 22, 48), (62, 12, 21), (92, 28, 0), + (116, 34, 0), (95, 12, 0), (86, 6, 0), (78, 0, 0), + (82, 21, 0), (100, 40, 12), (122, 39, 23), (130, 59, 15), + (160, 78, 28), (164, 79, 23), (169, 81, 18), (172, 71, 9), + (176, 62, 0), (177, 74, 15), (216, 111, 45), (229, 114, 57), + (237, 132, 77), (233, 145, 74), (224, 144, 69), (216, 143, 64), + (231, 136, 44), (218, 125, 45), (184, 102, 26), (163, 87, 11), + (116, 63, 0), (97, 62, 10), (79, 61, 21), (50, 45, 29), + (22, 29, 37), (21, 19, 30), (40, 26, 26), (98, 54, 17), + (122, 55, 13), (128, 48, 0), (124, 50, 0), (120, 53, 0), + (106, 46, 0), (103, 52, 9), (105, 46, 14), (113, 47, 13), + (109, 44, 14), (108, 49, 18), (107, 54, 23), (111, 64, 20), + (121, 78, 25), (125, 83, 25), (154, 95, 15), (186, 121, 39), + (202, 132, 60), (220, 131, 63), (227, 137, 68), (234, 143, 73), + (244, 153, 80), (255, 168, 108), (240, 173, 102), (216, 178, 131), + (232, 229, 194), (232, 231, 211), (233, 234, 228), (233, 232, 188), + (216, 203, 169), (209, 211, 189), (231, 225, 239), (240, 226, 241), + (249, 215, 248), (255, 225, 248), (252, 241, 239), (255, 229, 190), + (223, 196, 143), (181, 157, 87), (160, 123, 43), (156, 90, 40), + (152, 73, 30), (152, 75, 25), (153, 78, 20), (140, 76, 28), + (133, 83, 34), (136, 76, 50), (115, 68, 38), (102, 69, 36), + (98, 64, 26), (104, 55, 23), (97, 50, 20), (59, 9, 10), + (32, 6, 9), (25, 6, 0), (42, 6, 0), (51, 23, 0), + (79, 49, 0), (99, 48, 0), (95, 33, 0), (92, 34, 0), + (74, 19, 0), (56, 17, 0), (34, 4, 0), (20, 0, 0), + (18, 0, 0), (0, 11, 0), (14, 13, 0), (17, 7, 5), + (9, 6, 17), (19, 5, 18), (47, 17, 17), (90, 69, 38), + (75, 71, 104), (124, 96, 121), (122, 127, 227), (97, 111, 236), + (117, 94, 244), (82, 47, 235), (67, 36, 95), (77, 9, 84), + (108, 45, 76), (121, 55, 31), (148, 62, 27), (158, 76, 20), + (160, 71, 13), (150, 66, 19), (136, 60, 28), (121, 57, 29), + (123, 60, 27), (142, 64, 18), (168, 80, 34), (187, 106, 61), + (229, 150, 91), (253, 221, 120), (242, 232, 119), (231, 242, 103), + (233, 229, 103), (192, 170, 110), (188, 123, 91), (142, 95, 53), + (121, 70, 49), (96, 72, 28), (93, 62, 16), (50, 24, 9), + (26, 20, 8), (20, 26, 22), (97, 58, 29), (106, 76, 38), + (118, 63, 42), (142, 78, 43), (226, 125, 57), (173, 89, 29) + ), + +// 281 Apophysis-040427-51ThatwayGrn +((79, 66, 13), (83, 51, 0), (100, 55, 0), (118, 59, 0), + (119, 65, 0), (120, 72, 0), (119, 72, 0), (119, 72, 0), + (78, 55, 5), (66, 48, 5), (54, 41, 6), (56, 39, 10), + (58, 38, 14), (70, 61, 16), (82, 85, 18), (74, 109, 39), + (67, 133, 61), (67, 133, 62), (65, 125, 61), (64, 117, 61), + (67, 82, 33), (71, 48, 6), (68, 41, 3), (65, 35, 0), + (70, 53, 1), (69, 95, 25), (69, 137, 50), (67, 144, 51), + (66, 152, 53), (63, 156, 52), (61, 160, 52), (59, 163, 52), + (59, 163, 52), (58, 161, 52), (60, 161, 52), (62, 161, 53), + (61, 160, 52), (61, 160, 52), (61, 158, 52), (62, 157, 53), + (64, 134, 64), (67, 128, 69), (71, 123, 74), (72, 121, 78), + (73, 119, 82), (73, 119, 82), (73, 119, 82), (73, 119, 82), + (73, 121, 79), (68, 148, 53), (66, 150, 53), (65, 153, 53), + (66, 151, 53), (68, 149, 54), (70, 146, 54), (73, 143, 54), + (144, 90, 0), (125, 98, 6), (106, 107, 13), (86, 119, 39), + (67, 132, 66), (67, 131, 70), (68, 131, 74), (71, 129, 79), + (74, 127, 85), (75, 120, 87), (75, 119, 86), (75, 119, 86), + (75, 119, 86), (75, 119, 86), (76, 122, 86), (76, 119, 89), + (75, 119, 86), (68, 121, 82), (61, 124, 79), (62, 132, 69), + (64, 141, 59), (63, 145, 57), (63, 150, 55), (67, 148, 53), + (66, 141, 59), (70, 146, 55), (66, 149, 55), (62, 152, 56), + (63, 154, 54), (64, 157, 53), (61, 160, 52), (61, 160, 52), + (65, 153, 53), (67, 150, 53), (70, 147, 53), (85, 123, 34), + (101, 99, 16), (122, 84, 0), (107, 57, 0), (85, 42, 0), + (60, 32, 0), (53, 34, 1), (70, 38, 1), (88, 43, 2), + (95, 49, 1), (102, 56, 0), (117, 64, 0), (118, 71, 1), + (92, 84, 22), (80, 103, 46), (69, 123, 71), (64, 86, 48), + (60, 50, 25), (45, 32, 16), (37, 28, 11), (32, 18, 7), + (45, 32, 13), (70, 118, 70), (71, 119, 75), (72, 120, 80), + (76, 119, 91), (75, 120, 100), (76, 119, 100), (76, 119, 100), + (75, 122, 86), (115, 115, 45), (155, 108, 4), (158, 114, 3), + (162, 120, 2), (104, 137, 48), (71, 146, 55), (70, 146, 55), + (68, 136, 61), (67, 133, 62), (67, 133, 62), (67, 133, 62), + (67, 126, 68), (70, 120, 69), (109, 69, 17), (127, 82, 0), + (148, 78, 6), (137, 70, 3), (126, 62, 1), (113, 57, 2), + (100, 52, 3), (76, 30, 7), (63, 29, 1), (58, 22, 0), + (54, 21, 2), (61, 28, 0), (66, 30, 2), (72, 33, 4), + (103, 56, 4), (131, 73, 0), (157, 97, 0), (170, 133, 0), + (162, 148, 43), (124, 152, 39), (86, 157, 35), (72, 154, 56), + (66, 154, 52), (65, 156, 53), (65, 156, 53), (64, 155, 52), + (65, 156, 53), (63, 158, 54), (62, 159, 53), (62, 161, 53), + (60, 164, 53), (60, 164, 53), (62, 161, 53), (63, 158, 54), + (66, 152, 53), (67, 148, 53), (69, 145, 54), (106, 118, 32), + (154, 108, 0), (164, 115, 0), (143, 108, 16), (82, 118, 90), + (80, 119, 98), (78, 120, 100), (75, 119, 102), (78, 120, 100), + (79, 119, 95), (75, 119, 86), (71, 120, 75), (62, 70, 19), + (45, 28, 0), (44, 24, 3), (44, 21, 7), (37, 19, 5), + (45, 17, 3), (47, 21, 0), (49, 34, 1), (56, 48, 2), + (74, 54, 0), (98, 57, 1), (123, 59, 0), (128, 69, 0), + (130, 86, 0), (108, 98, 49), (73, 119, 80), (76, 119, 92), + (75, 120, 100), (72, 120, 108), (73, 119, 108), (75, 119, 102), + (76, 119, 100), (76, 119, 91), (73, 119, 80), (71, 120, 75), + (56, 57, 15), (51, 40, 8), (47, 36, 8), (44, 41, 8), + (47, 44, 11), (47, 50, 7), (53, 65, 1), (60, 91, 34), + (71, 120, 75), (75, 127, 89), (75, 134, 90), (71, 129, 79), + (64, 134, 62), (68, 148, 53), (67, 151, 55), (67, 151, 53), + (68, 148, 53), (67, 134, 63), (73, 124, 81), (76, 119, 91), + (79, 119, 95), (78, 120, 98), (80, 119, 98), (80, 119, 98), + (80, 119, 100), (80, 119, 98), (80, 119, 98), (78, 122, 97), + (75, 122, 88), (72, 127, 85), (69, 130, 73), (65, 139, 64), + (68, 148, 53), (68, 148, 53), (68, 141, 59), (70, 133, 62), + (67, 125, 67), (92, 71, 18), (62, 40, 19), (51, 29, 8), + (46, 25, 4), (57, 32, 1), (73, 46, 1), (105, 58, 4), + (131, 80, 1), (154, 99, 0), (178, 160, 62), (170, 124, 2) + ), + +// 282 Apophysis-040427-51TreeLife1 +((199, 144, 17), (41, 30, 44), (89, 62, 36), (138, 94, 29), + (161, 115, 26), (184, 137, 23), (190, 143, 30), (197, 149, 38), + (206, 169, 62), (214, 187, 99), (223, 206, 136), (222, 207, 148), + (221, 209, 161), (207, 169, 114), (193, 129, 68), (191, 133, 53), + (190, 138, 39), (173, 120, 6), (172, 119, 4), (171, 118, 2), + (166, 111, 1), (161, 105, 0), (162, 102, 0), (164, 100, 0), + (148, 76, 0), (142, 68, 0), (137, 61, 0), (131, 43, 0), + (125, 26, 0), (116, 22, 0), (107, 18, 0), (74, 0, 28), + (33, 0, 29), (7, 6, 12), (45, 10, 9), (84, 14, 6), + (106, 30, 3), (129, 47, 0), (137, 60, 0), (146, 74, 0), + (170, 113, 6), (176, 122, 8), (182, 132, 11), (194, 142, 17), + (206, 153, 23), (209, 160, 28), (212, 168, 33), (214, 181, 42), + (228, 189, 50), (238, 212, 65), (240, 213, 68), (243, 215, 72), + (233, 199, 62), (224, 184, 53), (217, 177, 51), (211, 171, 49), + (195, 147, 23), (187, 138, 15), (179, 129, 8), (171, 115, 6), + (164, 101, 4), (159, 94, 2), (155, 88, 1), (149, 77, 1), + (146, 74, 2), (152, 81, 1), (155, 90, 1), (159, 99, 1), + (158, 98, 1), (157, 97, 1), (144, 87, 0), (138, 68, 0), + (116, 69, 0), (116, 65, 0), (117, 61, 0), (121, 52, 0), + (125, 44, 1), (121, 42, 0), (117, 41, 0), (109, 42, 0), + (125, 44, 1), (139, 61, 0), (149, 81, 1), (159, 101, 2), + (164, 108, 4), (170, 116, 7), (177, 124, 10), (182, 132, 11), + (183, 133, 12), (184, 135, 10), (185, 137, 9), (185, 136, 10), + (185, 135, 12), (186, 136, 13), (190, 140, 15), (196, 149, 19), + (208, 162, 25), (221, 180, 40), (224, 184, 44), (228, 189, 49), + (225, 186, 46), (222, 183, 43), (216, 172, 37), (211, 162, 34), + (198, 151, 21), (190, 141, 16), (182, 132, 11), (176, 125, 8), + (171, 118, 6), (160, 100, 2), (148, 76, 0), (138, 64, 0), + (138, 61, 5), (145, 77, 6), (155, 91, 5), (165, 106, 4), + (181, 130, 12), (193, 143, 22), (204, 157, 25), (211, 165, 30), + (211, 167, 32), (206, 159, 35), (201, 151, 38), (195, 145, 27), + (189, 139, 16), (173, 120, 6), (161, 97, 7), (140, 67, 16), + (112, 35, 7), (54, 4, 29), (55, 13, 38), (56, 22, 47), + (32, 29, 36), (49, 35, 52), (43, 47, 85), (80, 52, 103), + (68, 77, 76), (82, 78, 89), (97, 79, 103), (104, 85, 84), + (112, 92, 65), (147, 95, 45), (165, 105, 9), (170, 116, 7), + (182, 132, 11), (192, 142, 17), (196, 147, 20), (200, 153, 23), + (205, 161, 28), (211, 165, 30), (203, 159, 26), (197, 150, 20), + (179, 121, 22), (173, 116, 33), (167, 112, 45), (176, 138, 161), + (165, 153, 203), (168, 156, 206), (171, 158, 228), (201, 201, 227), + (207, 195, 209), (255, 230, 156), (250, 235, 142), (246, 240, 128), + (246, 248, 115), (254, 245, 92), (255, 235, 96), (255, 233, 97), + (239, 202, 59), (237, 201, 58), (235, 200, 58), (237, 198, 59), + (232, 194, 61), (233, 203, 105), (211, 162, 155), (160, 101, 103), + (145, 88, 45), (131, 74, 31), (139, 65, 18), (138, 63, 5), + (137, 61, 0), (134, 63, 1), (134, 63, 1), (137, 62, 0), + (131, 49, 1), (130, 48, 0), (129, 47, 0), (132, 52, 1), + (139, 63, 0), (144, 72, 0), (147, 78, 0), (154, 91, 0), + (161, 101, 3), (164, 109, 8), (160, 125, 0), (173, 124, 3), + (182, 132, 11), (192, 142, 17), (204, 157, 27), (209, 159, 38), + (214, 170, 35), (221, 182, 42), (228, 189, 49), (229, 192, 49), + (231, 194, 53), (232, 193, 53), (227, 188, 48), (222, 181, 41), + (213, 169, 34), (201, 154, 24), (189, 132, 19), (163, 106, 16), + (118, 76, 34), (93, 69, 93), (110, 89, 108), (114, 75, 104), + (128, 70, 50), (153, 94, 24), (168, 116, 6), (173, 122, 7), + (181, 131, 10), (175, 124, 7), (172, 119, 5), (168, 106, 7), + (169, 89, 4), (150, 65, 0), (128, 46, 0), (117, 35, 0), + (109, 28, 0), (88, 0, 0), (65, 0, 26), (33, 0, 27), + (8, 0, 15), (38, 5, 26), (98, 14, 3), (116, 26, 15), + (117, 29, 15), (122, 43, 28), (111, 94, 110), (149, 131, 179), + (159, 145, 180), (131, 112, 134), (158, 97, 113), (167, 99, 38), + (176, 123, 11), (181, 130, 12), (188, 138, 15), (197, 151, 16), + (199, 164, 18), (213, 172, 32), (234, 189, 12), (255, 197, 35), + (240, 201, 44), (229, 190, 50), (220, 176, 41), (210, 161, 32) + ), + +// 283 Apophysis-040427-51TreeLife +((160, 85, 2), (162, 86, 2), (159, 84, 6), (157, 83, 10), + (161, 87, 6), (166, 92, 3), (167, 95, 2), (168, 98, 2), + (164, 90, 3), (157, 83, 2), (150, 76, 1), (144, 69, 0), + (138, 62, 0), (132, 55, 0), (127, 49, 0), (123, 46, 0), + (120, 43, 1), (118, 40, 1), (119, 39, 0), (120, 39, 0), + (123, 44, 0), (127, 49, 1), (130, 53, 1), (134, 57, 1), + (153, 110, 78), (186, 152, 121), (219, 194, 164), (234, 209, 131), + (250, 225, 99), (239, 209, 77), (229, 193, 55), (208, 157, 30), + (169, 98, 8), (134, 57, 1), (124, 48, 0), (115, 40, 0), + (111, 35, 0), (107, 31, 0), (106, 31, 0), (105, 32, 0), + (110, 36, 1), (114, 38, 1), (118, 40, 1), (120, 44, 2), + (123, 49, 4), (128, 52, 2), (133, 56, 0), (139, 64, 0), + (146, 69, 1), (161, 85, 7), (164, 98, 3), (167, 112, 0), + (164, 111, 28), (162, 111, 56), (153, 105, 60), (145, 99, 65), + (162, 97, 17), (154, 83, 13), (146, 70, 10), (133, 57, 5), + (121, 44, 0), (116, 40, 0), (112, 36, 0), (106, 31, 0), + (98, 26, 1), (96, 24, 0), (93, 30, 0), (90, 36, 0), + (95, 34, 0), (100, 32, 0), (111, 37, 0), (120, 43, 1), + (136, 66, 17), (160, 104, 58), (184, 142, 100), (196, 162, 141), + (209, 183, 182), (228, 208, 155), (247, 233, 128), (255, 245, 130), + (252, 238, 116), (253, 236, 104), (250, 233, 104), (248, 230, 104), + (246, 222, 94), (244, 215, 85), (221, 176, 49), (185, 129, 46), + (154, 78, 2), (144, 66, 1), (134, 54, 1), (127, 48, 3), + (121, 43, 5), (118, 39, 6), (113, 42, 14), (111, 35, 9), + (108, 33, 1), (108, 33, 1), (111, 36, 1), (115, 40, 1), + (116, 39, 0), (117, 39, 0), (120, 43, 1), (123, 46, 4), + (132, 55, 0), (133, 57, 0), (135, 59, 1), (134, 57, 0), + (133, 56, 0), (132, 55, 0), (131, 52, 0), (125, 47, 1), + (127, 46, 3), (132, 55, 1), (133, 57, 1), (135, 59, 1), + (140, 65, 0), (141, 71, 0), (141, 82, 0), (141, 72, 0), + (130, 53, 1), (124, 47, 0), (119, 42, 0), (117, 41, 0), + (115, 40, 1), (113, 37, 1), (108, 34, 0), (104, 33, 1), + (105, 32, 0), (108, 33, 1), (108, 33, 0), (109, 34, 0), + (112, 36, 0), (116, 38, 0), (117, 39, 0), (113, 38, 0), + (106, 31, 0), (103, 28, 0), (100, 26, 0), (98, 25, 0), + (97, 25, 1), (97, 25, 1), (95, 28, 2), (98, 26, 1), + (102, 28, 1), (104, 30, 1), (104, 31, 0), (105, 32, 0), + (104, 31, 0), (102, 28, 1), (99, 27, 2), (98, 25, 0), + (96, 24, 0), (95, 23, 0), (95, 23, 1), (96, 24, 0), + (96, 24, 0), (97, 25, 1), (102, 28, 1), (108, 34, 0), + (115, 40, 0), (135, 58, 2), (140, 63, 7), (145, 68, 12), + (151, 76, 9), (156, 101, 60), (177, 134, 81), (202, 169, 152), + (220, 203, 237), (219, 203, 238), (219, 203, 240), (225, 211, 202), + (252, 248, 138), (243, 222, 95), (211, 162, 31), (213, 133, 20), + (189, 115, 20), (164, 93, 3), (155, 79, 1), (148, 75, 0), + (147, 73, 0), (145, 71, 0), (146, 72, 1), (148, 71, 3), + (132, 55, 1), (128, 51, 1), (125, 47, 1), (120, 42, 0), + (118, 40, 1), (116, 41, 1), (115, 43, 0), (119, 42, 0), + (121, 44, 0), (126, 48, 0), (132, 52, 0), (134, 57, 1), + (130, 63, 8), (140, 70, 11), (139, 72, 20), (146, 122, 76), + (198, 164, 136), (207, 180, 189), (207, 182, 204), (211, 190, 199), + (224, 203, 212), (237, 224, 231), (241, 240, 173), (247, 223, 101), + (220, 175, 82), (183, 132, 69), (165, 94, 14), (154, 78, 2), + (141, 63, 0), (126, 50, 0), (118, 40, 1), (108, 33, 1), + (102, 28, 1), (93, 23, 0), (85, 18, 1), (70, 14, 0), + (70, 10, 0), (75, 9, 0), (87, 19, 0), (96, 24, 0), + (103, 29, 0), (110, 36, 0), (118, 41, 0), (127, 49, 1), + (134, 58, 0), (139, 63, 1), (142, 67, 0), (143, 68, 0), + (144, 66, 2), (138, 62, 2), (139, 60, 1), (137, 61, 1), + (135, 59, 1), (134, 58, 0), (137, 58, 1), (141, 59, 0), + (145, 68, 0), (150, 76, 1), (160, 88, 3), (169, 102, 0), + (190, 127, 13), (199, 141, 16), (205, 152, 24), (206, 151, 25), + (200, 136, 28), (176, 107, 14), (163, 88, 7), (150, 72, 8), + (142, 57, 0), (128, 51, 9), (130, 35, 0), (125, 36, 4) + ), + +// 284 Apophysis-040427-51triflwr +((105, 58, 4), (155, 91, 4), (157, 94, 12), (160, 98, 21), + (177, 101, 60), (194, 105, 99), (189, 109, 109), (185, 114, 120), + (148, 101, 21), (96, 61, 17), (44, 21, 13), (22, 11, 6), + (0, 1, 0), (0, 0, 13), (0, 0, 27), (1, 34, 60), + (2, 68, 94), (1, 57, 106), (57, 91, 147), (114, 125, 189), + (129, 153, 202), (145, 181, 215), (158, 195, 213), (172, 210, 211), + (115, 95, 156), (100, 54, 124), (85, 14, 92), (42, 9, 49), + (0, 4, 7), (0, 2, 3), (0, 0, 0), (1, 0, 0), + (6, 0, 0), (113, 36, 10), (128, 65, 5), (143, 94, 1), + (139, 110, 3), (136, 126, 5), (122, 128, 6), (109, 131, 7), + (40, 117, 1), (40, 116, 0), (41, 116, 0), (71, 107, 1), + (102, 99, 2), (102, 83, 4), (102, 68, 7), (115, 74, 20), + (93, 72, 45), (107, 55, 78), (132, 83, 104), (158, 111, 131), + (178, 159, 143), (198, 208, 155), (204, 203, 173), (211, 198, 192), + (179, 147, 158), (178, 137, 142), (178, 127, 126), (171, 140, 144), + (165, 154, 162), (154, 149, 172), (144, 144, 182), (117, 139, 197), + (54, 87, 202), (46, 59, 199), (23, 35, 180), (1, 11, 161), + (0, 28, 138), (0, 46, 116), (0, 50, 113), (7, 55, 129), + (66, 100, 210), (87, 137, 222), (109, 175, 235), (136, 191, 231), + (163, 208, 227), (160, 214, 218), (158, 220, 209), (148, 178, 204), + (128, 116, 162), (54, 45, 174), (38, 52, 128), (23, 59, 83), + (43, 65, 62), (63, 72, 41), (87, 78, 19), (128, 85, 7), + (153, 80, 1), (143, 46, 0), (133, 13, 0), (142, 10, 0), + (151, 7, 0), (172, 0, 23), (140, 0, 37), (136, 15, 4), + (137, 48, 4), (113, 71, 21), (68, 71, 48), (23, 71, 75), + (12, 72, 82), (1, 74, 89), (0, 66, 98), (0, 52, 110), + (80, 23, 126), (100, 42, 116), (121, 62, 106), (134, 65, 94), + (147, 69, 83), (142, 100, 16), (150, 93, 6), (162, 84, 2), + (170, 77, 0), (170, 83, 6), (167, 77, 3), (164, 72, 0), + (144, 56, 18), (129, 15, 25), (114, 13, 43), (124, 0, 62), + (185, 11, 34), (205, 16, 19), (226, 21, 4), (225, 31, 5), + (224, 41, 7), (176, 74, 0), (174, 76, 1), (165, 84, 5), + (152, 92, 6), (102, 95, 41), (70, 85, 42), (39, 76, 43), + (10, 81, 77), (0, 50, 113), (11, 0, 159), (18, 0, 168), + (0, 5, 183), (9, 15, 188), (18, 25, 193), (19, 24, 191), + (20, 23, 190), (0, 30, 136), (1, 60, 104), (22, 79, 72), + (60, 103, 13), (127, 129, 2), (132, 125, 4), (137, 122, 7), + (150, 93, 6), (157, 87, 1), (166, 83, 3), (163, 82, 1), + (150, 69, 6), (135, 56, 16), (120, 43, 27), (113, 27, 76), + (81, 3, 102), (47, 20, 99), (19, 43, 103), (38, 55, 73), + (1, 6, 10), (0, 0, 0), (3, 0, 0), (7, 0, 0), + (68, 59, 28), (108, 69, 4), (139, 103, 6), (136, 120, 7), + (133, 106, 0), (114, 90, 8), (96, 74, 17), (65, 69, 32), + (29, 79, 42), (14, 85, 71), (4, 84, 93), (16, 105, 83), + (6, 107, 49), (1, 108, 26), (1, 110, 19), (42, 122, 37), + (111, 96, 13), (145, 94, 5), (156, 91, 9), (169, 83, 6), + (219, 75, 49), (224, 92, 58), (229, 110, 67), (230, 84, 47), + (228, 70, 7), (176, 76, 0), (173, 81, 6), (188, 96, 71), + (215, 143, 103), (171, 192, 175), (173, 223, 220), (173, 228, 222), + (156, 244, 220), (149, 235, 255), (174, 233, 241), (174, 231, 240), + (178, 226, 238), (198, 202, 240), (203, 198, 228), (194, 230, 220), + (180, 225, 205), (196, 190, 174), (175, 164, 160), (182, 119, 138), + (143, 66, 110), (128, 34, 87), (137, 33, 82), (136, 28, 80), + (150, 30, 57), (167, 36, 68), (152, 93, 25), (169, 83, 6), + (179, 97, 0), (213, 101, 19), (233, 116, 72), (255, 187, 82), + (245, 255, 172), (232, 203, 247), (232, 178, 253), (239, 159, 228), + (221, 199, 201), (215, 169, 153), (228, 121, 75), (223, 120, 19), + (224, 93, 11), (206, 85, 2), (176, 76, 1), (170, 91, 0), + (161, 86, 3), (155, 88, 1), (152, 79, 0), (124, 54, 2), + (129, 35, 0), (131, 13, 0), (128, 12, 31), (106, 23, 43), + (75, 28, 62), (52, 7, 112), (40, 8, 145), (15, 2, 144), + (24, 11, 127), (64, 34, 88), (63, 45, 59), (73, 68, 26), + (120, 69, 4), (148, 81, 3), (164, 78, 1), (171, 78, 0), + (167, 69, 0), (171, 39, 62), (127, 64, 107), (136, 55, 98) + ), + +// 285 Apophysis-040427-51mitosis +((78, 82, 109), (113, 49, 65), (84, 46, 45), (55, 44, 26), + (53, 48, 29), (51, 53, 32), (45, 49, 38), (40, 46, 44), + (45, 37, 52), (47, 44, 55), (49, 52, 59), (59, 72, 83), + (70, 93, 107), (96, 119, 134), (122, 145, 161), (136, 156, 172), + (151, 168, 184), (119, 165, 189), (119, 174, 191), (120, 184, 194), + (163, 219, 214), (206, 255, 234), (224, 255, 243), (242, 255, 253), + (250, 250, 255), (233, 211, 215), (217, 172, 175), (229, 167, 134), + (242, 163, 94), (244, 149, 92), (247, 136, 90), (240, 130, 71), + (206, 149, 106), (180, 98, 134), (204, 98, 92), (229, 99, 50), + (200, 91, 51), (172, 83, 53), (163, 74, 72), (155, 65, 91), + (113, 101, 115), (118, 113, 117), (124, 125, 119), (139, 138, 133), + (155, 152, 147), (154, 157, 156), (154, 162, 165), (149, 144, 164), + (126, 129, 138), (82, 92, 93), (64, 74, 74), (47, 57, 56), + (47, 41, 47), (48, 26, 38), (51, 23, 28), (54, 20, 19), + (51, 5, 7), (89, 7, 3), (127, 9, 0), (151, 11, 5), + (175, 13, 10), (194, 31, 38), (213, 50, 67), (233, 33, 20), + (211, 21, 5), (159, 34, 12), (161, 45, 42), (164, 56, 72), + (156, 54, 72), (148, 53, 73), (123, 83, 71), (124, 33, 42), + (80, 24, 33), (67, 12, 16), (54, 0, 0), (30, 1, 0), + (6, 2, 1), (4, 3, 0), (3, 4, 0), (15, 4, 2), + (14, 4, 5), (16, 31, 26), (30, 36, 42), (45, 42, 59), + (51, 49, 69), (58, 56, 80), (79, 74, 104), (84, 78, 106), + (66, 65, 83), (55, 59, 69), (45, 53, 56), (38, 48, 48), + (31, 43, 41), (15, 30, 23), (10, 8, 9), (8, 6, 0), + (14, 6, 4), (22, 26, 12), (29, 35, 10), (37, 45, 8), + (36, 53, 8), (35, 62, 9), (48, 58, 6), (53, 59, 57), + (90, 101, 123), (91, 121, 140), (92, 141, 158), (91, 130, 149), + (91, 119, 140), (105, 117, 143), (96, 112, 128), (89, 105, 128), + (89, 116, 107), (63, 113, 124), (65, 111, 117), (68, 109, 111), + (81, 104, 112), (91, 97, 123), (126, 96, 134), (163, 111, 160), + (191, 180, 196), (195, 195, 201), (199, 211, 207), (222, 228, 231), + (246, 246, 255), (252, 249, 255), (252, 253, 255), (255, 251, 255), + (251, 255, 255), (196, 212, 211), (181, 197, 195), (167, 182, 179), + (151, 150, 156), (124, 116, 137), (98, 96, 109), (80, 86, 84), + (42, 59, 51), (37, 53, 51), (33, 48, 51), (29, 45, 43), + (26, 43, 35), (21, 32, 36), (20, 14, 26), (29, 14, 21), + (30, 29, 27), (54, 28, 27), (60, 26, 26), (67, 25, 26), + (90, 32, 44), (66, 51, 46), (61, 70, 87), (87, 85, 96), + (141, 98, 141), (149, 101, 146), (158, 105, 151), (141, 84, 119), + (106, 79, 114), (87, 78, 105), (69, 83, 86), (63, 66, 71), + (48, 59, 55), (44, 51, 61), (45, 58, 70), (46, 65, 80), + (59, 92, 81), (62, 88, 101), (61, 110, 117), (60, 87, 98), + (41, 51, 63), (39, 54, 58), (38, 57, 53), (39, 61, 49), + (48, 64, 53), (53, 76, 68), (85, 85, 83), (112, 113, 73), + (113, 113, 103), (125, 127, 124), (158, 156, 144), (158, 170, 170), + (161, 165, 174), (158, 149, 178), (127, 153, 150), (114, 120, 154), + (121, 153, 178), (143, 166, 178), (165, 179, 179), (175, 190, 195), + (210, 249, 248), (241, 255, 254), (247, 255, 254), (228, 237, 242), + (190, 173, 215), (148, 138, 162), (111, 99, 139), (100, 105, 101), + (67, 99, 86), (50, 73, 65), (49, 62, 55), (56, 65, 60), + (61, 86, 67), (58, 103, 82), (52, 102, 109), (70, 118, 128), + (76, 130, 142), (84, 115, 133), (80, 109, 127), (71, 117, 130), + (71, 117, 130), (74, 110, 122), (76, 100, 112), (70, 78, 97), + (59, 56, 75), (58, 39, 58), (80, 41, 44), (61, 20, 24), + (47, 8, 9), (59, 0, 2), (38, 4, 2), (26, 16, 25), + (37, 38, 40), (39, 48, 57), (48, 55, 73), (66, 68, 91), + (92, 91, 105), (103, 129, 116), (128, 136, 139), (142, 157, 162), + (130, 172, 150), (126, 147, 140), (127, 116, 110), (115, 88, 61), + (67, 62, 59), (50, 45, 49), (37, 49, 45), (34, 41, 34), + (25, 34, 31), (34, 36, 25), (24, 49, 7), (17, 40, 0), + (15, 20, 0), (8, 15, 0), (6, 6, 0), (14, 4, 2), + (23, 3, 2), (39, 1, 0), (38, 5, 0), (48, 11, 2), + (51, 21, 21), (39, 33, 33), (21, 32, 28), (13, 17, 16), + (27, 12, 15), (35, 23, 35), (30, 27, 38), (45, 31, 31) + ), + +// 286 Apophysis-040427-51triflwer +((142, 104, 5), (140, 108, 9), (121, 111, 10), (102, 114, 12), + (83, 73, 43), (64, 33, 74), (88, 73, 103), (113, 114, 132), + (160, 203, 186), (163, 207, 205), (167, 211, 224), (144, 200, 229), + (122, 189, 234), (121, 200, 242), (120, 212, 251), (133, 221, 244), + (147, 230, 238), (203, 237, 202), (201, 210, 196), (199, 184, 191), + (179, 151, 157), (159, 118, 124), (126, 110, 73), (93, 102, 23), + (0, 49, 115), (2, 28, 128), (4, 8, 141), (27, 24, 158), + (50, 40, 175), (58, 68, 190), (66, 96, 206), (99, 139, 208), + (149, 163, 212), (234, 235, 203), (230, 219, 194), (226, 203, 185), + (218, 221, 143), (211, 239, 102), (223, 220, 120), (235, 201, 138), + (215, 94, 13), (210, 103, 9), (205, 112, 6), (195, 105, 3), + (185, 99, 0), (179, 89, 2), (173, 79, 5), (167, 82, 2), + (165, 78, 1), (182, 65, 0), (163, 42, 0), (145, 20, 0), + (135, 20, 2), (126, 20, 4), (132, 12, 7), (139, 4, 11), + (118, 0, 61), (85, 13, 76), (52, 26, 91), (40, 16, 87), + (28, 7, 84), (15, 5, 42), (3, 4, 0), (0, 0, 0), + (0, 0, 0), (79, 54, 34), (95, 52, 20), (112, 51, 6), + (120, 37, 3), (129, 23, 0), (129, 18, 1), (131, 7, 5), + (108, 4, 57), (77, 19, 115), (47, 35, 173), (71, 51, 186), + (95, 68, 199), (92, 67, 178), (90, 67, 158), (89, 62, 157), + (99, 47, 130), (97, 50, 130), (128, 84, 133), (159, 118, 136), + (161, 117, 133), (163, 117, 130), (189, 133, 120), (188, 91, 58), + (155, 91, 4), (154, 89, 3), (154, 88, 2), (155, 84, 1), + (157, 80, 0), (169, 77, 0), (182, 74, 12), (188, 62, 66), + (165, 94, 112), (94, 93, 169), (103, 110, 178), (113, 128, 187), + (120, 148, 200), (127, 168, 214), (156, 178, 192), (113, 136, 190), + (93, 89, 165), (113, 96, 154), (134, 103, 144), (134, 95, 138), + (134, 87, 133), (159, 78, 93), (162, 40, 79), (127, 52, 13), + (143, 51, 2), (122, 69, 15), (119, 60, 21), (116, 52, 27), + (84, 19, 53), (34, 51, 79), (8, 66, 88), (7, 99, 84), + (5, 88, 78), (6, 93, 56), (8, 98, 34), (7, 89, 57), + (6, 80, 81), (8, 63, 93), (11, 62, 93), (0, 60, 104), + (0, 60, 107), (42, 26, 89), (48, 25, 88), (55, 25, 87), + (83, 57, 34), (116, 22, 12), (127, 13, 21), (124, 0, 52), + (125, 9, 72), (116, 43, 108), (108, 77, 145), (112, 80, 143), + (117, 84, 141), (130, 98, 139), (133, 111, 157), (90, 67, 158), + (17, 46, 186), (63, 103, 224), (80, 111, 209), (97, 119, 195), + (160, 174, 177), (210, 173, 214), (230, 215, 148), (231, 201, 147), + (211, 97, 71), (210, 93, 69), (210, 89, 68), (213, 81, 56), + (194, 65, 69), (185, 51, 60), (169, 42, 69), (155, 30, 72), + (163, 7, 46), (170, 1, 30), (164, 1, 37), (158, 1, 44), + (147, 0, 44), (133, 0, 45), (125, 15, 28), (124, 65, 25), + (133, 97, 0), (111, 101, 8), (89, 105, 16), (51, 90, 23), + (18, 67, 81), (14, 52, 97), (4, 27, 133), (10, 6, 142), + (25, 3, 138), (33, 0, 149), (50, 0, 126), (82, 24, 108), + (133, 39, 89), (156, 39, 81), (156, 40, 79), (191, 55, 59), + (248, 79, 10), (224, 89, 8), (200, 100, 6), (164, 85, 6), + (151, 90, 1), (149, 92, 2), (133, 88, 3), (119, 58, 1), + (84, 63, 20), (79, 75, 30), (67, 74, 23), (8, 5, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 2, 1), (2, 16, 104), (0, 37, 125), (2, 9, 142), + (4, 0, 147), (11, 0, 154), (16, 0, 150), (22, 1, 158), + (6, 0, 177), (13, 36, 210), (1, 38, 249), (0, 48, 221), + (18, 12, 180), (62, 10, 137), (69, 26, 69), (112, 67, 25), + (147, 72, 7), (163, 90, 11), (198, 118, 111), (211, 158, 116), + (204, 143, 114), (140, 89, 104), (56, 50, 60), (43, 58, 61), + (2, 2, 2), (0, 0, 0), (7, 14, 0), (80, 80, 10), + (106, 128, 1), (98, 129, 0), (76, 124, 4), (70, 124, 2), + (10, 97, 19), (1, 111, 16), (30, 126, 28), (78, 126, 6), + (130, 131, 1), (133, 129, 3), (137, 124, 9), (139, 112, 5), + (146, 95, 6), (150, 94, 7), (160, 88, 6), (171, 79, 2), + (175, 71, 0), (184, 71, 0), (176, 76, 0), (168, 77, 0), + (163, 80, 0), (154, 87, 0), (150, 88, 1), (140, 89, 0), + (117, 58, 0), (111, 40, 10), (58, 12, 0), (0, 0, 0) + ), + +// 287 Apophysis-040427-51yggF +((47, 48, 42), (64, 65, 59), (76, 77, 71), (88, 89, 84), + (90, 90, 93), (92, 92, 102), (93, 93, 103), (94, 94, 104), + (100, 101, 96), (95, 96, 91), (91, 92, 87), (81, 84, 79), + (72, 77, 71), (61, 65, 63), (50, 54, 55), (48, 50, 52), + (47, 47, 49), (42, 41, 39), (42, 42, 38), (42, 43, 38), + (41, 42, 38), (41, 41, 39), (43, 43, 41), (45, 45, 43), + (54, 53, 49), (52, 55, 47), (50, 58, 45), (50, 54, 46), + (50, 50, 48), (50, 47, 46), (51, 45, 45), (52, 42, 40), + (48, 46, 47), (56, 59, 64), (64, 67, 74), (72, 75, 84), + (74, 78, 88), (77, 81, 92), (82, 84, 94), (87, 87, 97), + (84, 94, 83), (81, 87, 79), (79, 80, 75), (69, 70, 70), + (60, 61, 66), (57, 58, 63), (55, 56, 61), (53, 52, 57), + (50, 49, 54), (46, 45, 50), (43, 43, 44), (41, 41, 39), + (36, 36, 37), (31, 32, 36), (31, 31, 36), (32, 31, 36), + (22, 21, 26), (14, 16, 18), (6, 12, 10), (16, 19, 16), + (26, 27, 22), (28, 28, 25), (30, 30, 28), (36, 36, 34), + (42, 43, 38), (54, 56, 45), (56, 58, 49), (59, 60, 54), + (59, 60, 55), (60, 61, 56), (60, 60, 58), (59, 63, 64), + (59, 62, 71), (63, 65, 67), (68, 69, 64), (64, 64, 61), + (60, 60, 58), (59, 59, 57), (59, 59, 57), (56, 56, 54), + (52, 52, 50), (46, 47, 42), (45, 45, 41), (45, 44, 40), + (45, 44, 41), (45, 45, 43), (46, 46, 44), (46, 45, 50), + (45, 44, 49), (42, 41, 46), (39, 38, 43), (38, 37, 42), + (38, 37, 42), (42, 42, 40), (43, 43, 45), (47, 46, 51), + (50, 49, 54), (50, 49, 54), (48, 47, 51), (46, 46, 48), + (43, 43, 43), (41, 41, 39), (36, 36, 34), (32, 32, 30), + (32, 32, 30), (37, 37, 34), (42, 43, 38), (48, 49, 44), + (54, 55, 50), (62, 63, 58), (74, 70, 67), (81, 82, 76), + (84, 85, 80), (79, 80, 74), (78, 78, 74), (77, 77, 75), + (73, 74, 69), (73, 73, 71), (73, 73, 81), (75, 75, 85), + (89, 92, 99), (112, 105, 101), (135, 119, 103), (159, 120, 68), + (183, 122, 33), (175, 109, 22), (166, 103, 10), (121, 72, 3), + (104, 68, 8), (108, 111, 120), (121, 124, 132), (134, 137, 144), + (163, 162, 167), (184, 186, 181), (175, 190, 185), (167, 166, 172), + (127, 128, 133), (111, 112, 112), (96, 97, 91), (96, 97, 91), + (97, 98, 92), (117, 117, 119), (135, 141, 131), (143, 144, 148), + (166, 165, 161), (185, 185, 193), (205, 202, 212), (226, 220, 232), + (251, 229, 208), (254, 224, 200), (242, 213, 157), (243, 189, 129), + (144, 147, 126), (131, 133, 127), (119, 119, 129), (105, 105, 103), + (86, 87, 82), (73, 73, 71), (68, 68, 66), (64, 65, 60), + (60, 61, 56), (58, 59, 53), (58, 59, 54), (59, 60, 55), + (59, 60, 55), (60, 61, 55), (62, 61, 57), (63, 64, 59), + (67, 67, 65), (68, 69, 65), (70, 71, 66), (71, 72, 67), + (76, 76, 74), (93, 92, 88), (106, 107, 102), (159, 129, 101), + (215, 162, 94), (216, 165, 102), (217, 205, 181), (226, 227, 231), + (240, 243, 232), (253, 227, 200), (254, 217, 188), (248, 196, 139), + (180, 128, 29), (149, 98, 14), (118, 69, 0), (47, 49, 36), + (37, 37, 35), (27, 27, 29), (26, 25, 30), (24, 26, 23), + (29, 29, 27), (35, 35, 33), (40, 40, 38), (43, 44, 39), + (48, 49, 44), (53, 53, 51), (57, 56, 54), (58, 59, 53), + (59, 60, 54), (58, 59, 53), (54, 55, 50), (51, 52, 47), + (47, 47, 45), (44, 44, 42), (41, 46, 39), (41, 48, 41), + (46, 47, 42), (48, 49, 44), (50, 51, 46), (51, 52, 47), + (51, 51, 49), (50, 50, 50), (49, 50, 52), (52, 51, 56), + (54, 53, 58), (59, 59, 57), (61, 60, 56), (63, 62, 58), + (64, 65, 60), (64, 66, 61), (65, 65, 63), (63, 63, 61), + (58, 60, 59), (55, 54, 59), (53, 52, 57), (50, 49, 54), + (47, 46, 51), (45, 45, 43), (41, 41, 39), (37, 37, 35), + (35, 35, 33), (31, 31, 29), (29, 29, 27), (29, 29, 27), + (28, 28, 26), (28, 28, 26), (29, 30, 25), (31, 31, 23), + (32, 33, 27), (35, 35, 33), (38, 38, 36), (40, 39, 35), + (44, 43, 38), (45, 46, 41), (52, 53, 48), (58, 59, 53), + (59, 60, 55), (60, 61, 56), (62, 63, 58), (64, 65, 60), + (63, 64, 59), (59, 60, 55), (57, 57, 55), (48, 52, 53) + ), + +// 288 Apophysis-040427-51Gwrap +((0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (167, 112, 29), (200, 139, 27), (233, 166, 25), (242, 176, 62), + (252, 186, 99), (245, 188, 96), (239, 191, 93), (243, 186, 90), + (247, 181, 87), (160, 146, 107), (107, 130, 122), (54, 114, 138), + (27, 127, 116), (0, 141, 95), (16, 154, 83), (32, 167, 72), + (181, 172, 139), (134, 110, 122), (87, 49, 106), (43, 24, 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, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (82, 53, 26), (164, 107, 52), + (194, 137, 36), (224, 168, 21), (250, 151, 6), (234, 66, 27), + (220, 36, 28), (237, 30, 27), (254, 24, 26), (233, 12, 21), + (212, 0, 17), (152, 20, 9), (92, 40, 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), (103, 49, 62), (178, 115, 44), (254, 181, 27), + (250, 181, 57), (247, 181, 87), (250, 183, 92), (254, 188, 29), + (255, 152, 0), (198, 107, 26), (141, 63, 53), (111, 57, 56), + (82, 51, 59), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 0, 0), (132, 56, 32), (176, 90, 75), + (203, 90, 76), (184, 79, 57), (174, 62, 42), (95, 53, 31), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (49, 70, 63), + (166, 146, 119), (197, 190, 171), (255, 255, 243), (254, 255, 224), + (253, 255, 120), (251, 184, 95), (255, 57, 58), (190, 6, 30), + (92, 37, 43), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 1, 1), (75, 118, 73), (103, 202, 0), + (170, 188, 76), (190, 188, 103), (185, 153, 52), (130, 104, 47), + (44, 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) + ), + +// 289 Apophysis-040428-1Gradient1 +((28, 157, 73), (31, 129, 68), (15, 64, 34), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (22, 98, 0), (25, 142, 4), (28, 187, 8), (26, 202, 4), + (25, 218, 1), (25, 218, 1), (25, 218, 1), (25, 218, 1), + (25, 218, 1), (25, 218, 1), (25, 218, 1), (25, 218, 1), + (28, 218, 4), (31, 219, 7), (32, 219, 8), (33, 219, 10), + (20, 180, 76), (25, 158, 73), (31, 137, 71), (31, 68, 76), + (31, 0, 82), (30, 0, 95), (30, 0, 109), (32, 0, 162), + (26, 0, 166), (75, 0, 131), (117, 29, 98), (159, 59, 66), + (172, 101, 68), (185, 144, 71), (193, 143, 42), (202, 143, 14), + (255, 55, 0), (228, 52, 30), (202, 50, 61), (165, 85, 44), + (129, 121, 27), (150, 139, 17), (171, 157, 7), (236, 218, 10), + (243, 224, 10), (243, 224, 10), (216, 186, 40), (189, 148, 71), + (163, 138, 58), (137, 129, 46), (140, 126, 51), (144, 124, 57), + (150, 144, 66), (109, 150, 83), (68, 157, 101), (55, 78, 106), + (43, 0, 112), (55, 0, 124), (67, 0, 137), (63, 0, 154), + (55, 0, 145), (13, 53, 36), (18, 119, 18), (23, 186, 1), + (24, 202, 1), (25, 218, 1), (25, 218, 1), (25, 218, 1), + (25, 218, 1), (23, 190, 1), (21, 163, 2), (22, 154, 5), + (23, 145, 9), (25, 151, 41), (28, 157, 73), (56, 169, 96), + (73, 162, 105), (207, 151, 41), (225, 187, 25), (243, 224, 10), + (226, 193, 36), (209, 163, 62), (241, 233, 218), (236, 248, 240), + (243, 224, 10), (249, 219, 5), (255, 215, 0), (255, 196, 0), + (255, 178, 0), (255, 132, 0), (201, 91, 0), (213, 51, 63), + (207, 0, 35), (255, 9, 0), (255, 63, 0), (255, 118, 0), + (255, 144, 0), (255, 171, 0), (255, 211, 0), (243, 224, 10), + (243, 224, 10), (243, 224, 10), (243, 224, 10), (243, 224, 10), + (243, 224, 10), (255, 200, 0), (255, 160, 0), (255, 138, 0), + (203, 145, 18), (195, 146, 47), (205, 105, 61), (216, 65, 76), + (209, 40, 52), (242, 0, 10), (204, 0, 37), (207, 50, 60), + (150, 58, 66), (90, 67, 41), (30, 77, 17), (23, 81, 11), + (17, 85, 6), (17, 74, 6), (14, 53, 7), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (18, 18, 13), (36, 36, 27), + (38, 68, 26), (61, 61, 45), (76, 61, 8), (32, 73, 18), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (13, 74, 5), (18, 129, 4), (32, 189, 10), + (28, 218, 4), (32, 219, 9), (34, 219, 11), (37, 219, 14), + (73, 190, 54), (66, 195, 111), (136, 236, 124), (183, 227, 199), + (73, 179, 110), (73, 177, 109), (73, 176, 109), (73, 176, 109), + (74, 155, 105), (141, 117, 55), (159, 59, 66), (189, 55, 65), + (202, 52, 63), (218, 76, 86), (210, 38, 159), (203, 0, 233), + (139, 0, 221), (127, 0, 233), (73, 0, 157), (55, 0, 109), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (14, 58, 6), (18, 86, 6), (12, 113, 0), + (19, 121, 4), (31, 147, 74), (62, 170, 100), (68, 173, 105), + (68, 173, 105), (49, 165, 90), (51, 109, 39), (29, 82, 15), + (47, 80, 0), (44, 85, 0), (42, 91, 0), (46, 128, 31), + (31, 147, 74), (32, 166, 80), (37, 160, 80), (45, 136, 29), + (23, 145, 9), (17, 126, 3), (12, 113, 0), (19, 130, 5), + (20, 156, 2), (25, 190, 4), (25, 218, 1), (28, 218, 4), + (43, 200, 0), (98, 174, 0), (222, 205, 9), (243, 224, 10), + (243, 224, 10), (243, 224, 10), (243, 224, 10), (255, 207, 0), + (239, 171, 21), (203, 145, 18), (140, 132, 45), (64, 165, 52), + (45, 173, 27), (31, 214, 9), (30, 207, 8), (71, 158, 0), + (104, 93, 21), (91, 91, 68), (72, 111, 92), (118, 58, 63), + (153, 0, 74), (159, 0, 70), (169, 0, 62), (176, 0, 45), + (133, 22, 30), (98, 76, 19), (19, 111, 5), (20, 153, 3), + (30, 207, 8), (33, 219, 10), (41, 201, 20), (47, 165, 88), + (66, 163, 101), (71, 162, 104), (113, 144, 129), (152, 145, 68), + (198, 155, 69), (209, 162, 61), (209, 162, 63), (201, 157, 69), + (208, 188, 181), (173, 137, 125), (161, 59, 67), (122, 58, 63), + (131, 21, 30), (73, 8, 13), (117, 18, 25), (128, 61, 37), + (126, 105, 22), (162, 55, 0), (197, 30, 43), (202, 0, 39), + (192, 0, 46), (191, 43, 54), (169, 119, 30), (169, 59, 67) + ), + +// 290 Apophysis-040428-3Gradient2 +((0, 97, 216), (82, 149, 179), (115, 153, 172), (148, 157, 166), + (146, 144, 131), (144, 132, 97), (139, 133, 99), (134, 134, 102), + (91, 95, 94), (91, 95, 94), (91, 95, 94), (101, 99, 86), + (112, 104, 79), (128, 114, 69), (145, 124, 60), (119, 100, 48), + (93, 77, 37), (54, 54, 40), (70, 72, 64), (86, 90, 89), + (137, 131, 132), (188, 173, 175), (187, 183, 185), (186, 193, 195), + (244, 216, 216), (206, 192, 192), (168, 168, 168), (104, 114, 156), + (40, 61, 144), (31, 40, 140), (22, 19, 137), (3, 0, 128), + (3, 0, 128), (1, 0, 37), (0, 0, 18), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (7, 7, 5), + (15, 15, 11), (18, 18, 13), (21, 21, 16), (38, 38, 28), + (73, 73, 54), (116, 186, 132), (155, 182, 131), (194, 179, 130), + (195, 159, 78), (196, 139, 26), (183, 129, 29), (170, 120, 32), + (104, 78, 24), (65, 52, 25), (27, 27, 27), (14, 14, 13), + (1, 1, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (4, 4, 3), + (8, 8, 6), (22, 22, 16), (28, 39, 15), (35, 101, 0), + (64, 178, 0), (215, 33, 24), (185, 21, 21), (155, 10, 19), + (137, 12, 21), (119, 14, 23), (64, 5, 10), (15, 15, 11), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (41, 8, 1), + (59, 37, 0), (44, 44, 33), (46, 46, 34), (48, 48, 36), + (56, 62, 66), (73, 53, 144), (126, 64, 95), (180, 129, 97), + (202, 174, 132), (214, 187, 141), (226, 201, 150), (233, 200, 138), + (240, 199, 127), (236, 176, 60), (228, 148, 6), (255, 69, 0), + (253, 40, 19), (221, 12, 26), (190, 6, 13), (160, 0, 0), + (145, 15, 18), (97, 45, 30), (97, 78, 39), (87, 87, 65), + (89, 120, 73), (85, 124, 71), (82, 129, 70), (56, 110, 68), + (31, 92, 67), (5, 80, 0), (30, 30, 22), (42, 32, 57), + (54, 17, 113), (22, 19, 142), (41, 11, 138), (61, 3, 135), + (82, 8, 143), (110, 5, 141), (86, 4, 137), (68, 0, 114), + (23, 21, 37), (23, 22, 27), (23, 23, 17), (22, 22, 16), + (24, 24, 18), (55, 15, 22), (114, 17, 89), (168, 6, 103), + (178, 14, 128), (80, 5, 135), (42, 4, 131), (4, 3, 128), + (1, 0, 36), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (23, 23, 17), (31, 31, 28), (39, 39, 39), (52, 39, 91), + (66, 15, 125), (59, 55, 151), (58, 56, 156), (113, 121, 125), + (135, 149, 159), (138, 142, 145), (91, 95, 94), (48, 48, 48), + (38, 38, 28), (21, 21, 16), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (36, 7, 1), (70, 45, 1), + (88, 56, 0), (143, 95, 3), (196, 130, 4), (228, 148, 9), + (228, 150, 13), (232, 163, 42), (233, 172, 64), (190, 178, 76), + (146, 141, 97), (122, 112, 84), (124, 67, 63), (111, 78, 27), + (168, 16, 20), (197, 51, 38), (161, 89, 66), (185, 127, 96), + (212, 130, 125), (245, 162, 168), (228, 188, 140), (209, 187, 160), + (191, 189, 153), (210, 196, 152), (252, 202, 101), (238, 185, 71), + (247, 175, 48), (233, 161, 34), (240, 161, 17), (230, 146, 0), + (230, 146, 0), (255, 84, 0), (238, 7, 0), (232, 11, 26), + (153, 8, 19), (75, 6, 12), (41, 8, 1), (7, 7, 5), + (0, 0, 0), (1, 1, 1), (15, 15, 11), (19, 19, 19), + (0, 16, 87), (0, 55, 114), (0, 113, 80), (82, 131, 67), + (90, 178, 40), (99, 151, 86), (90, 138, 79), (87, 87, 65), + (68, 64, 42), (57, 57, 42), (91, 63, 46), (148, 51, 66), + (177, 9, 169), (205, 9, 169), (205, 9, 169), (206, 9, 169), + (206, 9, 169), (217, 65, 165), (216, 120, 119), (216, 143, 31), + (224, 148, 14), (201, 127, 0), (167, 124, 105), (187, 141, 58) + ), + +// 291 Apophysis-040602-1 +((255, 255, 255), (255, 255, 255), (236, 214, 211), (218, 173, 167), + (184, 166, 158), (150, 160, 150), (150, 160, 150), (150, 160, 150), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (97, 83, 57), (104, 101, 84), (111, 119, 111), + (125, 134, 125), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (148, 158, 148), (149, 159, 149), (150, 160, 150), (145, 155, 145), + (140, 150, 140), (134, 127, 103), (128, 104, 66), (161, 59, 19), + (209, 127, 0), (182, 125, 108), (161, 137, 124), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (115, 97, 57), (160, 100, 51), (206, 103, 45), (181, 121, 90), + (157, 139, 135), (152, 147, 141), (147, 156, 147), (150, 160, 150), + (150, 160, 150), (150, 160, 150), (150, 160, 150), (150, 160, 150), + (150, 160, 150), (150, 160, 150), (150, 160, 150), (150, 160, 150), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (93, 99, 93), (91, 71, 47), + (3, 9, 5), (1, 4, 2), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (1, 1, 0), (25, 9, 0), + (71, 47, 13), (133, 83, 60), (136, 116, 100), (140, 150, 140), + (145, 155, 145), (150, 160, 150), (150, 160, 150), (184, 166, 126), + (255, 237, 174), (231, 221, 194), (208, 205, 214), (179, 182, 182), + (150, 160, 150), (140, 150, 140), (138, 148, 138), (87, 93, 87), + (1, 28, 117), (150, 160, 150), (202, 207, 202), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (150, 160, 150), (140, 150, 140), + (93, 92, 62), (43, 35, 22), (27, 25, 11), (12, 15, 0), + (1, 3, 0), (0, 0, 0), (1, 1, 1), (4, 3, 0), + (60, 52, 39), (100, 101, 89), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (87, 93, 87), (52, 41, 37), (26, 21, 15), (4, 4, 2), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 1, 1), (1, 0, 3), (1, 0, 5), + (1, 0, 9), (17, 15, 54), (38, 58, 108), (103, 115, 107), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (149, 151, 127), + (122, 131, 122), (115, 60, 40), (97, 28, 21), (22, 8, 8), + (4, 0, 2), (1, 0, 0), (2, 0, 0), (4, 0, 0), + (22, 0, 0), (69, 2, 19), (114, 21, 16), (102, 80, 56), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (150, 160, 150), (150, 160, 150), (212, 208, 200), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (212, 208, 200), (150, 160, 150), (150, 160, 150), + (150, 160, 150), (150, 160, 150), (150, 160, 150), (150, 160, 150), + (150, 160, 150), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (140, 150, 140), (140, 150, 140), + (140, 150, 140), (140, 150, 140), (150, 160, 150), (150, 160, 150), + (150, 160, 150), (150, 160, 150), (150, 160, 150), (150, 160, 150), + (150, 160, 150), (150, 160, 150), (150, 160, 150), (150, 160, 150), + (150, 160, 150), (150, 160, 150), (209, 182, 161), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (150, 160, 150), + (139, 148, 139), (93, 99, 93), (48, 64, 64), (11, 17, 53), + (0, 23, 117), (0, 23, 119), (3, 21, 119), (2, 22, 109), + (1, 0, 9), (0, 0, 5), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 1, 0), (3, 0, 0), (7, 0, 0), + (56, 21, 2), (117, 65, 43), (150, 136, 107), (150, 160, 150), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (255, 255, 255), (255, 255, 255), (255, 255, 255), (255, 255, 255) + ), + +// 292 Apophysis-040531-100figurine_2abcd +((210, 159, 138), (220, 182, 145), (209, 178, 152), (198, 175, 159), + (208, 159, 148), (218, 143, 137), (211, 123, 155), (204, 104, 174), + (207, 57, 154), (190, 58, 127), (174, 59, 100), (142, 46, 95), + (111, 33, 91), (110, 38, 90), (109, 43, 89), (116, 41, 92), + (123, 40, 96), (133, 54, 119), (134, 61, 133), (135, 68, 148), + (123, 99, 151), (111, 131, 155), (107, 134, 164), (104, 138, 173), + (97, 130, 165), (91, 124, 159), (85, 118, 153), (100, 99, 148), + (115, 80, 144), (128, 83, 132), (142, 86, 121), (177, 116, 111), + (190, 135, 130), (184, 183, 152), (190, 148, 153), (196, 113, 155), + (188, 78, 186), (180, 43, 217), (164, 38, 190), (148, 33, 164), + (73, 36, 116), (59, 21, 95), (46, 7, 74), (44, 5, 67), + (43, 4, 61), (43, 4, 62), (43, 5, 64), (44, 4, 64), + (53, 8, 73), (79, 31, 91), (99, 47, 97), (120, 64, 103), + (140, 74, 103), (161, 84, 104), (170, 83, 105), (180, 82, 107), + (176, 70, 108), (159, 59, 104), (142, 48, 100), (117, 39, 97), + (93, 31, 94), (91, 36, 95), (90, 41, 97), (69, 77, 80), + (59, 77, 115), (80, 106, 155), (77, 107, 149), (75, 109, 144), + (70, 101, 139), (66, 94, 134), (70, 92, 129), (57, 75, 121), + (55, 74, 116), (64, 83, 121), (73, 93, 126), (88, 107, 127), + (103, 122, 129), (89, 114, 134), (76, 106, 140), (72, 83, 147), + (78, 43, 109), (68, 27, 93), (63, 19, 86), (59, 12, 80), + (57, 11, 77), (56, 10, 75), (56, 10, 74), (46, 42, 75), + (48, 52, 100), (61, 44, 107), (75, 37, 114), (74, 34, 112), + (73, 32, 111), (82, 29, 101), (91, 30, 89), (107, 40, 93), + (117, 50, 101), (142, 58, 120), (152, 44, 130), (163, 31, 140), + (155, 39, 122), (148, 47, 105), (117, 31, 104), (109, 31, 93), + (89, 23, 113), (72, 15, 100), (56, 7, 88), (56, 8, 86), + (56, 10, 85), (57, 9, 83), (72, 15, 83), (85, 14, 80), + (92, 24, 73), (108, 29, 86), (119, 33, 90), (131, 38, 95), + (160, 67, 96), (189, 90, 119), (203, 90, 134), (203, 98, 115), + (206, 117, 123), (208, 127, 131), (210, 138, 139), (210, 137, 133), + (210, 136, 127), (203, 127, 131), (199, 131, 132), (182, 119, 136), + (163, 131, 144), (135, 140, 196), (126, 145, 187), (117, 151, 179), + (92, 118, 151), (92, 74, 116), (90, 47, 101), (81, 31, 92), + (80, 26, 102), (73, 26, 98), (66, 27, 94), (63, 27, 95), + (61, 28, 97), (48, 64, 98), (55, 74, 114), (45, 53, 92), + (43, 40, 83), (64, 23, 89), (68, 23, 87), (72, 24, 86), + (80, 21, 89), (86, 27, 91), (100, 38, 89), (113, 50, 93), + (205, 48, 115), (203, 48, 140), (202, 49, 165), (188, 56, 217), + (215, 60, 224), (205, 103, 213), (192, 114, 215), (236, 164, 202), + (239, 170, 199), (204, 198, 212), (204, 183, 195), (205, 169, 179), + (166, 121, 162), (132, 90, 138), (125, 62, 109), (93, 47, 96), + (63, 15, 77), (58, 11, 75), (54, 8, 73), (57, 9, 71), + (68, 14, 74), (91, 21, 83), (110, 36, 95), (149, 56, 113), + (183, 86, 117), (194, 110, 123), (197, 115, 127), (199, 123, 127), + (192, 111, 126), (189, 105, 128), (172, 104, 119), (144, 88, 115), + (134, 67, 100), (125, 59, 96), (116, 51, 93), (109, 47, 98), + (104, 45, 89), (99, 37, 88), (93, 44, 91), (101, 47, 97), + (108, 63, 102), (115, 79, 117), (140, 84, 111), (165, 99, 103), + (184, 106, 122), (181, 119, 130), (175, 126, 130), (159, 94, 118), + (143, 68, 111), (133, 63, 100), (126, 48, 96), (125, 59, 95), + (123, 72, 105), (134, 79, 110), (152, 71, 140), (190, 48, 158), + (179, 76, 185), (146, 91, 158), (136, 108, 157), (131, 140, 181), + (101, 131, 165), (96, 95, 127), (88, 70, 118), (82, 40, 106), + (86, 31, 88), (90, 29, 86), (91, 30, 89), (99, 30, 87), + (101, 31, 85), (103, 28, 87), (101, 27, 86), (101, 25, 89), + (94, 24, 87), (78, 22, 85), (70, 20, 81), (71, 18, 74), + (66, 19, 74), (62, 12, 73), (54, 10, 71), (47, 5, 68), + (47, 6, 66), (47, 6, 66), (51, 6, 71), (55, 6, 72), + (58, 6, 72), (57, 11, 76), (74, 13, 80), (88, 15, 84), + (95, 19, 81), (87, 30, 81), (80, 32, 90), (72, 27, 94), + (68, 19, 110), (66, 17, 109), (56, 9, 89), (49, 7, 81), + (46, 6, 76), (47, 7, 77), (54, 8, 81), (69, 21, 81), + (85, 31, 89), (106, 60, 99), (145, 91, 114), (161, 109, 121) + ), + +// 293 Apo-040627-1_chickadee_pix +((148, 120, 109), (130, 103, 92), (115, 95, 94), (101, 88, 97), + (103, 83, 81), (105, 79, 66), (106, 80, 67), (107, 81, 68), + (133, 108, 101), (128, 112, 115), (124, 116, 129), (134, 119, 120), + (145, 123, 112), (144, 123, 115), (144, 123, 118), (144, 123, 121), + (145, 123, 125), (147, 122, 115), (167, 143, 113), (187, 164, 112), + (195, 174, 127), (204, 185, 143), (221, 197, 165), (238, 210, 188), + (158, 137, 134), (136, 117, 109), (115, 97, 85), (91, 73, 62), + (68, 50, 40), (59, 43, 35), (50, 37, 31), (33, 20, 4), + (23, 9, 0), (5, 0, 1), (3, 1, 1), (1, 3, 2), + (6, 4, 3), (11, 5, 5), (20, 15, 8), (29, 26, 11), + (87, 57, 29), (119, 92, 25), (151, 127, 21), (176, 145, 10), + (202, 163, 0), (191, 160, 3), (181, 157, 7), (154, 141, 27), + (156, 111, 44), (142, 115, 104), (148, 119, 108), (154, 124, 113), + (154, 127, 116), (154, 130, 120), (153, 128, 119), (153, 126, 119), + (150, 122, 111), (148, 121, 110), (147, 120, 109), (142, 114, 103), + (137, 109, 98), (135, 107, 97), (134, 105, 97), (138, 108, 97), + (139, 111, 100), (148, 120, 109), (144, 118, 109), (141, 116, 109), + (140, 116, 110), (140, 116, 112), (137, 114, 108), (132, 105, 98), + (115, 88, 81), (107, 84, 75), (100, 80, 69), (87, 69, 60), + (75, 58, 51), (68, 52, 47), (62, 47, 44), (60, 46, 45), + (60, 50, 61), (52, 45, 39), (56, 44, 36), (61, 43, 33), + (59, 42, 32), (58, 41, 31), (52, 39, 33), (43, 33, 32), + (39, 31, 12), (38, 32, 20), (37, 34, 29), (42, 36, 34), + (47, 38, 39), (57, 43, 34), (60, 46, 35), (59, 46, 40), + (64, 50, 50), (67, 55, 67), (64, 54, 68), (61, 54, 70), + (66, 57, 70), (72, 60, 70), (86, 65, 60), (87, 67, 56), + (76, 58, 48), (64, 48, 38), (53, 39, 28), (44, 33, 17), + (35, 27, 6), (25, 23, 10), (13, 8, 5), (7, 1, 1), + (3, 0, 0), (0, 1, 0), (0, 0, 0), (1, 0, 0), + (5, 0, 0), (5, 1, 0), (12, 8, 0), (20, 18, 0), + (49, 34, 15), (60, 44, 27), (72, 54, 40), (76, 58, 45), + (81, 63, 51), (97, 77, 66), (101, 78, 72), (103, 80, 72), + (117, 92, 87), (130, 100, 89), (125, 96, 81), (120, 93, 74), + (123, 85, 62), (148, 113, 31), (184, 127, 22), (156, 109, 1), + (90, 69, 2), (62, 43, 2), (35, 17, 3), (33, 12, 1), + (31, 7, 0), (24, 6, 0), (19, 1, 0), (17, 4, 0), + (15, 5, 0), (13, 6, 0), (14, 6, 0), (15, 6, 1), + (21, 7, 0), (32, 22, 0), (38, 17, 0), (46, 34, 0), + (55, 39, 26), (55, 40, 30), (55, 42, 34), (58, 44, 33), + (56, 43, 35), (45, 34, 32), (36, 23, 15), (29, 10, 12), + (9, 8, 13), (10, 6, 0), (9, 5, 0), (9, 4, 0), + (9, 1, 0), (11, 1, 0), (16, 8, 0), (31, 10, 15), + (48, 39, 40), (53, 41, 40), (58, 44, 41), (59, 45, 42), + (71, 51, 42), (77, 61, 48), (98, 75, 61), (104, 77, 66), + (109, 82, 71), (111, 89, 78), (119, 92, 83), (133, 105, 93), + (152, 119, 104), (164, 133, 115), (160, 151, 142), (178, 158, 167), + (215, 204, 208), (205, 195, 196), (196, 186, 185), (171, 162, 157), + (145, 134, 112), (127, 103, 91), (115, 93, 82), (100, 76, 64), + (79, 57, 44), (70, 48, 24), (51, 37, 24), (29, 26, 19), + (15, 10, 17), (11, 6, 3), (6, 5, 1), (15, 10, 6), + (36, 22, 13), (57, 40, 30), (72, 53, 39), (94, 67, 48), + (105, 79, 64), (107, 81, 66), (102, 76, 63), (87, 65, 51), + (71, 53, 41), (60, 42, 30), (57, 40, 30), (62, 48, 3), + (61, 51, 0), (69, 47, 0), (99, 72, 27), (110, 87, 45), + (127, 101, 86), (150, 120, 110), (160, 147, 138), (178, 170, 149), + (201, 187, 187), (219, 206, 213), (229, 212, 202), (217, 208, 209), + (187, 171, 174), (155, 132, 126), (130, 103, 94), (106, 79, 70), + (93, 70, 52), (78, 59, 45), (67, 49, 39), (63, 45, 33), + (70, 51, 37), (77, 59, 47), (81, 74, 46), (96, 74, 63), + (93, 71, 57), (84, 60, 50), (70, 52, 32), (50, 41, 26), + (44, 27, 7), (41, 36, 0), (53, 45, 9), (61, 44, 34), + (82, 60, 47), (100, 77, 63), (108, 82, 69), (122, 95, 84), + (126, 104, 93), (132, 108, 98), (141, 113, 102), (141, 113, 109), + (138, 111, 104), (131, 106, 101), (125, 101, 99), (117, 98, 84) + ), + + + +// 294 2u0026t.jpg from bTomchek +((95, 14, 0), (88, 23, 17), (91, 40, 23), (94, 57, 30), + (97, 63, 20), (100, 70, 10), (96, 68, 8), (93, 67, 6), + (89, 32, 12), (93, 23, 17), (98, 15, 23), (100, 14, 20), + (102, 13, 17), (106, 11, 15), (110, 9, 13), (112, 9, 14), + (115, 10, 15), (124, 27, 10), (133, 44, 14), (142, 61, 18), + (136, 77, 21), (131, 94, 24), (131, 103, 16), (131, 112, 9), + (141, 107, 7), (153, 104, 3), (166, 101, 0), (172, 109, 5), + (178, 117, 10), (179, 118, 8), (181, 119, 6), (181, 117, 9), + (179, 114, 10), (147, 100, 8), (137, 90, 8), (127, 80, 8), + (131, 77, 6), (135, 75, 5), (135, 75, 9), (135, 75, 13), + (150, 99, 16), (155, 97, 13), (161, 95, 11), (165, 103, 5), + (169, 112, 0), (165, 121, 0), (161, 131, 0), (163, 133, 0), + (165, 135, 1), (152, 120, 9), (140, 94, 11), (128, 69, 13), + (121, 53, 13), (115, 37, 14), (116, 29, 15), (117, 22, 16), + (101, 9, 12), (99, 14, 16), (98, 20, 20), (105, 30, 16), + (112, 41, 13), (120, 51, 9), (128, 61, 6), (130, 72, 0), + (136, 89, 0), (143, 78, 10), (139, 77, 12), (135, 77, 14), + (130, 68, 17), (125, 60, 20), (110, 42, 23), (107, 34, 25), + (125, 51, 26), (130, 52, 20), (135, 53, 15), (136, 57, 13), + (137, 61, 11), (140, 68, 9), (144, 75, 8), (160, 81, 2), + (165, 77, 5), (136, 62, 0), (123, 44, 1), (110, 26, 2), + (104, 22, 1), (99, 18, 0), (90, 12, 8), (87, 6, 5), + (95, 6, 8), (94, 10, 11), (94, 14, 15), (92, 13, 17), + (90, 13, 19), (90, 22, 21), (99, 32, 23), (99, 42, 23), + (107, 38, 22), (117, 49, 36), (127, 51, 26), (137, 53, 16), + (144, 55, 22), (151, 57, 29), (144, 73, 41), (135, 72, 28), + (134, 60, 33), (123, 48, 24), (113, 36, 16), (112, 28, 10), + (112, 20, 5), (112, 14, 3), (113, 19, 7), (119, 43, 9), + (129, 50, 11), (128, 43, 14), (125, 39, 18), (123, 35, 23), + (112, 33, 18), (115, 25, 16), (112, 16, 17), (103, 8, 16), + (109, 29, 20), (113, 30, 25), (117, 31, 30), (117, 29, 32), + (118, 27, 34), (106, 28, 28), (105, 23, 25), (103, 18, 11), + (103, 16, 7), (128, 43, 4), (129, 54, 4), (131, 65, 4), + (141, 79, 0), (159, 87, 2), (167, 92, 9), (176, 100, 14), + (174, 119, 16), (174, 120, 14), (175, 121, 13), (174, 118, 10), + (173, 115, 8), (164, 103, 0), (164, 101, 0), (153, 103, 14), + (150, 120, 10), (137, 149, 5), (147, 151, 3), (157, 154, 1), + (166, 140, 4), (173, 146, 0), (172, 136, 0), (174, 130, 0), + (184, 152, 5), (187, 154, 7), (191, 156, 10), (180, 156, 0), + (184, 147, 0), (183, 137, 0), (183, 132, 4), (179, 129, 4), + (182, 132, 7), (174, 118, 33), (169, 110, 43), (165, 103, 54), + (145, 94, 28), (150, 77, 36), (140, 79, 25), (147, 85, 10), + (147, 84, 7), (144, 84, 3), (142, 84, 0), (155, 84, 2), + (160, 87, 0), (157, 85, 0), (155, 82, 3), (140, 71, 2), + (135, 66, 0), (129, 58, 0), (115, 49, 0), (110, 33, 5), + (97, 19, 0), (82, 14, 0), (86, 11, 6), (86, 7, 12), + (76, 21, 14), (80, 23, 16), (84, 25, 19), (90, 29, 24), + (106, 42, 15), (104, 60, 0), (104, 54, 0), (109, 34, 5), + (101, 19, 7), (106, 14, 1), (115, 28, 1), (134, 47, 4), + (133, 69, 5), (151, 86, 6), (161, 87, 0), (170, 92, 7), + (166, 97, 2), (162, 97, 3), (157, 98, 6), (154, 95, 3), + (139, 98, 0), (125, 98, 9), (126, 76, 5), (124, 63, 0), + (114, 56, 8), (103, 66, 13), (117, 61, 14), (127, 63, 15), + (133, 65, 16), (138, 68, 17), (151, 84, 13), (158, 103, 13), + (169, 118, 11), (176, 124, 4), (175, 127, 1), (175, 139, 0), + (171, 146, 1), (167, 148, 7), (170, 150, 3), (174, 160, 1), + (178, 159, 5), (178, 162, 4), (176, 173, 8), (177, 172, 10), + (168, 163, 9), (177, 172, 6), (180, 172, 1), (181, 191, 8), + (177, 175, 4), (160, 167, 2), (152, 163, 0), (152, 155, 2), + (142, 146, 7), (151, 125, 4), (148, 115, 10), (140, 98, 0), + (128, 80, 0), (123, 70, 0), (120, 55, 1), (126, 43, 9), + (121, 33, 11), (128, 18, 17), (129, 20, 17), (143, 39, 14), + (147, 71, 9), (148, 90, 6), (149, 110, 7), (156, 132, 0), + (165, 139, 0), (168, 140, 0), (166, 132, 6), (169, 139, 17) + ), + +// 295 2u0007t.jpg +((41, 88, 10), (77, 67, 16), (81, 66, 19), (86, 65, 22), + (89, 70, 27), (92, 75, 32), (69, 79, 31), (47, 84, 30), + (50, 38, 48), (58, 33, 45), (67, 29, 42), (56, 60, 57), + (45, 92, 72), (54, 104, 99), (64, 116, 127), (67, 120, 143), + (70, 124, 160), (96, 157, 178), (105, 163, 177), (114, 169, 176), + (111, 158, 104), (108, 148, 33), (115, 144, 28), (122, 141, 23), + (68, 99, 130), (62, 116, 143), (56, 134, 157), (45, 105, 142), + (34, 77, 128), (17, 77, 98), (0, 77, 69), (0, 78, 75), + (51, 121, 131), (89, 156, 185), (105, 150, 183), (121, 145, 181), + (123, 129, 174), (126, 113, 167), (117, 102, 162), (108, 92, 157), + (92, 15, 47), (134, 9, 52), (177, 4, 57), (181, 51, 49), + (185, 99, 42), (176, 108, 45), (168, 118, 49), (176, 155, 38), + (178, 160, 36), (167, 161, 25), (128, 158, 23), (90, 156, 22), + (74, 152, 50), (58, 148, 78), (64, 161, 104), (71, 174, 131), + (104, 137, 182), (120, 121, 174), (137, 106, 166), (150, 118, 99), + (163, 131, 32), (176, 144, 28), (190, 157, 24), (203, 165, 42), + (198, 120, 37), (195, 78, 34), (180, 84, 28), (165, 90, 23), + (142, 90, 28), (120, 91, 33), (39, 65, 56), (15, 66, 57), + (56, 36, 35), (64, 28, 39), (72, 20, 43), (67, 25, 57), + (63, 31, 72), (73, 51, 111), (83, 72, 151), (92, 80, 144), + (143, 30, 76), (134, 30, 27), (151, 47, 30), (169, 64, 34), + (175, 83, 35), (181, 102, 36), (188, 124, 37), (190, 147, 43), + (179, 189, 66), (172, 175, 52), (165, 161, 38), (149, 149, 32), + (133, 137, 26), (159, 126, 29), (171, 116, 33), (198, 120, 37), + (209, 105, 44), (187, 110, 30), (169, 116, 26), (152, 123, 23), + (152, 144, 23), (153, 166, 24), (133, 158, 40), (114, 182, 133), + (138, 184, 197), (119, 177, 196), (101, 171, 196), (91, 170, 191), + (82, 169, 186), (83, 160, 186), (89, 161, 175), (108, 153, 184), + (114, 160, 194), (134, 179, 158), (131, 168, 103), (128, 157, 49), + (159, 150, 33), (164, 142, 22), (176, 155, 28), (179, 139, 26), + (178, 136, 24), (161, 125, 21), (144, 114, 18), (129, 104, 22), + (115, 94, 27), (95, 80, 25), (102, 97, 31), (113, 103, 14), + (105, 102, 0), (112, 130, 18), (110, 132, 18), (108, 135, 18), + (88, 127, 12), (89, 121, 0), (101, 117, 0), (101, 111, 0), + (77, 74, 7), (69, 48, 5), (61, 23, 4), (57, 29, 20), + (54, 36, 36), (23, 11, 85), (29, 25, 101), (20, 38, 124), + (29, 75, 127), (69, 79, 138), (71, 85, 136), (73, 92, 134), + (76, 91, 150), (83, 143, 179), (110, 174, 201), (124, 186, 207), + (129, 181, 194), (102, 171, 188), (75, 162, 182), (31, 157, 135), + (22, 146, 110), (50, 149, 94), (45, 155, 116), (87, 175, 161), + (133, 188, 195), (139, 196, 205), (143, 196, 207), (147, 196, 210), + (170, 219, 223), (173, 211, 170), (163, 204, 160), (125, 194, 163), + (50, 151, 107), (37, 129, 96), (25, 107, 85), (20, 88, 65), + (46, 92, 56), (50, 131, 29), (58, 126, 15), (67, 126, 0), + (84, 121, 7), (77, 111, 1), (71, 77, 3), (68, 59, 0), + (68, 56, 8), (87, 50, 8), (91, 47, 8), (86, 59, 12), + (117, 102, 17), (133, 109, 17), (149, 117, 18), (156, 110, 14), + (164, 95, 30), (181, 114, 35), (197, 92, 44), (197, 94, 36), + (168, 95, 27), (162, 73, 29), (117, 71, 21), (100, 35, 33), + (58, 29, 34), (36, 24, 36), (42, 26, 29), (57, 27, 17), + (30, 21, 26), (31, 18, 25), (33, 17, 0), (16, 18, 0), + (10, 36, 27), (24, 35, 39), (49, 54, 24), (70, 91, 16), + (63, 119, 10), (62, 125, 10), (45, 136, 7), (33, 132, 15), + (48, 150, 25), (5, 157, 46), (13, 134, 63), (16, 171, 80), + (28, 189, 75), (35, 171, 89), (40, 160, 71), (49, 155, 54), + (50, 122, 76), (73, 123, 50), (122, 105, 35), (150, 93, 38), + (154, 75, 42), (134, 40, 40), (116, 35, 31), (86, 26, 28), + (64, 47, 21), (23, 64, 4), (50, 87, 7), (62, 96, 9), + (60, 110, 15), (55, 110, 52), (55, 126, 96), (75, 127, 149), + (66, 147, 174), (68, 161, 179), (45, 160, 167), (55, 160, 117), + (56, 145, 81), (98, 128, 38), (139, 121, 39), (139, 123, 28), + (126, 121, 19), (119, 111, 48), (99, 129, 67), (64, 121, 88), + (54, 144, 93), (86, 147, 106), (96, 104, 65), (72, 54, 50), + (80, 24, 23), (82, 24, 20), (93, 67, 8), (122, 93, 15) + ), + +// 296 2u0010t.jpg +((42, 44, 67), (60, 55, 77), (43, 47, 79), (27, 39, 81), + (18, 30, 79), (10, 21, 77), (17, 16, 69), (25, 11, 62), + (46, 32, 67), (54, 46, 83), (62, 60, 100), (58, 80, 94), + (55, 101, 88), (57, 102, 90), (60, 103, 93), (63, 89, 98), + (66, 76, 103), (37, 33, 107), (22, 18, 105), (8, 3, 103), + (4, 8, 84), (0, 13, 65), (4, 9, 48), (9, 5, 32), + (10, 13, 0), (9, 23, 22), (9, 33, 45), (16, 31, 66), + (24, 29, 87), (29, 32, 89), (34, 35, 92), (46, 36, 88), + (43, 43, 79), (28, 36, 99), (35, 29, 112), (43, 22, 125), + (31, 19, 136), (19, 16, 147), (9, 22, 135), (0, 29, 123), + (34, 50, 110), (47, 67, 129), (61, 85, 149), (67, 101, 145), + (73, 118, 141), (67, 121, 138), (62, 124, 135), (56, 112, 137), + (61, 97, 145), (58, 74, 110), (49, 69, 114), (41, 64, 118), + (24, 68, 142), (7, 73, 167), (8, 69, 170), (9, 65, 174), + (52, 77, 161), (56, 87, 153), (61, 97, 145), (69, 82, 130), + (77, 68, 115), (76, 56, 100), (75, 44, 86), (82, 37, 60), + (86, 23, 32), (68, 10, 0), (82, 11, 24), (97, 13, 49), + (104, 29, 38), (111, 46, 28), (118, 114, 25), (125, 129, 42), + (172, 143, 51), (192, 95, 56), (213, 48, 62), (203, 29, 42), + (193, 11, 23), (177, 11, 29), (161, 11, 36), (160, 28, 41), + (107, 41, 69), (58, 11, 127), (60, 19, 132), (63, 27, 137), + (77, 31, 135), (91, 35, 134), (104, 29, 124), (111, 46, 100), + (150, 21, 49), (143, 48, 70), (137, 76, 92), (126, 65, 112), + (116, 55, 132), (88, 49, 128), (66, 45, 146), (35, 45, 143), + (47, 66, 132), (101, 58, 127), (94, 61, 118), (88, 65, 109), + (84, 71, 108), (80, 77, 108), (70, 73, 106), (78, 73, 96), + (65, 65, 57), (60, 59, 31), (55, 53, 5), (69, 45, 10), + (84, 38, 15), (57, 61, 24), (53, 49, 37), (63, 43, 70), + (74, 48, 73), (118, 39, 86), (123, 32, 69), (129, 26, 53), + (136, 16, 26), (126, 18, 33), (114, 45, 50), (82, 49, 66), + (61, 44, 89), (41, 34, 90), (21, 24, 91), (20, 18, 87), + (19, 13, 83), (33, 7, 80), (34, 19, 88), (37, 22, 89), + (35, 31, 81), (40, 23, 68), (43, 17, 53), (47, 11, 39), + (52, 18, 19), (39, 27, 29), (16, 39, 57), (26, 37, 67), + (44, 28, 91), (66, 44, 112), (88, 60, 134), (81, 76, 137), + (75, 93, 141), (87, 108, 135), (109, 117, 76), (102, 108, 34), + (92, 127, 61), (72, 117, 176), (78, 128, 186), (84, 140, 197), + (73, 119, 196), (56, 94, 167), (47, 65, 167), (27, 43, 156), + (46, 43, 110), (46, 46, 100), (47, 49, 90), (43, 38, 78), + (39, 32, 66), (40, 26, 61), (40, 30, 57), (56, 15, 47), + (56, 6, 43), (53, 33, 45), (42, 48, 38), (32, 63, 32), + (24, 57, 48), (44, 47, 66), (64, 56, 80), (74, 64, 101), + (103, 66, 118), (101, 68, 123), (99, 70, 128), (95, 78, 123), + (84, 75, 128), (87, 83, 142), (102, 94, 154), (121, 113, 152), + (98, 135, 188), (113, 139, 190), (124, 149, 205), (129, 150, 177), + (125, 141, 166), (152, 65, 169), (113, 44, 151), (107, 30, 146), + (110, 42, 141), (115, 61, 142), (120, 80, 143), (92, 112, 145), + (96, 105, 110), (88, 72, 72), (74, 58, 61), (38, 54, 9), + (20, 62, 50), (31, 58, 77), (47, 58, 90), (41, 61, 96), + (41, 54, 96), (54, 53, 111), (56, 35, 100), (55, 28, 107), + (77, 31, 93), (115, 67, 63), (155, 99, 66), (154, 122, 65), + (141, 146, 52), (109, 142, 97), (104, 133, 163), (82, 111, 145), + (70, 100, 160), (67, 94, 139), (60, 64, 91), (74, 72, 60), + (89, 55, 56), (74, 50, 46), (85, 64, 33), (125, 51, 48), + (136, 43, 62), (122, 50, 62), (93, 39, 75), (86, 49, 67), + (80, 60, 88), (65, 59, 71), (62, 70, 73), (71, 66, 89), + (75, 59, 95), (105, 47, 95), (100, 63, 104), (75, 59, 104), + (66, 41, 124), (41, 31, 164), (23, 35, 169), (18, 59, 177), + (17, 57, 204), (7, 63, 212), (10, 78, 201), (49, 80, 186), + (84, 88, 162), (74, 76, 135), (87, 57, 119), (67, 70, 105), + (58, 50, 99), (59, 47, 87), (48, 35, 65), (52, 22, 58), + (68, 38, 66), (56, 48, 69), (36, 75, 70), (1, 97, 70), + (8, 75, 84), (20, 38, 76), (26, 48, 85), (34, 69, 91), + (28, 83, 88), (39, 73, 75), (60, 62, 75), (57, 43, 60) + ), + +// 297 2u0015t.jpg +((129, 96, 65), (144, 152, 101), (152, 164, 104), (161, 176, 107), + (161, 186, 119), (162, 197, 131), (165, 202, 136), (168, 207, 142), + (178, 193, 160), (178, 178, 150), (179, 163, 140), (177, 152, 155), + (176, 141, 171), (177, 149, 183), (178, 158, 195), (177, 166, 191), + (176, 174, 187), (182, 198, 169), (175, 190, 168), (168, 182, 167), + (161, 173, 157), (154, 165, 148), (152, 170, 145), (151, 175, 143), + (156, 183, 132), (164, 180, 125), (172, 177, 119), (170, 171, 126), + (168, 165, 134), (164, 167, 136), (160, 169, 138), (150, 171, 132), + (156, 170, 145), (160, 146, 159), (144, 136, 149), (129, 127, 140), + (120, 108, 132), (111, 89, 125), (106, 78, 118), (101, 68, 111), + (78, 21, 38), (66, 44, 47), (55, 67, 57), (68, 57, 73), + (82, 47, 89), (86, 53, 94), (90, 59, 100), (102, 81, 88), + (114, 109, 71), (129, 145, 82), (144, 155, 103), (160, 165, 124), + (153, 176, 124), (147, 187, 124), (153, 177, 121), (159, 167, 118), + (169, 155, 128), (173, 165, 129), (177, 176, 130), (173, 176, 133), + (170, 177, 136), (162, 169, 134), (155, 161, 133), (137, 139, 128), + (139, 128, 100), (138, 100, 38), (143, 99, 53), (148, 99, 69), + (154, 108, 76), (161, 118, 83), (170, 115, 85), (165, 106, 74), + (114, 44, 34), (105, 32, 33), (96, 20, 33), (84, 24, 21), + (72, 29, 10), (59, 20, 6), (46, 12, 3), (64, 16, 0), + (76, 33, 14), (88, 71, 28), (108, 83, 44), (128, 95, 60), + (130, 92, 67), (132, 90, 74), (129, 95, 86), (137, 102, 70), + (151, 81, 55), (132, 67, 38), (113, 54, 22), (108, 52, 29), + (103, 51, 37), (136, 87, 54), (142, 111, 91), (156, 133, 139), + (149, 164, 143), (180, 184, 159), (168, 190, 163), (156, 197, 167), + (158, 190, 162), (161, 184, 158), (160, 178, 154), (150, 185, 129), + (122, 177, 96), (133, 167, 100), (144, 157, 104), (152, 162, 109), + (160, 167, 115), (162, 161, 115), (160, 141, 108), (167, 123, 96), + (175, 121, 87), (155, 121, 93), (155, 119, 106), (156, 117, 120), + (165, 110, 142), (160, 88, 151), (139, 113, 148), (130, 132, 147), + (124, 154, 130), (113, 131, 123), (102, 109, 117), (105, 104, 113), + (109, 99, 110), (97, 85, 97), (89, 72, 106), (78, 63, 102), + (86, 68, 94), (135, 72, 54), (140, 76, 57), (145, 80, 60), + (137, 70, 54), (127, 63, 51), (119, 61, 50), (135, 63, 48), + (161, 93, 58), (154, 88, 60), (148, 83, 63), (144, 87, 62), + (141, 92, 62), (128, 96, 45), (110, 93, 41), (94, 104, 41), + (80, 120, 47), (113, 134, 101), (115, 123, 110), (118, 113, 120), + (126, 109, 127), (115, 93, 114), (123, 84, 115), (150, 100, 75), + (148, 133, 92), (156, 139, 85), (165, 146, 78), (165, 145, 95), + (167, 141, 104), (160, 150, 114), (153, 144, 115), (148, 147, 103), + (137, 129, 92), (122, 104, 68), (122, 105, 57), (122, 106, 46), + (139, 117, 57), (142, 129, 74), (159, 124, 86), (171, 139, 92), + (181, 125, 98), (179, 126, 100), (177, 127, 102), (179, 142, 98), + (163, 152, 122), (159, 157, 132), (145, 159, 133), (143, 142, 137), + (130, 124, 138), (131, 115, 125), (136, 121, 140), (149, 130, 162), + (152, 144, 167), (157, 153, 168), (171, 154, 170), (175, 149, 178), + (165, 178, 168), (158, 170, 166), (152, 162, 164), (144, 164, 137), + (147, 165, 125), (141, 161, 112), (143, 155, 109), (133, 154, 97), + (121, 136, 81), (119, 127, 86), (116, 113, 104), (100, 106, 102), + (110, 93, 112), (119, 79, 116), (105, 84, 123), (91, 82, 113), + (85, 81, 104), (87, 91, 103), (92, 87, 110), (107, 82, 112), + (106, 93, 110), (107, 102, 125), (115, 109, 137), (123, 112, 142), + (127, 122, 142), (141, 120, 139), (140, 102, 141), (118, 97, 138), + (117, 101, 130), (101, 98, 115), (64, 85, 86), (54, 99, 76), + (74, 58, 69), (88, 30, 26), (116, 35, 6), (117, 51, 17), + (104, 61, 27), (128, 79, 38), (145, 100, 59), (173, 113, 79), + (185, 121, 94), (201, 135, 113), (179, 143, 111), (180, 141, 160), + (184, 156, 178), (184, 159, 181), (192, 169, 187), (181, 184, 177), + (185, 194, 165), (177, 215, 154), (177, 214, 147), (167, 220, 138), + (153, 183, 119), (141, 143, 78), (112, 108, 45), (113, 80, 37), + (115, 81, 46), (98, 64, 97), (109, 57, 121), (129, 66, 123), + (126, 76, 125), (141, 84, 127), (147, 123, 119), (150, 145, 149), + (149, 142, 160), (139, 152, 134), (129, 160, 100), (116, 161, 78), + (116, 141, 76), (132, 136, 77), (145, 135, 74), (153, 114, 81) + ), + +// 298 2u0017pp1t.jpg +((199, 122, 218), (208, 121, 218), (202, 104, 202), (197, 87, 186), + (191, 99, 173), (185, 111, 160), (178, 126, 149), (171, 142, 138), + (196, 164, 123), (205, 163, 132), (214, 163, 142), (234, 163, 139), + (255, 164, 137), (235, 169, 110), (215, 174, 84), (215, 171, 77), + (215, 169, 71), (213, 114, 57), (209, 94, 54), (206, 74, 51), + (213, 85, 60), (221, 97, 69), (212, 109, 71), (204, 122, 74), + (185, 100, 63), (189, 89, 56), (193, 78, 49), (200, 71, 50), + (207, 65, 51), (206, 67, 49), (205, 70, 48), (210, 93, 50), + (210, 128, 72), (213, 136, 118), (213, 140, 116), (214, 145, 114), + (213, 121, 94), (212, 98, 74), (205, 80, 66), (198, 63, 59), + (193, 39, 39), (188, 49, 53), (184, 59, 67), (195, 51, 67), + (207, 43, 68), (204, 48, 64), (201, 54, 60), (197, 53, 45), + (189, 54, 48), (201, 68, 63), (207, 91, 78), (213, 114, 93), + (230, 126, 136), (247, 138, 179), (246, 152, 196), (246, 167, 214), + (247, 232, 193), (245, 223, 184), (244, 215, 175), (228, 192, 188), + (213, 169, 202), (208, 146, 210), (204, 124, 219), (169, 103, 193), + (161, 108, 186), (168, 126, 146), (176, 122, 138), (184, 118, 130), + (186, 113, 135), (188, 109, 140), (206, 98, 148), (202, 56, 163), + (194, 61, 127), (201, 83, 110), (208, 106, 94), (210, 86, 86), + (212, 66, 79), (201, 80, 100), (191, 95, 122), (172, 120, 124), + (168, 119, 102), (186, 129, 84), (185, 130, 86), (185, 132, 88), + (181, 130, 92), (177, 128, 96), (175, 131, 128), (170, 125, 154), + (169, 136, 181), (165, 145, 196), (162, 154, 211), (177, 151, 214), + (193, 148, 217), (190, 150, 203), (199, 142, 185), (204, 138, 174), + (195, 135, 143), (185, 114, 84), (169, 91, 106), (153, 69, 128), + (165, 80, 133), (178, 92, 139), (186, 91, 147), (192, 106, 145), + (201, 143, 139), (194, 159, 144), (187, 175, 149), (193, 172, 144), + (199, 170, 140), (204, 170, 125), (196, 169, 92), (192, 178, 71), + (207, 167, 79), (209, 126, 72), (220, 121, 81), (232, 117, 90), + (232, 69, 134), (252, 90, 150), (254, 92, 139), (255, 119, 135), + (238, 139, 170), (213, 166, 162), (189, 194, 154), (194, 201, 132), + (199, 209, 110), (195, 201, 95), (208, 207, 89), (201, 192, 87), + (203, 165, 58), (182, 108, 37), (182, 97, 54), (182, 86, 72), + (178, 93, 86), (172, 108, 134), (170, 111, 155), (180, 103, 159), + (187, 44, 172), (177, 57, 156), (168, 71, 140), (178, 91, 131), + (189, 112, 122), (206, 131, 110), (212, 157, 93), (217, 171, 75), + (230, 178, 76), (213, 154, 84), (213, 145, 84), (213, 137, 85), + (198, 141, 88), (192, 117, 88), (201, 108, 90), (204, 132, 94), + (181, 118, 111), (189, 107, 119), (197, 96, 128), (210, 98, 134), + (197, 105, 154), (218, 119, 173), (241, 117, 141), (221, 159, 122), + (217, 175, 77), (215, 205, 94), (223, 192, 91), (231, 180, 88), + (239, 180, 136), (243, 187, 170), (214, 180, 196), (227, 160, 227), + (179, 184, 203), (199, 197, 188), (219, 211, 174), (237, 229, 157), + (238, 241, 162), (246, 232, 169), (236, 218, 170), (217, 174, 132), + (204, 144, 74), (198, 133, 49), (181, 127, 27), (183, 114, 21), + (185, 128, 39), (193, 133, 60), (198, 141, 52), (210, 141, 64), + (192, 168, 46), (187, 161, 50), (183, 154, 54), (191, 153, 42), + (195, 146, 27), (191, 150, 44), (194, 135, 69), (198, 127, 65), + (195, 122, 67), (190, 115, 76), (205, 120, 81), (221, 116, 113), + (205, 131, 154), (207, 136, 178), (234, 140, 214), (214, 125, 235), + (208, 160, 244), (170, 171, 235), (199, 197, 210), (222, 236, 221), + (230, 228, 203), (245, 229, 169), (250, 206, 159), (237, 197, 146), + (234, 205, 139), (226, 206, 145), (201, 201, 127), (202, 208, 112), + (212, 222, 125), (216, 222, 152), (220, 215, 151), (236, 188, 139), + (229, 158, 166), (198, 132, 180), (180, 105, 170), (173, 80, 169), + (189, 91, 150), (193, 104, 148), (194, 130, 156), (219, 156, 141), + (229, 170, 136), (222, 174, 134), (223, 185, 140), (194, 164, 188), + (216, 149, 220), (187, 132, 236), (175, 117, 238), (145, 89, 226), + (158, 84, 239), (197, 71, 215), (229, 115, 185), (233, 133, 183), + (245, 130, 195), (215, 143, 209), (176, 167, 222), (190, 131, 189), + (190, 137, 181), (202, 151, 148), (192, 153, 110), (193, 150, 99), + (192, 170, 97), (199, 179, 120), (209, 169, 118), (207, 162, 95), + (208, 158, 85), (209, 167, 81), (201, 157, 70), (196, 147, 55), + (203, 143, 57), (206, 158, 58), (198, 183, 68), (198, 172, 61) + ), + +// 299 2u0017t.jpg +((48, 99, 204), (50, 97, 205), (52, 101, 208), (55, 106, 211), + (62, 94, 200), (70, 82, 190), (64, 86, 191), (59, 91, 192), + (81, 117, 179), (75, 159, 183), (69, 201, 187), (70, 208, 174), + (71, 216, 161), (48, 186, 143), (26, 157, 125), (17, 160, 128), + (8, 163, 131), (33, 141, 144), (40, 139, 151), (47, 138, 159), + (56, 133, 192), (65, 128, 225), (67, 128, 226), (69, 128, 228), + (51, 121, 216), (48, 124, 201), (45, 127, 187), (41, 147, 190), + (38, 168, 194), (46, 177, 193), (54, 187, 192), (64, 201, 183), + (74, 168, 154), (63, 126, 144), (52, 137, 141), (41, 148, 138), + (36, 155, 123), (31, 162, 108), (28, 160, 105), (26, 159, 102), + (34, 132, 75), (42, 124, 65), (51, 117, 56), (60, 121, 40), + (70, 125, 24), (71, 125, 19), (72, 126, 14), (85, 131, 22), + (80, 130, 45), (71, 125, 91), (63, 123, 111), (55, 122, 131), + (49, 104, 146), (44, 86, 162), (35, 89, 166), (27, 93, 171), + (35, 53, 161), (31, 39, 152), (27, 26, 143), (37, 59, 135), + (47, 93, 127), (46, 98, 108), (46, 104, 89), (11, 94, 86), + (6, 91, 94), (42, 72, 136), (46, 68, 134), (50, 65, 132), + (50, 57, 139), (51, 49, 146), (52, 77, 161), (44, 94, 189), + (31, 113, 186), (27, 104, 162), (23, 96, 139), (21, 101, 107), + (20, 107, 75), (21, 118, 64), (22, 130, 54), (0, 113, 54), + (19, 102, 48), (61, 101, 74), (67, 111, 93), (74, 121, 113), + (62, 121, 117), (50, 122, 121), (23, 132, 139), (10, 127, 145), + (55, 137, 161), (60, 137, 173), (65, 137, 185), (65, 143, 189), + (66, 149, 193), (48, 167, 197), (49, 147, 192), (60, 135, 190), + (56, 116, 179), (65, 114, 173), (64, 113, 161), (64, 112, 150), + (73, 116, 144), (82, 121, 138), (98, 129, 131), (96, 145, 124), + (84, 141, 124), (86, 141, 106), (88, 141, 89), (88, 139, 87), + (88, 138, 85), (87, 145, 69), (81, 137, 64), (68, 104, 60), + (53, 59, 55), (84, 94, 57), (91, 97, 61), (99, 100, 66), + (85, 94, 29), (85, 70, 29), (52, 37, 40), (28, 39, 69), + (37, 125, 12), (35, 138, 21), (33, 151, 31), (37, 135, 26), + (42, 120, 21), (24, 85, 43), (0, 61, 60), (3, 74, 92), + (15, 90, 111), (30, 118, 122), (31, 115, 116), (32, 112, 111), + (46, 106, 94), (60, 85, 107), (82, 118, 106), (80, 128, 90), + (72, 135, 116), (63, 132, 137), (54, 129, 158), (54, 135, 160), + (55, 142, 162), (59, 155, 171), (65, 168, 199), (54, 158, 211), + (54, 137, 205), (47, 108, 191), (49, 108, 192), (51, 109, 193), + (71, 98, 179), (59, 85, 162), (57, 96, 171), (54, 100, 178), + (69, 98, 224), (73, 110, 222), (78, 122, 221), (93, 136, 228), + (81, 139, 239), (68, 153, 210), (47, 166, 208), (57, 175, 203), + (73, 181, 209), (60, 202, 204), (60, 202, 196), (60, 202, 188), + (39, 201, 180), (30, 210, 171), (24, 186, 162), (34, 160, 148), + (44, 157, 155), (52, 165, 160), (60, 174, 166), (60, 159, 178), + (51, 159, 198), (61, 170, 201), (55, 181, 204), (36, 192, 181), + (0, 200, 170), (12, 205, 152), (12, 183, 130), (30, 169, 140), + (48, 151, 130), (77, 138, 130), (80, 143, 112), (78, 140, 91), + (67, 119, 80), (60, 119, 74), (53, 120, 69), (57, 131, 70), + (45, 158, 42), (50, 176, 32), (55, 210, 48), (80, 201, 74), + (72, 154, 106), (75, 175, 105), (78, 155, 119), (81, 173, 134), + (51, 202, 131), (21, 225, 128), (49, 209, 85), (56, 189, 96), + (73, 146, 116), (69, 110, 132), (57, 94, 162), (47, 89, 189), + (50, 76, 189), (47, 71, 177), (50, 68, 168), (58, 86, 160), + (64, 110, 160), (65, 139, 138), (51, 158, 104), (59, 159, 45), + (75, 152, 38), (60, 151, 11), (79, 120, 0), (89, 113, 15), + (78, 116, 39), (54, 146, 71), (51, 157, 121), (70, 158, 144), + (73, 144, 150), (67, 146, 176), (66, 134, 171), (71, 121, 194), + (66, 115, 174), (48, 104, 163), (48, 106, 144), (33, 95, 144), + (9, 72, 115), (18, 66, 114), (22, 22, 96), (2, 3, 83), + (21, 30, 107), (36, 36, 150), (52, 61, 178), (32, 74, 186), + (43, 77, 184), (47, 92, 175), (37, 120, 160), (34, 136, 138), + (41, 149, 134), (59, 134, 137), (80, 143, 112), (88, 159, 81), + (78, 190, 54), (96, 190, 44), (83, 173, 59), (94, 147, 75), + (83, 135, 97), (71, 124, 130), (60, 122, 147), (70, 109, 152), + (62, 98, 134), (58, 107, 137), (63, 116, 122), (59, 114, 74) + ), + +// 300 2u0018t.jpg +((135, 38, 171), (122, 35, 130), (138, 44, 114), (155, 54, 98), + (175, 42, 103), (196, 31, 108), (194, 23, 124), (192, 16, 140), + (177, 39, 135), (177, 55, 126), (178, 72, 118), (172, 72, 107), + (167, 73, 97), (158, 71, 100), (149, 69, 104), (142, 69, 101), + (136, 70, 98), (145, 88, 143), (151, 76, 155), (157, 64, 168), + (147, 58, 153), (138, 53, 138), (133, 58, 139), (128, 64, 140), + (124, 42, 152), (123, 32, 163), (122, 23, 175), (129, 31, 185), + (136, 39, 196), (136, 41, 191), (137, 44, 187), (145, 42, 147), + (157, 46, 123), (123, 41, 115), (114, 51, 104), (106, 61, 94), + (103, 61, 88), (100, 61, 82), (109, 68, 70), (119, 76, 59), + (147, 108, 39), (167, 119, 46), (187, 131, 54), (191, 108, 62), + (195, 85, 70), (194, 77, 82), (194, 70, 94), (178, 71, 101), + (149, 53, 117), (98, 25, 166), (109, 16, 153), (121, 8, 140), + (130, 14, 121), (139, 20, 102), (147, 26, 94), (155, 32, 87), + (139, 67, 78), (157, 99, 85), (175, 131, 92), (181, 117, 95), + (187, 104, 98), (187, 98, 118), (188, 92, 138), (183, 90, 160), + (196, 60, 168), (165, 38, 177), (152, 41, 186), (140, 44, 195), + (150, 46, 175), (161, 48, 156), (178, 49, 132), (184, 32, 107), + (194, 33, 103), (185, 47, 99), (176, 62, 96), (152, 72, 89), + (129, 83, 83), (124, 76, 74), (120, 69, 65), (107, 64, 84), + (110, 68, 80), (122, 134, 96), (143, 153, 97), (165, 173, 98), + (159, 176, 106), (154, 180, 115), (142, 180, 107), (141, 177, 113), + (150, 166, 117), (145, 159, 111), (140, 152, 106), (138, 154, 103), + (136, 157, 101), (151, 161, 108), (155, 145, 110), (150, 146, 98), + (139, 126, 92), (143, 91, 77), (156, 62, 62), (169, 34, 48), + (177, 29, 37), (185, 25, 27), (188, 4, 28), (159, 27, 40), + (166, 26, 75), (168, 27, 88), (171, 29, 101), (166, 28, 89), + (161, 27, 77), (166, 19, 61), (160, 31, 51), (151, 37, 36), + (164, 53, 23), (152, 41, 58), (140, 46, 61), (128, 52, 64), + (131, 59, 73), (132, 64, 79), (134, 67, 76), (139, 66, 83), + (174, 59, 137), (166, 57, 142), (159, 56, 147), (164, 57, 149), + (170, 59, 151), (180, 49, 153), (165, 45, 134), (155, 56, 102), + (154, 67, 76), (180, 88, 37), (172, 87, 46), (165, 86, 56), + (133, 91, 77), (139, 119, 86), (142, 152, 79), (146, 127, 97), + (167, 81, 130), (165, 85, 165), (163, 89, 200), (152, 83, 197), + (142, 77, 195), (166, 88, 198), (182, 107, 225), (167, 121, 209), + (200, 153, 171), (170, 150, 126), (166, 147, 123), (163, 145, 121), + (152, 156, 106), (153, 153, 99), (153, 147, 95), (180, 148, 101), + (208, 100, 97), (192, 92, 114), (177, 84, 131), (169, 74, 138), + (155, 43, 145), (147, 43, 138), (152, 68, 145), (167, 81, 130), + (153, 88, 122), (145, 121, 83), (149, 122, 85), (153, 123, 87), + (178, 108, 82), (212, 70, 92), (204, 57, 125), (208, 26, 103), + (159, 32, 109), (146, 33, 108), (134, 34, 107), (117, 37, 108), + (119, 47, 97), (109, 49, 83), (102, 53, 85), (93, 38, 77), + (91, 19, 92), (77, 14, 105), (110, 37, 116), (125, 25, 98), + (131, 16, 107), (139, 29, 92), (130, 48, 86), (112, 52, 78), + (143, 49, 83), (144, 48, 74), (145, 48, 65), (137, 48, 52), + (118, 34, 50), (107, 23, 56), (94, 51, 61), (94, 57, 48), + (109, 85, 59), (133, 85, 62), (129, 85, 72), (109, 79, 81), + (119, 51, 128), (124, 57, 162), (134, 39, 169), (137, 39, 162), + (134, 32, 132), (136, 24, 108), (155, 33, 110), (147, 52, 120), + (138, 63, 122), (148, 68, 103), (153, 78, 98), (155, 101, 89), + (159, 76, 104), (161, 73, 121), (151, 56, 124), (140, 63, 131), + (137, 49, 125), (113, 40, 132), (88, 43, 136), (104, 17, 132), + (149, 4, 123), (172, 22, 109), (167, 35, 108), (154, 20, 81), + (150, 34, 57), (127, 25, 73), (93, 6, 74), (78, 6, 69), + (91, 16, 81), (100, 39, 81), (124, 37, 88), (168, 36, 96), + (180, 41, 80), (192, 65, 84), (195, 66, 84), (194, 58, 94), + (172, 57, 98), (151, 57, 117), (148, 51, 120), (162, 45, 123), + (164, 47, 118), (173, 27, 108), (173, 35, 86), (176, 43, 70), + (179, 43, 47), (184, 53, 11), (195, 66, 24), (186, 76, 25), + (181, 53, 42), (180, 54, 57), (176, 45, 59), (180, 51, 71), + (179, 45, 95), (165, 55, 116), (169, 63, 138), (171, 66, 151), + (174, 74, 126), (187, 81, 101), (182, 80, 75), (187, 77, 24) + ), + + +// 301 2u0020pp1t.jpg +((115, 229, 180), (98, 154, 203), (102, 136, 219), (107, 118, 236), + (119, 112, 233), (131, 107, 231), (128, 105, 234), (125, 103, 237), + (113, 114, 241), (131, 137, 240), (150, 161, 240), (150, 162, 181), + (151, 163, 123), (142, 160, 125), (134, 157, 128), (122, 148, 150), + (110, 139, 173), (134, 150, 227), (125, 153, 231), (116, 157, 236), + (143, 147, 193), (170, 138, 151), (175, 126, 133), (181, 115, 116), + (208, 159, 103), (196, 153, 118), (185, 147, 134), (177, 148, 146), + (169, 149, 158), (156, 126, 197), (144, 104, 237), (128, 98, 230), + (112, 123, 241), (106, 176, 245), (105, 191, 228), (105, 207, 211), + (119, 211, 193), (133, 215, 175), (142, 212, 173), (152, 210, 172), + (158, 205, 163), (143, 199, 148), (128, 194, 133), (125, 204, 145), + (123, 214, 157), (124, 219, 160), (126, 224, 163), (124, 215, 172), + (121, 214, 185), (121, 222, 182), (123, 216, 180), (126, 211, 178), + (130, 209, 182), (134, 207, 187), (131, 204, 192), (129, 201, 198), + (151, 200, 196), (163, 201, 178), (176, 203, 160), (180, 198, 157), + (185, 193, 154), (175, 185, 148), (166, 178, 142), (152, 178, 141), + (147, 184, 115), (128, 206, 130), (139, 203, 137), (151, 200, 144), + (163, 196, 146), (176, 193, 148), (207, 162, 131), (215, 154, 125), + (232, 168, 94), (220, 161, 93), (208, 154, 92), (190, 151, 106), + (173, 149, 121), (175, 157, 126), (178, 165, 131), (159, 192, 149), + (136, 230, 168), (127, 240, 184), (117, 243, 182), (108, 247, 180), + (106, 243, 194), (104, 239, 209), (115, 228, 200), (124, 230, 207), + (166, 234, 209), (159, 224, 191), (153, 215, 174), (149, 213, 171), + (145, 212, 168), (143, 210, 166), (138, 218, 159), (153, 210, 157), + (171, 202, 132), (152, 159, 108), (154, 159, 107), (156, 159, 106), + (151, 161, 110), (147, 163, 114), (134, 165, 134), (98, 156, 202), + (73, 202, 164), (90, 211, 165), (107, 220, 166), (93, 215, 180), + (79, 210, 194), (92, 206, 207), (96, 200, 209), (86, 211, 203), + (84, 229, 196), (113, 231, 171), (119, 231, 178), (125, 231, 185), + (126, 228, 189), (120, 233, 177), (117, 220, 165), (101, 238, 170), + (94, 245, 152), (97, 240, 162), (100, 236, 172), (109, 228, 184), + (118, 220, 196), (127, 220, 209), (127, 215, 227), (111, 211, 227), + (86, 209, 242), (53, 185, 233), (60, 178, 240), (68, 171, 248), + (75, 188, 230), (84, 198, 224), (118, 207, 221), (113, 212, 207), + (131, 203, 163), (128, 191, 142), (125, 180, 122), (124, 179, 115), + (123, 179, 108), (128, 183, 116), (138, 188, 129), (146, 176, 138), + (153, 186, 157), (120, 195, 188), (113, 183, 198), (107, 171, 209), + (119, 187, 196), (154, 178, 165), (147, 163, 116), (145, 137, 100), + (173, 120, 80), (175, 124, 82), (177, 128, 85), (196, 117, 87), + (200, 126, 89), (196, 128, 83), (209, 131, 83), (227, 159, 84), + (235, 173, 90), (193, 190, 97), (183, 202, 107), (174, 214, 118), + (151, 242, 162), (118, 232, 163), (107, 223, 178), (82, 207, 199), + (72, 185, 225), (78, 173, 231), (85, 161, 237), (95, 144, 239), + (87, 147, 220), (91, 158, 228), (97, 157, 227), (120, 179, 219), + (132, 191, 199), (136, 204, 165), (130, 188, 163), (137, 191, 142), + (147, 188, 132), (149, 180, 120), (153, 166, 123), (172, 160, 120), + (194, 176, 110), (193, 187, 110), (192, 198, 110), (166, 213, 121), + (148, 221, 139), (124, 232, 146), (129, 229, 157), (124, 228, 167), + (107, 217, 190), (97, 214, 208), (95, 222, 213), (88, 228, 217), + (88, 221, 230), (85, 222, 230), (70, 204, 241), (56, 195, 238), + (62, 170, 234), (73, 168, 252), (87, 165, 248), (83, 153, 248), + (61, 151, 247), (59, 138, 241), (72, 140, 241), (79, 142, 247), + (89, 149, 245), (94, 148, 244), (106, 148, 234), (118, 130, 242), + (101, 145, 234), (103, 147, 212), (121, 169, 209), (123, 192, 173), + (122, 186, 149), (144, 186, 123), (143, 193, 108), (134, 181, 113), + (133, 184, 105), (142, 170, 96), (152, 175, 103), (184, 177, 89), + (194, 147, 65), (190, 123, 81), (186, 128, 88), (175, 149, 132), + (168, 169, 155), (107, 175, 198), (85, 173, 213), (71, 177, 235), + (65, 156, 247), (51, 151, 229), (62, 149, 229), (83, 168, 223), + (83, 191, 217), (84, 217, 212), (97, 233, 229), (104, 246, 222), + (120, 234, 226), (128, 223, 227), (130, 236, 232), (134, 233, 228), + (146, 236, 224), (130, 246, 211), (136, 220, 187), (152, 209, 176), + (157, 193, 167), (161, 166, 136), (157, 147, 112), (165, 145, 86), + (158, 139, 83), (133, 168, 110), (117, 231, 159), (114, 203, 123) + ), + +// 302 2u0020t.jpg +((178, 61, 28), (160, 61, 30), (159, 60, 38), (158, 60, 47), + (153, 41, 46), (148, 22, 46), (145, 14, 37), (142, 6, 28), + (117, 18, 23), (110, 27, 42), (104, 36, 61), (100, 28, 74), + (96, 21, 88), (97, 20, 103), (99, 19, 118), (106, 16, 111), + (114, 14, 104), (138, 23, 80), (143, 20, 66), (148, 18, 52), + (138, 24, 53), (128, 30, 55), (135, 29, 59), (143, 29, 63), + (159, 11, 61), (154, 19, 66), (150, 27, 71), (144, 32, 70), + (139, 38, 70), (129, 42, 80), (119, 46, 91), (103, 45, 106), + (109, 55, 115), (110, 73, 127), (113, 67, 128), (117, 62, 130), + (115, 59, 128), (113, 56, 127), (116, 58, 120), (119, 60, 114), + (103, 66, 109), (107, 64, 113), (111, 62, 117), (123, 56, 101), + (136, 50, 85), (136, 48, 71), (137, 47, 57), (132, 35, 66), + (125, 35, 87), (70, 28, 112), (41, 34, 135), (12, 41, 159), + (25, 76, 161), (39, 112, 163), (46, 116, 151), (53, 121, 140), + (95, 110, 129), (101, 93, 123), (108, 77, 118), (111, 86, 120), + (115, 95, 123), (106, 99, 131), (98, 104, 140), (96, 122, 139), + (91, 133, 157), (55, 122, 164), (69, 104, 141), (84, 87, 118), + (82, 72, 105), (81, 57, 93), (107, 57, 82), (108, 55, 51), + (156, 76, 27), (155, 84, 16), (155, 93, 6), (168, 93, 3), + (181, 94, 1), (180, 96, 7), (180, 98, 14), (173, 102, 12), + (172, 106, 9), (164, 119, 36), (172, 107, 24), (181, 96, 13), + (185, 83, 15), (190, 70, 18), (187, 64, 31), (170, 68, 30), + (150, 123, 32), (147, 135, 23), (145, 148, 15), (124, 153, 12), + (103, 159, 10), (133, 144, 6), (144, 140, 15), (133, 121, 19), + (133, 101, 24), (120, 53, 86), (129, 35, 90), (139, 18, 95), + (151, 18, 93), (163, 19, 91), (163, 11, 84), (153, 19, 72), + (163, 26, 52), (141, 24, 58), (120, 23, 64), (117, 27, 75), + (114, 31, 87), (94, 53, 111), (99, 59, 121), (90, 82, 129), + (78, 86, 151), (87, 118, 164), (93, 119, 166), (100, 121, 168), + (103, 101, 166), (72, 76, 165), (54, 79, 145), (39, 81, 131), + (15, 82, 152), (22, 87, 160), (30, 92, 169), (48, 96, 167), + (67, 101, 165), (97, 97, 149), (113, 96, 138), (125, 81, 116), + (156, 73, 103), (178, 37, 43), (173, 28, 39), (168, 20, 36), + (165, 10, 42), (169, 22, 50), (163, 26, 46), (158, 37, 54), + (113, 54, 86), (101, 63, 100), (90, 72, 114), (89, 76, 118), + (89, 81, 122), (98, 104, 138), (90, 122, 135), (50, 123, 114), + (49, 120, 116), (78, 82, 145), (83, 81, 147), (88, 81, 149), + (101, 79, 128), (110, 81, 139), (113, 72, 142), (139, 70, 137), + (144, 44, 116), (150, 39, 105), (157, 35, 94), (161, 17, 79), + (158, 13, 78), (157, 14, 78), (157, 16, 82), (138, 30, 90), + (125, 31, 84), (113, 46, 53), (121, 42, 51), (129, 39, 49), + (126, 19, 63), (142, 20, 61), (139, 20, 48), (144, 10, 35), + (167, 27, 38), (166, 38, 40), (166, 49, 42), (163, 73, 38), + (141, 86, 47), (112, 82, 108), (93, 67, 104), (60, 58, 123), + (58, 72, 135), (39, 87, 153), (39, 108, 175), (56, 104, 176), + (68, 60, 159), (83, 63, 134), (123, 53, 126), (137, 26, 120), + (121, 15, 89), (121, 18, 82), (121, 21, 75), (113, 11, 76), + (109, 20, 76), (118, 38, 97), (133, 38, 104), (142, 14, 97), + (159, 8, 101), (169, 13, 76), (186, 46, 59), (190, 58, 37), + (194, 98, 22), (193, 113, 14), (193, 106, 9), (180, 83, 14), + (173, 55, 5), (167, 31, 35), (159, 31, 32), (160, 36, 34), + (150, 51, 30), (158, 64, 38), (138, 75, 21), (137, 98, 23), + (141, 94, 12), (141, 95, 10), (145, 106, 13), (154, 114, 19), + (152, 114, 41), (103, 89, 60), (106, 91, 70), (102, 70, 75), + (106, 60, 63), (118, 71, 55), (165, 76, 36), (193, 85, 21), + (194, 74, 13), (198, 74, 14), (199, 67, 18), (176, 56, 6), + (185, 36, 30), (174, 31, 25), (150, 20, 30), (154, 13, 29), + (177, 20, 11), (183, 61, 12), (172, 94, 28), (170, 103, 35), + (163, 97, 37), (161, 87, 88), (127, 91, 117), (121, 107, 107), + (114, 86, 100), (115, 86, 88), (153, 80, 45), (164, 80, 33), + (147, 63, 53), (144, 56, 98), (124, 53, 111), (124, 80, 133), + (115, 88, 143), (109, 95, 157), (101, 105, 153), (103, 106, 149), + (97, 110, 154), (98, 107, 150), (83, 90, 132), (65, 108, 89), + (68, 97, 113), (72, 60, 134), (88, 43, 112), (71, 48, 126) + ), + +// 303 2u0024t.jpg +((14, 80, 34), (48, 76, 62), (69, 60, 71), (91, 44, 80), + (118, 37, 87), (145, 30, 95), (149, 48, 90), (154, 67, 86), + (157, 108, 67), (162, 114, 55), (167, 121, 44), (161, 106, 45), + (156, 92, 46), (164, 79, 47), (172, 67, 48), (162, 60, 49), + (152, 54, 51), (168, 98, 38), (177, 112, 25), (186, 126, 12), + (185, 120, 27), (185, 115, 43), (187, 115, 54), (189, 115, 66), + (180, 34, 45), (167, 44, 58), (155, 54, 72), (142, 66, 73), + (129, 78, 75), (123, 82, 70), (118, 87, 66), (112, 96, 62), + (109, 91, 77), (86, 74, 86), (82, 57, 90), (78, 41, 95), + (68, 31, 93), (58, 22, 92), (60, 14, 93), (62, 6, 95), + (67, 19, 59), (73, 16, 57), (79, 14, 56), (90, 34, 61), + (101, 55, 66), (113, 68, 62), (126, 81, 58), (151, 101, 50), + (159, 114, 33), (148, 121, 34), (154, 113, 24), (160, 105, 15), + (124, 96, 19), (88, 87, 23), (69, 63, 20), (51, 39, 17), + (55, 24, 56), (68, 42, 59), (82, 60, 62), (80, 94, 52), + (78, 128, 43), (80, 123, 29), (83, 118, 16), (91, 102, 34), + (115, 94, 65), (96, 68, 109), (89, 54, 106), (82, 40, 103), + (83, 48, 105), (84, 57, 108), (90, 76, 102), (100, 82, 94), + (98, 66, 79), (92, 55, 62), (86, 44, 45), (85, 36, 55), + (84, 28, 65), (78, 31, 74), (72, 34, 83), (62, 33, 89), + (59, 28, 96), (73, 11, 96), (85, 13, 67), (97, 15, 38), + (111, 34, 30), (125, 54, 22), (160, 59, 7), (149, 82, 30), + (190, 107, 5), (187, 101, 21), (185, 96, 38), (180, 100, 46), + (176, 104, 54), (171, 105, 57), (159, 103, 68), (161, 89, 64), + (168, 77, 56), (156, 92, 80), (151, 99, 69), (147, 107, 58), + (138, 110, 57), (130, 113, 57), (131, 107, 69), (121, 104, 74), + (132, 87, 68), (134, 69, 74), (137, 52, 81), (144, 41, 78), + (152, 31, 76), (148, 24, 86), (148, 9, 76), (142, 24, 76), + (149, 46, 47), (123, 87, 51), (121, 89, 45), (119, 92, 39), + (119, 99, 38), (133, 113, 40), (142, 94, 58), (141, 91, 68), + (120, 86, 76), (110, 73, 73), (100, 60, 71), (103, 54, 67), + (107, 49, 63), (101, 14, 48), (90, 6, 40), (85, 0, 34), + (78, 6, 54), (91, 20, 54), (96, 25, 61), (101, 31, 68), + (108, 61, 71), (121, 81, 69), (133, 92, 60), (125, 99, 40), + (128, 98, 62), (120, 97, 68), (113, 97, 74), (118, 94, 90), + (123, 91, 106), (106, 74, 95), (88, 80, 95), (84, 76, 91), + (83, 71, 91), (91, 51, 85), (95, 52, 82), (99, 53, 79), + (96, 65, 80), (106, 70, 72), (99, 84, 43), (95, 65, 27), + (75, 28, 38), (81, 21, 40), (87, 14, 43), (79, 37, 39), + (104, 61, 10), (133, 87, 37), (153, 93, 39), (162, 104, 40), + (161, 107, 35), (175, 118, 63), (178, 117, 66), (181, 117, 69), + (193, 107, 82), (206, 123, 81), (219, 122, 90), (203, 118, 87), + (143, 101, 103), (122, 107, 101), (102, 113, 99), (112, 112, 84), + (133, 120, 75), (143, 118, 51), (148, 121, 44), (167, 126, 74), + (172, 117, 76), (157, 108, 91), (145, 102, 83), (120, 91, 73), + (110, 83, 76), (100, 62, 75), (111, 52, 70), (99, 21, 60), + (100, 6, 56), (104, 9, 52), (108, 12, 49), (95, 15, 40), + (88, 17, 49), (93, 11, 49), (103, 15, 65), (123, 15, 77), + (119, 6, 84), (130, 1, 81), (139, 12, 101), (133, 33, 87), + (122, 45, 77), (109, 63, 73), (105, 65, 74), (104, 79, 74), + (113, 81, 56), (120, 73, 47), (91, 53, 30), (90, 57, 24), + (73, 64, 31), (42, 52, 27), (20, 36, 7), (13, 81, 24), + (21, 55, 41), (57, 30, 61), (70, 51, 44), (61, 103, 40), + (53, 107, 9), (36, 107, 37), (45, 116, 40), (69, 102, 47), + (79, 70, 89), (74, 45, 73), (72, 22, 75), (65, 27, 88), + (79, 29, 88), (92, 43, 90), (83, 53, 91), (80, 43, 94), + (80, 39, 109), (75, 34, 110), (72, 34, 107), (66, 27, 84), + (79, 44, 84), (90, 48, 84), (94, 70, 84), (109, 84, 88), + (104, 91, 83), (97, 91, 75), (125, 80, 57), (136, 81, 42), + (142, 103, 38), (133, 120, 15), (104, 138, 0), (85, 144, 16), + (79, 151, 15), (84, 145, 8), (118, 128, 5), (134, 118, 30), + (131, 113, 41), (138, 126, 44), (153, 125, 41), (150, 118, 45), + (155, 105, 54), (130, 94, 78), (121, 78, 97), (130, 65, 89), + (131, 59, 79), (125, 75, 66), (100, 69, 87), (102, 69, 80) + ), + +// 304 gradient0000.jpg +((244, 0, 12), (255, 0, 102), (240, 0, 160), (225, 0, 218), + (223, 0, 232), (221, 1, 247), (221, 0, 250), (221, 0, 254), + (229, 0, 241), (242, 0, 197), (255, 0, 154), (229, 0, 108), + (204, 0, 63), (171, 0, 33), (139, 0, 3), (131, 2, 2), + (124, 5, 1), (111, 10, 0), (117, 7, 0), (123, 4, 0), + (123, 4, 0), (123, 4, 0), (120, 7, 0), (118, 10, 0), + (119, 11, 0), (124, 6, 0), (129, 1, 0), (137, 0, 2), + (145, 0, 5), (144, 0, 2), (144, 0, 0), (134, 0, 1), + (127, 4, 0), (124, 5, 1), (124, 5, 0), (125, 6, 0), + (135, 3, 2), (145, 0, 5), (173, 0, 28), (202, 0, 52), + (254, 0, 117), (225, 0, 165), (197, 0, 214), (157, 0, 228), + (118, 0, 242), (115, 1, 248), (113, 2, 255), (114, 1, 255), + (118, 0, 242), (202, 0, 84), (173, 0, 50), (145, 0, 17), + (128, 7, 9), (112, 14, 1), (112, 14, 1), (112, 14, 1), + (130, 0, 0), (149, 0, 20), (169, 0, 41), (187, 0, 59), + (205, 0, 77), (229, 0, 99), (254, 0, 122), (245, 0, 215), + (241, 1, 224), (227, 0, 255), (221, 0, 240), (215, 0, 226), + (220, 0, 222), (225, 0, 218), (254, 0, 160), (246, 1, 81), + (244, 60, 10), (239, 48, 5), (235, 37, 0), (231, 33, 0), + (227, 29, 0), (231, 30, 0), (236, 31, 0), (239, 52, 1), + (252, 55, 21), (251, 13, 10), (247, 13, 5), (243, 13, 0), + (238, 10, 0), (234, 7, 0), (228, 22, 0), (228, 22, 0), + (233, 39, 1), (226, 49, 0), (220, 60, 0), (217, 69, 0), + (215, 78, 0), (220, 100, 37), (242, 77, 83), (255, 0, 130), + (255, 0, 174), (253, 0, 189), (253, 0, 150), (254, 0, 112), + (253, 0, 93), (252, 0, 75), (242, 0, 16), (231, 11, 0), + (131, 6, 0), (129, 3, 0), (128, 0, 0), (137, 2, 0), + (146, 4, 0), (156, 0, 3), (230, 0, 2), (236, 3, 0), + (233, 13, 0), (243, 18, 0), (242, 13, 0), (242, 8, 1), + (245, 1, 13), (238, 0, 23), (198, 0, 35), (147, 0, 8), + (124, 5, 1), (126, 2, 0), (128, 0, 0), (133, 0, 0), + (139, 1, 0), (151, 0, 9), (209, 0, 55), (220, 0, 102), + (203, 1, 209), (217, 0, 253), (217, 0, 253), (217, 0, 253), + (220, 0, 255), (221, 0, 254), (225, 0, 255), (224, 0, 254), + (217, 0, 255), (216, 0, 253), (215, 0, 252), (211, 0, 253), + (207, 0, 254), (206, 0, 255), (163, 0, 237), (119, 0, 244), + (110, 0, 247), (115, 1, 247), (129, 0, 239), (143, 0, 232), + (160, 0, 222), (162, 0, 225), (152, 0, 241), (116, 6, 255), + (91, 12, 254), (81, 17, 254), (71, 23, 255), (87, 14, 254), + (101, 4, 255), (119, 2, 254), (195, 4, 255), (206, 1, 254), + (217, 0, 255), (231, 0, 252), (233, 0, 241), (236, 0, 230), + (241, 0, 227), (255, 0, 180), (255, 0, 132), (254, 0, 124), + (254, 0, 174), (226, 0, 194), (199, 0, 215), (188, 1, 216), + (190, 0, 222), (194, 0, 223), (239, 1, 157), (205, 1, 90), + (202, 0, 52), (149, 1, 17), (140, 0, 11), (147, 0, 8), + (169, 0, 41), (203, 0, 60), (208, 0, 82), (255, 0, 130), + (246, 0, 221), (242, 0, 227), (238, 0, 233), (231, 0, 252), + (225, 0, 254), (220, 0, 254), (217, 0, 253), (214, 0, 254), + (207, 0, 255), (204, 0, 255), (137, 0, 254), (109, 9, 255), + (101, 13, 255), (97, 17, 255), (100, 12, 255), (103, 7, 254), + (106, 5, 255), (131, 0, 251), (196, 3, 254), (207, 0, 255), + (210, 0, 255), (215, 0, 254), (216, 1, 255), (210, 0, 255), + (204, 0, 255), (141, 0, 239), (116, 0, 255), (116, 0, 247), + (143, 0, 232), (187, 0, 229), (195, 0, 224), (220, 0, 222), + (254, 1, 172), (255, 0, 135), (255, 0, 118), (255, 0, 118), + (255, 0, 122), (255, 0, 120), (254, 0, 112), (255, 0, 107), + (255, 0, 106), (255, 0, 102), (252, 0, 75), (244, 0, 52), + (235, 0, 33), (239, 0, 41), (240, 0, 63), (255, 0, 102), + (255, 1, 161), (254, 0, 210), (246, 0, 223), (245, 0, 215), + (255, 0, 180), (255, 0, 128), (254, 31, 94), (212, 100, 86), + (221, 101, 38), (229, 84, 1), (217, 77, 0), (215, 35, 0), + (234, 1, 33), (250, 0, 100), (255, 0, 164), (237, 0, 228), + (233, 0, 250), (225, 0, 255), (215, 0, 252), (221, 0, 217), + (227, 0, 211), (255, 0, 130), (242, 0, 58), (234, 29, 0) + ), + +// 305 0t0507.jpg +((30, 61, 143), (2, 60, 157), (1, 49, 120), (1, 39, 84), + (15, 36, 82), (29, 33, 80), (44, 34, 108), (60, 35, 137), + (133, 77, 164), (107, 83, 178), (82, 89, 193), (69, 62, 164), + (56, 36, 135), (66, 39, 145), (77, 43, 155), (88, 54, 170), + (99, 65, 185), (144, 133, 193), (171, 181, 208), (198, 229, 223), + (202, 241, 215), (207, 253, 207), (200, 250, 201), (193, 247, 195), + (214, 228, 215), (207, 213, 209), (200, 199, 204), (197, 192, 204), + (195, 186, 205), (185, 183, 199), (175, 181, 193), (176, 181, 187), + (170, 177, 193), (165, 173, 186), (150, 173, 164), (135, 174, 143), + (111, 157, 134), (88, 141, 125), (59, 135, 155), (30, 129, 186), + (6, 95, 161), (3, 92, 147), (0, 89, 134), (7, 61, 100), + (14, 34, 67), (20, 26, 71), (27, 18, 75), (25, 22, 103), + (49, 33, 131), (35, 45, 142), (33, 36, 125), (32, 27, 109), + (19, 18, 87), (7, 9, 66), (7, 22, 81), (7, 36, 96), + (5, 61, 158), (49, 81, 167), (94, 102, 177), (118, 120, 177), + (143, 138, 178), (150, 162, 182), (157, 187, 187), (111, 198, 153), + (59, 254, 114), (37, 226, 98), (35, 165, 89), (34, 104, 80), + (46, 81, 91), (58, 59, 103), (52, 38, 136), (57, 56, 150), + (88, 97, 130), (110, 84, 154), (133, 71, 178), (136, 72, 194), + (140, 74, 210), (130, 70, 199), (120, 66, 188), (106, 58, 180), + (78, 40, 149), (35, 41, 65), (25, 47, 63), (16, 53, 61), + (9, 62, 59), (3, 71, 58), (6, 61, 42), (6, 52, 42), + (0, 42, 65), (1, 50, 110), (3, 59, 156), (4, 65, 157), + (5, 71, 158), (4, 82, 154), (16, 76, 138), (44, 53, 148), + (39, 77, 142), (24, 71, 65), (17, 77, 60), (11, 84, 55), + (10, 108, 57), (9, 133, 60), (39, 124, 83), (98, 123, 130), + (164, 120, 195), (189, 118, 207), (215, 117, 220), (218, 124, 222), + (222, 131, 224), (226, 128, 247), (217, 137, 255), (216, 121, 241), + (176, 107, 223), (50, 116, 190), (38, 121, 187), (26, 126, 185), + (22, 131, 187), (15, 110, 178), (9, 100, 170), (4, 98, 160), + (5, 109, 162), (17, 142, 124), (29, 176, 87), (38, 191, 98), + (48, 206, 109), (72, 202, 128), (100, 212, 140), (135, 199, 172), + (168, 197, 201), (217, 191, 216), (220, 177, 219), (223, 164, 222), + (236, 184, 223), (240, 181, 229), (244, 191, 243), (241, 221, 246), + (255, 235, 209), (228, 212, 217), (201, 189, 225), (195, 190, 224), + (189, 192, 223), (180, 204, 208), (165, 206, 198), (120, 203, 149), + (74, 191, 121), (19, 125, 175), (17, 128, 177), (16, 132, 179), + (12, 128, 175), (8, 111, 177), (5, 112, 156), (2, 103, 133), + (31, 77, 66), (25, 71, 64), (20, 66, 63), (15, 35, 59), + (15, 25, 61), (17, 15, 65), (30, 21, 76), (49, 38, 98), + (86, 46, 143), (141, 68, 185), (151, 76, 194), (162, 84, 204), + (140, 99, 177), (120, 114, 184), (60, 108, 193), (27, 114, 168), + (39, 74, 80), (34, 60, 78), (30, 47, 77), (45, 41, 92), + (52, 42, 102), (84, 76, 127), (83, 87, 112), (99, 116, 126), + (95, 112, 128), (40, 109, 184), (23, 139, 190), (25, 138, 194), + (33, 138, 195), (140, 156, 205), (163, 174, 236), (205, 175, 245), + (252, 180, 246), (246, 186, 238), (241, 193, 231), (199, 211, 199), + (185, 233, 183), (140, 217, 145), (106, 234, 147), (93, 234, 140), + (123, 204, 146), (129, 184, 152), (155, 138, 182), (160, 139, 198), + (180, 141, 198), (212, 162, 221), (210, 168, 234), (196, 182, 235), + (189, 164, 221), (169, 131, 218), (188, 147, 215), (198, 166, 205), + (189, 197, 208), (172, 231, 201), (93, 236, 148), (34, 244, 108), + (12, 214, 78), (21, 170, 76), (37, 120, 78), (78, 75, 120), + (61, 60, 162), (70, 90, 187), (57, 94, 183), (38, 90, 174), + (21, 101, 162), (4, 109, 141), (39, 101, 86), (35, 92, 77), + (18, 52, 54), (7, 14, 43), (5, 11, 45), (5, 6, 60), + (22, 12, 85), (36, 52, 140), (46, 82, 168), (78, 106, 190), + (134, 124, 210), (143, 137, 235), (217, 141, 255), (247, 151, 248), + (245, 154, 247), (246, 165, 232), (246, 165, 232), (240, 176, 226), + (227, 160, 213), (208, 124, 220), (173, 100, 208), (170, 90, 211), + (158, 119, 200), (171, 135, 181), (160, 137, 163), (171, 124, 170), + (167, 133, 193), (193, 134, 214), (221, 141, 240), (241, 144, 255), + (252, 169, 239), (244, 155, 249), (215, 141, 236), (174, 118, 217), + (143, 101, 165), (121, 131, 130), (59, 173, 101), (19, 189, 80) + ), + +// 306 0t0524.jpg +((69, 158, 156), (55, 60, 115), (40, 58, 106), (25, 57, 98), + (29, 77, 95), (33, 98, 92), (25, 100, 56), (18, 103, 20), + (95, 37, 26), (102, 28, 38), (109, 20, 50), (128, 34, 48), + (148, 48, 46), (125, 92, 105), (103, 137, 165), (101, 154, 169), + (100, 171, 173), (82, 162, 163), (61, 122, 143), (41, 83, 123), + (31, 62, 108), (21, 41, 94), (20, 31, 88), (20, 22, 83), + (30, 34, 81), (69, 45, 62), (109, 57, 44), (146, 53, 58), + (183, 49, 73), (213, 71, 120), (244, 94, 168), (241, 4, 108), + (213, 10, 99), (162, 18, 27), (136, 10, 35), (111, 2, 44), + (106, 1, 46), (102, 0, 48), (96, 4, 53), (91, 9, 58), + (44, 0, 59), (57, 14, 48), (71, 28, 38), (92, 24, 47), + (114, 20, 57), (117, 20, 45), (121, 20, 34), (151, 16, 23), + (187, 33, 25), (246, 67, 27), (241, 83, 27), (237, 100, 28), + (234, 83, 21), (231, 67, 14), (226, 63, 17), (222, 60, 21), + (234, 19, 0), (210, 26, 10), (186, 34, 20), (177, 17, 13), + (169, 0, 7), (168, 5, 5), (168, 11, 4), (148, 21, 6), + (112, 20, 0), (104, 15, 19), (83, 12, 17), (62, 9, 15), + (75, 7, 19), (88, 5, 23), (106, 1, 18), (88, 11, 29), + (46, 57, 59), (57, 49, 61), (69, 41, 64), (98, 51, 46), + (127, 61, 29), (158, 59, 22), (190, 57, 16), (210, 64, 5), + (219, 72, 18), (224, 80, 56), (233, 89, 52), (243, 99, 49), + (249, 94, 45), (255, 89, 41), (250, 107, 37), (255, 126, 40), + (210, 87, 53), (221, 89, 37), (233, 92, 21), (228, 78, 19), + (223, 65, 18), (236, 39, 46), (237, 45, 58), (239, 1, 76), + (239, 13, 53), (138, 30, 43), (104, 45, 50), (71, 60, 58), + (58, 55, 70), (45, 51, 83), (49, 53, 114), (69, 64, 118), + (143, 53, 45), (157, 51, 36), (172, 50, 27), (160, 38, 18), + (148, 27, 10), (117, 20, 13), (82, 4, 30), (56, 3, 33), + (65, 3, 52), (81, 5, 51), (78, 19, 43), (76, 34, 36), + (94, 41, 27), (119, 52, 23), (125, 51, 12), (122, 39, 31), + (90, 29, 34), (82, 29, 33), (75, 30, 33), (62, 52, 24), + (50, 74, 16), (66, 86, 1), (103, 63, 11), (148, 66, 10), + (198, 69, 11), (206, 36, 11), (185, 38, 5), (164, 41, 0), + (163, 35, 6), (142, 27, 0), (105, 29, 16), (70, 21, 27), + (33, 7, 36), (23, 13, 51), (13, 20, 66), (15, 17, 68), + (17, 14, 71), (24, 17, 68), (43, 12, 46), (57, 30, 73), + (67, 14, 66), (78, 23, 44), (80, 27, 46), (82, 31, 48), + (101, 38, 57), (115, 25, 50), (145, 29, 40), (155, 30, 12), + (160, 4, 15), (138, 7, 28), (116, 11, 41), (84, 23, 65), + (45, 40, 81), (40, 56, 89), (40, 38, 87), (69, 28, 42), + (87, 32, 37), (124, 44, 43), (132, 46, 32), (140, 49, 22), + (145, 42, 7), (121, 26, 6), (98, 30, 17), (76, 24, 36), + (35, 6, 50), (26, 8, 52), (17, 11, 55), (13, 21, 58), + (10, 30, 65), (16, 39, 70), (22, 39, 85), (17, 38, 91), + (24, 38, 85), (30, 42, 84), (34, 46, 88), (47, 65, 75), + (75, 78, 51), (97, 71, 36), (104, 69, 15), (124, 58, 8), + (152, 54, 19), (151, 49, 25), (151, 45, 32), (160, 46, 10), + (153, 32, 13), (168, 26, 22), (197, 26, 16), (224, 9, 25), + (204, 9, 17), (198, 10, 9), (172, 10, 7), (141, 7, 4), + (128, 5, 10), (116, 16, 14), (112, 18, 16), (106, 31, 35), + (89, 37, 60), (89, 48, 78), (116, 115, 120), (164, 188, 110), + (90, 161, 93), (70, 100, 108), (45, 67, 116), (30, 47, 93), + (15, 38, 92), (10, 42, 93), (22, 51, 95), (21, 59, 96), + (10, 89, 106), (1, 110, 115), (2, 125, 104), (1, 105, 114), + (2, 83, 112), (1, 65, 103), (14, 56, 96), (18, 71, 102), + (38, 81, 123), (32, 99, 126), (69, 115, 141), (87, 148, 153), + (118, 162, 163), (130, 163, 180), (187, 184, 203), (151, 200, 181), + (122, 181, 175), (72, 157, 154), (71, 146, 152), (15, 114, 120), + (15, 96, 100), (15, 81, 93), (20, 75, 96), (24, 76, 115), + (15, 81, 116), (7, 98, 117), (7, 124, 118), (9, 122, 120), + (33, 90, 97), (25, 64, 95), (9, 50, 94), (6, 40, 86), + (2, 33, 90), (13, 22, 81), (26, 17, 74), (27, 6, 65), + (35, 6, 52), (33, 23, 73), (30, 38, 85), (35, 44, 87), + (39, 60, 89), (48, 68, 95), (43, 99, 88), (33, 95, 94) + ), + +// 307 0t0533.jpg +((4, 32, 54), (54, 39, 108), (84, 99, 130), (115, 160, 153), + (138, 164, 165), (162, 169, 177), (164, 177, 183), (167, 186, 190), + (162, 224, 211), (189, 237, 233), (216, 251, 255), (228, 233, 238), + (241, 216, 222), (232, 174, 195), (223, 133, 168), (205, 133, 164), + (187, 134, 160), (176, 117, 227), (135, 98, 163), (94, 79, 100), + (75, 63, 69), (57, 47, 38), (47, 41, 39), (37, 36, 41), + (42, 50, 71), (62, 56, 71), (83, 63, 72), (109, 67, 76), + (135, 72, 80), (120, 64, 70), (105, 56, 60), (99, 48, 63), + (85, 88, 61), (108, 124, 87), (132, 114, 107), (157, 105, 128), + (151, 114, 141), (145, 124, 155), (154, 105, 171), (164, 86, 187), + (67, 38, 148), (33, 28, 112), (0, 19, 77), (6, 18, 49), + (12, 17, 21), (10, 18, 18), (8, 20, 16), (10, 27, 17), + (22, 49, 30), (62, 134, 70), (80, 162, 117), (98, 190, 165), + (115, 200, 180), (133, 211, 195), (139, 209, 196), (145, 208, 197), + (128, 222, 198), (122, 199, 181), (117, 177, 165), (123, 141, 153), + (130, 106, 142), (115, 100, 123), (100, 94, 104), (94, 71, 87), + (82, 70, 82), (47, 52, 58), (39, 60, 47), (31, 68, 37), + (35, 65, 36), (39, 62, 36), (51, 58, 64), (65, 79, 82), + (55, 55, 67), (39, 48, 55), (23, 41, 43), (14, 25, 57), + (6, 10, 71), (8, 15, 77), (11, 21, 83), (18, 28, 87), + (51, 27, 125), (35, 49, 62), (28, 50, 54), (21, 52, 47), + (11, 51, 49), (1, 51, 52), (7, 38, 32), (4, 14, 16), + (7, 9, 8), (12, 5, 10), (17, 1, 12), (15, 10, 14), + (14, 20, 16), (22, 35, 25), (36, 67, 36), (62, 94, 53), + (88, 117, 71), (122, 162, 100), (99, 135, 102), (76, 108, 105), + (78, 106, 104), (80, 104, 104), (78, 93, 98), (70, 88, 90), + (36, 103, 86), (38, 121, 98), (40, 139, 110), (26, 128, 97), + (12, 117, 84), (9, 117, 55), (9, 110, 52), (20, 110, 59), + (24, 119, 75), (77, 64, 92), (81, 69, 100), (85, 75, 109), + (86, 76, 100), (78, 87, 92), (71, 92, 95), (60, 90, 88), + (21, 81, 56), (17, 67, 41), (14, 54, 27), (10, 48, 31), + (7, 42, 35), (6, 43, 35), (3, 47, 30), (3, 75, 38), + (6, 83, 39), (18, 99, 56), (23, 109, 56), (29, 119, 57), + (55, 127, 64), (57, 133, 68), (69, 138, 73), (117, 136, 91), + (120, 151, 94), (101, 146, 86), (83, 142, 78), (73, 140, 75), + (63, 138, 73), (46, 117, 59), (19, 88, 41), (2, 66, 32), + (5, 42, 25), (3, 11, 13), (3, 5, 16), (4, 0, 19), + (1, 11, 12), (2, 17, 12), (5, 44, 23), (3, 79, 40), + (1, 113, 55), (8, 120, 58), (15, 128, 62), (21, 135, 65), + (13, 117, 56), (24, 95, 77), (47, 83, 79), (64, 62, 65), + (78, 60, 50), (83, 54, 72), (91, 53, 71), (100, 53, 71), + (113, 71, 83), (129, 77, 79), (143, 85, 109), (116, 81, 103), + (74, 85, 89), (67, 85, 87), (61, 85, 85), (36, 68, 65), + (18, 52, 54), (18, 58, 49), (18, 68, 56), (44, 70, 69), + (69, 90, 91), (69, 131, 116), (59, 147, 123), (57, 167, 138), + (81, 170, 148), (106, 167, 97), (115, 139, 91), (86, 118, 71), + (30, 41, 43), (27, 43, 35), (25, 46, 27), (6, 22, 22), + (9, 18, 17), (4, 29, 25), (6, 41, 34), (10, 58, 46), + (12, 75, 56), (12, 83, 41), (4, 98, 46), (3, 96, 49), + (9, 92, 66), (6, 82, 54), (4, 76, 52), (3, 70, 52), + (6, 63, 48), (9, 44, 38), (21, 36, 41), (22, 29, 35), + (32, 22, 31), (34, 19, 26), (36, 22, 21), (28, 23, 19), + (35, 32, 25), (38, 33, 30), (63, 36, 41), (70, 39, 44), + (76, 39, 46), (71, 35, 47), (45, 25, 34), (43, 20, 26), + (32, 19, 28), (19, 21, 20), (22, 17, 14), (15, 11, 12), + (13, 7, 9), (12, 10, 11), (26, 29, 22), (39, 39, 29), + (46, 37, 32), (65, 48, 41), (76, 40, 50), (66, 37, 42), + (55, 35, 37), (22, 32, 21), (15, 27, 17), (8, 10, 9), + (5, 7, 6), (4, 0, 3), (7, 7, 9), (10, 12, 11), + (6, 20, 20), (9, 38, 33), (1, 38, 57), (3, 66, 57), + (4, 72, 61), (4, 54, 53), (23, 49, 50), (40, 40, 40), + (58, 31, 40), (77, 49, 63), (65, 41, 75), (40, 55, 58), + (23, 70, 60), (28, 100, 76), (66, 108, 86), (85, 138, 130), + (107, 154, 148), (113, 166, 160), (126, 182, 171), (135, 161, 160) + ), + +// 308 0u0075.jpg +((74, 52, 215), (35, 11, 171), (24, 6, 160), (14, 2, 150), + (7, 2, 145), (0, 3, 140), (0, 1, 133), (0, 0, 126), + (0, 0, 126), (0, 0, 129), (0, 0, 132), (0, 0, 136), + (1, 0, 140), (2, 0, 130), (3, 0, 120), (2, 0, 106), + (2, 0, 93), (0, 0, 23), (0, 0, 11), (0, 0, 0), + (1, 0, 0), (3, 0, 0), (3, 0, 0), (3, 0, 0), + (0, 0, 0), (1, 0, 6), (3, 0, 13), (1, 0, 42), + (0, 0, 72), (0, 0, 90), (0, 1, 109), (0, 0, 120), + (0, 0, 122), (0, 0, 126), (0, 0, 132), (1, 0, 138), + (7, 0, 155), (13, 0, 172), (30, 0, 172), (48, 0, 172), + (98, 13, 166), (101, 7, 150), (104, 1, 134), (84, 0, 127), + (64, 0, 120), (51, 2, 130), (38, 4, 140), (24, 1, 151), + (23, 1, 164), (57, 4, 184), (74, 6, 179), (92, 9, 175), + (70, 4, 176), (49, 0, 177), (33, 0, 164), (17, 1, 151), + (0, 0, 98), (23, 0, 85), (47, 0, 72), (69, 5, 76), + (91, 11, 80), (91, 14, 94), (92, 17, 108), (104, 1, 132), + (106, 0, 162), (94, 6, 180), (95, 3, 179), (97, 0, 179), + (89, 0, 179), (81, 0, 180), (41, 2, 171), (21, 1, 160), + (1, 0, 125), (21, 5, 107), (42, 11, 89), (73, 5, 87), + (105, 0, 85), (110, 0, 97), (116, 0, 109), (131, 8, 174), + (137, 27, 212), (131, 44, 234), (121, 60, 232), (112, 77, 231), + (111, 84, 233), (110, 91, 235), (104, 74, 230), (106, 45, 201), + (106, 0, 110), (97, 0, 83), (88, 1, 56), (76, 0, 47), + (64, 0, 39), (43, 0, 27), (19, 0, 33), (0, 0, 56), + (0, 0, 86), (0, 1, 109), (25, 3, 79), (51, 6, 49), + (56, 8, 46), (62, 11, 44), (77, 8, 53), (94, 1, 54), + (105, 0, 105), (111, 0, 140), (117, 0, 175), (115, 0, 179), + (114, 0, 184), (110, 0, 193), (108, 5, 174), (110, 1, 168), + (121, 1, 148), (98, 2, 128), (82, 1, 119), (66, 0, 111), + (41, 0, 97), (1, 0, 115), (0, 0, 118), (0, 0, 122), + (0, 0, 112), (3, 2, 85), (7, 4, 59), (15, 7, 43), + (24, 11, 28), (37, 24, 33), (54, 9, 48), (81, 0, 77), + (81, 1, 122), (62, 27, 192), (66, 28, 194), (71, 30, 197), + (81, 11, 170), (74, 14, 128), (72, 6, 103), (82, 7, 92), + (79, 8, 48), (70, 6, 44), (62, 5, 40), (67, 3, 46), + (72, 2, 52), (62, 11, 103), (65, 1, 150), (51, 13, 184), + (59, 24, 204), (39, 0, 175), (33, 1, 166), (27, 2, 158), + (31, 1, 151), (24, 0, 150), (27, 0, 144), (37, 0, 142), + (52, 0, 113), (58, 0, 104), (64, 0, 96), (48, 1, 79), + (47, 0, 64), (33, 0, 25), (29, 0, 18), (42, 3, 32), + (67, 15, 53), (103, 0, 153), (104, 3, 166), (105, 7, 180), + (104, 24, 185), (76, 46, 204), (53, 49, 206), (17, 20, 183), + (11, 5, 175), (11, 3, 175), (11, 1, 176), (11, 1, 175), + (8, 1, 167), (0, 0, 148), (1, 0, 134), (23, 0, 130), + (54, 0, 156), (52, 0, 160), (65, 5, 165), (86, 0, 185), + (103, 10, 212), (116, 31, 222), (124, 45, 235), (143, 61, 249), + (135, 96, 247), (129, 99, 246), (124, 102, 245), (119, 94, 240), + (119, 84, 240), (104, 93, 232), (102, 80, 227), (92, 56, 216), + (106, 25, 166), (103, 7, 115), (91, 13, 61), (80, 2, 41), + (68, 1, 36), (54, 0, 13), (11, 0, 16), (1, 1, 3), + (0, 0, 2), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 0, 6), (1, 1, 27), (0, 0, 56), + (0, 0, 90), (0, 0, 112), (0, 0, 124), (10, 0, 135), + (41, 1, 113), (41, 1, 100), (36, 0, 76), (8, 4, 41), + (0, 0, 7), (1, 1, 0), (0, 2, 0), (0, 2, 0), + (0, 1, 0), (0, 0, 0), (1, 0, 2), (5, 1, 2), + (2, 1, 7), (3, 0, 32), (0, 1, 49), (0, 0, 75), + (0, 0, 110), (0, 0, 120), (0, 2, 127), (0, 0, 152), + (1, 0, 166), (18, 0, 180), (42, 0, 188), (76, 28, 200), + (118, 22, 218), (125, 29, 224), (125, 35, 231), (133, 42, 235), + (139, 39, 233), (140, 45, 237), (134, 61, 239), (125, 89, 241), + (135, 91, 248), (137, 87, 248), (143, 51, 240), (131, 50, 240), + (114, 62, 233), (114, 67, 231), (104, 64, 223), (114, 47, 225), + (104, 2, 197), (97, 1, 163), (61, 0, 53), (76, 3, 95) + ), +// 309 0u0298.jpg +((58, 63, 7), (75, 43, 20), (85, 44, 38), (95, 45, 57), + (109, 48, 51), (123, 52, 46), (116, 56, 43), (109, 61, 41), + (87, 47, 37), (90, 38, 37), (93, 30, 38), (98, 30, 32), + (104, 30, 27), (114, 49, 41), (124, 68, 55), (125, 71, 73), + (127, 74, 92), (89, 69, 81), (71, 70, 61), (53, 72, 42), + (30, 63, 26), (7, 54, 10), (5, 48, 9), (3, 43, 9), + (7, 41, 14), (11, 38, 19), (16, 36, 25), (13, 29, 20), + (11, 22, 16), (14, 21, 14), (17, 20, 13), (20, 16, 7), + (4, 26, 5), (19, 52, 33), (22, 45, 57), (26, 39, 81), + (39, 37, 87), (53, 35, 93), (46, 40, 77), (39, 46, 62), + (35, 74, 27), (46, 65, 32), (57, 56, 38), (70, 49, 47), + (84, 43, 57), (84, 45, 59), (85, 47, 62), (72, 44, 58), + (68, 42, 55), (54, 28, 55), (54, 27, 67), (54, 27, 80), + (67, 37, 71), (81, 47, 63), (80, 51, 65), (79, 55, 68), + (109, 77, 92), (101, 72, 84), (93, 67, 76), (86, 53, 64), + (80, 39, 53), (80, 35, 52), (81, 32, 51), (67, 26, 40), + (84, 24, 34), (96, 29, 21), (121, 64, 38), (147, 100, 56), + (153, 107, 55), (160, 114, 55), (166, 128, 66), (191, 138, 72), + (164, 108, 59), (149, 90, 46), (134, 72, 33), (113, 48, 19), + (92, 24, 5), (86, 23, 11), (80, 22, 18), (85, 5, 18), + (98, 15, 25), (125, 16, 47), (124, 28, 51), (124, 40, 55), + (117, 45, 58), (110, 50, 62), (101, 41, 49), (98, 27, 41), + (67, 1, 49), (65, 8, 40), (63, 16, 32), (63, 8, 27), + (63, 0, 23), (65, 2, 11), (74, 20, 10), (89, 33, 0), + (100, 47, 7), (122, 43, 36), (120, 57, 31), (118, 71, 27), + (119, 70, 18), (121, 69, 9), (111, 52, 20), (100, 42, 20), + (124, 73, 44), (128, 85, 40), (133, 97, 37), (132, 89, 39), + (131, 82, 41), (117, 38, 23), (93, 18, 23), (72, 0, 16), + (62, 7, 2), (51, 13, 0), (37, 14, 0), (23, 16, 0), + (17, 12, 6), (9, 25, 14), (5, 34, 29), (9, 39, 31), + (24, 43, 24), (38, 37, 26), (52, 31, 28), (50, 27, 24), + (48, 24, 20), (46, 12, 29), (40, 11, 33), (35, 2, 21), + (44, 4, 15), (58, 0, 5), (58, 6, 4), (59, 12, 4), + (55, 12, 6), (41, 22, 7), (29, 40, 24), (26, 52, 27), + (18, 52, 25), (23, 46, 29), (29, 40, 34), (33, 41, 36), + (37, 43, 39), (46, 33, 42), (59, 26, 35), (60, 18, 28), + (68, 22, 22), (58, 17, 0), (57, 15, 3), (56, 13, 6), + (57, 20, 12), (58, 13, 18), (48, 11, 19), (55, 4, 13), + (68, 2, 6), (63, 5, 7), (58, 8, 9), (53, 8, 15), + (41, 19, 22), (44, 21, 31), (47, 25, 37), (56, 26, 36), + (60, 32, 46), (76, 31, 38), (70, 25, 31), (65, 20, 25), + (66, 16, 19), (46, 14, 19), (35, 22, 14), (26, 23, 14), + (24, 39, 8), (22, 38, 16), (20, 38, 24), (24, 25, 30), + (30, 11, 33), (35, 9, 56), (38, 31, 38), (35, 30, 34), + (34, 46, 24), (40, 48, 9), (63, 45, 21), (70, 60, 9), + (82, 49, 6), (90, 53, 11), (87, 53, 18), (84, 51, 20), + (81, 34, 16), (79, 28, 19), (77, 23, 23), (56, 35, 30), + (53, 35, 35), (31, 29, 30), (15, 27, 17), (13, 26, 9), + (22, 42, 5), (12, 49, 15), (21, 39, 23), (37, 32, 38), + (48, 36, 46), (57, 46, 42), (91, 51, 52), (117, 59, 48), + (127, 69, 57), (135, 81, 81), (168, 106, 85), (193, 133, 99), + (175, 130, 89), (160, 106, 68), (152, 109, 67), (159, 100, 58), + (150, 75, 70), (132, 86, 50), (137, 103, 32), (147, 94, 44), + (161, 107, 47), (170, 102, 57), (158, 84, 71), (147, 75, 79), + (143, 70, 79), (136, 55, 62), (149, 39, 84), (152, 45, 117), + (140, 66, 93), (185, 127, 125), (209, 126, 122), (174, 188, 129), + (146, 190, 157), (138, 180, 114), (128, 108, 120), (153, 80, 109), + (112, 80, 93), (84, 105, 66), (99, 131, 64), (117, 117, 63), + (114, 80, 52), (104, 64, 52), (97, 52, 46), (87, 54, 45), + (82, 60, 46), (48, 48, 40), (45, 46, 41), (28, 49, 30), + (19, 40, 35), (13, 34, 25), (16, 16, 14), (23, 4, 8), + (29, 10, 6), (55, 11, 10), (77, 7, 17), (97, 7, 16), + (100, 14, 25), (94, 14, 25), (92, 22, 32), (74, 6, 31), + (74, 6, 31), (79, 22, 37), (73, 45, 21), (81, 31, 20) + ), + +// 310 0u0298pp1.jpg +((63, 63, 151), (98, 26, 170), (91, 33, 149), (84, 40, 129), + (73, 50, 122), (63, 60, 115), (54, 51, 103), (45, 43, 92), + (43, 32, 46), (40, 29, 57), (38, 27, 69), (35, 22, 77), + (33, 18, 85), (37, 29, 113), (41, 40, 142), (58, 55, 150), + (75, 71, 158), (70, 90, 149), (57, 66, 122), (45, 42, 95), + (42, 32, 107), (40, 23, 119), (41, 23, 119), (43, 23, 120), + (88, 26, 133), (80, 13, 150), (72, 1, 167), (46, 14, 147), + (20, 28, 127), (23, 26, 112), (27, 25, 98), (34, 37, 90), + (46, 44, 91), (36, 58, 71), (36, 57, 63), (36, 56, 55), + (39, 53, 48), (43, 50, 42), (44, 64, 46), (45, 78, 51), + (59, 61, 86), (59, 58, 86), (60, 55, 87), (46, 36, 64), + (32, 18, 41), (27, 21, 30), (23, 25, 20), (20, 21, 15), + (26, 14, 14), (39, 8, 5), (29, 8, 12), (20, 8, 20), + (14, 10, 31), (8, 13, 42), (11, 12, 31), (15, 12, 21), + (42, 0, 20), (46, 10, 25), (50, 20, 30), (45, 13, 49), + (41, 7, 68), (38, 6, 63), (36, 6, 58), (23, 0, 60), + (12, 4, 41), (14, 6, 19), (10, 6, 16), (6, 6, 14), + (7, 8, 13), (9, 10, 12), (14, 4, 12), (18, 0, 0), + (25, 16, 1), (23, 15, 11), (21, 14, 21), (10, 11, 39), + (0, 9, 57), (0, 13, 72), (0, 17, 87), (9, 26, 104), + (0, 27, 118), (37, 22, 127), (56, 13, 128), (76, 4, 129), + (88, 14, 151), (100, 24, 174), (133, 65, 202), (159, 86, 229), + (136, 65, 207), (108, 63, 178), (81, 61, 150), (58, 46, 147), + (35, 31, 144), (30, 24, 110), (29, 18, 97), (33, 14, 80), + (62, 17, 76), (32, 8, 60), (25, 10, 58), (19, 13, 57), + (15, 13, 53), (11, 14, 49), (4, 15, 45), (0, 12, 54), + (0, 4, 65), (5, 17, 86), (11, 30, 107), (23, 29, 112), + (35, 29, 117), (55, 47, 132), (99, 105, 189), (159, 119, 252), + (180, 136, 247), (255, 191, 205), (255, 179, 204), (255, 168, 203), + (228, 166, 181), (195, 129, 139), (88, 109, 138), (54, 77, 93), + (0, 23, 51), (6, 23, 48), (13, 24, 46), (16, 22, 53), + (19, 21, 60), (24, 20, 79), (20, 7, 79), (10, 15, 83), + (7, 22, 65), (0, 38, 77), (4, 36, 94), (8, 34, 111), + (1, 15, 103), (0, 5, 89), (0, 3, 84), (14, 18, 89), + (29, 57, 81), (38, 63, 84), (47, 70, 88), (65, 71, 105), + (83, 73, 123), (100, 92, 90), (131, 113, 73), (112, 64, 50), + (95, 62, 43), (66, 54, 58), (61, 49, 53), (56, 45, 49), + (29, 31, 44), (18, 25, 43), (24, 26, 65), (34, 47, 82), + (77, 31, 140), (85, 27, 158), (94, 23, 177), (114, 36, 197), + (103, 56, 160), (95, 71, 157), (71, 82, 171), (34, 66, 153), + (26, 51, 118), (69, 87, 135), (68, 89, 146), (67, 92, 158), + (86, 93, 161), (110, 119, 178), (95, 102, 157), (82, 99, 151), + (65, 98, 129), (61, 88, 109), (58, 78, 89), (50, 97, 53), + (26, 94, 19), (25, 71, 42), (32, 35, 14), (38, 31, 23), + (36, 52, 68), (62, 79, 99), (86, 70, 145), (124, 112, 194), + (145, 111, 231), (144, 110, 231), (101, 73, 194), (113, 93, 165), + (117, 48, 191), (117, 44, 202), (118, 40, 214), (128, 59, 201), + (116, 40, 174), (99, 7, 118), (68, 1, 78), (72, 17, 56), + (48, 25, 35), (37, 25, 45), (36, 19, 61), (34, 5, 89), + (33, 5, 90), (29, 1, 104), (33, 1, 110), (46, 10, 106), + (34, 13, 104), (14, 14, 110), (12, 12, 100), (0, 0, 112), + (11, 0, 111), (21, 7, 142), (45, 15, 161), (86, 30, 191), + (129, 83, 217), (169, 122, 254), (170, 202, 255), (134, 189, 219), + (86, 171, 236), (142, 128, 203), (119, 102, 180), (117, 71, 135), + (74, 40, 127), (44, 38, 98), (56, 25, 67), (58, 21, 65), + (47, 28, 48), (21, 22, 40), (25, 23, 45), (24, 8, 71), + (18, 15, 82), (15, 29, 102), (14, 31, 103), (18, 38, 99), + (14, 76, 99), (0, 62, 77), (18, 37, 70), (16, 49, 66), + (25, 65, 67), (5, 80, 50), (33, 68, 48), (48, 47, 55), + (47, 42, 49), (36, 29, 73), (43, 33, 86), (42, 32, 93), + (36, 11, 92), (18, 3, 98), (16, 1, 94), (18, 0, 84), + (4, 3, 83), (0, 9, 63), (0, 6, 53), (7, 3, 30), + (0, 0, 20), (4, 2, 26), (1, 0, 48), (21, 0, 69), + (25, 12, 66), (16, 33, 49), (53, 116, 37), (32, 78, 50) + ), + +// 311 0u0303.jpg +((184, 12, 34), (160, 94, 36), (126, 88, 18), (93, 82, 0), + (107, 69, 14), (121, 56, 28), (132, 39, 26), (143, 23, 24), + (158, 1, 32), (137, 1, 53), (117, 1, 74), (106, 16, 60), + (95, 31, 47), (97, 41, 62), (100, 52, 78), (99, 68, 79), + (99, 84, 81), (36, 17, 96), (33, 20, 95), (30, 24, 94), + (53, 49, 77), (77, 75, 60), (98, 78, 75), (119, 82, 90), + (136, 66, 138), (156, 65, 146), (177, 64, 154), (158, 32, 157), + (140, 0, 160), (149, 8, 137), (159, 17, 115), (128, 30, 91), + (117, 43, 102), (155, 36, 130), (132, 28, 109), (110, 21, 89), + (87, 19, 107), (65, 17, 126), (57, 25, 145), (49, 33, 165), + (52, 75, 106), (72, 95, 87), (93, 115, 69), (94, 110, 53), + (95, 106, 37), (80, 111, 34), (65, 117, 32), (62, 109, 28), + (70, 56, 30), (116, 32, 22), (120, 27, 43), (124, 23, 65), + (107, 38, 71), (91, 53, 78), (80, 55, 69), (70, 58, 60), + (25, 54, 10), (31, 41, 5), (37, 28, 0), (59, 21, 0), + (81, 15, 0), (94, 7, 1), (107, 0, 2), (106, 8, 5), + (121, 30, 27), (88, 93, 27), (59, 111, 19), (30, 129, 12), + (40, 129, 20), (51, 129, 28), (72, 145, 38), (97, 127, 91), + (129, 59, 131), (112, 48, 136), (95, 38, 141), (111, 51, 153), + (127, 65, 166), (121, 62, 168), (116, 60, 171), (106, 89, 185), + (99, 113, 174), (23, 62, 131), (56, 47, 102), (89, 32, 73), + (112, 30, 50), (136, 28, 28), (160, 46, 20), (157, 26, 0), + (164, 57, 5), (139, 54, 14), (115, 51, 24), (92, 46, 16), + (70, 41, 9), (65, 24, 18), (64, 19, 24), (74, 16, 30), + (58, 38, 40), (54, 14, 49), (49, 44, 48), (45, 75, 47), + (33, 82, 58), (22, 90, 69), (14, 88, 99), (58, 111, 69), + (76, 151, 84), (95, 149, 73), (114, 148, 62), (117, 162, 63), + (120, 177, 64), (98, 159, 64), (66, 140, 91), (46, 130, 140), + (15, 112, 165), (0, 66, 160), (5, 49, 171), (11, 32, 183), + (8, 13, 139), (24, 40, 138), (86, 5, 146), (96, 13, 101), + (63, 66, 59), (45, 60, 80), (27, 55, 102), (14, 32, 114), + (2, 9, 126), (11, 5, 103), (72, 0, 70), (130, 10, 45), + (152, 29, 24), (161, 35, 36), (163, 25, 55), (165, 16, 74), + (177, 6, 58), (187, 0, 29), (205, 12, 29), (198, 28, 31), + (133, 21, 20), (107, 26, 10), (81, 32, 0), (69, 40, 0), + (58, 48, 0), (39, 59, 8), (48, 91, 38), (69, 114, 45), + (112, 141, 48), (158, 143, 52), (161, 128, 46), (164, 114, 41), + (148, 107, 41), (137, 109, 36), (113, 105, 30), (97, 98, 28), + (140, 138, 61), (155, 133, 53), (171, 129, 45), (190, 131, 53), + (173, 90, 84), (158, 51, 133), (162, 35, 106), (159, 56, 51), + (175, 96, 39), (212, 63, 31), (220, 51, 17), (229, 39, 3), + (239, 17, 12), (242, 6, 42), (206, 0, 48), (161, 0, 31), + (133, 28, 58), (131, 42, 60), (129, 56, 63), (100, 55, 52), + (124, 89, 61), (132, 148, 83), (121, 154, 85), (120, 183, 78), + (130, 175, 58), (155, 168, 50), (209, 150, 30), (212, 206, 82), + (255, 161, 111), (214, 154, 120), (161, 155, 71), (128, 138, 114), + (79, 131, 189), (61, 133, 196), (44, 136, 203), (38, 132, 170), + (60, 122, 137), (87, 121, 94), (66, 113, 58), (59, 68, 21), + (47, 38, 21), (60, 58, 20), (87, 65, 54), (97, 99, 59), + (128, 111, 59), (175, 130, 65), (191, 129, 46), (184, 97, 44), + (161, 80, 25), (141, 68, 35), (121, 90, 25), (107, 72, 32), + (80, 66, 27), (78, 60, 24), (101, 10, 25), (103, 0, 12), + (122, 0, 30), (135, 2, 57), (151, 20, 62), (162, 25, 77), + (182, 12, 108), (157, 5, 124), (135, 3, 87), (131, 26, 66), + (86, 43, 62), (76, 70, 44), (70, 82, 46), (73, 90, 48), + (47, 81, 56), (12, 90, 50), (44, 114, 44), (56, 123, 44), + (68, 147, 68), (100, 184, 72), (91, 174, 86), (78, 148, 96), + (69, 144, 85), (80, 127, 81), (89, 109, 100), (100, 44, 145), + (128, 42, 175), (137, 58, 173), (129, 81, 143), (136, 100, 126), + (163, 157, 183), (166, 90, 155), (133, 71, 154), (106, 58, 170), + (76, 64, 166), (14, 79, 147), (1, 66, 120), (37, 64, 133), + (76, 66, 129), (94, 63, 78), (109, 49, 83), (164, 25, 106), + (173, 28, 119), (186, 31, 125), (159, 45, 133), (137, 42, 110), + (111, 71, 98), (119, 112, 96), (118, 131, 103), (117, 125, 76) + ), + +// 312 0u0333.jpg +((113, 106, 52), (66, 73, 42), (52, 84, 52), (38, 95, 63), + (51, 94, 76), (65, 94, 90), (65, 83, 92), (65, 73, 94), + (27, 51, 75), (32, 46, 77), (38, 42, 79), (45, 37, 68), + (53, 33, 58), (65, 25, 57), (78, 18, 56), (76, 30, 54), + (74, 42, 53), (71, 97, 70), (55, 114, 71), (40, 131, 72), + (46, 118, 51), (52, 106, 31), (38, 94, 15), (24, 83, 0), + (17, 65, 13), (38, 58, 15), (60, 51, 18), (101, 51, 33), + (143, 52, 49), (162, 55, 58), (182, 58, 68), (204, 101, 102), + (189, 129, 95), (164, 91, 100), (145, 83, 86), (126, 75, 72), + (132, 69, 67), (138, 64, 63), (164, 62, 61), (190, 60, 60), + (188, 35, 38), (160, 52, 28), (132, 69, 18), (126, 68, 41), + (121, 67, 65), (120, 67, 67), (119, 67, 69), (118, 86, 61), + (114, 94, 59), (152, 106, 83), (184, 129, 101), (216, 153, 120), + (190, 132, 107), (164, 111, 95), (153, 95, 82), (143, 79, 69), + (169, 94, 91), (196, 118, 102), (224, 143, 114), (205, 135, 104), + (186, 127, 95), (160, 112, 92), (135, 98, 89), (125, 76, 71), + (111, 62, 47), (84, 30, 28), (65, 35, 37), (47, 40, 47), + (44, 46, 50), (42, 52, 54), (52, 43, 48), (79, 64, 43), + (98, 82, 46), (101, 65, 46), (104, 49, 46), (83, 28, 41), + (62, 7, 36), (51, 4, 29), (40, 2, 23), (38, 3, 10), + (40, 6, 5), (26, 8, 6), (25, 21, 8), (25, 35, 10), + (35, 40, 17), (46, 45, 24), (46, 65, 46), (25, 70, 50), + (59, 103, 78), (72, 98, 93), (85, 94, 109), (84, 100, 110), + (83, 106, 112), (42, 119, 147), (97, 151, 138), (104, 190, 165), + (118, 129, 113), (72, 107, 87), (47, 88, 74), (22, 69, 61), + (27, 57, 49), (32, 45, 38), (14, 40, 27), (39, 50, 34), + (63, 54, 57), (89, 61, 67), (116, 69, 77), (129, 75, 77), + (143, 82, 77), (167, 96, 76), (190, 123, 97), (207, 117, 117), + (185, 80, 110), (131, 76, 81), (124, 81, 72), (118, 86, 63), + (108, 83, 61), (101, 106, 26), (93, 128, 24), (87, 95, 22), + (86, 72, 35), (70, 64, 35), (55, 57, 35), (48, 62, 33), + (41, 67, 32), (30, 75, 18), (18, 51, 22), (14, 43, 13), + (20, 36, 9), (46, 19, 2), (50, 27, 15), (55, 35, 28), + (48, 47, 29), (51, 54, 37), (54, 63, 16), (81, 69, 9), + (70, 78, 19), (78, 98, 32), (86, 118, 45), (112, 122, 64), + (139, 126, 84), (162, 141, 112), (195, 144, 97), (205, 110, 90), + (203, 84, 44), (204, 57, 41), (195, 46, 31), (187, 35, 22), + (152, 16, 16), (128, 8, 9), (99, 21, 21), (60, 7, 15), + (35, 14, 23), (38, 22, 30), (41, 30, 38), (41, 34, 42), + (34, 49, 54), (18, 77, 81), (25, 112, 95), (20, 99, 70), + (25, 76, 77), (30, 38, 49), (27, 28, 37), (24, 19, 26), + (12, 4, 27), (0, 3, 26), (23, 10, 36), (30, 15, 34), + (51, 13, 36), (51, 13, 34), (52, 13, 32), (59, 25, 24), + (63, 43, 19), (55, 44, 12), (36, 41, 19), (38, 30, 9), + (44, 25, 10), (62, 40, 17), (79, 38, 34), (72, 49, 31), + (66, 79, 36), (59, 92, 39), (45, 103, 52), (21, 103, 55), + (31, 135, 160), (29, 140, 151), (27, 146, 142), (26, 164, 139), + (2, 150, 124), (23, 102, 73), (15, 68, 52), (27, 25, 39), + (19, 17, 20), (37, 18, 11), (37, 20, 4), (17, 8, 1), + (11, 1, 2), (31, 7, 3), (54, 18, 4), (101, 19, 41), + (133, 34, 37), (145, 45, 45), (136, 59, 65), (114, 67, 77), + (102, 50, 88), (78, 43, 85), (73, 45, 85), (81, 64, 70), + (82, 61, 44), (110, 49, 54), (117, 56, 61), (99, 23, 69), + (75, 27, 79), (58, 39, 69), (53, 45, 68), (62, 68, 68), + (92, 92, 68), (108, 97, 67), (107, 84, 78), (92, 64, 102), + (44, 50, 84), (44, 34, 71), (62, 26, 72), (79, 26, 80), + (97, 29, 102), (76, 1, 70), (76, 11, 53), (56, 1, 43), + (52, 31, 40), (70, 44, 55), (84, 62, 38), (93, 35, 34), + (111, 30, 36), (121, 27, 41), (113, 29, 44), (115, 53, 38), + (129, 52, 44), (134, 54, 65), (159, 52, 44), (178, 60, 46), + (167, 95, 37), (178, 95, 65), (228, 135, 102), (220, 153, 124), + (182, 170, 120), (161, 173, 101), (179, 173, 113), (197, 149, 129), + (163, 145, 141), (165, 129, 133), (145, 122, 140), (134, 107, 112), + (118, 115, 110), (101, 118, 86), (107, 143, 99), (55, 128, 135) + ), + +// 313 0u0752.jpg +((32, 38, 28), (64, 72, 25), (81, 84, 27), (99, 96, 29), + (90, 91, 40), (81, 87, 51), (77, 76, 49), (73, 66, 48), + (78, 66, 42), (89, 71, 44), (101, 76, 46), (108, 76, 39), + (115, 76, 33), (81, 63, 31), (48, 50, 29), (41, 48, 25), + (34, 47, 21), (32, 45, 27), (32, 50, 37), (33, 56, 48), + (48, 82, 60), (64, 108, 72), (78, 112, 81), (92, 116, 90), + (121, 146, 80), (117, 145, 73), (114, 145, 67), (105, 126, 69), + (96, 108, 72), (95, 103, 67), (94, 98, 63), (83, 92, 61), + (56, 79, 59), (40, 48, 35), (35, 44, 34), (30, 41, 33), + (29, 40, 37), (29, 40, 42), (29, 37, 40), (30, 35, 38), + (21, 31, 23), (22, 33, 31), (24, 35, 39), (26, 35, 41), + (29, 36, 44), (29, 39, 45), (29, 43, 46), (27, 43, 43), + (23, 42, 36), (10, 30, 37), (15, 31, 30), (20, 33, 23), + (23, 37, 18), (26, 42, 13), (33, 48, 17), (41, 55, 22), + (60, 67, 23), (65, 64, 31), (70, 62, 39), (73, 51, 35), + (77, 40, 32), (75, 43, 25), (73, 46, 19), (47, 45, 24), + (56, 57, 23), (91, 91, 41), (124, 105, 43), (157, 119, 46), + (160, 118, 54), (164, 117, 63), (154, 108, 58), (118, 103, 48), + (95, 102, 58), (99, 102, 49), (103, 103, 41), (121, 89, 43), + (139, 76, 45), (135, 77, 50), (131, 79, 55), (141, 84, 57), + (147, 112, 80), (88, 99, 57), (74, 94, 50), (60, 89, 43), + (59, 82, 32), (59, 76, 21), (57, 71, 36), (43, 63, 51), + (59, 106, 90), (97, 132, 103), (136, 159, 117), (151, 165, 124), + (166, 171, 131), (191, 169, 145), (137, 175, 160), (133, 174, 158), + (143, 159, 120), (112, 99, 67), (96, 81, 54), (81, 63, 41), + (71, 57, 39), (61, 52, 37), (38, 56, 34), (27, 53, 44), + (39, 60, 63), (50, 58, 62), (61, 56, 62), (69, 61, 53), + (78, 66, 44), (86, 69, 49), (82, 83, 51), (77, 91, 56), + (77, 96, 50), (67, 72, 49), (64, 73, 45), (61, 75, 42), + (57, 55, 34), (50, 54, 31), (43, 48, 26), (42, 46, 23), + (20, 32, 22), (21, 29, 24), (22, 26, 27), (22, 25, 28), + (22, 25, 30), (13, 18, 22), (19, 22, 15), (27, 31, 17), + (38, 41, 30), (46, 56, 29), (48, 60, 31), (51, 64, 34), + (45, 69, 45), (44, 93, 63), (56, 105, 83), (71, 111, 84), + (97, 124, 93), (114, 138, 103), (131, 152, 113), (140, 153, 107), + (150, 155, 101), (155, 152, 101), (148, 151, 106), (146, 156, 122), + (165, 172, 131), (169, 180, 114), (159, 181, 108), (149, 182, 103), + (139, 161, 96), (96, 150, 101), (81, 134, 90), (67, 103, 65), + (42, 58, 29), (37, 53, 29), (32, 49, 30), (30, 51, 32), + (37, 58, 49), (44, 69, 73), (53, 81, 82), (64, 78, 78), + (59, 79, 68), (51, 64, 36), (52, 61, 36), (54, 59, 37), + (62, 61, 41), (70, 68, 43), (73, 79, 51), (87, 98, 66), + (108, 92, 69), (111, 92, 65), (115, 92, 61), (103, 83, 56), + (89, 61, 49), (86, 53, 48), (90, 58, 35), (112, 66, 33), + (134, 88, 39), (149, 115, 41), (137, 125, 53), (116, 133, 91), + (69, 154, 112), (47, 107, 117), (45, 73, 85), (37, 62, 82), + (25, 28, 45), (23, 28, 41), (22, 29, 37), (27, 26, 24), + (56, 30, 15), (70, 49, 32), (88, 76, 52), (110, 107, 54), + (130, 141, 73), (144, 167, 89), (140, 157, 103), (135, 149, 100), + (114, 139, 107), (73, 122, 101), (53, 95, 85), (54, 73, 45), + (45, 52, 34), (37, 35, 49), (34, 45, 67), (37, 59, 83), + (33, 66, 97), (33, 66, 99), (33, 68, 98), (44, 70, 83), + (37, 96, 78), (39, 88, 67), (32, 75, 65), (30, 55, 49), + (27, 39, 29), (20, 28, 17), (17, 29, 7), (22, 24, 11), + (30, 24, 8), (31, 25, 11), (33, 27, 11), (33, 37, 14), + (35, 44, 15), (37, 46, 17), (43, 36, 20), (53, 31, 20), + (60, 40, 29), (80, 57, 25), (113, 76, 24), (118, 81, 28), + (94, 76, 30), (74, 68, 18), (48, 59, 19), (44, 48, 23), + (43, 27, 12), (40, 26, 15), (31, 34, 17), (27, 38, 22), + (28, 42, 27), (34, 47, 27), (46, 51, 28), (53, 62, 33), + (61, 85, 53), (91, 105, 79), (112, 122, 88), (152, 126, 91), + (155, 140, 109), (171, 146, 106), (158, 130, 91), (149, 120, 64), + (151, 123, 60), (163, 130, 53), (167, 134, 55), (183, 143, 91), + (197, 146, 93), (190, 160, 136), (166, 163, 96), (146, 138, 76) + ), + +// 314 0u0768.jpg +((61, 117, 166), (17, 102, 182), (25, 106, 174), (33, 110, 166), + (36, 103, 144), (40, 96, 123), (46, 63, 114), (53, 31, 106), + (107, 13, 89), (121, 28, 86), (135, 43, 84), (134, 50, 81), + (133, 58, 78), (131, 61, 59), (129, 65, 40), (131, 55, 42), + (133, 45, 44), (91, 60, 76), (84, 96, 80), (77, 133, 84), + (44, 153, 89), (11, 174, 95), (22, 177, 99), (33, 181, 103), + (27, 184, 141), (21, 178, 164), (16, 173, 188), (15, 162, 201), + (14, 152, 214), (19, 163, 210), (24, 174, 207), (29, 176, 184), + (28, 199, 165), (55, 175, 202), (50, 172, 211), (45, 169, 221), + (46, 156, 202), (47, 143, 183), (48, 136, 189), (49, 130, 196), + (106, 122, 184), (121, 142, 149), (137, 163, 115), (138, 132, 76), + (140, 102, 37), (148, 75, 29), (157, 49, 21), (163, 40, 6), + (162, 27, 7), (124, 21, 77), (109, 27, 123), (94, 33, 170), + (64, 71, 173), (35, 110, 177), (21, 115, 169), (7, 120, 162), + (16, 128, 139), (22, 91, 120), (28, 55, 102), (38, 30, 84), + (49, 5, 66), (53, 11, 60), (58, 18, 55), (105, 8, 28), + (153, 47, 31), (126, 80, 65), (107, 88, 106), (89, 96, 148), + (82, 90, 161), (75, 84, 175), (27, 121, 209), (23, 130, 224), + (79, 73, 159), (70, 62, 116), (61, 52, 73), (56, 39, 69), + (52, 26, 65), (50, 30, 71), (48, 35, 78), (55, 23, 99), + (83, 57, 104), (54, 125, 119), (39, 132, 137), (24, 140, 155), + (26, 135, 163), (28, 131, 172), (33, 129, 215), (28, 132, 231), + (20, 176, 217), (33, 174, 211), (46, 173, 206), (44, 177, 177), + (42, 181, 148), (29, 132, 131), (25, 128, 133), (46, 132, 123), + (76, 141, 83), (51, 109, 25), (91, 99, 35), (132, 89, 46), + (145, 68, 33), (158, 47, 20), (165, 28, 12), (166, 13, 0), + (149, 14, 0), (138, 14, 38), (127, 14, 76), (128, 25, 77), + (129, 37, 78), (162, 32, 68), (171, 43, 78), (164, 58, 68), + (152, 91, 28), (165, 60, 12), (167, 46, 10), (169, 33, 9), + (181, 12, 19), (170, 5, 12), (143, 13, 37), (109, 22, 67), + (125, 20, 115), (136, 30, 133), (147, 41, 152), (153, 44, 128), + (160, 48, 104), (152, 25, 80), (169, 26, 80), (169, 11, 108), + (142, 3, 144), (139, 48, 141), (135, 51, 115), (132, 55, 89), + (115, 33, 56), (101, 23, 62), (110, 17, 72), (115, 4, 80), + (131, 20, 151), (119, 22, 169), (107, 25, 187), (93, 17, 182), + (79, 10, 178), (82, 15, 144), (39, 37, 134), (45, 22, 112), + (79, 8, 88), (124, 30, 56), (136, 28, 36), (149, 27, 16), + (151, 23, 22), (131, 6, 40), (115, 12, 55), (101, 5, 102), + (31, 5, 130), (21, 16, 137), (11, 28, 144), (15, 61, 157), + (22, 92, 180), (42, 117, 208), (41, 73, 194), (78, 74, 194), + (133, 66, 181), (138, 51, 104), (119, 37, 98), (101, 24, 92), + (57, 10, 88), (6, 12, 110), (12, 31, 125), (18, 71, 147), + (31, 27, 150), (28, 22, 156), (26, 17, 162), (15, 20, 184), + (11, 21, 194), (10, 10, 192), (3, 6, 205), (7, 37, 229), + (10, 70, 216), (21, 53, 188), (14, 57, 172), (22, 50, 185), + (23, 24, 194), (25, 12, 206), (14, 18, 203), (22, 52, 200), + (51, 54, 195), (52, 49, 194), (53, 45, 193), (76, 32, 207), + (108, 16, 205), (74, 24, 219), (55, 20, 226), (36, 57, 200), + (34, 68, 227), (44, 82, 219), (56, 93, 225), (57, 99, 209), + (73, 100, 217), (96, 137, 181), (69, 128, 162), (49, 115, 149), + (17, 88, 144), (30, 85, 139), (18, 32, 103), (25, 17, 100), + (37, 24, 70), (50, 21, 69), (80, 31, 76), (84, 92, 94), + (84, 99, 106), (68, 131, 102), (35, 162, 119), (60, 173, 130), + (54, 155, 139), (89, 130, 158), (66, 113, 143), (41, 84, 152), + (26, 85, 145), (32, 95, 126), (21, 100, 141), (27, 100, 143), + (29, 95, 155), (58, 76, 150), (83, 49, 161), (85, 43, 153), + (71, 36, 156), (59, 41, 123), (47, 31, 67), (24, 46, 25), + (0, 13, 30), (29, 33, 78), (9, 80, 108), (11, 136, 130), + (10, 152, 140), (53, 138, 158), (55, 138, 152), (57, 108, 151), + (82, 77, 161), (99, 57, 183), (101, 45, 198), (65, 33, 194), + (41, 29, 177), (51, 57, 177), (29, 84, 151), (11, 97, 156), + (18, 108, 171), (4, 122, 170), (12, 125, 191), (13, 152, 207), + (37, 146, 211), (53, 160, 212), (46, 166, 227), (49, 177, 240), + (84, 158, 223), (106, 142, 192), (133, 84, 189), (85, 77, 134) + ), + +// 315 0u0795.jpg +((34, 103, 134), (41, 113, 138), (23, 112, 151), (6, 112, 164), + (9, 95, 149), (13, 78, 134), (14, 75, 130), (16, 73, 126), + (26, 31, 113), (42, 19, 106), (59, 8, 100), (67, 13, 70), + (76, 18, 40), (71, 11, 22), (66, 4, 5), (44, 4, 2), + (22, 4, 0), (16, 19, 2), (18, 13, 22), (21, 7, 43), + (43, 3, 70), (66, 0, 98), (76, 0, 98), (87, 1, 98), + (141, 15, 96), (120, 36, 88), (100, 58, 80), (70, 64, 89), + (41, 71, 99), (26, 66, 110), (12, 62, 121), (16, 55, 134), + (24, 50, 134), (18, 47, 127), (15, 38, 107), (13, 29, 88), + (31, 59, 103), (50, 89, 118), (49, 108, 132), (49, 127, 147), + (39, 194, 136), (23, 147, 152), (7, 100, 169), (17, 67, 144), + (28, 34, 120), (25, 28, 113), (22, 23, 106), (21, 20, 98), + (43, 13, 75), (71, 9, 32), (73, 5, 16), (75, 1, 0), + (79, 0, 9), (83, 0, 18), (95, 9, 30), (107, 19, 43), + (67, 21, 23), (49, 12, 25), (32, 4, 27), (43, 17, 35), + (55, 31, 44), (48, 51, 63), (41, 71, 82), (23, 88, 126), + (11, 115, 166), (32, 162, 186), (34, 126, 151), (36, 90, 116), + (42, 80, 101), (49, 70, 87), (63, 62, 60), (74, 36, 61), + (121, 11, 72), (114, 11, 88), (107, 12, 104), (80, 7, 102), + (53, 3, 100), (51, 4, 100), (50, 6, 101), (52, 5, 101), + (58, 2, 101), (58, 12, 77), (45, 20, 50), (32, 29, 24), + (23, 24, 28), (14, 20, 32), (8, 10, 31), (22, 13, 40), + (41, 2, 65), (50, 2, 72), (60, 3, 80), (69, 1, 83), + (79, 0, 86), (87, 1, 88), (104, 7, 88), (123, 20, 73), + (140, 23, 68), (138, 17, 96), (113, 9, 96), (89, 2, 96), + (86, 1, 86), (84, 0, 77), (100, 3, 72), (124, 24, 50), + (140, 60, 23), (151, 59, 46), (163, 59, 70), (168, 52, 74), + (173, 45, 78), (184, 67, 86), (189, 68, 83), (198, 67, 99), + (197, 61, 101), (195, 67, 92), (200, 74, 97), (205, 82, 103), + (200, 77, 98), (191, 75, 86), (188, 70, 86), (160, 87, 52), + (142, 83, 13), (124, 53, 9), (106, 23, 5), (123, 40, 4), + (140, 57, 3), (149, 90, 24), (169, 114, 49), (200, 109, 106), + (198, 131, 115), (99, 181, 145), (92, 146, 134), (85, 111, 124), + (66, 75, 130), (92, 83, 74), (121, 90, 72), (187, 71, 80), + (205, 84, 103), (196, 111, 105), (187, 138, 108), (164, 137, 101), + (142, 137, 95), (138, 113, 93), (110, 89, 36), (90, 71, 29), + (69, 46, 52), (22, 34, 92), (36, 41, 115), (51, 48, 139), + (47, 75, 148), (5, 107, 173), (24, 129, 161), (26, 97, 149), + (25, 47, 132), (29, 37, 125), (34, 28, 118), (43, 14, 107), + (68, 1, 98), (106, 5, 97), (144, 18, 100), (182, 40, 100), + (200, 73, 100), (200, 126, 113), (193, 144, 101), (186, 162, 90), + (210, 139, 31), (143, 128, 59), (122, 172, 49), (96, 174, 62), + (130, 147, 105), (103, 156, 124), (76, 165, 143), (51, 124, 175), + (25, 139, 173), (18, 155, 187), (9, 175, 217), (0, 144, 197), + (0, 144, 197), (12, 114, 178), (9, 111, 175), (22, 92, 162), + (23, 55, 138), (14, 22, 105), (2, 4, 65), (17, 10, 43), + (18, 3, 72), (25, 5, 81), (32, 7, 91), (43, 6, 102), + (42, 11, 104), (46, 12, 106), (49, 9, 105), (46, 9, 104), + (48, 3, 94), (23, 9, 88), (25, 18, 60), (31, 13, 55), + (56, 2, 62), (80, 1, 66), (75, 20, 49), (73, 32, 48), + (62, 31, 39), (32, 18, 51), (7, 20, 54), (11, 28, 82), + (18, 25, 105), (31, 25, 113), (34, 29, 121), (20, 45, 129), + (17, 66, 132), (11, 72, 137), (18, 83, 137), (9, 93, 163), + (23, 148, 178), (3, 148, 195), (18, 189, 206), (10, 199, 219), + (21, 193, 213), (33, 186, 202), (64, 189, 181), (65, 165, 153), + (65, 140, 135), (41, 108, 127), (54, 83, 143), (38, 50, 124), + (36, 23, 111), (43, 14, 107), (39, 13, 104), (34, 22, 98), + (58, 52, 98), (80, 28, 100), (116, 12, 101), (133, 14, 98), + (143, 26, 107), (156, 26, 90), (160, 26, 99), (168, 31, 99), + (185, 41, 102), (193, 56, 100), (189, 56, 99), (175, 43, 92), + (152, 30, 87), (136, 15, 95), (97, 30, 84), (88, 2, 89), + (79, 0, 94), (76, 20, 109), (88, 27, 96), (104, 8, 45), + (95, 5, 33), (159, 25, 24), (178, 26, 41), (172, 4, 56), + (148, 37, 53), (112, 72, 60), (89, 114, 93), (84, 119, 113) + ), + +// 316 1u0214.jpg +((77, 64, 9), (21, 12, 77), (21, 25, 80), (22, 39, 83), + (14, 43, 94), (6, 48, 106), (14, 52, 100), (23, 57, 95), + (5, 47, 45), (23, 35, 51), (41, 24, 58), (46, 12, 42), + (51, 1, 26), (60, 4, 27), (70, 8, 29), (71, 7, 38), + (73, 6, 47), (72, 23, 55), (88, 37, 82), (105, 51, 109), + (113, 53, 90), (122, 55, 72), (114, 44, 65), (107, 33, 58), + (117, 31, 30), (101, 43, 35), (85, 56, 40), (75, 64, 29), + (65, 72, 18), (57, 65, 23), (50, 59, 28), (43, 51, 36), + (25, 35, 47), (26, 5, 70), (19, 6, 52), (13, 7, 35), + (13, 12, 29), (13, 18, 24), (13, 18, 29), (13, 19, 35), + (41, 63, 50), (44, 82, 55), (47, 102, 60), (56, 91, 60), + (66, 81, 60), (76, 75, 52), (87, 69, 45), (93, 63, 37), + (97, 63, 38), (102, 36, 22), (110, 36, 23), (118, 36, 24), + (107, 55, 15), (97, 74, 6), (93, 69, 3), (90, 65, 1), + (70, 84, 25), (56, 71, 33), (42, 59, 41), (45, 44, 57), + (48, 29, 74), (36, 33, 79), (25, 37, 85), (27, 53, 68), + (28, 67, 72), (30, 80, 87), (27, 80, 69), (24, 80, 51), + (28, 76, 43), (33, 73, 36), (54, 61, 30), (56, 45, 13), + (62, 35, 28), (64, 37, 27), (66, 40, 27), (64, 30, 34), + (62, 20, 42), (64, 23, 47), (66, 26, 52), (78, 33, 56), + (72, 35, 52), (70, 48, 24), (79, 55, 16), (88, 63, 9), + (97, 51, 12), (106, 40, 16), (112, 37, 14), (118, 28, 4), + (101, 25, 25), (100, 34, 24), (100, 43, 24), (92, 47, 22), + (84, 51, 20), (78, 62, 13), (79, 69, 0), (76, 74, 0), + (72, 84, 10), (67, 78, 22), (56, 80, 27), (45, 83, 32), + (33, 84, 40), (22, 86, 49), (16, 87, 69), (8, 104, 76), + (78, 112, 85), (108, 111, 87), (138, 110, 89), (146, 119, 85), + (155, 128, 81), (153, 128, 74), (185, 155, 45), (150, 121, 17), + (117, 60, 15), (87, 21, 7), (93, 14, 8), (100, 8, 9), + (104, 15, 17), (110, 35, 12), (105, 43, 2), (104, 50, 6), + (130, 68, 0), (146, 78, 6), (162, 88, 13), (135, 86, 12), + (108, 84, 12), (100, 100, 26), (81, 94, 14), (54, 84, 10), + (44, 86, 14), (52, 107, 39), (41, 116, 35), (31, 126, 32), + (33, 111, 49), (49, 104, 49), (52, 77, 45), (70, 57, 38), + (98, 41, 34), (93, 31, 36), (89, 22, 39), (80, 18, 34), + (72, 14, 29), (47, 14, 21), (30, 11, 13), (21, 24, 13), + (8, 39, 34), (25, 74, 71), (32, 73, 60), (40, 72, 49), + (44, 65, 34), (65, 70, 16), (57, 80, 8), (14, 74, 0), + (13, 10, 5), (8, 13, 7), (3, 16, 9), (4, 41, 34), + (19, 77, 78), (8, 124, 89), (13, 140, 51), (36, 111, 55), + (67, 96, 66), (119, 128, 61), (144, 138, 55), (169, 149, 50), + (170, 133, 44), (80, 119, 38), (46, 81, 17), (19, 42, 13), + (15, 10, 17), (18, 5, 16), (21, 0, 15), (23, 5, 31), + (22, 12, 37), (36, 24, 34), (35, 25, 23), (42, 42, 32), + (53, 49, 40), (54, 40, 73), (49, 81, 80), (51, 78, 63), + (69, 61, 58), (87, 50, 67), (63, 36, 53), (54, 22, 63), + (38, 3, 67), (39, 4, 69), (41, 6, 72), (47, 21, 66), + (66, 33, 76), (64, 37, 56), (80, 27, 37), (82, 34, 20), + (89, 43, 20), (89, 58, 14), (92, 68, 24), (74, 79, 25), + (71, 76, 20), (72, 80, 7), (79, 71, 8), (85, 40, 11), + (95, 28, 22), (81, 27, 27), (66, 11, 50), (58, 29, 73), + (71, 21, 92), (78, 20, 79), (91, 30, 45), (115, 18, 38), + (120, 27, 38), (108, 29, 34), (89, 47, 33), (51, 48, 17), + (47, 55, 14), (41, 35, 11), (57, 18, 1), (86, 20, 0), + (124, 11, 5), (142, 5, 33), (134, 16, 32), (126, 18, 52), + (107, 3, 90), (100, 5, 89), (78, 25, 81), (85, 16, 63), + (92, 23, 44), (118, 32, 33), (127, 39, 38), (116, 72, 87), + (89, 86, 97), (52, 120, 141), (24, 98, 107), (39, 75, 73), + (66, 67, 71), (82, 63, 49), (93, 72, 51), (103, 77, 42), + (125, 103, 4), (169, 108, 1), (171, 115, 20), (179, 131, 23), + (195, 107, 57), (162, 101, 34), (154, 103, 46), (156, 97, 37), + (160, 81, 38), (151, 59, 12), (152, 39, 5), (153, 19, 28), + (160, 38, 17), (156, 69, 15), (138, 87, 42), (124, 78, 42), + (143, 85, 74), (125, 86, 81), (130, 102, 90), (76, 130, 117) + ), + +// 317 1u0215.jpg +((29, 35, 21), (22, 59, 41), (31, 59, 58), (40, 59, 76), + (68, 63, 113), (96, 67, 151), (87, 81, 133), (79, 96, 116), + (90, 120, 158), (65, 99, 136), (40, 78, 114), (72, 44, 100), + (105, 11, 87), (126, 12, 84), (148, 13, 82), (148, 26, 76), + (148, 39, 70), (131, 61, 53), (139, 60, 54), (148, 59, 55), + (150, 47, 49), (152, 35, 44), (166, 34, 42), (181, 34, 40), + (188, 12, 14), (168, 6, 7), (149, 1, 1), (136, 7, 1), + (124, 14, 1), (112, 18, 5), (100, 22, 10), (81, 38, 6), + (50, 45, 15), (104, 12, 53), (118, 14, 50), (132, 17, 48), + (123, 12, 48), (114, 8, 48), (92, 10, 41), (71, 13, 35), + (25, 22, 17), (22, 30, 10), (19, 39, 4), (55, 34, 11), + (91, 29, 18), (97, 23, 23), (104, 18, 29), (111, 11, 35), + (115, 8, 36), (71, 13, 54), (36, 25, 64), (2, 38, 74), + (3, 22, 64), (5, 6, 54), (6, 5, 49), (7, 5, 45), + (7, 30, 10), (22, 29, 11), (38, 29, 12), (64, 18, 8), + (91, 7, 5), (81, 18, 7), (72, 29, 10), (44, 33, 13), + (30, 30, 30), (41, 14, 29), (69, 19, 45), (97, 25, 62), + (99, 30, 57), (102, 35, 53), (116, 33, 27), (140, 44, 20), + (196, 40, 25), (192, 31, 20), (189, 22, 16), (187, 14, 13), + (186, 7, 10), (184, 4, 11), (182, 2, 13), (146, 1, 6), + (114, 19, 23), (12, 8, 31), (6, 14, 31), (0, 21, 32), + (2, 27, 21), (5, 33, 10), (4, 39, 9), (10, 39, 9), + (7, 65, 4), (9, 71, 29), (12, 77, 55), (24, 81, 56), + (36, 86, 57), (49, 100, 93), (52, 84, 125), (93, 104, 132), + (100, 101, 145), (110, 130, 102), (95, 133, 86), (80, 136, 71), + (71, 113, 68), (63, 91, 66), (43, 75, 51), (28, 72, 36), + (32, 45, 25), (17, 60, 17), (3, 75, 9), (3, 77, 9), + (4, 79, 10), (9, 83, 20), (4, 68, 44), (13, 33, 58), + (22, 20, 69), (62, 4, 80), (70, 22, 76), (78, 41, 72), + (77, 44, 53), (35, 36, 22), (26, 29, 18), (14, 23, 20), + (5, 11, 11), (8, 8, 8), (11, 5, 5), (11, 9, 3), + (12, 14, 1), (19, 27, 3), (46, 52, 4), (69, 51, 11), + (107, 61, 2), (126, 44, 30), (125, 59, 27), (125, 75, 24), + (119, 75, 26), (72, 60, 22), (34, 50, 21), (6, 34, 11), + (8, 2, 30), (26, 10, 31), (45, 18, 33), (58, 37, 43), + (71, 56, 53), (77, 49, 71), (101, 32, 113), (105, 71, 122), + (130, 48, 114), (156, 12, 71), (169, 7, 51), (183, 3, 32), + (196, 11, 29), (215, 5, 4), (198, 17, 6), (191, 20, 13), + (132, 33, 27), (121, 30, 26), (111, 27, 25), (94, 19, 24), + (61, 47, 38), (48, 85, 33), (50, 93, 50), (77, 91, 68), + (128, 75, 41), (165, 31, 2), (158, 18, 6), (151, 6, 11), + (155, 22, 25), (176, 6, 32), (155, 1, 51), (147, 12, 45), + (140, 14, 15), (140, 15, 14), (140, 16, 14), (135, 16, 12), + (136, 30, 6), (127, 14, 6), (128, 2, 14), (118, 8, 17), + (128, 19, 40), (115, 9, 58), (131, 21, 66), (141, 10, 76), + (144, 14, 78), (147, 14, 57), (158, 4, 68), (169, 8, 60), + (197, 39, 38), (193, 39, 39), (189, 39, 40), (148, 24, 24), + (104, 19, 38), (45, 18, 33), (23, 15, 56), (24, 17, 58), + (5, 30, 60), (0, 42, 41), (16, 47, 49), (59, 45, 58), + (71, 52, 71), (86, 42, 75), (101, 66, 62), (134, 51, 59), + (131, 47, 96), (77, 114, 120), (80, 120, 109), (43, 124, 92), + (32, 124, 39), (30, 110, 39), (9, 103, 76), (44, 111, 93), + (62, 107, 74), (57, 114, 61), (62, 105, 59), (50, 106, 45), + (59, 122, 52), (75, 98, 72), (117, 88, 46), (126, 72, 36), + (145, 51, 23), (163, 36, 30), (188, 18, 45), (199, 18, 49), + (211, 48, 29), (210, 55, 33), (225, 67, 2), (227, 57, 5), + (230, 22, 18), (198, 41, 26), (186, 44, 43), (152, 39, 83), + (121, 35, 96), (89, 35, 61), (60, 31, 49), (30, 20, 47), + (8, 34, 25), (5, 48, 18), (9, 54, 21), (25, 69, 36), + (30, 77, 31), (33, 88, 31), (40, 85, 44), (48, 79, 48), + (64, 79, 82), (57, 42, 71), (44, 6, 83), (42, 1, 93), + (65, 26, 107), (75, 49, 96), (43, 78, 110), (5, 118, 126), + (40, 155, 142), (36, 150, 117), (83, 136, 68), (143, 90, 40), + (167, 82, 27), (182, 44, 44), (177, 39, 39), (145, 50, 32) + ), + +// 318 1u0216.jpg +((85, 57, 217), (47, 123, 149), (59, 116, 132), (71, 110, 115), + (110, 106, 97), (150, 102, 80), (178, 95, 77), (206, 88, 74), + (170, 78, 125), (118, 75, 132), (67, 72, 140), (46, 53, 144), + (25, 35, 148), (26, 26, 147), (27, 18, 147), (29, 14, 161), + (31, 10, 175), (31, 32, 184), (19, 29, 169), (7, 26, 154), + (51, 23, 151), (95, 20, 149), (96, 34, 141), (98, 48, 133), + (70, 55, 122), (45, 52, 142), (20, 50, 162), (28, 50, 185), + (36, 50, 208), (48, 59, 208), (60, 69, 208), (70, 112, 232), + (105, 111, 209), (152, 179, 170), (181, 163, 172), (211, 147, 174), + (197, 128, 162), (184, 109, 150), (173, 102, 141), (162, 96, 132), + (84, 100, 113), (88, 104, 121), (92, 109, 129), (115, 96, 152), + (139, 84, 175), (142, 72, 173), (145, 61, 172), (157, 53, 150), + (156, 53, 142), (67, 9, 191), (51, 10, 198), (35, 12, 206), + (25, 12, 214), (15, 12, 223), (14, 12, 213), (14, 13, 203), + (2, 3, 155), (6, 7, 163), (11, 11, 171), (30, 29, 191), + (50, 48, 211), (55, 52, 212), (61, 57, 214), (69, 55, 210), + (74, 73, 209), (86, 93, 199), (131, 76, 195), (176, 59, 191), + (183, 54, 172), (191, 50, 154), (215, 62, 109), (237, 90, 80), + (229, 180, 85), (221, 163, 103), (214, 147, 121), (194, 117, 129), + (174, 88, 137), (163, 71, 131), (152, 55, 126), (143, 23, 121), + (135, 42, 148), (126, 40, 167), (119, 55, 183), (112, 71, 199), + (106, 67, 199), (100, 64, 200), (71, 70, 206), (24, 88, 188), + (2, 114, 164), (18, 135, 168), (35, 157, 172), (40, 147, 167), + (45, 137, 162), (101, 118, 187), (90, 98, 196), (106, 99, 177), + (134, 127, 169), (178, 114, 151), (176, 100, 144), (175, 87, 138), + (190, 74, 124), (206, 62, 111), (188, 44, 113), (175, 20, 121), + (168, 10, 131), (163, 7, 125), (158, 5, 119), (157, 3, 112), + (156, 1, 105), (146, 18, 113), (130, 13, 130), (102, 23, 142), + (56, 54, 164), (4, 42, 169), (2, 45, 161), (0, 48, 153), + (26, 47, 138), (45, 70, 137), (45, 73, 136), (48, 72, 182), + (52, 61, 218), (49, 50, 220), (47, 39, 223), (44, 32, 221), + (41, 25, 220), (29, 38, 201), (24, 46, 166), (51, 48, 139), + (131, 19, 147), (186, 29, 100), (193, 22, 89), (200, 16, 78), + (213, 19, 82), (213, 33, 98), (212, 32, 97), (187, 19, 96), + (126, 38, 98), (86, 74, 122), (47, 111, 147), (42, 107, 152), + (37, 104, 157), (16, 104, 178), (7, 86, 205), (6, 50, 201), + (32, 45, 211), (27, 15, 201), (25, 19, 186), (23, 23, 171), + (0, 24, 158), (4, 25, 178), (10, 28, 174), (38, 22, 193), + (75, 33, 227), (100, 31, 216), (126, 29, 206), (154, 27, 192), + (124, 17, 211), (84, 17, 236), (74, 23, 238), (88, 60, 233), + (108, 89, 207), (165, 108, 211), (168, 111, 216), (172, 115, 222), + (200, 117, 185), (209, 140, 184), (215, 154, 149), (213, 162, 143), + (203, 128, 122), (204, 120, 112), (205, 113, 102), (221, 96, 92), + (244, 100, 99), (232, 102, 88), (201, 129, 104), (199, 137, 114), + (184, 118, 128), (194, 89, 93), (188, 85, 102), (191, 118, 135), + (159, 165, 161), (138, 168, 160), (64, 171, 181), (44, 170, 159), + (111, 138, 93), (140, 111, 98), (169, 84, 103), (207, 61, 84), + (197, 37, 101), (178, 34, 93), (136, 30, 118), (61, 64, 133), + (40, 102, 151), (44, 131, 161), (22, 155, 160), (25, 162, 155), + (41, 159, 173), (49, 148, 153), (98, 111, 156), (167, 76, 143), + (168, 63, 130), (214, 60, 94), (220, 38, 61), (221, 13, 45), + (214, 23, 30), (210, 32, 32), (245, 33, 21), (209, 51, 16), + (209, 57, 16), (200, 69, 1), (175, 101, 30), (190, 69, 38), + (193, 64, 86), (149, 39, 110), (102, 49, 153), (79, 41, 180), + (62, 30, 217), (60, 29, 228), (50, 48, 235), (54, 45, 224), + (71, 53, 225), (146, 81, 201), (182, 73, 198), (208, 73, 193), + (197, 76, 169), (205, 68, 146), (215, 72, 100), (233, 90, 74), + (228, 88, 71), (235, 61, 71), (178, 36, 92), (130, 27, 118), + (54, 56, 139), (23, 59, 181), (28, 40, 204), (37, 27, 210), + (66, 20, 207), (82, 32, 191), (109, 40, 191), (124, 11, 161), + (156, 24, 136), (191, 44, 151), (231, 43, 104), (240, 59, 92), + (228, 89, 122), (208, 139, 110), (226, 171, 115), (218, 162, 129), + (198, 125, 136), (176, 109, 127), (114, 141, 98), (100, 130, 96), + (84, 115, 97), (57, 102, 133), (47, 71, 133), (42, 60, 136) + ), + +// 319 1u0216pp1.jpg +((39, 104, 80), (57, 122, 114), (67, 146, 129), (78, 171, 144), + (97, 186, 98), (116, 202, 53), (147, 203, 41), (178, 205, 30), + (185, 182, 77), (186, 161, 108), (188, 140, 140), (172, 136, 150), + (156, 133, 161), (129, 142, 143), (103, 151, 125), (98, 157, 131), + (93, 163, 137), (65, 173, 54), (62, 148, 60), (60, 123, 66), + (59, 138, 71), (59, 153, 77), (51, 163, 91), (44, 173, 106), + (79, 205, 131), (70, 187, 136), (61, 170, 141), (37, 162, 158), + (13, 155, 175), (16, 153, 175), (20, 152, 175), (46, 166, 156), + (55, 152, 143), (78, 160, 75), (126, 172, 56), (175, 185, 37), + (210, 190, 57), (245, 196, 77), (242, 183, 75), (240, 170, 74), + (214, 105, 82), (229, 125, 84), (244, 145, 86), (239, 175, 92), + (234, 206, 99), (227, 189, 99), (220, 172, 100), (217, 149, 100), + (227, 186, 94), (232, 195, 55), (212, 194, 61), (193, 194, 67), + (162, 150, 94), (131, 107, 121), (118, 115, 111), (105, 123, 101), + (83, 152, 98), (84, 179, 85), (85, 207, 72), (94, 228, 97), + (104, 249, 122), (113, 247, 127), (123, 246, 132), (153, 242, 114), + (160, 212, 114), (175, 193, 91), (193, 161, 90), (212, 129, 89), + (184, 133, 85), (157, 138, 82), (146, 127, 69), (107, 77, 77), + (143, 137, 87), (152, 150, 72), (162, 164, 57), (186, 200, 45), + (211, 236, 33), (203, 239, 44), (196, 242, 56), (221, 237, 79), + (228, 245, 71), (255, 218, 55), (248, 200, 50), (242, 183, 45), + (248, 166, 53), (255, 149, 61), (248, 135, 91), (247, 145, 60), + (247, 181, 58), (244, 201, 74), (242, 222, 91), (228, 218, 107), + (215, 214, 124), (209, 206, 125), (195, 177, 131), (131, 159, 119), + (83, 173, 147), (30, 142, 164), (33, 121, 154), (37, 100, 144), + (43, 102, 144), (49, 104, 145), (52, 110, 134), (54, 124, 136), + (39, 147, 157), (54, 141, 144), (70, 136, 132), (103, 130, 132), + (136, 125, 133), (151, 128, 148), (177, 160, 144), (197, 181, 122), + (130, 224, 112), (69, 222, 131), (61, 217, 144), (53, 212, 158), + (46, 201, 161), (74, 181, 165), (76, 194, 162), (76, 205, 174), + (95, 227, 152), (127, 180, 157), (159, 134, 163), (173, 134, 152), + (188, 135, 141), (210, 68, 124), (211, 72, 113), (217, 76, 111), + (225, 97, 98), (192, 184, 59), (182, 187, 41), (173, 190, 24), + (176, 210, 25), (158, 208, 73), (104, 204, 108), (78, 154, 126), + (40, 105, 145), (32, 111, 124), (25, 117, 104), (32, 130, 100), + (40, 143, 96), (54, 203, 121), (60, 233, 141), (60, 232, 172), + (32, 243, 224), (45, 236, 231), (37, 232, 229), (29, 229, 227), + (43, 207, 183), (34, 186, 163), (19, 181, 170), (50, 195, 240), + (87, 167, 194), (83, 178, 178), (79, 189, 162), (82, 201, 135), + (117, 201, 124), (155, 213, 90), (195, 239, 58), (235, 247, 43), + (244, 252, 45), (171, 226, 10), (171, 222, 25), (171, 218, 40), + (105, 217, 45), (102, 222, 73), (92, 196, 71), (105, 197, 52), + (172, 177, 25), (176, 196, 25), (180, 215, 25), (162, 243, 50), + (157, 244, 88), (131, 235, 114), (90, 246, 123), (62, 224, 112), + (64, 234, 135), (52, 227, 136), (47, 211, 140), (24, 219, 149), + (26, 202, 163), (28, 192, 158), (57, 214, 159), (107, 244, 154), + (195, 255, 100), (206, 237, 111), (217, 219, 122), (218, 218, 122), + (216, 212, 123), (200, 198, 121), (206, 165, 121), (168, 150, 112), + (107, 155, 115), (72, 146, 129), (56, 130, 143), (42, 136, 146), + (54, 124, 150), (129, 98, 129), (139, 114, 146), (93, 129, 189), + (44, 133, 189), (26, 115, 171), (18, 104, 181), (7, 151, 185), + (26, 170, 178), (39, 207, 236), (18, 220, 240), (34, 218, 230), + (35, 219, 227), (59, 203, 167), (88, 218, 158), (113, 231, 145), + (150, 226, 104), (211, 214, 65), (222, 203, 83), (222, 201, 82), + (212, 198, 73), (228, 187, 61), (226, 211, 60), (237, 232, 66), + (242, 235, 67), (252, 228, 78), (230, 231, 75), (238, 237, 84), + (244, 253, 110), (243, 255, 111), (250, 253, 104), (240, 244, 85), + (252, 228, 102), (235, 224, 108), (226, 214, 112), (216, 180, 102), + (199, 147, 125), (190, 146, 137), (184, 147, 139), (181, 148, 141), + (188, 156, 143), (209, 188, 123), (210, 217, 121), (153, 255, 103), + (103, 246, 132), (75, 251, 143), (63, 246, 163), (80, 242, 133), + (101, 231, 135), (128, 222, 112), (146, 224, 104), (160, 212, 76), + (168, 207, 64), (197, 206, 35), (193, 194, 56), (207, 180, 73), + (203, 169, 80), (199, 150, 109), (193, 194, 116), (202, 178, 116) + ), + +// 320 3m0001.jpg +((37, 166, 208), (26, 126, 214), (34, 125, 223), (43, 124, 232), + (84, 147, 221), (125, 170, 211), (102, 149, 180), (80, 128, 150), + (12, 35, 103), (24, 22, 112), (37, 9, 122), (72, 9, 106), + (108, 9, 91), (128, 8, 105), (148, 7, 119), (153, 7, 135), + (159, 7, 151), (246, 55, 133), (234, 69, 108), (222, 84, 84), + (220, 77, 73), (218, 71, 63), (224, 60, 80), (231, 49, 97), + (203, 32, 98), (208, 22, 108), (214, 13, 119), (206, 15, 127), + (199, 18, 135), (202, 15, 149), (206, 13, 164), (181, 21, 191), + (163, 8, 198), (96, 68, 230), (68, 127, 212), (40, 187, 195), + (48, 163, 136), (57, 139, 77), (87, 140, 93), (117, 142, 110), + (224, 121, 90), (239, 120, 97), (255, 120, 104), (220, 94, 113), + (185, 68, 123), (182, 62, 123), (179, 56, 123), (174, 29, 104), + (169, 6, 97), (183, 30, 94), (166, 53, 100), (150, 77, 106), + (117, 92, 119), (84, 108, 132), (105, 92, 135), (127, 77, 138), + (183, 29, 153), (164, 25, 142), (146, 22, 132), (129, 25, 139), + (113, 28, 147), (102, 34, 167), (92, 40, 187), (123, 59, 182), + (156, 45, 176), (166, 169, 240), (160, 196, 231), (154, 224, 222), + (144, 206, 212), (135, 188, 202), (151, 186, 205), (152, 141, 207), + (190, 125, 209), (182, 133, 179), (174, 141, 150), (179, 113, 143), + (184, 86, 137), (177, 76, 132), (171, 67, 128), (171, 62, 153), + (179, 50, 153), (209, 59, 123), (211, 49, 122), (213, 40, 122), + (212, 43, 116), (211, 47, 110), (222, 77, 84), (236, 100, 76), + (234, 139, 85), (234, 141, 61), (234, 143, 38), (229, 133, 41), + (224, 123, 45), (239, 118, 89), (244, 93, 102), (245, 77, 152), + (250, 86, 175), (192, 149, 192), (184, 168, 199), (176, 187, 207), + (193, 161, 212), (210, 135, 218), (235, 75, 233), (228, 41, 220), + (229, 6, 195), (207, 5, 194), (186, 5, 194), (185, 6, 194), + (184, 8, 195), (170, 4, 176), (185, 8, 174), (182, 46, 170), + (124, 115, 196), (13, 87, 196), (17, 104, 218), (21, 121, 241), + (38, 117, 246), (67, 43, 225), (59, 64, 164), (87, 43, 156), + (167, 45, 106), (178, 58, 76), (190, 71, 47), (192, 79, 47), + (195, 87, 48), (189, 81, 42), (174, 60, 50), (145, 11, 74), + (125, 14, 65), (119, 32, 111), (128, 33, 125), (137, 34, 139), + (149, 21, 140), (174, 23, 160), (191, 20, 174), (197, 45, 182), + (194, 89, 208), (143, 138, 206), (92, 187, 205), (89, 182, 191), + (86, 177, 178), (74, 148, 159), (57, 123, 173), (41, 112, 176), + (33, 121, 171), (29, 67, 148), (32, 54, 137), (35, 41, 127), + (45, 33, 143), (30, 7, 149), (0, 24, 165), (19, 25, 165), + (34, 44, 194), (36, 33, 205), (39, 22, 216), (45, 8, 186), + (68, 3, 159), (107, 9, 128), (111, 7, 130), (117, 5, 152), + (122, 18, 129), (169, 62, 134), (163, 70, 126), (157, 79, 118), + (183, 82, 138), (222, 88, 151), (223, 74, 158), (220, 49, 153), + (189, 44, 113), (178, 48, 114), (167, 53, 115), (112, 41, 107), + (77, 79, 136), (50, 95, 128), (76, 93, 171), (111, 69, 213), + (156, 50, 208), (194, 33, 191), (198, 48, 207), (217, 70, 184), + (213, 89, 177), (240, 91, 172), (240, 59, 140), (220, 45, 146), + (179, 43, 169), (153, 53, 160), (128, 64, 151), (79, 98, 166), + (117, 108, 151), (121, 79, 142), (145, 92, 98), (144, 103, 119), + (144, 176, 137), (127, 221, 143), (121, 230, 162), (90, 216, 202), + (80, 205, 211), (95, 220, 216), (98, 212, 202), (114, 211, 176), + (144, 167, 139), (146, 101, 144), (133, 58, 140), (139, 33, 141), + (140, 11, 155), (165, 7, 164), (192, 23, 176), (202, 35, 167), + (209, 32, 146), (202, 34, 122), (194, 30, 117), (188, 44, 105), + (186, 27, 93), (186, 12, 75), (190, 30, 102), (222, 29, 122), + (243, 28, 132), (229, 37, 138), (222, 27, 145), (230, 35, 153), + (243, 10, 154), (212, 11, 165), (218, 23, 177), (200, 28, 192), + (181, 66, 209), (149, 101, 213), (154, 127, 206), (98, 125, 214), + (85, 151, 247), (136, 119, 213), (151, 98, 216), (160, 74, 227), + (150, 66, 222), (175, 47, 222), (167, 25, 231), (184, 19, 201), + (201, 13, 172), (214, 24, 184), (197, 53, 210), (194, 86, 187), + (222, 109, 191), (178, 129, 158), (161, 135, 134), (187, 99, 150), + (207, 91, 138), (216, 92, 142), (225, 105, 133), (231, 113, 127), + (238, 102, 122), (231, 110, 93), (239, 126, 92), (238, 147, 90), + (234, 146, 100), (229, 201, 118), (235, 193, 145), (171, 188, 206) + ), + +// 321 3m0004.jpg +((24, 26, 38), (15, 20, 14), (32, 49, 9), (50, 78, 4), + (71, 71, 3), (93, 65, 2), (98, 58, 3), (103, 52, 5), + (88, 8, 19), (81, 11, 21), (74, 14, 24), (51, 20, 30), + (29, 26, 37), (14, 15, 36), (0, 4, 36), (6, 10, 41), + (13, 17, 46), (43, 36, 87), (59, 39, 88), (76, 43, 90), + (87, 32, 73), (99, 22, 56), (103, 13, 45), (108, 5, 35), + (179, 31, 45), (196, 31, 71), (214, 31, 97), (168, 26, 79), + (123, 22, 62), (114, 26, 58), (105, 31, 54), (74, 37, 21), + (89, 45, 20), (123, 117, 19), (128, 126, 9), (134, 135, 0), + (150, 133, 32), (166, 131, 65), (173, 114, 61), (180, 97, 57), + (142, 72, 72), (99, 90, 49), (57, 109, 27), (35, 132, 49), + (14, 156, 72), (38, 163, 89), (62, 171, 106), (123, 125, 104), + (108, 62, 72), (92, 34, 46), (84, 26, 42), (76, 19, 38), + (69, 31, 43), (62, 43, 49), (56, 53, 48), (51, 64, 47), + (11, 103, 36), (26, 150, 32), (41, 197, 28), (64, 175, 34), + (87, 154, 41), (76, 123, 23), (65, 93, 6), (102, 96, 10), + (107, 69, 6), (63, 53, 52), (74, 73, 52), (85, 93, 52), + (94, 86, 38), (104, 79, 25), (112, 66, 43), (105, 62, 30), + (105, 50, 20), (109, 35, 11), (113, 20, 2), (97, 16, 3), + (81, 13, 4), (74, 16, 3), (67, 20, 2), (69, 30, 1), + (65, 27, 14), (60, 59, 67), (39, 83, 92), (18, 108, 117), + (14, 111, 147), (10, 114, 177), (20, 108, 198), (35, 69, 130), + (30, 58, 61), (28, 45, 45), (26, 32, 30), (40, 39, 32), + (55, 47, 34), (61, 70, 23), (58, 83, 25), (73, 81, 42), + (81, 76, 38), (68, 52, 65), (83, 55, 74), (99, 59, 83), + (112, 69, 83), (126, 80, 83), (182, 126, 137), (143, 159, 156), + (61, 121, 131), (56, 81, 96), (51, 42, 61), (46, 35, 60), + (42, 29, 59), (38, 22, 49), (61, 20, 36), (83, 17, 29), + (85, 5, 14), (68, 22, 9), (58, 15, 9), (48, 8, 9), + (64, 27, 11), (109, 41, 20), (141, 74, 4), (162, 96, 9), + (175, 60, 15), (166, 37, 9), (157, 15, 3), (166, 14, 9), + (176, 13, 16), (178, 15, 16), (187, 19, 52), (218, 24, 61), + (205, 48, 55), (141, 34, 112), (143, 25, 127), (146, 17, 143), + (88, 4, 144), (63, 16, 130), (65, 42, 132), (50, 34, 143), + (28, 36, 119), (24, 41, 93), (20, 47, 68), (22, 66, 52), + (24, 86, 37), (52, 87, 7), (22, 73, 6), (26, 60, 25), + (41, 54, 47), (60, 7, 121), (75, 14, 118), (91, 22, 115), + (105, 42, 99), (124, 37, 72), (132, 46, 59), (144, 55, 41), + (209, 41, 32), (216, 31, 33), (224, 22, 34), (228, 59, 40), + (232, 100, 35), (243, 108, 27), (228, 110, 74), (241, 149, 48), + (226, 147, 44), (245, 167, 17), (239, 173, 16), (233, 180, 16), + (236, 168, 5), (224, 156, 21), (200, 160, 11), (189, 136, 22), + (104, 119, 78), (106, 128, 82), (109, 137, 86), (125, 160, 68), + (112, 182, 50), (133, 180, 52), (171, 161, 14), (176, 169, 19), + (212, 159, 27), (192, 126, 66), (221, 100, 89), (219, 102, 93), + (223, 132, 85), (212, 144, 71), (200, 139, 108), (199, 169, 119), + (248, 167, 120), (225, 156, 120), (203, 145, 121), (172, 75, 86), + (148, 52, 80), (123, 40, 56), (114, 33, 32), (114, 31, 23), + (113, 23, 14), (103, 13, 25), (91, 4, 12), (83, 11, 15), + (44, 15, 20), (26, 16, 14), (2, 11, 16), (10, 12, 11), + (21, 18, 1), (22, 24, 3), (13, 41, 3), (4, 44, 20), + (2, 50, 26), (17, 47, 11), (31, 19, 21), (83, 9, 44), + (147, 23, 57), (172, 52, 53), (200, 81, 85), (202, 104, 59), + (191, 126, 96), (197, 131, 117), (168, 114, 102), (118, 80, 77), + (94, 75, 60), (105, 65, 55), (123, 76, 68), (161, 77, 43), + (195, 66, 37), (231, 110, 6), (216, 128, 0), (233, 140, 9), + (217, 139, 15), (199, 135, 12), (184, 108, 32), (170, 119, 38), + (128, 103, 19), (83, 135, 27), (15, 168, 85), (1, 185, 133), + (23, 141, 143), (44, 129, 166), (41, 77, 200), (83, 59, 143), + (92, 60, 145), (94, 35, 145), (86, 35, 104), (119, 17, 91), + (142, 31, 82), (111, 26, 49), (87, 31, 40), (91, 42, 38), + (97, 37, 27), (101, 44, 37), (100, 53, 27), (110, 69, 25), + (107, 42, 40), (101, 45, 72), (109, 7, 91), (89, 19, 92), + (77, 30, 85), (55, 13, 95), (69, 11, 62), (37, 13, 65) + ), + +// 322 3m0005.jpg +((112, 35, 45), (85, 8, 40), (99, 30, 33), (113, 53, 27), + (118, 53, 34), (123, 53, 41), (143, 59, 46), (163, 65, 52), + (170, 9, 123), (124, 14, 116), (79, 20, 110), (55, 29, 105), + (31, 39, 101), (22, 31, 96), (13, 23, 92), (35, 28, 78), + (57, 33, 65), (120, 100, 135), (115, 130, 139), (110, 161, 144), + (122, 190, 165), (134, 219, 186), (133, 227, 184), (133, 236, 183), + (96, 214, 156), (106, 206, 133), (116, 199, 111), (108, 152, 84), + (100, 106, 58), (82, 89, 42), (64, 73, 26), (33, 54, 21), + (14, 45, 37), (2, 22, 83), (7, 23, 73), (13, 25, 63), + (13, 29, 51), (14, 33, 39), (15, 32, 37), (16, 31, 36), + (37, 48, 34), (81, 37, 25), (125, 27, 16), (140, 30, 11), + (155, 34, 7), (159, 37, 3), (163, 40, 0), (155, 59, 8), + (109, 60, 28), (33, 37, 12), (33, 26, 7), (33, 15, 3), + (16, 11, 7), (0, 7, 12), (0, 4, 6), (0, 1, 0), + (21, 3, 15), (32, 9, 9), (43, 15, 3), (50, 23, 21), + (57, 31, 40), (60, 46, 55), (63, 62, 70), (78, 107, 79), + (82, 110, 72), (46, 98, 23), (51, 92, 20), (56, 87, 17), + (42, 88, 27), (29, 89, 37), (16, 74, 33), (19, 68, 39), + (49, 56, 15), (61, 49, 27), (73, 42, 39), (85, 80, 65), + (98, 118, 91), (100, 149, 101), (103, 180, 112), (102, 233, 129), + (89, 213, 115), (54, 148, 95), (33, 105, 95), (13, 62, 95), + (6, 38, 96), (0, 14, 97), (17, 8, 63), (35, 17, 43), + (44, 33, 37), (36, 38, 45), (29, 43, 54), (32, 37, 63), + (36, 31, 72), (33, 30, 73), (18, 58, 70), (15, 91, 61), + (32, 86, 54), (37, 94, 41), (42, 76, 41), (47, 58, 41), + (51, 56, 40), (56, 54, 39), (61, 37, 51), (108, 44, 42), + (145, 23, 62), (128, 15, 40), (111, 7, 18), (84, 18, 19), + (58, 29, 21), (18, 32, 33), (2, 47, 24), (6, 53, 21), + (7, 80, 35), (14, 103, 39), (17, 97, 32), (21, 92, 26), + (36, 106, 17), (45, 113, 12), (40, 124, 36), (66, 120, 94), + (67, 152, 149), (66, 134, 116), (65, 116, 83), (69, 115, 86), + (74, 114, 90), (104, 133, 105), (130, 149, 94), (177, 182, 79), + (204, 197, 106), (246, 226, 155), (234, 212, 119), (222, 199, 83), + (228, 156, 72), (246, 93, 75), (181, 136, 81), (152, 143, 78), + (185, 140, 107), (175, 153, 120), (165, 166, 134), (170, 176, 136), + (175, 187, 139), (173, 188, 129), (148, 182, 98), (117, 174, 129), + (87, 154, 137), (39, 124, 95), (24, 122, 103), (10, 120, 111), + (11, 105, 87), (6, 97, 54), (15, 135, 27), (25, 129, 14), + (15, 67, 3), (15, 62, 12), (16, 58, 22), (14, 42, 46), + (22, 46, 50), (51, 27, 63), (70, 6, 90), (71, 24, 78), + (52, 45, 86), (57, 87, 27), (82, 112, 25), (107, 137, 23), + (167, 158, 27), (229, 175, 27), (255, 196, 33), (236, 162, 53), + (112, 126, 47), (101, 124, 43), (91, 123, 40), (100, 98, 50), + (106, 89, 63), (61, 72, 55), (94, 81, 49), (114, 67, 25), + (106, 59, 33), (81, 32, 38), (69, 45, 33), (77, 104, 49), + (105, 140, 48), (133, 161, 59), (162, 184, 76), (202, 204, 43), + (239, 143, 33), (206, 131, 39), (173, 119, 45), (175, 91, 57), + (169, 32, 60), (209, 9, 48), (212, 5, 11), (197, 19, 33), + (185, 22, 25), (125, 8, 34), (78, 9, 38), (76, 11, 67), + (116, 23, 104), (100, 28, 114), (76, 20, 127), (51, 67, 103), + (37, 75, 94), (32, 79, 73), (48, 119, 49), (84, 108, 48), + (97, 108, 16), (109, 95, 20), (113, 82, 2), (89, 44, 3), + (80, 29, 8), (55, 16, 9), (31, 10, 27), (9, 5, 22), + (11, 8, 25), (11, 20, 37), (13, 28, 35), (12, 12, 20), + (25, 23, 11), (24, 27, 18), (58, 54, 16), (96, 87, 28), + (149, 114, 56), (141, 148, 53), (119, 129, 92), (122, 159, 92), + (115, 152, 108), (113, 162, 107), (109, 163, 137), (170, 125, 182), + (158, 119, 122), (147, 106, 122), (132, 105, 112), (119, 79, 113), + (113, 101, 85), (60, 109, 77), (17, 114, 105), (22, 76, 120), + (17, 69, 90), (10, 68, 79), (17, 81, 80), (33, 76, 59), + (60, 69, 48), (98, 63, 25), (122, 103, 27), (144, 117, 26), + (157, 133, 47), (171, 109, 60), (229, 93, 79), (222, 81, 89), + (181, 86, 108), (189, 50, 107), (203, 16, 119), (211, 22, 80), + (210, 79, 59), (175, 97, 23), (108, 118, 19), (33, 128, 34) + ), + +// 323 3m0006.jpg +((13, 117, 206), (44, 114, 52), (26, 111, 30), (8, 108, 9), + (39, 57, 15), (70, 6, 22), (69, 5, 54), (69, 4, 86), + (38, 5, 118), (21, 12, 104), (5, 19, 90), (9, 21, 79), + (13, 24, 69), (29, 36, 73), (45, 49, 78), (48, 44, 76), + (51, 40, 74), (70, 19, 96), (85, 18, 95), (101, 17, 95), + (95, 18, 105), (89, 19, 115), (84, 20, 110), (79, 21, 106), + (64, 10, 130), (56, 29, 136), (49, 48, 142), (59, 53, 135), + (69, 59, 128), (78, 67, 114), (88, 75, 101), (136, 74, 85), + (143, 72, 70), (166, 105, 50), (171, 83, 35), (177, 61, 20), + (155, 55, 10), (133, 50, 0), (140, 49, 5), (148, 49, 10), + (202, 26, 72), (216, 34, 60), (231, 42, 49), (223, 86, 56), + (215, 130, 63), (220, 133, 60), (226, 136, 58), (218, 188, 102), + (205, 229, 69), (129, 172, 93), (93, 161, 90), (58, 150, 87), + (73, 145, 95), (88, 140, 104), (104, 128, 98), (121, 117, 92), + (138, 83, 80), (135, 73, 100), (132, 64, 121), (144, 101, 102), + (156, 139, 83), (154, 141, 82), (152, 144, 81), (113, 134, 65), + (127, 88, 83), (101, 32, 95), (121, 27, 103), (141, 22, 112), + (139, 28, 92), (137, 35, 72), (144, 56, 46), (143, 114, 48), + (148, 181, 94), (167, 181, 102), (186, 182, 111), (169, 190, 125), + (153, 198, 139), (137, 175, 145), (121, 153, 152), (104, 159, 190), + (71, 142, 230), (60, 166, 214), (102, 163, 186), (144, 160, 159), + (157, 159, 131), (170, 159, 103), (223, 152, 70), (237, 145, 42), + (199, 61, 58), (174, 44, 63), (150, 28, 69), (151, 23, 62), + (153, 19, 56), (129, 6, 61), (119, 3, 48), (114, 12, 36), + (80, 23, 32), (80, 3, 81), (84, 10, 88), (89, 18, 96), + (83, 13, 93), (77, 8, 91), (90, 39, 82), (94, 38, 77), + (129, 72, 29), (152, 79, 39), (176, 86, 49), (175, 93, 69), + (174, 100, 89), (164, 122, 132), (140, 100, 196), (54, 111, 178), + (43, 129, 176), (20, 139, 219), (29, 134, 227), (38, 129, 236), + (88, 203, 248), (164, 193, 237), (152, 178, 229), (131, 187, 178), + (59, 160, 142), (42, 144, 110), (25, 129, 78), (36, 125, 77), + (48, 121, 76), (74, 122, 82), (95, 108, 88), (153, 86, 67), + (147, 67, 56), (103, 82, 81), (104, 103, 97), (105, 125, 113), + (58, 150, 127), (33, 177, 150), (33, 175, 159), (36, 136, 170), + (81, 105, 73), (135, 114, 54), (189, 123, 36), (197, 127, 44), + (205, 132, 53), (205, 98, 52), (201, 74, 91), (196, 71, 127), + (215, 39, 138), (156, 13, 105), (151, 11, 105), (147, 9, 105), + (137, 20, 135), (104, 67, 119), (59, 109, 120), (29, 75, 127), + (80, 39, 81), (80, 51, 63), (81, 64, 46), (45, 93, 45), + (47, 69, 83), (42, 68, 127), (22, 75, 187), (16, 116, 230), + (41, 160, 244), (46, 201, 249), (48, 180, 216), (51, 160, 183), + (6, 155, 126), (31, 172, 60), (139, 162, 32), (185, 138, 24), + (207, 123, 37), (203, 105, 33), (200, 87, 29), (195, 25, 12), + (184, 24, 8), (177, 15, 10), (168, 3, 17), (136, 2, 35), + (101, 6, 74), (59, 5, 89), (21, 8, 88), (13, 5, 78), + (9, 0, 48), (33, 0, 49), (58, 14, 37), (46, 43, 86), + (0, 67, 116), (3, 100, 130), (6, 134, 145), (19, 145, 206), + (5, 205, 230), (21, 211, 243), (6, 203, 209), (48, 169, 188), + (27, 146, 178), (24, 139, 122), (61, 95, 97), (68, 85, 103), + (75, 64, 58), (75, 44, 75), (93, 39, 63), (129, 69, 45), + (123, 59, 34), (126, 53, 21), (124, 37, 7), (97, 22, 16), + (77, 35, 49), (79, 62, 34), (38, 52, 26), (37, 55, 13), + (58, 96, 19), (122, 61, 0), (129, 66, 12), (138, 127, 35), + (119, 163, 78), (147, 205, 82), (194, 226, 67), (193, 220, 45), + (188, 159, 42), (185, 116, 21), (166, 78, 38), (139, 72, 17), + (134, 123, 17), (146, 148, 3), (189, 152, 2), (193, 123, 11), + (185, 92, 15), (206, 54, 17), (184, 26, 23), (180, 9, 25), + (166, 19, 27), (150, 25, 21), (132, 11, 30), (153, 17, 37), + (166, 0, 42), (218, 28, 74), (218, 32, 82), (206, 26, 61), + (165, 27, 43), (147, 20, 13), (152, 3, 0), (169, 20, 0), + (171, 20, 11), (167, 21, 21), (178, 29, 9), (180, 52, 27), + (173, 113, 61), (158, 115, 83), (121, 92, 148), (54, 120, 170), + (58, 97, 152), (48, 64, 123), (56, 34, 81), (84, 34, 85), + (84, 30, 106), (120, 66, 98), (95, 132, 91), (129, 100, 102) + ), + +// 324 3m0007.jpg +((0, 213, 157), (12, 213, 221), (11, 217, 227), (11, 222, 233), + (43, 218, 202), (75, 214, 172), (119, 179, 159), (164, 144, 146), + (213, 142, 62), (212, 129, 64), (212, 116, 66), (167, 93, 95), + (123, 70, 124), (127, 57, 144), (132, 44, 164), (117, 49, 173), + (103, 54, 182), (64, 110, 125), (79, 126, 110), (95, 143, 95), + (97, 129, 83), (99, 116, 71), (103, 110, 93), (107, 105, 116), + (120, 100, 163), (146, 121, 140), (172, 142, 118), (164, 119, 122), + (156, 97, 127), (159, 87, 135), (162, 77, 144), (161, 66, 148), + (159, 75, 153), (134, 94, 165), (101, 105, 181), (69, 116, 198), + (74, 90, 169), (79, 65, 140), (82, 58, 134), (86, 52, 128), + (122, 56, 104), (133, 59, 120), (144, 62, 136), (147, 53, 134), + (150, 44, 132), (164, 28, 123), (178, 12, 114), (178, 7, 99), + (144, 37, 79), (129, 67, 70), (163, 83, 58), (197, 100, 47), + (220, 80, 54), (244, 60, 62), (243, 37, 67), (243, 14, 73), + (240, 37, 100), (227, 52, 88), (214, 67, 77), (168, 63, 81), + (123, 59, 85), (106, 58, 78), (90, 58, 71), (68, 50, 92), + (41, 81, 117), (48, 122, 161), (43, 100, 155), (39, 79, 149), + (35, 61, 156), (32, 44, 164), (43, 24, 168), (34, 12, 175), + (8, 44, 158), (11, 93, 158), (15, 142, 159), (10, 162, 174), + (6, 183, 189), (8, 178, 189), (10, 173, 190), (37, 164, 183), + (55, 115, 203), (43, 88, 155), (68, 75, 133), (94, 62, 112), + (107, 73, 109), (120, 85, 107), (108, 85, 93), (86, 139, 109), + (36, 117, 121), (30, 101, 129), (24, 86, 137), (21, 99, 127), + (18, 113, 117), (0, 108, 125), (3, 126, 131), (46, 128, 116), + (58, 118, 118), (97, 77, 112), (101, 74, 104), (105, 71, 96), + (99, 66, 99), (93, 61, 102), (68, 104, 78), (80, 158, 82), + (50, 142, 91), (35, 114, 101), (20, 86, 112), (15, 76, 118), + (11, 67, 124), (2, 55, 151), (1, 39, 162), (11, 43, 203), + (20, 73, 241), (20, 130, 191), (10, 126, 187), (0, 123, 183), + (5, 117, 180), (3, 113, 176), (2, 88, 165), (4, 52, 162), + (18, 21, 154), (32, 17, 152), (47, 13, 151), (39, 15, 141), + (32, 18, 132), (17, 21, 129), (33, 21, 121), (55, 23, 132), + (50, 2, 112), (71, 46, 103), (73, 47, 99), (75, 49, 96), + (83, 86, 79), (112, 151, 98), (176, 173, 120), (230, 171, 127), + (89, 145, 219), (45, 166, 200), (2, 187, 182), (4, 191, 178), + (6, 195, 175), (40, 207, 127), (56, 186, 80), (60, 214, 80), + (57, 223, 77), (74, 203, 139), (60, 174, 150), (46, 146, 162), + (16, 131, 138), (20, 149, 110), (60, 185, 85), (70, 188, 114), + (32, 184, 111), (23, 167, 105), (14, 150, 100), (34, 95, 100), + (46, 56, 125), (68, 38, 136), (71, 27, 162), (61, 16, 161), + (89, 9, 158), (111, 34, 164), (112, 37, 146), (113, 40, 129), + (101, 29, 129), (106, 6, 164), (95, 7, 179), (90, 49, 187), + (80, 63, 191), (99, 72, 184), (119, 82, 178), (160, 87, 158), + (224, 70, 184), (161, 88, 206), (94, 114, 229), (74, 131, 218), + (33, 157, 217), (13, 169, 191), (25, 192, 174), (91, 163, 160), + (151, 149, 124), (181, 156, 66), (225, 172, 102), (237, 146, 93), + (232, 71, 123), (220, 50, 111), (209, 29, 100), (178, 11, 117), + (144, 20, 230), (106, 27, 233), (23, 48, 236), (15, 115, 191), + (24, 115, 188), (20, 77, 164), (14, 52, 149), (5, 37, 140), + (1, 33, 120), (19, 37, 121), (22, 32, 129), (17, 64, 142), + (49, 48, 128), (64, 34, 132), (59, 23, 131), (58, 40, 148), + (28, 71, 139), (27, 85, 135), (31, 124, 106), (49, 117, 102), + (64, 84, 83), (62, 45, 99), (12, 47, 79), (5, 68, 85), + (12, 91, 124), (3, 117, 143), (2, 120, 170), (3, 121, 171), + (7, 139, 188), (7, 168, 188), (9, 163, 189), (2, 129, 174), + (3, 117, 171), (7, 107, 166), (13, 55, 165), (47, 42, 162), + (68, 38, 160), (73, 41, 168), (87, 24, 155), (95, 36, 128), + (125, 25, 124), (139, 12, 103), (130, 55, 94), (111, 36, 119), + (69, 52, 144), (17, 89, 165), (3, 116, 172), (12, 117, 146), + (14, 118, 129), (8, 76, 125), (0, 70, 129), (28, 38, 100), + (54, 33, 110), (89, 33, 124), (93, 4, 120), (97, 23, 100), + (89, 7, 73), (91, 33, 74), (118, 45, 90), (124, 82, 104), + (163, 120, 176), (171, 152, 207), (165, 187, 226), (166, 160, 222), + (188, 145, 201), (173, 106, 186), (136, 99, 140), (162, 82, 153) + ), + +// 325 3m0008.jpg +((206, 79, 156), (193, 35, 122), (190, 27, 122), (188, 19, 122), + (156, 15, 113), (125, 12, 104), (132, 33, 92), (140, 54, 81), + (163, 151, 153), (126, 176, 154), (89, 201, 155), (88, 194, 181), + (88, 187, 208), (97, 184, 196), (107, 181, 184), (115, 186, 187), + (124, 192, 191), (172, 178, 132), (193, 136, 99), (215, 94, 67), + (167, 93, 44), (120, 93, 22), (131, 80, 15), (143, 67, 9), + (137, 3, 2), (129, 22, 7), (121, 42, 12), (117, 51, 14), + (113, 60, 16), (99, 52, 20), (86, 45, 25), (39, 6, 13), + (26, 29, 44), (50, 74, 38), (68, 74, 36), (87, 75, 35), + (84, 102, 27), (82, 130, 20), (79, 135, 40), (76, 141, 61), + (41, 134, 79), (41, 128, 70), (41, 123, 61), (29, 88, 35), + (17, 54, 10), (12, 49, 10), (7, 44, 10), (24, 41, 22), + (30, 38, 15), (115, 19, 5), (91, 10, 7), (67, 2, 10), + (45, 6, 6), (24, 11, 3), (14, 6, 13), (4, 2, 23), + (13, 35, 93), (44, 32, 101), (76, 29, 109), (70, 65, 96), + (64, 101, 84), (71, 99, 64), (78, 98, 45), (48, 151, 59), + (26, 119, 39), (14, 126, 14), (29, 113, 11), (45, 100, 9), + (58, 96, 9), (71, 93, 10), (100, 57, 50), (134, 68, 54), + (160, 73, 46), (153, 56, 36), (147, 39, 27), (128, 32, 21), + (110, 26, 15), (122, 44, 25), (134, 63, 35), (139, 54, 77), + (129, 89, 98), (119, 180, 123), (140, 190, 128), (162, 201, 134), + (173, 198, 130), (184, 195, 126), (183, 194, 98), (146, 184, 73), + (109, 127, 85), (75, 127, 82), (41, 127, 80), (24, 121, 90), + (8, 116, 101), (16, 145, 127), (21, 150, 145), (27, 124, 175), + (67, 60, 137), (79, 14, 144), (103, 27, 144), (127, 40, 144), + (144, 30, 136), (161, 21, 128), (171, 28, 133), (222, 68, 138), + (222, 92, 156), (164, 107, 97), (107, 122, 39), (69, 126, 35), + (32, 130, 31), (19, 118, 38), (12, 126, 77), (19, 147, 99), + (29, 158, 154), (61, 208, 215), (66, 200, 196), (72, 193, 178), + (61, 161, 151), (36, 181, 80), (38, 169, 55), (72, 151, 8), + (64, 106, 6), (70, 81, 14), (77, 57, 22), (64, 52, 16), + (51, 47, 10), (37, 52, 9), (2, 108, 20), (2, 129, 40), + (1, 159, 66), (30, 107, 73), (39, 98, 83), (48, 89, 93), + (77, 56, 121), (85, 35, 120), (103, 30, 122), (112, 42, 112), + (130, 50, 101), (103, 52, 82), (76, 55, 64), (78, 60, 78), + (80, 66, 92), (87, 38, 119), (92, 58, 153), (143, 64, 171), + (185, 58, 145), (204, 102, 165), (199, 111, 169), (194, 121, 174), + (178, 88, 176), (139, 52, 156), (91, 26, 92), (30, 9, 52), + (8, 27, 5), (7, 22, 13), (7, 18, 22), (28, 24, 39), + (72, 44, 41), (93, 41, 30), (116, 22, 36), (110, 7, 36), + (115, 13, 52), (161, 33, 81), (160, 29, 89), (160, 26, 97), + (158, 32, 96), (167, 67, 119), (176, 94, 166), (144, 106, 189), + (116, 169, 149), (101, 165, 136), (87, 161, 124), (61, 117, 104), + (35, 74, 107), (20, 16, 101), (39, 6, 110), (74, 17, 124), + (61, 49, 123), (70, 93, 137), (75, 111, 143), (89, 156, 182), + (104, 180, 180), (77, 176, 171), (78, 158, 169), (62, 157, 151), + (17, 108, 93), (32, 102, 88), (48, 96, 84), (46, 94, 98), + (78, 100, 123), (97, 157, 158), (121, 188, 170), (188, 204, 193), + (145, 160, 179), (111, 96, 137), (121, 50, 108), (114, 30, 82), + (119, 10, 91), (96, 9, 78), (87, 3, 78), (74, 37, 55), + (55, 33, 46), (54, 40, 57), (26, 56, 66), (46, 7, 100), + (77, 25, 100), (78, 8, 97), (81, 4, 100), (95, 11, 109), + (83, 30, 102), (72, 51, 108), (85, 70, 99), (93, 113, 88), + (108, 184, 138), (64, 206, 156), (65, 216, 227), (80, 202, 205), + (124, 196, 195), (160, 165, 197), (166, 155, 198), (154, 125, 209), + (160, 78, 189), (177, 52, 190), (155, 38, 152), (151, 59, 110), + (118, 96, 59), (108, 75, 70), (67, 69, 55), (78, 39, 44), + (81, 34, 42), (68, 25, 44), (96, 6, 32), (102, 19, 37), + (105, 46, 38), (106, 59, 31), (107, 85, 44), (111, 107, 43), + (121, 122, 54), (110, 89, 68), (92, 79, 109), (33, 60, 113), + (5, 54, 130), (4, 30, 117), (52, 46, 110), (88, 78, 165), + (115, 87, 171), (115, 161, 184), (134, 145, 209), (116, 121, 221), + (95, 95, 217), (116, 97, 204), (167, 131, 169), (179, 131, 111), + (204, 192, 82), (197, 158, 81), (177, 120, 67), (97, 93, 20) + ), + +// 326 3m0009.jpg +((82, 69, 25), (111, 9, 33), (88, 15, 53), (65, 21, 74), + (53, 39, 81), (42, 57, 88), (38, 67, 109), (35, 78, 131), + (111, 196, 163), (125, 204, 162), (139, 213, 162), (148, 205, 162), + (158, 198, 163), (117, 165, 137), (77, 132, 111), (60, 119, 113), + (43, 106, 115), (5, 76, 166), (4, 80, 149), (4, 85, 132), + (33, 78, 118), (62, 71, 104), (76, 59, 89), (90, 47, 75), + (124, 20, 31), (102, 12, 29), (80, 5, 28), (53, 3, 16), + (27, 2, 5), (19, 4, 4), (11, 7, 4), (1, 5, 4), + (4, 16, 2), (10, 17, 9), (7, 22, 5), (4, 27, 1), + (7, 31, 3), (10, 35, 6), (9, 34, 8), (8, 33, 11), + (49, 41, 30), (72, 44, 18), (96, 47, 6), (106, 58, 21), + (116, 70, 37), (125, 69, 44), (135, 68, 52), (144, 122, 72), + (163, 218, 101), (148, 221, 142), (127, 178, 119), (107, 135, 97), + (83, 132, 78), (60, 130, 60), (57, 126, 68), (55, 123, 76), + (9, 128, 136), (7, 153, 172), (6, 179, 209), (11, 179, 210), + (17, 180, 211), (18, 177, 210), (20, 174, 210), (22, 156, 191), + (15, 114, 146), (3, 54, 146), (6, 47, 129), (10, 40, 112), + (7, 37, 91), (4, 34, 70), (22, 38, 25), (24, 52, 29), + (13, 132, 50), (38, 156, 104), (64, 180, 159), (40, 176, 155), + (16, 173, 152), (12, 152, 139), (9, 132, 127), (24, 110, 75), + (26, 109, 41), (40, 87, 15), (26, 77, 12), (12, 67, 10), + (12, 55, 8), (12, 44, 7), (17, 27, 19), (31, 28, 49), + (72, 115, 85), (111, 145, 111), (151, 176, 137), (159, 175, 140), + (167, 174, 143), (186, 168, 166), (177, 199, 161), (178, 220, 144), + (150, 185, 117), (67, 114, 104), (39, 97, 100), (12, 81, 96), + (16, 55, 102), (20, 29, 108), (15, 23, 98), (20, 25, 93), + (19, 27, 64), (36, 42, 62), (53, 58, 61), (52, 56, 56), + (52, 54, 51), (38, 28, 39), (65, 39, 42), (89, 36, 44), + (146, 30, 31), (190, 38, 15), (187, 36, 10), (185, 34, 5), + (150, 41, 8), (107, 13, 5), (56, 24, 1), (48, 19, 5), + (53, 7, 35), (39, 39, 48), (25, 71, 61), (40, 103, 62), + (56, 136, 63), (60, 159, 102), (38, 156, 130), (34, 143, 146), + (30, 129, 160), (8, 137, 143), (7, 130, 140), (7, 123, 138), + (4, 94, 120), (5, 104, 99), (30, 73, 79), (16, 69, 59), + (6, 45, 18), (13, 31, 15), (20, 17, 12), (22, 23, 9), + (24, 29, 7), (18, 31, 1), (8, 47, 0), (9, 36, 1), + (25, 29, 6), (46, 26, 0), (45, 24, 1), (44, 23, 2), + (23, 20, 13), (22, 27, 23), (33, 28, 32), (48, 15, 36), + (24, 2, 25), (30, 10, 19), (37, 18, 14), (50, 3, 9), + (58, 2, 3), (64, 14, 3), (65, 4, 12), (120, 6, 6), + (131, 24, 14), (84, 29, 24), (70, 23, 34), (56, 17, 44), + (46, 7, 60), (31, 11, 46), (15, 17, 40), (19, 23, 24), + (31, 1, 27), (40, 0, 29), (49, 0, 32), (44, 17, 34), + (54, 13, 29), (59, 15, 28), (71, 18, 48), (108, 16, 39), + (143, 33, 42), (141, 22, 18), (149, 30, 8), (136, 25, 16), + (106, 17, 11), (61, 24, 6), (56, 25, 5), (73, 31, 17), + (42, 40, 28), (37, 59, 23), (33, 78, 19), (28, 100, 60), + (78, 122, 86), (94, 119, 87), (117, 110, 56), (137, 58, 27), + (163, 29, 4), (185, 22, 23), (158, 15, 43), (135, 13, 50), + (91, 21, 83), (110, 53, 122), (156, 99, 140), (111, 103, 127), + (52, 82, 120), (32, 74, 114), (16, 28, 128), (20, 12, 131), + (14, 19, 123), (30, 16, 93), (16, 15, 47), (17, 19, 18), + (15, 26, 18), (12, 36, 14), (24, 39, 10), (38, 35, 16), + (79, 48, 27), (77, 108, 28), (109, 142, 11), (162, 103, 9), + (176, 80, 19), (139, 94, 97), (156, 125, 156), (172, 171, 187), + (145, 195, 184), (146, 187, 179), (135, 162, 145), (97, 149, 160), + (70, 134, 118), (26, 114, 118), (17, 107, 131), (34, 105, 135), + (25, 130, 136), (12, 132, 157), (7, 147, 206), (15, 155, 208), + (25, 148, 189), (13, 114, 144), (2, 91, 125), (14, 38, 100), + (7, 31, 77), (13, 22, 39), (21, 14, 48), (12, 9, 56), + (10, 6, 65), (1, 20, 99), (7, 11, 134), (16, 9, 139), + (5, 15, 112), (0, 7, 61), (5, 16, 48), (0, 8, 29), + (2, 9, 27), (9, 4, 34), (6, 18, 76), (4, 15, 81), + (15, 30, 87), (29, 16, 69), (39, 10, 2), (33, 13, 50) + ), + +// 327 3m0010.jpg +((244, 135, 96), (221, 130, 112), (231, 142, 128), (242, 155, 145), + (222, 157, 143), (202, 159, 142), (183, 162, 123), (164, 165, 105), + (54, 110, 39), (54, 85, 32), (55, 61, 25), (72, 63, 21), + (89, 65, 17), (77, 52, 13), (66, 39, 10), (55, 39, 16), + (45, 39, 23), (4, 82, 22), (12, 92, 34), (21, 102, 46), + (43, 100, 29), (65, 99, 13), (77, 101, 18), (90, 103, 23), + (104, 104, 14), (117, 89, 25), (130, 75, 36), (145, 94, 34), + (161, 114, 32), (162, 120, 34), (164, 127, 36), (188, 150, 67), + (217, 150, 63), (229, 189, 120), (203, 166, 118), (178, 144, 116), + (126, 113, 120), (74, 83, 124), (70, 56, 115), (66, 29, 107), + (49, 28, 87), (50, 55, 93), (51, 82, 100), (43, 83, 93), + (35, 85, 86), (33, 64, 71), (32, 44, 56), (34, 35, 55), + (31, 40, 35), (111, 103, 20), (140, 137, 45), (169, 171, 70), + (184, 190, 83), (200, 210, 97), (224, 194, 103), (248, 179, 110), + (191, 144, 152), (177, 164, 120), (164, 184, 89), (163, 195, 77), + (162, 207, 65), (154, 188, 64), (146, 169, 63), (170, 147, 41), + (172, 132, 63), (165, 131, 60), (144, 94, 52), (123, 57, 45), + (116, 51, 58), (109, 45, 71), (113, 29, 42), (117, 42, 37), + (127, 30, 47), (110, 28, 51), (93, 27, 55), (69, 27, 35), + (45, 27, 15), (44, 20, 9), (44, 14, 4), (27, 8, 4), + (22, 23, 5), (5, 15, 77), (16, 13, 82), (28, 12, 87), + (28, 11, 90), (29, 11, 93), (43, 2, 81), (62, 19, 73), + (106, 48, 60), (133, 41, 35), (160, 34, 11), (154, 41, 6), + (149, 48, 2), (146, 58, 18), (115, 72, 21), (101, 92, 15), + (101, 94, 16), (47, 82, 26), (24, 96, 71), (1, 110, 117), + (10, 94, 103), (19, 79, 89), (19, 28, 87), (29, 14, 83), + (75, 64, 81), (98, 99, 67), (121, 134, 54), (129, 116, 44), + (138, 99, 34), (131, 76, 19), (130, 66, 28), (126, 73, 19), + (119, 58, 4), (113, 60, 26), (109, 55, 26), (106, 50, 27), + (97, 50, 34), (100, 55, 16), (98, 40, 18), (115, 40, 17), + (141, 25, 10), (131, 32, 9), (122, 39, 9), (113, 53, 4), + (104, 67, 0), (112, 96, 9), (107, 119, 9), (139, 146, 17), + (142, 127, 24), (177, 160, 28), (179, 170, 49), (182, 180, 71), + (212, 205, 62), (225, 207, 99), (223, 223, 135), (195, 219, 123), + (186, 245, 75), (141, 226, 60), (96, 208, 46), (93, 198, 36), + (91, 189, 26), (67, 149, 127), (51, 150, 129), (18, 100, 158), + (37, 119, 169), (67, 168, 154), (82, 165, 169), (97, 162, 184), + (97, 105, 142), (164, 77, 96), (148, 43, 58), (139, 34, 38), + (149, 26, 54), (170, 39, 81), (191, 52, 109), (187, 80, 108), + (157, 100, 71), (145, 96, 79), (143, 96, 80), (108, 71, 89), + (81, 36, 77), (58, 32, 61), (51, 32, 54), (44, 33, 47), + (42, 24, 50), (36, 18, 42), (42, 19, 37), (46, 26, 37), + (87, 18, 37), (91, 12, 31), (96, 7, 25), (91, 2, 20), + (98, 14, 12), (83, 4, 0), (76, 12, 2), (78, 15, 8), + (75, 27, 5), (95, 28, 9), (110, 30, 23), (119, 32, 22), + (125, 43, 22), (125, 53, 31), (134, 66, 29), (149, 75, 12), + (110, 91, 15), (97, 83, 15), (85, 75, 16), (97, 54, 38), + (103, 32, 36), (119, 26, 21), (135, 19, 22), (152, 5, 47), + (155, 2, 46), (129, 4, 22), (102, 20, 9), (59, 38, 11), + (35, 29, 15), (18, 41, 13), (0, 53, 7), (22, 28, 18), + (17, 10, 44), (2, 15, 50), (6, 4, 53), (45, 4, 62), + (86, 1, 58), (115, 13, 60), (113, 4, 46), (89, 5, 28), + (82, 6, 18), (61, 4, 11), (35, 5, 29), (41, 2, 47), + (43, 13, 67), (54, 23, 83), (87, 18, 101), (97, 32, 100), + (142, 83, 77), (158, 117, 71), (167, 140, 97), (185, 124, 95), + (169, 96, 113), (180, 65, 156), (113, 90, 181), (99, 199, 225), + (108, 212, 221), (86, 196, 147), (61, 149, 125), (28, 140, 115), + (30, 83, 101), (11, 21, 72), (26, 21, 88), (6, 30, 126), + (35, 72, 127), (15, 109, 119), (18, 124, 112), (15, 118, 62), + (55, 72, 54), (58, 51, 32), (84, 32, 36), (83, 27, 10), + (86, 32, 4), (96, 42, 8), (93, 71, 14), (96, 109, 27), + (129, 169, 73), (107, 137, 77), (60, 96, 130), (49, 69, 128), + (60, 60, 88), (62, 56, 66), (95, 44, 41), (104, 52, 64), + (111, 53, 78), (142, 60, 72), (161, 27, 122), (132, 46, 107) + ), + +// 328 3m0011.jpg +((31, 61, 35), (8, 36, 40), (8, 47, 43), (9, 59, 47), + (11, 48, 55), (14, 38, 64), (13, 30, 57), (12, 23, 51), + (31, 15, 28), (26, 14, 46), (21, 13, 64), (27, 8, 129), + (33, 3, 195), (46, 8, 179), (59, 13, 164), (50, 11, 135), + (42, 10, 107), (50, 2, 44), (57, 13, 57), (64, 25, 70), + (109, 36, 85), (154, 47, 101), (184, 59, 101), (215, 72, 102), + (196, 147, 176), (164, 152, 168), (133, 157, 161), (145, 182, 147), + (157, 207, 134), (151, 192, 143), (145, 177, 153), (145, 145, 171), + (109, 182, 165), (78, 156, 222), (66, 184, 219), (55, 213, 216), + (62, 217, 223), (69, 222, 230), (87, 213, 237), (106, 205, 244), + (153, 156, 227), (127, 136, 222), (102, 117, 218), (95, 102, 186), + (88, 87, 155), (90, 83, 151), (92, 79, 148), (98, 36, 147), + (95, 33, 132), (104, 42, 125), (81, 47, 117), (58, 53, 109), + (43, 73, 110), (29, 94, 112), (30, 91, 108), (31, 88, 105), + (58, 124, 76), (29, 104, 77), (0, 84, 78), (16, 88, 101), + (32, 93, 124), (61, 89, 134), (91, 85, 145), (129, 120, 173), + (152, 117, 171), (94, 75, 157), (82, 54, 126), (70, 34, 95), + (68, 51, 89), (67, 69, 84), (49, 91, 103), (53, 128, 131), + (71, 121, 220), (71, 111, 174), (72, 102, 128), (57, 68, 106), + (43, 35, 84), (54, 31, 83), (66, 27, 82), (101, 40, 110), + (87, 32, 123), (80, 24, 151), (55, 41, 182), (30, 59, 213), + (34, 67, 204), (39, 75, 195), (66, 97, 164), (69, 122, 156), + (68, 152, 137), (67, 133, 103), (66, 115, 70), (48, 96, 53), + (30, 78, 36), (8, 43, 11), (0, 38, 1), (2, 14, 10), + (5, 27, 15), (47, 31, 6), (58, 73, 33), (69, 116, 61), + (57, 150, 80), (45, 185, 99), (141, 208, 141), (131, 212, 75), + (245, 234, 30), (212, 165, 35), (179, 97, 41), (207, 54, 53), + (235, 12, 66), (198, 56, 104), (143, 41, 78), (67, 24, 52), + (47, 27, 55), (19, 22, 27), (11, 17, 20), (3, 13, 14), + (4, 5, 7), (2, 0, 1), (1, 0, 0), (0, 13, 0), + (20, 34, 35), (41, 49, 49), (62, 64, 63), (77, 92, 79), + (93, 121, 96), (76, 129, 135), (83, 145, 184), (102, 155, 149), + (71, 126, 129), (16, 63, 31), (8, 40, 28), (0, 17, 25), + (0, 13, 17), (0, 5, 5), (0, 2, 1), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 3, 0), (0, 4, 4), (0, 3, 6), + (0, 0, 0), (0, 0, 9), (4, 3, 17), (8, 7, 25), + (27, 16, 50), (31, 33, 72), (28, 13, 98), (8, 24, 86), + (12, 1, 57), (13, 6, 54), (14, 12, 51), (31, 8, 26), + (68, 0, 29), (101, 43, 58), (120, 118, 70), (118, 166, 150), + (140, 221, 152), (112, 208, 220), (95, 173, 224), (79, 138, 228), + (86, 133, 213), (99, 114, 209), (97, 122, 204), (84, 153, 194), + (147, 222, 201), (159, 226, 198), (171, 231, 195), (188, 140, 242), + (189, 106, 198), (216, 97, 241), (240, 66, 223), (217, 22, 220), + (183, 65, 149), (139, 56, 138), (128, 25, 108), (82, 38, 87), + (86, 29, 84), (112, 18, 71), (149, 14, 116), (142, 39, 108), + (97, 32, 184), (100, 34, 194), (103, 37, 205), (168, 38, 174), + (152, 54, 141), (193, 67, 105), (167, 91, 59), (105, 117, 31), + (66, 64, 25), (54, 58, 21), (73, 37, 11), (84, 15, 20), + (61, 3, 25), (47, 28, 13), (34, 73, 18), (53, 111, 53), + (63, 123, 97), (56, 135, 130), (65, 117, 154), (60, 87, 174), + (27, 52, 179), (37, 52, 145), (20, 22, 107), (27, 16, 50), + (18, 10, 21), (2, 3, 7), (1, 0, 5), (8, 0, 3), + (13, 7, 9), (37, 0, 14), (39, 23, 10), (43, 46, 27), + (34, 57, 41), (22, 62, 51), (31, 51, 49), (18, 39, 68), + (0, 39, 78), (12, 40, 105), (29, 14, 109), (61, 18, 110), + (107, 24, 158), (205, 34, 200), (162, 47, 252), (108, 25, 241), + (54, 51, 246), (104, 77, 252), (112, 79, 255), (107, 104, 217), + (88, 110, 255), (79, 103, 239), (74, 127, 219), (72, 141, 172), + (55, 114, 128), (22, 80, 92), (21, 79, 67), (25, 49, 36), + (24, 30, 28), (27, 24, 35), (33, 20, 50), (40, 30, 55), + (66, 23, 50), (125, 27, 66), (129, 31, 69), (66, 49, 85), + (56, 51, 83), (49, 28, 67), (49, 46, 41), (43, 60, 52), + (35, 48, 57), (30, 36, 68), (51, 21, 81), (58, 22, 83) + ), + +// 329 3m0012.jpg +((20, 34, 73), (36, 22, 48), (36, 34, 72), (36, 46, 97), + (59, 53, 131), (82, 61, 166), (62, 56, 186), (42, 51, 206), + (41, 23, 105), (50, 40, 84), (59, 58, 64), (86, 51, 35), + (113, 45, 6), (150, 117, 19), (188, 189, 33), (214, 222, 84), + (240, 255, 136), (253, 220, 139), (243, 182, 110), (233, 145, 82), + (159, 81, 58), (86, 17, 35), (69, 8, 37), (53, 0, 40), + (9, 0, 12), (4, 2, 14), (0, 5, 17), (0, 10, 21), + (0, 16, 25), (1, 19, 21), (2, 23, 18), (7, 6, 11), + (22, 27, 4), (24, 62, 47), (76, 88, 71), (128, 115, 96), + (139, 129, 144), (151, 143, 192), (144, 140, 196), (137, 137, 201), + (91, 12, 241), (78, 24, 176), (65, 37, 111), (57, 18, 79), + (50, 0, 48), (44, 3, 36), (38, 7, 25), (14, 5, 0), + (8, 0, 2), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 1), (0, 0, 2), (5, 0, 6), + (11, 0, 11), (17, 0, 16), (24, 0, 22), (56, 17, 48), + (95, 20, 50), (214, 72, 122), (234, 94, 105), (255, 116, 89), + (238, 107, 95), (221, 98, 101), (189, 42, 96), (144, 16, 93), + (77, 8, 73), (77, 9, 81), (78, 11, 90), (88, 14, 86), + (98, 17, 83), (96, 16, 91), (95, 16, 99), (109, 29, 102), + (145, 27, 87), (133, 51, 113), (161, 57, 139), (189, 64, 166), + (205, 65, 196), (222, 66, 227), (189, 116, 250), (174, 165, 218), + (239, 131, 146), (201, 108, 114), (164, 86, 82), (124, 51, 59), + (84, 16, 37), (51, 4, 12), (37, 18, 11), (20, 0, 0), + (35, 0, 15), (57, 4, 46), (68, 2, 56), (79, 0, 66), + (66, 2, 71), (54, 4, 77), (64, 40, 92), (59, 72, 127), + (74, 180, 230), (115, 170, 230), (156, 160, 231), (159, 163, 224), + (163, 166, 217), (174, 124, 127), (164, 59, 162), (168, 47, 153), + (179, 30, 158), (135, 7, 128), (130, 19, 138), (125, 32, 149), + (111, 42, 159), (122, 87, 181), (125, 90, 144), (95, 36, 94), + (48, 9, 56), (38, 20, 45), (28, 32, 35), (32, 33, 36), + (36, 34, 37), (44, 53, 60), (80, 46, 71), (146, 81, 63), + (189, 129, 57), (175, 201, 42), (159, 202, 36), (144, 204, 31), + (117, 162, 103), (79, 143, 106), (83, 113, 167), (42, 110, 149), + (20, 23, 120), (21, 16, 94), (23, 9, 68), (21, 6, 49), + (20, 4, 31), (14, 2, 14), (7, 0, 0), (1, 0, 0), + (0, 0, 0), (0, 0, 2), (0, 0, 3), (0, 1, 4), + (1, 12, 14), (12, 27, 8), (19, 23, 9), (23, 20, 3), + (48, 55, 13), (63, 67, 7), (78, 79, 1), (82, 82, 22), + (114, 81, 10), (116, 99, 9), (94, 125, 22), (62, 105, 59), + (53, 82, 51), (64, 57, 73), (62, 75, 76), (60, 94, 80), + (87, 119, 104), (91, 162, 104), (86, 215, 71), (180, 202, 104), + (205, 249, 38), (198, 227, 34), (192, 205, 30), (202, 160, 78), + (228, 166, 129), (239, 205, 157), (252, 192, 228), (236, 190, 218), + (240, 172, 133), (255, 153, 70), (239, 84, 30), (192, 36, 57), + (102, 9, 54), (84, 46, 83), (64, 44, 93), (66, 56, 90), + (67, 54, 84), (99, 59, 83), (131, 64, 82), (138, 92, 120), + (105, 150, 171), (30, 189, 185), (23, 199, 248), (2, 146, 232), + (40, 78, 161), (96, 43, 149), (115, 38, 150), (146, 30, 157), + (147, 6, 144), (159, 1, 120), (169, 48, 119), (178, 58, 147), + (233, 42, 155), (219, 24, 162), (223, 13, 148), (215, 15, 163), + (205, 6, 157), (171, 5, 147), (93, 41, 126), (64, 75, 105), + (22, 57, 121), (23, 97, 96), (48, 66, 66), (29, 36, 46), + (15, 39, 85), (23, 28, 94), (60, 0, 81), (112, 24, 108), + (146, 34, 170), (173, 38, 254), (210, 2, 244), (227, 32, 250), + (242, 2, 211), (219, 13, 95), (203, 36, 79), (132, 23, 64), + (87, 20, 71), (76, 7, 62), (63, 4, 68), (51, 2, 67), + (42, 0, 46), (31, 4, 37), (15, 20, 24), (4, 21, 31), + (11, 16, 54), (27, 3, 87), (29, 20, 83), (47, 20, 87), + (84, 28, 91), (98, 34, 131), (129, 51, 197), (148, 59, 185), + (152, 68, 179), (164, 39, 193), (148, 21, 226), (203, 72, 238), + (162, 157, 224), (88, 198, 171), (90, 190, 164), (72, 226, 116), + (118, 157, 32), (130, 122, 21), (97, 105, 6), (59, 61, 0), + (56, 44, 28), (99, 20, 49), (178, 40, 76), (201, 76, 80) + ), + +// 330 3m0013.jpg +((10, 81, 49), (57, 81, 93), (41, 119, 130), (25, 158, 167), + (21, 189, 175), (17, 221, 184), (42, 214, 175), (68, 207, 166), + (91, 142, 161), (92, 136, 158), (93, 130, 156), (93, 122, 135), + (94, 114, 115), (90, 105, 101), (86, 96, 88), (82, 74, 73), + (78, 53, 59), (177, 61, 12), (158, 48, 13), (140, 35, 14), + (108, 26, 8), (76, 17, 3), (60, 15, 6), (45, 14, 9), + (5, 28, 36), (10, 59, 50), (16, 90, 65), (13, 111, 93), + (10, 132, 121), (24, 130, 127), (39, 128, 134), (33, 126, 118), + (16, 104, 82), (0, 69, 71), (16, 57, 86), (33, 46, 101), + (40, 60, 116), (48, 74, 131), (36, 85, 102), (24, 96, 74), + (7, 105, 66), (11, 100, 53), (15, 96, 40), (11, 61, 21), + (8, 26, 2), (4, 21, 1), (0, 16, 0), (14, 12, 0), + (25, 29, 14), (44, 79, 13), (48, 131, 19), (53, 184, 26), + (40, 149, 30), (27, 114, 35), (24, 87, 37), (21, 60, 39), + (21, 49, 34), (30, 48, 42), (40, 48, 51), (55, 59, 68), + (71, 70, 86), (79, 78, 93), (88, 86, 100), (79, 68, 74), + (71, 69, 30), (70, 31, 16), (95, 43, 15), (120, 55, 15), + (129, 69, 10), (139, 83, 6), (144, 104, 16), (186, 85, 31), + (143, 29, 19), (88, 25, 21), (34, 22, 24), (22, 15, 14), + (10, 9, 4), (11, 8, 2), (13, 7, 0), (16, 11, 0), + (21, 6, 1), (24, 15, 20), (28, 22, 21), (33, 30, 23), + (40, 44, 23), (47, 58, 24), (65, 75, 22), (109, 89, 38), + (130, 124, 10), (108, 133, 8), (86, 142, 7), (76, 143, 5), + (67, 144, 4), (72, 87, 2), (37, 64, 11), (39, 35, 0), + (49, 15, 5), (27, 13, 4), (23, 23, 2), (20, 34, 0), + (17, 33, 0), (15, 32, 0), (11, 54, 0), (16, 54, 5), + (38, 50, 10), (83, 70, 17), (129, 90, 25), (152, 117, 29), + (176, 144, 33), (190, 208, 10), (172, 205, 14), (126, 227, 35), + (77, 168, 28), (68, 109, 43), (50, 98, 25), (33, 88, 7), + (21, 127, 5), (19, 163, 3), (20, 155, 3), (11, 114, 7), + (16, 65, 10), (24, 59, 10), (33, 54, 11), (43, 50, 12), + (53, 47, 13), (88, 72, 12), (109, 122, 52), (126, 141, 36), + (121, 130, 47), (111, 85, 98), (98, 67, 108), (86, 49, 118), + (93, 59, 145), (79, 52, 145), (42, 50, 99), (19, 49, 75), + (14, 51, 44), (21, 59, 37), (29, 67, 30), (33, 62, 30), + (37, 57, 30), (32, 56, 40), (26, 58, 43), (3, 63, 53), + (18, 84, 57), (61, 123, 48), (94, 174, 43), (127, 226, 39), + (176, 200, 24), (197, 204, 13), (202, 167, 13), (189, 144, 29), + (195, 78, 35), (184, 51, 44), (173, 24, 53), (163, 9, 61), + (158, 27, 41), (129, 21, 37), (77, 49, 9), (58, 23, 29), + (63, 10, 54), (55, 27, 75), (53, 26, 67), (51, 25, 60), + (50, 11, 30), (69, 14, 11), (76, 6, 8), (77, 15, 0), + (79, 44, 14), (71, 60, 19), (63, 77, 24), (38, 78, 25), + (17, 102, 63), (14, 129, 62), (9, 189, 22), (44, 204, 36), + (46, 163, 30), (11, 122, 54), (24, 86, 47), (43, 58, 63), + (43, 45, 57), (51, 28, 74), (50, 35, 92), (69, 31, 82), + (59, 8, 67), (49, 5, 52), (40, 3, 37), (53, 8, 28), + (49, 14, 20), (56, 29, 36), (38, 25, 42), (38, 10, 58), + (32, 16, 79), (22, 44, 65), (26, 46, 47), (4, 22, 26), + (10, 20, 29), (33, 17, 28), (38, 7, 15), (50, 1, 7), + (53, 2, 0), (68, 15, 7), (62, 12, 13), (50, 16, 14), + (35, 41, 39), (43, 47, 30), (49, 47, 22), (44, 53, 24), + (35, 52, 42), (81, 43, 84), (111, 5, 80), (144, 17, 36), + (172, 77, 33), (181, 123, 0), (136, 195, 17), (124, 188, 32), + (103, 110, 103), (100, 92, 152), (85, 93, 165), (80, 123, 166), + (59, 118, 196), (47, 98, 151), (41, 125, 127), (29, 127, 86), + (19, 119, 57), (21, 125, 76), (39, 117, 101), (53, 123, 113), + (36, 145, 104), (42, 133, 89), (17, 108, 67), (15, 90, 67), + (13, 75, 70), (29, 60, 81), (37, 58, 75), (36, 64, 76), + (22, 85, 68), (9, 104, 72), (9, 99, 87), (0, 108, 108), + (5, 123, 101), (0, 165, 143), (1, 172, 156), (5, 181, 161), + (18, 197, 168), (29, 143, 179), (66, 179, 195), (60, 199, 160), + (56, 191, 151), (41, 171, 127), (85, 119, 103), (148, 121, 44), + (158, 117, 12), (144, 139, 45), (46, 121, 18), (108, 150, 22) + ), + +// 331 3m0014.jpg +((181, 71, 12), (111, 62, 58), (113, 78, 41), (115, 95, 24), + (157, 88, 22), (200, 82, 20), (209, 74, 22), (218, 67, 24), + (208, 66, 44), (162, 57, 53), (117, 49, 62), (80, 28, 55), + (44, 7, 48), (31, 6, 43), (19, 5, 38), (14, 7, 22), + (9, 9, 7), (22, 6, 7), (35, 7, 10), (48, 9, 14), + (26, 14, 17), (4, 20, 20), (5, 22, 23), (7, 25, 27), + (32, 19, 26), (33, 26, 50), (34, 33, 75), (37, 60, 94), + (41, 88, 114), (38, 93, 114), (35, 98, 115), (22, 99, 117), + (20, 116, 128), (38, 123, 130), (45, 116, 112), (52, 110, 95), + (39, 101, 100), (27, 93, 105), (16, 77, 97), (5, 62, 89), + (23, 95, 109), (33, 127, 104), (44, 159, 100), (57, 186, 104), + (70, 213, 108), (71, 205, 102), (72, 197, 97), (111, 177, 87), + (136, 154, 78), (127, 101, 52), (109, 85, 60), (91, 70, 69), + (88, 58, 63), (85, 47, 58), (89, 49, 59), (94, 51, 61), + (192, 70, 47), (187, 78, 58), (182, 87, 69), (141, 76, 70), + (100, 65, 72), (90, 54, 66), (81, 44, 61), (71, 26, 47), + (89, 18, 24), (91, 13, 11), (79, 22, 16), (68, 31, 22), + (58, 33, 20), (49, 36, 19), (55, 57, 43), (47, 36, 40), + (21, 38, 19), (22, 51, 21), (24, 65, 23), (48, 49, 35), + (72, 34, 47), (84, 38, 39), (96, 42, 32), (148, 10, 25), + (153, 3, 15), (95, 23, 24), (91, 40, 35), (87, 57, 46), + (102, 57, 52), (118, 58, 58), (139, 60, 55), (151, 44, 28), + (184, 24, 26), (173, 35, 27), (163, 46, 28), (156, 79, 35), + (150, 113, 42), (137, 133, 42), (84, 138, 42), (40, 112, 46), + (2, 93, 13), (128, 62, 2), (163, 34, 3), (199, 7, 4), + (200, 3, 2), (202, 0, 0), (164, 20, 9), (109, 20, 4), + (30, 7, 1), (42, 6, 11), (54, 6, 22), (61, 5, 20), + (68, 4, 18), (59, 13, 16), (54, 11, 20), (64, 24, 24), + (53, 27, 26), (33, 29, 4), (20, 27, 5), (7, 26, 7), + (22, 40, 14), (13, 43, 19), (4, 59, 1), (1, 83, 11), + (35, 52, 68), (39, 65, 62), (43, 78, 56), (48, 68, 61), + (54, 58, 67), (54, 50, 73), (40, 39, 70), (28, 37, 46), + (47, 15, 38), (76, 20, 29), (85, 13, 41), (94, 6, 54), + (120, 16, 27), (130, 6, 8), (172, 5, 13), (172, 20, 9), + (183, 24, 5), (167, 31, 17), (151, 38, 30), (145, 34, 27), + (139, 30, 25), (86, 63, 31), (58, 89, 48), (55, 96, 56), + (50, 85, 65), (84, 137, 59), (82, 143, 57), (80, 149, 56), + (103, 133, 43), (111, 95, 69), (89, 99, 26), (84, 94, 21), + (68, 53, 30), (74, 59, 29), (81, 65, 29), (91, 65, 50), + (127, 91, 41), (160, 91, 24), (185, 79, 17), (191, 75, 18), + (180, 52, 3), (187, 55, 34), (195, 58, 37), (204, 62, 40), + (194, 25, 18), (203, 15, 6), (212, 53, 14), (210, 83, 38), + (236, 145, 62), (202, 147, 76), (168, 149, 90), (130, 159, 131), + (106, 138, 89), (98, 108, 109), (97, 96, 94), (124, 102, 78), + (146, 133, 78), (145, 153, 80), (150, 161, 83), (122, 185, 71), + (100, 200, 86), (50, 165, 87), (19, 185, 85), (15, 155, 68), + (43, 138, 44), (39, 138, 62), (35, 139, 80), (76, 170, 84), + (114, 176, 75), (145, 183, 74), (180, 186, 114), (179, 202, 150), + (141, 201, 173), (150, 230, 131), (137, 179, 93), (126, 157, 64), + (122, 135, 47), (80, 101, 84), (74, 101, 86), (57, 63, 99), + (64, 50, 75), (60, 39, 58), (91, 25, 61), (98, 12, 57), + (105, 35, 59), (123, 48, 27), (127, 60, 43), (85, 68, 74), + (76, 80, 91), (69, 94, 91), (94, 73, 54), (133, 94, 37), + (172, 76, 16), (209, 83, 25), (205, 114, 44), (229, 148, 59), + (190, 148, 76), (188, 149, 94), (194, 162, 85), (205, 178, 99), + (214, 179, 97), (214, 193, 84), (219, 214, 94), (240, 218, 107), + (216, 208, 99), (197, 184, 105), (183, 186, 97), (173, 196, 80), + (167, 189, 78), (154, 154, 66), (122, 144, 46), (85, 150, 60), + (62, 176, 89), (42, 173, 107), (13, 133, 106), (7, 135, 48), + (10, 109, 18), (46, 111, 17), (123, 134, 30), (160, 152, 67), + (175, 175, 89), (204, 229, 99), (202, 233, 95), (165, 213, 103), + (155, 205, 74), (147, 164, 62), (109, 141, 68), (54, 131, 95), + (61, 143, 105), (79, 134, 129), (57, 176, 118), (89, 166, 130), + (147, 197, 124), (191, 190, 110), (188, 173, 166), (184, 169, 126) + ), + +// 332 3m0015.jpg +((95, 98, 19), (96, 92, 63), (100, 100, 73), (105, 109, 84), + (86, 130, 86), (67, 151, 89), (73, 131, 95), (79, 112, 101), + (85, 68, 60), (108, 69, 56), (132, 71, 53), (166, 103, 68), + (201, 135, 83), (201, 124, 87), (202, 114, 92), (195, 122, 109), + (189, 130, 126), (192, 91, 81), (161, 87, 70), (130, 84, 60), + (116, 82, 52), (103, 81, 44), (98, 92, 42), (94, 104, 41), + (98, 135, 83), (104, 144, 94), (110, 154, 105), (101, 129, 104), + (93, 105, 103), (96, 101, 100), (99, 97, 98), (113, 113, 77), + (111, 88, 46), (134, 88, 28), (136, 94, 50), (138, 101, 72), + (127, 125, 92), (116, 150, 113), (129, 153, 113), (142, 157, 114), + (203, 177, 120), (168, 139, 135), (133, 101, 150), (121, 82, 108), + (109, 63, 66), (106, 57, 55), (104, 51, 45), (115, 36, 41), + (114, 25, 47), (52, 14, 5), (47, 15, 15), (43, 16, 25), + (43, 12, 33), (43, 8, 41), (60, 12, 35), (77, 17, 29), + (117, 14, 57), (116, 24, 57), (116, 34, 57), (99, 63, 62), + (82, 92, 68), (75, 92, 81), (68, 92, 94), (63, 105, 85), + (43, 86, 69), (23, 79, 32), (26, 58, 28), (30, 38, 25), + (30, 29, 28), (30, 20, 31), (32, 5, 48), (26, 9, 53), + (18, 8, 32), (43, 26, 37), (68, 44, 42), (54, 49, 52), + (41, 54, 63), (35, 51, 58), (30, 49, 53), (15, 37, 51), + (18, 34, 49), (29, 38, 37), (32, 50, 51), (35, 63, 66), + (32, 67, 77), (30, 72, 88), (50, 84, 112), (38, 111, 102), + (69, 118, 114), (65, 104, 102), (61, 91, 91), (67, 82, 80), + (73, 74, 69), (73, 68, 62), (97, 72, 52), (93, 35, 47), + (99, 14, 55), (104, 39, 71), (111, 30, 68), (119, 22, 65), + (114, 20, 72), (109, 18, 79), (93, 16, 60), (72, 27, 56), + (107, 51, 138), (106, 31, 122), (105, 11, 107), (117, 15, 84), + (129, 20, 61), (130, 13, 29), (116, 23, 18), (128, 33, 1), + (108, 45, 30), (78, 12, 22), (69, 13, 25), (61, 15, 28), + (43, 30, 22), (26, 34, 10), (19, 45, 6), (0, 71, 14), + (14, 150, 128), (38, 145, 141), (63, 141, 154), (49, 153, 131), + (36, 165, 109), (5, 155, 68), (22, 124, 51), (52, 104, 38), + (76, 76, 50), (153, 95, 143), (162, 103, 154), (171, 111, 165), + (187, 147, 174), (203, 94, 185), (192, 44, 140), (144, 37, 109), + (198, 20, 78), (171, 17, 48), (145, 14, 19), (142, 25, 28), + (139, 36, 37), (144, 41, 24), (151, 53, 14), (115, 68, 24), + (83, 78, 22), (46, 115, 22), (31, 121, 30), (17, 127, 38), + (33, 139, 65), (44, 128, 94), (73, 156, 128), (19, 221, 173), + (117, 198, 215), (132, 187, 215), (148, 176, 215), (207, 159, 209), + (223, 147, 212), (252, 205, 175), (242, 173, 144), (201, 195, 135), + (191, 196, 138), (202, 156, 158), (194, 161, 146), (187, 167, 134), + (158, 115, 99), (136, 91, 86), (117, 80, 74), (91, 54, 48), + (38, 52, 17), (48, 59, 17), (58, 66, 17), (49, 79, 15), + (43, 83, 31), (50, 69, 63), (44, 82, 67), (63, 86, 76), + (49, 108, 50), (39, 99, 61), (11, 86, 82), (6, 83, 63), + (25, 112, 61), (28, 136, 51), (10, 172, 61), (15, 186, 46), + (65, 178, 88), (75, 171, 82), (85, 165, 76), (105, 147, 109), + (98, 128, 128), (86, 156, 166), (173, 141, 144), (189, 101, 89), + (208, 90, 62), (187, 39, 73), (135, 63, 51), (119, 52, 61), + (85, 58, 73), (65, 61, 75), (34, 69, 73), (47, 54, 72), + (85, 39, 86), (139, 66, 85), (152, 96, 79), (188, 108, 81), + (207, 99, 60), (180, 57, 23), (152, 36, 21), (137, 43, 5), + (96, 46, 9), (87, 58, 14), (80, 37, 47), (81, 31, 66), + (48, 18, 68), (38, 16, 65), (32, 12, 40), (23, 34, 18), + (33, 38, 8), (3, 48, 17), (4, 43, 24), (0, 38, 15), + (23, 24, 18), (1, 7, 5), (12, 12, 24), (7, 20, 29), + (1, 16, 35), (0, 24, 36), (7, 18, 50), (3, 19, 68), + (23, 42, 59), (47, 57, 66), (68, 52, 62), (83, 45, 58), + (85, 40, 37), (76, 26, 25), (42, 12, 14), (20, 17, 10), + (23, 32, 29), (23, 50, 57), (18, 70, 84), (24, 97, 90), + (20, 116, 102), (49, 102, 82), (51, 125, 74), (55, 109, 75), + (58, 100, 88), (56, 67, 73), (57, 55, 66), (78, 38, 38), + (69, 17, 19), (71, 13, 11), (70, 32, 11), (77, 29, 19), + (94, 50, 15), (129, 57, 17), (148, 71, 63), (152, 61, 42) + ), + +// 333 3m0016.jpg +((148, 85, 42), (51, 97, 50), (40, 66, 45), (30, 35, 41), + (17, 31, 29), (5, 28, 18), (6, 38, 10), (7, 49, 3), + (43, 97, 19), (40, 112, 20), (38, 127, 21), (36, 137, 15), + (34, 148, 9), (70, 145, 8), (106, 142, 8), (128, 136, 20), + (151, 131, 32), (183, 133, 44), (189, 153, 35), (195, 173, 27), + (198, 168, 36), (202, 163, 46), (200, 167, 71), (198, 172, 97), + (189, 155, 83), (201, 123, 50), (213, 91, 18), (176, 59, 21), + (139, 27, 25), (134, 20, 16), (129, 14, 7), (129, 17, 33), + (148, 29, 87), (195, 51, 74), (194, 66, 75), (194, 81, 77), + (202, 68, 72), (211, 55, 68), (211, 53, 52), (211, 51, 37), + (216, 87, 66), (228, 73, 51), (240, 60, 37), (227, 36, 22), + (215, 12, 8), (203, 20, 26), (191, 29, 44), (126, 29, 20), + (84, 37, 7), (53, 1, 5), (43, 14, 19), (34, 27, 34), + (17, 41, 51), (0, 55, 69), (1, 73, 87), (2, 91, 105), + (9, 95, 156), (6, 65, 179), (3, 36, 203), (70, 31, 193), + (137, 27, 184), (143, 26, 184), (150, 26, 184), (179, 33, 160), + (192, 35, 164), (206, 13, 154), (199, 24, 155), (193, 35, 156), + (193, 34, 154), (193, 34, 153), (193, 44, 134), (141, 57, 109), + (73, 28, 61), (66, 35, 57), (60, 43, 53), (64, 63, 76), + (68, 84, 99), (81, 89, 108), (94, 94, 118), (82, 129, 147), + (72, 167, 133), (55, 156, 152), (59, 134, 170), (63, 112, 189), + (57, 88, 187), (52, 64, 186), (42, 42, 138), (59, 50, 103), + (69, 43, 42), (69, 37, 30), (70, 32, 19), (83, 34, 20), + (96, 37, 21), (130, 57, 16), (149, 75, 64), (171, 74, 81), + (168, 60, 109), (118, 28, 89), (102, 25, 80), (86, 22, 72), + (71, 20, 71), (57, 18, 71), (36, 57, 78), (20, 85, 51), + (3, 97, 61), (27, 101, 76), (52, 106, 92), (61, 109, 114), + (70, 112, 137), (89, 104, 173), (72, 90, 166), (84, 36, 122), + (70, 21, 66), (117, 10, 80), (134, 13, 95), (151, 16, 111), + (191, 25, 151), (185, 31, 165), (160, 51, 176), (102, 46, 155), + (63, 33, 155), (39, 23, 150), (16, 13, 146), (29, 20, 127), + (43, 28, 109), (42, 23, 87), (60, 28, 67), (17, 57, 59), + (21, 85, 50), (41, 84, 75), (58, 89, 68), (75, 94, 62), + (109, 119, 23), (135, 116, 58), (171, 127, 102), (174, 116, 140), + (197, 75, 98), (203, 94, 75), (209, 113, 52), (197, 119, 47), + (186, 125, 42), (146, 121, 28), (123, 99, 35), (128, 85, 16), + (112, 63, 49), (125, 22, 105), (114, 17, 103), (103, 13, 101), + (73, 0, 141), (13, 18, 196), (19, 64, 207), (43, 118, 173), + (27, 73, 123), (33, 68, 118), (40, 63, 113), (45, 122, 148), + (58, 138, 149), (15, 133, 163), (36, 154, 132), (35, 149, 123), + (22, 151, 51), (16, 125, 44), (25, 114, 29), (34, 104, 15), + (40, 81, 37), (43, 83, 74), (56, 82, 105), (79, 94, 149), + (59, 87, 111), (56, 84, 94), (53, 82, 77), (42, 44, 43), + (48, 55, 22), (38, 65, 22), (34, 49, 20), (12, 36, 0), + (18, 17, 15), (21, 7, 22), (32, 23, 52), (43, 22, 81), + (56, 11, 130), (85, 41, 138), (144, 73, 129), (181, 61, 135), + (196, 84, 120), (212, 87, 98), (228, 90, 77), (217, 72, 77), + (213, 47, 97), (235, 43, 102), (202, 47, 139), (190, 45, 138), + (127, 46, 148), (85, 41, 154), (47, 34, 122), (15, 21, 109), + (0, 50, 76), (6, 61, 102), (16, 93, 121), (13, 132, 162), + (13, 146, 165), (11, 145, 174), (18, 133, 164), (59, 121, 132), + (108, 86, 109), (91, 94, 83), (115, 119, 68), (75, 144, 89), + (55, 128, 85), (32, 135, 92), (62, 135, 90), (132, 145, 76), + (171, 162, 85), (155, 145, 84), (112, 142, 118), (56, 137, 94), + (65, 107, 93), (53, 99, 63), (88, 62, 99), (123, 65, 115), + (166, 67, 111), (179, 80, 83), (187, 79, 95), (181, 79, 103), + (123, 87, 99), (113, 82, 97), (83, 62, 105), (19, 41, 98), + (12, 54, 76), (37, 39, 54), (55, 22, 43), (64, 3, 45), + (51, 17, 33), (44, 21, 7), (53, 25, 1), (55, 33, 9), + (54, 43, 11), (63, 62, 41), (84, 87, 78), (113, 106, 78), + (187, 98, 94), (196, 80, 117), (220, 88, 148), (206, 108, 169), + (212, 110, 123), (203, 118, 81), (196, 140, 43), (196, 131, 15), + (177, 129, 3), (174, 126, 2), (139, 123, 2), (101, 142, 22), + (75, 147, 21), (102, 110, 50), (149, 52, 168), (119, 79, 103) + ), + +// 334 3m0018.jpg +((21, 63, 181), (3, 76, 217), (3, 93, 208), (3, 111, 199), + (28, 128, 151), (54, 145, 104), (53, 154, 96), (52, 164, 88), + (62, 111, 105), (52, 85, 92), (42, 60, 80), (25, 50, 70), + (9, 40, 60), (10, 57, 73), (11, 75, 87), (22, 73, 81), + (34, 72, 75), (28, 78, 49), (23, 97, 33), (18, 116, 17), + (19, 119, 19), (20, 122, 22), (31, 123, 22), (43, 124, 22), + (142, 125, 21), (187, 156, 23), (233, 188, 25), (210, 159, 36), + (187, 131, 48), (180, 125, 47), (174, 120, 46), (199, 95, 94), + (147, 86, 85), (172, 141, 156), (202, 157, 128), (232, 174, 100), + (229, 160, 101), (227, 146, 103), (223, 126, 143), (219, 107, 183), + (160, 74, 123), (132, 45, 102), (105, 16, 82), (100, 26, 72), + (95, 37, 62), (108, 39, 54), (122, 41, 47), (160, 38, 51), + (145, 30, 73), (38, 8, 62), (27, 17, 91), (16, 26, 121), + (35, 53, 111), (54, 81, 102), (51, 90, 113), (48, 100, 124), + (19, 149, 162), (63, 149, 139), (108, 149, 117), (110, 159, 112), + (113, 169, 108), (112, 176, 101), (111, 184, 95), (117, 199, 91), + (127, 201, 86), (236, 189, 49), (212, 140, 32), (189, 91, 16), + (161, 70, 27), (134, 50, 39), (84, 36, 13), (58, 14, 13), + (60, 14, 17), (95, 26, 30), (130, 38, 43), (140, 31, 30), + (151, 24, 17), (141, 41, 33), (132, 58, 49), (127, 78, 35), + (106, 79, 49), (48, 88, 15), (50, 62, 35), (52, 37, 56), + (52, 61, 65), (53, 85, 74), (99, 117, 95), (105, 138, 109), + (150, 192, 90), (177, 193, 116), (204, 194, 143), (192, 186, 131), + (180, 178, 119), (161, 184, 114), (133, 182, 117), (103, 165, 118), + (77, 189, 117), (62, 171, 78), (58, 145, 67), (54, 120, 56), + (47, 117, 47), (40, 114, 39), (43, 119, 80), (63, 133, 97), + (71, 134, 55), (80, 149, 59), (90, 165, 64), (91, 176, 66), + (92, 187, 69), (87, 192, 74), (83, 165, 93), (125, 146, 69), + (115, 96, 54), (97, 67, 29), (94, 62, 40), (91, 58, 51), + (66, 78, 40), (48, 76, 28), (34, 84, 25), (34, 105, 45), + (95, 79, 82), (113, 85, 116), (131, 91, 151), (127, 104, 159), + (124, 117, 168), (120, 180, 154), (120, 182, 119), (125, 177, 128), + (113, 159, 157), (97, 88, 91), (104, 67, 108), (111, 47, 125), + (81, 62, 144), (47, 44, 113), (42, 72, 110), (40, 75, 129), + (83, 71, 95), (100, 89, 76), (117, 107, 58), (109, 111, 46), + (101, 116, 35), (146, 106, 11), (196, 120, 22), (195, 119, 35), + (138, 82, 33), (102, 31, 89), (97, 25, 89), (92, 19, 90), + (57, 10, 88), (24, 17, 120), (8, 21, 162), (14, 24, 156), + (17, 97, 106), (16, 110, 99), (16, 124, 92), (31, 116, 77), + (46, 95, 50), (82, 72, 37), (106, 53, 39), (155, 49, 1), + (221, 64, 11), (234, 178, 21), (233, 183, 40), (233, 188, 59), + (196, 191, 110), (162, 194, 93), (149, 181, 108), (123, 183, 158), + (74, 127, 177), (75, 100, 154), (77, 73, 132), (96, 31, 85), + (69, 31, 52), (32, 41, 38), (0, 37, 10), (0, 41, 5), + (0, 78, 2), (4, 67, 24), (25, 70, 15), (23, 95, 29), + (36, 104, 17), (37, 99, 13), (43, 78, 24), (70, 52, 16), + (186, 29, 14), (195, 29, 25), (204, 29, 36), (224, 105, 23), + (230, 153, 47), (235, 185, 70), (228, 166, 93), (165, 143, 119), + (111, 99, 121), (61, 90, 130), (54, 60, 146), (27, 25, 188), + (11, 16, 206), (4, 37, 228), (0, 23, 199), (20, 16, 152), + (87, 29, 141), (107, 31, 131), (102, 4, 141), (127, 4, 146), + (164, 40, 94), (168, 40, 39), (187, 19, 16), (199, 51, 37), + (151, 69, 57), (127, 138, 78), (114, 129, 96), (71, 138, 107), + (35, 118, 90), (3, 84, 87), (0, 73, 89), (2, 58, 95), + (24, 74, 85), (33, 107, 74), (17, 134, 53), (22, 144, 45), + (26, 127, 47), (25, 81, 36), (37, 55, 41), (37, 48, 54), + (40, 42, 54), (16, 38, 51), (23, 28, 47), (16, 10, 46), + (8, 21, 29), (4, 28, 12), (26, 18, 29), (24, 5, 11), + (46, 3, 20), (52, 11, 7), (53, 43, 8), (67, 26, 30), + (132, 31, 37), (150, 15, 9), (180, 12, 1), (208, 11, 3), + (208, 5, 27), (147, 20, 37), (73, 26, 42), (38, 23, 46), + (43, 11, 76), (87, 10, 90), (105, 34, 128), (157, 49, 151), + (132, 53, 230), (127, 90, 195), (131, 106, 187), (113, 137, 137), + (171, 174, 105), (180, 147, 54), (234, 160, 13), (232, 138, 24) + ), + +// 335 4u0002.jpg +((113, 196, 42), (78, 160, 16), (96, 132, 13), (115, 105, 10), + (100, 84, 5), (86, 63, 0), (84, 60, 3), (83, 57, 6), + (91, 89, 14), (119, 123, 10), (148, 157, 6), (142, 133, 9), + (137, 109, 12), (123, 104, 7), (110, 100, 3), (89, 92, 7), + (68, 84, 11), (32, 92, 32), (36, 103, 54), (40, 115, 76), + (38, 121, 76), (36, 128, 77), (40, 124, 74), (44, 120, 71), + (59, 76, 42), (63, 59, 25), (67, 43, 9), (71, 41, 29), + (76, 40, 50), (74, 40, 53), (73, 41, 56), (65, 35, 71), + (72, 46, 73), (80, 40, 92), (97, 33, 83), (115, 26, 74), + (109, 22, 58), (103, 19, 42), (100, 21, 40), (97, 23, 38), + (55, 19, 21), (47, 25, 43), (39, 32, 66), (33, 56, 60), + (28, 81, 55), (33, 96, 61), (38, 111, 68), (56, 96, 72), + (69, 85, 75), (159, 40, 96), (190, 35, 102), (221, 30, 108), + (189, 51, 76), (158, 73, 44), (134, 78, 36), (110, 83, 28), + (67, 140, 23), (48, 146, 41), (29, 153, 59), (30, 148, 72), + (31, 143, 85), (35, 134, 84), (39, 126, 84), (54, 109, 70), + (72, 110, 63), (90, 95, 73), (73, 97, 66), (57, 99, 59), + (60, 79, 60), (64, 60, 61), (50, 68, 56), (39, 85, 49), + (30, 117, 36), (42, 128, 25), (55, 139, 15), (49, 123, 9), + (44, 107, 3), (45, 93, 1), (47, 80, 0), (62, 76, 15), + (80, 60, 33), (76, 84, 7), (69, 111, 7), (63, 139, 7), + (58, 145, 14), (54, 151, 22), (59, 158, 29), (57, 148, 43), + (40, 105, 51), (42, 81, 40), (45, 58, 30), (55, 49, 25), + (65, 40, 20), (91, 32, 26), (99, 50, 20), (97, 48, 31), + (110, 43, 52), (141, 53, 52), (135, 65, 59), (130, 78, 67), + (123, 71, 53), (116, 64, 40), (125, 96, 20), (118, 105, 3), + (157, 136, 29), (167, 152, 20), (178, 169, 12), (176, 168, 8), + (175, 167, 4), (189, 182, 16), (199, 151, 75), (187, 132, 50), + (176, 96, 71), (176, 52, 60), (178, 55, 58), (181, 59, 56), + (174, 103, 51), (125, 124, 18), (89, 155, 32), (115, 194, 79), + (112, 208, 83), (77, 180, 70), (42, 152, 57), (28, 143, 65), + (15, 135, 73), (1, 144, 90), (12, 153, 75), (5, 150, 45), + (48, 164, 39), (91, 221, 99), (102, 205, 98), (114, 189, 98), + (85, 186, 90), (50, 112, 91), (35, 94, 72), (32, 62, 38), + (55, 34, 7), (67, 18, 14), (79, 2, 22), (82, 7, 18), + (85, 13, 14), (98, 13, 16), (88, 23, 27), (79, 43, 21), + (66, 63, 8), (36, 30, 6), (35, 44, 8), (34, 58, 10), + (15, 66, 23), (1, 76, 9), (14, 65, 6), (12, 48, 12), + (9, 10, 15), (18, 9, 11), (27, 9, 7), (29, 17, 0), + (26, 16, 17), (19, 10, 37), (33, 24, 27), (35, 46, 38), + (42, 37, 44), (118, 85, 76), (144, 94, 67), (171, 104, 59), + (153, 190, 24), (161, 218, 25), (129, 217, 43), (115, 213, 52), + (53, 115, 90), (52, 99, 85), (52, 84, 81), (26, 45, 60), + (3, 3, 57), (22, 17, 40), (8, 51, 41), (13, 88, 21), + (28, 79, 12), (29, 74, 15), (61, 65, 15), (85, 58, 13), + (121, 55, 29), (141, 31, 40), (150, 36, 44), (145, 45, 43), + (76, 150, 27), (62, 153, 29), (48, 157, 32), (19, 139, 42), + (28, 129, 49), (25, 121, 49), (19, 119, 47), (10, 129, 49), + (18, 133, 66), (4, 131, 86), (29, 129, 77), (22, 127, 70), + (23, 115, 50), (10, 120, 49), (5, 114, 47), (22, 97, 38), + (22, 68, 29), (41, 41, 33), (53, 19, 18), (45, 19, 20), + (33, 19, 19), (38, 28, 3), (57, 21, 5), (65, 8, 0), + (90, 16, 13), (107, 47, 0), (89, 60, 4), (84, 85, 27), + (99, 83, 58), (104, 101, 60), (80, 126, 53), (83, 108, 27), + (124, 110, 11), (168, 112, 38), (179, 102, 56), (144, 96, 56), + (110, 83, 40), (99, 81, 7), (106, 63, 12), (103, 53, 0), + (112, 49, 14), (117, 32, 29), (114, 18, 45), (135, 14, 47), + (164, 22, 78), (170, 13, 94), (187, 9, 93), (168, 10, 87), + (153, 30, 76), (131, 36, 58), (115, 33, 56), (116, 19, 60), + (132, 16, 51), (150, 43, 73), (146, 31, 96), (115, 31, 83), + (115, 48, 91), (134, 45, 101), (180, 27, 110), (202, 20, 97), + (195, 18, 88), (185, 24, 78), (184, 29, 69), (152, 16, 54), + (137, 14, 42), (136, 44, 65), (109, 74, 81), (96, 104, 63), + (74, 141, 38), (51, 152, 48), (10, 152, 78), (25, 148, 68) + ), + +// 336 4u0003.jpg +((67, 30, 73), (148, 55, 108), (148, 80, 73), (149, 106, 38), + (120, 79, 23), (91, 53, 8), (65, 61, 5), (40, 69, 3), + (54, 84, 30), (69, 95, 62), (85, 107, 94), (124, 98, 119), + (163, 90, 145), (140, 120, 170), (117, 151, 196), (121, 154, 202), + (125, 158, 209), (107, 188, 217), (93, 169, 177), (80, 151, 137), + (73, 151, 108), (66, 152, 79), (63, 141, 77), (60, 131, 75), + (9, 116, 22), (5, 99, 13), (1, 82, 5), (20, 59, 18), + (39, 36, 31), (55, 31, 41), (71, 27, 52), (84, 58, 87), + (76, 72, 89), (61, 89, 75), (51, 76, 49), (42, 63, 24), + (36, 63, 22), (30, 63, 20), (31, 66, 23), (32, 69, 26), + (5, 45, 45), (3, 26, 34), (1, 7, 23), (20, 17, 22), + (40, 27, 21), (40, 28, 19), (41, 29, 17), (69, 11, 25), + (112, 23, 43), (140, 51, 97), (134, 43, 110), (128, 35, 124), + (119, 38, 92), (110, 41, 60), (110, 32, 49), (110, 23, 39), + (67, 21, 5), (64, 30, 10), (62, 40, 16), (87, 35, 32), + (113, 30, 48), (113, 41, 59), (114, 53, 71), (109, 84, 64), + (169, 95, 82), (181, 219, 82), (137, 201, 96), (94, 184, 110), + (85, 174, 110), (77, 164, 111), (119, 108, 116), (123, 96, 139), + (142, 116, 189), (152, 109, 181), (163, 103, 173), (166, 96, 189), + (169, 90, 205), (177, 72, 201), (186, 55, 197), (163, 60, 165), + (146, 47, 153), (106, 9, 63), (111, 18, 57), (117, 27, 52), + (98, 35, 60), (79, 44, 68), (72, 82, 92), (67, 96, 130), + (36, 116, 139), (51, 141, 117), (67, 167, 95), (69, 164, 83), + (72, 162, 72), (59, 118, 62), (66, 89, 81), (71, 76, 79), + (82, 42, 30), (75, 10, 6), (81, 35, 44), (88, 60, 83), + (79, 70, 87), (71, 81, 91), (47, 109, 106), (35, 116, 107), + (11, 106, 98), (7, 91, 61), (4, 77, 24), (19, 73, 30), + (34, 69, 37), (46, 48, 43), (69, 26, 80), (88, 22, 112), + (86, 10, 110), (109, 0, 107), (99, 4, 92), (89, 9, 78), + (71, 8, 65), (61, 13, 75), (47, 2, 97), (11, 24, 94), + (1, 28, 49), (23, 34, 55), (45, 40, 62), (52, 27, 81), + (59, 15, 100), (67, 42, 100), (87, 73, 99), (113, 73, 97), + (130, 85, 114), (127, 67, 141), (122, 50, 139), (118, 33, 137), + (114, 33, 138), (109, 27, 101), (113, 18, 100), (97, 16, 93), + (107, 10, 87), (111, 7, 111), (116, 5, 136), (114, 10, 130), + (112, 16, 124), (94, 11, 99), (70, 16, 66), (39, 51, 37), + (10, 100, 2), (21, 62, 4), (36, 54, 14), (52, 46, 24), + (78, 14, 5), (92, 11, 26), (99, 5, 41), (86, 16, 44), + (65, 16, 48), (56, 16, 38), (47, 17, 29), (41, 14, 47), + (35, 23, 47), (57, 52, 49), (88, 68, 93), (133, 101, 104), + (189, 128, 109), (195, 182, 90), (199, 179, 99), (204, 177, 108), + (206, 146, 138), (156, 139, 132), (73, 142, 137), (58, 127, 156), + (57, 148, 130), (60, 151, 129), (64, 154, 128), (62, 152, 142), + (86, 171, 138), (94, 185, 118), (126, 145, 160), (130, 141, 163), + (73, 149, 136), (51, 133, 95), (29, 124, 82), (12, 110, 72), + (17, 115, 64), (19, 112, 67), (50, 63, 53), (57, 18, 47), + (80, 27, 73), (85, 29, 89), (91, 31, 105), (89, 28, 123), + (112, 65, 145), (116, 85, 116), (111, 120, 91), (81, 157, 82), + (77, 174, 61), (57, 159, 50), (43, 144, 50), (46, 144, 45), + (57, 117, 43), (43, 108, 54), (24, 83, 39), (8, 61, 43), + (9, 93, 43), (12, 89, 53), (4, 68, 68), (6, 70, 80), + (6, 86, 87), (10, 81, 99), (9, 70, 91), (29, 62, 105), + (62, 97, 116), (112, 104, 128), (178, 97, 116), (167, 89, 149), + (135, 73, 138), (132, 51, 154), (125, 34, 95), (107, 19, 61), + (87, 21, 69), (88, 36, 102), (101, 91, 125), (55, 122, 149), + (67, 152, 157), (117, 155, 191), (150, 140, 175), (157, 122, 186), + (154, 90, 168), (147, 86, 164), (104, 59, 152), (62, 87, 144), + (36, 129, 110), (45, 135, 84), (44, 138, 78), (32, 131, 66), + (23, 109, 44), (3, 85, 19), (2, 50, 8), (5, 21, 10), + (5, 3, 16), (30, 2, 25), (38, 29, 20), (34, 43, 24), + (27, 45, 7), (6, 42, 4), (14, 19, 15), (23, 22, 36), + (32, 4, 45), (28, 5, 61), (52, 15, 58), (64, 9, 66), + (80, 33, 85), (78, 64, 97), (78, 76, 98), (69, 81, 67), + (48, 112, 52), (27, 111, 51), (25, 111, 38), (28, 97, 34) + ), + +// 337 4u0004.jpg +((68, 10, 148), (17, 39, 114), (37, 62, 107), (57, 86, 100), + (63, 86, 97), (70, 87, 94), (74, 80, 94), (79, 74, 94), + (98, 51, 33), (141, 34, 16), (185, 18, 0), (202, 54, 29), + (220, 90, 58), (222, 137, 38), (225, 184, 18), (180, 191, 20), + (135, 198, 23), (68, 218, 33), (46, 209, 80), (25, 201, 128), + (25, 191, 144), (25, 182, 161), (30, 164, 130), (35, 147, 99), + (56, 148, 39), (41, 172, 20), (26, 196, 1), (13, 198, 15), + (1, 201, 30), (20, 202, 48), (39, 204, 66), (89, 216, 83), + (116, 248, 85), (103, 197, 173), (53, 153, 154), (4, 110, 136), + (25, 109, 113), (47, 108, 90), (73, 95, 82), (99, 82, 74), + (164, 35, 63), (162, 27, 53), (161, 19, 43), (125, 24, 84), + (89, 29, 125), (69, 23, 137), (49, 17, 150), (51, 18, 135), + (50, 39, 95), (152, 12, 75), (167, 27, 65), (182, 42, 55), + (156, 85, 49), (131, 129, 44), (115, 142, 46), (99, 156, 49), + (22, 169, 0), (26, 164, 7), (30, 159, 15), (31, 159, 50), + (33, 159, 86), (27, 159, 96), (22, 159, 107), (49, 155, 168), + (66, 148, 196), (141, 203, 224), (122, 146, 175), (104, 90, 126), + (96, 83, 121), (88, 76, 116), (62, 96, 121), (33, 111, 85), + (81, 166, 73), (57, 190, 60), (34, 215, 48), (21, 228, 37), + (8, 241, 27), (9, 220, 36), (10, 199, 45), (4, 183, 63), + (34, 168, 83), (53, 163, 216), (71, 192, 181), (90, 222, 146), + (106, 229, 116), (123, 236, 86), (137, 205, 94), (131, 192, 73), + (95, 154, 74), (94, 129, 53), (93, 105, 33), (114, 98, 29), + (136, 91, 26), (160, 103, 26), (189, 114, 33), (213, 112, 60), + (162, 92, 94), (136, 114, 93), (119, 132, 96), (102, 150, 100), + (85, 157, 96), (68, 164, 93), (77, 176, 67), (30, 172, 64), + (35, 174, 45), (30, 176, 58), (26, 179, 71), (27, 186, 82), + (29, 193, 94), (47, 223, 98), (29, 253, 128), (4, 245, 142), + (18, 228, 155), (25, 105, 220), (26, 87, 237), (28, 69, 255), + (23, 44, 233), (23, 15, 238), (12, 13, 181), (30, 10, 123), + (70, 24, 73), (35, 14, 70), (1, 5, 68), (4, 15, 65), + (8, 26, 62), (10, 26, 62), (26, 51, 56), (42, 38, 27), + (47, 14, 23), (39, 1, 0), (33, 14, 0), (27, 27, 1), + (16, 39, 13), (25, 51, 24), (6, 69, 12), (37, 90, 12), + (29, 90, 31), (26, 102, 26), (23, 114, 21), (32, 135, 12), + (42, 157, 4), (65, 185, 10), (64, 175, 10), (60, 140, 17), + (107, 110, 19), (169, 125, 18), (168, 149, 19), (168, 173, 21), + (189, 116, 5), (196, 111, 4), (175, 99, 15), (188, 111, 31), + (125, 94, 50), (133, 76, 49), (141, 59, 48), (142, 65, 37), + (146, 84, 45), (171, 81, 3), (187, 86, 18), (166, 85, 32), + (141, 76, 54), (53, 99, 125), (43, 107, 126), (34, 116, 128), + (32, 136, 125), (34, 148, 89), (73, 119, 70), (103, 82, 61), + (143, 35, 6), (135, 39, 6), (128, 44, 7), (87, 73, 24), + (39, 28, 22), (37, 9, 32), (48, 28, 39), (76, 31, 64), + (79, 46, 63), (47, 75, 17), (12, 71, 25), (4, 107, 86), + (1, 70, 103), (0, 106, 164), (31, 75, 226), (52, 45, 237), + (102, 1, 181), (92, 23, 163), (82, 46, 146), (108, 43, 107), + (69, 88, 92), (56, 113, 42), (53, 133, 20), (56, 113, 19), + (63, 106, 17), (83, 103, 40), (108, 82, 57), (129, 63, 41), + (132, 79, 48), (120, 115, 47), (81, 116, 32), (75, 137, 36), + (53, 135, 97), (77, 117, 119), (97, 73, 147), (77, 28, 180), + (113, 51, 150), (133, 81, 117), (142, 163, 84), (152, 162, 47), + (180, 126, 80), (183, 104, 123), (116, 87, 169), (92, 129, 210), + (87, 71, 242), (57, 68, 222), (66, 22, 207), (26, 35, 152), + (22, 62, 88), (61, 43, 59), (44, 46, 59), (16, 75, 69), + (52, 90, 103), (37, 109, 123), (5, 82, 134), (14, 14, 164), + (72, 9, 184), (74, 46, 183), (36, 112, 112), (9, 128, 38), + (7, 175, 56), (24, 184, 52), (17, 234, 33), (28, 237, 50), + (56, 201, 34), (60, 197, 29), (84, 200, 39), (88, 216, 15), + (67, 206, 1), (77, 180, 15), (85, 129, 32), (80, 79, 59), + (65, 85, 58), (58, 79, 48), (36, 92, 47), (46, 119, 37), + (76, 152, 44), (143, 202, 32), (189, 251, 18), (140, 214, 15), + (117, 220, 29), (115, 237, 50), (120, 238, 58), (91, 221, 69), + (105, 167, 66), (78, 155, 59), (52, 192, 41), (68, 173, 55) + ), + +// 338 4u0005.jpg +((63, 63, 89), (65, 108, 114), (74, 130, 111), (84, 153, 108), + (140, 156, 111), (197, 160, 115), (206, 135, 116), (215, 111, 118), + (198, 60, 179), (164, 32, 203), (131, 5, 227), (97, 15, 194), + (63, 25, 162), (73, 23, 126), (83, 22, 91), (70, 31, 72), + (58, 40, 54), (55, 84, 30), (44, 130, 76), (34, 177, 123), + (26, 201, 162), (18, 226, 202), (55, 216, 184), (92, 207, 166), + (83, 184, 52), (105, 200, 44), (127, 216, 36), (179, 199, 86), + (231, 183, 137), (228, 168, 149), (226, 153, 162), (213, 97, 172), + (178, 60, 209), (111, 5, 225), (75, 17, 208), (40, 30, 191), + (30, 68, 203), (21, 106, 215), (22, 96, 184), (24, 87, 154), + (36, 83, 113), (36, 103, 122), (36, 123, 132), (28, 140, 138), + (20, 158, 145), (18, 187, 141), (16, 217, 137), (2, 224, 137), + (1, 237, 127), (3, 177, 92), (36, 174, 60), (70, 171, 29), + (61, 134, 18), (53, 98, 7), (45, 92, 7), (38, 87, 8), + (8, 106, 67), (17, 97, 90), (26, 88, 113), (47, 95, 136), + (68, 103, 159), (86, 98, 179), (105, 94, 199), (163, 84, 211), + (186, 97, 227), (213, 99, 238), (214, 77, 225), (216, 55, 213), + (211, 47, 210), (206, 39, 207), (183, 56, 189), (134, 37, 178), + (170, 62, 112), (133, 108, 76), (96, 154, 41), (90, 189, 48), + (84, 224, 55), (74, 203, 79), (65, 182, 104), (38, 227, 137), + (34, 231, 152), (32, 197, 157), (49, 172, 134), (66, 148, 112), + (69, 158, 98), (73, 168, 84), (74, 167, 35), (67, 175, 29), + (111, 177, 25), (137, 173, 23), (164, 170, 22), (185, 186, 30), + (206, 203, 38), (197, 232, 18), (127, 240, 36), (93, 244, 67), + (69, 228, 74), (63, 195, 148), (76, 152, 145), (89, 109, 142), + (122, 89, 151), (155, 69, 160), (219, 69, 158), (219, 95, 168), + (176, 67, 210), (135, 90, 208), (94, 113, 207), (85, 127, 206), + (76, 141, 205), (71, 184, 192), (102, 193, 178), (107, 126, 220), + (206, 158, 220), (228, 99, 156), (231, 89, 153), (235, 79, 150), + (217, 55, 115), (192, 79, 61), (189, 56, 103), (193, 50, 112), + (250, 49, 141), (236, 103, 125), (223, 157, 109), (222, 172, 115), + (222, 187, 121), (182, 221, 106), (124, 223, 55), (117, 223, 52), + (102, 181, 40), (158, 112, 114), (177, 94, 113), (197, 77, 112), + (191, 58, 141), (144, 69, 138), (95, 35, 95), (95, 4, 81), + (73, 97, 9), (85, 107, 16), (98, 118, 23), (80, 106, 24), + (62, 95, 26), (57, 76, 12), (122, 97, 17), (141, 47, 35), + (187, 56, 72), (229, 9, 145), (218, 12, 150), (208, 16, 155), + (164, 25, 154), (120, 30, 117), (109, 19, 115), (110, 16, 140), + (140, 47, 198), (161, 39, 185), (183, 32, 173), (198, 8, 156), + (166, 4, 201), (144, 31, 225), (145, 36, 205), (158, 77, 205), + (143, 60, 200), (88, 98, 185), (72, 103, 174), (57, 108, 163), + (54, 144, 153), (55, 118, 169), (55, 96, 202), (46, 103, 216), + (63, 56, 185), (57, 61, 161), (52, 66, 137), (37, 85, 149), + (48, 93, 152), (43, 108, 128), (31, 83, 131), (36, 65, 125), + (47, 42, 108), (27, 36, 77), (17, 60, 41), (38, 66, 18), + (68, 118, 19), (99, 161, 2), (110, 166, 13), (123, 203, 18), + (109, 196, 31), (115, 177, 53), (121, 159, 76), (219, 185, 113), + (208, 116, 119), (182, 96, 145), (169, 73, 144), (134, 74, 126), + (119, 62, 167), (95, 68, 147), (59, 100, 146), (54, 100, 124), + (58, 84, 109), (39, 99, 97), (50, 117, 84), (77, 150, 69), + (112, 119, 51), (181, 110, 48), (211, 131, 44), (96, 151, 34), + (78, 166, 46), (77, 160, 68), (49, 166, 87), (28, 181, 65), + (8, 145, 77), (0, 116, 56), (23, 120, 77), (28, 81, 97), + (19, 76, 96), (7, 83, 109), (33, 95, 146), (17, 133, 180), + (26, 162, 186), (16, 214, 225), (9, 240, 222), (6, 244, 212), + (10, 236, 199), (14, 232, 205), (16, 227, 212), (41, 191, 189), + (58, 176, 186), (84, 108, 196), (97, 106, 199), (121, 64, 167), + (130, 65, 169), (113, 55, 178), (95, 18, 130), (90, 35, 103), + (63, 5, 89), (58, 17, 87), (48, 21, 88), (37, 75, 94), + (43, 93, 128), (24, 135, 154), (34, 180, 167), (13, 200, 169), + (15, 233, 159), (9, 225, 140), (17, 193, 112), (23, 129, 89), + (25, 69, 52), (12, 59, 4), (10, 41, 7), (6, 30, 17), + (9, 17, 38), (8, 37, 32), (0, 53, 70), (24, 66, 64), + (32, 77, 80), (30, 132, 108), (20, 185, 151), (15, 155, 116) + ), + +// 339 4u0006.jpg +((35, 159, 183), (61, 171, 142), (60, 185, 118), (60, 200, 95), + (81, 188, 90), (103, 176, 86), (124, 140, 55), (146, 105, 25), + (115, 33, 45), (128, 42, 31), (142, 52, 18), (172, 81, 13), + (202, 110, 9), (188, 123, 46), (174, 137, 84), (162, 151, 113), + (150, 165, 142), (96, 202, 200), (77, 205, 197), (58, 209, 194), + (41, 167, 184), (24, 126, 175), (29, 105, 172), (35, 85, 170), + (83, 72, 150), (68, 100, 162), (54, 128, 175), (67, 139, 157), + (80, 150, 139), (97, 148, 138), (114, 147, 138), (139, 150, 154), + (148, 184, 174), (105, 217, 203), (87, 219, 216), (70, 221, 230), + (75, 189, 209), (81, 157, 189), (91, 164, 188), (102, 171, 187), + (81, 184, 157), (80, 166, 156), (79, 148, 155), (78, 146, 132), + (77, 144, 109), (75, 137, 100), (74, 130, 91), (65, 88, 72), + (66, 53, 45), (89, 57, 36), (58, 86, 43), (27, 116, 50), + (40, 120, 67), (53, 125, 85), (56, 127, 79), (60, 129, 74), + (156, 116, 28), (192, 98, 31), (228, 80, 34), (236, 61, 49), + (245, 42, 64), (233, 31, 61), (221, 21, 58), (196, 10, 49), + (170, 15, 73), (106, 25, 42), (105, 49, 51), (105, 73, 60), + (90, 85, 62), (76, 97, 64), (48, 103, 64), (9, 126, 71), + (9, 154, 79), (7, 158, 95), (5, 162, 111), (41, 182, 128), + (78, 203, 145), (80, 199, 161), (83, 196, 178), (83, 219, 217), + (80, 225, 230), (94, 213, 207), (104, 193, 189), (115, 174, 172), + (133, 161, 144), (151, 148, 117), (167, 121, 88), (211, 68, 54), + (240, 38, 52), (202, 40, 44), (164, 42, 37), (132, 37, 40), + (100, 32, 43), (31, 56, 0), (2, 94, 21), (9, 135, 53), + (25, 181, 46), (18, 208, 76), (24, 180, 41), (30, 152, 7), + (21, 141, 5), (12, 131, 3), (1, 108, 26), (8, 134, 9), + (24, 184, 62), (26, 172, 81), (28, 160, 100), (38, 140, 99), + (49, 121, 99), (77, 116, 85), (160, 92, 133), (171, 59, 143), + (173, 47, 155), (133, 29, 124), (165, 22, 107), (197, 15, 90), + (201, 17, 87), (213, 25, 84), (218, 9, 75), (217, 23, 49), + (221, 63, 16), (227, 77, 23), (234, 92, 30), (220, 83, 49), + (207, 74, 69), (149, 78, 48), (151, 84, 57), (146, 84, 85), + (178, 97, 96), (158, 48, 75), (149, 59, 74), (141, 71, 73), + (95, 63, 74), (48, 37, 95), (104, 19, 112), (108, 6, 106), + (137, 36, 114), (122, 78, 126), (108, 121, 138), (103, 128, 150), + (98, 135, 162), (109, 102, 240), (119, 82, 195), (109, 21, 159), + (95, 56, 119), (62, 102, 65), (54, 126, 48), (46, 151, 32), + (41, 145, 8), (81, 151, 26), (125, 130, 12), (152, 103, 11), + (139, 39, 16), (118, 33, 11), (98, 27, 7), (129, 16, 12), + (154, 30, 40), (136, 32, 59), (129, 14, 83), (137, 21, 96), + (201, 6, 100), (224, 13, 84), (218, 6, 67), (212, 0, 51), + (197, 11, 22), (174, 5, 2), (229, 48, 5), (227, 57, 5), + (225, 72, 31), (197, 88, 37), (170, 104, 44), (110, 135, 44), + (47, 193, 22), (32, 171, 54), (46, 146, 84), (78, 124, 52), + (130, 121, 64), (133, 131, 82), (118, 116, 129), (114, 90, 122), + (108, 86, 161), (113, 90, 162), (128, 83, 138), (149, 54, 88), + (149, 117, 79), (132, 128, 96), (115, 139, 113), (99, 137, 122), + (48, 137, 119), (42, 159, 143), (10, 133, 167), (32, 111, 116), + (66, 84, 124), (54, 86, 97), (35, 52, 95), (44, 88, 89), + (42, 95, 101), (13, 134, 89), (13, 146, 83), (5, 149, 87), + (17, 138, 133), (18, 129, 184), (18, 108, 186), (60, 125, 215), + (44, 149, 181), (43, 182, 141), (18, 183, 88), (2, 171, 78), + (8, 169, 55), (15, 122, 52), (22, 108, 47), (16, 107, 76), + (41, 129, 104), (50, 163, 143), (38, 181, 175), (68, 193, 185), + (66, 221, 155), (66, 224, 150), (105, 184, 136), (141, 168, 151), + (141, 160, 154), (132, 146, 110), (138, 148, 87), (159, 91, 56), + (148, 81, 36), (127, 45, 24), (120, 56, 29), (114, 79, 75), + (80, 102, 55), (40, 125, 31), (24, 140, 13), (31, 120, 26), + (27, 98, 32), (48, 57, 10), (119, 43, 27), (166, 34, 32), + (169, 9, 47), (196, 5, 48), (215, 2, 34), (221, 9, 31), + (206, 23, 25), (221, 55, 31), (207, 57, 43), (183, 42, 85), + (147, 55, 122), (102, 48, 172), (56, 67, 221), (34, 25, 206), + (46, 2, 147), (90, 0, 138), (98, 1, 168), (112, 11, 139), + (102, 10, 97), (128, 47, 90), (195, 50, 67), (232, 60, 10) + ), + +// 340 4u0007.jpg +((12, 10, 57), (0, 23, 37), (13, 19, 20), (26, 16, 4), + (30, 32, 17), (35, 48, 31), (31, 70, 39), (27, 93, 47), + (35, 82, 66), (47, 79, 65), (60, 76, 65), (109, 74, 53), + (158, 73, 42), (178, 59, 39), (198, 45, 37), (211, 45, 37), + (224, 45, 38), (206, 96, 19), (204, 106, 18), (203, 117, 18), + (167, 101, 14), (132, 86, 11), (117, 69, 15), (103, 53, 20), + (78, 48, 58), (80, 49, 64), (83, 50, 71), (79, 28, 61), + (76, 7, 52), (64, 5, 51), (52, 3, 50), (32, 22, 49), + (13, 35, 59), (17, 59, 39), (34, 70, 43), (51, 81, 47), + (34, 63, 38), (18, 45, 30), (17, 37, 26), (16, 29, 22), + (14, 1, 31), (7, 8, 36), (0, 16, 42), (12, 9, 40), + (24, 2, 38), (22, 2, 36), (21, 2, 34), (23, 8, 31), + (16, 9, 16), (34, 36, 22), (47, 46, 33), (61, 57, 45), + (57, 76, 55), (53, 96, 66), (53, 102, 69), (53, 109, 72), + (66, 182, 107), (70, 193, 150), (75, 205, 193), (70, 170, 182), + (66, 136, 172), (63, 118, 148), (60, 100, 125), (50, 78, 82), + (52, 58, 90), (70, 53, 61), (108, 38, 38), (147, 24, 16), + (148, 18, 25), (150, 12, 35), (131, 17, 27), (84, 21, 29), + (59, 48, 44), (49, 47, 49), (39, 46, 54), (24, 45, 52), + (10, 45, 51), (7, 44, 45), (4, 43, 40), (1, 31, 3), + (12, 21, 2), (27, 1, 4), (15, 4, 8), (4, 7, 12), + (8, 12, 20), (13, 17, 28), (22, 35, 52), (32, 70, 71), + (4, 148, 139), (12, 144, 154), (20, 141, 170), (30, 123, 142), + (41, 105, 114), (61, 82, 83), (71, 73, 60), (70, 69, 38), + (118, 77, 15), (189, 118, 26), (142, 102, 56), (95, 86, 87), + (70, 92, 99), (46, 98, 111), (38, 139, 151), (27, 147, 172), + (15, 145, 194), (12, 163, 198), (9, 181, 203), (6, 176, 211), + (4, 172, 219), (3, 189, 238), (7, 195, 243), (25, 197, 243), + (66, 209, 217), (82, 198, 221), (80, 194, 207), (78, 190, 194), + (64, 147, 163), (42, 132, 140), (37, 94, 105), (38, 62, 72), + (41, 38, 81), (44, 45, 69), (47, 52, 58), (51, 40, 54), + (56, 28, 51), (57, 21, 23), (57, 18, 19), (68, 7, 2), + (62, 11, 7), (63, 30, 13), (77, 37, 17), (91, 45, 21), + (121, 74, 20), (166, 86, 25), (182, 81, 3), (198, 66, 1), + (245, 80, 24), (234, 68, 27), (223, 57, 31), (231, 65, 29), + (239, 74, 28), (226, 91, 10), (210, 79, 7), (196, 82, 22), + (194, 119, 26), (97, 109, 27), (103, 108, 57), (110, 107, 88), + (114, 95, 101), (129, 81, 81), (106, 76, 88), (99, 88, 68), + (118, 51, 32), (148, 47, 28), (179, 44, 25), (220, 6, 14), + (152, 16, 4), (106, 31, 26), (82, 36, 47), (68, 52, 53), + (55, 68, 61), (56, 67, 53), (57, 70, 61), (59, 74, 69), + (71, 70, 84), (64, 95, 98), (49, 126, 134), (55, 138, 152), + (30, 112, 90), (38, 99, 83), (46, 86, 77), (59, 75, 75), + (56, 66, 75), (49, 62, 81), (33, 63, 87), (34, 86, 99), + (27, 131, 132), (13, 130, 140), (29, 129, 144), (30, 113, 127), + (63, 83, 116), (79, 62, 80), (93, 71, 73), (91, 72, 76), + (92, 104, 102), (84, 112, 123), (76, 121, 144), (100, 145, 187), + (100, 176, 192), (95, 194, 233), (80, 193, 227), (78, 152, 201), + (57, 146, 186), (26, 121, 149), (0, 75, 96), (26, 41, 74), + (22, 25, 60), (25, 21, 58), (37, 39, 51), (25, 60, 66), + (18, 60, 74), (3, 85, 83), (2, 103, 71), (10, 103, 95), + (22, 112, 139), (54, 122, 169), (74, 89, 158), (77, 56, 115), + (130, 15, 146), (108, 41, 94), (141, 56, 79), (133, 66, 39), + (118, 56, 57), (88, 69, 65), (73, 78, 84), (67, 112, 109), + (54, 130, 128), (52, 169, 153), (56, 209, 191), (68, 194, 182), + (72, 143, 129), (100, 123, 139), (86, 117, 120), (78, 120, 116), + (64, 111, 131), (66, 97, 115), (63, 71, 90), (42, 59, 89), + (44, 66, 80), (38, 68, 58), (44, 62, 50), (20, 60, 52), + (9, 49, 25), (2, 48, 1), (27, 25, 2), (41, 23, 11), + (56, 28, 17), (47, 57, 23), (44, 52, 39), (48, 61, 67), + (47, 53, 77), (63, 39, 87), (65, 52, 80), (70, 46, 70), + (78, 20, 32), (47, 17, 9), (31, 14, 7), (19, 1, 13), + (14, 1, 18), (9, 1, 14), (12, 3, 20), (26, 6, 31), + (38, 9, 39), (67, 15, 53), (90, 8, 48), (109, 9, 73) + ), + +// 341 4u0008.jpg +((92, 215, 223), (92, 212, 226), (95, 215, 222), (98, 218, 219), + (104, 195, 203), (110, 172, 187), (128, 167, 180), (146, 163, 173), + (172, 101, 97), (144, 89, 81), (117, 77, 65), (93, 77, 77), + (70, 78, 89), (67, 92, 101), (64, 107, 114), (63, 103, 111), + (62, 99, 108), (7, 83, 119), (21, 115, 140), (35, 148, 162), + (32, 167, 190), (29, 186, 219), (42, 194, 228), (56, 203, 237), + (95, 198, 243), (108, 177, 218), (121, 157, 193), (133, 147, 172), + (146, 138, 151), (126, 122, 135), (107, 106, 120), (85, 87, 86), + (68, 58, 83), (60, 27, 48), (55, 23, 45), (51, 19, 42), + (68, 28, 48), (85, 38, 54), (89, 58, 56), (93, 78, 59), + (99, 90, 93), (95, 130, 129), (91, 170, 165), (87, 191, 192), + (84, 213, 219), (76, 218, 223), (68, 223, 227), (55, 220, 216), + (55, 209, 217), (82, 165, 207), (86, 155, 195), (90, 145, 184), + (88, 147, 183), (86, 149, 182), (82, 156, 187), (79, 164, 193), + (64, 150, 173), (53, 137, 153), (42, 125, 133), (35, 101, 121), + (28, 77, 109), (29, 76, 99), (30, 76, 89), (18, 81, 90), + (10, 69, 75), (35, 60, 91), (40, 52, 87), (46, 44, 83), + (36, 52, 84), (26, 60, 85), (30, 75, 94), (32, 114, 125), + (45, 153, 192), (64, 165, 206), (84, 177, 220), (85, 172, 217), + (87, 168, 215), (89, 154, 190), (91, 141, 166), (114, 116, 115), + (122, 83, 78), (152, 100, 102), (148, 132, 128), (144, 164, 155), + (114, 153, 157), (84, 143, 159), (67, 128, 149), (59, 121, 132), + (40, 78, 115), (32, 85, 137), (24, 93, 160), (27, 105, 165), + (30, 117, 170), (48, 146, 175), (63, 159, 181), (79, 160, 163), + (86, 154, 177), (16, 117, 147), (8, 91, 125), (0, 65, 103), + (1, 65, 102), (2, 66, 101), (3, 49, 82), (0, 38, 60), + (25, 0, 19), (76, 10, 24), (128, 21, 29), (154, 28, 39), + (181, 36, 49), (223, 70, 75), (241, 95, 70), (230, 40, 50), + (212, 32, 61), (136, 82, 96), (117, 91, 124), (98, 101, 152), + (63, 91, 175), (26, 125, 148), (36, 159, 138), (35, 132, 125), + (36, 99, 91), (39, 84, 86), (42, 70, 82), (39, 79, 90), + (36, 88, 99), (19, 119, 143), (30, 164, 165), (66, 165, 186), + (92, 169, 179), (168, 161, 145), (184, 142, 123), (200, 124, 101), + (175, 103, 81), (136, 80, 63), (114, 78, 64), (99, 76, 60), + (55, 62, 54), (54, 70, 64), (53, 78, 74), (68, 84, 78), + (83, 90, 83), (105, 96, 87), (155, 121, 112), (187, 117, 109), + (215, 103, 81), (160, 85, 66), (128, 81, 62), (96, 78, 58), + (84, 89, 82), (83, 90, 83), (57, 112, 91), (56, 101, 130), + (30, 119, 149), (31, 126, 150), (33, 134, 152), (53, 122, 153), + (63, 118, 148), (85, 114, 146), (71, 95, 105), (84, 91, 84), + (151, 89, 78), (207, 95, 73), (207, 97, 80), (207, 99, 87), + (178, 111, 120), (166, 157, 142), (109, 173, 157), (43, 184, 193), + (24, 183, 213), (27, 175, 216), (31, 168, 220), (60, 187, 206), + (89, 200, 193), (88, 205, 196), (91, 188, 233), (86, 198, 236), + (51, 207, 220), (28, 202, 226), (22, 199, 232), (20, 210, 236), + (22, 220, 219), (33, 229, 228), (32, 213, 234), (47, 213, 229), + (41, 205, 230), (32, 201, 227), (23, 198, 225), (6, 161, 215), + (16, 145, 200), (44, 157, 213), (39, 145, 195), (52, 146, 171), + (26, 113, 130), (21, 89, 110), (36, 73, 89), (29, 62, 81), + (25, 47, 60), (19, 29, 54), (14, 23, 28), (19, 50, 32), + (32, 43, 71), (40, 60, 61), (57, 67, 76), (77, 60, 78), + (103, 67, 69), (130, 30, 42), (170, 13, 24), (203, 14, 21), + (206, 15, 22), (214, 58, 18), (200, 28, 44), (149, 33, 42), + (130, 23, 41), (107, 3, 4), (100, 7, 2), (79, 2, 0), + (75, 52, 72), (72, 90, 128), (52, 132, 167), (46, 161, 180), + (49, 159, 194), (59, 147, 185), (85, 122, 193), (96, 128, 201), + (144, 122, 145), (156, 117, 135), (173, 108, 114), (157, 121, 135), + (147, 140, 158), (138, 176, 177), (111, 201, 191), (102, 205, 222), + (83, 208, 236), (75, 234, 255), (92, 233, 250), (87, 224, 242), + (101, 222, 231), (106, 228, 233), (100, 218, 228), (103, 217, 228), + (108, 222, 222), (114, 209, 213), (138, 184, 182), (166, 168, 155), + (198, 121, 111), (216, 101, 82), (225, 99, 84), (212, 115, 96), + (207, 128, 111), (184, 155, 137), (151, 174, 180), (121, 215, 214), + (105, 215, 204), (88, 210, 213), (57, 176, 208), (32, 157, 175) + ), + +// 342 4u0009.jpg +((56, 63, 229), (69, 13, 224), (103, 12, 227), (137, 12, 230), + (148, 20, 229), (160, 29, 229), (153, 33, 228), (146, 37, 227), + (152, 74, 246), (161, 87, 247), (170, 100, 248), (155, 105, 210), + (141, 111, 173), (174, 77, 155), (207, 43, 138), (184, 36, 147), + (162, 29, 156), (82, 58, 206), (69, 88, 198), (56, 118, 191), + (70, 134, 144), (84, 151, 98), (71, 173, 121), (59, 196, 144), + (0, 191, 201), (22, 206, 201), (45, 222, 202), (50, 185, 189), + (55, 149, 177), (77, 119, 160), (100, 90, 143), (79, 30, 119), + (109, 24, 53), (207, 110, 77), (202, 119, 97), (198, 128, 118), + (179, 80, 165), (160, 32, 213), (151, 33, 213), (142, 35, 213), + (128, 12, 222), (103, 8, 220), (79, 4, 219), (61, 5, 219), + (43, 7, 219), (35, 18, 220), (27, 30, 221), (47, 57, 217), + (41, 73, 234), (44, 84, 233), (44, 87, 235), (45, 91, 238), + (48, 90, 234), (51, 90, 230), (62, 95, 233), (74, 100, 236), + (101, 78, 220), (114, 68, 163), (127, 59, 106), (156, 104, 90), + (185, 149, 75), (152, 144, 94), (119, 139, 114), (77, 141, 125), + (58, 151, 141), (77, 150, 218), (99, 120, 219), (121, 91, 221), + (125, 79, 229), (130, 68, 237), (141, 65, 235), (149, 34, 223), + (183, 8, 223), (182, 13, 217), (182, 18, 211), (159, 74, 189), + (137, 131, 167), (144, 148, 171), (152, 166, 175), (183, 153, 153), + (167, 164, 147), (107, 177, 153), (98, 170, 171), (89, 163, 190), + (90, 162, 196), (92, 161, 203), (114, 181, 200), (157, 146, 225), + (142, 91, 232), (146, 98, 195), (150, 106, 159), (147, 117, 144), + (145, 129, 129), (146, 154, 113), (185, 150, 112), (176, 163, 93), + (128, 171, 102), (56, 203, 99), (62, 199, 76), (69, 196, 53), + (76, 210, 60), (83, 224, 67), (103, 211, 50), (169, 156, 2), + (222, 50, 40), (167, 38, 111), (112, 27, 182), (111, 36, 192), + (111, 46, 202), (60, 87, 216), (66, 128, 201), (89, 136, 214), + (103, 158, 188), (189, 148, 126), (195, 153, 131), (201, 159, 137), + (224, 157, 130), (215, 138, 118), (204, 132, 118), (223, 138, 97), + (220, 146, 37), (224, 109, 44), (228, 73, 51), (216, 77, 41), + (204, 82, 31), (146, 84, 87), (132, 79, 147), (106, 60, 169), + (104, 77, 220), (57, 99, 199), (61, 96, 196), (66, 94, 194), + (73, 80, 152), (78, 50, 135), (156, 19, 91), (191, 26, 105), + (236, 2, 115), (223, 11, 124), (211, 20, 133), (186, 17, 127), + (162, 15, 121), (165, 14, 109), (199, 11, 108), (194, 8, 119), + (164, 23, 135), (129, 6, 221), (113, 17, 224), (97, 29, 228), + (70, 22, 222), (71, 12, 218), (84, 27, 217), (102, 43, 219), + (197, 123, 112), (207, 127, 88), (218, 131, 64), (185, 174, 33), + (232, 151, 59), (227, 167, 105), (171, 177, 165), (107, 208, 202), + (98, 229, 239), (49, 228, 232), (48, 229, 227), (47, 231, 223), + (46, 229, 233), (49, 235, 234), (43, 242, 209), (29, 223, 223), + (20, 100, 241), (31, 99, 238), (42, 98, 235), (45, 81, 231), + (60, 68, 228), (67, 59, 220), (70, 34, 218), (52, 22, 204), + (60, 14, 226), (86, 36, 223), (79, 72, 228), (96, 102, 222), + (125, 134, 175), (150, 124, 127), (107, 76, 133), (134, 29, 113), + (164, 69, 137), (150, 89, 156), (136, 110, 175), (116, 129, 199), + (83, 160, 216), (86, 191, 212), (54, 201, 217), (57, 199, 209), + (48, 141, 175), (51, 119, 154), (38, 45, 133), (37, 10, 139), + (59, 59, 155), (70, 95, 187), (80, 137, 227), (77, 115, 226), + (58, 91, 222), (48, 91, 222), (54, 110, 219), (50, 120, 231), + (44, 146, 231), (47, 195, 231), (43, 216, 188), (45, 196, 179), + (74, 173, 129), (63, 131, 74), (87, 137, 74), (119, 93, 78), + (117, 90, 61), (102, 86, 73), (118, 105, 112), (83, 130, 136), + (109, 106, 223), (139, 99, 224), (137, 108, 226), (137, 123, 221), + (122, 144, 219), (94, 201, 209), (80, 215, 219), (60, 217, 236), + (45, 204, 236), (42, 196, 234), (60, 154, 218), (71, 108, 223), + (79, 47, 220), (102, 32, 218), (113, 55, 225), (134, 86, 206), + (173, 118, 137), (194, 137, 120), (203, 142, 137), (160, 135, 174), + (166, 156, 225), (145, 152, 222), (123, 105, 239), (93, 109, 230), + (97, 106, 235), (125, 103, 237), (140, 85, 231), (144, 84, 232), + (134, 74, 232), (147, 74, 241), (148, 76, 238), (147, 69, 231), + (130, 50, 223), (128, 39, 193), (150, 19, 151), (167, 21, 86), + (203, 48, 43), (171, 49, 0), (144, 84, 21), (45, 214, 61) + ), + +// 343 4u0009b.jpg +((28, 89, 30), (31, 44, 27), (27, 62, 21), (24, 80, 15), + (32, 85, 20), (41, 90, 25), (33, 87, 29), (25, 85, 33), + (19, 69, 6), (20, 71, 3), (21, 73, 1), (15, 79, 2), + (9, 86, 4), (5, 91, 14), (1, 97, 25), (6, 100, 26), + (11, 103, 28), (4, 88, 54), (21, 95, 57), (38, 103, 60), + (39, 107, 69), (40, 111, 79), (38, 114, 82), (37, 118, 86), + (41, 132, 115), (54, 137, 122), (68, 142, 129), (85, 146, 128), + (103, 151, 127), (116, 162, 137), (129, 173, 148), (150, 186, 158), + (155, 179, 155), (139, 169, 135), (124, 156, 129), (110, 143, 124), + (101, 142, 119), (92, 142, 115), (88, 141, 116), (85, 140, 117), + (57, 139, 127), (67, 153, 138), (77, 168, 150), (72, 160, 147), + (67, 153, 144), (63, 151, 142), (59, 149, 140), (52, 142, 130), + (42, 140, 127), (38, 117, 88), (42, 119, 90), (47, 122, 92), + (60, 132, 108), (74, 143, 125), (83, 153, 137), (92, 163, 149), + (155, 205, 194), (169, 212, 203), (184, 219, 213), (172, 226, 218), + (160, 233, 224), (154, 232, 223), (148, 231, 223), (178, 234, 223), + (204, 238, 240), (209, 228, 234), (190, 219, 221), (172, 211, 208), + (167, 204, 200), (162, 197, 193), (151, 182, 164), (149, 172, 146), + (114, 158, 122), (102, 147, 111), (90, 136, 100), (90, 136, 100), + (90, 136, 100), (88, 142, 100), (86, 148, 101), (86, 154, 97), + (88, 152, 92), (105, 143, 94), (104, 144, 104), (104, 145, 115), + (111, 150, 118), (119, 156, 122), (123, 160, 129), (108, 154, 128), + (83, 138, 115), (69, 138, 106), (56, 139, 97), (58, 129, 92), + (60, 119, 87), (46, 107, 74), (40, 103, 60), (35, 103, 54), + (34, 117, 49), (34, 131, 114), (47, 139, 126), (61, 148, 139), + (70, 157, 144), (79, 166, 149), (93, 176, 148), (107, 182, 149), + (120, 191, 159), (118, 189, 158), (116, 187, 157), (112, 185, 159), + (109, 184, 161), (104, 178, 145), (102, 174, 137), (104, 178, 141), + (113, 178, 146), (121, 163, 143), (123, 164, 143), (126, 165, 144), + (125, 164, 137), (110, 153, 125), (98, 149, 118), (94, 147, 127), + (116, 184, 147), (133, 199, 171), (150, 215, 195), (153, 221, 205), + (157, 227, 216), (147, 219, 207), (129, 202, 182), (133, 197, 162), + (125, 190, 150), (110, 168, 120), (104, 165, 114), (98, 163, 109), + (83, 156, 101), (82, 146, 96), (81, 148, 95), (73, 141, 80), + (37, 108, 42), (42, 105, 44), (47, 102, 47), (54, 108, 52), + (61, 114, 58), (61, 113, 65), (68, 120, 81), (79, 129, 94), + (76, 139, 110), (47, 123, 95), (37, 115, 83), (27, 107, 72), + (20, 102, 66), (22, 91, 60), (20, 92, 52), (46, 105, 57), + (79, 121, 73), (83, 122, 68), (88, 124, 63), (77, 136, 68), + (73, 132, 68), (66, 122, 51), (64, 123, 57), (63, 119, 80), + (52, 125, 96), (68, 144, 132), (77, 149, 141), (86, 155, 150), + (109, 164, 159), (119, 174, 177), (124, 175, 176), (130, 177, 169), + (124, 174, 171), (119, 174, 173), (115, 175, 175), (99, 167, 166), + (95, 164, 161), (80, 155, 150), (76, 149, 142), (63, 147, 134), + (51, 141, 129), (63, 137, 120), (75, 139, 104), (77, 139, 102), + (81, 131, 94), (83, 131, 81), (72, 121, 55), (48, 103, 48), + (57, 94, 25), (52, 97, 36), (48, 101, 47), (52, 114, 75), + (75, 129, 93), (83, 151, 104), (106, 164, 114), (123, 167, 150), + (140, 183, 176), (154, 196, 195), (165, 202, 208), (169, 210, 202), + (171, 214, 195), (175, 220, 197), (169, 211, 201), (151, 206, 177), + (134, 204, 178), (126, 199, 172), (126, 197, 167), (133, 194, 163), + (134, 181, 171), (133, 180, 174), (135, 180, 173), (137, 186, 165), + (153, 192, 163), (162, 192, 166), (170, 206, 178), (152, 189, 182), + (156, 195, 164), (154, 186, 162), (139, 174, 154), (140, 174, 149), + (135, 169, 144), (135, 167, 146), (126, 165, 144), (108, 167, 147), + (103, 170, 137), (100, 173, 144), (88, 159, 155), (84, 154, 146), + (78, 147, 126), (89, 142, 122), (84, 143, 115), (90, 146, 117), + (100, 149, 119), (104, 148, 133), (106, 163, 144), (115, 170, 164), + (120, 174, 174), (129, 179, 176), (133, 185, 183), (136, 195, 163), + (132, 193, 159), (134, 191, 158), (135, 178, 169), (133, 173, 162), + (121, 181, 153), (118, 186, 149), (118, 189, 157), (115, 191, 165), + (100, 191, 176), (103, 169, 167), (99, 165, 163), (86, 172, 147), + (87, 174, 140), (90, 168, 128), (94, 166, 116), (87, 151, 117), + (79, 136, 117), (56, 131, 111), (14, 107, 76), (28, 118, 93) + ), + +// 344 4u0010.jpg +((59, 175, 174), (32, 163, 173), (46, 171, 173), (61, 180, 174), + (117, 181, 159), (174, 182, 145), (165, 156, 98), (156, 131, 51), + (224, 97, 44), (205, 59, 59), (186, 22, 75), (180, 14, 84), + (174, 6, 94), (178, 28, 110), (182, 50, 126), (177, 60, 149), + (172, 71, 173), (95, 106, 185), (73, 89, 178), (52, 72, 171), + (65, 47, 124), (79, 22, 77), (82, 42, 87), (86, 62, 98), + (20, 103, 143), (18, 97, 160), (17, 91, 178), (11, 82, 179), + (5, 73, 180), (11, 65, 172), (17, 58, 164), (26, 45, 140), + (48, 51, 166), (47, 66, 168), (78, 93, 176), (109, 120, 184), + (143, 113, 184), (178, 107, 185), (160, 78, 174), (143, 50, 164), + (90, 54, 152), (67, 74, 163), (44, 95, 174), (31, 138, 163), + (18, 181, 152), (13, 197, 148), (8, 213, 144), (39, 144, 130), + (61, 103, 127), (50, 81, 187), (44, 111, 210), (38, 141, 234), + (42, 136, 232), (46, 132, 231), (44, 119, 208), (43, 106, 186), + (16, 97, 186), (22, 84, 181), (29, 72, 177), (35, 81, 180), + (42, 91, 183), (45, 96, 179), (48, 102, 176), (54, 106, 181), + (41, 105, 179), (12, 110, 207), (34, 108, 204), (56, 106, 201), + (75, 114, 205), (95, 122, 209), (147, 135, 199), (179, 151, 192), + (174, 147, 190), (146, 106, 196), (119, 65, 202), (103, 51, 202), + (88, 37, 202), (88, 25, 198), (88, 13, 194), (96, 6, 199), + (78, 7, 205), (97, 23, 204), (112, 21, 219), (128, 19, 234), + (147, 11, 237), (166, 3, 240), (189, 8, 247), (168, 32, 228), + (135, 69, 195), (116, 84, 195), (97, 100, 195), (98, 86, 194), + (100, 72, 193), (81, 53, 172), (68, 53, 170), (56, 41, 168), + (50, 52, 187), (50, 85, 201), (33, 79, 191), (16, 74, 181), + (24, 60, 181), (32, 46, 181), (45, 35, 157), (55, 41, 176), + (51, 114, 185), (45, 136, 185), (40, 158, 186), (48, 146, 179), + (56, 134, 173), (77, 91, 196), (67, 75, 174), (49, 62, 192), + (33, 51, 197), (75, 12, 241), (79, 21, 243), (83, 30, 245), + (103, 54, 242), (107, 22, 201), (106, 23, 177), (110, 8, 110), + (135, 6, 96), (173, 5, 89), (212, 5, 83), (215, 5, 84), + (219, 6, 86), (211, 10, 78), (201, 22, 90), (203, 25, 121), + (222, 52, 115), (206, 84, 135), (191, 99, 146), (176, 115, 157), + (176, 137, 194), (157, 125, 188), (130, 82, 182), (117, 46, 148), + (65, 4, 107), (104, 10, 89), (144, 17, 72), (150, 17, 75), + (157, 17, 78), (135, 56, 101), (121, 32, 114), (116, 24, 125), + (105, 41, 155), (103, 51, 162), (88, 59, 166), (74, 67, 171), + (52, 81, 181), (56, 87, 195), (40, 65, 183), (37, 79, 177), + (34, 86, 222), (40, 95, 233), (47, 104, 245), (69, 96, 239), + (76, 52, 200), (78, 18, 202), (93, 19, 194), (109, 24, 190), + (134, 24, 211), (189, 15, 148), (176, 16, 132), (164, 18, 117), + (130, 26, 147), (137, 30, 162), (109, 36, 187), (114, 62, 207), + (112, 80, 207), (111, 74, 201), (111, 69, 195), (125, 67, 188), + (167, 96, 190), (177, 100, 202), (161, 105, 202), (170, 112, 189), + (189, 96, 167), (156, 56, 116), (170, 20, 84), (168, 5, 96), + (172, 16, 99), (146, 23, 127), (115, 40, 143), (105, 55, 150), + (65, 48, 178), (56, 45, 189), (47, 43, 200), (52, 17, 207), + (70, 23, 199), (69, 33, 191), (83, 23, 181), (57, 8, 151), + (56, 18, 139), (86, 22, 142), (86, 52, 162), (48, 31, 169), + (18, 9, 186), (18, 19, 205), (17, 18, 194), (22, 33, 183), + (28, 56, 189), (15, 60, 187), (1, 67, 179), (13, 30, 134), + (49, 33, 142), (92, 30, 129), (158, 30, 127), (201, 85, 134), + (220, 145, 105), (227, 166, 83), (225, 163, 90), (176, 171, 175), + (133, 184, 153), (90, 140, 189), (58, 146, 196), (57, 123, 209), + (58, 89, 197), (30, 95, 187), (30, 91, 182), (32, 61, 191), + (14, 75, 200), (26, 73, 251), (14, 26, 234), (46, 58, 206), + (82, 96, 203), (86, 102, 200), (61, 147, 180), (69, 166, 182), + (73, 149, 175), (83, 138, 192), (127, 116, 192), (157, 101, 200), + (134, 91, 206), (126, 101, 205), (102, 103, 196), (92, 117, 197), + (114, 132, 198), (135, 157, 198), (98, 158, 159), (60, 167, 137), + (97, 134, 142), (113, 70, 159), (144, 79, 61), (218, 113, 58), + (234, 127, 33), (218, 124, 60), (207, 143, 55), (217, 159, 60), + (228, 148, 77), (193, 70, 114), (178, 31, 111), (149, 81, 130), + (136, 119, 112), (91, 195, 108), (74, 230, 133), (13, 202, 134) + ), + +// 345 4u0011.jpg +((21, 14, 144), (4, 49, 130), (7, 53, 131), (10, 58, 132), + (16, 44, 143), (23, 31, 155), (23, 38, 151), (24, 46, 148), + (20, 66, 116), (22, 79, 97), (25, 93, 78), (62, 107, 67), + (100, 122, 57), (132, 101, 35), (164, 81, 13), (163, 79, 14), + (162, 78, 16), (147, 42, 13), (138, 29, 8), (130, 17, 3), + (109, 21, 22), (88, 25, 42), (82, 28, 46), (76, 31, 51), + (51, 20, 36), (68, 28, 30), (86, 36, 25), (121, 39, 15), + (157, 43, 6), (164, 44, 9), (172, 45, 12), (171, 64, 22), + (150, 52, 15), (73, 20, 16), (41, 33, 10), (9, 46, 5), + (20, 56, 9), (32, 67, 13), (56, 53, 13), (80, 40, 14), + (112, 51, 20), (119, 90, 33), (126, 130, 46), (105, 130, 36), + (85, 130, 27), (65, 109, 29), (45, 88, 32), (50, 111, 78), + (28, 97, 79), (35, 108, 97), (27, 97, 128), (19, 87, 160), + (20, 63, 168), (22, 40, 176), (23, 37, 174), (25, 34, 173), + (7, 71, 145), (12, 84, 107), (18, 98, 69), (26, 92, 57), + (35, 86, 45), (43, 89, 26), (51, 93, 7), (83, 122, 3), + (50, 160, 27), (66, 152, 15), (70, 150, 10), (74, 149, 5), + (100, 179, 15), (126, 210, 26), (151, 196, 69), (162, 207, 80), + (110, 105, 101), (94, 90, 111), (78, 75, 122), (78, 72, 117), + (78, 69, 112), (80, 60, 115), (82, 51, 119), (66, 44, 119), + (59, 39, 138), (42, 39, 152), (33, 32, 161), (24, 26, 171), + (22, 21, 168), (20, 16, 165), (11, 28, 158), (21, 24, 155), + (17, 9, 130), (30, 7, 115), (43, 6, 101), (50, 3, 85), + (57, 0, 69), (40, 2, 41), (29, 17, 31), (35, 28, 44), + (65, 24, 40), (40, 25, 90), (39, 28, 113), (38, 31, 137), + (73, 19, 134), (109, 7, 132), (139, 21, 117), (199, 29, 58), + (201, 26, 31), (187, 34, 23), (174, 43, 15), (172, 42, 17), + (170, 41, 19), (131, 36, 44), (98, 70, 58), (81, 70, 100), + (62, 60, 107), (14, 25, 133), (12, 16, 132), (10, 8, 131), + (0, 5, 155), (15, 13, 184), (19, 26, 176), (24, 34, 157), + (52, 51, 111), (70, 44, 73), (88, 37, 36), (103, 41, 28), + (119, 45, 20), (170, 51, 17), (170, 50, 13), (183, 53, 3), + (200, 59, 13), (182, 72, 21), (176, 75, 13), (170, 79, 6), + (142, 110, 7), (101, 150, 7), (132, 170, 5), (131, 152, 13), + (174, 106, 25), (189, 90, 28), (205, 74, 32), (201, 59, 20), + (197, 45, 8), (173, 0, 2), (191, 22, 3), (204, 41, 6), + (199, 50, 7), (218, 147, 21), (196, 141, 27), (175, 136, 33), + (172, 172, 22), (144, 143, 17), (134, 105, 47), (130, 88, 90), + (170, 11, 140), (156, 14, 141), (143, 17, 143), (126, 25, 147), + (118, 28, 128), (96, 39, 94), (74, 41, 52), (75, 41, 39), + (53, 43, 16), (39, 45, 11), (32, 36, 12), (25, 27, 14), + (19, 30, 32), (24, 13, 30), (22, 6, 81), (8, 36, 86), + (17, 58, 148), (13, 58, 151), (9, 59, 154), (17, 101, 147), + (40, 126, 113), (84, 167, 33), (136, 159, 17), (168, 200, 57), + (185, 150, 34), (167, 110, 39), (164, 73, 16), (149, 38, 21), + (130, 16, 6), (107, 29, 25), (93, 37, 36), (90, 54, 42), + (73, 37, 98), (58, 30, 95), (44, 24, 93), (20, 17, 104), + (24, 27, 120), (30, 29, 123), (18, 31, 135), (35, 44, 135), + (34, 30, 150), (24, 30, 150), (29, 10, 136), (29, 17, 129), + (49, 34, 137), (61, 9, 143), (83, 24, 144), (114, 44, 116), + (136, 36, 48), (102, 40, 43), (101, 41, 41), (98, 33, 57), + (78, 37, 67), (58, 13, 80), (50, 5, 106), (37, 12, 96), + (48, 3, 86), (63, 6, 74), (56, 15, 83), (61, 26, 92), + (70, 36, 110), (55, 42, 114), (42, 58, 136), (35, 69, 132), + (43, 75, 152), (23, 89, 176), (7, 100, 195), (22, 77, 170), + (23, 58, 162), (16, 52, 162), (32, 52, 164), (40, 42, 155), + (60, 55, 149), (106, 23, 131), (128, 59, 150), (139, 59, 144), + (127, 89, 80), (132, 55, 25), (119, 50, 19), (107, 40, 34), + (83, 24, 52), (58, 30, 89), (49, 56, 108), (24, 64, 89), + (17, 49, 110), (25, 30, 96), (25, 10, 111), (20, 1, 126), + (21, 2, 128), (32, 16, 148), (22, 30, 154), (17, 47, 133), + (11, 45, 109), (10, 44, 72), (43, 32, 62), (53, 39, 54), + (46, 38, 77), (29, 60, 115), (25, 75, 110), (19, 77, 150), + (18, 111, 170), (19, 114, 182), (13, 103, 166), (18, 80, 157) + ), + +// 346 4u0012.jpg +((69, 55, 153), (50, 63, 141), (26, 70, 140), (3, 77, 140), + (13, 69, 146), (24, 61, 152), (35, 54, 158), (47, 48, 164), + (94, 44, 131), (83, 29, 115), (73, 15, 99), (56, 13, 97), + (40, 12, 96), (44, 24, 77), (48, 36, 58), (56, 31, 68), + (65, 27, 78), (80, 21, 77), (96, 16, 79), (113, 12, 82), + (111, 15, 110), (109, 18, 139), (102, 15, 147), (96, 13, 155), + (108, 31, 187), (108, 35, 170), (108, 40, 153), (107, 43, 185), + (106, 47, 217), (107, 59, 223), (108, 71, 229), (102, 70, 213), + (69, 69, 219), (63, 35, 207), (65, 32, 201), (67, 30, 195), + (58, 36, 192), (50, 42, 189), (57, 44, 187), (64, 47, 185), + (37, 40, 153), (54, 31, 142), (71, 22, 131), (79, 12, 127), + (87, 3, 124), (86, 3, 128), (86, 4, 132), (63, 17, 149), + (46, 10, 134), (65, 10, 101), (74, 6, 90), (84, 3, 79), + (79, 35, 72), (75, 67, 65), (64, 56, 67), (53, 45, 69), + (17, 58, 124), (25, 81, 149), (34, 104, 174), (73, 110, 199), + (112, 116, 224), (117, 123, 217), (122, 131, 210), (110, 117, 198), + (101, 96, 180), (66, 44, 181), (60, 29, 183), (54, 15, 186), + (56, 11, 188), (58, 8, 191), (60, 18, 166), (52, 19, 136), + (30, 16, 77), (25, 11, 70), (20, 7, 63), (17, 11, 63), + (15, 16, 64), (16, 17, 71), (17, 19, 78), (31, 38, 67), + (31, 55, 67), (12, 66, 113), (13, 60, 125), (14, 55, 137), + (18, 55, 150), (23, 56, 163), (48, 93, 186), (55, 113, 220), + (36, 114, 212), (33, 105, 217), (31, 96, 222), (30, 82, 219), + (29, 69, 216), (59, 26, 203), (64, 26, 199), (63, 19, 192), + (52, 40, 186), (24, 86, 161), (23, 100, 161), (23, 115, 162), + (31, 131, 184), (39, 148, 207), (72, 161, 221), (104, 173, 215), + (78, 148, 234), (64, 132, 216), (51, 116, 198), (39, 113, 176), + (28, 111, 155), (22, 104, 142), (6, 130, 182), (10, 140, 216), + (16, 135, 227), (44, 151, 223), (55, 138, 221), (66, 125, 219), + (71, 89, 171), (98, 63, 147), (100, 60, 113), (88, 44, 103), + (38, 45, 125), (29, 36, 127), (20, 28, 129), (10, 33, 124), + (0, 38, 120), (0, 16, 119), (0, 20, 111), (4, 33, 109), + (7, 47, 132), (16, 118, 133), (15, 112, 127), (14, 106, 121), + (27, 82, 138), (38, 62, 168), (50, 66, 164), (55, 90, 194), + (33, 108, 209), (18, 111, 184), (3, 114, 159), (6, 103, 150), + (10, 92, 142), (4, 58, 120), (4, 38, 109), (12, 30, 106), + (27, 22, 114), (60, 3, 160), (66, 6, 173), (73, 10, 187), + (56, 8, 182), (41, 16, 136), (31, 9, 107), (17, 8, 101), + (19, 14, 117), (17, 14, 114), (15, 15, 111), (7, 17, 102), + (11, 18, 99), (5, 2, 91), (3, 30, 77), (11, 28, 84), + (15, 34, 103), (23, 53, 143), (22, 58, 161), (22, 63, 179), + (50, 47, 186), (50, 49, 185), (65, 70, 174), (77, 43, 153), + (67, 18, 99), (69, 14, 88), (72, 10, 77), (75, 10, 74), + (63, 10, 66), (65, 24, 80), (34, 19, 100), (21, 24, 105), + (17, 24, 105), (27, 28, 92), (33, 22, 91), (25, 16, 83), + (16, 8, 91), (26, 12, 100), (36, 17, 96), (37, 23, 108), + (60, 21, 138), (53, 27, 143), (47, 34, 148), (34, 34, 134), + (20, 16, 136), (21, 49, 148), (10, 96, 145), (4, 112, 158), + (31, 137, 215), (68, 160, 235), (75, 147, 221), (63, 117, 217), + (97, 79, 225), (96, 107, 231), (109, 119, 240), (115, 138, 214), + (112, 140, 214), (114, 153, 210), (115, 160, 219), (109, 160, 203), + (109, 173, 211), (109, 170, 214), (110, 151, 207), (105, 147, 195), + (109, 128, 197), (119, 107, 193), (118, 58, 192), (110, 50, 164), + (95, 57, 160), (68, 76, 149), (49, 88, 165), (12, 95, 149), + (3, 95, 146), (11, 94, 144), (12, 56, 151), (22, 30, 175), + (53, 15, 180), (70, 16, 188), (89, 29, 213), (106, 26, 209), + (104, 11, 206), (101, 11, 205), (82, 21, 236), (83, 6, 234), + (70, 3, 223), (69, 16, 210), (86, 7, 186), (94, 6, 178), + (76, 14, 157), (114, 7, 147), (113, 14, 140), (94, 10, 88), + (62, 4, 65), (66, 2, 52), (59, 5, 54), (54, 12, 62), + (64, 7, 75), (72, 12, 108), (98, 7, 128), (110, 16, 140), + (89, 34, 138), (76, 43, 148), (53, 53, 151), (34, 44, 141), + (23, 53, 125), (30, 37, 125), (32, 42, 131), (34, 48, 153), + (47, 67, 164), (81, 81, 167), (111, 118, 208), (113, 105, 208) + ), + +// 347 4u0013.jpg +((123, 95, 81), (157, 143, 46), (173, 172, 56), (189, 201, 67), + (179, 195, 99), (170, 190, 131), (166, 190, 108), (163, 190, 85), + (176, 180, 43), (180, 173, 35), (184, 167, 27), (178, 157, 20), + (172, 148, 14), (165, 135, 20), (158, 122, 26), (158, 111, 30), + (158, 101, 34), (117, 85, 74), (97, 55, 72), (78, 25, 71), + (59, 15, 83), (41, 6, 96), (24, 26, 95), (8, 46, 95), + (44, 104, 105), (55, 109, 100), (66, 115, 96), (97, 101, 82), + (128, 87, 69), (135, 84, 75), (142, 82, 81), (129, 103, 76), + (117, 118, 86), (129, 154, 99), (141, 136, 90), (153, 119, 82), + (138, 98, 63), (123, 78, 45), (118, 77, 39), (114, 77, 33), + (84, 67, 24), (96, 73, 25), (109, 79, 27), (112, 83, 37), + (116, 88, 48), (124, 92, 39), (132, 97, 31), (154, 103, 37), + (158, 100, 37), (155, 110, 9), (158, 126, 19), (162, 142, 29), + (168, 154, 39), (174, 167, 50), (176, 170, 49), (178, 174, 48), + (187, 181, 45), (188, 185, 43), (190, 190, 42), (192, 196, 54), + (195, 203, 66), (197, 198, 73), (200, 194, 80), (188, 217, 91), + (175, 210, 110), (163, 226, 112), (166, 224, 104), (170, 222, 96), + (186, 223, 94), (202, 225, 93), (208, 221, 79), (208, 219, 78), + (198, 199, 59), (195, 191, 47), (193, 183, 36), (183, 161, 36), + (174, 139, 37), (167, 128, 38), (160, 117, 39), (147, 106, 60), + (132, 83, 50), (137, 67, 41), (139, 70, 51), (142, 74, 61), + (145, 75, 56), (148, 76, 52), (143, 78, 46), (140, 85, 31), + (134, 82, 0), (129, 86, 0), (125, 91, 0), (122, 87, 0), + (119, 83, 0), (113, 76, 5), (121, 65, 6), (134, 78, 3), + (141, 99, 13), (173, 145, 2), (178, 156, 11), (183, 167, 20), + (174, 165, 22), (165, 164, 24), (175, 149, 26), (173, 148, 29), + (148, 121, 4), (135, 108, 4), (123, 96, 5), (123, 91, 16), + (123, 87, 27), (115, 82, 37), (127, 81, 22), (148, 101, 31), + (160, 128, 25), (188, 178, 44), (191, 185, 46), (195, 192, 49), + (194, 207, 65), (195, 214, 72), (202, 211, 70), (201, 204, 65), + (216, 206, 72), (205, 211, 77), (194, 216, 82), (176, 210, 86), + (158, 205, 91), (132, 194, 109), (109, 173, 138), (66, 159, 149), + (71, 171, 99), (96, 134, 93), (85, 135, 78), (74, 136, 63), + (102, 117, 36), (112, 112, 26), (124, 96, 22), (151, 109, 11), + (171, 134, 2), (175, 145, 8), (180, 157, 15), (173, 157, 24), + (167, 157, 33), (166, 164, 55), (160, 172, 64), (150, 173, 65), + (136, 166, 70), (124, 154, 64), (133, 163, 68), (143, 173, 73), + (168, 196, 75), (157, 209, 85), (162, 217, 87), (158, 217, 89), + (158, 211, 97), (150, 197, 93), (143, 184, 90), (129, 160, 90), + (125, 132, 65), (133, 106, 27), (144, 105, 30), (144, 111, 40), + (152, 99, 45), (159, 123, 39), (151, 131, 35), (143, 139, 32), + (116, 125, 42), (124, 112, 36), (106, 96, 34), (77, 89, 27), + (95, 59, 11), (92, 59, 5), (89, 59, 0), (98, 66, 0), + (119, 56, 0), (124, 76, 14), (126, 83, 15), (105, 76, 16), + (70, 53, 9), (61, 20, 24), (71, 26, 67), (36, 36, 98), + (3, 50, 104), (22, 83, 78), (50, 50, 26), (66, 62, 25), + (82, 82, 20), (97, 86, 22), (112, 91, 24), (126, 98, 24), + (120, 110, 23), (105, 118, 36), (98, 116, 40), (102, 128, 63), + (107, 128, 53), (128, 139, 37), (124, 130, 22), (145, 116, 24), + (149, 108, 18), (142, 104, 21), (130, 96, 32), (112, 98, 59), + (71, 81, 70), (54, 104, 92), (56, 124, 73), (45, 116, 102), + (35, 110, 90), (4, 77, 96), (3, 46, 91), (11, 40, 80), + (43, 11, 74), (35, 41, 37), (12, 58, 47), (9, 23, 23), + (43, 13, 13), (48, 42, 10), (59, 58, 1), (63, 57, 21), + (86, 56, 32), (98, 64, 37), (104, 76, 26), (106, 86, 25), + (100, 113, 7), (100, 124, 2), (132, 167, 21), (159, 174, 47), + (181, 201, 68), (168, 215, 85), (166, 218, 94), (168, 220, 96), + (166, 217, 86), (182, 203, 74), (189, 203, 64), (185, 188, 55), + (174, 168, 30), (177, 140, 10), (160, 110, 11), (146, 96, 23), + (131, 72, 38), (125, 56, 41), (109, 68, 48), (121, 74, 46), + (123, 72, 45), (135, 83, 70), (123, 103, 79), (108, 122, 86), + (112, 147, 83), (131, 165, 81), (140, 171, 95), (145, 193, 94), + (134, 220, 109), (130, 184, 108), (112, 192, 95), (110, 163, 107), + (121, 157, 87), (132, 159, 88), (191, 140, 61), (160, 152, 71) + ), + +// 348 4u0019.jpg +((147, 37, 36), (156, 76, 15), (148, 97, 14), (141, 118, 14), + (134, 89, 7), (127, 61, 0), (134, 67, 2), (142, 73, 4), + (140, 115, 31), (117, 134, 66), (94, 154, 102), (84, 156, 107), + (75, 158, 112), (81, 155, 116), (88, 153, 121), (88, 153, 120), + (89, 153, 119), (158, 80, 67), (157, 73, 48), (157, 67, 30), + (136, 95, 45), (115, 124, 61), (107, 130, 64), (99, 136, 67), + (111, 145, 95), (137, 137, 67), (164, 130, 40), (165, 96, 24), + (166, 62, 9), (171, 64, 11), (177, 67, 14), (180, 85, 27), + (162, 102, 52), (123, 128, 87), (112, 115, 104), (101, 102, 122), + (74, 90, 127), (48, 79, 133), (40, 74, 140), (32, 69, 147), + (23, 123, 159), (26, 135, 165), (29, 148, 172), (43, 154, 185), + (57, 161, 198), (64, 141, 180), (72, 121, 162), (91, 115, 125), + (101, 92, 93), (147, 21, 24), (146, 13, 19), (146, 6, 15), + (144, 14, 9), (143, 22, 3), (141, 28, 2), (139, 34, 2), + (126, 26, 24), (128, 23, 21), (130, 20, 19), (133, 20, 11), + (136, 21, 3), (140, 23, 2), (145, 25, 1), (138, 23, 0), + (124, 24, 1), (136, 43, 12), (147, 45, 9), (159, 47, 7), + (153, 40, 5), (147, 34, 4), (146, 31, 4), (138, 23, 4), + (105, 3, 16), (89, 4, 18), (74, 6, 21), (40, 3, 22), + (6, 1, 24), (3, 0, 27), (0, 0, 30), (2, 26, 28), + (29, 38, 47), (51, 50, 45), (37, 40, 35), (24, 30, 26), + (22, 23, 28), (21, 17, 31), (3, 14, 32), (13, 22, 21), + (87, 42, 37), (115, 57, 28), (144, 73, 19), (150, 80, 19), + (156, 87, 20), (149, 92, 5), (149, 94, 3), (136, 77, 7), + (150, 71, 12), (158, 85, 6), (157, 76, 10), (157, 67, 15), + (160, 59, 13), (164, 52, 12), (145, 43, 28), (129, 43, 26), + (91, 43, 59), (71, 55, 85), (51, 68, 111), (55, 63, 105), + (60, 59, 99), (86, 58, 83), (103, 70, 65), (128, 69, 53), + (139, 58, 57), (144, 65, 34), (132, 72, 35), (121, 79, 37), + (96, 68, 21), (115, 81, 33), (107, 71, 73), (107, 96, 92), + (150, 94, 67), (168, 81, 55), (187, 68, 44), (182, 61, 41), + (177, 54, 38), (165, 55, 18), (156, 49, 13), (131, 55, 3), + (100, 43, 23), (20, 14, 52), (18, 12, 54), (17, 11, 57), + (24, 12, 58), (22, 23, 69), (37, 30, 71), (67, 67, 79), + (62, 141, 110), (89, 131, 98), (117, 121, 86), (112, 109, 81), + (108, 97, 77), (108, 77, 57), (102, 55, 47), (73, 37, 49), + (57, 36, 93), (29, 33, 96), (26, 36, 90), (23, 40, 84), + (22, 30, 77), (70, 49, 64), (97, 63, 53), (117, 40, 46), + (141, 46, 26), (141, 50, 28), (142, 54, 30), (140, 53, 26), + (145, 60, 6), (139, 55, 9), (135, 48, 20), (138, 41, 24), + (127, 50, 30), (112, 37, 41), (116, 38, 38), (121, 40, 36), + (124, 42, 21), (122, 26, 27), (129, 5, 15), (119, 7, 19), + (81, 14, 6), (64, 15, 6), (47, 17, 6), (57, 38, 23), + (67, 34, 15), (90, 46, 21), (112, 56, 0), (133, 56, 2), + (139, 49, 0), (142, 50, 1), (154, 33, 6), (150, 25, 7), + (142, 18, 8), (137, 17, 16), (136, 19, 25), (139, 17, 32), + (117, 59, 107), (100, 76, 103), (84, 93, 100), (72, 142, 118), + (46, 122, 146), (6, 86, 159), (19, 82, 135), (28, 71, 88), + (22, 62, 87), (31, 41, 68), (39, 57, 71), (51, 65, 78), + (64, 74, 99), (61, 96, 116), (58, 112, 124), (85, 103, 115), + (121, 97, 85), (155, 93, 56), (161, 46, 41), (169, 59, 22), + (184, 47, 13), (203, 25, 11), (161, 31, 9), (155, 42, 12), + (135, 31, 38), (117, 40, 56), (81, 65, 65), (81, 79, 90), + (60, 111, 115), (57, 115, 155), (28, 93, 135), (25, 40, 131), + (37, 37, 127), (88, 40, 116), (110, 45, 49), (108, 26, 30), + (105, 14, 21), (96, 9, 28), (84, 7, 25), (78, 18, 17), + (70, 22, 48), (49, 22, 63), (14, 31, 57), (12, 41, 83), + (11, 66, 105), (0, 138, 135), (5, 135, 185), (5, 134, 192), + (25, 146, 157), (3, 156, 135), (25, 159, 152), (36, 116, 167), + (55, 94, 159), (63, 70, 99), (68, 70, 69), (81, 62, 29), + (56, 39, 21), (25, 9, 9), (15, 21, 11), (44, 35, 6), + (78, 36, 0), (120, 27, 9), (147, 18, 22), (159, 20, 27), + (161, 4, 15), (147, 2, 9), (144, 16, 17), (138, 32, 10), + (135, 51, 7), (138, 66, 18), (143, 97, 37), (145, 92, 24) + ), + +// 349 4u0022.jpg +((112, 56, 57), (71, 75, 52), (84, 91, 62), (97, 107, 73), + (104, 87, 67), (112, 67, 61), (105, 56, 62), (99, 46, 64), + (75, 21, 34), (56, 25, 24), (38, 29, 14), (23, 34, 10), + (8, 39, 7), (25, 40, 3), (42, 41, 0), (53, 42, 7), + (64, 43, 14), (92, 34, 33), (103, 24, 27), (114, 14, 22), + (117, 30, 31), (120, 47, 41), (113, 54, 50), (107, 62, 59), + (115, 83, 70), (118, 111, 82), (121, 140, 95), (120, 112, 103), + (119, 85, 112), (123, 86, 115), (127, 88, 119), (150, 71, 92), + (182, 85, 104), (199, 104, 100), (182, 87, 89), (165, 70, 78), + (162, 57, 65), (160, 44, 53), (152, 33, 43), (145, 23, 34), + (75, 4, 2), (75, 9, 8), (76, 14, 15), (88, 24, 23), + (100, 35, 31), (105, 48, 25), (110, 61, 20), (119, 27, 28), + (122, 15, 33), (153, 15, 40), (143, 28, 48), (133, 42, 57), + (122, 62, 49), (112, 83, 41), (106, 81, 36), (100, 79, 32), + (77, 47, 9), (66, 54, 14), (55, 62, 20), (68, 68, 15), + (82, 74, 11), (95, 78, 30), (109, 83, 50), (139, 70, 63), + (159, 59, 71), (185, 32, 62), (176, 35, 72), (168, 38, 82), + (164, 38, 81), (161, 39, 80), (166, 46, 71), (154, 46, 59), + (113, 70, 28), (82, 71, 20), (52, 72, 13), (57, 78, 29), + (63, 84, 45), (67, 79, 48), (72, 74, 52), (101, 76, 54), + (129, 78, 61), (157, 66, 81), (167, 90, 86), (177, 115, 92), + (181, 152, 107), (186, 189, 122), (174, 218, 123), (160, 154, 96), + (168, 99, 84), (156, 88, 68), (144, 78, 52), (136, 58, 53), + (129, 38, 55), (116, 39, 49), (107, 22, 29), (115, 6, 12), + (114, 2, 16), (99, 4, 28), (94, 4, 29), (89, 5, 31), + (97, 6, 39), (105, 7, 48), (107, 12, 42), (114, 5, 37), + (123, 9, 9), (130, 16, 8), (137, 24, 8), (136, 18, 14), + (136, 12, 20), (138, 14, 24), (137, 13, 23), (131, 14, 23), + (132, 16, 25), (119, 11, 37), (127, 8, 42), (136, 5, 47), + (140, 10, 44), (129, 33, 71), (150, 40, 75), (134, 50, 65), + (116, 45, 77), (115, 26, 69), (114, 7, 61), (109, 5, 58), + (104, 4, 56), (97, 15, 51), (94, 15, 44), (86, 23, 40), + (93, 33, 41), (96, 48, 48), (88, 52, 42), (81, 56, 36), + (50, 61, 29), (27, 58, 17), (19, 64, 5), (6, 73, 4), + (24, 47, 29), (27, 26, 37), (31, 6, 45), (27, 8, 40), + (23, 11, 35), (14, 18, 19), (18, 21, 26), (49, 32, 22), + (69, 24, 18), (99, 8, 13), (101, 9, 10), (104, 10, 8), + (107, 6, 10), (127, 16, 22), (141, 14, 35), (153, 35, 49), + (147, 74, 67), (147, 88, 74), (147, 102, 81), (129, 152, 72), + (131, 141, 68), (116, 98, 62), (137, 76, 73), (149, 77, 81), + (161, 96, 78), (155, 89, 73), (143, 81, 81), (132, 74, 89), + (117, 45, 82), (78, 63, 68), (58, 63, 40), (39, 21, 33), + (11, 8, 17), (7, 5, 16), (3, 2, 16), (7, 10, 19), + (19, 5, 20), (33, 21, 21), (45, 17, 31), (73, 8, 40), + (74, 7, 40), (66, 7, 37), (70, 22, 34), (72, 46, 55), + (82, 48, 36), (109, 37, 51), (112, 33, 62), (115, 17, 58), + (91, 13, 37), (84, 16, 39), (78, 19, 41), (59, 18, 34), + (50, 33, 25), (26, 62, 24), (12, 83, 43), (22, 70, 54), + (8, 40, 55), (35, 23, 45), (41, 15, 42), (33, 16, 50), + (43, 10, 67), (33, 3, 55), (46, 6, 43), (64, 6, 21), + (64, 7, 13), (65, 5, 17), (71, 5, 33), (75, 3, 43), + (72, 2, 54), (74, 15, 47), (72, 28, 45), (80, 36, 49), + (70, 33, 85), (67, 53, 88), (83, 87, 90), (76, 58, 82), + (94, 25, 82), (123, 17, 55), (125, 4, 58), (125, 5, 50), + (116, 10, 50), (112, 16, 44), (105, 23, 27), (103, 21, 25), + (94, 18, 28), (86, 17, 20), (88, 18, 16), (87, 29, 9), + (87, 30, 10), (81, 34, 4), (68, 35, 2), (60, 28, 13), + (52, 16, 4), (44, 24, 15), (36, 39, 10), (26, 41, 22), + (25, 33, 22), (50, 33, 26), (74, 20, 36), (87, 26, 44), + (94, 23, 55), (100, 16, 50), (97, 16, 33), (77, 15, 30), + (73, 26, 20), (77, 32, 11), (86, 48, 29), (122, 58, 48), + (128, 76, 55), (139, 74, 68), (126, 64, 53), (118, 48, 46), + (124, 31, 14), (114, 17, 0), (104, 15, 1), (104, 26, 14), + (100, 34, 22), (87, 39, 1), (70, 58, 0), (78, 47, 3) + ), + +// 350 k2u0217.jpg +((62, 139, 107), (12, 96, 96), (16, 109, 112), (20, 123, 128), + (77, 126, 147), (134, 130, 167), (187, 125, 178), (240, 121, 189), + (234, 89, 190), (174, 69, 198), (114, 50, 207), (96, 29, 157), + (79, 9, 108), (91, 10, 94), (103, 12, 81), (115, 12, 92), + (127, 12, 103), (233, 70, 117), (233, 68, 87), (234, 66, 57), + (233, 70, 68), (233, 74, 79), (201, 75, 91), (170, 76, 103), + (64, 24, 33), (37, 21, 16), (11, 18, 0), (5, 18, 1), + (0, 18, 2), (0, 16, 7), (0, 15, 12), (0, 2, 21), + (6, 6, 32), (42, 10, 93), (80, 12, 101), (118, 14, 109), + (170, 57, 138), (223, 100, 167), (231, 107, 176), (239, 115, 185), + (243, 144, 164), (241, 133, 148), (240, 123, 132), (235, 86, 85), + (231, 49, 38), (230, 48, 35), (230, 47, 33), (228, 44, 32), + (228, 20, 20), (77, 11, 38), (55, 5, 29), (34, 0, 21), + (24, 9, 11), (14, 18, 1), (8, 27, 2), (2, 37, 4), + (35, 138, 57), (92, 142, 101), (150, 146, 145), (195, 133, 160), + (240, 121, 175), (240, 120, 182), (241, 120, 189), (240, 108, 194), + (238, 99, 182), (233, 66, 156), (211, 45, 162), (190, 24, 168), + (170, 21, 155), (151, 18, 143), (115, 36, 128), (75, 32, 150), + (122, 122, 192), (176, 128, 217), (231, 135, 243), (240, 169, 241), + (250, 204, 240), (250, 205, 240), (250, 206, 241), (249, 205, 240), + (247, 189, 230), (242, 151, 212), (237, 94, 202), (233, 38, 192), + (231, 38, 193), (230, 39, 194), (202, 25, 194), (193, 28, 193), + (134, 16, 130), (110, 13, 106), (87, 10, 82), (75, 9, 75), + (63, 9, 69), (53, 9, 58), (65, 4, 63), (68, 14, 66), + (73, 10, 67), (88, 7, 63), (105, 14, 82), (123, 22, 102), + (142, 19, 119), (162, 17, 136), (220, 72, 124), (237, 98, 95), + (231, 65, 103), (232, 52, 122), (234, 39, 141), (232, 33, 144), + (231, 27, 148), (230, 28, 150), (231, 26, 155), (230, 28, 150), + (230, 29, 145), (233, 53, 186), (232, 60, 178), (232, 67, 171), + (235, 71, 166), (234, 76, 161), (248, 74, 145), (238, 93, 90), + (235, 86, 82), (203, 156, 72), (172, 227, 63), (165, 219, 51), + (158, 212, 40), (56, 117, 37), (84, 95, 55), (91, 12, 67), + (124, 11, 101), (200, 43, 174), (219, 70, 182), (239, 98, 190), + (242, 140, 203), (246, 166, 219), (248, 187, 229), (249, 192, 233), + (245, 171, 220), (244, 166, 205), (244, 161, 191), (245, 160, 190), + (246, 160, 189), (245, 159, 184), (247, 158, 186), (245, 156, 210), + (246, 179, 223), (244, 161, 215), (242, 150, 207), (241, 140, 200), + (234, 86, 180), (205, 43, 180), (159, 24, 144), (121, 14, 110), + (44, 17, 124), (39, 21, 101), (35, 26, 79), (43, 40, 51), + (42, 88, 42), (34, 103, 40), (32, 66, 42), (34, 22, 24), + (14, 22, 1), (5, 29, 29), (2, 27, 37), (0, 26, 46), + (2, 21, 79), (19, 11, 122), (14, 47, 142), (40, 27, 167), + (12, 84, 184), (20, 110, 196), (29, 136, 208), (16, 123, 179), + (35, 84, 142), (104, 32, 116), (132, 47, 150), (184, 21, 162), + (198, 21, 171), (230, 27, 168), (228, 34, 157), (230, 36, 159), + (232, 43, 172), (233, 56, 188), (238, 70, 215), (194, 71, 237), + (200, 33, 173), (184, 25, 159), (168, 17, 146), (127, 16, 108), + (122, 15, 97), (125, 11, 99), (126, 14, 114), (160, 26, 149), + (215, 52, 179), (239, 119, 193), (245, 167, 209), (248, 185, 228), + (244, 174, 224), (242, 151, 210), (238, 101, 183), (186, 47, 172), + (130, 37, 107), (73, 14, 60), (47, 7, 41), (34, 5, 35), + (35, 8, 25), (47, 33, 30), (36, 78, 12), (59, 87, 47), + (66, 43, 72), (66, 19, 71), (68, 19, 74), (102, 63, 110), + (67, 109, 97), (26, 74, 86), (4, 59, 79), (9, 60, 87), + (38, 12, 121), (48, 0, 106), (100, 21, 128), (159, 29, 151), + (199, 51, 171), (230, 100, 174), (240, 123, 191), (242, 142, 202), + (242, 153, 209), (242, 144, 203), (241, 124, 195), (238, 102, 178), + (235, 80, 174), (236, 79, 170), (236, 75, 169), (233, 71, 174), + (236, 67, 166), (234, 59, 152), (232, 55, 146), (233, 29, 160), + (218, 36, 155), (188, 21, 163), (127, 14, 118), (81, 11, 110), + (44, 20, 144), (21, 25, 148), (16, 46, 156), (16, 55, 150), + (31, 17, 114), (8, 28, 65), (10, 2, 17), (10, 0, 9), + (35, 1, 36), (47, 0, 60), (39, 13, 84), (37, 11, 72), + (5, 8, 59), (2, 13, 41), (11, 31, 56), (3, 86, 68) + ), + +// 351 ku0213.jpg +((50, 142, 0), (53, 168, 13), (108, 173, 6), (163, 179, 0), + (191, 158, 4), (219, 137, 9), (207, 134, 24), (195, 132, 39), + (184, 47, 127), (132, 51, 163), (81, 56, 200), (75, 61, 205), + (70, 67, 210), (62, 70, 203), (54, 74, 197), (64, 79, 171), + (75, 85, 146), (113, 71, 75), (97, 43, 104), (81, 16, 134), + (53, 8, 169), (25, 0, 204), (18, 0, 215), (12, 1, 227), + (57, 1, 184), (80, 8, 156), (104, 16, 128), (92, 20, 122), + (80, 25, 116), (78, 50, 118), (77, 76, 120), (39, 163, 137), + (63, 196, 105), (13, 226, 120), (6, 162, 165), (0, 99, 210), + (15, 100, 200), (30, 101, 191), (48, 94, 171), (67, 88, 151), + (108, 115, 47), (84, 82, 32), (60, 49, 17), (61, 50, 15), + (63, 51, 13), (92, 38, 16), (122, 25, 19), (171, 36, 43), + (182, 58, 56), (243, 14, 71), (249, 44, 53), (255, 74, 36), + (252, 116, 18), (249, 158, 0), (252, 139, 4), (255, 121, 9), + (238, 13, 0), (223, 24, 0), (209, 36, 0), (170, 45, 16), + (132, 54, 32), (122, 35, 51), (113, 16, 70), (107, 21, 30), + (83, 0, 29), (48, 0, 25), (43, 22, 27), (38, 45, 29), + (54, 49, 53), (71, 53, 77), (64, 41, 184), (71, 30, 228), + (56, 6, 243), (44, 3, 240), (33, 0, 238), (46, 15, 229), + (60, 31, 220), (66, 55, 225), (73, 80, 230), (29, 162, 218), + (106, 216, 207), (138, 201, 174), (138, 149, 182), (139, 98, 190), + (131, 89, 180), (123, 80, 170), (160, 83, 101), (178, 134, 87), + (189, 103, 80), (146, 87, 109), (103, 71, 138), (94, 62, 147), + (86, 53, 157), (58, 49, 194), (99, 63, 213), (121, 21, 239), + (127, 76, 207), (91, 36, 138), (78, 28, 111), (65, 21, 84), + (64, 17, 72), (63, 14, 61), (98, 4, 92), (130, 6, 76), + (174, 61, 67), (204, 113, 72), (235, 165, 77), (245, 185, 60), + (255, 206, 44), (234, 224, 49), (255, 253, 39), (235, 253, 9), + (240, 218, 34), (254, 181, 26), (253, 158, 23), (252, 135, 21), + (255, 75, 27), (251, 72, 32), (255, 46, 41), (248, 34, 36), + (206, 71, 67), (227, 47, 52), (248, 23, 37), (250, 13, 18), + (252, 3, 0), (254, 0, 8), (255, 4, 74), (243, 2, 81), + (209, 32, 112), (145, 100, 201), (127, 108, 216), (110, 117, 231), + (44, 184, 217), (32, 203, 187), (41, 254, 136), (66, 255, 129), + (74, 126, 209), (50, 92, 175), (26, 58, 141), (17, 51, 131), + (8, 44, 122), (4, 148, 157), (18, 234, 151), (1, 254, 145), + (1, 250, 160), (8, 192, 254), (4, 180, 251), (1, 168, 249), + (3, 198, 228), (1, 251, 162), (0, 255, 129), (11, 255, 134), + (38, 224, 97), (49, 235, 77), (61, 247, 58), (56, 253, 77), + (36, 234, 115), (52, 235, 142), (77, 218, 139), (122, 195, 106), + (118, 179, 135), (202, 74, 157), (197, 73, 134), (193, 73, 111), + (223, 76, 86), (218, 136, 80), (228, 137, 66), (220, 186, 50), + (193, 126, 81), (158, 95, 68), (123, 64, 56), (80, 21, 75), + (16, 0, 77), (1, 3, 86), (0, 10, 66), (13, 2, 6), + (31, 16, 23), (46, 33, 63), (0, 16, 117), (0, 0, 122), + (20, 11, 136), (44, 9, 151), (55, 6, 124), (59, 0, 78), + (138, 17, 88), (167, 28, 101), (197, 39, 114), (134, 43, 122), + (101, 81, 153), (70, 109, 200), (55, 103, 203), (32, 159, 255), + (12, 160, 248), (0, 182, 246), (27, 211, 219), (21, 214, 147), + (8, 180, 108), (28, 141, 95), (0, 80, 79), (0, 59, 105), + (0, 41, 116), (0, 0, 149), (8, 13, 191), (29, 27, 196), + (40, 94, 216), (47, 121, 252), (27, 160, 239), (29, 201, 187), + (13, 206, 115), (13, 191, 107), (30, 212, 68), (81, 244, 43), + (50, 224, 13), (30, 209, 4), (32, 202, 43), (79, 157, 81), + (129, 155, 84), (149, 206, 99), (176, 180, 95), (247, 213, 64), + (247, 188, 22), (243, 171, 25), (241, 112, 70), (223, 98, 66), + (255, 91, 74), (255, 66, 97), (244, 41, 123), (235, 2, 127), + (223, 0, 107), (154, 0, 172), (74, 7, 175), (52, 0, 189), + (42, 6, 168), (22, 0, 115), (25, 2, 74), (39, 9, 35), + (95, 7, 65), (168, 6, 92), (221, 34, 89), (180, 0, 183), + (172, 6, 254), (149, 19, 255), (150, 80, 205), (153, 140, 184), + (155, 207, 135), (143, 211, 108), (158, 160, 77), (91, 123, 16), + (59, 59, 33), (38, 6, 73), (10, 3, 107), (49, 35, 149), + (39, 47, 154), (45, 38, 131), (4, 55, 74), (27, 102, 11) + ), + +// 352 ku0215.jpg +((48, 23, 27), (38, 9, 27), (59, 18, 33), (80, 28, 40), + (81, 46, 72), (83, 65, 105), (74, 47, 109), (65, 30, 114), + (87, 60, 141), (117, 38, 116), (147, 16, 92), (104, 10, 69), + (62, 5, 46), (54, 11, 43), (47, 17, 41), (49, 23, 45), + (51, 30, 49), (71, 55, 84), (52, 63, 93), (33, 72, 103), + (44, 79, 87), (55, 87, 72), (45, 83, 63), (35, 79, 54), + (22, 67, 38), (37, 65, 48), (53, 64, 58), (51, 37, 78), + (50, 10, 98), (44, 9, 99), (38, 9, 101), (40, 7, 96), + (22, 27, 57), (32, 41, 14), (26, 37, 14), (20, 33, 15), + (12, 22, 16), (5, 12, 18), (2, 13, 19), (0, 15, 20), + (21, 19, 66), (13, 21, 66), (6, 23, 67), (21, 31, 54), + (36, 40, 41), (51, 44, 37), (66, 49, 33), (77, 49, 46), + (102, 45, 36), (169, 46, 31), (186, 38, 18), (204, 30, 5), + (204, 37, 9), (205, 45, 13), (205, 39, 26), (206, 33, 39), + (228, 61, 45), (219, 37, 24), (210, 13, 4), (192, 12, 8), + (175, 11, 12), (167, 12, 11), (159, 14, 11), (134, 10, 12), + (124, 14, 13), (117, 17, 2), (108, 22, 3), (100, 28, 4), + (97, 27, 7), (94, 27, 10), (93, 28, 10), (90, 29, 24), + (106, 38, 49), (117, 49, 54), (129, 61, 60), (145, 53, 46), + (162, 46, 33), (167, 43, 35), (173, 41, 37), (187, 34, 37), + (187, 24, 51), (133, 11, 60), (103, 26, 43), (74, 41, 26), + (60, 44, 23), (47, 47, 21), (10, 51, 7), (25, 99, 12), + (5, 51, 5), (20, 32, 9), (35, 14, 13), (48, 7, 6), + (62, 0, 0), (63, 33, 9), (67, 27, 15), (94, 14, 27), + (103, 19, 32), (109, 17, 38), (117, 8, 31), (126, 0, 24), + (133, 1, 14), (141, 2, 5), (158, 8, 0), (177, 6, 0), + (200, 13, 30), (186, 10, 22), (173, 8, 14), (159, 14, 11), + (146, 20, 8), (129, 12, 5), (127, 2, 0), (99, 0, 0), + (96, 18, 14), (99, 20, 25), (102, 17, 22), (106, 15, 20), + (118, 29, 15), (150, 28, 5), (156, 22, 13), (157, 24, 15), + (149, 67, 19), (137, 47, 20), (126, 27, 22), (122, 25, 24), + (118, 23, 27), (101, 24, 42), (67, 20, 30), (50, 5, 36), + (22, 18, 33), (10, 30, 54), (18, 30, 52), (26, 31, 51), + (46, 19, 36), (89, 27, 32), (128, 37, 36), (153, 49, 48), + (206, 26, 37), (206, 26, 35), (207, 26, 33), (200, 30, 34), + (193, 35, 36), (192, 31, 37), (176, 19, 50), (146, 37, 58), + (147, 41, 53), (159, 30, 9), (174, 29, 4), (189, 28, 0), + (189, 29, 37), (178, 43, 40), (149, 18, 49), (111, 10, 52), + (103, 15, 55), (84, 16, 70), (65, 18, 86), (70, 31, 110), + (91, 17, 102), (98, 20, 96), (109, 17, 54), (119, 21, 62), + (124, 23, 65), (131, 45, 120), (131, 52, 136), (131, 60, 152), + (127, 63, 149), (133, 63, 135), (163, 52, 95), (122, 61, 66), + (83, 82, 64), (76, 86, 68), (69, 90, 73), (73, 79, 75), + (68, 56, 68), (39, 21, 33), (23, 11, 21), (25, 15, 14), + (24, 0, 3), (14, 8, 12), (12, 22, 23), (6, 35, 43), + (16, 34, 48), (16, 50, 51), (19, 55, 41), (16, 68, 29), + (13, 50, 43), (10, 48, 42), (7, 46, 41), (1, 29, 33), + (3, 22, 20), (6, 32, 5), (1, 22, 3), (8, 17, 16), + (4, 7, 12), (11, 10, 6), (38, 35, 0), (53, 61, 24), + (84, 97, 44), (79, 113, 62), (40, 110, 82), (71, 107, 71), + (96, 103, 72), (86, 132, 83), (63, 135, 71), (41, 132, 62), + (16, 110, 58), (19, 97, 81), (48, 85, 104), (53, 125, 113), + (136, 159, 149), (84, 83, 88), (52, 72, 81), (29, 59, 67), + (24, 65, 49), (6, 83, 41), (19, 86, 55), (9, 94, 63), + (16, 86, 62), (53, 71, 75), (93, 65, 53), (101, 21, 48), + (117, 13, 36), (148, 17, 33), (158, 19, 14), (155, 16, 9), + (135, 4, 12), (132, 10, 23), (119, 0, 36), (117, 7, 42), + (117, 8, 39), (90, 20, 30), (50, 22, 36), (25, 40, 43), + (19, 45, 42), (24, 61, 43), (29, 63, 38), (62, 75, 47), + (83, 68, 49), (106, 76, 14), (163, 74, 44), (167, 85, 47), + (168, 76, 27), (194, 40, 30), (173, 35, 9), (141, 31, 18), + (119, 36, 28), (80, 37, 18), (42, 12, 24), (38, 16, 29), + (38, 24, 39), (49, 53, 26), (103, 44, 30), (134, 46, 26), + (151, 53, 50), (134, 79, 48), (85, 78, 112), (104, 91, 83) + ), + +// 353 s00026.jpg +((65, 0, 180), (27, 0, 97), (34, 0, 80), (42, 0, 64), + (59, 5, 36), (76, 11, 9), (94, 10, 12), (113, 9, 16), + (167, 44, 3), (204, 50, 2), (241, 56, 2), (208, 38, 5), + (175, 21, 9), (154, 11, 93), (134, 1, 178), (145, 1, 192), + (157, 1, 206), (203, 5, 248), (196, 3, 224), (189, 1, 200), + (176, 8, 109), (164, 15, 19), (173, 33, 11), (182, 52, 3), + (255, 121, 31), (246, 145, 41), (238, 169, 52), (221, 150, 49), + (204, 132, 47), (187, 118, 44), (170, 105, 41), (188, 56, 7), + (215, 62, 2), (202, 121, 30), (187, 107, 29), (173, 94, 28), + (161, 84, 25), (150, 74, 22), (138, 73, 25), (126, 72, 28), + (126, 28, 1), (118, 25, 1), (111, 23, 1), (119, 27, 0), + (127, 32, 0), (131, 48, 9), (136, 65, 19), (157, 95, 36), + (161, 102, 42), (219, 163, 54), (207, 148, 52), (196, 134, 51), + (182, 119, 46), (169, 105, 41), (165, 95, 34), (161, 85, 27), + (115, 25, 0), (109, 13, 2), (104, 1, 4), (102, 0, 67), + (101, 0, 130), (96, 0, 146), (91, 0, 163), (15, 0, 215), + (10, 0, 226), (27, 1, 90), (45, 5, 49), (63, 9, 9), + (61, 10, 6), (59, 12, 4), (48, 11, 3), (43, 9, 8), + (17, 7, 6), (12, 4, 9), (8, 2, 12), (13, 1, 15), + (18, 1, 19), (18, 1, 30), (19, 1, 41), (35, 0, 61), + (51, 1, 74), (106, 0, 134), (115, 0, 159), (124, 0, 184), + (115, 1, 206), (107, 2, 229), (38, 0, 245), (37, 0, 185), + (124, 33, 110), (183, 82, 71), (243, 131, 33), (249, 148, 33), + (255, 165, 34), (255, 184, 50), (243, 214, 58), (246, 252, 68), + (216, 229, 79), (209, 160, 55), (188, 134, 48), (168, 109, 41), + (157, 101, 40), (146, 93, 39), (124, 121, 18), (137, 90, 38), + (97, 51, 17), (85, 47, 15), (73, 44, 14), (58, 23, 27), + (43, 3, 40), (32, 1, 61), (20, 10, 70), (0, 1, 52), + (7, 1, 37), (21, 6, 11), (30, 8, 8), (40, 11, 5), + (74, 22, 1), (78, 22, 0), (90, 18, 3), (76, 19, 0), + (28, 4, 28), (18, 2, 40), (9, 1, 52), (8, 1, 62), + (7, 1, 73), (31, 1, 75), (42, 0, 76), (67, 0, 132), + (122, 0, 145), (211, 191, 158), (233, 214, 125), (255, 238, 93), + (248, 248, 76), (243, 253, 79), (221, 235, 77), (242, 199, 61), + (213, 151, 52), (165, 108, 37), (118, 65, 23), (94, 51, 12), + (71, 37, 2), (54, 17, 1), (33, 20, 3), (11, 8, 1), + (6, 7, 2), (0, 4, 3), (0, 3, 7), (0, 3, 12), + (1, 3, 18), (16, 3, 29), (36, 0, 62), (59, 0, 82), + (144, 0, 184), (167, 0, 196), (190, 1, 209), (146, 2, 214), + (139, 0, 187), (138, 0, 155), (155, 13, 39), (134, 37, 2), + (124, 62, 23), (114, 62, 22), (107, 58, 20), (100, 54, 18), + (111, 57, 19), (110, 75, 33), (83, 77, 25), (69, 73, 38), + (48, 36, 12), (32, 28, 8), (16, 20, 5), (17, 18, 2), + (8, 10, 7), (5, 11, 11), (0, 19, 13), (0, 13, 3), + (2, 10, 0), (4, 7, 0), (2, 7, 1), (1, 6, 0), + (0, 4, 7), (0, 4, 16), (12, 4, 28), (27, 0, 53), + (66, 0, 87), (77, 0, 99), (88, 0, 112), (94, 0, 125), + (83, 0, 104), (64, 4, 40), (76, 28, 5), (76, 24, 2), + (52, 14, 1), (37, 10, 3), (16, 9, 3), (6, 6, 8), + (1, 4, 13), (1, 3, 18), (2, 2, 30), (8, 1, 45), + (6, 0, 60), (9, 0, 81), (24, 0, 110), (17, 1, 152), + (14, 0, 150), (5, 0, 125), (1, 0, 94), (0, 0, 72), + (3, 2, 46), (1, 2, 20), (0, 4, 16), (0, 2, 14), + (1, 3, 15), (0, 3, 18), (0, 2, 27), (0, 1, 32), + (1, 1, 35), (9, 0, 43), (40, 0, 63), (52, 0, 74), + (86, 0, 107), (101, 0, 122), (144, 8, 72), (161, 82, 26), + (167, 85, 29), (151, 92, 36), (128, 76, 29), (80, 57, 0), + (53, 17, 1), (19, 15, 0), (7, 13, 1), (6, 11, 4), + (6, 8, 5), (5, 7, 2), (7, 6, 4), (8, 4, 1), + (14, 7, 1), (27, 13, 0), (43, 13, 2), (60, 15, 12), + (43, 0, 46), (45, 0, 65), (57, 0, 95), (53, 0, 130), + (42, 0, 128), (21, 0, 131), (22, 0, 126), (6, 0, 102), + (7, 0, 77), (6, 0, 77), (3, 0, 69), (5, 0, 67), + (1, 1, 61), (8, 2, 40), (17, 32, 13), (6, 4, 26) + ), + +// 354 s00043.jpg +((49, 72, 90), (59, 99, 109), (64, 115, 120), (70, 131, 132), + (73, 134, 141), (76, 138, 151), (97, 146, 146), (118, 154, 142), + (171, 185, 134), (167, 177, 121), (164, 170, 108), (122, 165, 132), + (81, 160, 157), (101, 175, 178), (121, 191, 199), (114, 171, 178), + (108, 151, 158), (147, 130, 84), (138, 96, 65), (129, 62, 46), + (129, 55, 31), (129, 49, 16), (129, 52, 12), (130, 56, 9), + (132, 63, 8), (128, 89, 30), (124, 116, 53), (137, 127, 65), + (150, 138, 78), (152, 141, 80), (154, 144, 82), (161, 157, 93), + (168, 167, 100), (160, 165, 101), (137, 158, 109), (114, 151, 117), + (91, 139, 123), (68, 128, 129), (70, 132, 106), (72, 136, 84), + (133, 127, 65), (140, 124, 52), (147, 122, 40), (145, 134, 43), + (144, 146, 47), (148, 141, 58), (152, 137, 70), (145, 133, 81), + (143, 137, 105), (118, 102, 89), (101, 115, 75), (84, 129, 62), + (64, 82, 52), (45, 35, 43), (42, 32, 41), (40, 30, 39), + (37, 22, 29), (40, 30, 37), (43, 38, 45), (44, 46, 55), + (46, 54, 65), (48, 61, 74), (50, 69, 83), (115, 85, 74), + (130, 78, 91), (129, 85, 56), (136, 96, 45), (144, 108, 34), + (141, 110, 32), (139, 112, 31), (134, 127, 37), (133, 131, 18), + (130, 128, 9), (125, 118, 6), (120, 109, 3), (113, 99, 6), + (106, 89, 9), (110, 78, 8), (114, 68, 8), (113, 65, 1), + (121, 56, 2), (102, 52, 1), (87, 75, 7), (73, 98, 14), + (61, 81, 19), (50, 65, 24), (48, 71, 85), (52, 84, 99), + (74, 134, 145), (101, 139, 130), (129, 144, 115), (141, 150, 108), + (153, 156, 101), (157, 158, 98), (151, 139, 79), (154, 131, 61), + (139, 110, 32), (114, 70, 7), (93, 62, 9), (72, 55, 12), + (71, 57, 11), (71, 59, 11), (67, 79, 7), (85, 87, 0), + (125, 131, 67), (125, 132, 88), (125, 133, 110), (117, 115, 100), + (110, 97, 91), (57, 84, 79), (44, 60, 73), (46, 52, 64), + (44, 44, 54), (47, 57, 69), (49, 68, 81), (51, 79, 93), + (65, 125, 125), (69, 153, 137), (72, 153, 138), (73, 157, 142), + (82, 147, 151), (105, 140, 127), (128, 133, 103), (133, 134, 96), + (139, 135, 90), (155, 142, 74), (149, 119, 46), (143, 98, 33), + (132, 65, 23), (85, 40, 0), (77, 37, 0), (70, 34, 0), + (56, 28, 4), (48, 23, 18), (39, 26, 33), (37, 35, 49), + (43, 59, 84), (46, 65, 83), (50, 72, 83), (82, 71, 71), + (115, 71, 60), (129, 68, 37), (134, 56, 17), (125, 43, 3), + (111, 42, 0), (90, 33, 4), (81, 32, 5), (72, 32, 6), + (72, 55, 3), (89, 64, 7), (78, 73, 5), (70, 64, 4), + (56, 60, 1), (51, 46, 0), (47, 33, 0), (36, 21, 16), + (39, 24, 29), (37, 39, 54), (42, 51, 68), (48, 74, 89), + (57, 112, 72), (97, 94, 17), (100, 83, 12), (104, 73, 8), + (88, 53, 13), (78, 39, 22), (60, 31, 25), (44, 34, 42), + (38, 30, 43), (36, 26, 38), (35, 23, 33), (38, 22, 25), + (54, 23, 18), (63, 27, 13), (70, 27, 8), (77, 29, 6), + (76, 30, 4), (66, 30, 4), (58, 25, 10), (39, 21, 19), + (35, 19, 19), (35, 20, 17), (37, 23, 12), (49, 37, 0), + (37, 54, 2), (43, 45, 1), (49, 36, 1), (47, 23, 19), + (45, 34, 40), (53, 48, 54), (50, 72, 83), (59, 124, 81), + (58, 127, 83), (65, 123, 124), (62, 110, 112), (53, 85, 98), + (50, 76, 89), (50, 59, 64), (54, 45, 46), (56, 26, 18), + (56, 26, 16), (41, 30, 38), (43, 38, 45), (44, 41, 50), + (44, 42, 53), (42, 39, 50), (41, 31, 40), (39, 23, 26), + (35, 21, 21), (36, 22, 13), (50, 29, 0), (69, 36, 3), + (73, 51, 1), (92, 65, 38), (123, 101, 44), (148, 132, 73), + (158, 149, 80), (166, 157, 88), (162, 158, 87), (158, 150, 78), + (152, 148, 51), (138, 118, 32), (124, 95, 19), (120, 69, 14), + (113, 44, 11), (99, 40, 0), (100, 64, 2), (111, 82, 2), + (101, 84, 0), (98, 90, 0), (104, 84, 11), (124, 95, 19), + (137, 110, 29), (153, 130, 50), (159, 146, 67), (158, 151, 63), + (164, 158, 82), (165, 159, 81), (160, 159, 69), (165, 159, 81), + (166, 160, 82), (163, 160, 89), (164, 160, 89), (168, 164, 90), + (169, 169, 95), (166, 172, 108), (165, 171, 107), (166, 166, 96), + (158, 150, 78), (155, 137, 65), (144, 119, 37), (126, 101, 21), + (140, 83, 30), (138, 82, 33), (143, 110, 57), (141, 92, 36) + ), + +// 355 s00118.jpg +((209, 120, 106), (219, 128, 109), (213, 128, 107), (207, 129, 106), + (190, 115, 96), (174, 101, 86), (164, 91, 74), (154, 81, 62), + (141, 77, 68), (142, 81, 71), (144, 86, 74), (157, 89, 80), + (170, 93, 87), (189, 107, 95), (208, 121, 104), (199, 114, 117), + (190, 108, 131), (161, 113, 155), (155, 123, 170), (150, 133, 185), + (142, 145, 190), (135, 157, 196), (137, 154, 196), (140, 151, 196), + (160, 133, 186), (178, 126, 172), (197, 119, 158), (197, 113, 135), + (198, 107, 112), (193, 104, 110), (189, 102, 108), (150, 83, 100), + (134, 77, 94), (114, 74, 98), (119, 70, 83), (125, 66, 68), + (119, 67, 65), (113, 68, 62), (106, 71, 66), (99, 74, 70), + (30, 82, 103), (27, 83, 103), (24, 85, 103), (59, 94, 106), + (95, 104, 109), (105, 100, 116), (115, 97, 123), (126, 104, 143), + (136, 124, 174), (177, 182, 202), (179, 198, 207), (182, 214, 213), + (217, 212, 199), (252, 210, 186), (244, 215, 177), (237, 220, 168), + (255, 208, 141), (234, 175, 127), (214, 143, 113), (206, 127, 107), + (199, 112, 102), (193, 107, 99), (187, 102, 97), (164, 86, 86), + (148, 78, 86), (144, 82, 103), (120, 94, 109), (96, 106, 115), + (64, 93, 108), (33, 81, 101), (8, 72, 82), (9, 21, 47), + (17, 15, 18), (10, 11, 18), (3, 7, 18), (1, 18, 51), + (0, 30, 85), (1, 38, 85), (2, 46, 85), (15, 70, 75), + (34, 73, 90), (94, 92, 116), (136, 99, 120), (178, 107, 125), + (201, 115, 127), (224, 123, 129), (245, 145, 145), (250, 146, 145), + (248, 204, 193), (240, 219, 216), (232, 235, 240), (209, 223, 228), + (187, 212, 217), (191, 209, 197), (138, 169, 190), (104, 131, 160), + (81, 108, 115), (9, 109, 99), (7, 94, 76), (5, 79, 54), + (7, 66, 40), (10, 54, 27), (13, 48, 6), (62, 50, 36), + (104, 53, 60), (91, 64, 79), (78, 76, 98), (82, 86, 115), + (86, 96, 132), (77, 96, 138), (103, 101, 140), (135, 122, 139), + (152, 167, 124), (190, 130, 106), (185, 116, 109), (180, 103, 113), + (146, 88, 113), (134, 80, 103), (111, 77, 104), (116, 78, 103), + (194, 104, 116), (215, 121, 124), (236, 139, 132), (237, 148, 127), + (238, 158, 123), (241, 181, 121), (238, 196, 124), (244, 206, 123), + (233, 194, 153), (214, 170, 141), (225, 163, 143), (236, 156, 145), + (238, 154, 120), (223, 139, 111), (223, 132, 111), (228, 138, 112), + (235, 133, 128), (205, 124, 145), (175, 116, 162), (158, 115, 161), + (142, 115, 160), (106, 140, 177), (86, 141, 148), (35, 129, 95), + (11, 101, 63), (48, 50, 36), (56, 61, 46), (65, 72, 56), + (111, 107, 72), (148, 91, 80), (175, 108, 91), (197, 120, 100), + (216, 134, 110), (216, 131, 109), (217, 129, 109), (210, 116, 114), + (205, 119, 118), (183, 111, 148), (140, 113, 158), (76, 126, 161), + (28, 112, 122), (10, 124, 124), (11, 107, 113), (12, 90, 102), + (10, 87, 105), (23, 78, 134), (36, 125, 139), (91, 147, 164), + (170, 127, 207), (182, 129, 194), (195, 131, 181), (200, 120, 157), + (201, 117, 150), (193, 108, 129), (202, 113, 115), (177, 101, 127), + (143, 102, 142), (101, 89, 125), (72, 95, 137), (47, 93, 145), + (25, 60, 141), (11, 89, 127), (19, 123, 136), (19, 131, 132), + (102, 145, 179), (114, 154, 184), (127, 164, 190), (183, 185, 135), + (221, 155, 121), (212, 147, 115), (206, 134, 109), (206, 118, 104), + (191, 109, 95), (184, 105, 92), (177, 105, 90), (154, 98, 83), + (159, 93, 81), (160, 90, 82), (173, 95, 91), (199, 101, 102), + (203, 112, 107), (199, 109, 108), (188, 102, 105), (175, 93, 95), + (145, 81, 97), (136, 78, 93), (140, 75, 81), (132, 70, 71), + (127, 67, 66), (128, 71, 64), (126, 68, 64), (127, 65, 66), + (130, 69, 68), (134, 76, 72), (139, 79, 69), (132, 73, 67), + (127, 67, 66), (126, 69, 62), (125, 67, 63), (124, 66, 62), + (119, 63, 64), (114, 61, 67), (111, 60, 56), (109, 58, 57), + (82, 65, 55), (50, 93, 39), (41, 102, 42), (44, 115, 47), + (48, 83, 77), (27, 71, 84), (10, 62, 73), (16, 25, 42), + (27, 27, 39), (57, 35, 38), (94, 52, 56), (112, 62, 71), + (113, 69, 86), (124, 70, 84), (128, 67, 72), (124, 65, 69), + (111, 59, 63), (88, 46, 47), (68, 36, 37), (39, 25, 25), + (12, 20, 9), (1, 23, 0), (20, 22, 11), (29, 30, 14), + (63, 33, 31), (69, 50, 44), (59, 51, 64), (68, 60, 73), + (80, 65, 84), (90, 75, 94), (103, 68, 92), (140, 82, 94) + ), + +// 356 s00138.jpg +((247, 164, 0), (176, 98, 76), (170, 92, 66), (164, 87, 57), + (158, 82, 58), (153, 78, 59), (154, 78, 62), (155, 79, 65), + (139, 66, 59), (133, 63, 59), (128, 60, 59), (144, 63, 46), + (160, 67, 33), (178, 77, 28), (197, 87, 24), (206, 96, 23), + (216, 105, 23), (147, 188, 48), (149, 138, 68), (152, 88, 88), + (163, 91, 78), (175, 95, 68), (186, 97, 50), (197, 100, 32), + (234, 118, 15), (236, 121, 10), (239, 124, 5), (229, 131, 2), + (219, 139, 0), (192, 168, 18), (166, 198, 37), (122, 226, 27), + (64, 219, 19), (164, 222, 23), (184, 218, 22), (204, 214, 21), + (226, 206, 16), (248, 199, 11), (247, 196, 8), (247, 193, 5), + (249, 191, 6), (252, 186, 11), (255, 182, 16), (253, 179, 10), + (252, 176, 5), (251, 178, 4), (251, 180, 4), (250, 179, 1), + (250, 184, 2), (254, 180, 5), (253, 175, 4), (253, 170, 4), + (246, 163, 8), (239, 157, 13), (232, 139, 24), (225, 121, 36), + (197, 100, 55), (214, 108, 41), (231, 117, 28), (230, 115, 18), + (230, 113, 8), (228, 111, 6), (227, 110, 5), (223, 107, 0), + (222, 105, 10), (179, 82, 27), (164, 72, 33), (149, 63, 40), + (139, 59, 43), (129, 55, 46), (112, 48, 49), (111, 46, 50), + (131, 55, 42), (152, 63, 34), (173, 72, 26), (193, 96, 16), + (214, 120, 6), (227, 132, 6), (241, 145, 7), (251, 156, 4), + (251, 156, 2), (237, 122, 5), (200, 96, 19), (164, 70, 34), + (146, 62, 39), (128, 54, 45), (102, 45, 54), (83, 38, 59), + (69, 34, 67), (67, 33, 67), (66, 32, 67), (63, 31, 69), + (61, 30, 71), (56, 29, 72), (52, 29, 75), (56, 29, 72), + (55, 27, 68), (56, 29, 74), (48, 26, 76), (40, 23, 78), + (41, 23, 78), (43, 24, 79), (45, 27, 79), (53, 29, 77), + (64, 30, 65), (76, 35, 61), (89, 41, 57), (99, 44, 54), + (109, 47, 52), (127, 50, 34), (152, 58, 22), (171, 80, 0), + (213, 116, 0), (248, 186, 5), (246, 192, 11), (245, 199, 18), + (227, 211, 14), (192, 206, 9), (211, 201, 8), (238, 179, 0), + (250, 169, 0), (250, 160, 0), (250, 152, 1), (248, 148, 1), + (247, 145, 1), (242, 130, 4), (233, 121, 11), (227, 117, 4), + (227, 117, 2), (226, 124, 0), (230, 127, 1), (235, 130, 2), + (245, 140, 0), (248, 143, 2), (252, 150, 6), (253, 153, 7), + (255, 169, 4), (255, 171, 8), (255, 173, 12), (255, 172, 9), + (255, 171, 6), (253, 165, 3), (250, 151, 21), (246, 136, 25), + (218, 108, 23), (137, 49, 9), (129, 45, 17), (121, 42, 25), + (113, 46, 38), (103, 43, 45), (99, 40, 46), (99, 43, 54), + (100, 44, 55), (101, 46, 58), (102, 48, 62), (105, 45, 55), + (107, 46, 53), (112, 48, 49), (115, 50, 48), (122, 51, 47), + (126, 53, 46), (129, 55, 44), (129, 54, 43), (130, 53, 43), + (132, 51, 32), (134, 52, 30), (136, 57, 42), (138, 56, 32), + (149, 62, 35), (155, 64, 34), (161, 67, 33), (175, 74, 28), + (189, 83, 25), (220, 102, 14), (221, 104, 11), (223, 107, 8), + (219, 104, 11), (192, 86, 34), (154, 74, 49), (126, 53, 46), + (125, 52, 46), (131, 54, 44), (145, 60, 39), (156, 62, 26), + (215, 99, 14), (221, 104, 12), (228, 110, 10), (241, 129, 3), + (247, 140, 0), (246, 138, 3), (239, 131, 5), (229, 112, 7), + (218, 104, 5), (182, 74, 12), (163, 62, 16), (155, 62, 5), + (164, 65, 0), (181, 75, 0), (211, 103, 0), (232, 128, 0), + (242, 137, 9), (247, 145, 1), (237, 134, 5), (228, 124, 0), + (219, 108, 0), (203, 93, 14), (167, 72, 18), (139, 58, 39), + (120, 52, 49), (101, 44, 53), (92, 41, 58), (89, 40, 59), + (89, 40, 59), (89, 40, 59), (87, 40, 60), (86, 37, 56), + (84, 39, 60), (80, 37, 64), (71, 34, 65), (77, 37, 63), + (79, 34, 55), (91, 40, 59), (106, 45, 52), (118, 48, 40), + (149, 59, 32), (164, 92, 0), (211, 128, 0), (239, 154, 12), + (252, 153, 34), (253, 159, 37), (255, 163, 60), (236, 138, 51), + (182, 98, 70), (141, 74, 68), (108, 49, 55), (97, 43, 56), + (88, 41, 61), (79, 42, 75), (59, 32, 77), (57, 30, 75), + (63, 31, 70), (67, 33, 68), (72, 33, 64), (83, 32, 49), + (69, 21, 37), (54, 11, 38), (83, 10, 0), (87, 19, 6), + (96, 34, 37), (91, 40, 55), (97, 43, 57), (99, 43, 54), + (109, 47, 52), (125, 57, 54), (139, 68, 48), (168, 95, 62) + ), + +// 357 s00149.jpg +((145, 15, 25), (124, 27, 21), (102, 17, 21), (80, 8, 22), + (57, 4, 25), (35, 1, 28), (26, 3, 30), (18, 5, 33), + (0, 23, 29), (3, 27, 33), (6, 31, 38), (8, 36, 36), + (11, 42, 34), (20, 35, 32), (30, 28, 31), (23, 24, 30), + (17, 20, 29), (3, 4, 24), (2, 2, 23), (2, 0, 22), + (3, 0, 22), (4, 0, 23), (4, 0, 23), (5, 0, 23), + (26, 3, 32), (47, 3, 28), (69, 4, 24), (113, 13, 56), + (158, 22, 88), (170, 25, 99), (182, 29, 111), (230, 13, 100), + (249, 6, 90), (253, 2, 82), (247, 3, 79), (241, 4, 76), + (236, 7, 87), (231, 11, 98), (229, 14, 104), (228, 17, 110), + (187, 46, 142), (175, 48, 141), (163, 50, 140), (111, 29, 93), + (60, 8, 46), (55, 6, 41), (51, 4, 36), (36, 0, 28), + (34, 0, 25), (34, 23, 27), (27, 32, 36), (20, 41, 46), + (21, 56, 44), (23, 72, 42), (22, 73, 42), (21, 75, 43), + (9, 61, 39), (4, 43, 32), (0, 26, 25), (0, 15, 24), + (1, 4, 23), (1, 2, 23), (2, 0, 24), (0, 0, 24), + (0, 5, 27), (5, 17, 39), (4, 28, 50), (4, 40, 62), + (7, 40, 64), (11, 41, 67), (18, 41, 72), (13, 30, 56), + (10, 14, 41), (17, 13, 36), (25, 12, 32), (23, 7, 27), + (22, 3, 23), (18, 1, 23), (15, 0, 23), (6, 1, 24), + (1, 9, 28), (3, 26, 34), (2, 38, 37), (1, 51, 40), + (0, 55, 45), (0, 60, 50), (0, 47, 63), (7, 43, 67), + (36, 44, 83), (26, 51, 86), (17, 58, 90), (15, 56, 86), + (13, 54, 82), (26, 31, 61), (44, 17, 52), (57, 7, 42), + (52, 5, 25), (53, 18, 24), (69, 20, 24), (85, 23, 24), + (103, 27, 58), (121, 31, 93), (181, 26, 104), (225, 24, 120), + (243, 15, 113), (235, 15, 111), (227, 16, 109), (222, 15, 103), + (217, 15, 97), (185, 1, 51), (128, 1, 31), (77, 0, 32), + (47, 4, 23), (7, 1, 27), (5, 3, 26), (4, 5, 25), + (2, 5, 24), (3, 4, 24), (15, 5, 32), (27, 2, 31), + (22, 6, 33), (18, 10, 36), (14, 14, 40), (19, 20, 49), + (24, 27, 58), (49, 23, 62), (50, 24, 61), (55, 27, 67), + (93, 51, 115), (192, 25, 105), (201, 15, 89), (211, 6, 73), + (221, 14, 30), (216, 10, 30), (197, 15, 27), (138, 41, 22), + (86, 10, 22), (70, 5, 23), (55, 1, 25), (48, 4, 24), + (42, 8, 24), (21, 7, 30), (7, 13, 37), (2, 29, 46), + (13, 45, 44), (1, 49, 59), (1, 41, 56), (2, 33, 53), + (1, 30, 44), (2, 19, 39), (4, 10, 34), (1, 9, 30), + (16, 2, 25), (24, 1, 24), (32, 0, 23), (47, 2, 23), + (65, 1, 28), (81, 0, 33), (129, 6, 26), (194, 6, 31), + (242, 33, 26), (249, 92, 23), (247, 93, 23), (246, 95, 24), + (227, 89, 26), (206, 76, 14), (177, 69, 30), (152, 65, 35), + (127, 30, 24), (126, 29, 23), (125, 28, 22), (124, 30, 22), + (103, 21, 23), (74, 8, 46), (56, 14, 52), (22, 22, 50), + (11, 23, 37), (4, 22, 36), (8, 16, 39), (5, 19, 32), + (5, 17, 29), (19, 13, 25), (37, 14, 24), (63, 18, 23), + (164, 60, 23), (199, 58, 23), (235, 56, 23), (248, 70, 22), + (250, 62, 24), (218, 20, 107), (221, 24, 116), (188, 45, 137), + (173, 25, 101), (141, 5, 53), (174, 0, 37), (172, 5, 61), + (133, 23, 84), (115, 31, 91), (38, 86, 64), (38, 62, 46), + (28, 49, 42), (24, 37, 27), (29, 31, 26), (39, 28, 24), + (57, 21, 21), (76, 25, 22), (101, 28, 22), (142, 51, 24), + (204, 45, 41), (223, 19, 28), (233, 19, 29), (241, 2, 44), + (244, 0, 54), (249, 0, 68), (254, 0, 72), (248, 0, 63), + (243, 2, 71), (240, 1, 68), (187, 1, 50), (177, 0, 42), + (98, 3, 27), (70, 12, 52), (52, 39, 83), (30, 44, 79), + (0, 63, 80), (2, 83, 110), (25, 109, 173), (69, 133, 230), + (36, 125, 205), (22, 84, 131), (4, 81, 107), (1, 52, 69), + (0, 34, 48), (0, 21, 35), (1, 9, 30), (6, 1, 23), + (14, 0, 23), (16, 0, 24), (28, 0, 25), (34, 0, 24), + (36, 1, 25), (38, 5, 22), (58, 10, 24), (83, 16, 23), + (120, 15, 22), (176, 0, 36), (208, 19, 26), (222, 18, 27), + (223, 17, 27), (219, 15, 27), (195, 0, 40), (144, 1, 44), + (105, 3, 27), (68, 12, 21), (0, 30, 32), (33, 19, 19) + ), +// 358 vchira_0001.jpg +((157, 75, 51), (218, 60, 206), (229, 48, 230), (241, 37, 255), + (244, 28, 248), (248, 20, 241), (243, 21, 232), (239, 22, 223), + (192, 66, 251), (120, 114, 248), (48, 163, 246), (33, 182, 244), + (18, 201, 243), (20, 204, 244), (22, 208, 246), (18, 226, 250), + (15, 245, 255), (18, 244, 224), (38, 230, 213), (58, 216, 202), + (90, 223, 199), (122, 230, 196), (122, 240, 177), (123, 250, 159), + (96, 250, 154), (85, 251, 174), (74, 253, 195), (46, 236, 225), + (18, 220, 255), (26, 219, 250), (35, 219, 245), (74, 238, 201), + (94, 250, 185), (158, 221, 174), (142, 238, 162), (127, 255, 151), + (144, 225, 144), (162, 195, 138), (191, 195, 151), (220, 195, 164), + (236, 166, 117), (242, 188, 93), (248, 211, 70), (250, 233, 35), + (253, 255, 0), (253, 242, 11), (254, 229, 23), (248, 207, 19), + (241, 200, 46), (226, 199, 94), (209, 191, 101), (193, 184, 109), + (133, 197, 149), (74, 210, 190), (41, 219, 205), (8, 229, 220), + (22, 209, 182), (79, 212, 183), (136, 215, 184), (165, 186, 191), + (195, 157, 198), (220, 149, 199), (246, 141, 200), (242, 139, 158), + (215, 138, 190), (194, 136, 184), (219, 100, 216), (244, 64, 249), + (240, 59, 243), (237, 55, 238), (233, 21, 227), (208, 13, 229), + (123, 13, 164), (137, 6, 158), (151, 0, 153), (170, 26, 150), + (190, 52, 147), (204, 85, 147), (219, 119, 147), (202, 132, 96), + (190, 91, 52), (166, 57, 136), (185, 73, 172), (205, 90, 209), + (213, 94, 196), (222, 98, 184), (232, 126, 128), (248, 146, 82), + (249, 190, 52), (251, 160, 88), (254, 131, 124), (251, 91, 142), + (248, 52, 160), (241, 40, 208), (232, 15, 207), (208, 16, 215), + (197, 0, 154), (113, 11, 74), (120, 48, 37), (128, 85, 0), + (132, 105, 0), (137, 125, 0), (164, 181, 4), (175, 179, 6), + (204, 236, 11), (220, 232, 7), (236, 229, 3), (233, 212, 4), + (231, 196, 6), (240, 187, 19), (241, 185, 50), (221, 215, 55), + (212, 220, 101), (166, 182, 135), (144, 155, 140), (122, 129, 145), + (111, 78, 61), (79, 22, 57), (64, 0, 92), (100, 17, 107), + (151, 17, 86), (152, 14, 100), (154, 12, 114), (159, 22, 122), + (164, 32, 131), (210, 27, 141), (220, 20, 217), (209, 7, 217), + (228, 6, 227), (220, 9, 228), (215, 20, 203), (211, 31, 178), + (198, 28, 99), (138, 43, 51), (136, 93, 0), (118, 97, 16), + (72, 102, 48), (58, 91, 24), (45, 80, 0), (40, 81, 4), + (36, 82, 9), (39, 55, 0), (19, 49, 0), (13, 49, 23), + (0, 63, 50), (37, 145, 218), (35, 152, 222), (34, 159, 226), + (4, 170, 208), (3, 125, 176), (10, 42, 127), (29, 59, 123), + (114, 18, 167), (133, 32, 204), (153, 47, 241), (191, 8, 223), + (203, 6, 236), (210, 21, 238), (177, 72, 200), (161, 59, 221), + (138, 62, 212), (64, 60, 147), (61, 52, 125), (59, 44, 103), + (1, 68, 35), (31, 45, 9), (21, 10, 18), (18, 9, 14), + (5, 7, 0), (4, 3, 11), (3, 0, 22), (15, 21, 45), + (30, 20, 70), (37, 35, 46), (63, 4, 0), (68, 0, 5), + (86, 10, 36), (124, 18, 67), (146, 53, 142), (95, 130, 184), + (104, 208, 171), (99, 232, 187), (88, 216, 245), (47, 193, 252), + (111, 172, 237), (141, 133, 238), (172, 94, 240), (207, 50, 243), + (229, 29, 242), (172, 38, 247), (143, 43, 251), (99, 92, 234), + (76, 171, 229), (41, 178, 214), (36, 187, 146), (87, 193, 95), + (154, 188, 6), (181, 187, 3), (191, 185, 1), (212, 165, 23), + (237, 113, 77), (231, 79, 104), (234, 57, 135), (238, 14, 175), + (232, 42, 166), (241, 93, 125), (255, 189, 83), (233, 239, 55), + (231, 248, 46), (215, 231, 96), (199, 227, 127), (201, 235, 141), + (162, 218, 145), (151, 251, 127), (179, 245, 113), (173, 239, 89), + (155, 202, 12), (172, 144, 19), (139, 96, 2), (149, 114, 10), + (185, 149, 11), (251, 199, 35), (228, 236, 75), (206, 245, 128), + (164, 203, 159), (138, 216, 200), (105, 181, 241), (120, 176, 235), + (156, 200, 201), (199, 216, 200), (200, 222, 173), (172, 203, 195), + (168, 135, 216), (145, 93, 240), (146, 51, 195), (105, 20, 165), + (118, 0, 140), (71, 0, 96), (63, 0, 101), (49, 24, 63), + (30, 24, 58), (41, 0, 17), (60, 39, 0), (69, 35, 0), + (92, 78, 0), (96, 115, 7), (96, 187, 68), (92, 226, 115), + (40, 194, 134), (75, 104, 110), (111, 61, 62), (107, 0, 92), + (106, 0, 81), (126, 19, 9), (108, 21, 14), (66, 0, 19) + ), + +// 359 vchira_0003.jpg +((85, 39, 189), (141, 23, 195), (149, 11, 167), (158, 0, 139), + (147, 0, 134), (137, 0, 130), (131, 2, 134), (126, 4, 138), + (90, 12, 148), (99, 9, 142), (109, 6, 137), (111, 3, 132), + (113, 1, 127), (123, 3, 111), (133, 6, 95), (141, 19, 77), + (149, 32, 59), (154, 81, 12), (155, 90, 11), (157, 100, 10), + (144, 105, 7), (131, 110, 5), (131, 110, 2), (132, 111, 0), + (156, 143, 3), (168, 161, 21), (180, 179, 39), (217, 202, 35), + (255, 225, 32), (255, 228, 29), (255, 232, 27), (255, 231, 20), + (245, 218, 7), (191, 174, 6), (178, 155, 5), (165, 137, 4), + (155, 130, 8), (146, 124, 13), (136, 111, 8), (127, 98, 4), + (147, 45, 33), (128, 24, 81), (110, 4, 130), (103, 15, 155), + (97, 26, 180), (94, 26, 173), (91, 27, 167), (95, 8, 113), + (129, 37, 52), (162, 92, 30), (168, 110, 22), (175, 128, 14), + (186, 146, 13), (198, 164, 13), (199, 168, 21), (200, 172, 29), + (183, 126, 21), (188, 85, 57), (193, 45, 93), (192, 31, 113), + (191, 18, 134), (191, 24, 122), (191, 30, 110), (183, 34, 98), + (193, 36, 87), (196, 34, 91), (195, 32, 98), (195, 30, 106), + (188, 25, 112), (181, 21, 119), (168, 0, 131), (135, 9, 152), + (97, 14, 154), (100, 7, 136), (104, 1, 119), (105, 1, 111), + (107, 2, 103), (110, 1, 104), (114, 0, 106), (125, 4, 109), + (148, 12, 88), (137, 28, 49), (134, 41, 39), (131, 55, 29), + (125, 61, 29), (119, 67, 30), (111, 52, 22), (109, 43, 17), + (77, 13, 4), (78, 29, 4), (79, 46, 5), (88, 56, 7), + (98, 66, 9), (107, 75, 0), (127, 100, 0), (140, 134, 0), + (174, 158, 3), (242, 123, 83), (232, 108, 80), (223, 93, 77), + (208, 77, 69), (194, 61, 62), (175, 57, 53), (174, 43, 61), + (193, 66, 77), (208, 73, 80), (224, 81, 83), (204, 62, 79), + (185, 44, 76), (177, 33, 86), (165, 52, 56), (148, 71, 19), + (126, 71, 7), (116, 92, 2), (115, 93, 3), (115, 94, 5), + (115, 96, 4), (120, 94, 0), (150, 95, 31), (161, 55, 65), + (165, 13, 96), (169, 25, 101), (173, 38, 107), (173, 38, 97), + (174, 38, 88), (177, 66, 47), (189, 104, 21), (218, 147, 23), + (232, 154, 30), (214, 184, 10), (213, 194, 10), (212, 205, 11), + (237, 203, 18), (248, 208, 14), (244, 191, 27), (237, 141, 54), + (233, 132, 50), (220, 135, 38), (208, 138, 27), (195, 130, 18), + (183, 123, 9), (156, 104, 21), (118, 72, 22), (121, 65, 6), + (119, 48, 0), (118, 0, 69), (118, 0, 75), (118, 0, 82), + (125, 0, 87), (125, 4, 97), (138, 2, 104), (147, 5, 113), + (159, 27, 103), (162, 36, 93), (165, 46, 84), (161, 58, 51), + (162, 94, 33), (167, 110, 23), (172, 121, 6), (172, 119, 17), + (178, 112, 25), (162, 68, 34), (165, 58, 45), (169, 48, 57), + (164, 41, 62), (158, 25, 88), (123, 15, 127), (93, 29, 167), + (70, 82, 218), (62, 99, 220), (55, 116, 223), (125, 72, 224), + (143, 17, 179), (158, 0, 139), (173, 5, 126), (210, 42, 101), + (220, 66, 102), (235, 118, 83), (219, 151, 54), (244, 201, 34), + (255, 220, 34), (255, 249, 34), (255, 243, 21), (249, 214, 28), + (239, 153, 40), (232, 143, 44), (226, 134, 49), (208, 100, 51), + (187, 79, 43), (171, 45, 69), (154, 22, 71), (138, 0, 88), + (136, 0, 103), (131, 9, 118), (126, 4, 123), (148, 1, 118), + (162, 8, 120), (161, 5, 114), (143, 7, 105), (141, 2, 103), + (143, 7, 91), (155, 14, 82), (149, 21, 54), (149, 27, 50), + (152, 36, 39), (140, 67, 34), (139, 79, 19), (130, 100, 0), + (136, 99, 0), (153, 104, 2), (161, 94, 3), (151, 92, 0), + (137, 73, 12), (124, 66, 28), (114, 48, 32), (130, 17, 60), + (115, 0, 93), (114, 0, 97), (98, 0, 104), (95, 0, 128), + (81, 3, 139), (82, 11, 143), (89, 0, 137), (114, 4, 139), + (128, 10, 120), (140, 3, 119), (140, 5, 123), (150, 0, 128), + (159, 6, 130), (149, 10, 173), (145, 19, 191), (129, 14, 193), + (108, 22, 195), (125, 39, 200), (111, 50, 187), (97, 43, 201), + (87, 43, 190), (113, 9, 156), (147, 15, 99), (142, 38, 47), + (158, 76, 29), (161, 102, 12), (154, 118, 0), (140, 111, 9), + (140, 125, 6), (156, 132, 6), (161, 126, 8), (172, 132, 1), + (188, 144, 0), (198, 149, 12), (220, 166, 8), (250, 206, 23), + (254, 209, 32), (249, 209, 36), (226, 182, 34), (223, 159, 23) + ), + +// 360 vchira_0012.jpg +((211, 48, 91), (113, 23, 0), (78, 32, 0), (43, 41, 0), + (31, 30, 16), (20, 20, 32), (28, 12, 37), (36, 4, 43), + (118, 2, 49), (145, 11, 68), (172, 21, 88), (171, 31, 83), + (170, 41, 79), (212, 82, 105), (255, 124, 132), (250, 136, 129), + (245, 149, 127), (198, 200, 179), (219, 169, 195), (240, 138, 212), + (218, 100, 147), (196, 63, 82), (165, 43, 78), (134, 23, 74), + (100, 18, 40), (56, 9, 21), (13, 0, 2), (11, 0, 4), + (9, 0, 6), (4, 9, 15), (0, 19, 25), (20, 8, 58), + (53, 0, 56), (56, 15, 19), (63, 19, 15), (70, 24, 11), + (112, 60, 15), (155, 96, 20), (171, 136, 10), (188, 176, 0), + (210, 255, 80), (203, 224, 93), (197, 193, 106), (164, 152, 90), + (131, 111, 74), (137, 80, 57), (144, 50, 40), (127, 46, 1), + (169, 98, 34), (170, 209, 118), (145, 231, 110), (120, 253, 102), + (99, 246, 114), (78, 239, 127), (60, 217, 121), (43, 196, 116), + (26, 101, 168), (41, 64, 151), (57, 28, 134), (67, 23, 123), + (77, 18, 112), (110, 9, 112), (144, 0, 113), (148, 8, 113), + (101, 15, 50), (35, 50, 9), (17, 45, 26), (0, 41, 44), + (0, 53, 35), (0, 66, 26), (36, 101, 81), (54, 146, 121), + (53, 231, 121), (59, 233, 130), (65, 236, 140), (73, 239, 132), + (81, 243, 124), (99, 241, 121), (117, 239, 118), (158, 253, 107), + (189, 218, 108), (212, 208, 147), (198, 214, 151), (185, 220, 156), + (169, 210, 144), (153, 200, 132), (99, 166, 95), (99, 143, 118), + (13, 67, 101), (6, 76, 118), (0, 86, 136), (0, 112, 147), + (0, 138, 159), (12, 132, 148), (0, 114, 117), (40, 154, 120), + (42, 194, 109), (46, 212, 110), (71, 226, 115), (97, 241, 120), + (105, 246, 114), (114, 251, 109), (137, 235, 100), (151, 254, 101), + (144, 255, 96), (131, 255, 98), (118, 255, 101), (108, 255, 102), + (98, 255, 104), (98, 252, 132), (98, 254, 145), (107, 252, 159), + (105, 251, 142), (135, 235, 119), (134, 231, 115), (133, 228, 112), + (149, 255, 107), (128, 250, 90), (119, 252, 101), (102, 246, 99), + (49, 202, 86), (49, 166, 94), (50, 130, 103), (37, 133, 107), + (25, 137, 112), (8, 149, 83), (50, 161, 67), (63, 188, 52), + (120, 201, 98), (184, 208, 134), (219, 198, 128), (255, 189, 123), + (253, 125, 116), (218, 94, 66), (187, 161, 24), (219, 232, 0), + (253, 255, 36), (244, 252, 42), (235, 249, 48), (245, 237, 68), + (255, 225, 89), (214, 249, 95), (195, 237, 89), (158, 252, 102), + (167, 255, 107), (193, 230, 125), (200, 238, 131), (208, 247, 138), + (228, 231, 144), (197, 234, 129), (154, 248, 136), (118, 255, 132), + (117, 240, 133), (132, 242, 136), (147, 244, 139), (165, 246, 153), + (159, 243, 147), (134, 231, 136), (88, 159, 99), (38, 109, 105), + (9, 62, 93), (40, 33, 75), (49, 16, 73), (59, 0, 72), + (64, 0, 83), (65, 1, 87), (57, 13, 100), (120, 43, 137), + (178, 18, 180), (195, 86, 163), (213, 154, 146), (218, 226, 44), + (233, 222, 18), (187, 138, 35), (179, 89, 36), (177, 49, 74), + (120, 40, 79), (71, 4, 55), (41, 11, 85), (48, 16, 113), + (68, 19, 136), (136, 92, 145), (169, 182, 128), (191, 222, 162), + (153, 225, 187), (168, 234, 177), (183, 244, 167), (191, 205, 188), + (193, 234, 204), (202, 217, 222), (183, 160, 242), (178, 91, 248), + (150, 169, 165), (131, 165, 104), (106, 189, 121), (62, 227, 148), + (56, 237, 160), (35, 233, 145), (30, 242, 184), (59, 236, 220), + (116, 197, 227), (148, 226, 186), (131, 245, 173), (145, 246, 166), + (132, 249, 135), (168, 246, 127), (176, 222, 150), (169, 187, 137), + (170, 155, 148), (117, 57, 117), (97, 41, 68), (81, 15, 51), + (50, 34, 44), (50, 54, 19), (56, 45, 15), (69, 45, 35), + (102, 67, 9), (116, 71, 16), (74, 128, 0), (69, 137, 14), + (49, 119, 56), (73, 191, 53), (127, 204, 102), (174, 233, 139), + (193, 224, 144), (215, 200, 157), (219, 200, 134), (223, 201, 99), + (177, 176, 96), (176, 67, 62), (149, 62, 68), (148, 24, 52), + (130, 27, 46), (146, 47, 42), (174, 57, 40), (171, 113, 16), + (141, 205, 56), (85, 234, 90), (90, 248, 125), (75, 255, 158), + (72, 231, 199), (121, 233, 195), (145, 245, 195), (168, 242, 215), + (180, 221, 207), (165, 222, 203), (149, 186, 212), (100, 200, 255), + (51, 206, 252), (88, 111, 223), (41, 153, 203), (19, 218, 163), + (83, 255, 167), (143, 219, 193), (165, 197, 186), (255, 145, 163) + ), + +// 361 vchira_0013.jpg +((180, 215, 243), (103, 96, 234), (93, 75, 206), (84, 54, 178), + (89, 45, 160), (94, 37, 142), (93, 30, 142), (93, 24, 143), + (64, 31, 174), (59, 43, 174), (55, 55, 175), (69, 56, 188), + (83, 58, 201), (95, 55, 211), (108, 52, 221), (111, 68, 230), + (115, 84, 240), (114, 111, 216), (92, 103, 201), (70, 95, 187), + (65, 94, 191), (60, 93, 196), (57, 90, 195), (54, 88, 195), + (75, 77, 214), (101, 65, 226), (128, 54, 239), (105, 56, 224), + (83, 59, 209), (78, 60, 204), (74, 62, 200), (64, 55, 198), + (50, 61, 177), (85, 91, 211), (94, 89, 224), (103, 87, 237), + (125, 67, 233), (148, 47, 229), (162, 45, 236), (176, 43, 244), + (179, 63, 236), (171, 66, 241), (164, 69, 247), (172, 73, 238), + (180, 77, 230), (175, 89, 217), (170, 102, 205), (151, 82, 191), + (92, 44, 153), (41, 13, 53), (30, 6, 35), (19, 0, 17), + (15, 0, 18), (12, 0, 20), (18, 0, 24), (25, 0, 29), + (32, 20, 92), (57, 15, 117), (82, 11, 143), (109, 8, 164), + (137, 5, 185), (142, 10, 191), (148, 16, 198), (146, 47, 216), + (146, 102, 251), (119, 122, 255), (115, 110, 236), (112, 99, 217), + (122, 114, 211), (132, 130, 205), (214, 173, 169), (237, 209, 255), + (148, 112, 248), (140, 138, 248), (132, 164, 249), (108, 159, 231), + (84, 154, 214), (80, 153, 220), (76, 152, 227), (89, 135, 229), + (88, 103, 228), (64, 78, 200), (63, 60, 188), (63, 43, 176), + (62, 38, 176), (61, 34, 177), (69, 29, 164), (67, 10, 149), + (52, 12, 108), (38, 6, 84), (25, 1, 61), (25, 2, 59), + (26, 3, 57), (28, 2, 49), (27, 4, 33), (11, 13, 26), + (6, 7, 37), (9, 13, 61), (23, 12, 71), (38, 11, 82), + (42, 9, 80), (47, 7, 78), (48, 2, 75), (54, 0, 87), + (43, 23, 112), (43, 28, 120), (44, 33, 129), (38, 44, 139), + (32, 55, 149), (27, 68, 150), (17, 62, 127), (20, 27, 108), + (17, 25, 87), (11, 10, 44), (15, 5, 48), (20, 0, 53), + (31, 3, 54), (52, 5, 73), (58, 3, 96), (77, 6, 136), + (116, 27, 193), (122, 35, 205), (128, 44, 217), (122, 36, 207), + (116, 28, 198), (103, 28, 193), (83, 33, 180), (64, 61, 168), + (63, 79, 166), (109, 76, 215), (118, 78, 214), (128, 81, 213), + (131, 61, 196), (115, 46, 201), (109, 26, 180), (94, 9, 139), + (68, 0, 86), (85, 0, 111), (103, 0, 136), (115, 8, 159), + (127, 16, 183), (158, 30, 213), (172, 74, 223), (176, 87, 255), + (185, 90, 252), (180, 108, 242), (172, 103, 242), (164, 99, 243), + (162, 68, 252), (149, 32, 234), (143, 23, 219), (137, 24, 204), + (67, 41, 168), (62, 45, 155), (57, 50, 143), (36, 43, 134), + (41, 32, 115), (33, 44, 98), (39, 28, 84), (41, 19, 84), + (54, 16, 117), (98, 10, 146), (105, 12, 152), (113, 14, 159), + (102, 28, 177), (83, 44, 187), (82, 59, 199), (89, 72, 213), + (79, 84, 202), (75, 73, 201), (71, 63, 200), (71, 63, 184), + (55, 58, 173), (42, 53, 159), (42, 44, 155), (37, 59, 160), + (34, 76, 160), (26, 83, 152), (32, 89, 170), (39, 96, 186), + (22, 116, 180), (35, 107, 192), (48, 129, 210), (41, 99, 198), + (42, 62, 177), (45, 52, 164), (48, 42, 152), (59, 30, 138), + (85, 27, 137), (92, 38, 150), (112, 45, 187), (112, 70, 196), + (131, 104, 197), (126, 70, 231), (135, 56, 223), (130, 24, 192), + (114, 32, 179), (110, 39, 179), (94, 40, 180), (65, 54, 159), + (51, 55, 144), (33, 86, 136), (33, 61, 124), (43, 53, 124), + (40, 48, 120), (45, 37, 114), (84, 66, 114), (90, 65, 159), + (96, 81, 186), (91, 67, 187), (81, 58, 174), (84, 42, 170), + (83, 17, 153), (66, 5, 134), (69, 15, 129), (50, 12, 123), + (42, 19, 133), (63, 32, 151), (87, 23, 172), (90, 13, 181), + (88, 34, 192), (90, 42, 190), (75, 65, 200), (54, 88, 211), + (49, 107, 207), (46, 98, 208), (37, 91, 191), (50, 71, 180), + (61, 62, 170), (73, 48, 139), (77, 22, 126), (52, 29, 120), + (32, 28, 112), (26, 27, 94), (23, 3, 102), (23, 0, 83), + (33, 5, 92), (43, 8, 90), (45, 17, 104), (40, 31, 120), + (30, 36, 134), (22, 59, 130), (18, 49, 93), (6, 24, 88), + (4, 15, 77), (0, 9, 42), (4, 8, 19), (8, 0, 15), + (14, 1, 11), (5, 3, 17), (7, 19, 19), (7, 30, 46), + (0, 33, 49), (6, 24, 60), (0, 33, 80), (9, 34, 65) + ), + +// 362 vchira_0014.jpg +((45, 230, 126), (110, 183, 68), (100, 173, 62), (91, 164, 56), + (81, 152, 60), (72, 140, 65), (51, 132, 84), (31, 124, 103), + (12, 94, 45), (7, 71, 31), (2, 49, 17), (14, 57, 17), + (27, 65, 18), (40, 86, 27), (54, 107, 37), (54, 101, 45), + (55, 96, 54), (93, 147, 113), (56, 137, 113), (19, 127, 114), + (9, 121, 105), (0, 115, 97), (0, 103, 79), (0, 91, 61), + (69, 116, 20), (116, 119, 41), (164, 122, 62), (127, 96, 34), + (91, 70, 7), (74, 59, 3), (57, 48, 0), (35, 49, 16), + (30, 55, 25), (25, 38, 44), (24, 34, 49), (24, 30, 54), + (30, 38, 45), (37, 47, 36), (46, 71, 32), (55, 96, 28), + (99, 119, 0), (114, 123, 21), (129, 127, 42), (111, 84, 61), + (93, 41, 80), (79, 32, 71), (65, 23, 63), (61, 13, 53), + (58, 10, 32), (43, 28, 0), (59, 31, 22), (75, 35, 44), + (136, 65, 54), (198, 95, 64), (184, 136, 53), (171, 177, 43), + (147, 204, 99), (173, 206, 81), (199, 208, 63), (222, 214, 77), + (245, 220, 91), (236, 233, 80), (228, 247, 69), (225, 245, 132), + (222, 229, 177), (146, 208, 183), (191, 200, 197), (237, 192, 212), + (237, 195, 187), (237, 199, 162), (202, 184, 136), (151, 161, 124), + (83, 100, 64), (70, 77, 60), (57, 55, 56), (34, 37, 46), + (12, 19, 37), (6, 16, 25), (0, 13, 14), (0, 31, 13), + (0, 36, 0), (15, 82, 28), (28, 95, 61), (42, 108, 94), + (51, 142, 125), (60, 176, 157), (79, 222, 216), (90, 238, 202), + (14, 191, 173), (10, 150, 137), (6, 110, 101), (3, 84, 84), + (0, 59, 68), (14, 22, 45), (3, 6, 23), (0, 10, 12), + (0, 17, 3), (0, 34, 0), (16, 59, 17), (32, 84, 35), + (53, 97, 56), (74, 111, 78), (121, 163, 81), (132, 186, 126), + (131, 162, 182), (127, 180, 209), (123, 198, 237), (110, 217, 224), + (97, 237, 211), (80, 250, 214), (34, 251, 230), (0, 241, 252), + (61, 236, 229), (103, 210, 218), (119, 178, 213), (136, 146, 208), + (146, 135, 201), (147, 145, 159), (132, 114, 126), (124, 124, 114), + (85, 117, 116), (86, 101, 106), (88, 85, 96), (94, 83, 96), + (100, 82, 96), (145, 89, 126), (138, 70, 119), (97, 8, 136), + (60, 5, 106), (18, 75, 60), (19, 82, 50), (20, 90, 40), + (26, 91, 33), (43, 72, 8), (50, 65, 0), (47, 60, 0), + (36, 44, 7), (20, 50, 3), (4, 57, 0), (2, 52, 0), + (0, 48, 0), (0, 47, 0), (36, 46, 0), (7, 39, 0), + (0, 40, 19), (15, 69, 45), (18, 74, 45), (22, 79, 46), + (39, 64, 61), (81, 53, 101), (140, 28, 201), (188, 44, 191), + (185, 67, 143), (142, 70, 120), (99, 73, 98), (70, 56, 47), + (47, 26, 31), (29, 24, 31), (25, 34, 13), (18, 18, 0), + (4, 13, 0), (0, 24, 2), (1, 25, 1), (3, 27, 0), + (15, 35, 8), (36, 44, 33), (42, 40, 53), (38, 33, 56), + (30, 50, 77), (22, 51, 66), (14, 52, 55), (25, 51, 26), + (36, 42, 16), (42, 31, 9), (45, 5, 13), (36, 11, 14), + (22, 23, 18), (0, 40, 26), (2, 49, 59), (13, 43, 71), + (17, 47, 73), (16, 36, 73), (15, 16, 44), (15, 9, 19), + (0, 33, 0), (14, 44, 5), (29, 56, 11), (60, 78, 18), + (138, 136, 33), (183, 160, 4), (212, 201, 33), (169, 187, 39), + (123, 197, 40), (158, 170, 72), (161, 176, 91), (154, 176, 127), + (162, 167, 135), (163, 147, 173), (184, 104, 163), (135, 84, 143), + (138, 146, 185), (92, 139, 183), (93, 149, 200), (115, 185, 183), + (125, 186, 181), (119, 149, 139), (115, 139, 107), (94, 143, 113), + (106, 164, 116), (145, 175, 167), (146, 229, 187), (204, 236, 173), + (205, 240, 158), (183, 198, 129), (186, 159, 129), (167, 167, 113), + (118, 138, 66), (107, 92, 59), (76, 72, 34), (32, 62, 38), + (20, 92, 46), (59, 96, 65), (134, 137, 92), (152, 203, 144), + (136, 200, 176), (122, 242, 170), (94, 245, 176), (85, 241, 180), + (75, 255, 147), (123, 219, 83), (194, 214, 41), (248, 245, 0), + (210, 236, 41), (207, 219, 85), (218, 213, 111), (190, 201, 122), + (177, 197, 134), (132, 200, 179), (112, 190, 210), (74, 191, 198), + (40, 180, 181), (0, 95, 134), (43, 67, 91), (18, 34, 86), + (18, 23, 53), (0, 3, 37), (12, 11, 42), (58, 3, 60), + (86, 0, 84), (106, 0, 134), (117, 10, 148), (196, 35, 177), + (182, 52, 202), (135, 34, 192), (89, 6, 136), (19, 33, 59) + ), + +// 363 vchira_0015.jpg +((104, 83, 122), (0, 48, 110), (0, 32, 101), (0, 17, 92), + (37, 40, 98), (74, 63, 105), (98, 55, 108), (123, 47, 112), + (125, 61, 121), (128, 63, 125), (132, 66, 130), (154, 113, 147), + (177, 161, 164), (201, 197, 201), (226, 233, 239), (235, 244, 240), + (245, 255, 242), (255, 240, 190), (215, 225, 199), (175, 211, 209), + (106, 156, 173), (37, 101, 137), (26, 83, 134), (15, 66, 132), + (18, 14, 91), (26, 8, 82), (35, 2, 73), (56, 31, 85), + (78, 60, 98), (85, 60, 104), (93, 61, 110), (73, 31, 117), + (59, 21, 98), (44, 0, 60), (53, 24, 61), (62, 48, 63), + (69, 60, 106), (76, 72, 149), (100, 80, 164), (125, 89, 179), + (170, 67, 200), (148, 91, 206), (127, 116, 212), (125, 128, 189), + (123, 140, 166), (128, 154, 196), (133, 168, 226), (151, 193, 253), + (197, 174, 242), (205, 224, 228), (219, 236, 207), (233, 249, 186), + (244, 252, 179), (255, 255, 172), (255, 255, 161), (255, 255, 150), + (247, 218, 20), (251, 220, 96), (255, 223, 172), (245, 218, 199), + (235, 213, 226), (232, 206, 240), (229, 199, 255), (255, 210, 255), + (255, 195, 255), (241, 188, 230), (245, 164, 197), (250, 140, 165), + (242, 142, 169), (235, 145, 173), (179, 98, 139), (157, 124, 151), + (143, 173, 123), (117, 192, 114), (92, 212, 106), (83, 148, 109), + (74, 85, 113), (81, 83, 113), (88, 81, 114), (99, 96, 105), + (150, 130, 119), (217, 205, 153), (220, 193, 172), (223, 181, 191), + (223, 170, 162), (224, 160, 133), (250, 177, 98), (241, 142, 75), + (118, 87, 93), (163, 116, 130), (209, 146, 167), (214, 155, 167), + (220, 164, 167), (193, 178, 175), (179, 178, 158), (116, 142, 159), + (89, 108, 122), (77, 50, 65), (71, 44, 60), (65, 38, 55), + (80, 44, 73), (95, 50, 91), (115, 58, 101), (94, 47, 101), + (33, 24, 55), (50, 36, 65), (67, 49, 75), (82, 65, 94), + (97, 82, 113), (120, 130, 157), (134, 159, 166), (174, 200, 215), + (202, 200, 222), (255, 245, 255), (255, 236, 254), (255, 228, 254), + (203, 206, 225), (180, 202, 226), (167, 140, 217), (108, 115, 170), + (75, 48, 163), (62, 54, 168), (50, 60, 173), (40, 66, 160), + (31, 73, 147), (41, 95, 157), (28, 98, 184), (12, 106, 194), + (33, 103, 189), (96, 140, 211), (114, 148, 217), (132, 157, 224), + (159, 155, 239), (134, 148, 211), (88, 150, 201), (101, 192, 193), + (85, 191, 142), (113, 153, 115), (142, 115, 88), (177, 130, 81), + (212, 145, 75), (234, 169, 51), (249, 182, 29), (255, 201, 85), + (243, 209, 138), (209, 225, 176), (208, 206, 195), (207, 187, 214), + (188, 200, 224), (195, 211, 227), (188, 200, 224), (168, 203, 225), + (111, 125, 170), (89, 113, 163), (67, 102, 156), (49, 70, 135), + (0, 47, 142), (7, 28, 119), (28, 22, 128), (102, 20, 193), + (144, 7, 199), (199, 8, 235), (198, 7, 237), (197, 7, 239), + (148, 27, 230), (123, 41, 239), (139, 79, 237), (149, 59, 193), + (60, 10, 73), (58, 8, 48), (57, 6, 23), (52, 13, 0), + (49, 16, 1), (38, 0, 0), (23, 0, 17), (18, 0, 59), + (14, 25, 55), (32, 30, 79), (43, 56, 91), (47, 50, 93), + (40, 23, 119), (60, 0, 93), (51, 1, 72), (66, 0, 38), + (53, 19, 0), (51, 26, 0), (50, 33, 0), (56, 35, 34), + (54, 39, 70), (57, 64, 74), (82, 49, 120), (128, 29, 148), + (124, 11, 161), (86, 25, 162), (53, 113, 165), (89, 140, 206), + (125, 155, 207), (151, 193, 233), (179, 236, 255), (207, 252, 249), + (247, 255, 255), (255, 236, 229), (224, 189, 219), (186, 163, 215), + (134, 117, 161), (104, 109, 138), (80, 83, 118), (38, 63, 117), + (8, 36, 83), (0, 31, 60), (9, 13, 86), (11, 1, 74), + (0, 16, 68), (0, 2, 61), (31, 8, 60), (64, 8, 35), + (147, 32, 45), (186, 18, 53), (208, 59, 26), (206, 108, 7), + (185, 103, 4), (195, 80, 25), (127, 68, 26), (116, 32, 0), + (96, 20, 0), (82, 4, 0), (76, 0, 0), (30, 0, 2), + (2, 6, 41), (1, 16, 49), (17, 14, 45), (65, 28, 0), + (110, 43, 37), (150, 62, 60), (174, 67, 59), (183, 117, 65), + (170, 143, 52), (207, 120, 27), (233, 84, 41), (233, 84, 41), + (234, 72, 51), (207, 84, 86), (182, 95, 103), (146, 90, 99), + (120, 55, 75), (108, 45, 74), (86, 48, 61), (71, 46, 42), + (67, 32, 64), (125, 10, 65), (158, 5, 85), (152, 32, 57), + (200, 45, 41), (182, 68, 0), (152, 42, 17), (119, 7, 0) + ), + +// 364 vchira_17.jpg +((23, 59, 55), (8, 128, 67), (20, 155, 77), (33, 182, 88), + (38, 184, 83), (43, 186, 78), (33, 178, 85), (23, 171, 93), + (0, 130, 106), (9, 112, 112), (19, 95, 118), (9, 89, 142), + (0, 83, 167), (16, 74, 151), (32, 65, 136), (42, 53, 140), + (53, 42, 144), (117, 10, 186), (127, 8, 150), (137, 7, 115), + (116, 4, 102), (95, 1, 89), (71, 11, 91), (48, 22, 93), + (0, 101, 98), (9, 100, 124), (18, 100, 150), (36, 84, 165), + (55, 68, 180), (65, 65, 191), (76, 63, 203), (104, 51, 204), + (123, 32, 198), (163, 5, 203), (175, 9, 201), (188, 14, 200), + (176, 22, 209), (164, 31, 218), (135, 69, 233), (106, 107, 249), + (19, 135, 134), (32, 165, 111), (46, 196, 88), (47, 205, 100), + (49, 215, 113), (47, 223, 125), (46, 231, 137), (41, 235, 149), + (28, 225, 153), (23, 207, 133), (12, 187, 117), (2, 167, 101), + (15, 160, 109), (29, 153, 117), (18, 157, 133), (7, 161, 149), + (21, 151, 201), (58, 108, 212), (95, 65, 223), (145, 47, 230), + (196, 30, 238), (221, 31, 231), (247, 33, 225), (242, 64, 140), + (186, 82, 91), (112, 0, 119), (90, 44, 163), (68, 89, 208), + (57, 99, 205), (46, 109, 202), (22, 152, 188), (29, 169, 122), + (21, 167, 82), (32, 174, 79), (44, 181, 77), (46, 190, 81), + (48, 199, 86), (49, 199, 85), (51, 199, 85), (58, 211, 97), + (55, 219, 106), (58, 220, 108), (63, 224, 107), (69, 229, 107), + (67, 224, 100), (65, 220, 93), (61, 210, 84), (58, 211, 94), + (51, 211, 101), (37, 196, 100), (24, 181, 100), (12, 170, 103), + (0, 159, 106), (13, 123, 120), (17, 87, 112), (23, 51, 101), + (53, 46, 116), (66, 10, 119), (70, 15, 146), (75, 20, 174), + (74, 21, 177), (74, 23, 180), (85, 19, 155), (80, 37, 168), + (58, 66, 193), (52, 79, 192), (47, 93, 191), (38, 108, 192), + (30, 124, 194), (6, 127, 172), (0, 164, 153), (0, 135, 144), + (3, 136, 131), (0, 116, 122), (4, 88, 111), (9, 61, 100), + (0, 34, 80), (4, 34, 32), (0, 29, 13), (19, 72, 18), + (0, 130, 98), (16, 167, 103), (33, 204, 108), (38, 210, 113), + (43, 217, 119), (43, 223, 136), (18, 211, 164), (1, 215, 187), + (6, 186, 223), (48, 182, 255), (48, 159, 240), (48, 136, 226), + (40, 106, 200), (13, 77, 149), (16, 57, 109), (23, 20, 89), + (130, 0, 86), (129, 15, 86), (129, 30, 87), (119, 25, 115), + (109, 21, 144), (118, 44, 199), (81, 80, 220), (67, 83, 178), + (28, 122, 134), (3, 112, 106), (17, 96, 92), (31, 81, 78), + (35, 79, 78), (11, 111, 85), (11, 132, 97), (16, 156, 95), + (12, 182, 120), (13, 185, 126), (14, 189, 132), (4, 184, 159), + (6, 165, 169), (12, 171, 193), (20, 169, 193), (42, 145, 222), + (65, 140, 242), (47, 158, 240), (32, 177, 219), (17, 197, 198), + (22, 222, 175), (35, 236, 158), (48, 242, 155), (51, 244, 155), + (48, 242, 155), (46, 241, 154), (44, 240, 154), (32, 233, 157), + (21, 222, 167), (18, 211, 182), (40, 163, 231), (100, 132, 241), + (156, 56, 242), (220, 20, 253), (239, 21, 239), (230, 2, 235), + (226, 0, 224), (193, 1, 174), (157, 44, 98), (126, 29, 82), + (36, 0, 40), (22, 6, 47), (9, 12, 55), (11, 23, 95), + (25, 29, 116), (70, 35, 127), (62, 25, 157), (54, 44, 166), + (66, 38, 151), (79, 14, 114), (49, 14, 82), (63, 0, 73), + (70, 0, 65), (98, 0, 73), (100, 3, 70), (122, 16, 64), + (122, 57, 29), (45, 129, 31), (35, 149, 53), (13, 138, 60), + (20, 134, 64), (30, 156, 72), (24, 165, 86), (27, 183, 99), + (32, 208, 123), (43, 231, 137), (44, 233, 141), (44, 236, 150), + (49, 242, 153), (55, 240, 139), (58, 240, 139), (56, 236, 136), + (59, 239, 132), (63, 232, 117), (61, 223, 101), (55, 212, 95), + (54, 212, 99), (54, 218, 106), (56, 227, 113), (42, 231, 139), + (36, 233, 153), (32, 233, 155), (36, 234, 155), (36, 234, 157), + (31, 231, 158), (28, 222, 149), (18, 208, 146), (25, 157, 117), + (2, 126, 102), (0, 64, 91), (36, 5, 46), (68, 9, 29), + (31, 1, 37), (18, 2, 28), (20, 67, 13), (23, 106, 26), + (35, 135, 45), (45, 144, 79), (22, 159, 81), (23, 174, 93), + (25, 196, 118), (38, 211, 121), (36, 228, 143), (39, 236, 154), + (42, 239, 157), (40, 237, 157), (38, 235, 153), (34, 232, 155), + (23, 217, 147), (22, 203, 132), (32, 187, 96), (47, 185, 73) + ), + +// 365 vchira_18pp1.jpg +((74, 7, 183), (102, 15, 208), (108, 66, 231), (115, 117, 254), + (128, 116, 254), (142, 115, 254), (141, 111, 252), (140, 108, 251), + (197, 52, 179), (198, 54, 176), (200, 57, 173), (183, 78, 205), + (166, 99, 238), (152, 130, 246), (139, 162, 255), (130, 165, 250), + (122, 168, 246), (106, 119, 247), (125, 115, 248), (145, 111, 250), + (162, 99, 240), (180, 87, 230), (192, 81, 213), (204, 76, 197), + (242, 106, 178), (225, 76, 166), (208, 46, 155), (194, 31, 146), + (181, 17, 138), (183, 17, 137), (185, 17, 136), (185, 17, 136), + (193, 32, 146), (226, 104, 151), (239, 119, 152), (252, 135, 153), + (253, 167, 173), (255, 199, 194), (253, 211, 198), (251, 223, 202), + (250, 253, 242), (252, 251, 248), (254, 249, 255), (245, 248, 250), + (236, 248, 246), (190, 235, 241), (144, 223, 236), (120, 202, 216), + (145, 162, 255), (255, 167, 255), (251, 171, 234), (248, 176, 214), + (241, 149, 204), (234, 122, 194), (220, 87, 182), (206, 53, 170), + (139, 10, 172), (132, 16, 183), (125, 23, 195), (125, 29, 205), + (126, 35, 216), (132, 40, 219), (139, 46, 222), (143, 72, 230), + (150, 92, 255), (156, 133, 255), (173, 155, 255), (190, 178, 255), + (181, 155, 248), (172, 133, 242), (157, 109, 247), (161, 64, 219), + (169, 14, 142), (158, 9, 114), (148, 5, 87), (127, 4, 91), + (106, 3, 95), (117, 1, 97), (129, 0, 100), (142, 1, 116), + (148, 3, 130), (166, 10, 145), (175, 13, 140), (184, 16, 135), + (184, 15, 132), (184, 15, 130), (185, 13, 125), (186, 15, 130), + (191, 27, 140), (205, 45, 150), (219, 63, 160), (234, 75, 144), + (249, 88, 129), (253, 76, 102), (233, 44, 112), (221, 23, 100), + (206, 23, 105), (157, 4, 87), (165, 3, 94), (174, 2, 102), + (180, 6, 111), (187, 11, 120), (184, 12, 122), (191, 17, 128), + (245, 72, 102), (236, 67, 120), (227, 62, 139), (220, 56, 133), + (213, 51, 127), (215, 41, 138), (193, 20, 128), (186, 12, 123), + (199, 11, 106), (184, 12, 120), (178, 6, 115), (173, 1, 111), + (140, 0, 120), (136, 3, 144), (125, 9, 158), (130, 2, 147), + (152, 7, 148), (160, 10, 147), (169, 13, 146), (169, 17, 153), + (170, 22, 160), (202, 45, 162), (196, 65, 169), (204, 71, 190), + (216, 102, 215), (248, 135, 197), (238, 135, 206), (228, 135, 215), + (232, 170, 233), (189, 189, 255), (178, 219, 241), (245, 191, 217), + (254, 192, 197), (242, 170, 167), (230, 148, 137), (242, 131, 120), + (255, 114, 104), (255, 90, 133), (248, 93, 151), (231, 87, 156), + (215, 50, 155), (172, 8, 129), (164, 6, 132), (156, 5, 136), + (129, 0, 124), (116, 0, 135), (65, 18, 124), (76, 4, 166), + (66, 5, 168), (67, 2, 173), (68, 0, 179), (59, 2, 192), + (74, 0, 199), (96, 18, 215), (112, 74, 247), (137, 92, 247), + (155, 79, 231), (171, 34, 182), (172, 31, 173), (174, 28, 165), + (168, 21, 163), (155, 18, 170), (130, 45, 166), (123, 58, 210), + (113, 112, 231), (140, 106, 235), (167, 100, 239), (218, 114, 225), + (246, 128, 204), (250, 143, 185), (244, 152, 203), (243, 155, 203), + (187, 144, 213), (116, 170, 244), (68, 149, 231), (85, 192, 212), + (126, 231, 224), (207, 255, 226), (245, 255, 244), (238, 245, 253), + (255, 239, 255), (245, 230, 255), (236, 222, 255), (240, 199, 243), + (217, 155, 238), (150, 112, 251), (84, 72, 240), (77, 0, 196), + (72, 0, 204), (27, 1, 222), (55, 89, 213), (47, 153, 201), + (60, 165, 212), (36, 159, 192), (28, 150, 191), (43, 119, 229), + (86, 88, 248), (112, 18, 192), (117, 7, 182), (137, 13, 173), + (163, 21, 167), (167, 38, 165), (160, 111, 193), (118, 159, 238), + (109, 169, 242), (119, 165, 250), (142, 144, 255), (135, 96, 241), + (153, 51, 212), (141, 26, 192), (153, 14, 165), (164, 12, 147), + (179, 17, 139), (184, 20, 143), (168, 22, 157), (146, 15, 173), + (139, 26, 194), (138, 29, 198), (126, 23, 190), (137, 15, 178), + (158, 14, 164), (173, 27, 164), (175, 21, 155), (188, 30, 153), + (212, 50, 161), (223, 81, 165), (236, 103, 158), (255, 135, 172), + (251, 143, 175), (242, 169, 189), (249, 222, 192), (255, 227, 218), + (253, 237, 237), (255, 240, 255), (246, 228, 228), (255, 215, 223), + (233, 185, 245), (168, 115, 245), (151, 77, 234), (133, 39, 215), + (117, 12, 192), (114, 10, 181), (102, 5, 183), (101, 10, 176), + (113, 10, 154), (114, 0, 161), (100, 5, 185), (97, 17, 214), + (81, 81, 239), (44, 121, 229), (75, 177, 217), (52, 169, 202) + ), + +// 366 vchira_19.jpg +((225, 128, 161), (246, 212, 86), (231, 233, 65), (216, 254, 44), + (158, 206, 23), (101, 158, 3), (102, 126, 1), (104, 95, 0), + (189, 151, 6), (206, 193, 8), (224, 235, 11), (213, 245, 24), + (203, 255, 37), (155, 249, 56), (107, 243, 75), (98, 244, 98), + (90, 246, 121), (207, 243, 91), (200, 230, 116), (193, 217, 141), + (173, 228, 146), (154, 240, 151), (121, 242, 138), (89, 244, 126), + (13, 244, 212), (7, 190, 176), (1, 136, 140), (1, 93, 108), + (1, 51, 76), (9, 37, 62), (17, 23, 49), (7, 23, 23), + (3, 12, 17), (6, 45, 0), (27, 62, 2), (49, 79, 5), + (90, 116, 8), (131, 154, 11), (137, 192, 34), (144, 230, 57), + (173, 225, 127), (93, 168, 109), (13, 112, 92), (12, 88, 70), + (12, 65, 49), (7, 59, 58), (2, 54, 67), (19, 54, 94), + (35, 46, 110), (13, 38, 95), (37, 51, 52), (62, 65, 10), + (63, 66, 11), (65, 68, 13), (43, 66, 10), (21, 64, 8), + (2, 41, 10), (35, 43, 5), (69, 45, 0), (104, 70, 0), + (139, 95, 0), (160, 122, 0), (182, 149, 0), (226, 229, 0), + (248, 239, 12), (241, 250, 0), (247, 251, 0), (253, 252, 1), + (250, 251, 5), (247, 250, 9), (245, 255, 11), (229, 249, 30), + (241, 233, 44), (248, 168, 93), (255, 103, 143), (250, 83, 147), + (246, 64, 151), (246, 100, 142), (246, 137, 134), (255, 160, 98), + (251, 157, 57), (171, 149, 1), (125, 111, 0), (80, 74, 0), + (55, 91, 16), (30, 108, 32), (10, 137, 86), (0, 159, 131), + (59, 253, 190), (89, 221, 180), (120, 189, 170), (135, 192, 165), + (150, 196, 160), (101, 134, 165), (45, 146, 106), (74, 96, 50), + (37, 73, 11), (0, 37, 29), (0, 36, 28), (0, 35, 28), + (1, 35, 42), (3, 35, 56), (5, 42, 68), (24, 17, 85), + (38, 11, 82), (31, 5, 51), (25, 0, 21), (28, 3, 24), + (31, 6, 27), (33, 1, 50), (56, 0, 65), (89, 1, 79), + (106, 0, 110), (146, 0, 134), (168, 1, 150), (191, 2, 166), + (238, 60, 148), (238, 108, 82), (229, 142, 39), (233, 203, 0), + (180, 122, 25), (148, 92, 12), (116, 63, 0), (93, 50, 0), + (70, 38, 0), (42, 8, 0), (28, 1, 0), (29, 10, 12), + (41, 10, 8), (87, 0, 33), (119, 6, 62), (151, 13, 91), + (192, 10, 129), (201, 2, 179), (213, 7, 177), (210, 11, 192), + (144, 22, 209), (72, 81, 164), (1, 140, 119), (1, 129, 109), + (2, 118, 99), (7, 106, 62), (5, 68, 41), (2, 50, 26), + (10, 40, 14), (1, 90, 62), (1, 101, 80), (1, 113, 99), + (6, 136, 90), (9, 152, 99), (0, 173, 138), (15, 224, 167), + (46, 169, 102), (43, 157, 64), (40, 145, 27), (48, 85, 7), + (58, 99, 3), (56, 145, 1), (52, 144, 35), (70, 176, 28), + (54, 182, 61), (122, 217, 65), (83, 176, 52), (45, 135, 39), + (26, 61, 7), (22, 16, 0), (11, 8, 0), (0, 18, 0), + (8, 3, 7), (8, 3, 3), (8, 3, 0), (2, 1, 9), + (3, 3, 13), (2, 1, 6), (3, 0, 4), (8, 0, 0), + (4, 2, 7), (6, 0, 11), (15, 0, 21), (29, 6, 26), + (43, 0, 28), (75, 0, 61), (99, 1, 86), (110, 0, 93), + (70, 3, 80), (55, 1, 74), (41, 0, 69), (28, 4, 54), + (59, 1, 23), (74, 20, 18), (98, 23, 28), (142, 46, 34), + (148, 65, 21), (163, 79, 68), (202, 73, 91), (153, 15, 64), + (138, 20, 52), (135, 21, 57), (132, 8, 58), (113, 23, 48), + (86, 3, 55), (55, 9, 11), (53, 5, 5), (55, 22, 5), + (75, 42, 9), (56, 63, 12), (47, 32, 9), (29, 42, 0), + (32, 39, 0), (100, 71, 3), (156, 90, 16), (200, 117, 15), + (236, 197, 14), (248, 242, 32), (255, 251, 34), (248, 252, 15), + (235, 255, 12), (233, 252, 20), (197, 226, 40), (164, 190, 7), + (107, 126, 1), (89, 89, 0), (65, 138, 0), (59, 148, 0), + (96, 159, 10), (117, 175, 13), (139, 187, 0), (194, 216, 19), + (181, 174, 21), (183, 73, 58), (200, 44, 92), (250, 38, 184), + (216, 3, 189), (216, 5, 195), (229, 7, 216), (253, 27, 222), + (229, 143, 180), (234, 178, 129), (235, 185, 98), (223, 211, 65), + (177, 255, 71), (225, 229, 54), (233, 225, 38), (242, 185, 20), + (196, 110, 25), (119, 65, 18), (71, 43, 19), (51, 19, 22), + (36, 30, 56), (31, 30, 108), (106, 0, 110), (144, 4, 175), + (172, 12, 182), (149, 9, 168), (113, 61, 109), (9, 65, 114) + ), + +// 367 vchira_28.jpg +((0, 2, 44), (0, 71, 177), (12, 101, 195), (24, 131, 213), + (13, 117, 214), (3, 103, 215), (5, 91, 190), (8, 80, 165), + (26, 68, 108), (29, 55, 79), (33, 42, 51), (60, 51, 45), + (88, 61, 40), (75, 69, 60), (63, 77, 80), (47, 65, 78), + (31, 53, 76), (25, 35, 47), (38, 20, 26), (52, 6, 6), + (54, 12, 8), (56, 19, 11), (63, 26, 10), (70, 34, 10), + (114, 41, 6), (79, 38, 14), (45, 35, 23), (43, 24, 12), + (42, 14, 2), (27, 10, 3), (12, 7, 4), (3, 2, 0), + (4, 1, 10), (13, 3, 4), (54, 16, 18), (96, 30, 32), + (130, 62, 31), (164, 95, 30), (178, 97, 27), (192, 100, 25), + (166, 124, 74), (172, 144, 111), (178, 165, 149), (210, 170, 104), + (242, 175, 60), (248, 199, 43), (255, 223, 26), (252, 233, 69), + (254, 242, 122), (221, 225, 250), (188, 184, 193), (156, 143, 137), + (115, 112, 113), (74, 81, 89), (71, 67, 83), (68, 54, 77), + (40, 44, 56), (55, 74, 97), (70, 104, 139), (122, 147, 172), + (174, 190, 205), (183, 198, 211), (193, 207, 218), (193, 199, 231), + (173, 194, 215), (101, 137, 161), (82, 84, 145), (63, 31, 130), + (64, 15, 85), (65, 0, 40), (50, 3, 19), (72, 6, 16), + (105, 12, 23), (109, 15, 20), (114, 19, 17), (99, 12, 22), + (84, 6, 28), (88, 5, 37), (93, 5, 47), (133, 5, 53), + (165, 26, 19), (153, 22, 27), (103, 49, 68), (54, 77, 109), + (49, 80, 131), (45, 83, 154), (24, 83, 163), (52, 94, 168), + (3, 67, 191), (17, 58, 193), (32, 50, 196), (54, 38, 208), + (76, 26, 221), (88, 39, 208), (151, 23, 208), (203, 1, 209), + (137, 6, 180), (110, 35, 187), (78, 60, 195), (46, 85, 204), + (26, 71, 192), (7, 57, 180), (0, 40, 130), (11, 43, 84), + (12, 9, 76), (17, 10, 87), (22, 12, 99), (19, 20, 121), + (17, 28, 143), (2, 51, 172), (11, 52, 180), (16, 46, 178), + (61, 11, 162), (51, 6, 75), (34, 4, 56), (18, 2, 38), + (7, 14, 22), (0, 6, 22), (1, 11, 36), (0, 10, 37), + (0, 9, 70), (6, 7, 71), (12, 5, 72), (15, 3, 57), + (18, 1, 43), (35, 0, 49), (60, 8, 12), (115, 26, 0), + (171, 53, 3), (199, 97, 35), (182, 112, 59), (165, 128, 84), + (192, 156, 158), (203, 193, 201), (218, 203, 198), (220, 212, 201), + (223, 206, 160), (220, 200, 160), (218, 195, 161), (211, 185, 148), + (204, 176, 136), (187, 139, 77), (220, 149, 57), (213, 125, 15), + (221, 94, 23), (221, 36, 112), (199, 22, 120), (177, 9, 128), + (159, 2, 143), (165, 1, 192), (208, 10, 181), (255, 48, 198), + (218, 145, 162), (207, 150, 166), (196, 155, 171), (200, 113, 147), + (223, 35, 129), (179, 5, 152), (151, 1, 135), (108, 2, 172), + (87, 0, 85), (16, 6, 30), (10, 3, 22), (4, 0, 14), + (5, 6, 10), (34, 12, 1), (56, 29, 10), (98, 38, 2), + (186, 44, 34), (189, 30, 48), (193, 17, 63), (205, 45, 73), + (222, 17, 112), (188, 40, 114), (157, 119, 80), (126, 107, 153), + (71, 113, 153), (64, 115, 162), (36, 130, 204), (48, 120, 204), + (87, 72, 213), (77, 20, 185), (78, 25, 129), (104, 12, 59), + (138, 72, 12), (148, 74, 7), (158, 76, 3), (183, 82, 2), + (203, 104, 2), (219, 102, 0), (226, 116, 1), (208, 116, 7), + (209, 117, 16), (192, 105, 34), (167, 105, 54), (85, 92, 98), + (85, 89, 90), (57, 60, 49), (43, 39, 38), (67, 35, 12), + (111, 54, 11), (176, 90, 15), (222, 96, 55), (237, 172, 68), + (222, 170, 86), (179, 125, 63), (144, 100, 55), (134, 83, 52), + (75, 56, 39), (27, 34, 40), (16, 29, 45), (1, 10, 51), + (7, 27, 77), (1, 21, 84), (10, 50, 99), (0, 33, 114), + (2, 32, 122), (1, 56, 147), (17, 94, 172), (71, 147, 196), + (105, 168, 211), (154, 186, 211), (199, 213, 216), (220, 218, 219), + (223, 224, 226), (222, 217, 211), (194, 209, 216), (134, 214, 247), + (121, 164, 217), (94, 177, 227), (77, 148, 214), (78, 159, 214), + (56, 181, 235), (27, 150, 228), (61, 144, 212), (62, 81, 222), + (62, 36, 189), (91, 2, 152), (101, 1, 89), (95, 1, 75), + (52, 2, 51), (84, 3, 44), (145, 9, 55), (196, 18, 104), + (219, 36, 119), (211, 19, 154), (224, 1, 212), (213, 5, 215), + (185, 1, 175), (113, 34, 141), (125, 0, 82), (123, 18, 61), + (129, 103, 76), (174, 141, 126), (232, 222, 212), (217, 189, 168) + ), + +// 368 vchira_2pp1.jpg +((179, 181, 0), (231, 161, 3), (239, 153, 1), (248, 146, 0), + (210, 116, 0), (173, 87, 0), (165, 82, 0), (157, 78, 0), + (133, 20, 26), (108, 15, 59), (84, 11, 92), (65, 29, 94), + (46, 48, 97), (23, 39, 162), (1, 31, 227), (4, 40, 240), + (7, 50, 253), (12, 165, 199), (17, 158, 160), (23, 152, 121), + (28, 147, 84), (33, 143, 48), (39, 151, 43), (46, 160, 38), + (16, 90, 93), (9, 68, 140), (2, 47, 188), (22, 38, 211), + (42, 30, 234), (51, 15, 208), (60, 0, 183), (92, 21, 141), + (122, 33, 61), (235, 140, 0), (223, 191, 2), (212, 242, 4), + (157, 242, 9), (103, 243, 14), (78, 243, 21), (53, 244, 29), + (17, 236, 118), (39, 187, 115), (61, 139, 113), (54, 135, 84), + (48, 132, 55), (31, 131, 77), (15, 130, 99), (15, 66, 113), + (3, 71, 144), (2, 141, 122), (8, 100, 116), (14, 60, 110), + (46, 35, 106), (79, 10, 103), (84, 10, 100), (90, 10, 97), + (56, 41, 100), (47, 87, 65), (39, 134, 30), (21, 185, 30), + (4, 237, 31), (9, 240, 31), (15, 243, 32), (39, 250, 25), + (40, 248, 15), (86, 197, 33), (105, 169, 16), (124, 141, 0), + (86, 140, 0), (48, 139, 0), (0, 135, 0), (26, 203, 24), + (117, 234, 44), (180, 213, 60), (244, 193, 76), (244, 192, 66), + (244, 192, 56), (248, 198, 50), (252, 204, 44), (225, 247, 24), + (230, 255, 32), (254, 227, 0), (249, 179, 0), (244, 132, 0), + (249, 103, 0), (255, 75, 1), (253, 43, 10), (255, 23, 12), + (247, 3, 75), (152, 2, 130), (58, 2, 185), (36, 9, 195), + (15, 16, 205), (8, 12, 221), (19, 9, 230), (10, 16, 252), + (7, 33, 254), (6, 85, 203), (15, 88, 196), (24, 92, 189), + (14, 88, 213), (5, 84, 237), (21, 74, 238), (33, 58, 213), + (172, 146, 111), (126, 194, 84), (80, 243, 58), (48, 238, 61), + (17, 234, 65), (22, 234, 87), (22, 209, 128), (3, 176, 133), + (39, 139, 189), (23, 8, 211), (69, 10, 188), (115, 12, 165), + (188, 2, 113), (226, 1, 67), (213, 8, 51), (228, 22, 24), + (227, 51, 62), (178, 30, 93), (130, 9, 125), (98, 5, 145), + (66, 1, 165), (55, 6, 194), (30, 2, 200), (47, 3, 162), + (75, 2, 119), (110, 13, 80), (128, 14, 71), (146, 16, 62), + (155, 5, 76), (154, 15, 57), (195, 29, 29), (252, 46, 9), + (243, 77, 3), (218, 67, 11), (193, 57, 19), (175, 63, 23), + (157, 70, 27), (133, 68, 40), (128, 41, 58), (111, 77, 39), + (45, 142, 47), (46, 200, 70), (56, 213, 58), (67, 226, 46), + (80, 249, 6), (128, 238, 3), (205, 219, 8), (233, 211, 29), + (192, 106, 0), (185, 90, 0), (179, 75, 0), (162, 69, 51), + (102, 76, 113), (51, 86, 92), (45, 140, 56), (37, 198, 69), + (21, 226, 25), (27, 227, 7), (35, 234, 15), (43, 241, 24), + (73, 240, 10), (78, 225, 12), (56, 207, 32), (66, 214, 66), + (68, 206, 252), (49, 144, 241), (31, 83, 231), (30, 48, 246), + (1, 22, 251), (1, 11, 230), (3, 19, 236), (21, 23, 248), + (11, 38, 239), (0, 43, 213), (0, 33, 206), (9, 23, 171), + (6, 48, 146), (7, 47, 134), (11, 46, 127), (13, 25, 123), + (83, 66, 59), (85, 89, 32), (87, 113, 6), (148, 132, 0), + (176, 134, 0), (193, 160, 0), (188, 170, 0), (199, 188, 0), + (207, 180, 3), (224, 150, 27), (222, 142, 45), (222, 119, 86), + (255, 168, 71), (242, 146, 59), (237, 85, 46), (243, 61, 11), + (220, 70, 9), (197, 91, 15), (143, 74, 7), (33, 82, 3), + (47, 140, 7), (59, 198, 9), (124, 227, 0), (199, 247, 3), + (215, 231, 11), (226, 228, 7), (240, 182, 13), (234, 154, 15), + (221, 167, 9), (164, 181, 43), (152, 188, 18), (118, 209, 7), + (168, 196, 0), (159, 163, 14), (165, 133, 0), (143, 139, 3), + (139, 158, 0), (89, 195, 1), (63, 211, 0), (61, 219, 0), + (119, 235, 4), (164, 244, 5), (215, 234, 18), (237, 235, 12), + (255, 195, 40), (253, 142, 8), (245, 112, 7), (221, 128, 7), + (156, 142, 0), (120, 200, 5), (70, 204, 19), (28, 241, 35), + (11, 252, 49), (66, 228, 46), (128, 242, 9), (178, 229, 4), + (218, 208, 32), (241, 180, 14), (240, 147, 7), (232, 118, 4), + (249, 52, 7), (250, 23, 14), (223, 1, 24), (193, 11, 34), + (207, 5, 21), (218, 0, 14), (227, 12, 7), (254, 34, 8), + (246, 75, 3), (228, 107, 2), (186, 201, 76), (193, 125, 24) + ), + +// 369 00017 +((86, 162, 180), (79, 164, 187), (79, 163, 189), (80, 162, 191), + (86, 163, 190), (93, 164, 189), (96, 164, 188), (100, 164, 188), + (105, 163, 185), (102, 167, 183), (100, 171, 182), (97, 176, 180), + (94, 182, 179), (90, 190, 178), (87, 198, 177), (87, 202, 176), + (88, 206, 175), (95, 223, 178), (102, 226, 178), (109, 230, 178), + (117, 231, 175), (125, 233, 173), (128, 232, 171), (131, 231, 170), + (145, 226, 164), (149, 223, 164), (153, 220, 164), (157, 217, 164), + (162, 215, 164), (161, 214, 163), (160, 214, 163), (161, 210, 162), + (163, 206, 164), (166, 196, 172), (167, 190, 175), (168, 185, 179), + (169, 178, 181), (171, 172, 184), (173, 168, 183), (176, 165, 183), + (189, 149, 180), (192, 139, 181), (195, 130, 183), (195, 123, 186), + (196, 117, 189), (193, 114, 191), (190, 111, 193), (184, 106, 197), + (177, 103, 202), (163, 101, 209), (156, 103, 211), (149, 106, 214), + (142, 108, 213), (135, 110, 213), (133, 112, 211), (132, 114, 209), + (131, 122, 200), (135, 122, 199), (140, 123, 198), (142, 120, 196), + (145, 118, 194), (144, 116, 192), (144, 114, 191), (141, 110, 186), + (139, 105, 180), (136, 103, 170), (133, 102, 169), (131, 101, 169), + (129, 100, 169), (127, 100, 169), (127, 98, 170), (127, 98, 170), + (125, 99, 171), (126, 103, 169), (127, 107, 168), (127, 108, 170), + (127, 109, 172), (126, 109, 172), (126, 109, 172), (125, 107, 170), + (125, 106, 167), (128, 107, 166), (126, 107, 169), (124, 108, 173), + (123, 107, 176), (123, 107, 179), (121, 106, 183), (117, 103, 188), + (108, 98, 189), (104, 103, 189), (100, 108, 190), (98, 111, 192), + (96, 114, 194), (91, 121, 200), (87, 128, 202), (83, 134, 203), + (78, 142, 204), (69, 158, 197), (62, 161, 190), (55, 165, 183), + (55, 167, 179), (55, 169, 176), (57, 175, 172), (58, 183, 168), + (57, 190, 160), (55, 191, 157), (53, 192, 155), (51, 191, 155), + (50, 191, 155), (50, 191, 150), (54, 191, 145), (61, 191, 141), + (68, 191, 140), (82, 189, 136), (84, 188, 135), (86, 187, 135), + (92, 181, 129), (102, 178, 125), (112, 179, 120), (123, 182, 115), + (140, 187, 106), (146, 184, 102), (152, 181, 98), (152, 178, 98), + (153, 175, 98), (156, 169, 98), (163, 164, 98), (169, 160, 103), + (175, 157, 108), (182, 154, 126), (181, 151, 129), (181, 148, 133), + (183, 139, 139), (187, 129, 142), (195, 121, 147), (203, 115, 151), + (221, 108, 158), (226, 102, 162), (231, 96, 166), (231, 92, 168), + (232, 88, 170), (232, 82, 174), (231, 78, 178), (230, 75, 179), + (229, 74, 178), (228, 78, 177), (227, 79, 176), (227, 81, 175), + (226, 81, 171), (226, 79, 171), (227, 76, 173), (227, 71, 177), + (229, 64, 182), (226, 63, 181), (224, 62, 180), (218, 62, 178), + (212, 61, 176), (204, 61, 174), (197, 62, 172), (190, 63, 173), + (184, 62, 172), (171, 65, 164), (167, 66, 159), (163, 67, 155), + (154, 70, 145), (148, 72, 139), (144, 73, 135), (141, 72, 134), + (142, 71, 132), (141, 71, 131), (141, 71, 131), (143, 71, 132), + (145, 67, 132), (145, 64, 131), (145, 60, 136), (144, 53, 144), + (145, 45, 152), (145, 38, 162), (145, 32, 167), (143, 29, 165), + (141, 29, 164), (140, 30, 162), (138, 32, 160), (139, 36, 158), + (147, 36, 149), (148, 36, 148), (150, 36, 147), (153, 32, 145), + (155, 29, 144), (157, 28, 144), (157, 27, 145), (158, 26, 143), + (162, 26, 146), (170, 28, 150), (175, 29, 153), (179, 29, 153), + (182, 28, 154), (181, 27, 152), (177, 30, 149), (172, 32, 145), + (166, 36, 138), (159, 40, 131), (151, 43, 123), (144, 46, 121), + (137, 52, 121), (128, 58, 123), (118, 62, 121), (109, 65, 120), + (105, 70, 120), (102, 75, 122), (99, 79, 124), (98, 83, 130), + (98, 85, 136), (96, 88, 143), (93, 92, 152), (91, 96, 159), + (92, 101, 164), (92, 104, 165), (94, 105, 167), (97, 107, 172), + (99, 109, 178), (98, 109, 184), (94, 107, 187), (92, 106, 190), + (91, 107, 192), (90, 109, 196), (91, 114, 202), (95, 121, 205), + (101, 127, 207), (105, 134, 210), (108, 140, 211), (112, 145, 210), + (114, 149, 208), (113, 149, 205), (112, 152, 203), (113, 156, 202), + (114, 160, 201), (115, 159, 201), (116, 155, 201), (119, 151, 201), + (121, 145, 200), (126, 137, 200), (129, 130, 199), (134, 123, 194), + (137, 117, 190), (135, 114, 186), (134, 113, 181), (131, 115, 178), + (127, 116, 175), (121, 120, 174), (113, 126, 173), (109, 136, 174), + (105, 143, 175), (101, 149, 176), (97, 154, 177), (90, 159, 179) + ), + +// 370 040208-115 +((88, 175, 222), (100, 187, 234), (106, 192, 238), (113, 197, 242), + (108, 187, 227), (103, 178, 212), (98, 177, 207), (94, 176, 203), + (133, 142, 168), (143, 146, 166), (153, 151, 165), (141, 157, 164), + (129, 163, 163), (111, 142, 134), (94, 122, 105), (89, 123, 109), + (84, 124, 114), (51, 103, 100), (40, 66, 82), (29, 29, 65), + (58, 26, 89), (87, 23, 113), (102, 30, 128), (117, 37, 144), + (78, 72, 130), (80, 126, 166), (83, 181, 203), (68, 167, 204), + (54, 153, 206), (53, 152, 203), (53, 152, 201), (48, 152, 200), + (59, 148, 193), (54, 146, 192), (46, 141, 185), (39, 137, 179), + (35, 120, 161), (31, 104, 144), (28, 97, 120), (26, 91, 97), + (10, 36, 43), (11, 28, 31), (13, 21, 19), (6, 11, 10), + (0, 2, 1), (0, 1, 1), (0, 0, 1), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 3, 3), (0, 6, 7), (6, 13, 16), (13, 21, 26), + (28, 24, 29), (24, 22, 36), (20, 21, 43), (35, 38, 52), + (51, 56, 62), (56, 62, 66), (62, 68, 70), (64, 94, 88), + (129, 103, 110), (170, 125, 134), (174, 145, 154), (179, 166, 174), + (181, 169, 180), (184, 173, 187), (179, 178, 200), (187, 203, 225), + (181, 195, 238), (182, 205, 244), (184, 216, 250), (178, 220, 244), + (173, 224, 238), (167, 213, 231), (162, 202, 225), (157, 180, 215), + (157, 177, 212), (160, 163, 190), (150, 176, 198), (141, 189, 206), + (135, 189, 207), (130, 189, 209), (125, 184, 223), (119, 197, 238), + (119, 192, 244), (129, 205, 245), (140, 219, 247), (145, 233, 250), + (151, 247, 253), (149, 252, 255), (151, 254, 255), (160, 238, 255), + (176, 238, 255), (178, 235, 241), (164, 208, 220), (151, 182, 200), + (149, 184, 193), (148, 186, 187), (136, 188, 190), (119, 169, 176), + (138, 176, 190), (133, 174, 195), (129, 173, 200), (130, 165, 196), + (132, 158, 192), (91, 97, 179), (103, 92, 187), (131, 110, 189), + (182, 133, 187), (153, 141, 168), (156, 143, 161), (160, 146, 155), + (160, 130, 136), (162, 125, 126), (163, 101, 100), (170, 78, 78), + (190, 67, 83), (212, 55, 71), (234, 43, 59), (218, 52, 71), + (203, 62, 83), (204, 81, 97), (206, 84, 106), (225, 88, 129), + (222, 56, 72), (215, 94, 118), (221, 96, 127), (227, 99, 137), + (212, 97, 116), (225, 95, 117), (234, 100, 116), (231, 113, 131), + (219, 151, 169), (208, 146, 169), (198, 141, 169), (191, 139, 158), + (185, 138, 148), (163, 106, 112), (163, 84, 89), (160, 61, 69), + (160, 51, 69), (125, 50, 74), (114, 38, 63), (103, 26, 53), + (27, 13, 51), (2, 11, 35), (5, 0, 7), (1, 0, 2), + (28, 0, 35), (35, 3, 43), (42, 7, 51), (80, 12, 95), + (100, 40, 93), (110, 31, 60), (143, 32, 52), (125, 44, 37), + (118, 35, 58), (100, 10, 103), (105, 13, 104), (110, 16, 105), + (141, 35, 132), (170, 86, 162), (181, 100, 157), (151, 118, 157), + (140, 97, 108), (136, 92, 102), (132, 88, 97), (129, 100, 106), + (129, 116, 126), (99, 112, 122), (65, 94, 125), (61, 87, 116), + (67, 71, 103), (130, 70, 98), (138, 53, 50), (141, 51, 52), + (146, 40, 57), (151, 32, 48), (144, 45, 53), (160, 51, 58), + (160, 42, 44), (166, 48, 52), (173, 54, 60), (187, 62, 85), + (189, 67, 85), (187, 64, 82), (179, 67, 71), (176, 62, 66), + (170, 67, 68), (174, 61, 65), (170, 64, 66), (165, 65, 64), + (162, 65, 70), (166, 83, 88), (166, 88, 93), (163, 89, 91), + (157, 102, 97), (157, 106, 116), (160, 95, 97), (154, 96, 94), + (152, 114, 113), (144, 124, 128), (134, 129, 140), (118, 123, 135), + (119, 143, 136), (114, 148, 137), (116, 155, 145), (108, 158, 170), + (103, 164, 166), (102, 211, 182), (116, 247, 234), (118, 249, 247), + (129, 248, 250), (135, 250, 247), (149, 250, 247), (141, 246, 245), + (141, 249, 240), (146, 247, 247), (146, 211, 236), (148, 203, 228), + (144, 226, 228), (136, 199, 233), (135, 174, 222), (148, 193, 225), + (166, 192, 219), (182, 208, 244), (197, 219, 250), (214, 222, 252), + (215, 219, 250), (193, 216, 252), (173, 223, 253), (160, 222, 253), + (144, 221, 244), (129, 206, 236), (125, 203, 233), (102, 239, 230), + (99, 204, 199), (84, 169, 197), (70, 137, 149), (21, 119, 101), + (24, 99, 91), (24, 62, 56), (23, 46, 40), (26, 26, 27), + (26, 32, 30), (34, 46, 42), (35, 92, 67), (48, 101, 113), + (62, 107, 119), (62, 139, 160), (62, 150, 184), (72, 171, 220) + ), + +// 371 040221-00 +((112, 84, 74), (97, 83, 80), (96, 83, 80), (95, 84, 81), + (92, 77, 73), (90, 71, 66), (86, 67, 62), (82, 63, 58), + (67, 43, 40), (65, 36, 33), (64, 30, 27), (68, 26, 21), + (73, 22, 16), (80, 19, 12), (87, 17, 9), (90, 16, 8), + (93, 16, 7), (111, 21, 7), (121, 25, 9), (131, 29, 12), + (137, 32, 13), (143, 36, 14), (144, 35, 13), (146, 35, 13), + (148, 37, 13), (149, 39, 14), (151, 42, 15), (144, 45, 18), + (138, 48, 21), (132, 46, 21), (127, 45, 22), (112, 41, 22), + (96, 35, 20), (69, 23, 13), (61, 20, 11), (54, 17, 10), + (52, 16, 9), (50, 15, 9), (49, 14, 9), (48, 14, 9), + (49, 12, 11), (54, 16, 14), (59, 21, 18), (70, 30, 26), + (81, 39, 34), (88, 43, 38), (95, 48, 42), (110, 59, 49), + (123, 68, 57), (141, 85, 73), (149, 94, 82), (157, 103, 92), + (161, 108, 97), (166, 113, 102), (169, 114, 101), (172, 115, 100), + (170, 106, 89), (164, 97, 80), (158, 88, 72), (149, 78, 65), + (140, 69, 58), (138, 64, 53), (137, 60, 49), (132, 52, 39), + (135, 52, 39), (136, 50, 36), (131, 51, 39), (126, 52, 42), + (124, 53, 44), (123, 55, 46), (111, 49, 42), (109, 52, 48), + (115, 61, 53), (115, 66, 58), (115, 71, 63), (111, 75, 67), + (108, 79, 72), (103, 77, 72), (98, 76, 72), (95, 76, 70), + (98, 75, 66), (117, 78, 60), (132, 90, 71), (147, 103, 83), + (153, 110, 90), (159, 117, 97), (170, 131, 114), (176, 141, 125), + (185, 148, 130), (190, 152, 134), (195, 157, 139), (199, 162, 143), + (203, 167, 148), (214, 182, 166), (221, 196, 183), (226, 206, 198), + (226, 213, 207), (220, 214, 211), (220, 215, 211), (221, 216, 212), + (223, 219, 215), (226, 222, 218), (234, 228, 224), (243, 236, 231), + (244, 239, 238), (237, 233, 232), (231, 227, 226), (226, 222, 220), + (222, 218, 215), (210, 206, 203), (202, 196, 192), (191, 184, 181), + (181, 173, 171), (170, 165, 165), (169, 164, 164), (169, 164, 163), + (169, 165, 164), (172, 169, 168), (176, 172, 172), (178, 175, 175), + (183, 182, 183), (182, 182, 182), (181, 183, 182), (180, 183, 182), + (180, 183, 182), (179, 180, 180), (177, 177, 174), (174, 168, 166), + (173, 161, 156), (169, 142, 129), (168, 138, 123), (168, 135, 117), + (168, 126, 105), (170, 123, 98), (172, 119, 92), (175, 117, 91), + (190, 118, 87), (198, 119, 85), (207, 120, 84), (210, 119, 83), + (213, 118, 83), (216, 117, 79), (210, 111, 78), (201, 104, 71), + (190, 96, 65), (178, 85, 52), (178, 82, 48), (178, 79, 45), + (180, 76, 38), (180, 73, 33), (179, 72, 28), (175, 72, 25), + (176, 74, 28), (180, 76, 30), (185, 79, 32), (196, 85, 39), + (208, 90, 46), (217, 99, 51), (223, 105, 54), (226, 109, 58), + (227, 109, 59), (223, 99, 56), (222, 93, 54), (221, 87, 52), + (215, 81, 49), (209, 75, 44), (202, 72, 39), (195, 69, 33), + (192, 69, 26), (192, 67, 26), (192, 66, 26), (191, 63, 27), + (189, 59, 28), (185, 58, 29), (177, 58, 30), (172, 63, 35), + (168, 70, 42), (170, 79, 49), (172, 84, 58), (174, 86, 64), + (174, 86, 67), (167, 82, 66), (154, 76, 63), (139, 69, 58), + (114, 60, 49), (110, 58, 48), (106, 56, 47), (103, 52, 44), + (105, 49, 41), (111, 46, 36), (115, 44, 32), (120, 48, 29), + (125, 51, 28), (133, 55, 30), (141, 61, 31), (151, 68, 35), + (162, 74, 41), (174, 80, 47), (184, 86, 51), (190, 91, 54), + (193, 91, 55), (192, 90, 55), (188, 89, 53), (184, 90, 54), + (182, 88, 55), (182, 87, 55), (181, 86, 53), (177, 81, 49), + (175, 76, 44), (171, 70, 36), (169, 67, 35), (168, 65, 36), + (172, 69, 40), (178, 75, 45), (180, 83, 54), (183, 91, 60), + (185, 97, 65), (188, 101, 72), (189, 105, 77), (192, 111, 87), + (194, 117, 95), (197, 123, 105), (197, 130, 113), (190, 136, 121), + (182, 137, 125), (175, 135, 122), (169, 130, 117), (160, 123, 110), + (151, 111, 100), (142, 101, 90), (130, 94, 82), (115, 85, 77), + (101, 77, 68), (91, 68, 59), (85, 62, 51), (81, 53, 43), + (81, 46, 34), (84, 40, 28), (90, 37, 25), (94, 34, 23), + (98, 35, 23), (106, 38, 28), (115, 42, 29), (126, 43, 29), + (135, 44, 28), (146, 48, 28), (153, 48, 27), (154, 51, 28), + (155, 54, 36), (154, 61, 43), (153, 67, 52), (149, 72, 59), + (147, 80, 68), (142, 83, 71), (134, 84, 70), (122, 83, 72) + ), + +// 372 040221-11 +((31, 15, 114), (40, 21, 136), (45, 23, 145), (51, 26, 154), + (55, 27, 159), (59, 29, 165), (60, 30, 167), (61, 31, 170), + (65, 33, 178), (67, 34, 182), (70, 36, 186), (73, 37, 191), + (76, 38, 197), (81, 40, 204), (87, 43, 211), (91, 44, 216), + (95, 46, 221), (112, 53, 243), (120, 55, 249), (129, 57, 255), + (138, 58, 255), (147, 60, 255), (151, 60, 255), (155, 61, 255), + (170, 66, 255), (174, 67, 255), (178, 68, 255), (178, 68, 255), + (178, 68, 255), (177, 67, 255), (177, 67, 255), (172, 66, 255), + (164, 64, 255), (136, 55, 234), (120, 49, 219), (104, 44, 204), + (90, 38, 187), (77, 32, 171), (71, 30, 163), (65, 28, 156), + (45, 20, 132), (41, 18, 127), (38, 16, 122), (42, 18, 128), + (46, 21, 134), (50, 22, 139), (55, 23, 145), (64, 27, 158), + (72, 31, 171), (89, 39, 199), (96, 44, 215), (104, 49, 232), + (107, 51, 240), (111, 54, 249), (110, 54, 248), (110, 54, 248), + (98, 48, 229), (89, 45, 217), (81, 42, 206), (75, 39, 198), + (70, 37, 190), (68, 35, 186), (66, 34, 183), (62, 33, 177), + (60, 31, 171), (59, 31, 171), (62, 32, 176), (66, 34, 182), + (67, 35, 184), (68, 36, 186), (68, 36, 184), (67, 34, 182), + (62, 32, 176), (60, 32, 174), (59, 32, 173), (56, 30, 169), + (53, 29, 165), (50, 28, 162), (48, 27, 160), (44, 26, 156), + (42, 27, 156), (45, 29, 168), (50, 32, 177), (56, 36, 187), + (59, 37, 192), (62, 38, 197), (70, 42, 209), (77, 46, 222), + (95, 55, 253), (102, 58, 254), (110, 61, 255), (112, 62, 255), + (115, 64, 255), (118, 64, 255), (121, 64, 255), (123, 65, 255), + (126, 65, 255), (129, 65, 255), (129, 65, 255), (129, 65, 255), + (129, 65, 255), (129, 65, 255), (128, 65, 255), (126, 65, 255), + (123, 65, 255), (119, 64, 255), (116, 64, 255), (113, 62, 255), + (110, 61, 255), (103, 59, 255), (93, 55, 250), (83, 50, 234), + (73, 45, 216), (51, 33, 173), (46, 29, 162), (42, 26, 151), + (32, 20, 128), (21, 12, 106), (12, 7, 88), (6, 3, 73), + (1, 0, 59), (3, 0, 60), (5, 0, 61), (7, 0, 63), + (9, 1, 66), (14, 4, 76), (20, 6, 87), (26, 11, 101), + (31, 15, 114), (40, 21, 136), (42, 22, 140), (45, 23, 145), + (51, 26, 154), (55, 28, 160), (59, 29, 165), (61, 31, 170), + (65, 33, 178), (67, 34, 182), (70, 36, 186), (71, 36, 188), + (72, 37, 190), (76, 38, 197), (81, 40, 203), (87, 43, 211), + (95, 46, 221), (112, 53, 243), (117, 54, 248), (122, 55, 253), + (129, 57, 255), (138, 57, 255), (147, 60, 255), (155, 61, 255), + (170, 66, 255), (172, 66, 255), (175, 67, 255), (178, 68, 255), + (178, 68, 255), (178, 68, 255), (177, 67, 255), (172, 66, 255), + (164, 64, 255), (136, 55, 234), (128, 52, 226), (120, 50, 218), + (104, 44, 204), (89, 38, 187), (77, 32, 171), (65, 28, 156), + (45, 20, 132), (42, 18, 128), (40, 17, 125), (38, 16, 122), + (40, 17, 126), (46, 21, 134), (55, 23, 145), (64, 27, 158), + (72, 31, 171), (81, 36, 184), (89, 39, 199), (96, 44, 215), + (104, 49, 232), (110, 53, 243), (111, 54, 249), (110, 54, 248), + (98, 48, 229), (93, 46, 222), (89, 44, 216), (81, 42, 206), + (75, 39, 198), (70, 37, 190), (66, 34, 183), (62, 33, 177), + (60, 31, 171), (59, 31, 168), (59, 31, 171), (62, 33, 176), + (66, 34, 182), (68, 36, 186), (68, 36, 184), (67, 34, 182), + (65, 33, 178), (62, 32, 176), (61, 32, 176), (59, 32, 173), + (56, 31, 170), (53, 29, 165), (48, 27, 160), (44, 26, 156), + (42, 27, 156), (43, 28, 161), (45, 29, 168), (50, 33, 177), + (56, 36, 187), (62, 38, 197), (70, 42, 209), (77, 46, 222), + (86, 50, 237), (95, 55, 253), (103, 59, 255), (110, 61, 255), + (115, 64, 255), (118, 64, 255), (121, 64, 255), (123, 65, 255), + (126, 65, 255), (128, 65, 255), (129, 65, 255), (129, 65, 255), + (129, 65, 255), (129, 65, 255), (128, 65, 255), (126, 65, 255), + (125, 65, 255), (123, 65, 255), (120, 65, 255), (116, 64, 255), + (110, 61, 255), (103, 59, 255), (93, 55, 250), (83, 50, 234), + (73, 45, 216), (62, 39, 197), (51, 33, 173), (42, 26, 151), + (32, 20, 128), (21, 12, 106), (12, 7, 88), (6, 3, 73), + (3, 1, 65), (1, 0, 59), (1, 0, 57), (5, 0, 61), + (9, 1, 66), (14, 4, 76), (20, 6, 87), (26, 11, 101) + ), + +// 373 040221-12 +((97, 81, 35), (82, 94, 46), (81, 97, 49), (80, 100, 53), + (83, 101, 54), (86, 102, 55), (94, 104, 55), (103, 106, 56), + (138, 114, 59), (147, 116, 63), (157, 119, 67), (161, 118, 66), + (165, 117, 65), (173, 113, 58), (181, 110, 52), (189, 107, 47), + (197, 104, 43), (219, 99, 37), (216, 98, 38), (214, 97, 39), + (204, 96, 38), (194, 95, 37), (191, 93, 34), (189, 91, 31), + (186, 81, 19), (182, 78, 17), (178, 75, 16), (169, 75, 17), + (161, 76, 19), (156, 77, 20), (151, 79, 21), (140, 83, 24), + (127, 84, 24), (111, 77, 21), (104, 73, 20), (98, 70, 19), + (92, 70, 20), (86, 70, 22), (80, 71, 23), (75, 72, 24), + (60, 76, 31), (57, 76, 31), (54, 76, 32), (54, 74, 32), + (54, 73, 32), (53, 72, 32), (53, 71, 32), (54, 72, 34), + (54, 72, 34), (57, 75, 35), (58, 77, 34), (60, 79, 34), + (62, 80, 34), (64, 81, 35), (64, 81, 35), (65, 81, 36), + (70, 85, 39), (77, 87, 39), (85, 89, 39), (99, 90, 37), + (114, 92, 35), (122, 93, 35), (130, 95, 35), (145, 97, 34), + (160, 102, 36), (185, 103, 36), (196, 100, 32), (207, 97, 29), + (211, 95, 26), (215, 93, 24), (222, 88, 18), (224, 84, 14), + (213, 74, 9), (202, 69, 8), (191, 64, 8), (174, 60, 7), + (158, 56, 6), (150, 55, 6), (143, 55, 6), (128, 52, 7), + (114, 48, 7), (90, 38, 6), (75, 34, 5), (61, 30, 5), + (54, 29, 6), (48, 28, 7), (39, 29, 8), (32, 30, 8), + (33, 32, 8), (37, 34, 7), (41, 36, 7), (43, 36, 8), + (45, 37, 10), (53, 41, 10), (62, 46, 11), (77, 53, 11), + (97, 58, 9), (133, 73, 8), (150, 76, 8), (167, 80, 9), + (172, 81, 10), (178, 83, 11), (190, 84, 11), (202, 85, 9), + (215, 81, 6), (210, 77, 4), (205, 74, 3), (198, 71, 3), + (191, 68, 3), (175, 62, 4), (158, 57, 3), (142, 54, 5), + (131, 52, 8), (109, 54, 15), (104, 55, 17), (100, 57, 20), + (94, 60, 26), (90, 63, 29), (89, 66, 32), (94, 66, 34), + (117, 73, 34), (133, 84, 34), (149, 95, 35), (157, 101, 39), + (165, 108, 43), (180, 122, 54), (190, 130, 63), (197, 138, 71), + (205, 145, 78), (221, 162, 89), (223, 167, 93), (226, 173, 98), + (229, 186, 111), (227, 193, 122), (223, 197, 132), (216, 193, 134), + (213, 175, 124), (216, 167, 114), (219, 160, 104), (220, 155, 99), + (221, 151, 95), (224, 142, 89), (222, 129, 80), (218, 115, 63), + (217, 102, 47), (225, 87, 19), (226, 86, 15), (228, 85, 11), + (234, 86, 8), (237, 86, 8), (239, 88, 8), (238, 87, 9), + (238, 87, 10), (237, 88, 10), (236, 90, 11), (231, 95, 16), + (226, 101, 24), (221, 109, 33), (217, 116, 44), (211, 121, 54), + (205, 124, 65), (190, 126, 72), (184, 126, 73), (178, 126, 75), + (163, 125, 78), (153, 121, 77), (142, 118, 77), (134, 114, 78), + (120, 106, 70), (116, 103, 67), (113, 100, 65), (104, 95, 59), + (99, 86, 51), (98, 76, 41), (103, 67, 31), (110, 58, 24), + (117, 53, 18), (124, 50, 15), (126, 53, 15), (125, 57, 16), + (123, 59, 19), (122, 59, 19), (122, 56, 17), (121, 54, 16), + (118, 53, 18), (116, 55, 19), (114, 58, 20), (112, 65, 25), + (110, 73, 32), (111, 81, 38), (113, 89, 46), (114, 98, 52), + (123, 106, 55), (132, 115, 55), (142, 120, 54), (152, 123, 53), + (165, 126, 50), (175, 131, 50), (177, 131, 54), (182, 131, 56), + (186, 134, 57), (185, 132, 56), (178, 127, 51), (173, 121, 44), + (167, 117, 38), (159, 112, 38), (151, 106, 40), (145, 106, 44), + (143, 109, 52), (138, 114, 60), (135, 116, 65), (132, 120, 68), + (132, 125, 70), (136, 127, 71), (140, 125, 69), (152, 123, 65), + (162, 121, 62), (171, 118, 59), (173, 114, 56), (172, 115, 55), + (171, 116, 56), (169, 114, 55), (172, 110, 52), (178, 104, 44), + (187, 97, 37), (195, 88, 30), (203, 84, 23), (207, 82, 20), + (209, 82, 19), (210, 84, 21), (210, 84, 21), (211, 83, 20), + (214, 79, 19), (217, 76, 16), (220, 70, 12), (223, 66, 8), + (224, 65, 8), (225, 65, 6), (223, 65, 5), (223, 64, 5), + (221, 62, 4), (218, 60, 5), (215, 56, 5), (212, 54, 5), + (211, 51, 5), (207, 51, 5), (200, 52, 4), (190, 54, 6), + (180, 59, 9), (169, 61, 11), (151, 58, 10), (137, 56, 11), + (127, 56, 13), (118, 58, 15), (106, 61, 19), (99, 71, 26) + ), + +// 374 040221-13 +((73, 127, 125), (87, 141, 136), (88, 141, 139), (89, 142, 142), + (81, 134, 138), (74, 126, 135), (69, 120, 131), (65, 115, 128), + (46, 92, 107), (35, 80, 94), (24, 69, 82), (18, 53, 75), + (13, 38, 69), (17, 24, 69), (22, 11, 69), (25, 8, 70), + (29, 6, 71), (33, 21, 78), (38, 30, 86), (44, 39, 94), + (56, 47, 107), (68, 55, 121), (72, 61, 126), (77, 67, 131), + (77, 101, 144), (73, 113, 143), (69, 125, 142), (67, 127, 137), + (66, 130, 133), (65, 129, 131), (64, 129, 129), (62, 124, 122), + (57, 115, 117), (37, 92, 90), (27, 80, 75), (18, 68, 61), + (12, 57, 51), (6, 47, 41), (3, 40, 37), (1, 33, 34), + (0, 20, 21), (0, 20, 19), (0, 21, 18), (0, 28, 23), + (0, 36, 29), (7, 43, 36), (14, 51, 44), (32, 64, 61), + (50, 73, 82), (86, 96, 119), (99, 101, 128), (113, 106, 137), + (118, 110, 144), (124, 114, 151), (122, 111, 151), (120, 108, 151), + (104, 91, 136), (92, 84, 120), (81, 77, 104), (64, 70, 89), + (47, 63, 75), (38, 59, 68), (30, 56, 62), (14, 48, 51), + (5, 40, 37), (0, 43, 20), (3, 47, 24), (6, 52, 28), + (10, 55, 32), (14, 59, 36), (20, 67, 44), (26, 72, 53), + (38, 94, 71), (48, 103, 84), (58, 112, 98), (72, 121, 112), + (86, 130, 126), (95, 134, 132), (104, 138, 139), (118, 144, 150), + (129, 148, 159), (148, 153, 174), (152, 153, 176), (156, 153, 178), + (158, 152, 178), (160, 152, 179), (159, 149, 177), (159, 144, 176), + (159, 119, 169), (154, 105, 165), (150, 92, 162), (145, 90, 161), + (140, 88, 160), (129, 91, 156), (119, 89, 152), (112, 88, 149), + (104, 80, 144), (88, 68, 134), (78, 78, 128), (69, 88, 122), + (65, 95, 121), (62, 102, 120), (59, 113, 120), (59, 120, 122), + (67, 129, 130), (77, 136, 133), (87, 143, 136), (92, 146, 138), + (97, 149, 141), (105, 155, 148), (110, 158, 156), (110, 160, 162), + (112, 162, 164), (105, 162, 161), (101, 159, 161), (98, 157, 161), + (90, 154, 159), (80, 149, 157), (71, 144, 154), (70, 144, 152), + (70, 142, 152), (74, 142, 155), (79, 143, 158), (82, 142, 159), + (85, 142, 160), (94, 143, 162), (102, 147, 163), (109, 150, 168), + (113, 153, 172), (123, 157, 177), (125, 157, 177), (128, 157, 178), + (132, 158, 177), (136, 160, 179), (137, 161, 181), (140, 162, 184), + (152, 166, 189), (156, 167, 189), (160, 168, 189), (160, 169, 189), + (160, 170, 189), (160, 172, 191), (161, 173, 193), (160, 173, 195), + (158, 172, 194), (148, 168, 187), (143, 166, 183), (138, 165, 179), + (127, 161, 171), (113, 153, 163), (98, 141, 153), (84, 132, 141), + (62, 109, 113), (57, 103, 104), (52, 98, 95), (41, 87, 80), + (28, 70, 64), (16, 57, 50), (6, 49, 40), (1, 42, 34), + (1, 41, 28), (0, 41, 19), (0, 38, 16), (0, 36, 14), + (0, 32, 9), (0, 28, 9), (0, 25, 11), (0, 26, 15), + (0, 25, 15), (0, 22, 12), (0, 20, 10), (0, 14, 9), + (0, 8, 11), (0, 5, 19), (0, 3, 33), (0, 0, 46), + (15, 0, 54), (33, 0, 61), (46, 3, 71), (55, 17, 82), + (62, 29, 95), (67, 39, 109), (70, 43, 117), (74, 43, 122), + (74, 47, 121), (70, 54, 120), (67, 62, 120), (58, 75, 123), + (47, 87, 123), (37, 93, 125), (34, 95, 125), (33, 94, 123), + (37, 100, 123), (43, 106, 126), (48, 114, 130), (51, 121, 136), + (56, 127, 141), (61, 129, 144), (67, 134, 145), (73, 137, 141), + (78, 139, 141), (80, 137, 143), (85, 134, 146), (91, 125, 147), + (97, 117, 147), (102, 105, 143), (100, 89, 133), (87, 71, 119), + (76, 59, 106), (66, 47, 97), (59, 44, 90), (59, 43, 91), + (62, 43, 94), (56, 45, 94), (51, 46, 94), (46, 51, 94), + (43, 66, 95), (49, 84, 101), (60, 103, 115), (73, 123, 129), + (84, 136, 141), (94, 142, 148), (103, 149, 154), (109, 152, 157), + (114, 155, 159), (119, 157, 160), (122, 159, 162), (123, 162, 165), + (126, 163, 167), (130, 163, 170), (136, 160, 173), (144, 154, 177), + (149, 144, 179), (151, 139, 181), (148, 139, 183), (144, 140, 183), + (140, 143, 183), (138, 144, 185), (136, 139, 183), (133, 132, 178), + (124, 127, 173), (111, 125, 165), (96, 128, 155), (82, 134, 145), + (71, 137, 137), (61, 133, 128), (54, 126, 121), (49, 120, 114), + (47, 115, 108), (44, 115, 101), (47, 117, 98), (49, 120, 96), + (51, 119, 101), (55, 119, 105), (59, 118, 113), (64, 122, 119) + ), + +// 375 040221-14 +((141, 124, 150), (148, 124, 134), (140, 127, 129), (132, 131, 124), + (116, 137, 127), (100, 143, 131), (89, 145, 134), (79, 148, 138), + (78, 155, 146), (80, 162, 154), (82, 169, 163), (88, 174, 166), + (94, 180, 170), (100, 185, 178), (107, 190, 187), (109, 190, 189), + (111, 191, 191), (106, 201, 205), (99, 204, 206), (92, 208, 208), + (97, 212, 211), (102, 217, 214), (109, 219, 214), (117, 222, 215), + (136, 225, 217), (121, 218, 207), (107, 212, 198), (83, 193, 182), + (59, 174, 166), (52, 165, 157), (45, 157, 148), (38, 142, 137), + (42, 129, 124), (50, 120, 101), (52, 112, 87), (54, 105, 74), + (59, 99, 59), (65, 94, 44), (73, 95, 44), (81, 96, 45), + (114, 115, 61), (125, 130, 73), (137, 145, 85), (145, 155, 86), + (154, 166, 87), (156, 169, 86), (159, 173, 85), (169, 172, 83), + (179, 169, 81), (188, 153, 88), (189, 144, 87), (191, 136, 86), + (189, 126, 75), (188, 116, 65), (191, 111, 57), (194, 106, 49), + (207, 71, 23), (215, 58, 18), (223, 46, 13), (228, 38, 14), + (234, 30, 15), (232, 30, 14), (230, 31, 13), (214, 34, 13), + (196, 33, 13), (158, 32, 16), (141, 33, 22), (125, 34, 29), + (121, 34, 32), (117, 34, 35), (99, 41, 44), (82, 49, 52), + (61, 75, 67), (58, 91, 75), (55, 107, 83), (65, 117, 88), + (75, 128, 94), (77, 130, 97), (80, 133, 100), (81, 139, 104), + (82, 143, 105), (83, 151, 110), (82, 154, 111), (82, 157, 113), + (80, 155, 113), (79, 154, 114), (70, 148, 117), (59, 141, 113), + (35, 124, 113), (24, 118, 110), (14, 112, 108), (13, 110, 105), + (12, 108, 103), (15, 105, 98), (18, 102, 92), (22, 100, 87), + (25, 100, 83), (21, 94, 79), (22, 93, 74), (24, 92, 70), + (27, 91, 67), (31, 91, 64), (47, 82, 54), (63, 77, 44), + (89, 68, 36), (98, 65, 35), (107, 62, 35), (110, 64, 36), + (113, 67, 38), (125, 62, 37), (138, 55, 33), (149, 48, 26), + (160, 40, 22), (151, 32, 18), (146, 34, 20), (141, 37, 23), + (131, 43, 28), (124, 49, 36), (120, 62, 47), (129, 67, 59), + (131, 67, 79), (135, 64, 82), (139, 62, 85), (138, 61, 87), + (137, 61, 90), (140, 76, 102), (158, 88, 114), (173, 108, 124), + (190, 112, 137), (224, 106, 122), (226, 96, 115), (229, 87, 108), + (232, 77, 95), (231, 69, 82), (216, 80, 73), (200, 86, 75), + (159, 84, 59), (141, 72, 47), (124, 61, 35), (119, 54, 30), + (115, 48, 26), (103, 48, 20), (95, 55, 23), (83, 64, 31), + (75, 74, 38), (59, 90, 52), (57, 90, 56), (56, 91, 60), + (57, 93, 66), (59, 99, 71), (58, 105, 77), (62, 113, 82), + (75, 127, 85), (75, 127, 84), (76, 127, 83), (75, 126, 78), + (75, 125, 74), (70, 122, 71), (65, 119, 71), (65, 121, 74), + (69, 128, 79), (74, 138, 86), (75, 140, 87), (77, 142, 88), + (80, 147, 89), (80, 148, 89), (79, 147, 92), (82, 147, 94), + (86, 149, 100), (85, 147, 99), (85, 146, 99), (85, 144, 97), + (85, 139, 86), (81, 132, 77), (80, 124, 67), (79, 116, 59), + (75, 107, 51), (69, 95, 43), (62, 87, 41), (60, 82, 35), + (58, 79, 27), (66, 75, 24), (78, 73, 20), (88, 72, 19), + (109, 64, 16), (114, 62, 16), (119, 60, 17), (119, 67, 16), + (127, 77, 25), (137, 90, 39), (147, 108, 57), (162, 126, 74), + (178, 141, 87), (194, 145, 98), (193, 151, 99), (189, 158, 100), + (179, 162, 104), (161, 167, 111), (147, 172, 119), (137, 177, 123), + (143, 182, 130), (146, 183, 131), (150, 181, 122), (150, 177, 108), + (141, 170, 94), (135, 162, 83), (127, 150, 66), (134, 142, 54), + (145, 134, 49), (162, 127, 42), (177, 125, 37), (182, 120, 33), + (187, 118, 32), (176, 117, 31), (171, 121, 31), (170, 124, 36), + (178, 130, 46), (190, 138, 57), (198, 147, 69), (208, 152, 82), + (204, 160, 99), (195, 174, 116), (183, 186, 131), (174, 202, 151), + (169, 215, 166), (169, 227, 183), (177, 231, 197), (189, 236, 211), + (196, 238, 221), (199, 235, 226), (200, 236, 234), (195, 237, 233), + (193, 235, 230), (186, 226, 224), (187, 215, 218), (192, 199, 208), + (198, 178, 192), (205, 160, 184), (208, 146, 174), (209, 133, 170), + (206, 126, 165), (200, 124, 165), (192, 126, 169), (188, 122, 165), + (192, 120, 162), (198, 115, 161), (197, 105, 168), (204, 101, 172), + (209, 99, 172), (211, 101, 172), (207, 106, 173), (193, 116, 170), + (183, 125, 164), (163, 127, 161), (154, 130, 161), (144, 129, 159) + ), + +// 376 040221-19 +((35, 145, 173), (44, 138, 178), (43, 138, 179), (42, 138, 180), + (35, 140, 179), (29, 143, 178), (28, 151, 168), (27, 160, 159), + (47, 172, 129), (64, 174, 121), (82, 177, 113), (98, 183, 114), + (114, 189, 116), (128, 196, 104), (143, 203, 92), (148, 204, 86), + (153, 205, 81), (171, 205, 69), (181, 200, 76), (192, 195, 83), + (194, 190, 87), (197, 186, 92), (194, 182, 91), (192, 178, 90), + (174, 170, 90), (171, 173, 94), (169, 176, 99), (174, 184, 111), + (179, 192, 123), (181, 195, 130), (184, 199, 137), (182, 203, 155), + (181, 203, 171), (172, 208, 194), (174, 213, 199), (177, 218, 205), + (177, 224, 211), (177, 230, 218), (176, 228, 223), (175, 227, 228), + (155, 209, 241), (146, 198, 241), (138, 188, 242), (134, 185, 233), + (131, 182, 224), (130, 181, 216), (130, 180, 208), (124, 175, 190), + (119, 163, 177), (97, 126, 144), (86, 106, 130), (75, 87, 116), + (67, 77, 96), (59, 67, 76), (56, 64, 68), (53, 62, 60), + (39, 57, 36), (31, 54, 34), (24, 51, 33), (18, 48, 32), + (12, 45, 31), (11, 44, 30), (10, 44, 30), (7, 45, 31), + (8, 48, 34), (13, 63, 42), (22, 67, 43), (32, 72, 44), + (37, 74, 46), (43, 76, 49), (53, 78, 59), (66, 76, 72), + (83, 76, 103), (93, 81, 116), (103, 87, 130), (108, 103, 142), + (114, 119, 154), (119, 127, 161), (125, 136, 169), (138, 150, 182), + (145, 163, 192), (161, 179, 198), (157, 188, 193), (154, 197, 189), + (150, 204, 190), (146, 212, 191), (136, 223, 197), (131, 234, 201), + (135, 245, 191), (146, 246, 178), (158, 247, 165), (164, 247, 158), + (171, 248, 152), (175, 242, 145), (179, 238, 144), (179, 231, 139), + (179, 224, 137), (185, 218, 125), (187, 218, 117), (190, 219, 110), + (191, 218, 110), (193, 217, 111), (190, 208, 114), (187, 199, 122), + (172, 169, 140), (155, 154, 154), (138, 140, 169), (131, 137, 175), + (125, 135, 182), (109, 129, 196), (100, 127, 204), (93, 127, 200), + (93, 121, 197), (82, 107, 180), (82, 105, 173), (82, 103, 166), + (87, 101, 155), (100, 106, 145), (113, 119, 134), (125, 129, 130), + (144, 150, 129), (143, 149, 130), (143, 149, 132), (143, 147, 133), + (144, 145, 135), (150, 147, 141), (147, 144, 153), (143, 143, 159), + (139, 142, 169), (109, 145, 185), (98, 146, 187), (88, 148, 189), + (77, 154, 193), (65, 157, 200), (56, 159, 199), (51, 159, 192), + (53, 149, 162), (51, 149, 144), (49, 150, 127), (49, 151, 125), + (49, 152, 123), (47, 149, 125), (46, 147, 126), (47, 136, 123), + (55, 132, 119), (66, 134, 107), (65, 138, 109), (64, 143, 111), + (62, 147, 121), (55, 151, 134), (42, 150, 148), (35, 149, 155), + (31, 149, 161), (32, 152, 160), (33, 155, 159), (40, 157, 156), + (49, 162, 155), (52, 160, 155), (51, 153, 146), (47, 141, 135), + (38, 122, 121), (25, 85, 84), (24, 79, 76), (24, 73, 68), + (29, 64, 59), (31, 63, 51), (35, 70, 49), (37, 76, 51), + (36, 87, 58), (35, 89, 59), (34, 92, 60), (37, 95, 63), + (37, 93, 65), (34, 93, 67), (35, 95, 70), (35, 96, 75), + (34, 100, 78), (35, 105, 81), (42, 112, 83), (53, 118, 86), + (59, 122, 89), (75, 127, 93), (86, 128, 103), (92, 127, 112), + (89, 122, 124), (88, 121, 124), (87, 121, 124), (78, 119, 124), + (81, 118, 116), (85, 116, 112), (90, 113, 105), (87, 105, 105), + (83, 97, 100), (72, 85, 93), (51, 69, 84), (34, 53, 68), + (20, 38, 51), (11, 27, 34), (3, 19, 26), (2, 16, 22), + (5, 21, 21), (8, 31, 27), (15, 46, 36), (25, 60, 45), + (34, 72, 54), (42, 83, 62), (47, 90, 68), (51, 95, 69), + (50, 100, 72), (51, 107, 79), (55, 119, 87), (62, 130, 101), + (73, 147, 118), (90, 162, 129), (104, 172, 132), (115, 177, 131), + (123, 179, 129), (122, 179, 124), (119, 177, 127), (114, 182, 135), + (113, 184, 142), (112, 184, 144), (110, 182, 144), (112, 178, 137), + (108, 168, 123), (97, 152, 110), (85, 139, 101), (70, 124, 94), + (53, 109, 88), (37, 93, 84), (25, 80, 76), (17, 65, 67), + (8, 51, 58), (4, 41, 49), (2, 32, 41), (0, 27, 35), + (0, 24, 31), (0, 20, 28), (0, 19, 25), (0, 18, 25), + (1, 19, 23), (1, 19, 20), (3, 19, 20), (3, 19, 22), + (3, 20, 27), (3, 24, 33), (2, 30, 42), (5, 40, 52), + (12, 58, 63), (22, 75, 71), (31, 80, 91), (39, 89, 109), + (40, 103, 129), (36, 115, 148), (32, 120, 165), (34, 130, 178) + ), + +// 377 040221-2 +((46, 16, 16), (47, 16, 16), (48, 17, 17), (50, 18, 18), + (51, 18, 18), (53, 19, 19), (54, 19, 19), (56, 20, 20), + (59, 30, 21), (57, 31, 20), (56, 33, 20), (54, 32, 19), + (52, 31, 18), (48, 30, 16), (44, 30, 15), (42, 32, 14), + (41, 34, 14), (36, 44, 15), (37, 49, 17), (39, 54, 19), + (41, 59, 21), (43, 65, 23), (43, 66, 23), (44, 68, 24), + (43, 71, 25), (42, 70, 24), (42, 69, 24), (39, 63, 22), + (36, 57, 20), (34, 55, 19), (33, 53, 19), (26, 46, 16), + (19, 41, 14), (10, 28, 10), (8, 24, 8), (7, 20, 7), + (6, 18, 6), (5, 16, 5), (5, 15, 5), (5, 15, 5), + (4, 12, 4), (4, 12, 4), (4, 13, 4), (12, 19, 6), + (21, 25, 9), (26, 27, 10), (31, 29, 11), (43, 39, 15), + (54, 49, 19), (74, 71, 26), (78, 76, 27), (83, 82, 29), + (82, 84, 30), (82, 86, 31), (80, 86, 31), (79, 87, 31), + (84, 96, 34), (88, 101, 36), (93, 106, 38), (95, 107, 38), + (97, 109, 39), (98, 110, 39), (99, 111, 40), (102, 112, 40), + (110, 120, 43), (104, 112, 40), (96, 104, 37), (88, 96, 34), + (83, 91, 32), (78, 86, 31), (67, 77, 27), (59, 71, 25), + (46, 60, 21), (44, 58, 20), (42, 56, 20), (49, 61, 21), + (57, 66, 23), (63, 71, 25), (69, 77, 27), (80, 86, 31), + (90, 93, 33), (111, 111, 40), (119, 119, 42), (127, 127, 45), + (129, 130, 46), (132, 133, 48), (134, 136, 49), (132, 136, 49), + (131, 137, 49), (129, 136, 49), (128, 136, 49), (127, 135, 48), + (127, 134, 48), (127, 133, 48), (126, 130, 46), (124, 127, 45), + (124, 126, 45), (120, 121, 43), (113, 117, 42), (106, 114, 41), + (100, 109, 39), (95, 105, 37), (85, 99, 35), (75, 94, 33), + (54, 81, 29), (43, 71, 25), (32, 62, 22), (26, 57, 20), + (20, 52, 18), (14, 41, 14), (12, 34, 12), (9, 26, 9), + (7, 22, 7), (6, 17, 6), (6, 18, 6), (6, 19, 6), + (8, 23, 8), (14, 34, 12), (27, 47, 16), (41, 60, 21), + (69, 90, 32), (81, 102, 36), (94, 114, 41), (99, 117, 42), + (104, 121, 43), (110, 124, 44), (114, 126, 45), (116, 123, 44), + (118, 120, 43), (123, 117, 44), (127, 120, 45), (131, 123, 47), + (139, 129, 50), (148, 135, 53), (155, 143, 56), (161, 149, 58), + (170, 161, 61), (173, 166, 62), (176, 171, 63), (178, 173, 64), + (180, 176, 65), (185, 181, 66), (186, 182, 67), (183, 181, 66), + (182, 178, 65), (168, 164, 60), (164, 159, 58), (160, 154, 57), + (154, 145, 55), (143, 135, 51), (134, 129, 48), (128, 125, 46), + (120, 123, 44), (118, 123, 44), (117, 123, 44), (115, 121, 43), + (111, 120, 43), (107, 115, 41), (103, 109, 39), (102, 105, 37), + (103, 105, 37), (114, 113, 41), (117, 115, 42), (121, 118, 43), + (127, 123, 45), (131, 126, 47), (133, 127, 48), (133, 129, 48), + (139, 136, 50), (139, 138, 50), (139, 140, 50), (141, 145, 52), + (142, 146, 52), (143, 151, 54), (145, 155, 56), (147, 158, 57), + (148, 161, 58), (150, 163, 58), (154, 165, 59), (161, 170, 61), + (167, 177, 63), (177, 186, 67), (188, 197, 71), (195, 207, 74), + (199, 217, 78), (199, 218, 78), (200, 219, 79), (199, 219, 79), + (197, 217, 78), (195, 217, 78), (191, 214, 77), (187, 210, 75), + (184, 207, 74), (178, 202, 73), (173, 198, 71), (170, 194, 70), + (169, 189, 68), (167, 183, 66), (164, 177, 63), (161, 167, 60), + (157, 158, 57), (158, 152, 57), (157, 148, 56), (151, 142, 54), + (143, 133, 51), (137, 129, 49), (130, 122, 46), (123, 116, 44), + (117, 110, 42), (112, 106, 40), (111, 102, 40), (105, 97, 37), + (97, 89, 35), (89, 79, 32), (80, 67, 28), (75, 56, 27), + (68, 45, 24), (59, 35, 21), (54, 29, 19), (53, 27, 19), + (52, 29, 18), (52, 31, 18), (52, 33, 18), (52, 39, 18), + (50, 43, 18), (47, 46, 16), (47, 54, 19), (49, 60, 21), + (51, 65, 23), (54, 68, 24), (53, 71, 25), (53, 72, 26), + (52, 74, 26), (51, 74, 26), (50, 74, 26), (49, 72, 26), + (52, 71, 25), (52, 68, 24), (53, 66, 23), (55, 66, 23), + (56, 68, 24), (57, 68, 24), (58, 68, 24), (59, 68, 24), + (58, 66, 23), (57, 63, 22), (56, 59, 21), (53, 54, 19), + (50, 50, 18), (50, 46, 18), (50, 42, 18), (46, 36, 16), + (43, 29, 15), (41, 24, 14), (43, 20, 15), (44, 15, 15) + ), + +// 378 040221-21 +((138, 101, 87), (142, 105, 101), (142, 107, 103), (143, 110, 105), + (145, 112, 105), (147, 115, 106), (148, 116, 107), (150, 117, 108), + (144, 111, 105), (137, 105, 100), (131, 99, 95), (124, 92, 88), + (117, 86, 82), (114, 81, 75), (111, 76, 68), (110, 74, 66), + (110, 72, 64), (105, 63, 59), (101, 59, 56), (97, 55, 54), + (97, 55, 53), (97, 55, 52), (98, 56, 52), (100, 57, 53), + (107, 63, 53), (106, 62, 51), (105, 62, 49), (101, 60, 47), + (98, 59, 46), (98, 59, 45), (98, 60, 45), (103, 60, 45), + (106, 62, 46), (109, 64, 40), (105, 62, 35), (101, 60, 31), + (99, 60, 29), (98, 60, 28), (98, 60, 28), (98, 60, 29), + (102, 63, 31), (99, 62, 28), (97, 62, 26), (92, 59, 22), + (88, 57, 19), (85, 55, 17), (82, 54, 16), (80, 53, 15), + (79, 53, 17), (80, 55, 19), (83, 57, 22), (86, 59, 25), + (89, 61, 29), (93, 63, 34), (94, 63, 36), (95, 63, 39), + (94, 62, 43), (92, 61, 44), (90, 61, 46), (91, 63, 48), + (92, 65, 50), (92, 65, 51), (93, 66, 52), (92, 64, 54), + (89, 62, 53), (79, 54, 48), (75, 51, 44), (72, 49, 40), + (72, 49, 39), (72, 49, 38), (72, 49, 38), (73, 49, 38), + (81, 54, 45), (87, 58, 50), (93, 62, 56), (99, 66, 62), + (105, 71, 68), (106, 73, 71), (108, 76, 74), (113, 81, 80), + (119, 88, 88), (136, 103, 102), (143, 108, 106), (151, 114, 110), + (152, 115, 110), (154, 117, 110), (152, 115, 110), (146, 113, 108), + (132, 104, 104), (126, 98, 98), (121, 92, 92), (118, 89, 88), + (116, 86, 84), (110, 78, 77), (103, 70, 70), (93, 62, 63), + (83, 54, 57), (67, 38, 46), (63, 35, 40), (60, 33, 34), + (59, 32, 32), (59, 32, 31), (60, 32, 28), (60, 33, 27), + (63, 35, 29), (65, 38, 29), (67, 42, 30), (68, 44, 30), + (69, 47, 31), (73, 53, 34), (79, 58, 36), (86, 64, 40), + (92, 69, 45), (106, 78, 55), (110, 81, 58), (114, 85, 61), + (121, 92, 69), (131, 102, 80), (145, 118, 97), (160, 134, 113), + (184, 161, 145), (194, 173, 158), (204, 185, 172), (206, 188, 177), + (209, 191, 182), (219, 204, 197), (228, 216, 212), (236, 228, 225), + (243, 237, 237), (247, 239, 235), (244, 235, 229), (241, 232, 223), + (233, 222, 212), (226, 212, 202), (217, 201, 191), (212, 196, 188), + (196, 174, 166), (186, 162, 150), (176, 151, 135), (169, 144, 126), + (163, 138, 118), (149, 122, 100), (137, 113, 91), (127, 103, 84), + (118, 95, 78), (108, 83, 63), (105, 81, 59), (103, 79, 56), + (97, 75, 49), (90, 70, 42), (85, 65, 37), (82, 61, 33), + (85, 60, 30), (87, 61, 30), (90, 62, 31), (96, 66, 34), + (102, 70, 37), (107, 74, 42), (112, 78, 47), (118, 81, 51), + (124, 86, 56), (140, 96, 62), (142, 98, 64), (145, 100, 67), + (149, 104, 71), (150, 106, 75), (149, 106, 79), (147, 107, 85), + (147, 109, 90), (146, 109, 91), (145, 109, 92), (146, 110, 94), + (146, 111, 94), (146, 111, 95), (143, 110, 99), (143, 110, 104), + (145, 113, 112), (153, 124, 125), (162, 136, 139), (172, 149, 152), + (180, 158, 155), (184, 161, 156), (184, 161, 157), (176, 150, 151), + (159, 142, 146), (156, 141, 148), (154, 141, 150), (149, 140, 145), + (144, 134, 136), (137, 128, 126), (126, 110, 110), (110, 94, 92), + (95, 76, 73), (83, 65, 62), (74, 57, 53), (67, 51, 43), + (65, 48, 36), (67, 46, 32), (70, 47, 30), (75, 50, 30), + (82, 55, 33), (90, 63, 37), (98, 71, 41), (108, 79, 48), + (118, 87, 55), (126, 95, 62), (135, 104, 70), (144, 112, 79), + (151, 119, 86), (154, 123, 92), (153, 123, 95), (151, 122, 97), + (145, 116, 97), (139, 111, 96), (134, 105, 95), (127, 99, 91), + (120, 93, 88), (112, 86, 82), (102, 78, 76), (92, 69, 68), + (84, 62, 63), (81, 56, 59), (81, 55, 55), (83, 56, 55), + (88, 59, 55), (93, 63, 57), (96, 67, 59), (96, 69, 61), + (98, 71, 63), (103, 76, 66), (110, 82, 68), (115, 88, 70), + (120, 94, 71), (124, 98, 73), (122, 98, 73), (117, 96, 70), + (112, 92, 67), (109, 88, 61), (105, 85, 56), (103, 83, 50), + (102, 81, 44), (103, 81, 41), (101, 79, 37), (100, 77, 33), + (99, 75, 31), (98, 75, 30), (100, 75, 31), (101, 74, 34), + (103, 74, 37), (103, 73, 41), (104, 72, 42), (107, 73, 45), + (112, 77, 50), (118, 83, 56), (124, 87, 65), (132, 94, 76) + ), + +// 379 040221-22 +((91, 108, 100), (93, 109, 98), (89, 105, 92), (86, 101, 87), + (83, 98, 85), (81, 95, 84), (78, 92, 82), (76, 89, 81), + (63, 74, 71), (56, 66, 65), (50, 59, 60), (43, 52, 56), + (37, 45, 52), (34, 40, 49), (31, 36, 47), (31, 36, 46), + (31, 36, 45), (33, 38, 43), (33, 38, 44), (34, 39, 45), + (35, 40, 45), (36, 41, 45), (37, 43, 45), (39, 45, 45), + (46, 56, 54), (55, 65, 62), (64, 74, 71), (82, 91, 84), + (101, 109, 98), (109, 116, 104), (117, 123, 110), (128, 135, 119), + (139, 145, 128), (152, 157, 136), (152, 155, 135), (152, 153, 134), + (140, 144, 125), (129, 135, 116), (123, 130, 112), (118, 126, 108), + (101, 110, 94), (96, 106, 91), (91, 102, 88), (90, 101, 87), + (89, 100, 87), (90, 100, 88), (91, 101, 89), (92, 101, 92), + (95, 103, 96), (99, 108, 100), (100, 110, 100), (102, 112, 101), + (101, 112, 101), (100, 112, 101), (99, 111, 99), (99, 110, 98), + (96, 103, 90), (90, 98, 85), (85, 93, 80), (78, 85, 74), + (71, 78, 68), (67, 72, 65), (64, 67, 63), (56, 58, 56), + (49, 52, 52), (36, 42, 44), (32, 37, 42), (28, 33, 41), + (27, 32, 40), (26, 31, 40), (25, 30, 40), (26, 31, 40), + (27, 32, 43), (27, 32, 44), (27, 33, 45), (27, 33, 45), + (27, 33, 45), (27, 33, 45), (27, 34, 45), (28, 34, 46), + (28, 35, 47), (30, 37, 49), (33, 40, 49), (36, 44, 50), + (37, 46, 51), (39, 48, 52), (41, 49, 51), (43, 48, 51), + (48, 53, 50), (52, 58, 53), (56, 64, 56), (57, 65, 59), + (59, 67, 62), (63, 71, 67), (69, 78, 75), (75, 87, 83), + (82, 95, 89), (92, 106, 99), (96, 111, 102), (101, 116, 106), + (103, 117, 107), (106, 119, 108), (107, 120, 107), (106, 119, 106), + (109, 123, 107), (113, 126, 110), (118, 130, 114), (118, 130, 115), + (118, 130, 116), (117, 130, 117), (113, 128, 116), (111, 127, 115), + (110, 126, 111), (103, 113, 99), (98, 107, 94), (94, 101, 90), + (84, 90, 82), (73, 79, 72), (65, 71, 66), (58, 62, 60), + (47, 48, 51), (40, 42, 48), (34, 37, 46), (32, 35, 45), + (30, 34, 45), (27, 31, 45), (26, 30, 44), (26, 31, 44), + (26, 31, 44), (29, 33, 47), (30, 34, 47), (32, 36, 48), + (37, 41, 51), (41, 47, 54), (45, 54, 57), (49, 59, 61), + (59, 70, 66), (63, 75, 68), (67, 80, 71), (68, 81, 72), + (69, 83, 74), (70, 85, 74), (71, 85, 74), (72, 86, 74), + (73, 86, 75), (77, 89, 81), (79, 91, 84), (82, 94, 88), + (89, 102, 96), (96, 111, 104), (103, 120, 113), (110, 126, 120), + (119, 135, 131), (121, 136, 132), (123, 138, 133), (125, 142, 133), + (129, 144, 133), (131, 146, 131), (132, 143, 129), (132, 141, 125), + (130, 138, 120), (128, 135, 114), (128, 134, 113), (128, 134, 113), + (128, 134, 113), (125, 132, 112), (123, 129, 110), (118, 124, 107), + (103, 111, 95), (99, 107, 92), (95, 103, 89), (88, 96, 83), + (80, 88, 79), (71, 78, 74), (63, 70, 68), (54, 61, 63), + (48, 55, 57), (43, 49, 53), (38, 43, 51), (34, 39, 49), + (31, 36, 49), (30, 34, 48), (30, 34, 47), (31, 34, 46), + (31, 36, 46), (32, 37, 46), (34, 39, 46), (37, 43, 47), + (42, 48, 49), (46, 53, 53), (50, 58, 57), (55, 64, 61), + (61, 70, 66), (66, 77, 69), (71, 81, 73), (73, 83, 74), + (73, 84, 74), (73, 84, 75), (73, 84, 76), (75, 85, 77), + (77, 88, 78), (80, 93, 80), (84, 97, 84), (90, 105, 91), + (100, 113, 99), (110, 122, 106), (117, 128, 111), (120, 130, 114), + (120, 132, 115), (121, 131, 114), (121, 129, 113), (119, 124, 109), + (111, 116, 101), (100, 105, 92), (88, 94, 83), (76, 83, 75), + (68, 73, 70), (60, 65, 65), (54, 59, 62), (49, 55, 58), + (44, 50, 56), (40, 46, 56), (41, 46, 55), (44, 46, 55), + (49, 49, 56), (54, 52, 57), (58, 54, 59), (62, 60, 61), + (69, 66, 63), (77, 71, 66), (83, 76, 69), (87, 80, 72), + (89, 84, 75), (91, 89, 78), (95, 94, 81), (100, 97, 85), + (103, 99, 88), (105, 101, 89), (105, 102, 90), (103, 103, 89), + (103, 102, 89), (101, 100, 88), (98, 97, 86), (95, 94, 84), + (89, 92, 80), (85, 90, 77), (81, 88, 75), (79, 87, 75), + (78, 88, 76), (80, 91, 80), (84, 96, 86), (85, 99, 90), + (86, 100, 89), (86, 101, 90), (85, 100, 90), (88, 104, 93) + ), + +// 380 040221-23 +((109, 35, 30), (87, 22, 31), (81, 31, 29), (75, 40, 27), + (73, 49, 23), (71, 58, 19), (73, 59, 20), (75, 60, 22), + (87, 79, 33), (100, 82, 41), (114, 86, 50), (124, 71, 58), + (134, 57, 67), (137, 55, 67), (140, 53, 68), (140, 51, 67), + (141, 50, 67), (131, 31, 62), (126, 28, 52), (122, 25, 42), + (114, 29, 31), (107, 33, 21), (104, 32, 18), (102, 32, 16), + (102, 32, 16), (99, 34, 17), (97, 37, 18), (89, 43, 23), + (81, 50, 28), (80, 55, 33), (79, 60, 38), (79, 73, 43), + (81, 89, 46), (57, 115, 50), (49, 130, 64), (42, 145, 78), + (39, 161, 79), (36, 178, 81), (30, 181, 77), (24, 184, 73), + (16, 163, 76), (13, 153, 74), (11, 143, 72), (10, 132, 61), + (10, 122, 50), (11, 113, 51), (12, 105, 52), (15, 90, 60), + (13, 88, 74), (17, 110, 85), (18, 106, 88), (20, 102, 92), + (21, 99, 100), (23, 96, 109), (28, 99, 106), (33, 102, 104), + (62, 87, 76), (77, 73, 70), (93, 59, 64), (111, 50, 63), + (130, 42, 62), (141, 40, 61), (152, 39, 61), (169, 43, 62), + (182, 51, 73), (181, 45, 100), (182, 43, 105), (183, 42, 110), + (186, 43, 109), (189, 44, 109), (189, 44, 110), (186, 37, 110), + (181, 28, 104), (186, 23, 97), (192, 18, 91), (192, 11, 84), + (193, 5, 78), (191, 4, 73), (190, 4, 69), (188, 4, 60), + (185, 3, 54), (167, 6, 40), (154, 7, 32), (141, 9, 24), + (137, 7, 20), (134, 5, 16), (127, 4, 11), (118, 4, 6), + (96, 5, 5), (91, 5, 6), (87, 5, 7), (84, 9, 7), + (82, 14, 8), (72, 33, 11), (66, 54, 14), (68, 71, 20), + (74, 70, 21), (84, 66, 18), (85, 71, 16), (86, 77, 15), + (87, 73, 15), (89, 69, 16), (96, 52, 12), (96, 32, 10), + (80, 8, 0), (68, 4, 0), (56, 1, 0), (51, 0, 0), + (47, 0, 0), (40, 0, 2), (37, 0, 3), (34, 1, 4), + (35, 2, 4), (39, 2, 4), (40, 2, 3), (42, 2, 3), + (45, 2, 4), (47, 2, 4), (46, 3, 4), (40, 2, 6), + (26, 2, 8), (22, 5, 7), (19, 8, 7), (17, 8, 8), + (15, 8, 9), (15, 9, 10), (16, 7, 11), (21, 11, 8), + (33, 14, 6), (58, 16, 4), (64, 13, 3), (70, 11, 3), + (81, 8, 3), (94, 8, 2), (107, 9, 2), (119, 8, 4), + (136, 3, 10), (141, 2, 13), (146, 1, 17), (146, 1, 18), + (146, 2, 20), (140, 2, 20), (135, 2, 21), (131, 2, 20), + (128, 1, 20), (111, 1, 15), (104, 1, 14), (98, 1, 13), + (87, 2, 9), (79, 1, 6), (72, 1, 4), (66, 1, 2), + (47, 5, 5), (43, 6, 6), (40, 8, 8), (34, 12, 11), + (35, 14, 16), (40, 16, 19), (49, 18, 23), (60, 21, 28), + (74, 20, 27), (105, 24, 26), (114, 22, 24), (123, 21, 23), + (141, 22, 21), (160, 15, 23), (173, 11, 27), (180, 14, 30), + (173, 17, 23), (166, 20, 21), (159, 23, 20), (142, 32, 26), + (121, 50, 35), (104, 66, 51), (84, 76, 62), (65, 81, 60), + (46, 83, 57), (27, 85, 54), (20, 88, 51), (17, 83, 54), + (22, 76, 51), (35, 65, 49), (47, 56, 47), (64, 51, 41), + (90, 47, 35), (90, 48, 35), (90, 50, 35), (89, 51, 38), + (87, 54, 46), (87, 58, 51), (89, 53, 52), (77, 50, 51), + (69, 42, 43), (59, 31, 40), (54, 29, 36), (60, 26, 33), + (68, 28, 34), (80, 31, 34), (92, 27, 41), (99, 21, 50), + (105, 20, 60), (115, 26, 67), (125, 40, 70), (139, 52, 73), + (143, 56, 75), (140, 50, 80), (136, 45, 77), (131, 43, 70), + (130, 44, 57), (130, 48, 44), (129, 43, 36), (125, 36, 28), + (119, 27, 23), (110, 17, 17), (102, 11, 14), (96, 7, 10), + (89, 6, 6), (85, 7, 4), (82, 9, 2), (83, 14, 3), + (88, 17, 5), (94, 21, 6), (98, 26, 11), (105, 27, 22), + (108, 28, 36), (116, 25, 51), (123, 21, 61), (125, 21, 61), + (128, 17, 60), (127, 14, 60), (128, 11, 67), (133, 5, 79), + (137, 3, 83), (139, 3, 81), (147, 2, 73), (153, 2, 66), + (159, 7, 66), (165, 15, 70), (166, 24, 76), (167, 33, 80), + (168, 36, 79), (169, 41, 75), (170, 45, 73), (169, 54, 74), + (170, 65, 76), (172, 71, 77), (170, 75, 76), (172, 73, 73), + (170, 73, 73), (168, 73, 71), (166, 70, 68), (155, 69, 64), + (151, 60, 58), (145, 54, 52), (135, 49, 44), (126, 39, 35) + ), + +// 381 040221-24 +((96, 87, 69), (102, 93, 75), (102, 95, 78), (103, 97, 81), + (100, 97, 83), (97, 98, 86), (95, 98, 88), (94, 99, 90), + (108, 114, 102), (114, 122, 108), (121, 130, 114), (126, 134, 117), + (132, 139, 121), (133, 140, 121), (134, 141, 122), (134, 140, 121), + (134, 140, 121), (134, 135, 114), (133, 133, 113), (133, 132, 112), + (137, 133, 114), (141, 135, 116), (142, 137, 118), (144, 140, 120), + (152, 149, 130), (156, 151, 133), (160, 154, 137), (161, 155, 137), + (163, 157, 138), (162, 156, 139), (162, 156, 141), (160, 157, 143), + (156, 154, 144), (142, 147, 137), (131, 137, 127), (121, 128, 118), + (107, 114, 106), (94, 100, 94), (87, 93, 88), (81, 87, 83), + (57, 63, 65), (46, 53, 56), (36, 43, 48), (29, 36, 40), + (22, 30, 33), (20, 28, 31), (19, 26, 30), (19, 27, 32), + (20, 30, 37), (30, 44, 54), (39, 53, 62), (49, 62, 70), + (58, 70, 76), (67, 79, 82), (71, 83, 85), (76, 88, 88), + (93, 105, 102), (103, 113, 109), (113, 122, 117), (122, 130, 124), + (132, 139, 131), (136, 142, 133), (141, 146, 135), (150, 153, 138), + (157, 159, 141), (167, 163, 141), (168, 162, 138), (170, 161, 136), + (171, 160, 133), (172, 159, 131), (173, 156, 127), (172, 153, 122), + (170, 151, 117), (167, 150, 114), (164, 149, 111), (164, 148, 110), + (164, 148, 110), (164, 148, 111), (165, 149, 112), (166, 149, 114), + (168, 155, 118), (177, 164, 130), (177, 168, 134), (178, 172, 139), + (178, 172, 140), (178, 173, 142), (175, 173, 143), (171, 170, 142), + (161, 159, 136), (154, 152, 130), (148, 146, 125), (145, 142, 122), + (142, 139, 119), (139, 134, 112), (135, 127, 103), (133, 122, 95), + (131, 117, 87), (124, 107, 77), (120, 104, 76), (117, 102, 75), + (117, 103, 77), (117, 105, 79), (118, 108, 85), (124, 116, 92), + (145, 136, 109), (153, 144, 116), (161, 152, 123), (163, 153, 125), + (165, 155, 128), (166, 157, 131), (161, 154, 134), (155, 150, 133), + (149, 146, 133), (132, 133, 122), (127, 129, 119), (122, 125, 116), + (114, 117, 108), (107, 109, 99), (99, 99, 91), (90, 90, 81), + (76, 74, 68), (75, 68, 60), (75, 63, 52), (76, 61, 49), + (77, 59, 46), (81, 55, 41), (86, 51, 36), (91, 50, 31), + (100, 51, 32), (112, 62, 43), (118, 67, 46), (125, 73, 50), + (138, 84, 59), (151, 98, 72), (165, 111, 84), (176, 125, 95), + (195, 145, 119), (196, 154, 130), (198, 164, 142), (198, 168, 146), + (198, 172, 150), (197, 178, 159), (195, 183, 165), (190, 185, 167), + (183, 183, 165), (162, 166, 152), (155, 160, 146), (149, 154, 141), + (137, 143, 131), (125, 131, 120), (114, 118, 110), (106, 109, 101), + (93, 96, 85), (90, 93, 82), (87, 91, 79), (84, 85, 74), + (82, 83, 70), (84, 84, 69), (89, 85, 67), (96, 87, 67), + (103, 91, 67), (123, 102, 69), (127, 104, 69), (131, 106, 69), + (135, 108, 72), (138, 113, 75), (144, 117, 77), (148, 118, 81), + (153, 121, 86), (154, 122, 87), (156, 123, 88), (157, 124, 87), + (155, 121, 89), (147, 120, 89), (141, 117, 90), (133, 114, 93), + (126, 114, 98), (124, 117, 103), (127, 122, 110), (133, 128, 115), + (139, 134, 122), (143, 138, 126), (143, 140, 127), (138, 138, 124), + (118, 123, 114), (113, 118, 110), (108, 114, 107), (99, 108, 102), + (94, 103, 100), (90, 100, 99), (86, 99, 100), (82, 101, 105), + (77, 102, 111), (74, 101, 111), (68, 96, 108), (60, 91, 104), + (58, 86, 100), (58, 81, 93), (55, 75, 87), (52, 72, 82), + (50, 71, 84), (49, 70, 84), (49, 70, 83), (46, 69, 83), + (46, 69, 84), (49, 67, 82), (48, 65, 79), (47, 63, 77), + (43, 63, 80), (39, 60, 79), (35, 56, 76), (30, 52, 74), + (26, 50, 72), (25, 48, 73), (26, 49, 72), (32, 52, 73), + (40, 60, 81), (51, 69, 87), (62, 78, 90), (71, 84, 91), + (80, 88, 91), (85, 88, 87), (89, 83, 80), (90, 74, 67), + (88, 68, 59), (85, 63, 53), (83, 61, 49), (81, 59, 43), + (79, 56, 40), (73, 55, 37), (68, 51, 35), (60, 44, 32), + (50, 36, 30), (39, 29, 27), (28, 20, 24), (20, 13, 19), + (14, 7, 15), (9, 6, 13), (7, 8, 14), (8, 11, 15), + (12, 15, 21), (18, 21, 27), (24, 28, 34), (32, 35, 41), + (41, 42, 47), (53, 48, 51), (64, 55, 54), (74, 64, 55), + (85, 70, 58), (85, 71, 58), (85, 72, 57), (83, 73, 59), + (81, 73, 59), (81, 74, 60), (83, 74, 61), (84, 78, 63) + ), + +// 382 040221-25 +((173, 218, 4), (187, 194, 5), (203, 186, 5), (219, 178, 6), + (218, 173, 6), (218, 169, 6), (207, 164, 5), (196, 159, 5), + (158, 136, 6), (145, 133, 4), (132, 131, 3), (117, 134, 4), + (102, 137, 6), (95, 142, 6), (89, 148, 7), (92, 152, 9), + (95, 156, 12), (115, 180, 34), (135, 187, 56), (156, 195, 79), + (170, 182, 80), (185, 169, 82), (189, 166, 75), (193, 163, 68), + (212, 178, 80), (215, 163, 75), (218, 149, 71), (212, 129, 46), + (207, 110, 22), (206, 105, 16), (206, 101, 10), (207, 100, 7), + (209, 89, 7), (209, 62, 5), (210, 44, 5), (211, 26, 5), + (217, 15, 4), (223, 5, 4), (224, 4, 3), (226, 4, 3), + (225, 4, 5), (227, 5, 4), (229, 6, 4), (235, 10, 4), + (241, 15, 4), (242, 19, 4), (243, 24, 5), (244, 35, 6), + (245, 41, 5), (250, 43, 3), (251, 42, 3), (252, 41, 4), + (251, 40, 3), (250, 39, 3), (249, 35, 3), (248, 32, 3), + (232, 15, 3), (221, 17, 3), (211, 20, 3), (200, 31, 3), + (190, 42, 3), (183, 48, 3), (177, 55, 4), (168, 76, 10), + (160, 98, 21), (169, 146, 69), (178, 154, 88), (188, 163, 107), + (188, 166, 106), (188, 170, 105), (183, 180, 91), (179, 190, 90), + (178, 184, 100), (168, 175, 78), (158, 166, 56), (138, 166, 33), + (118, 167, 10), (113, 167, 9), (109, 168, 8), (105, 173, 13), + (109, 182, 14), (139, 196, 13), (155, 203, 13), (171, 210, 13), + (175, 217, 13), (179, 224, 14), (197, 231, 13), (215, 238, 11), + (235, 232, 5), (220, 225, 5), (205, 219, 5), (197, 215, 5), + (190, 211, 6), (178, 202, 4), (163, 193, 3), (145, 183, 3), + (124, 172, 3), (95, 158, 6), (89, 156, 5), (84, 155, 5), + (82, 154, 5), (80, 153, 5), (79, 150, 5), (82, 148, 6), + (86, 141, 6), (94, 125, 5), (103, 110, 5), (110, 102, 4), + (117, 94, 4), (130, 77, 4), (140, 67, 3), (152, 52, 3), + (159, 35, 3), (164, 14, 6), (163, 18, 5), (163, 23, 5), + (164, 36, 4), (160, 54, 2), (156, 70, 4), (152, 84, 5), + (160, 112, 5), (165, 110, 4), (170, 109, 3), (172, 103, 3), + (175, 97, 3), (179, 88, 3), (191, 79, 4), (195, 67, 5), + (191, 53, 5), (161, 43, 6), (154, 43, 5), (148, 44, 4), + (141, 41, 6), (139, 36, 5), (144, 37, 6), (143, 40, 6), + (157, 38, 4), (172, 26, 4), (188, 15, 4), (194, 10, 4), + (201, 6, 4), (209, 8, 6), (214, 15, 5), (209, 26, 7), + (200, 40, 7), (168, 65, 8), (161, 72, 7), (155, 80, 7), + (142, 97, 8), (134, 113, 8), (125, 131, 8), (118, 143, 8), + (121, 162, 5), (124, 164, 4), (128, 167, 4), (133, 169, 6), + (133, 170, 8), (131, 165, 9), (132, 162, 8), (134, 157, 7), + (136, 150, 7), (123, 141, 11), (119, 140, 11), (115, 139, 12), + (110, 137, 10), (109, 133, 8), (108, 134, 6), (104, 134, 7), + (95, 141, 8), (95, 142, 8), (95, 143, 8), (96, 148, 7), + (97, 156, 8), (99, 166, 7), (101, 177, 7), (105, 184, 7), + (111, 187, 9), (115, 187, 14), (120, 192, 16), (133, 199, 15), + (148, 209, 10), (167, 216, 9), (181, 214, 10), (183, 209, 13), + (197, 189, 9), (203, 186, 7), (209, 183, 6), (224, 177, 4), + (229, 170, 5), (229, 160, 6), (229, 141, 6), (229, 119, 6), + (233, 95, 6), (240, 76, 7), (243, 64, 7), (247, 57, 7), + (250, 55, 6), (251, 53, 6), (252, 54, 7), (251, 55, 8), + (250, 60, 7), (252, 68, 7), (251, 75, 7), (251, 82, 6), + (250, 83, 7), (249, 78, 7), (251, 69, 7), (249, 60, 7), + (246, 48, 6), (242, 40, 7), (236, 35, 8), (235, 38, 8), + (233, 52, 9), (235, 71, 10), (235, 89, 18), (231, 113, 30), + (232, 133, 43), (227, 152, 58), (227, 177, 59), (222, 186, 61), + (218, 198, 57), (218, 195, 55), (219, 181, 61), (225, 166, 55), + (220, 137, 50), (216, 116, 35), (210, 95, 20), (206, 81, 12), + (208, 74, 6), (203, 70, 6), (204, 71, 6), (204, 69, 5), + (208, 70, 5), (208, 75, 5), (202, 89, 6), (202, 105, 6), + (202, 121, 6), (204, 131, 7), (200, 133, 7), (187, 132, 7), + (169, 128, 7), (151, 128, 6), (140, 131, 7), (129, 135, 6), + (119, 134, 5), (111, 134, 5), (101, 131, 3), (99, 134, 3), + (101, 146, 3), (104, 157, 5), (108, 167, 4), (110, 170, 4), + (116, 175, 4), (130, 185, 2), (147, 200, 5), (161, 215, 5) + ), + +// 383 040221-26 +((157, 81, 83), (137, 70, 91), (125, 64, 91), (113, 59, 92), + (107, 55, 91), (101, 52, 90), (101, 52, 89), (101, 52, 88), + (120, 62, 95), (130, 67, 96), (140, 73, 97), (147, 77, 96), + (155, 82, 95), (161, 86, 96), (167, 90, 98), (168, 91, 99), + (169, 93, 100), (172, 93, 106), (171, 95, 114), (170, 98, 122), + (170, 101, 132), (170, 105, 143), (168, 108, 148), (167, 111, 153), + (163, 113, 157), (163, 112, 154), (164, 111, 152), (174, 117, 153), + (184, 124, 154), (190, 131, 157), (196, 138, 161), (209, 152, 163), + (218, 163, 165), (221, 164, 152), (221, 159, 141), (222, 154, 130), + (219, 147, 124), (217, 140, 119), (214, 138, 117), (212, 136, 115), + (191, 123, 113), (178, 113, 111), (165, 104, 110), (152, 91, 112), + (140, 78, 114), (135, 73, 112), (130, 68, 111), (120, 61, 107), + (110, 56, 107), (94, 53, 105), (92, 52, 108), (90, 52, 111), + (97, 53, 110), (104, 55, 110), (109, 56, 109), (115, 58, 108), + (136, 68, 98), (145, 71, 92), (155, 75, 86), (163, 75, 80), + (171, 75, 75), (173, 74, 73), (176, 74, 71), (178, 74, 68), + (177, 74, 68), (166, 75, 76), (160, 73, 77), (154, 71, 78), + (151, 68, 77), (148, 66, 76), (144, 63, 73), (139, 61, 69), + (121, 56, 77), (115, 56, 84), (109, 56, 91), (112, 59, 96), + (116, 63, 101), (123, 67, 100), (131, 72, 99), (146, 86, 102), + (159, 98, 107), (174, 121, 123), (174, 128, 134), (174, 135, 145), + (177, 136, 147), (180, 138, 149), (184, 143, 150), (186, 144, 150), + (184, 144, 147), (173, 139, 147), (162, 134, 148), (157, 129, 147), + (153, 124, 147), (146, 116, 140), (142, 105, 133), (143, 98, 126), + (144, 93, 119), (149, 95, 111), (155, 105, 114), (161, 115, 118), + (164, 119, 121), (168, 124, 125), (179, 132, 133), (188, 139, 143), + (205, 150, 162), (212, 157, 171), (219, 165, 181), (218, 169, 186), + (218, 174, 191), (218, 183, 197), (219, 189, 201), (222, 190, 204), + (221, 191, 207), (224, 193, 207), (223, 192, 205), (222, 192, 203), + (216, 191, 200), (211, 187, 195), (203, 177, 187), (194, 166, 176), + (179, 149, 163), (172, 141, 157), (166, 133, 152), (165, 131, 150), + (165, 129, 149), (162, 121, 143), (158, 109, 134), (155, 98, 127), + (154, 90, 121), (156, 82, 108), (161, 84, 106), (166, 86, 104), + (176, 93, 102), (186, 100, 102), (197, 109, 104), (203, 119, 108), + (207, 129, 122), (201, 126, 128), (195, 124, 134), (189, 120, 136), + (184, 116, 138), (176, 110, 140), (167, 107, 140), (164, 106, 139), + (166, 108, 138), (174, 117, 139), (175, 118, 140), (176, 120, 141), + (177, 120, 140), (176, 121, 141), (178, 122, 137), (183, 122, 130), + (200, 126, 117), (201, 126, 116), (203, 126, 115), (201, 127, 114), + (192, 126, 117), (182, 125, 121), (171, 120, 123), (162, 112, 121), + (157, 103, 114), (148, 80, 96), (147, 75, 92), (146, 71, 88), + (145, 66, 83), (144, 64, 80), (147, 63, 80), (154, 67, 78), + (175, 79, 75), (181, 82, 74), (188, 86, 73), (202, 94, 73), + (213, 101, 73), (223, 106, 77), (228, 112, 81), (231, 120, 87), + (230, 126, 95), (223, 130, 106), (215, 132, 116), (209, 133, 120), + (200, 128, 123), (188, 121, 124), (176, 114, 125), (168, 108, 122), + (151, 95, 120), (151, 94, 119), (151, 94, 118), (154, 91, 115), + (155, 87, 110), (155, 81, 105), (155, 78, 98), (154, 71, 87), + (150, 65, 80), (148, 62, 74), (148, 60, 69), (148, 60, 65), + (151, 59, 61), (153, 59, 59), (154, 58, 59), (152, 55, 57), + (150, 54, 55), (150, 52, 54), (149, 52, 55), (150, 54, 56), + (154, 57, 57), (161, 63, 60), (169, 68, 62), (177, 73, 63), + (187, 76, 63), (196, 79, 64), (202, 81, 65), (207, 81, 66), + (210, 82, 66), (211, 84, 66), (208, 83, 67), (206, 82, 66), + (204, 80, 66), (201, 77, 64), (196, 72, 63), (188, 66, 61), + (179, 62, 59), (168, 59, 60), (157, 57, 64), (148, 55, 68), + (143, 56, 72), (143, 59, 75), (145, 62, 76), (151, 65, 77), + (156, 71, 79), (159, 77, 83), (161, 82, 90), (165, 88, 96), + (171, 92, 100), (179, 97, 101), (190, 98, 101), (204, 101, 97), + (217, 106, 93), (228, 110, 94), (235, 114, 96), (239, 120, 100), + (240, 128, 105), (241, 134, 110), (243, 137, 111), (244, 137, 109), + (245, 138, 107), (245, 135, 104), (243, 132, 100), (241, 131, 99), + (239, 134, 100), (236, 136, 103), (233, 136, 104), (223, 130, 100), + (212, 122, 96), (200, 112, 90), (186, 100, 86), (172, 88, 82) + ), + +// 384 040221-27 +((200, 139, 100), (180, 128, 94), (175, 123, 93), (170, 119, 92), + (167, 116, 89), (165, 113, 87), (162, 108, 87), (159, 104, 87), + (147, 89, 80), (146, 86, 73), (145, 84, 67), (149, 90, 63), + (154, 96, 60), (167, 107, 59), (180, 119, 58), (185, 124, 59), + (191, 130, 61), (210, 146, 65), (215, 149, 66), (220, 152, 68), + (223, 155, 70), (226, 158, 72), (229, 162, 73), (232, 166, 74), + (242, 183, 85), (246, 189, 89), (250, 196, 93), (252, 198, 94), + (254, 201, 96), (252, 199, 95), (250, 197, 94), (245, 191, 91), + (239, 181, 87), (218, 155, 76), (207, 142, 69), (196, 129, 63), + (185, 116, 57), (175, 104, 51), (169, 99, 47), (164, 94, 44), + (145, 73, 37), (135, 63, 33), (126, 53, 29), (121, 46, 27), + (116, 40, 25), (115, 39, 25), (115, 39, 26), (117, 41, 26), + (121, 45, 32), (132, 54, 49), (136, 62, 58), (141, 70, 68), + (147, 78, 74), (153, 87, 81), (156, 91, 83), (159, 95, 85), + (162, 104, 91), (164, 105, 92), (166, 107, 93), (165, 108, 94), + (165, 109, 96), (165, 110, 97), (165, 112, 98), (169, 117, 100), + (173, 126, 103), (183, 141, 112), (187, 145, 111), (192, 149, 110), + (194, 150, 110), (197, 152, 110), (202, 155, 107), (209, 161, 104), + (226, 175, 107), (233, 182, 111), (240, 190, 116), (245, 196, 117), + (251, 202, 118), (252, 203, 116), (254, 204, 115), (254, 204, 110), + (254, 204, 105), (254, 202, 96), (254, 197, 93), (254, 193, 90), + (254, 189, 89), (254, 186, 88), (253, 182, 90), (253, 180, 92), + (253, 179, 96), (253, 181, 97), (253, 183, 98), (253, 184, 98), + (253, 186, 98), (254, 183, 94), (254, 181, 94), (253, 180, 95), + (253, 179, 96), (252, 179, 102), (251, 182, 107), (250, 186, 112), + (250, 186, 112), (250, 186, 113), (249, 185, 112), (247, 183, 110), + (242, 174, 106), (238, 170, 102), (234, 166, 98), (231, 164, 97), + (229, 162, 96), (228, 156, 95), (229, 150, 94), (228, 145, 93), + (226, 140, 91), (214, 125, 85), (209, 121, 82), (205, 117, 79), + (193, 111, 74), (184, 106, 70), (181, 103, 70), (184, 104, 73), + (192, 113, 89), (197, 117, 99), (202, 122, 110), (202, 123, 114), + (202, 125, 119), (200, 130, 125), (198, 133, 126), (202, 139, 127), + (207, 146, 129), (224, 166, 132), (229, 171, 133), (234, 177, 135), + (242, 186, 138), (248, 194, 140), (251, 197, 138), (253, 200, 133), + (254, 202, 120), (254, 202, 113), (254, 203, 106), (254, 203, 103), + (254, 203, 100), (254, 203, 97), (254, 203, 95), (254, 203, 94), + (253, 202, 93), (252, 193, 94), (251, 191, 95), (250, 189, 97), + (249, 187, 103), (249, 187, 109), (250, 188, 118), (250, 191, 126), + (251, 198, 139), (250, 198, 139), (250, 199, 140), (250, 196, 139), + (249, 195, 139), (249, 193, 137), (248, 191, 138), (248, 188, 138), + (244, 188, 138), (228, 178, 127), (222, 172, 121), (216, 166, 116), + (204, 153, 104), (192, 138, 88), (181, 124, 74), (172, 108, 62), + (162, 89, 46), (158, 84, 43), (155, 79, 40), (144, 68, 32), + (133, 57, 26), (121, 47, 18), (110, 36, 12), (99, 25, 8), + (90, 20, 5), (90, 21, 9), (96, 23, 15), (101, 29, 19), + (109, 37, 26), (119, 49, 34), (130, 61, 43), (141, 71, 50), + (152, 94, 63), (156, 99, 67), (161, 105, 72), (169, 117, 84), + (178, 128, 95), (189, 141, 106), (201, 154, 118), (216, 165, 127), + (227, 177, 132), (237, 188, 134), (244, 196, 135), (249, 204, 135), + (252, 209, 133), (253, 208, 129), (249, 203, 125), (244, 193, 120), + (236, 183, 112), (228, 173, 102), (219, 163, 92), (214, 154, 84), + (207, 150, 78), (206, 146, 73), (204, 143, 71), (202, 136, 67), + (198, 131, 67), (195, 126, 64), (186, 120, 63), (179, 113, 63), + (168, 106, 63), (162, 104, 63), (159, 103, 66), (158, 102, 67), + (159, 103, 70), (162, 103, 72), (165, 107, 75), (168, 112, 80), + (171, 113, 86), (175, 118, 92), (179, 124, 96), (183, 128, 98), + (186, 133, 99), (191, 136, 98), (195, 137, 98), (198, 142, 99), + (201, 145, 103), (205, 149, 109), (208, 153, 113), (212, 156, 117), + (218, 162, 120), (225, 168, 121), (230, 172, 121), (232, 176, 118), + (232, 178, 115), (233, 179, 114), (231, 179, 112), (230, 177, 110), + (229, 176, 108), (230, 176, 106), (234, 179, 105), (238, 183, 103), + (243, 187, 102), (248, 192, 102), (251, 196, 101), (253, 200, 101), + (255, 202, 99), (255, 202, 97), (253, 199, 97), (251, 193, 98), + (243, 183, 100), (234, 173, 101), (223, 161, 101), (211, 149, 101) + ), + +// 385 040221-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), + (3, 5, 4), (6, 9, 9), (9, 14, 15), (12, 18, 19), + (15, 23, 23), (16, 26, 26), (17, 29, 30), (18, 32, 32), + (20, 35, 35), (27, 39, 40), (25, 37, 39), (24, 36, 38), + (21, 33, 35), (18, 30, 32), (16, 27, 30), (15, 25, 28), + (17, 24, 24), (17, 27, 28), (18, 30, 32), (26, 42, 43), + (34, 54, 54), (36, 59, 59), (38, 64, 65), (48, 85, 85), + (71, 107, 105), (92, 165, 160), (107, 180, 175), (122, 195, 190), + (98, 157, 155), (75, 120, 120), (72, 119, 118), (70, 118, 117), + (33, 58, 56), (29, 49, 48), (25, 40, 40), (22, 37, 37), + (20, 35, 35), (19, 32, 33), (18, 30, 32), (14, 27, 28), + (14, 27, 28), (13, 25, 27), (11, 22, 24), (9, 19, 22), + (8, 18, 20), (7, 17, 19), (8, 17, 18), (9, 17, 17), + (9, 17, 17), (9, 17, 17), (10, 18, 18), (12, 20, 20), + (14, 22, 22), (14, 22, 22), (14, 22, 22), (12, 23, 22), + (10, 22, 20), (7, 17, 19), (7, 17, 19), (7, 17, 19), + (7, 15, 16), (7, 14, 14), (5, 13, 13), (5, 13, 13), + (2, 14, 15), (3, 14, 16), (5, 15, 18), (6, 14, 16), + (7, 14, 14), (6, 13, 13), (5, 13, 13), (4, 12, 12), + (2, 12, 14), (4, 24, 24), (8, 31, 31), (12, 38, 39), + (15, 39, 40), (19, 41, 41), (23, 40, 41), (24, 41, 41), + (23, 40, 40), (20, 37, 37), (18, 35, 35), (16, 33, 33), + (14, 32, 32), (14, 27, 28), (18, 33, 33), (23, 40, 40), + (27, 51, 53), (48, 77, 77), (54, 87, 87), (61, 98, 98), + (63, 101, 100), (65, 105, 103), (60, 98, 101), (66, 92, 94), + (55, 95, 94), (51, 86, 87), (48, 77, 80), (44, 71, 73), + (40, 66, 67), (40, 65, 64), (38, 63, 64), (36, 54, 54), + (29, 53, 48), (22, 36, 36), (20, 30, 30), (18, 25, 25), + (12, 19, 19), (7, 12, 13), (3, 8, 9), (2, 4, 3), + (2, 2, 2), (1, 2, 1), (0, 2, 1), (0, 1, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 7, 9), (1, 8, 9), (3, 10, 10), + (9, 17, 17), (12, 22, 24), (13, 25, 27), (15, 30, 30), + (22, 36, 36), (22, 37, 37), (23, 38, 38), (21, 38, 38), + (20, 38, 38), (19, 36, 36), (20, 35, 35), (22, 36, 36), + (22, 39, 39), (24, 39, 39), (24, 39, 39), (24, 39, 39), + (23, 40, 40), (22, 41, 41), (18, 45, 43), (22, 46, 44), + (28, 53, 51), (28, 53, 50), (29, 53, 50), (33, 53, 53), + (36, 54, 54), (32, 54, 54), (29, 49, 48), (30, 44, 46), + (25, 40, 40), (17, 32, 32), (15, 29, 30), (14, 27, 28), + (13, 25, 27), (14, 24, 27), (17, 27, 30), (22, 32, 34), + (25, 45, 44), (25, 45, 44), (25, 45, 44), (29, 51, 51), + (32, 54, 54), (30, 53, 53), (29, 49, 49), (27, 46, 46), + (25, 45, 45), (25, 43, 44), (24, 41, 43), (25, 43, 44), + (25, 45, 45), (30, 53, 53), (30, 55, 54), (35, 60, 59), + (43, 67, 69), (43, 70, 71), (44, 74, 74), (49, 81, 82), + (53, 87, 89), (46, 79, 77), (45, 77, 79), (43, 72, 72), + (36, 64, 61), (35, 60, 59), (33, 55, 58), (29, 51, 51), + (28, 45, 45), (28, 46, 43), (25, 43, 44), (24, 44, 43), + (24, 39, 39), (19, 34, 34), (14, 27, 28), (12, 22, 24), + (9, 14, 18), (5, 10, 12), (4, 5, 8), (3, 4, 7), + (2, 7, 8), (3, 10, 10), (4, 9, 10), (5, 10, 9), + (5, 10, 12), (7, 12, 13), (7, 14, 14), (7, 14, 14), + (9, 17, 17), (9, 19, 22), (7, 22, 22), (10, 23, 24), + (12, 22, 24), (12, 22, 24), (14, 24, 27), (13, 25, 27), + (18, 28, 30), (18, 30, 32), (18, 33, 33), (20, 38, 38), + (23, 40, 41), (24, 41, 43), (25, 48, 48), (29, 51, 51), + (30, 53, 53), (32, 54, 54), (30, 56, 58), (32, 58, 59), + (32, 58, 59), (39, 64, 63), (40, 65, 64), (43, 75, 74), + (45, 77, 76), (45, 75, 75), (44, 70, 71), (39, 64, 63), + (38, 63, 64), (33, 63, 63), (33, 58, 56), (32, 56, 55), + (33, 58, 59), (38, 67, 67), (43, 72, 72), (48, 77, 77), + (53, 90, 90), (54, 98, 98), (75, 129, 131), (60, 102, 103) + ), + +// 386 040221-29 +((44, 40, 28), (53, 50, 35), (53, 49, 36), (53, 49, 37), + (47, 47, 34), (42, 46, 32), (40, 41, 29), (39, 36, 27), + (35, 35, 25), (33, 31, 22), (31, 28, 19), (28, 27, 15), + (25, 26, 12), (23, 24, 14), (21, 22, 17), (21, 21, 15), + (21, 21, 13), (22, 20, 7), (21, 17, 5), (21, 15, 3), + (17, 13, 2), (14, 11, 2), (15, 12, 3), (16, 13, 4), + (19, 19, 11), (22, 20, 12), (25, 22, 13), (27, 26, 18), + (29, 30, 24), (31, 31, 26), (33, 32, 28), (39, 35, 26), + (41, 39, 26), (54, 51, 32), (61, 58, 36), (68, 66, 41), + (86, 79, 48), (105, 93, 55), (110, 98, 58), (115, 103, 61), + (111, 105, 73), (107, 102, 75), (104, 99, 77), (100, 93, 62), + (96, 87, 48), (90, 81, 41), (85, 76, 35), (65, 58, 30), + (55, 49, 25), (44, 38, 16), (41, 34, 14), (38, 31, 12), + (30, 27, 11), (23, 24, 10), (21, 22, 10), (20, 20, 10), + (17, 16, 11), (18, 16, 12), (20, 16, 13), (19, 17, 12), + (19, 19, 11), (18, 19, 11), (18, 19, 11), (19, 18, 13), + (21, 17, 14), (16, 17, 12), (14, 15, 9), (13, 14, 6), + (9, 12, 5), (6, 11, 4), (13, 14, 9), (14, 15, 9), + (17, 16, 11), (17, 17, 8), (18, 18, 6), (23, 20, 5), + (28, 23, 4), (31, 24, 2), (35, 25, 0), (40, 30, 3), + (31, 24, 6), (32, 29, 14), (34, 31, 16), (37, 34, 19), + (38, 34, 17), (40, 35, 16), (45, 34, 14), (43, 38, 19), + (33, 34, 18), (28, 29, 17), (24, 25, 17), (23, 23, 17), + (23, 22, 17), (23, 20, 15), (25, 23, 11), (30, 27, 10), + (31, 32, 14), (39, 40, 24), (41, 40, 24), (44, 41, 24), + (45, 43, 24), (47, 45, 24), (50, 44, 22), (53, 45, 26), + (58, 52, 28), (58, 52, 28), (58, 52, 28), (58, 53, 26), + (59, 54, 25), (61, 52, 21), (62, 57, 25), (58, 54, 29), + (58, 53, 31), (64, 60, 35), (68, 61, 37), (73, 62, 40), + (87, 78, 47), (110, 101, 68), (126, 115, 83), (136, 123, 88), + (139, 128, 98), (130, 122, 91), (122, 116, 84), (113, 107, 80), + (104, 99, 77), (85, 82, 63), (75, 69, 53), (63, 60, 45), + (52, 50, 37), (31, 28, 23), (29, 26, 19), (27, 24, 15), + (26, 23, 14), (25, 23, 11), (27, 23, 11), (31, 25, 13), + (36, 31, 11), (40, 34, 13), (44, 38, 16), (46, 40, 18), + (48, 42, 20), (50, 45, 25), (54, 49, 30), (60, 54, 38), + (59, 57, 44), (65, 53, 31), (65, 55, 31), (65, 58, 32), + (69, 59, 34), (76, 65, 43), (98, 86, 46), (115, 104, 74), + (154, 145, 106), (167, 160, 111), (180, 175, 117), (193, 183, 124), + (183, 172, 126), (180, 163, 117), (158, 148, 112), (134, 130, 101), + (104, 97, 81), (75, 70, 48), (74, 66, 42), (73, 63, 36), + (75, 67, 31), (88, 82, 32), (108, 94, 49), (123, 110, 65), + (166, 154, 94), (164, 153, 98), (162, 152, 103), (165, 153, 113), + (160, 151, 120), (162, 155, 113), (156, 145, 100), (143, 136, 90), + (121, 113, 76), (102, 93, 62), (83, 74, 43), (76, 68, 32), + (71, 65, 33), (74, 67, 38), (80, 77, 46), (98, 91, 65), + (96, 96, 72), (95, 96, 71), (94, 97, 70), (83, 81, 60), + (77, 75, 50), (76, 73, 42), (72, 68, 43), (69, 67, 46), + (74, 72, 51), (78, 76, 55), (86, 80, 54), (97, 91, 65), + (97, 91, 59), (105, 94, 49), (88, 79, 46), (81, 67, 38), + (67, 63, 36), (63, 57, 35), (56, 55, 34), (52, 45, 26), + (45, 39, 25), (46, 43, 26), (49, 46, 29), (49, 47, 35), + (62, 56, 40), (81, 74, 48), (104, 93, 65), (121, 111, 84), + (137, 125, 83), (151, 135, 86), (128, 119, 80), (105, 94, 66), + (81, 76, 44), (67, 60, 31), (57, 51, 25), (51, 45, 23), + (46, 41, 19), (45, 39, 23), (44, 43, 23), (48, 43, 24), + (49, 43, 17), (53, 49, 20), (56, 50, 16), (59, 51, 14), + (59, 55, 20), (60, 51, 18), (56, 45, 23), (50, 43, 25), + (47, 44, 25), (41, 40, 22), (34, 32, 19), (31, 29, 16), + (24, 24, 14), (20, 22, 11), (21, 21, 11), (27, 24, 9), + (31, 28, 11), (37, 32, 12), (44, 37, 18), (59, 50, 21), + (73, 66, 38), (108, 94, 65), (137, 127, 100), (185, 175, 140), + (221, 214, 172), (233, 224, 185), (196, 183, 141), (152, 143, 110), + (128, 118, 82), (113, 104, 65), (83, 78, 49), (76, 66, 39) + ), + +// 387 040221-30 +((84, 36, 31), (82, 62, 55), (90, 62, 56), (98, 63, 58), + (115, 55, 48), (132, 47, 38), (136, 41, 32), (141, 35, 27), + (146, 15, 6), (132, 10, 3), (119, 6, 0), (104, 15, 10), + (90, 24, 21), (85, 35, 28), (80, 47, 35), (77, 52, 40), + (74, 57, 46), (75, 63, 43), (78, 63, 38), (81, 64, 34), + (86, 68, 39), (91, 72, 44), (95, 76, 49), (100, 81, 55), + (125, 77, 55), (133, 68, 49), (141, 59, 43), (154, 48, 27), + (168, 38, 11), (166, 32, 8), (164, 27, 5), (156, 28, 3), + (144, 23, 2), (108, 22, 10), (88, 23, 14), (68, 24, 19), + (57, 35, 25), (47, 47, 32), (52, 42, 31), (57, 38, 31), + (82, 25, 19), (102, 16, 12), (123, 7, 6), (121, 5, 3), + (120, 4, 0), (119, 13, 3), (118, 23, 7), (115, 43, 27), + (120, 52, 45), (135, 113, 95), (144, 121, 109), (153, 130, 124), + (146, 130, 125), (139, 131, 126), (132, 123, 117), (126, 115, 109), + (111, 69, 62), (98, 49, 45), (86, 30, 28), (73, 16, 15), + (60, 3, 2), (52, 2, 1), (45, 2, 1), (30, 0, 0), + (15, 2, 0), (3, 0, 0), (2, 0, 0), (2, 0, 0), + (2, 0, 0), (2, 0, 0), (3, 1, 1), (7, 5, 4), + (19, 21, 17), (28, 31, 26), (37, 42, 35), (50, 57, 48), + (63, 73, 62), (69, 79, 68), (76, 85, 74), (93, 104, 92), + (102, 112, 97), (100, 111, 95), (93, 102, 87), (87, 93, 79), + (85, 94, 79), (83, 95, 79), (85, 90, 77), (92, 87, 79), + (127, 117, 104), (145, 128, 111), (163, 140, 119), (164, 149, 127), + (165, 159, 136), (173, 163, 139), (170, 161, 143), (155, 158, 143), + (140, 140, 132), (110, 100, 95), (98, 73, 69), (87, 47, 44), + (82, 39, 37), (77, 32, 31), (65, 21, 17), (57, 12, 5), + (41, 12, 2), (30, 12, 1), (20, 13, 1), (18, 11, 0), + (16, 9, 0), (12, 5, 0), (10, 5, 0), (11, 2, 0), + (19, 0, 0), (47, 0, 0), (52, 0, 0), (57, 0, 0), + (64, 12, 4), (68, 24, 11), (73, 20, 13), (79, 24, 15), + (103, 35, 19), (100, 38, 17), (97, 42, 15), (98, 39, 12), + (100, 37, 9), (77, 42, 10), (50, 43, 10), (37, 29, 7), + (29, 22, 6), (10, 9, 4), (8, 6, 2), (6, 4, 1), + (4, 3, 0), (2, 2, 0), (1, 0, 0), (0, 0, 0), + (0, 1, 0), (3, 3, 2), (7, 6, 5), (8, 8, 6), + (10, 10, 8), (16, 20, 17), (23, 27, 24), (28, 31, 26), + (32, 39, 31), (42, 36, 28), (44, 33, 25), (46, 31, 22), + (50, 27, 17), (52, 20, 12), (50, 15, 6), (45, 10, 1), + (28, 6, 1), (23, 4, 0), (18, 3, 0), (11, 0, 0), + (6, 0, 0), (6, 2, 2), (8, 6, 4), (14, 11, 8), + (27, 12, 8), (52, 11, 8), (59, 10, 7), (67, 10, 6), + (78, 3, 2), (86, 0, 0), (89, 0, 0), (86, 2, 2), + (70, 24, 17), (69, 28, 22), (68, 33, 28), (69, 54, 44), + (70, 73, 59), (82, 85, 78), (98, 100, 96), (110, 118, 109), + (126, 133, 123), (135, 141, 134), (141, 151, 140), (145, 151, 140), + (144, 142, 137), (139, 137, 132), (133, 125, 124), (122, 110, 116), + (109, 105, 105), (109, 105, 104), (109, 105, 104), (109, 105, 106), + (112, 111, 110), (119, 123, 115), (124, 128, 117), (133, 129, 114), + (141, 131, 111), (137, 130, 111), (137, 129, 106), (138, 125, 99), + (129, 115, 99), (118, 107, 98), (111, 99, 89), (103, 86, 74), + (96, 72, 60), (91, 61, 53), (86, 56, 51), (89, 63, 54), + (89, 71, 61), (90, 77, 72), (96, 90, 86), (97, 99, 92), + (98, 102, 91), (99, 105, 92), (105, 111, 96), (109, 116, 103), + (110, 123, 109), (114, 128, 111), (114, 123, 111), (109, 119, 108), + (96, 111, 97), (83, 90, 76), (72, 73, 59), (60, 56, 42), + (57, 37, 23), (57, 21, 13), (62, 14, 5), (72, 7, 0), + (81, 1, 0), (89, 1, 1), (95, 1, 1), (100, 1, 1), + (100, 1, 1), (99, 2, 2), (99, 2, 1), (98, 0, 0), + (93, 1, 0), (82, 3, 1), (66, 3, 0), (55, 3, 0), + (40, 4, 0), (21, 4, 0), (13, 6, 0), (10, 7, 2), + (12, 11, 6), (18, 20, 13), (25, 26, 18), (39, 34, 21), + (60, 40, 26), (83, 36, 30), (106, 41, 30), (120, 49, 35), + (125, 49, 40), (127, 52, 44), (125, 51, 43), (114, 41, 35), + (98, 36, 29), (94, 24, 21), (94, 15, 17), (88, 26, 24) + ), + +// 388 040221-31 +((46, 43, 27), (52, 49, 31), (51, 48, 32), (50, 47, 33), + (46, 44, 32), (42, 42, 32), (41, 42, 31), (40, 42, 31), + (46, 46, 36), (52, 51, 37), (58, 56, 38), (63, 59, 36), + (69, 62, 34), (70, 62, 35), (71, 63, 37), (71, 64, 36), + (72, 65, 35), (68, 59, 29), (64, 57, 29), (60, 55, 30), + (59, 52, 25), (58, 49, 21), (57, 48, 19), (57, 47, 18), + (52, 44, 16), (48, 39, 14), (44, 35, 12), (39, 32, 13), + (34, 29, 15), (31, 27, 15), (29, 26, 15), (25, 23, 15), + (23, 21, 15), (23, 23, 17), (27, 26, 18), (32, 30, 20), + (42, 39, 27), (52, 48, 35), (59, 55, 41), (66, 62, 47), + (95, 88, 68), (99, 91, 71), (104, 95, 75), (101, 93, 72), + (98, 91, 70), (94, 86, 64), (90, 81, 58), (76, 66, 46), + (62, 54, 33), (42, 37, 19), (39, 33, 16), (37, 30, 14), + (36, 31, 15), (36, 33, 17), (37, 34, 18), (39, 35, 20), + (44, 40, 25), (45, 41, 25), (47, 42, 26), (46, 40, 24), + (46, 39, 23), (45, 38, 21), (44, 37, 19), (40, 34, 16), + (36, 31, 12), (29, 23, 7), (26, 21, 6), (23, 20, 6), + (22, 19, 6), (21, 19, 7), (20, 19, 7), (19, 18, 8), + (16, 16, 9), (15, 15, 8), (14, 14, 7), (13, 12, 5), + (12, 11, 4), (11, 10, 3), (11, 10, 3), (10, 9, 2), + (8, 7, 1), (7, 4, 0), (7, 3, 0), (8, 3, 0), + (8, 3, 0), (9, 3, 0), (11, 4, 0), (12, 6, 0), + (16, 10, 2), (16, 12, 3), (17, 14, 5), (18, 15, 6), + (20, 17, 8), (23, 20, 11), (27, 24, 14), (31, 27, 16), + (36, 33, 18), (46, 42, 23), (49, 44, 22), (52, 46, 22), + (53, 46, 21), (54, 47, 21), (53, 46, 21), (50, 43, 20), + (45, 38, 14), (42, 36, 12), (40, 34, 10), (38, 32, 9), + (36, 31, 9), (34, 29, 8), (32, 27, 5), (32, 26, 4), + (32, 26, 3), (37, 28, 4), (38, 29, 5), (40, 31, 7), + (45, 35, 10), (50, 41, 14), (55, 44, 17), (57, 48, 22), + (58, 53, 33), (60, 55, 37), (63, 57, 41), (63, 59, 42), + (64, 61, 44), (70, 67, 48), (76, 73, 52), (86, 77, 56), + (89, 84, 59), (94, 89, 59), (94, 87, 58), (95, 86, 58), + (91, 84, 60), (84, 80, 57), (79, 77, 58), (82, 78, 60), + (96, 91, 77), (106, 99, 82), (116, 108, 88), (121, 113, 90), + (127, 119, 93), (138, 130, 99), (146, 136, 103), (153, 143, 106), + (157, 146, 107), (156, 149, 108), (153, 147, 108), (151, 145, 109), + (145, 139, 106), (139, 134, 104), (124, 124, 97), (108, 110, 89), + (81, 81, 64), (73, 75, 59), (66, 69, 54), (55, 58, 44), + (45, 48, 35), (41, 40, 28), (37, 35, 23), (34, 32, 19), + (31, 29, 16), (29, 28, 15), (28, 27, 15), (28, 27, 15), + (28, 28, 16), (29, 28, 16), (31, 30, 17), (32, 31, 19), + (35, 34, 23), (35, 34, 23), (36, 35, 23), (38, 36, 24), + (41, 38, 25), (44, 42, 27), (49, 46, 27), (58, 54, 30), + (69, 64, 37), (82, 77, 45), (93, 87, 52), (105, 100, 59), + (116, 109, 68), (126, 118, 76), (128, 119, 78), (124, 117, 74), + (113, 105, 65), (109, 102, 62), (106, 99, 60), (101, 91, 54), + (100, 92, 53), (104, 96, 58), (113, 108, 68), (131, 123, 84), + (159, 149, 97), (181, 171, 118), (196, 189, 136), (207, 199, 156), + (219, 211, 161), (216, 207, 158), (201, 192, 146), (177, 170, 136), + (158, 152, 121), (135, 130, 103), (113, 106, 82), (93, 87, 64), + (82, 77, 52), (76, 72, 47), (72, 69, 46), (68, 67, 45), + (67, 65, 43), (65, 62, 39), (62, 59, 34), (56, 54, 28), + (50, 49, 22), (44, 42, 16), (39, 35, 12), (33, 29, 6), + (29, 24, 2), (24, 21, 1), (21, 19, 2), (20, 18, 3), + (21, 18, 4), (22, 19, 5), (24, 21, 7), (26, 25, 9), + (32, 30, 14), (40, 38, 17), (52, 47, 22), (65, 59, 29), + (80, 73, 39), (95, 87, 46), (109, 101, 53), (123, 112, 61), + (134, 120, 69), (139, 125, 74), (135, 123, 75), (126, 116, 72), + (114, 104, 67), (101, 91, 61), (85, 78, 53), (69, 63, 44), + (55, 50, 33), (44, 39, 25), (35, 33, 19), (29, 28, 16), + (25, 25, 13), (22, 22, 12), (20, 20, 11), (18, 18, 10), + (17, 17, 9), (17, 16, 9), (17, 16, 10), (20, 19, 11), + (21, 20, 11), (31, 28, 15), (38, 34, 19), (48, 43, 26) + ), + +// 389 040221-32 +((206, 195, 184), (218, 208, 198), (220, 210, 199), (222, 212, 201), + (226, 217, 206), (231, 222, 212), (233, 223, 212), (235, 225, 213), + (234, 223, 211), (229, 218, 206), (225, 214, 201), (220, 208, 195), + (215, 203, 190), (212, 200, 188), (209, 198, 187), (209, 198, 187), + (210, 199, 187), (214, 205, 195), (219, 210, 200), (224, 215, 205), + (231, 222, 212), (238, 230, 220), (239, 231, 221), (241, 233, 223), + (235, 226, 216), (223, 214, 203), (211, 202, 191), (192, 182, 169), + (174, 162, 148), (164, 150, 134), (154, 138, 121), (133, 110, 89), + (119, 94, 72), (99, 68, 41), (97, 68, 43), (96, 69, 46), + (99, 73, 51), (102, 77, 56), (102, 77, 56), (102, 77, 56), + (92, 68, 48), (88, 62, 40), (84, 56, 33), (83, 56, 34), + (82, 57, 36), (83, 59, 39), (85, 62, 43), (93, 70, 49), + (103, 78, 54), (117, 94, 74), (121, 96, 73), (126, 99, 73), + (120, 95, 72), (115, 92, 71), (107, 85, 65), (100, 78, 59), + (80, 57, 37), (76, 53, 34), (72, 50, 32), (84, 57, 33), + (97, 65, 35), (103, 72, 44), (110, 80, 53), (123, 95, 69), + (136, 109, 82), (155, 138, 120), (160, 145, 129), (165, 152, 139), + (165, 152, 139), (165, 152, 140), (165, 152, 140), (165, 151, 139), + (169, 150, 130), (174, 155, 133), (180, 160, 137), (188, 166, 140), + (196, 172, 143), (197, 174, 145), (198, 176, 148), (200, 178, 152), + (202, 181, 155), (205, 185, 159), (203, 186, 163), (202, 187, 167), + (201, 186, 166), (201, 186, 166), (197, 183, 166), (190, 179, 165), + (185, 170, 155), (178, 162, 148), (171, 155, 141), (168, 151, 136), + (165, 148, 132), (158, 141, 126), (152, 137, 121), (151, 135, 120), + (153, 137, 122), (166, 154, 141), (177, 164, 149), (188, 174, 158), + (192, 178, 162), (196, 182, 166), (201, 187, 168), (206, 190, 167), + (205, 186, 161), (203, 182, 156), (201, 179, 152), (198, 177, 152), + (195, 176, 152), (191, 174, 154), (190, 174, 156), (187, 174, 160), + (185, 175, 164), (185, 175, 165), (184, 174, 163), (183, 173, 162), + (181, 169, 158), (175, 162, 149), (166, 152, 136), (155, 138, 120), + (128, 108, 88), (117, 94, 73), (106, 81, 58), (103, 77, 54), + (100, 74, 51), (98, 71, 47), (99, 71, 48), (107, 77, 50), + (118, 86, 55), (130, 104, 81), (135, 109, 85), (140, 115, 90), + (143, 122, 101), (144, 126, 107), (149, 129, 107), (150, 130, 108), + (153, 133, 111), (156, 138, 118), (159, 143, 126), (159, 145, 130), + (160, 147, 134), (163, 151, 139), (169, 158, 147), (175, 164, 155), + (179, 168, 158), (193, 180, 165), (197, 183, 167), (201, 187, 170), + (205, 190, 172), (209, 193, 174), (207, 192, 173), (201, 185, 166), + (178, 162, 146), (172, 154, 137), (167, 147, 128), (155, 131, 108), + (140, 116, 93), (131, 103, 77), (121, 90, 61), (105, 76, 49), + (89, 62, 39), (69, 46, 26), (63, 42, 23), (58, 38, 21), + (63, 41, 23), (79, 54, 33), (92, 71, 52), (111, 91, 74), + (157, 140, 123), (165, 151, 136), (174, 162, 149), (189, 178, 166), + (203, 193, 182), (214, 205, 195), (224, 214, 205), (229, 220, 211), + (232, 222, 211), (233, 223, 210), (232, 221, 208), (230, 218, 202), + (227, 214, 195), (224, 210, 191), (221, 208, 189), (218, 206, 188), + (217, 206, 191), (217, 207, 193), (217, 209, 196), (218, 209, 199), + (221, 212, 202), (223, 215, 204), (223, 215, 204), (222, 213, 202), + (218, 209, 198), (214, 205, 194), (208, 199, 188), (199, 189, 178), + (190, 180, 169), (182, 171, 158), (177, 163, 146), (176, 159, 140), + (175, 158, 138), (176, 157, 135), (180, 160, 138), (181, 164, 146), + (181, 166, 150), (179, 166, 153), (178, 167, 156), (179, 167, 156), + (178, 167, 156), (178, 168, 159), (179, 169, 159), (180, 170, 160), + (181, 171, 162), (183, 173, 163), (185, 175, 164), (186, 176, 166), + (188, 179, 168), (193, 182, 170), (199, 186, 171), (204, 190, 174), + (208, 194, 177), (212, 197, 179), (214, 200, 183), (216, 202, 186), + (218, 204, 187), (218, 205, 191), (220, 208, 194), (224, 211, 195), + (225, 213, 198), (225, 215, 202), (226, 215, 202), (224, 215, 202), + (220, 212, 201), (217, 208, 197), (213, 204, 193), (210, 200, 188), + (208, 197, 185), (205, 195, 183), (206, 195, 183), (208, 198, 186), + (211, 202, 191), (217, 208, 198), (225, 215, 206), (231, 222, 212), + (236, 227, 218), (239, 230, 221), (239, 231, 222), (237, 228, 219), + (233, 225, 216), (230, 221, 213), (224, 216, 206), (220, 211, 201), + (213, 203, 193), (208, 198, 187), (211, 201, 191), (209, 199, 188) + ), + +// 390 040221-33 +((135, 92, 121), (124, 76, 110), (117, 68, 105), (110, 61, 101), + (106, 59, 100), (102, 58, 99), (99, 59, 100), (96, 60, 101), + (92, 70, 124), (94, 79, 137), (97, 88, 151), (104, 99, 161), + (111, 110, 172), (118, 119, 176), (125, 128, 181), (124, 130, 182), + (124, 132, 184), (119, 127, 182), (118, 126, 181), (117, 126, 181), + (120, 123, 177), (124, 120, 173), (128, 120, 170), (133, 120, 167), + (146, 118, 154), (149, 111, 146), (153, 105, 139), (151, 97, 132), + (150, 90, 125), (148, 86, 120), (147, 82, 115), (147, 75, 107), + (144, 71, 105), (138, 69, 104), (138, 70, 106), (139, 72, 109), + (142, 73, 109), (145, 75, 110), (148, 77, 110), (152, 80, 110), + (156, 87, 115), (156, 92, 121), (156, 98, 128), (157, 104, 136), + (158, 110, 145), (159, 112, 148), (160, 115, 151), (166, 120, 153), + (171, 121, 151), (173, 117, 144), (171, 116, 141), (170, 116, 139), + (163, 114, 136), (156, 112, 134), (154, 110, 132), (153, 109, 131), + (152, 102, 119), (154, 100, 117), (156, 99, 115), (159, 104, 119), + (163, 110, 123), (162, 112, 125), (161, 114, 127), (162, 118, 133), + (160, 123, 137), (161, 123, 141), (161, 122, 142), (161, 121, 143), + (164, 125, 146), (168, 130, 149), (172, 136, 152), (178, 145, 162), + (175, 158, 174), (164, 153, 171), (153, 149, 169), (139, 139, 164), + (125, 129, 160), (119, 123, 155), (113, 118, 151), (102, 110, 146), + (97, 106, 141), (91, 103, 134), (83, 105, 132), (76, 108, 130), + (71, 109, 131), (66, 110, 133), (57, 107, 130), (49, 100, 129), + (42, 85, 121), (42, 77, 113), (42, 69, 105), (42, 66, 98), + (43, 64, 91), (44, 65, 82), (48, 67, 77), (53, 70, 81), + (56, 75, 89), (67, 87, 107), (71, 83, 110), (75, 79, 113), + (75, 78, 112), (75, 77, 112), (76, 75, 108), (76, 72, 105), + (70, 73, 107), (68, 80, 110), (66, 87, 113), (64, 89, 115), + (62, 92, 117), (56, 98, 121), (50, 104, 120), (48, 104, 118), + (47, 103, 116), (58, 118, 125), (64, 123, 126), (70, 128, 128), + (84, 142, 136), (98, 155, 144), (110, 168, 153), (123, 180, 164), + (145, 195, 181), (159, 203, 191), (173, 212, 202), (181, 216, 207), + (190, 220, 213), (207, 229, 223), (224, 237, 233), (235, 240, 240), + (242, 241, 242), (241, 234, 241), (238, 231, 239), (236, 228, 237), + (228, 222, 233), (218, 217, 227), (216, 217, 226), (212, 211, 222), + (208, 207, 219), (210, 207, 219), (213, 208, 220), (214, 207, 220), + (215, 206, 221), (210, 207, 220), (212, 212, 223), (215, 216, 226), + (214, 217, 225), (223, 228, 233), (225, 230, 234), (227, 233, 235), + (231, 235, 237), (224, 236, 236), (216, 232, 233), (211, 224, 228), + (198, 200, 207), (196, 197, 203), (195, 195, 199), (188, 190, 188), + (182, 185, 178), (168, 179, 165), (149, 168, 152), (130, 153, 137), + (111, 132, 122), (83, 95, 91), (78, 88, 85), (73, 81, 79), + (71, 77, 72), (68, 80, 67), (61, 84, 64), (52, 87, 61), + (37, 74, 54), (36, 69, 52), (35, 65, 51), (40, 55, 50), + (50, 55, 55), (62, 64, 65), (76, 78, 79), (92, 98, 98), + (109, 116, 114), (124, 133, 130), (137, 148, 143), (152, 157, 154), + (169, 163, 162), (184, 172, 174), (199, 181, 184), (213, 195, 200), + (238, 224, 227), (241, 230, 232), (244, 236, 238), (248, 246, 247), + (252, 252, 251), (255, 255, 255), (255, 255, 255), (255, 255, 255), + (252, 251, 251), (248, 242, 244), (243, 231, 234), (234, 217, 225), + (225, 203, 214), (214, 188, 204), (204, 174, 193), (195, 163, 186), + (186, 153, 178), (177, 141, 169), (171, 129, 156), (164, 116, 145), + (156, 103, 130), (146, 91, 118), (138, 79, 104), (131, 74, 96), + (124, 76, 95), (120, 81, 99), (123, 90, 105), (130, 99, 114), + (142, 113, 124), (151, 127, 135), (163, 136, 141), (174, 142, 144), + (179, 149, 144), (181, 151, 144), (180, 152, 144), (174, 147, 141), + (173, 144, 140), (169, 144, 142), (167, 141, 142), (168, 134, 141), + (168, 130, 134), (167, 124, 128), (164, 117, 117), (153, 102, 104), + (143, 88, 90), (132, 77, 79), (120, 68, 69), (108, 59, 63), + (100, 53, 60), (98, 52, 60), (100, 53, 63), (105, 56, 69), + (113, 65, 80), (122, 75, 91), (131, 85, 101), (136, 94, 111), + (141, 102, 121), (145, 111, 129), (150, 118, 137), (155, 120, 144), + (162, 130, 154), (169, 138, 163), (176, 143, 169), (175, 144, 173), + (179, 146, 178), (175, 146, 175), (170, 143, 168), (162, 133, 158), + (155, 125, 149), (149, 119, 142), (147, 112, 133), (137, 101, 123) + ), + +// 391 040221-34 +((158, 126, 83), (176, 149, 109), (171, 152, 120), (167, 155, 132), + (181, 169, 150), (195, 183, 168), (205, 194, 180), (216, 206, 193), + (244, 240, 234), (248, 246, 242), (252, 252, 251), (251, 247, 242), + (251, 243, 234), (245, 229, 216), (239, 215, 199), (232, 206, 189), + (226, 197, 180), (181, 157, 152), (155, 137, 137), (130, 118, 123), + (113, 101, 112), (96, 85, 101), (91, 80, 97), (86, 75, 94), + (96, 77, 87), (112, 80, 87), (128, 84, 87), (144, 84, 80), + (161, 84, 73), (167, 84, 68), (173, 84, 64), (177, 81, 61), + (168, 79, 59), (144, 65, 48), (129, 58, 46), (114, 52, 45), + (112, 58, 48), (111, 65, 52), (117, 74, 56), (124, 83, 60), + (156, 127, 100), (176, 147, 123), (196, 168, 146), (214, 187, 163), + (233, 207, 180), (238, 213, 184), (243, 220, 188), (244, 220, 187), + (238, 209, 184), (227, 172, 162), (229, 165, 145), (231, 159, 128), + (225, 153, 113), (219, 147, 99), (217, 142, 96), (216, 137, 93), + (219, 136, 88), (211, 137, 84), (204, 138, 80), (193, 129, 72), + (183, 120, 65), (177, 113, 60), (172, 107, 55), (161, 94, 50), + (149, 76, 40), (135, 55, 28), (140, 62, 32), (145, 69, 36), + (150, 76, 41), (155, 83, 47), (169, 100, 60), (179, 116, 83), + (197, 154, 130), (207, 169, 139), (218, 185, 149), (213, 183, 149), + (208, 182, 149), (199, 174, 146), (190, 167, 144), (164, 153, 147), + (141, 138, 139), (98, 107, 116), (86, 87, 97), (74, 68, 79), + (68, 63, 75), (63, 58, 72), (59, 54, 69), (55, 52, 71), + (83, 43, 52), (98, 43, 43), (113, 44, 34), (115, 43, 32), + (118, 43, 31), (117, 46, 28), (115, 52, 31), (113, 65, 42), + (100, 76, 50), (73, 75, 66), (61, 77, 77), (50, 79, 89), + (42, 84, 95), (35, 89, 101), (21, 88, 111), (11, 81, 117), + (7, 56, 115), (12, 53, 106), (17, 51, 98), (23, 47, 91), + (29, 44, 85), (40, 41, 74), (46, 37, 64), (54, 34, 53), + (57, 35, 43), (83, 32, 26), (88, 34, 26), (94, 36, 26), + (108, 40, 31), (116, 54, 42), (125, 69, 51), (137, 81, 58), + (155, 89, 59), (152, 88, 60), (149, 87, 61), (142, 85, 61), + (136, 84, 62), (118, 79, 57), (104, 70, 48), (94, 60, 43), + (88, 52, 40), (93, 63, 50), (97, 70, 57), (102, 78, 65), + (115, 99, 85), (138, 120, 108), (161, 141, 132), (186, 165, 150), + (216, 188, 162), (211, 182, 159), (207, 177, 157), (199, 170, 154), + (191, 164, 151), (178, 144, 133), (167, 123, 110), (156, 103, 87), + (144, 85, 65), (120, 61, 52), (121, 61, 51), (122, 61, 51), + (135, 73, 53), (149, 88, 55), (161, 101, 62), (171, 114, 71), + (197, 143, 88), (205, 151, 91), (213, 160, 95), (225, 173, 102), + (231, 182, 107), (231, 184, 112), (231, 186, 115), (232, 187, 119), + (233, 189, 123), (236, 193, 130), (236, 196, 135), (237, 199, 141), + (238, 206, 156), (240, 214, 172), (242, 220, 187), (245, 224, 195), + (249, 237, 221), (249, 240, 228), (250, 244, 236), (251, 250, 248), + (253, 253, 253), (254, 254, 254), (255, 255, 255), (255, 255, 255), + (254, 255, 255), (254, 255, 255), (254, 255, 255), (254, 255, 255), + (255, 255, 255), (254, 255, 255), (254, 255, 255), (254, 255, 255), + (254, 254, 254), (253, 253, 253), (252, 252, 252), (249, 247, 246), + (244, 237, 230), (234, 220, 212), (219, 200, 189), (199, 178, 166), + (171, 153, 146), (145, 133, 121), (120, 113, 99), (98, 101, 80), + (78, 91, 61), (59, 85, 54), (49, 75, 46), (45, 69, 45), + (53, 73, 47), (69, 82, 48), (92, 106, 56), (116, 119, 63), + (140, 129, 71), (161, 134, 79), (179, 135, 81), (197, 148, 86), + (210, 160, 93), (221, 173, 102), (227, 182, 109), (227, 184, 113), + (228, 186, 114), (228, 185, 115), (229, 185, 116), (230, 186, 118), + (233, 188, 116), (234, 189, 113), (238, 189, 106), (238, 188, 102), + (237, 187, 102), (238, 186, 102), (232, 180, 102), (226, 171, 92), + (212, 155, 83), (195, 138, 73), (181, 123, 69), (165, 108, 67), + (150, 96, 63), (133, 80, 54), (115, 64, 45), (97, 51, 39), + (81, 44, 40), (67, 41, 47), (54, 39, 51), (46, 38, 52), + (39, 32, 47), (32, 30, 43), (35, 29, 43), (33, 26, 43), + (29, 28, 43), (24, 22, 38), (17, 22, 36), (20, 28, 37), + (30, 33, 36), (40, 43, 42), (54, 52, 45), (67, 65, 57), + (85, 85, 71), (106, 103, 79), (126, 121, 89), (149, 131, 94), + (170, 141, 97), (166, 134, 92), (163, 129, 85), (159, 128, 81) + ), + +// 392 040221-35 +((186, 160, 182), (190, 133, 166), (189, 121, 158), (188, 110, 151), + (194, 104, 151), (201, 99, 152), (202, 102, 153), (204, 105, 155), + (202, 133, 169), (208, 148, 180), (214, 164, 192), (210, 174, 194), + (207, 185, 196), (200, 193, 196), (193, 202, 196), (195, 205, 199), + (198, 209, 203), (198, 206, 203), (191, 198, 195), (185, 190, 188), + (187, 189, 190), (189, 189, 192), (193, 187, 194), (197, 186, 197), + (211, 197, 209), (217, 205, 216), (224, 214, 224), (224, 212, 223), + (224, 210, 222), (220, 208, 218), (217, 207, 215), (206, 203, 207), + (194, 198, 198), (165, 168, 168), (150, 156, 154), (135, 144, 140), + (128, 139, 134), (122, 135, 128), (122, 134, 127), (122, 134, 127), + (129, 137, 137), (127, 143, 143), (125, 150, 150), (120, 147, 152), + (116, 144, 155), (112, 139, 153), (108, 134, 151), (96, 118, 144), + (84, 102, 131), (70, 71, 109), (68, 57, 99), (67, 44, 90), + (69, 34, 80), (72, 25, 70), (75, 27, 70), (78, 29, 71), + (96, 55, 86), (102, 67, 97), (108, 80, 108), (105, 94, 117), + (102, 108, 127), (100, 112, 129), (99, 116, 131), (94, 116, 131), + (85, 111, 128), (79, 92, 115), (86, 78, 105), (93, 64, 96), + (93, 57, 91), (94, 50, 87), (90, 40, 80), (88, 40, 80), + (93, 56, 94), (94, 60, 96), (96, 64, 98), (88, 74, 96), + (80, 84, 95), (75, 91, 99), (70, 98, 104), (62, 105, 113), + (58, 108, 117), (56, 107, 110), (59, 101, 111), (62, 96, 112), + (63, 90, 113), (64, 85, 115), (63, 73, 117), (59, 65, 113), + (50, 50, 92), (47, 40, 82), (45, 30, 73), (44, 26, 70), + (44, 23, 67), (44, 18, 68), (42, 15, 66), (44, 18, 67), + (49, 26, 76), (75, 49, 102), (91, 56, 119), (108, 63, 137), + (114, 69, 144), (120, 75, 151), (131, 91, 158), (137, 108, 163), + (152, 130, 175), (155, 134, 176), (158, 139, 178), (156, 138, 176), + (155, 137, 175), (154, 128, 168), (154, 122, 162), (154, 115, 155), + (156, 106, 147), (147, 76, 137), (144, 70, 135), (141, 64, 134), + (139, 55, 133), (139, 54, 131), (139, 61, 129), (135, 62, 127), + (128, 67, 127), (129, 73, 130), (131, 80, 133), (131, 84, 133), + (132, 88, 133), (131, 98, 131), (128, 101, 126), (127, 101, 122), + (124, 93, 115), (110, 70, 101), (104, 64, 94), (98, 58, 88), + (86, 51, 78), (71, 41, 64), (61, 29, 55), (54, 19, 47), + (56, 6, 36), (56, 12, 37), (57, 19, 39), (58, 25, 43), + (60, 32, 48), (63, 42, 54), (77, 55, 68), (93, 62, 81), + (103, 76, 96), (117, 107, 118), (120, 115, 123), (123, 123, 129), + (130, 132, 136), (138, 138, 143), (144, 145, 150), (148, 148, 153), + (153, 155, 159), (154, 156, 159), (155, 157, 160), (154, 157, 162), + (152, 156, 161), (147, 154, 160), (140, 152, 161), (134, 149, 160), + (129, 147, 159), (129, 141, 153), (129, 138, 151), (130, 136, 150), + (134, 126, 149), (135, 116, 147), (138, 101, 137), (142, 85, 126), + (150, 65, 110), (151, 65, 111), (153, 66, 113), (155, 65, 114), + (150, 60, 108), (141, 49, 98), (122, 46, 89), (108, 51, 83), + (96, 63, 82), (83, 73, 78), (74, 70, 68), (57, 65, 59), + (45, 62, 50), (40, 64, 49), (44, 75, 56), (57, 85, 64), + (89, 111, 94), (101, 120, 105), (113, 130, 117), (138, 152, 144), + (162, 170, 167), (180, 184, 184), (189, 191, 192), (194, 196, 200), + (192, 198, 204), (185, 197, 204), (172, 190, 201), (153, 177, 191), + (136, 163, 182), (118, 152, 174), (104, 144, 168), (94, 140, 165), + (84, 138, 163), (81, 135, 162), (81, 136, 164), (81, 137, 165), + (81, 135, 165), (78, 131, 159), (75, 116, 151), (75, 100, 143), + (76, 87, 136), (75, 76, 133), (71, 77, 128), (68, 75, 126), + (68, 72, 128), (78, 76, 131), (94, 82, 140), (109, 101, 148), + (122, 122, 157), (136, 142, 174), (153, 167, 189), (175, 186, 205), + (195, 202, 218), (206, 216, 221), (209, 217, 220), (203, 215, 212), + (192, 205, 200), (178, 185, 184), (157, 167, 167), (132, 142, 145), + (107, 118, 119), (84, 98, 99), (67, 70, 79), (57, 50, 73), + (53, 37, 75), (57, 32, 77), (67, 39, 84), (76, 49, 88), + (81, 58, 99), (86, 71, 113), (88, 81, 128), (91, 92, 139), + (88, 99, 145), (81, 104, 145), (77, 111, 145), (74, 113, 144), + (77, 119, 142), (82, 118, 145), (90, 123, 148), (101, 132, 156), + (119, 142, 163), (139, 160, 172), (157, 172, 181), (169, 179, 185), + (173, 181, 186), (173, 178, 182), (174, 175, 182), (179, 170, 184) + ), + +// 393 040221-36 +((8, 4, 11), (9, 4, 13), (9, 4, 14), (10, 5, 15), + (11, 6, 18), (12, 7, 21), (14, 8, 24), (16, 10, 27), + (29, 23, 47), (37, 28, 55), (45, 33, 64), (48, 35, 66), + (52, 37, 69), (52, 36, 68), (52, 36, 68), (51, 36, 68), + (51, 36, 68), (49, 38, 71), (49, 37, 70), (50, 36, 69), + (47, 33, 63), (44, 31, 57), (41, 28, 51), (38, 26, 46), + (23, 13, 26), (16, 9, 20), (9, 5, 15), (8, 5, 15), + (8, 5, 15), (10, 7, 17), (13, 9, 20), (20, 16, 29), + (29, 23, 39), (50, 41, 63), (60, 48, 73), (70, 56, 83), + (77, 62, 90), (85, 68, 98), (87, 71, 101), (90, 74, 105), + (96, 79, 112), (95, 79, 113), (95, 79, 114), (92, 76, 109), + (90, 73, 105), (87, 70, 101), (84, 67, 97), (76, 62, 87), + (67, 55, 76), (47, 39, 53), (36, 30, 42), (26, 22, 32), + (18, 15, 24), (11, 8, 16), (8, 6, 13), (6, 4, 10), + (2, 0, 4), (1, 0, 3), (0, 0, 2), (0, 0, 2), + (0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), + (0, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 2), + (0, 0, 2), (0, 0, 3), (0, 0, 3), (1, 0, 4), + (4, 2, 11), (8, 5, 18), (12, 9, 26), (20, 16, 37), + (29, 24, 48), (34, 28, 53), (40, 33, 59), (50, 41, 70), + (58, 48, 76), (69, 57, 87), (70, 57, 89), (71, 58, 91), + (71, 57, 92), (71, 57, 93), (73, 58, 92), (74, 58, 92), + (73, 57, 87), (70, 54, 80), (67, 51, 73), (64, 48, 70), + (61, 46, 67), (54, 41, 62), (51, 36, 59), (50, 35, 60), + (49, 35, 62), (55, 40, 73), (61, 44, 78), (68, 48, 84), + (71, 50, 87), (75, 53, 90), (85, 57, 95), (93, 64, 105), + (106, 78, 126), (110, 83, 135), (114, 89, 145), (115, 90, 147), + (116, 92, 150), (115, 92, 152), (115, 90, 149), (114, 88, 145), + (111, 84, 139), (99, 74, 124), (94, 71, 120), (90, 69, 117), + (81, 64, 111), (71, 57, 105), (62, 51, 97), (54, 45, 89), + (46, 36, 73), (47, 34, 68), (48, 32, 63), (50, 33, 62), + (53, 34, 62), (61, 38, 62), (68, 42, 64), (75, 48, 69), + (83, 55, 75), (100, 70, 87), (105, 73, 90), (110, 76, 94), + (121, 84, 102), (133, 92, 111), (144, 100, 118), (154, 108, 127), + (165, 119, 145), (163, 120, 149), (161, 122, 153), (159, 121, 154), + (158, 121, 155), (156, 120, 157), (152, 116, 155), (148, 112, 151), + (142, 105, 146), (123, 93, 135), (116, 88, 131), (110, 84, 127), + (98, 76, 119), (88, 68, 111), (77, 62, 102), (70, 55, 93), + (57, 41, 73), (54, 38, 68), (51, 36, 64), (45, 31, 57), + (41, 28, 51), (42, 27, 47), (47, 30, 47), (53, 35, 50), + (60, 37, 52), (70, 41, 55), (70, 41, 56), (71, 41, 57), + (69, 40, 56), (67, 39, 55), (66, 38, 54), (68, 40, 55), + (71, 42, 55), (71, 41, 54), (71, 41, 53), (68, 38, 50), + (59, 33, 44), (48, 25, 36), (35, 17, 28), (24, 11, 20), + (16, 6, 14), (9, 3, 9), (5, 1, 6), (3, 0, 5), + (2, 0, 4), (2, 0, 4), (1, 0, 4), (1, 0, 4), + (1, 0, 3), (1, 0, 3), (1, 0, 3), (1, 0, 2), + (1, 0, 2), (1, 0, 2), (1, 0, 3), (1, 0, 3), + (1, 0, 5), (1, 0, 6), (2, 0, 8), (3, 0, 9), + (4, 1, 10), (5, 1, 11), (6, 1, 12), (7, 1, 12), + (7, 1, 12), (7, 1, 13), (7, 1, 14), (8, 1, 15), + (8, 1, 15), (8, 1, 16), (8, 1, 16), (8, 1, 15), + (8, 1, 14), (8, 1, 13), (7, 2, 13), (7, 2, 13), + (9, 4, 17), (11, 6, 22), (15, 12, 31), (23, 18, 42), + (33, 26, 53), (44, 35, 63), (55, 44, 73), (66, 52, 81), + (77, 62, 89), (87, 69, 97), (96, 77, 107), (106, 86, 117), + (117, 94, 130), (127, 103, 141), (137, 112, 151), (147, 118, 157), + (155, 125, 161), (162, 128, 162), (166, 131, 161), (169, 133, 159), + (170, 132, 158), (168, 130, 159), (163, 128, 159), (157, 123, 157), + (149, 118, 152), (140, 110, 145), (129, 102, 135), (119, 93, 123), + (110, 85, 111), (100, 77, 99), (91, 69, 91), (81, 61, 83), + (70, 53, 75), (59, 45, 67), (48, 37, 60), (40, 31, 53), + (32, 25, 43), (24, 18, 33), (19, 13, 25), (15, 9, 19), + (12, 7, 15), (10, 5, 12), (6, 1, 9), (8, 3, 11) + ), + +// 394 040221-37 +((128, 92, 57), (118, 83, 51), (108, 76, 46), (98, 69, 41), + (81, 56, 36), (64, 43, 32), (59, 39, 32), (55, 35, 32), + (45, 32, 32), (42, 32, 32), (40, 32, 32), (39, 32, 32), + (39, 32, 32), (38, 32, 32), (37, 32, 32), (37, 32, 32), + (38, 32, 32), (39, 32, 32), (40, 32, 32), (41, 32, 32), + (41, 32, 32), (41, 32, 32), (40, 32, 32), (40, 32, 32), + (38, 32, 32), (35, 32, 32), (33, 32, 32), (32, 32, 32), + (32, 32, 32), (32, 32, 32), (32, 32, 32), (32, 32, 32), + (32, 32, 32), (32, 32, 32), (33, 32, 32), (35, 32, 32), + (39, 32, 32), (44, 32, 32), (47, 33, 32), (50, 34, 33), + (63, 44, 41), (72, 51, 43), (82, 58, 46), (91, 65, 48), + (101, 73, 50), (105, 76, 51), (109, 80, 53), (113, 82, 56), + (115, 83, 57), (113, 82, 56), (110, 79, 54), (107, 76, 52), + (103, 73, 51), (99, 71, 50), (95, 69, 48), (92, 67, 47), + (77, 58, 41), (72, 54, 39), (68, 50, 37), (66, 47, 35), + (65, 45, 34), (66, 45, 34), (67, 45, 35), (68, 46, 35), + (70, 47, 37), (80, 55, 41), (84, 57, 43), (89, 59, 45), + (91, 60, 45), (94, 62, 46), (98, 63, 49), (100, 64, 50), + (106, 69, 50), (110, 72, 50), (115, 75, 50), (119, 80, 52), + (124, 85, 55), (124, 86, 57), (125, 87, 59), (127, 89, 62), + (127, 92, 64), (127, 93, 65), (124, 92, 63), (122, 92, 62), + (119, 90, 62), (117, 89, 62), (110, 85, 61), (99, 79, 61), + (81, 64, 58), (71, 57, 53), (62, 50, 49), (57, 46, 45), + (53, 43, 41), (45, 37, 35), (35, 32, 32), (32, 32, 32), + (32, 32, 32), (32, 32, 32), (32, 32, 32), (32, 32, 32), + (32, 32, 32), (32, 32, 32), (32, 32, 32), (32, 32, 32), + (32, 32, 32), (32, 32, 32), (32, 32, 32), (32, 32, 32), + (32, 32, 32), (34, 32, 32), (37, 32, 32), (39, 32, 32), + (43, 32, 32), (47, 32, 32), (48, 33, 32), (50, 34, 32), + (55, 37, 32), (59, 41, 34), (68, 50, 39), (79, 57, 46), + (101, 76, 63), (114, 88, 74), (128, 101, 85), (132, 105, 88), + (137, 110, 92), (142, 117, 100), (148, 122, 107), (152, 125, 110), + (153, 125, 111), (154, 128, 115), (154, 127, 113), (154, 127, 112), + (149, 122, 109), (143, 117, 105), (135, 110, 98), (125, 100, 88), + (104, 80, 68), (96, 71, 59), (89, 63, 50), (86, 60, 46), + (83, 58, 43), (79, 53, 39), (77, 52, 37), (77, 53, 35), + (76, 53, 34), (71, 50, 32), (69, 48, 32), (68, 47, 32), + (65, 45, 32), (63, 44, 32), (63, 46, 32), (64, 49, 32), + (73, 55, 38), (74, 56, 39), (76, 58, 40), (80, 62, 44), + (82, 64, 49), (86, 68, 53), (89, 71, 58), (94, 76, 64), + (98, 79, 70), (107, 88, 79), (109, 88, 79), (111, 89, 80), + (112, 89, 80), (115, 89, 80), (115, 91, 79), (112, 87, 80), + (105, 82, 81), (103, 80, 81), (101, 79, 81), (103, 80, 82), + (109, 85, 86), (122, 97, 93), (137, 111, 104), (153, 127, 112), + (164, 136, 118), (172, 142, 124), (175, 145, 125), (175, 145, 127), + (177, 147, 131), (179, 151, 140), (188, 160, 147), (189, 160, 145), + (181, 151, 130), (173, 143, 121), (165, 135, 113), (146, 117, 95), + (124, 99, 83), (109, 87, 77), (93, 74, 69), (86, 65, 63), + (79, 59, 53), (74, 53, 45), (71, 51, 37), (73, 52, 33), + (75, 55, 32), (80, 58, 34), (87, 63, 39), (92, 68, 44), + (98, 71, 49), (103, 76, 55), (110, 83, 61), (118, 91, 65), + (129, 98, 67), (140, 106, 71), (151, 113, 75), (161, 122, 81), + (169, 130, 88), (176, 137, 98), (181, 143, 104), (187, 148, 107), + (189, 153, 110), (189, 152, 109), (189, 151, 109), (188, 149, 109), + (185, 148, 110), (181, 145, 110), (177, 141, 109), (171, 137, 107), + (160, 128, 104), (151, 118, 98), (140, 109, 92), (130, 100, 87), + (122, 92, 80), (115, 85, 74), (109, 79, 69), (103, 71, 64), + (95, 65, 61), (89, 61, 57), (85, 57, 55), (82, 56, 53), + (82, 56, 52), (82, 57, 52), (82, 58, 51), (83, 59, 55), + (85, 62, 58), (86, 65, 61), (88, 68, 62), (92, 69, 59), + (94, 73, 59), (97, 74, 57), (98, 75, 55), (101, 76, 55), + (105, 80, 56), (110, 83, 58), (117, 87, 59), (124, 93, 62), + (139, 103, 69), (143, 106, 69), (141, 103, 65), (139, 99, 63), + (133, 97, 62), (130, 94, 61), (121, 87, 53), (125, 91, 57) + ), + +// 395 040221-38 +((197, 85, 22), (191, 80, 20), (192, 79, 19), (193, 78, 18), + (197, 80, 19), (201, 83, 20), (202, 84, 22), (204, 86, 25), + (204, 100, 41), (208, 111, 52), (213, 123, 64), (219, 135, 78), + (225, 148, 92), (230, 162, 106), (236, 177, 120), (238, 182, 125), + (241, 187, 131), (246, 202, 145), (245, 203, 146), (245, 204, 148), + (237, 200, 145), (230, 196, 143), (225, 191, 140), (221, 187, 137), + (204, 167, 117), (196, 158, 109), (189, 150, 101), (177, 141, 95), + (166, 132, 89), (160, 127, 86), (155, 123, 83), (145, 115, 77), + (137, 109, 74), (130, 104, 70), (128, 100, 67), (126, 97, 64), + (124, 91, 58), (123, 86, 53), (122, 83, 50), (122, 81, 48), + (117, 77, 45), (116, 76, 44), (115, 76, 43), (118, 73, 39), + (121, 70, 35), (123, 69, 33), (125, 69, 31), (126, 67, 30), + (123, 66, 30), (111, 67, 34), (107, 65, 33), (104, 63, 32), + (102, 61, 30), (101, 59, 28), (99, 58, 28), (98, 58, 29), + (86, 58, 33), (81, 58, 35), (76, 59, 38), (78, 60, 38), + (81, 62, 39), (83, 63, 39), (85, 64, 40), (90, 66, 40), + (95, 68, 40), (107, 70, 40), (113, 71, 39), (120, 72, 39), + (122, 73, 38), (125, 74, 38), (131, 75, 36), (135, 75, 35), + (145, 75, 33), (148, 76, 34), (152, 78, 35), (155, 80, 36), + (159, 83, 37), (160, 84, 37), (161, 85, 38), (164, 86, 37), + (164, 85, 37), (161, 84, 37), (158, 82, 36), (156, 80, 35), + (155, 78, 33), (154, 77, 32), (152, 73, 29), (150, 70, 27), + (149, 65, 22), (150, 66, 22), (152, 67, 23), (154, 70, 25), + (156, 73, 28), (161, 81, 35), (165, 91, 45), (170, 99, 53), + (173, 104, 58), (182, 112, 62), (184, 115, 64), (187, 119, 66), + (188, 120, 67), (189, 122, 69), (187, 123, 72), (185, 121, 71), + (183, 119, 68), (186, 121, 70), (189, 124, 73), (191, 128, 77), + (194, 132, 82), (199, 138, 89), (201, 144, 95), (202, 149, 101), + (200, 149, 101), (196, 145, 99), (195, 143, 97), (195, 142, 96), + (189, 136, 92), (179, 130, 88), (166, 120, 80), (150, 106, 69), + (122, 80, 47), (111, 72, 41), (100, 64, 36), (95, 62, 35), + (91, 61, 35), (83, 59, 36), (76, 57, 36), (77, 56, 34), + (83, 54, 30), (98, 53, 24), (103, 53, 23), (108, 54, 22), + (115, 56, 22), (126, 58, 21), (140, 60, 18), (151, 61, 16), + (167, 60, 8), (170, 60, 7), (173, 60, 7), (176, 62, 7), + (179, 64, 7), (186, 67, 9), (189, 71, 11), (193, 76, 14), + (194, 79, 17), (197, 84, 22), (199, 85, 23), (201, 87, 24), + (204, 87, 25), (205, 88, 26), (203, 89, 26), (201, 88, 26), + (192, 84, 26), (189, 81, 25), (187, 79, 24), (179, 74, 23), + (170, 71, 23), (163, 72, 25), (156, 74, 29), (151, 78, 36), + (150, 84, 42), (150, 94, 54), (151, 97, 58), (152, 101, 62), + (153, 108, 69), (155, 115, 75), (161, 123, 83), (167, 131, 89), + (188, 149, 100), (193, 153, 102), (198, 157, 104), (206, 162, 106), + (213, 169, 109), (218, 174, 111), (221, 178, 117), (225, 184, 121), + (230, 189, 124), (231, 188, 124), (229, 186, 121), (226, 180, 114), + (219, 171, 108), (212, 163, 104), (204, 158, 102), (197, 150, 100), + (180, 135, 89), (177, 130, 84), (174, 126, 79), (172, 115, 68), + (172, 108, 59), (176, 104, 52), (177, 103, 51), (177, 104, 52), + (175, 108, 55), (178, 111, 58), (183, 115, 61), (192, 121, 64), + (200, 127, 68), (205, 130, 73), (203, 132, 75), (199, 131, 76), + (196, 129, 76), (194, 127, 74), (195, 127, 73), (196, 124, 70), + (194, 119, 67), (190, 113, 62), (186, 106, 56), (180, 99, 49), + (174, 96, 46), (168, 94, 45), (163, 94, 47), (160, 94, 49), + (158, 95, 51), (159, 95, 51), (158, 94, 50), (159, 94, 49), + (158, 92, 48), (156, 90, 47), (155, 89, 46), (157, 90, 46), + (156, 90, 45), (156, 89, 44), (156, 88, 43), (152, 87, 44), + (147, 86, 45), (142, 87, 48), (135, 88, 52), (130, 90, 55), + (125, 92, 58), (122, 93, 61), (119, 93, 61), (120, 94, 62), + (123, 93, 60), (130, 94, 58), (139, 97, 57), (149, 101, 55), + (158, 104, 55), (165, 111, 60), (172, 118, 66), (181, 126, 74), + (190, 135, 81), (201, 142, 84), (209, 143, 84), (211, 143, 81), + (210, 140, 79), (207, 137, 77), (203, 133, 78), (202, 133, 77), + (203, 129, 74), (201, 123, 67), (197, 115, 59), (194, 106, 48), + (192, 97, 39), (193, 92, 31), (196, 89, 26), (198, 86, 22) + ), + +// 396 040221-39 +((44, 41, 38), (39, 39, 48), (36, 45, 59), (33, 51, 71), + (37, 59, 87), (41, 68, 104), (44, 74, 112), (47, 81, 120), + (52, 102, 154), (46, 104, 165), (41, 106, 176), (33, 99, 175), + (25, 93, 175), (24, 86, 164), (24, 80, 153), (25, 77, 146), + (27, 75, 140), (40, 70, 124), (44, 66, 114), (49, 63, 105), + (57, 61, 94), (65, 59, 83), (70, 60, 78), (76, 62, 74), + (109, 83, 79), (129, 99, 88), (149, 115, 97), (164, 134, 111), + (180, 153, 126), (185, 161, 133), (190, 170, 140), (199, 186, 153), + (209, 199, 168), (229, 219, 184), (234, 225, 188), (240, 231, 192), + (239, 230, 189), (239, 230, 186), (238, 228, 183), (238, 227, 180), + (232, 217, 161), (223, 205, 152), (214, 193, 143), (199, 177, 132), + (185, 162, 122), (177, 153, 115), (170, 145, 109), (157, 129, 95), + (150, 116, 78), (142, 99, 55), (146, 100, 54), (150, 101, 54), + (150, 104, 64), (151, 108, 74), (153, 110, 77), (156, 113, 80), + (158, 127, 96), (160, 135, 105), (163, 143, 114), (165, 152, 126), + (168, 162, 139), (170, 166, 144), (172, 170, 150), (172, 177, 164), + (173, 182, 170), (166, 179, 174), (157, 169, 167), (149, 159, 161), + (142, 152, 154), (136, 145, 148), (127, 132, 138), (124, 121, 123), + (117, 107, 98), (109, 101, 89), (102, 95, 80), (92, 88, 73), + (83, 82, 67), (79, 79, 68), (75, 77, 70), (63, 74, 79), + (59, 76, 89), (51, 94, 116), (51, 103, 122), (51, 113, 129), + (53, 117, 130), (56, 122, 132), (56, 126, 139), (60, 130, 141), + (62, 138, 151), (65, 142, 153), (69, 146, 156), (75, 148, 152), + (81, 150, 149), (93, 153, 146), (106, 155, 139), (113, 152, 129), + (122, 153, 124), (135, 154, 128), (144, 156, 131), (153, 158, 135), + (159, 161, 137), (165, 164, 140), (174, 167, 142), (184, 171, 143), + (188, 171, 141), (179, 162, 134), (171, 153, 128), (164, 146, 124), + (158, 139, 121), (140, 123, 115), (129, 113, 111), (123, 106, 105), + (123, 107, 105), (126, 109, 104), (127, 110, 104), (129, 111, 105), + (126, 108, 107), (122, 107, 114), (118, 108, 117), (120, 118, 125), + (144, 148, 140), (161, 165, 148), (179, 182, 157), (185, 187, 161), + (191, 192, 165), (195, 195, 170), (189, 201, 176), (181, 204, 177), + (174, 206, 175), (163, 199, 165), (163, 195, 161), (163, 192, 158), + (166, 181, 151), (163, 172, 146), (153, 159, 137), (140, 148, 127), + (109, 114, 99), (99, 96, 83), (89, 79, 68), (87, 72, 62), + (85, 66, 57), (82, 54, 49), (81, 48, 44), (80, 43, 42), + (77, 40, 39), (69, 33, 35), (65, 33, 35), (62, 34, 35), + (55, 37, 42), (52, 43, 53), (52, 48, 63), (54, 58, 73), + (72, 75, 91), (77, 81, 94), (83, 87, 97), (94, 101, 105), + (103, 114, 116), (116, 124, 123), (128, 137, 128), (138, 145, 131), + (155, 150, 131), (177, 153, 115), (178, 152, 112), (179, 151, 110), + (189, 154, 105), (203, 158, 95), (211, 159, 85), (217, 156, 77), + (233, 154, 51), (225, 145, 48), (218, 136, 45), (200, 124, 41), + (183, 111, 35), (162, 101, 29), (142, 92, 28), (135, 94, 27), + (133, 99, 23), (123, 92, 23), (105, 85, 27), (88, 73, 28), + (69, 62, 26), (51, 51, 26), (34, 44, 29), (25, 43, 32), + (32, 51, 43), (36, 53, 46), (41, 56, 50), (53, 61, 56), + (67, 64, 60), (78, 69, 63), (87, 74, 69), (100, 82, 75), + (114, 93, 85), (128, 106, 97), (143, 123, 112), (159, 138, 126), + (171, 155, 139), (175, 170, 153), (174, 182, 166), (173, 191, 174), + (174, 198, 180), (175, 207, 187), (182, 213, 193), (191, 219, 198), + (199, 226, 204), (198, 231, 215), (193, 235, 220), (183, 235, 225), + (171, 234, 227), (160, 227, 228), (158, 223, 229), (158, 221, 227), + (153, 219, 231), (145, 216, 233), (132, 204, 235), (115, 191, 226), + (93, 167, 210), (76, 146, 195), (63, 127, 176), (53, 112, 156), + (45, 101, 138), (39, 89, 127), (33, 77, 114), (26, 60, 95), + (21, 43, 78), (23, 28, 61), (29, 19, 44), (37, 17, 32), + (45, 21, 28), (55, 27, 30), (62, 33, 33), (68, 39, 38), + (72, 47, 47), (76, 57, 56), (86, 67, 65), (98, 79, 76), + (113, 94, 88), (128, 112, 103), (146, 128, 117), (160, 144, 132), + (166, 159, 144), (174, 169, 151), (179, 174, 157), (180, 174, 156), + (178, 172, 153), (174, 167, 147), (170, 159, 141), (160, 150, 133), + (148, 140, 123), (134, 128, 112), (118, 112, 99), (103, 94, 82), + (85, 79, 68), (69, 65, 56), (58, 53, 48), (51, 45, 41) + ), + +// 397 040221-40 +((111, 54, 43), (93, 45, 37), (95, 49, 39), (98, 53, 42), + (103, 60, 54), (108, 68, 66), (103, 69, 69), (98, 70, 73), + (80, 78, 86), (75, 78, 87), (70, 78, 88), (52, 70, 82), + (35, 62, 77), (24, 50, 67), (14, 38, 58), (14, 32, 52), + (15, 27, 47), (20, 18, 24), (24, 14, 19), (28, 11, 15), + (31, 7, 15), (34, 3, 16), (35, 5, 18), (37, 8, 20), + (45, 33, 47), (53, 46, 65), (62, 59, 84), (66, 69, 96), + (71, 80, 108), (70, 84, 113), (70, 89, 119), (76, 91, 123), + (79, 91, 122), (81, 75, 94), (70, 62, 79), (59, 49, 64), + (48, 35, 49), (38, 21, 34), (34, 17, 30), (30, 14, 26), + (17, 14, 26), (12, 12, 25), (8, 11, 25), (5, 12, 25), + (3, 13, 26), (3, 13, 26), (3, 14, 26), (6, 14, 24), + (11, 12, 19), (23, 8, 10), (28, 8, 8), (34, 8, 6), + (40, 9, 6), (46, 11, 6), (49, 11, 6), (53, 12, 7), + (65, 15, 12), (70, 18, 15), (76, 21, 18), (81, 23, 21), + (86, 26, 24), (87, 26, 26), (89, 26, 28), (94, 23, 33), + (99, 30, 44), (115, 51, 71), (119, 58, 82), (124, 66, 94), + (121, 69, 98), (118, 73, 103), (105, 76, 112), (96, 82, 119), + (86, 94, 127), (74, 87, 116), (62, 81, 106), (51, 68, 89), + (41, 56, 72), (41, 53, 66), (41, 50, 61), (40, 44, 54), + (42, 36, 41), (50, 21, 19), (54, 19, 15), (58, 17, 12), + (59, 17, 12), (61, 18, 13), (64, 21, 15), (68, 27, 21), + (100, 54, 42), (120, 65, 51), (140, 77, 60), (142, 79, 61), + (145, 81, 63), (155, 84, 65), (160, 85, 63), (168, 85, 62), + (182, 83, 59), (183, 83, 60), (166, 76, 60), (150, 70, 61), + (144, 62, 57), (138, 54, 54), (127, 41, 44), (124, 39, 41), + (102, 42, 49), (85, 32, 43), (68, 22, 38), (61, 16, 30), + (55, 10, 22), (47, 4, 11), (38, 4, 5), (33, 5, 3), + (30, 5, 5), (35, 4, 10), (38, 5, 10), (42, 7, 10), + (49, 10, 11), (55, 10, 12), (62, 8, 13), (70, 8, 15), + (99, 18, 18), (118, 26, 21), (137, 35, 25), (145, 41, 29), + (153, 48, 34), (160, 59, 45), (168, 71, 54), (178, 77, 57), + (179, 81, 55), (160, 80, 57), (149, 78, 57), (139, 76, 57), + (120, 66, 54), (99, 53, 45), (73, 42, 35), (53, 28, 26), + (32, 9, 13), (33, 7, 11), (34, 5, 10), (35, 5, 10), + (37, 6, 10), (40, 6, 8), (44, 6, 6), (48, 6, 5), + (51, 6, 4), (50, 6, 4), (48, 6, 3), (46, 6, 3), + (40, 5, 3), (33, 4, 1), (25, 4, 1), (20, 2, 1), + (11, 1, 0), (9, 1, 0), (8, 1, 1), (6, 2, 2), + (5, 5, 9), (6, 11, 19), (7, 18, 29), (7, 21, 37), + (8, 21, 37), (6, 19, 33), (6, 20, 34), (6, 21, 36), + (5, 22, 38), (5, 20, 35), (3, 15, 26), (2, 8, 14), + (7, 1, 2), (9, 0, 1), (12, 0, 1), (18, 0, 0), + (24, 1, 0), (30, 1, 0), (34, 1, 0), (36, 0, 0), + (39, 1, 0), (40, 1, 0), (42, 1, 0), (43, 1, 0), + (44, 0, 0), (46, 0, 0), (46, 0, 0), (48, 1, 1), + (55, 4, 2), (57, 5, 3), (59, 7, 4), (64, 12, 8), + (68, 22, 21), (77, 36, 39), (86, 52, 59), (102, 71, 77), + (122, 85, 85), (137, 101, 96), (159, 116, 111), (170, 135, 137), + (184, 156, 163), (200, 172, 179), (210, 185, 188), (225, 189, 189), + (228, 193, 196), (224, 194, 202), (217, 191, 202), (207, 187, 196), + (194, 169, 174), (180, 154, 154), (164, 133, 134), (145, 111, 111), + (133, 97, 92), (115, 74, 66), (98, 58, 44), (81, 49, 32), + (66, 43, 31), (64, 50, 45), (66, 59, 62), (73, 68, 77), + (79, 82, 90), (86, 96, 107), (98, 110, 125), (110, 128, 148), + (126, 143, 170), (136, 160, 189), (149, 174, 202), (162, 183, 211), + (171, 193, 219), (187, 199, 221), (191, 205, 229), (198, 211, 232), + (205, 213, 234), (205, 215, 236), (205, 213, 231), (197, 206, 227), + (186, 198, 217), (173, 186, 206), (158, 170, 192), (141, 153, 176), + (125, 132, 158), (110, 112, 137), (98, 94, 117), (85, 78, 96), + (77, 62, 76), (74, 46, 57), (73, 32, 40), (78, 22, 27), + (79, 20, 19), (81, 20, 16), (83, 21, 14), (91, 23, 12), + (105, 29, 16), (116, 38, 22), (122, 49, 33), (117, 51, 39), + (110, 47, 36), (109, 48, 36), (110, 46, 32), (113, 53, 38) + ), + +// 398 040221-41 +((26, 82, 100), (26, 68, 89), (22, 64, 84), (19, 60, 80), + (15, 58, 74), (12, 57, 68), (10, 57, 65), (9, 57, 62), + (16, 67, 66), (18, 64, 61), (20, 62, 56), (19, 57, 49), + (18, 52, 43), (16, 50, 39), (15, 49, 36), (15, 49, 35), + (15, 49, 35), (17, 49, 37), (16, 44, 34), (16, 40, 31), + (14, 32, 27), (12, 25, 23), (11, 23, 21), (10, 22, 19), + (11, 25, 19), (17, 33, 26), (24, 42, 34), (30, 51, 43), + (37, 61, 52), (38, 64, 57), (39, 67, 63), (41, 72, 73), + (39, 76, 82), (36, 84, 100), (37, 89, 108), (39, 94, 116), + (39, 97, 121), (40, 100, 127), (39, 100, 129), (39, 101, 132), + (31, 93, 127), (23, 83, 120), (16, 74, 114), (11, 64, 102), + (7, 55, 90), (6, 51, 84), (5, 47, 79), (3, 41, 71), + (3, 36, 61), (4, 32, 47), (4, 30, 40), (4, 29, 34), + (4, 30, 29), (5, 31, 24), (4, 32, 23), (4, 34, 22), + (3, 42, 22), (5, 47, 28), (8, 52, 34), (11, 59, 44), + (14, 66, 54), (16, 70, 61), (18, 75, 68), (24, 85, 79), + (32, 97, 89), (46, 121, 105), (53, 126, 111), (60, 131, 117), + (62, 132, 120), (65, 133, 123), (66, 131, 130), (66, 129, 137), + (65, 128, 152), (63, 127, 154), (61, 127, 156), (60, 126, 155), + (60, 126, 155), (57, 124, 155), (55, 122, 155), (48, 116, 154), + (41, 110, 152), (26, 94, 138), (19, 84, 128), (12, 74, 118), + (10, 71, 114), (9, 68, 110), (7, 64, 106), (6, 61, 103), + (4, 60, 107), (3, 60, 106), (2, 61, 106), (2, 60, 104), + (2, 59, 102), (1, 54, 93), (1, 50, 84), (0, 44, 74), + (0, 41, 69), (1, 37, 67), (1, 37, 68), (1, 37, 69), + (1, 36, 68), (1, 35, 67), (1, 35, 65), (1, 33, 62), + (2, 33, 61), (7, 37, 64), (12, 41, 67), (16, 45, 70), + (20, 49, 74), (29, 57, 80), (37, 66, 86), (44, 75, 91), + (47, 82, 95), (48, 91, 103), (47, 91, 104), (47, 91, 105), + (46, 90, 107), (47, 89, 105), (48, 87, 100), (51, 84, 94), + (48, 73, 72), (41, 64, 61), (35, 56, 50), (31, 50, 45), + (27, 45, 41), (19, 35, 33), (12, 27, 29), (8, 21, 28), + (3, 17, 29), (1, 17, 35), (1, 18, 35), (1, 19, 36), + (1, 18, 37), (1, 17, 35), (1, 17, 34), (2, 16, 33), + (2, 17, 34), (2, 18, 35), (3, 19, 36), (2, 18, 35), + (2, 18, 34), (2, 16, 31), (2, 17, 29), (2, 17, 29), + (2, 20, 32), (4, 28, 46), (5, 31, 51), (6, 35, 56), + (8, 42, 66), (12, 48, 75), (15, 56, 80), (20, 64, 84), + (26, 77, 94), (26, 79, 96), (27, 81, 99), (27, 81, 101), + (27, 80, 101), (27, 77, 100), (24, 71, 93), (25, 67, 85), + (27, 63, 75), (25, 55, 56), (24, 53, 53), (23, 52, 51), + (22, 51, 47), (24, 51, 49), (25, 53, 52), (29, 58, 57), + (45, 73, 69), (49, 76, 72), (53, 79, 75), (58, 86, 80), + (60, 91, 83), (60, 94, 85), (59, 94, 85), (57, 92, 85), + (58, 94, 85), (59, 95, 85), (60, 91, 82), (61, 87, 78), + (58, 80, 72), (52, 73, 63), (44, 64, 53), (33, 55, 44), + (15, 48, 32), (11, 48, 31), (8, 49, 30), (5, 50, 30), + (6, 56, 35), (11, 66, 43), (18, 75, 50), (24, 84, 58), + (30, 93, 67), (34, 101, 74), (39, 111, 83), (45, 120, 93), + (48, 127, 104), (55, 137, 117), (61, 142, 128), (69, 146, 137), + (74, 149, 147), (77, 147, 152), (79, 146, 157), (80, 144, 160), + (79, 140, 162), (79, 138, 166), (80, 137, 170), (83, 139, 175), + (87, 143, 182), (90, 146, 185), (92, 149, 186), (94, 150, 185), + (93, 150, 182), (88, 148, 180), (84, 144, 178), (79, 141, 177), + (75, 137, 177), (71, 133, 173), (67, 128, 167), (64, 121, 157), + (61, 112, 144), (55, 104, 130), (48, 94, 117), (42, 84, 105), + (35, 75, 100), (27, 69, 98), (20, 66, 102), (16, 64, 104), + (15, 63, 106), (16, 63, 106), (17, 63, 105), (19, 64, 103), + (24, 66, 104), (28, 70, 107), (31, 76, 117), (34, 84, 129), + (36, 92, 142), (38, 99, 153), (39, 104, 163), (37, 107, 165), + (37, 107, 160), (35, 106, 152), (33, 105, 143), (32, 105, 136), + (32, 105, 129), (33, 107, 125), (35, 108, 129), (37, 109, 133), + (39, 110, 133), (36, 103, 123), (31, 97, 115), (26, 92, 109), + (24, 88, 103), (21, 86, 95), (20, 83, 92), (21, 80, 92) + ), + +// 399 040221-42 +((147, 160, 181), (166, 171, 186), (170, 173, 187), (174, 176, 188), + (174, 175, 186), (174, 174, 185), (174, 171, 182), (174, 168, 179), + (159, 157, 169), (144, 151, 167), (129, 145, 166), (115, 138, 165), + (101, 132, 164), (87, 126, 162), (74, 121, 160), (67, 118, 160), + (61, 116, 161), (49, 108, 164), (48, 108, 165), (48, 108, 166), + (54, 111, 166), (60, 115, 167), (67, 119, 169), (75, 123, 172), + (109, 143, 185), (123, 155, 193), (138, 168, 201), (156, 180, 206), + (175, 193, 212), (184, 197, 213), (193, 201, 214), (197, 204, 213), + (197, 203, 210), (191, 193, 200), (180, 184, 190), (170, 175, 181), + (153, 163, 173), (136, 151, 165), (127, 145, 163), (119, 139, 161), + (89, 116, 146), (78, 107, 137), (68, 98, 128), (60, 91, 124), + (52, 84, 121), (50, 81, 118), (48, 78, 116), (46, 75, 109), + (47, 72, 103), (62, 82, 108), (71, 89, 113), (81, 97, 119), + (85, 101, 123), (90, 106, 128), (90, 107, 129), (91, 109, 130), + (87, 104, 126), (79, 98, 123), (71, 92, 120), (60, 85, 116), + (49, 79, 113), (45, 76, 112), (41, 74, 111), (36, 72, 113), + (33, 72, 119), (31, 74, 127), (31, 73, 125), (32, 73, 124), + (32, 73, 124), (33, 74, 125), (36, 76, 127), (37, 77, 127), + (39, 77, 124), (39, 78, 126), (39, 79, 128), (42, 83, 133), + (46, 88, 138), (48, 91, 142), (51, 94, 147), (53, 99, 156), + (55, 103, 164), (53, 103, 168), (53, 103, 168), (53, 103, 169), + (53, 103, 169), (53, 103, 170), (53, 103, 171), (53, 104, 170), + (55, 105, 167), (64, 109, 167), (74, 114, 167), (81, 119, 168), + (88, 124, 170), (105, 135, 175), (118, 145, 181), (130, 152, 183), + (143, 159, 185), (161, 169, 185), (160, 166, 179), (159, 164, 174), + (155, 159, 169), (152, 154, 164), (140, 144, 156), (128, 134, 149), + (109, 120, 135), (102, 113, 129), (95, 107, 123), (92, 106, 124), + (90, 105, 125), (86, 105, 130), (81, 106, 138), (73, 109, 144), + (65, 109, 145), (50, 100, 140), (47, 96, 137), (44, 92, 135), + (38, 87, 133), (32, 86, 132), (29, 89, 136), (29, 89, 138), + (39, 85, 134), (50, 90, 133), (62, 95, 133), (69, 98, 134), + (77, 102, 136), (82, 106, 139), (84, 106, 140), (83, 105, 137), + (84, 104, 132), (92, 101, 121), (91, 100, 120), (90, 99, 120), + (86, 99, 121), (83, 100, 125), (86, 101, 125), (92, 104, 127), + (103, 113, 132), (110, 118, 135), (117, 124, 139), (120, 126, 140), + (124, 128, 141), (131, 133, 143), (137, 139, 148), (141, 142, 153), + (143, 147, 156), (150, 153, 163), (152, 156, 165), (154, 159, 168), + (159, 163, 174), (164, 168, 179), (168, 173, 183), (173, 176, 185), + (175, 179, 189), (174, 179, 188), (174, 179, 187), (172, 177, 185), + (173, 177, 181), (174, 177, 181), (175, 176, 182), (175, 178, 181), + (175, 180, 183), (188, 193, 195), (192, 196, 199), (196, 200, 204), + (201, 207, 213), (203, 210, 219), (202, 211, 221), (200, 209, 220), + (182, 195, 211), (174, 188, 207), (167, 182, 203), (145, 163, 193), + (123, 144, 180), (102, 125, 165), (82, 110, 152), (69, 101, 142), + (59, 94, 141), (49, 90, 142), (44, 86, 144), (40, 85, 145), + (39, 87, 145), (43, 92, 149), (47, 98, 154), (51, 102, 159), + (57, 104, 162), (60, 105, 161), (64, 107, 161), (73, 112, 164), + (85, 120, 166), (97, 130, 173), (110, 140, 182), (125, 151, 187), + (141, 161, 193), (157, 171, 196), (171, 180, 198), (180, 186, 205), + (187, 191, 206), (191, 191, 205), (190, 188, 200), (184, 182, 190), + (175, 174, 182), (159, 162, 176), (144, 148, 167), (126, 132, 159), + (108, 120, 150), (94, 114, 145), (80, 109, 145), (69, 105, 146), + (61, 97, 144), (55, 86, 135), (51, 82, 124), (50, 81, 118), + (53, 83, 119), (56, 86, 122), (61, 85, 121), (64, 85, 117), + (68, 85, 112), (75, 87, 111), (79, 92, 114), (85, 96, 119), + (89, 102, 124), (94, 108, 129), (102, 114, 131), (109, 119, 134), + (116, 123, 136), (121, 128, 139), (125, 133, 144), (129, 138, 147), + (134, 142, 151), (136, 143, 152), (135, 143, 152), (129, 140, 152), + (119, 134, 151), (109, 127, 146), (97, 117, 138), (85, 106, 129), + (75, 96, 120), (63, 87, 113), (58, 78, 105), (56, 73, 99), + (52, 70, 96), (54, 70, 99), (53, 74, 107), (55, 78, 116), + (63, 84, 123), (65, 89, 128), (68, 94, 136), (67, 98, 145), + (67, 102, 152), (74, 108, 157), (81, 114, 160), (91, 121, 164), + (103, 129, 166), (113, 136, 170), (124, 144, 172), (136, 153, 176) + ), + +// 400 040221-43 +((53, 75, 76), (58, 80, 82), (57, 80, 80), (57, 81, 79), + (53, 78, 77), (50, 75, 76), (48, 74, 76), (46, 73, 77), + (41, 71, 80), (39, 67, 77), (37, 64, 74), (35, 60, 70), + (34, 56, 66), (35, 53, 62), (37, 51, 58), (38, 51, 57), + (40, 51, 56), (48, 54, 57), (51, 56, 58), (55, 59, 60), + (56, 59, 59), (57, 59, 59), (57, 59, 59), (57, 59, 59), + (60, 60, 56), (66, 64, 59), (72, 68, 62), (79, 73, 67), + (86, 79, 72), (88, 80, 73), (90, 81, 75), (91, 82, 76), + (89, 80, 74), (88, 76, 69), (89, 76, 67), (91, 76, 66), + (92, 75, 65), (93, 74, 64), (92, 73, 63), (91, 72, 62), + (84, 63, 56), (78, 59, 52), (72, 56, 49), (70, 57, 49), + (68, 58, 50), (66, 59, 51), (65, 60, 52), (63, 61, 57), + (61, 62, 59), (57, 60, 60), (56, 59, 58), (56, 59, 56), + (55, 58, 55), (55, 58, 54), (54, 58, 54), (54, 58, 54), + (49, 53, 51), (46, 49, 49), (43, 46, 47), (42, 43, 44), + (41, 41, 42), (42, 41, 42), (43, 42, 42), (44, 43, 43), + (47, 47, 46), (47, 60, 64), (47, 68, 74), (48, 76, 84), + (49, 80, 89), (50, 84, 95), (55, 96, 108), (61, 104, 115), + (72, 113, 121), (73, 116, 124), (74, 119, 128), (73, 121, 131), + (72, 123, 134), (71, 122, 133), (71, 121, 133), (72, 117, 129), + (72, 113, 120), (71, 101, 102), (70, 93, 90), (70, 85, 79), + (70, 82, 75), (70, 79, 71), (68, 71, 65), (66, 67, 59), + (65, 60, 48), (69, 59, 45), (73, 59, 43), (75, 60, 44), + (78, 62, 45), (82, 64, 47), (83, 66, 52), (82, 67, 56), + (78, 68, 59), (72, 67, 60), (69, 66, 62), (66, 66, 64), + (65, 66, 65), (64, 67, 67), (61, 67, 71), (57, 67, 73), + (48, 63, 72), (41, 58, 67), (35, 54, 63), (32, 51, 60), + (30, 48, 57), (25, 42, 53), (23, 40, 51), (23, 40, 51), + (27, 42, 53), (37, 55, 60), (40, 58, 62), (43, 61, 65), + (48, 68, 70), (52, 72, 73), (56, 76, 75), (63, 78, 76), + (83, 86, 78), (92, 91, 80), (102, 97, 83), (105, 98, 83), + (108, 99, 84), (112, 103, 86), (114, 105, 87), (118, 107, 86), + (123, 107, 87), (142, 117, 93), (144, 119, 95), (147, 122, 98), + (152, 127, 104), (153, 130, 110), (152, 133, 112), (148, 134, 116), + (157, 143, 126), (159, 145, 128), (161, 148, 131), (161, 146, 129), + (161, 145, 127), (157, 139, 119), (148, 130, 110), (140, 121, 102), + (133, 114, 96), (122, 106, 91), (120, 105, 90), (119, 104, 89), + (114, 99, 83), (108, 91, 75), (101, 85, 69), (92, 79, 64), + (77, 72, 64), (74, 71, 65), (71, 70, 67), (66, 69, 70), + (61, 66, 70), (57, 64, 69), (53, 61, 66), (50, 57, 63), + (47, 54, 59), (42, 51, 56), (41, 50, 56), (40, 49, 57), + (39, 49, 58), (39, 49, 59), (40, 52, 60), (42, 55, 61), + (46, 62, 65), (46, 63, 66), (47, 64, 67), (46, 65, 68), + (44, 63, 69), (41, 63, 69), (40, 63, 69), (39, 63, 70), + (39, 63, 69), (40, 64, 68), (43, 64, 66), (44, 62, 63), + (45, 58, 58), (45, 54, 52), (47, 51, 47), (48, 49, 43), + (54, 49, 41), (55, 49, 41), (57, 50, 41), (60, 51, 42), + (64, 54, 43), (68, 56, 44), (70, 57, 44), (72, 59, 46), + (73, 60, 46), (74, 59, 46), (72, 59, 49), (70, 61, 52), + (68, 63, 57), (66, 66, 62), (66, 70, 69), (68, 77, 77), + (73, 84, 82), (79, 91, 88), (85, 97, 94), (90, 101, 98), + (90, 104, 101), (89, 103, 103), (88, 103, 104), (86, 103, 104), + (86, 104, 103), (88, 104, 101), (90, 103, 99), (88, 101, 94), + (83, 95, 90), (77, 90, 86), (71, 85, 84), (63, 82, 82), + (57, 79, 81), (52, 76, 80), (48, 75, 77), (45, 71, 75), + (40, 67, 73), (39, 65, 73), (37, 65, 72), (36, 64, 71), + (34, 62, 72), (33, 62, 70), (33, 59, 65), (32, 54, 58), + (33, 48, 51), (35, 44, 44), (39, 40, 37), (41, 37, 33), + (43, 37, 32), (46, 39, 31), (46, 39, 31), (48, 39, 31), + (50, 40, 31), (52, 39, 28), (54, 37, 25), (53, 35, 24), + (53, 34, 24), (51, 34, 25), (48, 34, 27), (44, 35, 30), + (40, 35, 33), (37, 36, 33), (33, 34, 34), (32, 34, 36), + (33, 36, 38), (39, 41, 42), (43, 46, 46), (46, 50, 50), + (48, 57, 54), (50, 62, 59), (50, 65, 65), (50, 69, 69) + ), + +// 401 040221-44 +((56, 32, 15), (81, 40, 17), (91, 41, 20), (101, 43, 23), + (104, 42, 23), (108, 42, 23), (105, 40, 20), (102, 39, 17), + (86, 28, 13), (81, 26, 12), (77, 24, 11), (75, 24, 10), + (73, 25, 9), (78, 26, 9), (83, 28, 9), (87, 29, 9), + (91, 30, 10), (102, 31, 13), (102, 28, 11), (103, 26, 9), + (100, 22, 7), (98, 18, 6), (94, 16, 5), (90, 15, 5), + (68, 12, 5), (62, 13, 7), (57, 14, 10), (55, 17, 14), + (54, 21, 19), (54, 23, 19), (55, 26, 20), (61, 30, 25), + (72, 37, 25), (104, 54, 39), (115, 64, 44), (127, 74, 49), + (137, 76, 47), (147, 79, 46), (150, 76, 43), (154, 74, 41), + (152, 75, 41), (141, 69, 39), (130, 64, 38), (116, 51, 29), + (103, 39, 21), (95, 34, 18), (88, 30, 15), (76, 22, 12), + (69, 22, 13), (54, 30, 11), (45, 29, 9), (36, 28, 7), + (33, 27, 6), (31, 27, 5), (31, 28, 5), (32, 29, 6), + (27, 26, 5), (26, 20, 4), (25, 14, 4), (32, 13, 4), + (40, 13, 5), (48, 14, 5), (56, 15, 6), (72, 22, 5), + (89, 31, 7), (123, 46, 20), (143, 62, 34), (163, 79, 48), + (173, 91, 59), (184, 104, 71), (196, 130, 86), (212, 145, 94), + (215, 145, 86), (210, 144, 93), (206, 144, 101), (194, 130, 87), + (183, 116, 73), (176, 107, 61), (169, 99, 49), (153, 77, 34), + (142, 62, 30), (139, 47, 26), (142, 58, 37), (146, 69, 48), + (151, 79, 56), (156, 90, 64), (171, 106, 77), (183, 116, 80), + (200, 121, 85), (199, 123, 87), (198, 126, 90), (194, 122, 84), + (191, 118, 78), (188, 108, 65), (183, 88, 52), (178, 74, 38), + (172, 65, 32), (156, 55, 19), (156, 53, 17), (156, 52, 16), + (156, 51, 15), (156, 51, 14), (159, 52, 13), (153, 52, 11), + (141, 48, 6), (136, 43, 4), (132, 38, 2), (129, 35, 1), + (126, 32, 1), (121, 29, 1), (116, 27, 1), (111, 26, 1), + (107, 25, 1), (93, 22, 3), (89, 21, 3), (86, 21, 4), + (80, 21, 7), (74, 19, 7), (71, 17, 8), (67, 16, 9), + (67, 16, 10), (72, 16, 9), (78, 16, 9), (82, 17, 9), + (86, 18, 10), (95, 22, 9), (105, 26, 10), (114, 31, 13), + (124, 33, 14), (133, 35, 14), (131, 34, 13), (130, 34, 12), + (126, 35, 12), (119, 33, 13), (112, 32, 12), (105, 30, 11), + (90, 24, 3), (86, 22, 2), (83, 20, 2), (82, 19, 3), + (81, 19, 5), (82, 15, 5), (81, 13, 4), (80, 12, 5), + (79, 12, 4), (76, 7, 6), (75, 5, 5), (74, 4, 4), + (67, 2, 3), (58, 4, 3), (48, 5, 3), (39, 4, 3), + (28, 2, 1), (25, 2, 0), (23, 2, 0), (19, 3, 1), + (17, 4, 1), (17, 3, 1), (19, 4, 1), (22, 4, 0), + (23, 6, 1), (24, 8, 3), (24, 8, 3), (25, 9, 4), + (26, 9, 4), (25, 9, 4), (21, 10, 4), (18, 10, 4), + (12, 10, 4), (11, 9, 4), (11, 9, 4), (10, 9, 4), + (9, 9, 3), (9, 10, 3), (10, 12, 6), (13, 17, 12), + (13, 25, 17), (21, 33, 22), (31, 39, 26), (46, 44, 29), + (67, 48, 34), (79, 56, 39), (98, 68, 44), (113, 80, 45), + (150, 89, 38), (155, 88, 36), (160, 88, 35), (170, 89, 36), + (175, 94, 33), (172, 98, 33), (171, 96, 31), (164, 90, 25), + (157, 78, 26), (151, 69, 25), (140, 64, 23), (132, 57, 24), + (123, 53, 25), (110, 42, 31), (98, 32, 32), (83, 23, 28), + (68, 16, 23), (57, 15, 17), (46, 14, 20), (36, 12, 19), + (27, 9, 18), (18, 5, 13), (14, 4, 7), (12, 7, 6), + (15, 9, 9), (21, 13, 11), (32, 15, 13), (49, 16, 17), + (67, 19, 21), (83, 23, 27), (96, 28, 31), (105, 34, 30), + (115, 36, 30), (127, 36, 29), (132, 35, 26), (130, 34, 24), + (123, 33, 19), (110, 32, 16), (99, 28, 13), (85, 23, 10), + (70, 17, 6), (57, 13, 3), (45, 9, 2), (35, 7, 2), + (26, 5, 2), (18, 4, 2), (11, 3, 1), (6, 2, 0), + (4, 2, 0), (3, 1, 0), (2, 1, 0), (2, 1, 0), + (1, 0, 0), (0, 0, 1), (0, 0, 0), (1, 0, 0), + (1, 0, 0), (3, 0, 1), (4, 0, 1), (5, 0, 1), + (5, 0, 1), (5, 0, 0), (5, 1, 1), (6, 1, 0), + (6, 2, 0), (5, 2, 0), (5, 3, 0), (5, 5, 1), + (8, 7, 1), (17, 11, 2), (28, 17, 8), (42, 24, 11) + ), + +// 402 040221-45 +((78, 97, 108), (74, 87, 90), (61, 74, 76), (48, 61, 63), + (52, 67, 70), (57, 73, 77), (64, 81, 85), (71, 89, 94), + (92, 120, 129), (95, 133, 148), (98, 146, 167), (95, 151, 175), + (93, 157, 183), (85, 158, 182), (78, 160, 182), (71, 157, 180), + (65, 155, 178), (44, 144, 172), (42, 141, 166), (41, 138, 161), + (41, 128, 151), (41, 118, 142), (39, 111, 136), (38, 104, 130), + (35, 73, 106), (36, 61, 93), (37, 49, 80), (32, 38, 72), + (28, 27, 65), (24, 23, 63), (20, 19, 61), (15, 14, 53), + (13, 10, 48), (12, 11, 49), (11, 15, 54), (11, 20, 59), + (13, 27, 62), (16, 35, 66), (19, 40, 69), (22, 46, 73), + (30, 67, 99), (33, 73, 104), (36, 79, 109), (34, 78, 106), + (33, 78, 103), (32, 75, 101), (31, 72, 100), (28, 66, 91), + (24, 57, 83), (11, 42, 66), (9, 37, 64), (8, 32, 63), + (9, 30, 58), (10, 28, 53), (8, 27, 51), (7, 27, 49), + (11, 30, 53), (14, 30, 49), (17, 30, 45), (18, 29, 42), + (19, 29, 40), (19, 32, 43), (19, 36, 47), (21, 45, 58), + (21, 55, 69), (25, 78, 99), (28, 93, 118), (32, 108, 138), + (36, 115, 145), (40, 122, 153), (51, 136, 168), (65, 147, 176), + (86, 161, 188), (95, 161, 189), (105, 162, 190), (110, 160, 187), + (116, 159, 184), (113, 157, 182), (111, 155, 181), (102, 148, 177), + (90, 142, 173), (66, 134, 165), (55, 132, 161), (44, 130, 158), + (39, 129, 159), (34, 129, 160), (28, 131, 162), (24, 135, 164), + (28, 138, 170), (35, 139, 171), (42, 140, 173), (46, 141, 174), + (50, 142, 175), (55, 148, 178), (59, 153, 187), (65, 157, 191), + (73, 156, 191), (90, 149, 184), (91, 152, 184), (92, 156, 184), + (92, 157, 182), (92, 159, 180), (90, 156, 175), (90, 145, 164), + (83, 119, 139), (73, 109, 121), (63, 100, 103), (56, 95, 99), + (50, 91, 95), (46, 79, 91), (42, 70, 94), (37, 68, 94), + (32, 67, 94), (21, 80, 107), (22, 84, 114), (23, 89, 122), + (24, 100, 136), (25, 110, 148), (23, 120, 156), (22, 127, 159), + (24, 125, 156), (24, 120, 153), (25, 115, 151), (26, 113, 149), + (27, 111, 148), (29, 105, 146), (30, 103, 144), (31, 104, 144), + (30, 107, 147), (31, 113, 152), (32, 113, 151), (33, 114, 151), + (35, 117, 149), (35, 118, 143), (35, 118, 139), (29, 115, 135), + (22, 106, 129), (23, 103, 126), (25, 100, 123), (24, 100, 123), + (23, 101, 124), (18, 100, 125), (13, 104, 132), (11, 108, 136), + (11, 112, 141), (13, 114, 148), (14, 112, 147), (15, 111, 146), + (18, 104, 141), (22, 99, 135), (25, 95, 130), (29, 94, 130), + (46, 93, 130), (50, 94, 130), (54, 96, 131), (60, 99, 131), + (63, 106, 135), (62, 112, 140), (63, 117, 146), (65, 124, 149), + (72, 132, 154), (88, 144, 165), (91, 146, 169), (94, 148, 174), + (101, 151, 178), (113, 158, 183), (122, 162, 188), (132, 164, 191), + (136, 164, 191), (135, 162, 189), (134, 160, 187), (127, 152, 178), + (118, 142, 173), (107, 135, 167), (99, 128, 160), (94, 125, 158), + (92, 121, 152), (87, 116, 148), (82, 115, 146), (79, 110, 143), + (74, 108, 140), (71, 101, 133), (66, 88, 120), (57, 78, 103), + (39, 54, 72), (34, 48, 64), (29, 43, 57), (21, 28, 42), + (13, 15, 31), (9, 7, 29), (9, 9, 34), (10, 16, 44), + (15, 25, 53), (20, 36, 65), (24, 45, 83), (27, 61, 102), + (29, 76, 122), (30, 91, 136), (35, 103, 143), (41, 111, 150), + (48, 119, 156), (56, 128, 163), (65, 138, 169), (74, 145, 174), + (85, 153, 179), (98, 157, 185), (111, 163, 190), (125, 170, 194), + (139, 176, 198), (149, 185, 203), (157, 188, 207), (163, 194, 213), + (166, 197, 216), (170, 202, 220), (170, 207, 224), (170, 206, 224), + (173, 208, 225), (173, 205, 223), (173, 204, 221), (169, 203, 221), + (160, 198, 217), (153, 192, 210), (143, 179, 195), (130, 161, 176), + (116, 142, 154), (101, 121, 132), (88, 103, 111), (76, 86, 89), + (59, 67, 71), (42, 52, 56), (28, 39, 49), (25, 35, 50), + (26, 37, 53), (32, 43, 62), (40, 53, 73), (43, 66, 89), + (51, 81, 110), (60, 93, 126), (72, 107, 141), (87, 120, 152), + (99, 132, 160), (109, 145, 171), (117, 152, 177), (122, 158, 182), + (124, 162, 183), (126, 163, 183), (124, 165, 185), (123, 167, 189), + (125, 169, 194), (128, 172, 196), (130, 175, 197), (134, 179, 200), + (135, 181, 201), (116, 157, 179), (101, 135, 156), (86, 111, 129) + ), + +// 403 040221-46 +((76, 81, 83), (85, 89, 95), (92, 97, 106), (100, 105, 118), + (110, 114, 129), (120, 124, 140), (124, 128, 146), (129, 133, 153), + (136, 140, 165), (133, 137, 163), (131, 135, 161), (125, 129, 157), + (119, 124, 153), (112, 113, 141), (105, 103, 130), (100, 98, 123), + (96, 93, 117), (79, 80, 105), (82, 80, 97), (85, 81, 89), + (88, 82, 86), (92, 84, 84), (92, 86, 86), (93, 88, 88), + (109, 101, 93), (115, 106, 96), (122, 112, 99), (124, 114, 101), + (127, 116, 103), (127, 116, 104), (128, 117, 106), (128, 119, 112), + (126, 120, 119), (120, 119, 126), (116, 117, 127), (112, 116, 129), + (106, 112, 130), (100, 108, 132), (96, 104, 132), (93, 101, 132), + (79, 87, 130), (72, 80, 127), (65, 74, 124), (58, 67, 120), + (51, 60, 116), (49, 58, 114), (48, 56, 113), (48, 56, 111), + (49, 56, 112), (50, 59, 112), (53, 62, 115), (57, 66, 119), + (61, 71, 123), (66, 76, 128), (68, 78, 129), (70, 81, 130), + (87, 93, 133), (101, 100, 136), (115, 108, 139), (123, 113, 137), + (132, 118, 135), (133, 118, 131), (134, 118, 127), (135, 115, 124), + (134, 112, 120), (124, 103, 118), (108, 94, 114), (92, 85, 111), + (83, 79, 108), (75, 73, 105), (59, 63, 99), (49, 54, 96), + (38, 49, 96), (38, 49, 95), (39, 50, 95), (43, 52, 94), + (47, 55, 94), (48, 56, 94), (50, 58, 94), (54, 63, 94), + (56, 65, 91), (59, 66, 86), (58, 65, 85), (58, 65, 85), + (58, 65, 84), (59, 66, 83), (56, 64, 82), (56, 63, 81), + (56, 64, 91), (59, 68, 98), (62, 72, 105), (63, 72, 107), + (65, 73, 109), (64, 75, 115), (63, 73, 120), (61, 71, 122), + (58, 69, 124), (55, 66, 122), (53, 64, 119), (52, 62, 116), + (52, 62, 115), (52, 62, 114), (57, 64, 113), (63, 70, 114), + (91, 89, 119), (108, 100, 125), (125, 111, 131), (130, 115, 134), + (135, 119, 138), (143, 129, 142), (149, 135, 145), (155, 141, 148), + (160, 144, 149), (153, 142, 157), (150, 142, 159), (147, 142, 162), + (138, 142, 172), (135, 143, 177), (132, 141, 179), (128, 138, 178), + (122, 134, 175), (121, 132, 169), (120, 131, 164), (118, 127, 159), + (116, 124, 155), (119, 115, 143), (117, 109, 136), (119, 107, 130), + (126, 114, 130), (146, 135, 149), (151, 140, 157), (156, 146, 165), + (163, 157, 176), (174, 167, 181), (182, 182, 183), (195, 189, 185), + (203, 203, 200), (201, 199, 197), (199, 196, 194), (197, 190, 188), + (195, 185, 182), (189, 175, 176), (177, 167, 171), (163, 155, 165), + (150, 144, 162), (122, 123, 147), (115, 118, 143), (108, 113, 140), + (96, 105, 134), (88, 96, 131), (82, 92, 129), (80, 90, 129), + (87, 96, 136), (92, 100, 141), (98, 105, 146), (112, 118, 158), + (132, 136, 170), (150, 155, 181), (169, 172, 193), (187, 190, 204), + (203, 203, 218), (231, 229, 231), (233, 231, 231), (236, 233, 231), + (233, 231, 223), (222, 219, 218), (204, 204, 209), (190, 189, 197), + (161, 160, 166), (155, 153, 159), (149, 147, 152), (137, 136, 145), + (130, 131, 142), (128, 131, 146), (128, 131, 145), (130, 133, 145), + (134, 136, 148), (135, 138, 155), (137, 143, 167), (135, 144, 176), + (130, 140, 177), (124, 134, 174), (115, 125, 168), (110, 120, 164), + (109, 117, 161), (111, 118, 158), (113, 119, 156), (119, 120, 148), + (128, 120, 141), (137, 125, 138), (149, 131, 139), (158, 136, 141), + (169, 144, 144), (180, 149, 145), (192, 156, 150), (204, 170, 157), + (212, 178, 168), (218, 190, 182), (223, 201, 193), (228, 208, 201), + (234, 223, 207), (241, 232, 214), (245, 240, 225), (240, 243, 237), + (233, 240, 243), (220, 231, 239), (204, 216, 228), (193, 202, 213), + (173, 182, 201), (153, 165, 192), (130, 143, 179), (106, 119, 162), + (89, 99, 138), (73, 81, 117), (63, 70, 99), (58, 66, 88), + (54, 62, 84), (54, 61, 79), (54, 61, 79), (56, 62, 80), + (62, 68, 84), (66, 74, 89), (73, 80, 93), (78, 85, 99), + (81, 88, 106), (84, 89, 112), (83, 89, 118), (83, 89, 122), + (84, 89, 124), (88, 94, 127), (92, 97, 130), (95, 100, 133), + (94, 99, 136), (87, 93, 136), (83, 89, 134), (79, 86, 132), + (75, 82, 129), (70, 78, 125), (62, 71, 119), (54, 62, 114), + (47, 55, 111), (44, 51, 109), (42, 49, 112), (42, 51, 112), + (45, 54, 113), (49, 57, 116), (54, 61, 117), (59, 66, 119), + (65, 73, 118), (71, 78, 115), (74, 80, 109), (74, 78, 100), + (74, 77, 94), (73, 76, 88), (72, 77, 85), (74, 80, 85) + ), + +// 404 040221-47 +((141, 128, 93), (130, 114, 87), (117, 102, 81), (105, 91, 76), + (89, 83, 74), (74, 75, 73), (75, 75, 74), (76, 75, 75), + (78, 78, 76), (77, 75, 72), (77, 72, 68), (73, 65, 61), + (70, 59, 55), (68, 56, 53), (67, 53, 51), (67, 53, 50), + (68, 54, 50), (76, 60, 51), (85, 62, 50), (95, 65, 49), + (101, 65, 49), (108, 66, 49), (107, 67, 49), (107, 68, 49), + (98, 69, 52), (90, 67, 52), (82, 66, 53), (73, 62, 52), + (65, 59, 52), (59, 56, 51), (53, 54, 51), (40, 49, 51), + (26, 44, 50), (5, 40, 51), (2, 39, 50), (0, 38, 50), + (0, 37, 50), (0, 36, 50), (0, 35, 49), (0, 35, 49), + (0, 35, 49), (0, 35, 49), (0, 35, 50), (0, 35, 50), + (0, 36, 50), (0, 36, 50), (0, 36, 51), (0, 36, 51), + (0, 37, 52), (1, 38, 53), (8, 42, 55), (16, 47, 57), + (33, 58, 63), (50, 70, 69), (60, 78, 73), (71, 86, 78), + (107, 114, 89), (119, 121, 92), (132, 129, 95), (142, 130, 92), + (152, 132, 89), (158, 133, 90), (164, 135, 91), (171, 137, 91), + (177, 138, 89), (175, 133, 84), (166, 121, 73), (158, 109, 63), + (153, 101, 59), (149, 94, 56), (139, 82, 50), (130, 71, 45), + (121, 62, 41), (119, 61, 39), (118, 60, 38), (111, 58, 38), + (104, 57, 39), (99, 55, 39), (94, 54, 40), (85, 53, 41), + (76, 52, 45), (63, 50, 46), (54, 48, 46), (46, 47, 47), + (41, 46, 47), (36, 45, 48), (24, 43, 47), (14, 40, 48), + (1, 35, 48), (0, 34, 48), (0, 34, 48), (0, 33, 48), + (0, 33, 48), (0, 34, 48), (0, 34, 48), (0, 35, 48), + (0, 36, 48), (1, 37, 49), (1, 37, 49), (1, 37, 50), + (1, 37, 50), (1, 37, 51), (1, 38, 51), (1, 39, 52), + (2, 41, 52), (3, 40, 52), (4, 40, 53), (6, 39, 52), + (8, 39, 52), (13, 39, 51), (20, 39, 50), (27, 41, 48), + (35, 44, 45), (47, 47, 44), (50, 47, 43), (53, 48, 43), + (58, 51, 43), (65, 54, 47), (75, 59, 49), (91, 69, 52), + (126, 95, 67), (138, 105, 71), (151, 116, 76), (153, 118, 78), + (155, 121, 80), (151, 120, 83), (144, 117, 83), (137, 117, 81), + (131, 114, 84), (121, 112, 85), (118, 111, 84), (116, 111, 84), + (105, 103, 82), (88, 92, 77), (71, 78, 67), (53, 63, 58), + (25, 39, 44), (23, 35, 39), (22, 31, 35), (22, 30, 34), + (23, 30, 34), (23, 29, 34), (23, 27, 33), (23, 24, 33), + (20, 23, 32), (22, 23, 29), (22, 23, 28), (23, 23, 28), + (22, 25, 31), (20, 26, 33), (17, 26, 37), (11, 26, 41), + (3, 27, 47), (2, 27, 47), (1, 28, 48), (1, 28, 48), + (1, 27, 46), (2, 26, 43), (3, 25, 39), (4, 24, 37), + (6, 24, 34), (5, 26, 36), (4, 26, 36), (4, 26, 37), + (6, 25, 37), (7, 25, 34), (13, 25, 31), (22, 27, 27), + (38, 33, 27), (41, 34, 28), (44, 36, 29), (49, 37, 32), + (47, 39, 36), (44, 39, 38), (43, 40, 38), (42, 40, 39), + (43, 41, 40), (44, 42, 40), (46, 42, 40), (43, 41, 43), + (36, 40, 45), (28, 39, 47), (19, 37, 49), (11, 36, 51), + (1, 34, 52), (1, 34, 52), (1, 34, 52), (1, 34, 51), + (1, 34, 51), (0, 35, 51), (0, 35, 51), (0, 36, 51), + (0, 37, 51), (0, 37, 50), (0, 38, 50), (0, 39, 50), + (0, 40, 49), (0, 41, 49), (0, 41, 49), (0, 41, 48), + (0, 41, 49), (0, 41, 49), (0, 41, 49), (0, 41, 49), + (0, 41, 49), (0, 41, 49), (0, 41, 49), (0, 40, 49), + (0, 40, 49), (0, 40, 49), (0, 40, 49), (0, 40, 50), + (0, 39, 50), (0, 39, 50), (0, 39, 50), (0, 39, 49), + (0, 39, 49), (0, 39, 49), (0, 38, 48), (0, 38, 48), + (0, 37, 48), (1, 36, 49), (4, 34, 47), (9, 34, 45), + (16, 35, 43), (25, 38, 42), (36, 44, 43), (52, 56, 46), + (68, 69, 52), (84, 80, 57), (100, 91, 61), (113, 97, 62), + (123, 100, 63), (126, 101, 65), (130, 104, 66), (131, 107, 68), + (127, 110, 72), (122, 113, 76), (117, 112, 76), (111, 106, 73), + (104, 98, 71), (98, 89, 68), (97, 84, 64), (95, 82, 63), + (98, 86, 66), (105, 94, 70), (110, 101, 72), (119, 106, 74), + (128, 110, 75), (135, 110, 72), (133, 107, 69), (132, 106, 68), + (131, 108, 70), (130, 113, 74), (129, 118, 81), (131, 125, 91) + ), + +// 405 040221-48 +((100, 70, 92), (101, 71, 93), (107, 78, 100), (114, 85, 108), + (118, 89, 112), (122, 94, 116), (123, 96, 117), (124, 98, 118), + (124, 99, 119), (125, 100, 120), (127, 102, 121), (126, 103, 124), + (126, 105, 127), (130, 110, 131), (135, 115, 135), (136, 118, 137), + (138, 121, 139), (139, 130, 137), (133, 129, 132), (127, 129, 128), + (118, 121, 119), (109, 114, 110), (104, 108, 106), (99, 103, 102), + (87, 78, 84), (83, 67, 77), (79, 57, 71), (74, 52, 65), + (70, 47, 60), (68, 45, 57), (66, 43, 55), (62, 44, 54), + (60, 44, 52), (50, 40, 45), (43, 36, 38), (37, 33, 32), + (29, 27, 26), (22, 22, 21), (20, 20, 19), (18, 19, 18), + (22, 21, 22), (28, 27, 30), (34, 33, 38), (41, 38, 43), + (48, 43, 48), (50, 45, 51), (53, 48, 54), (55, 49, 53), + (55, 48, 49), (47, 45, 45), (44, 42, 42), (41, 40, 39), + (42, 40, 40), (43, 40, 41), (47, 43, 45), (51, 46, 49), + (79, 69, 71), (91, 82, 82), (103, 96, 93), (108, 101, 96), + (114, 107, 99), (112, 104, 98), (111, 101, 98), (105, 91, 94), + (96, 81, 86), (82, 62, 75), (79, 59, 74), (77, 56, 73), + (79, 56, 75), (82, 57, 77), (90, 62, 85), (97, 69, 95), + (109, 85, 110), (109, 87, 110), (109, 89, 111), (104, 87, 105), + (100, 86, 99), (96, 84, 93), (92, 82, 88), (87, 78, 82), + (84, 76, 78), (85, 70, 75), (89, 70, 82), (94, 71, 90), + (97, 73, 93), (101, 76, 96), (111, 84, 107), (120, 95, 116), + (135, 113, 136), (145, 124, 144), (156, 136, 153), (158, 138, 157), + (161, 140, 161), (166, 145, 166), (176, 155, 175), (183, 161, 182), + (180, 158, 179), (179, 160, 179), (172, 156, 170), (165, 152, 161), + (162, 149, 156), (160, 147, 152), (152, 140, 146), (149, 138, 146), + (154, 136, 149), (155, 134, 152), (156, 133, 156), (158, 133, 157), + (160, 133, 158), (157, 128, 157), (152, 124, 149), (149, 121, 140), + (143, 117, 133), (130, 114, 119), (124, 111, 114), (119, 108, 110), + (107, 103, 102), (96, 99, 94), (87, 91, 85), (76, 83, 75), + (56, 69, 57), (51, 62, 51), (46, 56, 46), (44, 53, 45), + (42, 50, 45), (40, 45, 44), (45, 45, 48), (58, 51, 59), + (69, 58, 69), (99, 77, 96), (106, 82, 103), (113, 87, 111), + (121, 97, 121), (130, 103, 127), (132, 103, 128), (126, 99, 120), + (115, 85, 100), (102, 75, 87), (89, 66, 74), (85, 62, 71), + (81, 59, 69), (73, 54, 64), (66, 51, 60), (62, 49, 57), + (63, 51, 60), (74, 65, 74), (77, 71, 78), (81, 77, 82), + (94, 88, 93), (103, 98, 103), (109, 110, 107), (115, 117, 111), + (113, 111, 107), (111, 107, 102), (109, 103, 97), (105, 98, 93), + (103, 92, 91), (103, 88, 88), (106, 89, 91), (111, 97, 100), + (119, 105, 114), (135, 117, 135), (138, 119, 138), (141, 122, 141), + (148, 128, 149), (150, 134, 150), (151, 138, 147), (152, 141, 144), + (146, 147, 137), (145, 146, 135), (144, 145, 133), (143, 141, 128), + (139, 139, 128), (136, 138, 128), (134, 132, 125), (128, 123, 119), + (120, 121, 114), (111, 116, 107), (106, 105, 99), (104, 103, 98), + (102, 103, 97), (104, 100, 95), (105, 97, 99), (104, 95, 100), + (95, 85, 94), (91, 81, 89), (87, 78, 85), (78, 72, 75), + (73, 64, 68), (69, 59, 62), (64, 55, 57), (63, 52, 57), + (65, 49, 58), (66, 50, 60), (68, 50, 61), (69, 49, 61), + (71, 50, 61), (70, 50, 61), (69, 50, 63), (73, 52, 66), + (78, 57, 71), (83, 66, 80), (92, 71, 91), (102, 81, 99), + (108, 92, 105), (114, 98, 110), (113, 101, 111), (110, 99, 107), + (108, 92, 102), (102, 84, 97), (95, 76, 93), (93, 68, 90), + (92, 65, 90), (93, 69, 91), (99, 75, 95), (106, 85, 102), + (114, 95, 108), (122, 104, 116), (129, 109, 125), (134, 112, 129), + (131, 112, 128), (126, 107, 126), (119, 98, 120), (106, 88, 107), + (93, 82, 97), (81, 74, 84), (68, 66, 71), (66, 68, 67), + (64, 69, 65), (65, 65, 65), (73, 69, 67), (80, 71, 71), + (84, 66, 73), (89, 68, 73), (94, 70, 74), (100, 71, 78), + (101, 79, 83), (104, 85, 91), (112, 91, 100), (115, 99, 106), + (119, 102, 110), (124, 104, 114), (124, 109, 114), (126, 111, 112), + (128, 113, 113), (129, 117, 114), (128, 120, 112), (126, 119, 111), + (125, 119, 110), (123, 114, 107), (119, 107, 105), (115, 100, 103), + (109, 92, 102), (107, 82, 101), (100, 74, 95), (95, 70, 89) + ), + +// 406 040221-49 +((129, 121, 95), (110, 101, 78), (98, 89, 68), (86, 78, 59), + (75, 67, 49), (64, 56, 40), (61, 54, 38), (59, 52, 37), + (52, 42, 29), (49, 38, 25), (47, 35, 22), (48, 36, 22), + (50, 38, 22), (57, 46, 28), (65, 54, 35), (70, 59, 39), + (76, 65, 44), (97, 86, 62), (109, 97, 71), (121, 109, 80), + (129, 117, 86), (137, 125, 92), (140, 128, 93), (143, 131, 95), + (151, 134, 96), (154, 135, 93), (158, 136, 91), (159, 135, 89), + (161, 135, 87), (160, 133, 84), (160, 132, 82), (155, 126, 76), + (147, 117, 68), (126, 96, 48), (116, 85, 41), (106, 75, 34), + (100, 71, 32), (94, 67, 30), (92, 66, 30), (90, 65, 31), + (84, 66, 35), (81, 64, 36), (78, 62, 38), (77, 61, 37), + (76, 61, 37), (77, 61, 37), (78, 62, 37), (82, 64, 38), + (90, 71, 41), (109, 87, 52), (118, 96, 59), (128, 106, 66), + (137, 115, 75), (146, 124, 84), (150, 128, 89), (154, 132, 94), + (172, 151, 113), (180, 160, 122), (189, 170, 132), (195, 178, 141), + (201, 186, 150), (202, 188, 152), (203, 190, 155), (202, 192, 158), + (200, 188, 157), (191, 176, 141), (184, 167, 131), (178, 159, 121), + (173, 154, 115), (169, 150, 110), (157, 138, 99), (144, 124, 85), + (117, 96, 58), (105, 83, 46), (93, 71, 35), (86, 65, 30), + (79, 59, 26), (76, 57, 25), (73, 55, 25), (70, 55, 27), + (69, 55, 28), (72, 61, 37), (78, 67, 42), (85, 73, 48), + (88, 76, 50), (91, 80, 53), (98, 87, 58), (108, 93, 61), + (124, 106, 68), (132, 111, 71), (140, 117, 74), (142, 119, 75), + (145, 121, 77), (146, 124, 80), (146, 125, 81), (143, 123, 80), + (140, 121, 79), (138, 118, 76), (140, 121, 79), (143, 124, 82), + (145, 127, 86), (147, 130, 90), (152, 138, 99), (155, 145, 109), + (161, 152, 117), (162, 151, 114), (164, 150, 112), (164, 148, 109), + (165, 147, 106), (166, 147, 103), (166, 145, 102), (165, 143, 100), + (162, 140, 98), (152, 130, 89), (150, 126, 85), (148, 123, 81), + (144, 118, 73), (142, 115, 70), (144, 115, 72), (147, 120, 77), + (157, 132, 91), (164, 140, 97), (172, 148, 104), (176, 152, 108), + (181, 157, 112), (190, 166, 120), (199, 176, 130), (206, 184, 140), + (211, 191, 149), (221, 200, 152), (221, 200, 150), (221, 200, 148), + (219, 197, 142), (215, 190, 134), (208, 182, 127), (197, 173, 121), + (176, 152, 104), (163, 140, 94), (150, 129, 84), (144, 122, 78), + (138, 116, 73), (125, 103, 61), (112, 91, 53), (101, 81, 45), + (93, 72, 41), (77, 61, 35), (74, 59, 34), (72, 57, 33), + (69, 54, 32), (66, 52, 32), (66, 52, 33), (68, 54, 33), + (76, 59, 34), (77, 60, 34), (79, 62, 34), (79, 62, 33), + (81, 62, 32), (81, 61, 31), (81, 62, 32), (84, 65, 35), + (89, 69, 38), (103, 84, 46), (107, 87, 47), (112, 90, 49), + (119, 95, 51), (125, 99, 52), (128, 101, 54), (131, 104, 58), + (137, 113, 68), (139, 116, 70), (141, 119, 73), (145, 124, 79), + (149, 128, 83), (151, 130, 85), (150, 130, 87), (146, 128, 89), + (143, 127, 91), (139, 126, 92), (136, 126, 95), (135, 128, 100), + (136, 131, 104), (139, 134, 107), (143, 138, 110), (150, 143, 112), + (159, 150, 114), (160, 150, 114), (161, 151, 115), (160, 151, 116), + (161, 151, 115), (159, 149, 114), (159, 148, 111), (158, 146, 108), + (159, 144, 102), (158, 140, 96), (156, 135, 91), (153, 131, 85), + (148, 125, 81), (145, 120, 75), (139, 114, 70), (134, 108, 65), + (130, 104, 61), (126, 101, 59), (125, 99, 57), (125, 100, 58), + (128, 104, 62), (132, 108, 67), (136, 114, 74), (141, 121, 83), + (146, 129, 92), (151, 135, 100), (155, 142, 109), (164, 151, 118), + (171, 159, 125), (180, 167, 131), (190, 176, 136), (197, 182, 140), + (202, 185, 140), (202, 183, 136), (202, 180, 131), (198, 174, 124), + (193, 167, 115), (189, 160, 109), (184, 157, 105), (181, 153, 103), + (177, 150, 100), (174, 147, 97), (170, 144, 94), (166, 138, 89), + (162, 133, 85), (157, 129, 81), (153, 125, 81), (149, 122, 79), + (143, 117, 75), (136, 113, 73), (128, 105, 67), (119, 98, 61), + (109, 88, 53), (100, 79, 47), (92, 73, 43), (87, 68, 37), + (83, 65, 34), (81, 63, 33), (81, 63, 35), (80, 65, 39), + (80, 69, 44), (84, 74, 53), (91, 83, 62), (101, 93, 70), + (114, 106, 80), (127, 117, 89), (133, 125, 94), (138, 129, 98), + (140, 132, 101), (139, 131, 103), (136, 128, 100), (132, 125, 98) + ), + +// 407 040221-50 +((100, 53, 51), (104, 58, 56), (102, 56, 53), (101, 55, 51), + (97, 51, 48), (93, 47, 45), (92, 46, 45), (92, 45, 45), + (99, 49, 48), (99, 48, 48), (99, 47, 49), (99, 46, 48), + (100, 45, 48), (95, 43, 45), (91, 41, 43), (88, 39, 42), + (85, 37, 42), (80, 36, 40), (81, 37, 41), (82, 39, 42), + (88, 43, 46), (95, 48, 50), (100, 52, 53), (105, 56, 57), + (125, 67, 68), (128, 69, 69), (131, 71, 71), (129, 68, 70), + (127, 66, 70), (124, 63, 68), (121, 61, 67), (110, 57, 61), + (103, 54, 55), (90, 44, 50), (88, 44, 48), (87, 44, 46), + (86, 42, 44), (85, 41, 43), (84, 40, 42), (84, 39, 42), + (82, 36, 39), (82, 37, 40), (83, 38, 41), (89, 40, 43), + (95, 43, 45), (100, 45, 47), (105, 48, 50), (116, 57, 57), + (128, 69, 67), (153, 90, 90), (162, 96, 99), (172, 103, 109), + (169, 104, 111), (167, 106, 114), (164, 104, 113), (162, 103, 112), + (140, 84, 90), (126, 74, 78), (112, 64, 67), (100, 55, 55), + (89, 47, 44), (84, 44, 41), (80, 41, 38), (74, 37, 34), + (70, 33, 32), (66, 29, 30), (65, 29, 29), (64, 29, 28), + (64, 29, 28), (65, 30, 29), (65, 30, 29), (66, 31, 29), + (68, 32, 30), (68, 32, 30), (68, 33, 30), (67, 33, 30), + (67, 33, 31), (66, 33, 31), (66, 34, 31), (67, 34, 31), + (66, 34, 31), (67, 34, 31), (66, 33, 31), (66, 33, 31), + (66, 33, 30), (67, 33, 30), (67, 32, 30), (68, 32, 30), + (72, 35, 34), (78, 38, 37), (85, 42, 40), (89, 44, 43), + (94, 47, 46), (102, 51, 53), (108, 56, 59), (115, 60, 62), + (124, 65, 67), (138, 76, 80), (143, 81, 83), (149, 86, 87), + (153, 91, 90), (158, 96, 94), (168, 106, 105), (177, 113, 110), + (177, 111, 108), (174, 109, 107), (172, 107, 107), (168, 102, 104), + (164, 97, 101), (157, 89, 92), (150, 82, 87), (145, 78, 84), + (141, 75, 84), (145, 80, 89), (146, 83, 90), (147, 87, 92), + (149, 91, 96), (152, 97, 98), (154, 99, 100), (154, 98, 98), + (139, 85, 82), (129, 77, 73), (119, 70, 65), (113, 64, 59), + (108, 58, 53), (96, 47, 42), (84, 41, 36), (74, 38, 32), + (68, 34, 28), (64, 30, 24), (64, 30, 24), (65, 30, 25), + (67, 32, 27), (72, 33, 29), (79, 37, 33), (87, 44, 41), + (113, 62, 59), (128, 72, 69), (144, 82, 79), (152, 88, 85), + (161, 95, 92), (180, 111, 106), (200, 131, 124), (210, 141, 136), + (220, 145, 145), (238, 147, 159), (236, 147, 159), (234, 147, 160), + (231, 141, 159), (223, 122, 147), (219, 110, 140), (202, 102, 127), + (168, 80, 96), (160, 76, 90), (153, 73, 84), (134, 66, 73), + (118, 58, 58), (108, 51, 49), (101, 50, 47), (100, 50, 49), + (101, 51, 51), (109, 54, 57), (111, 55, 57), (113, 56, 58), + (113, 56, 60), (108, 55, 59), (103, 52, 56), (97, 49, 50), + (79, 39, 39), (74, 36, 36), (69, 34, 34), (62, 30, 28), + (57, 27, 24), (54, 26, 22), (53, 25, 21), (53, 24, 21), + (53, 24, 21), (54, 26, 22), (57, 27, 23), (60, 30, 25), + (64, 32, 28), (68, 35, 31), (72, 37, 33), (75, 39, 36), + (80, 41, 39), (81, 41, 39), (82, 42, 39), (82, 43, 38), + (80, 41, 39), (77, 39, 37), (75, 38, 35), (71, 37, 32), + (67, 34, 31), (63, 31, 29), (60, 29, 27), (57, 28, 25), + (56, 26, 24), (55, 25, 23), (54, 24, 23), (54, 24, 23), + (55, 24, 23), (56, 25, 23), (57, 25, 24), (58, 26, 25), + (59, 27, 26), (61, 28, 27), (63, 30, 28), (64, 31, 29), + (66, 32, 31), (67, 33, 32), (68, 34, 33), (69, 33, 33), + (70, 33, 33), (69, 33, 32), (68, 32, 31), (67, 30, 31), + (66, 28, 29), (64, 27, 27), (62, 26, 25), (60, 26, 24), + (59, 25, 23), (58, 25, 22), (57, 25, 22), (57, 26, 22), + (57, 27, 22), (57, 28, 23), (58, 28, 24), (59, 29, 26), + (61, 30, 28), (63, 31, 29), (65, 32, 30), (68, 33, 31), + (72, 34, 33), (75, 35, 35), (76, 36, 37), (77, 36, 37), + (78, 37, 36), (79, 37, 38), (79, 37, 39), (77, 36, 41), + (76, 36, 41), (75, 37, 41), (77, 37, 41), (79, 40, 43), + (85, 45, 48), (91, 52, 54), (100, 60, 61), (106, 65, 66), + (110, 71, 70), (113, 72, 70), (115, 73, 71), (112, 68, 68), + (106, 63, 64), (107, 64, 65), (110, 66, 65), (109, 63, 61) + ), + +// 408 040221-51 +((106, 94, 87), (105, 92, 84), (102, 88, 80), (100, 85, 77), + (93, 78, 70), (86, 72, 63), (87, 73, 64), (88, 75, 65), + (91, 78, 67), (93, 79, 67), (95, 80, 68), (99, 82, 69), + (103, 85, 71), (109, 92, 77), (116, 100, 84), (120, 103, 88), + (124, 107, 92), (137, 122, 107), (144, 128, 113), (151, 135, 120), + (156, 141, 127), (162, 148, 134), (164, 150, 135), (167, 152, 137), + (168, 153, 139), (164, 149, 136), (160, 146, 134), (156, 142, 129), + (152, 138, 125), (151, 136, 122), (150, 135, 120), (147, 132, 116), + (147, 131, 113), (146, 131, 111), (146, 131, 112), (147, 132, 113), + (147, 132, 113), (147, 133, 114), (147, 132, 113), (147, 132, 113), + (147, 131, 110), (145, 130, 110), (144, 130, 110), (140, 127, 109), + (137, 124, 108), (135, 122, 107), (134, 121, 106), (131, 117, 100), + (127, 111, 94), (119, 103, 85), (114, 99, 82), (110, 95, 79), + (109, 94, 78), (108, 94, 78), (107, 93, 77), (107, 93, 77), + (109, 95, 76), (106, 94, 75), (104, 93, 74), (101, 90, 73), + (98, 87, 72), (97, 87, 71), (97, 87, 71), (100, 89, 71), + (105, 92, 74), (121, 109, 88), (129, 117, 97), (137, 125, 106), + (139, 128, 109), (141, 131, 112), (145, 134, 114), (143, 133, 113), + (142, 131, 110), (138, 128, 108), (135, 126, 107), (131, 122, 104), + (128, 119, 102), (123, 115, 99), (119, 111, 96), (109, 102, 88), + (100, 92, 79), (80, 73, 62), (74, 66, 57), (69, 59, 53), + (67, 57, 51), (65, 55, 49), (61, 51, 47), (59, 48, 45), + (56, 45, 43), (56, 44, 43), (56, 43, 43), (56, 43, 43), + (56, 43, 43), (56, 42, 43), (56, 42, 42), (56, 43, 40), + (56, 43, 40), (57, 44, 40), (58, 45, 41), (60, 46, 42), + (61, 46, 42), (62, 47, 43), (64, 49, 43), (66, 50, 45), + (68, 52, 46), (68, 52, 46), (68, 52, 47), (67, 52, 46), + (67, 52, 46), (65, 50, 44), (62, 47, 41), (60, 44, 39), + (55, 40, 35), (49, 33, 29), (48, 33, 28), (47, 33, 27), + (46, 31, 25), (42, 30, 24), (41, 28, 22), (39, 26, 20), + (35, 22, 16), (36, 23, 17), (37, 25, 19), (38, 26, 20), + (39, 28, 22), (41, 31, 25), (43, 32, 27), (45, 33, 29), + (45, 34, 30), (47, 36, 31), (48, 37, 31), (49, 38, 32), + (51, 42, 35), (54, 44, 38), (57, 46, 41), (60, 48, 43), + (63, 51, 45), (65, 53, 46), (68, 56, 47), (70, 57, 47), + (72, 59, 48), (75, 62, 50), (78, 65, 52), (79, 66, 54), + (79, 67, 55), (79, 67, 54), (79, 66, 53), (79, 66, 53), + (79, 65, 52), (79, 65, 51), (79, 64, 49), (77, 63, 47), + (75, 61, 44), (74, 60, 44), (74, 60, 44), (74, 59, 44), + (74, 59, 45), (74, 59, 45), (74, 59, 45), (73, 58, 45), + (72, 58, 44), (71, 56, 44), (71, 56, 44), (71, 56, 45), + (72, 57, 47), (74, 59, 49), (76, 61, 53), (79, 64, 55), + (89, 74, 65), (93, 78, 69), (98, 83, 74), (107, 92, 83), + (117, 101, 91), (126, 111, 101), (135, 119, 109), (142, 127, 117), + (148, 134, 122), (156, 142, 128), (163, 149, 136), (171, 157, 144), + (178, 164, 151), (184, 170, 157), (187, 174, 162), (189, 175, 165), + (189, 175, 163), (189, 175, 163), (189, 176, 163), (190, 176, 164), + (195, 182, 169), (200, 187, 175), (204, 191, 180), (205, 193, 180), + (205, 193, 181), (206, 193, 181), (201, 189, 176), (202, 189, 176), + (204, 193, 180), (205, 193, 181), (203, 191, 178), (200, 188, 173), + (194, 182, 167), (183, 170, 154), (171, 157, 140), (160, 146, 130), + (152, 137, 123), (143, 128, 115), (134, 119, 107), (125, 110, 98), + (116, 102, 89), (107, 93, 79), (98, 85, 71), (93, 79, 64), + (89, 75, 60), (88, 73, 59), (88, 74, 59), (90, 75, 61), + (92, 77, 60), (95, 80, 62), (98, 84, 65), (102, 88, 67), + (107, 93, 70), (114, 100, 78), (124, 109, 88), (133, 117, 96), + (141, 125, 105), (148, 132, 113), (153, 138, 120), (158, 144, 125), + (161, 147, 130), (166, 153, 137), (172, 159, 144), (177, 164, 151), + (182, 169, 157), (187, 174, 163), (190, 178, 166), (191, 178, 167), + (191, 179, 167), (191, 179, 168), (191, 179, 167), (190, 178, 167), + (188, 176, 165), (183, 172, 160), (177, 166, 154), (171, 159, 148), + (163, 152, 141), (156, 145, 135), (152, 140, 130), (149, 137, 128), + (151, 139, 129), (148, 136, 127), (139, 126, 118), (129, 116, 107), + (119, 105, 97), (111, 96, 89), (101, 87, 80), (101, 89, 81) + ), + +// 409 040221-52 +((94, 102, 103), (98, 107, 121), (102, 111, 129), (106, 115, 137), + (110, 120, 146), (115, 125, 156), (116, 127, 159), (118, 129, 163), + (120, 132, 176), (115, 128, 175), (111, 125, 174), (104, 119, 167), + (98, 114, 161), (92, 108, 153), (86, 103, 146), (83, 101, 141), + (81, 99, 137), (74, 91, 118), (71, 87, 106), (69, 83, 95), + (68, 80, 88), (67, 78, 82), (67, 78, 82), (68, 79, 83), + (77, 87, 93), (83, 93, 101), (90, 99, 109), (98, 105, 115), + (107, 112, 122), (110, 115, 126), (113, 118, 130), (121, 125, 140), + (128, 132, 150), (141, 144, 171), (143, 147, 180), (145, 151, 189), + (145, 151, 193), (146, 152, 198), (146, 152, 198), (147, 153, 199), + (151, 157, 199), (153, 158, 199), (156, 160, 199), (155, 160, 199), + (154, 160, 199), (152, 159, 199), (151, 158, 200), (148, 156, 201), + (146, 153, 202), (145, 154, 202), (145, 154, 202), (145, 154, 202), + (143, 152, 197), (141, 150, 192), (138, 147, 188), (135, 144, 184), + (119, 129, 166), (111, 121, 156), (104, 114, 147), (95, 106, 139), + (87, 99, 131), (84, 96, 126), (81, 94, 121), (76, 89, 110), + (72, 85, 100), (65, 78, 84), (64, 77, 83), (64, 76, 82), + (64, 76, 85), (65, 77, 88), (68, 81, 95), (74, 86, 104), + (88, 99, 118), (96, 106, 127), (104, 114, 136), (112, 121, 146), + (120, 129, 157), (124, 132, 162), (128, 136, 168), (137, 144, 179), + (144, 151, 189), (158, 162, 200), (163, 166, 203), (169, 171, 206), + (170, 172, 207), (172, 174, 208), (176, 177, 209), (179, 179, 210), + (182, 181, 212), (180, 179, 211), (178, 178, 211), (175, 176, 210), + (173, 174, 210), (166, 169, 206), (159, 164, 201), (151, 156, 194), + (143, 149, 186), (128, 137, 168), (122, 131, 159), (117, 126, 151), + (114, 123, 146), (111, 121, 142), (106, 117, 135), (100, 112, 131), + (92, 106, 130), (91, 106, 131), (91, 107, 132), (93, 108, 133), + (95, 110, 135), (102, 115, 138), (110, 122, 141), (118, 128, 146), + (125, 134, 153), (138, 146, 172), (140, 148, 177), (143, 150, 182), + (147, 155, 192), (153, 161, 201), (160, 166, 206), (165, 170, 208), + (173, 175, 207), (173, 175, 204), (174, 175, 201), (171, 172, 198), + (169, 170, 196), (164, 166, 192), (158, 161, 189), (155, 158, 187), + (152, 156, 185), (150, 154, 185), (151, 155, 184), (153, 157, 184), + (152, 155, 182), (149, 153, 180), (145, 150, 177), (141, 147, 176), + (137, 143, 174), (139, 145, 177), (141, 147, 180), (144, 149, 182), + (148, 152, 184), (154, 157, 187), (158, 160, 190), (161, 163, 194), + (162, 164, 195), (156, 159, 193), (153, 157, 191), (151, 155, 190), + (146, 151, 185), (140, 145, 178), (133, 139, 169), (127, 134, 160), + (116, 123, 139), (112, 119, 134), (108, 115, 130), (99, 107, 120), + (91, 100, 110), (82, 91, 100), (73, 83, 89), (64, 75, 78), + (57, 68, 67), (47, 58, 47), (45, 56, 43), (44, 55, 40), + (43, 54, 35), (42, 53, 33), (42, 53, 32), (43, 54, 33), + (45, 57, 37), (46, 57, 38), (47, 58, 40), (48, 60, 46), + (51, 64, 54), (57, 70, 63), (64, 76, 73), (73, 84, 84), + (81, 92, 96), (89, 99, 107), (96, 106, 118), (101, 110, 129), + (103, 115, 140), (107, 120, 152), (111, 124, 163), (115, 129, 173), + (121, 136, 185), (122, 137, 184), (124, 138, 183), (124, 137, 178), + (120, 133, 170), (114, 127, 160), (106, 121, 150), (98, 114, 142), + (90, 106, 133), (82, 99, 126), (76, 93, 117), (71, 88, 109), + (66, 82, 99), (62, 78, 88), (60, 75, 77), (60, 73, 69), + (60, 72, 63), (59, 72, 60), (59, 70, 59), (59, 71, 62), + (59, 71, 65), (59, 72, 71), (61, 75, 78), (64, 78, 86), + (67, 81, 92), (71, 86, 98), (75, 89, 102), (78, 93, 106), + (80, 95, 111), (80, 95, 116), (81, 97, 125), (81, 99, 136), + (82, 101, 145), (82, 102, 151), (81, 102, 156), (80, 100, 155), + (79, 100, 151), (76, 96, 142), (74, 93, 134), (73, 91, 128), + (73, 91, 123), (74, 91, 118), (74, 90, 114), (74, 89, 109), + (73, 88, 102), (70, 85, 92), (67, 81, 79), (65, 77, 68), + (63, 75, 59), (62, 74, 52), (61, 74, 48), (63, 74, 46), + (64, 75, 45), (64, 76, 44), (64, 76, 43), (65, 76, 42), + (65, 77, 41), (66, 78, 40), (66, 78, 40), (65, 78, 39), + (65, 77, 40), (64, 77, 41), (63, 76, 43), (62, 75, 46), + (61, 74, 51), (63, 76, 51), (66, 78, 53), (72, 82, 55), + (77, 86, 62), (82, 90, 70), (87, 95, 79), (92, 99, 88) + ), + +// 410 040221-53 +((44, 119, 111), (47, 122, 116), (43, 128, 117), (40, 134, 119), + (41, 136, 123), (42, 139, 127), (46, 139, 132), (51, 140, 138), + (58, 152, 158), (65, 158, 168), (73, 164, 179), (83, 164, 186), + (94, 164, 194), (98, 166, 197), (102, 168, 201), (103, 170, 203), + (105, 172, 205), (111, 180, 216), (121, 185, 217), (132, 190, 218), + (143, 199, 222), (154, 208, 227), (150, 211, 231), (147, 215, 235), + (144, 213, 234), (149, 211, 231), (154, 209, 228), (141, 206, 227), + (128, 204, 226), (120, 198, 222), (112, 193, 218), (99, 181, 209), + (97, 169, 200), (84, 153, 180), (75, 144, 168), (67, 136, 156), + (60, 126, 142), (53, 117, 128), (51, 112, 121), (49, 107, 114), + (43, 84, 98), (43, 81, 98), (44, 79, 99), (50, 85, 104), + (57, 92, 110), (62, 94, 115), (67, 97, 121), (78, 97, 137), + (84, 98, 148), (88, 106, 152), (89, 106, 151), (91, 106, 151), + (91, 101, 151), (91, 97, 152), (87, 96, 151), (84, 96, 151), + (70, 100, 138), (65, 95, 134), (61, 90, 131), (58, 88, 131), + (55, 87, 132), (54, 86, 129), (53, 86, 127), (42, 84, 117), + (38, 79, 108), (37, 74, 103), (38, 76, 103), (40, 79, 104), + (41, 84, 106), (42, 90, 109), (45, 101, 117), (50, 114, 128), + (65, 129, 149), (72, 136, 158), (79, 144, 168), (84, 150, 177), + (90, 156, 186), (92, 157, 188), (95, 159, 191), (98, 160, 194), + (100, 161, 195), (100, 161, 195), (99, 159, 193), (98, 158, 191), + (97, 157, 189), (96, 156, 188), (92, 154, 184), (89, 153, 181), + (81, 146, 171), (73, 140, 162), (66, 134, 154), (61, 131, 149), + (57, 129, 144), (47, 123, 135), (42, 118, 127), (37, 114, 120), + (34, 109, 115), (31, 108, 113), (37, 113, 120), (43, 118, 127), + (47, 121, 132), (52, 124, 137), (64, 133, 150), (73, 142, 163), + (94, 159, 189), (99, 164, 196), (105, 170, 204), (105, 171, 205), + (106, 173, 207), (107, 174, 209), (106, 175, 209), (104, 174, 207), + (100, 170, 202), (87, 159, 185), (85, 156, 181), (83, 153, 178), + (78, 149, 172), (78, 143, 171), (78, 139, 171), (82, 132, 171), + (82, 122, 163), (79, 116, 158), (76, 110, 153), (75, 107, 151), + (75, 105, 149), (75, 102, 145), (72, 100, 138), (69, 102, 135), + (62, 106, 133), (59, 118, 134), (60, 121, 136), (62, 124, 139), + (68, 131, 148), (73, 143, 161), (79, 152, 173), (85, 159, 183), + (94, 165, 193), (95, 165, 195), (97, 166, 197), (97, 166, 196), + (98, 166, 196), (97, 165, 195), (98, 163, 194), (97, 163, 194), + (97, 162, 194), (97, 161, 192), (97, 160, 192), (98, 160, 192), + (97, 159, 191), (97, 158, 189), (93, 155, 185), (89, 150, 178), + (74, 134, 154), (70, 128, 147), (66, 122, 140), (56, 112, 128), + (49, 103, 116), (43, 99, 110), (42, 97, 107), (41, 98, 107), + (43, 101, 112), (53, 114, 128), (58, 118, 135), (64, 123, 142), + (75, 136, 156), (90, 142, 173), (99, 145, 184), (107, 146, 190), + (108, 141, 173), (109, 139, 168), (110, 137, 164), (110, 129, 147), + (109, 121, 137), (104, 111, 132), (97, 109, 123), (91, 114, 125), + (91, 121, 124), (91, 128, 126), (94, 133, 138), (95, 137, 150), + (96, 145, 168), (99, 155, 186), (100, 165, 196), (103, 173, 200), + (97, 171, 194), (94, 168, 190), (92, 165, 187), (86, 156, 181), + (79, 152, 171), (74, 147, 162), (68, 143, 155), (64, 136, 148), + (61, 130, 145), (56, 125, 141), (51, 123, 136), (43, 123, 133), + (37, 120, 127), (32, 116, 121), (31, 109, 112), (26, 100, 99), + (19, 95, 90), (12, 91, 80), (4, 87, 74), (3, 83, 68), + (8, 75, 62), (14, 71, 58), (19, 70, 55), (23, 69, 54), + (28, 73, 56), (33, 74, 59), (43, 77, 65), (52, 80, 73), + (60, 80, 81), (67, 86, 90), (69, 94, 101), (72, 103, 111), + (74, 111, 123), (75, 114, 131), (74, 117, 139), (68, 119, 145), + (58, 118, 142), (51, 116, 136), (43, 107, 124), (37, 96, 110), + (28, 85, 100), (18, 71, 88), (11, 61, 80), (10, 52, 74), + (13, 49, 68), (18, 47, 69), (24, 47, 73), (29, 47, 77), + (36, 53, 85), (39, 61, 92), (41, 71, 98), (44, 81, 104), + (45, 85, 107), (46, 90, 108), (44, 94, 108), (37, 95, 106), + (30, 95, 101), (25, 93, 96), (23, 92, 94), (22, 93, 95), + (17, 96, 96), (14, 98, 99), (10, 101, 99), (7, 103, 99), + (8, 107, 102), (12, 111, 107), (16, 115, 114), (21, 120, 120), + (25, 122, 126), (31, 124, 124), (36, 123, 120), (41, 120, 115) + ), + +// 411 040221-54 +((187, 125, 54), (191, 123, 49), (193, 132, 52), (195, 141, 56), + (197, 147, 57), (199, 153, 59), (199, 156, 60), (199, 160, 61), + (192, 156, 68), (182, 156, 75), (173, 157, 83), (162, 155, 91), + (151, 153, 99), (132, 141, 101), (113, 129, 104), (101, 120, 103), + (89, 112, 103), (47, 68, 93), (38, 58, 88), (30, 48, 83), + (31, 46, 79), (32, 45, 75), (36, 45, 72), (40, 46, 69), + (63, 54, 54), (77, 63, 52), (92, 72, 50), (107, 90, 58), + (123, 108, 67), (132, 115, 71), (141, 122, 75), (159, 136, 77), + (178, 143, 78), (203, 152, 57), (206, 152, 54), (209, 152, 52), + (205, 146, 51), (201, 140, 51), (197, 133, 48), (193, 127, 45), + (183, 114, 32), (176, 109, 30), (169, 105, 28), (151, 95, 27), + (133, 85, 27), (122, 79, 27), (111, 74, 27), (93, 67, 28), + (80, 60, 31), (63, 51, 31), (59, 50, 29), (55, 49, 27), + (54, 49, 25), (54, 49, 24), (55, 51, 26), (57, 53, 29), + (75, 69, 42), (98, 86, 52), (121, 103, 63), (141, 121, 71), + (162, 140, 80), (166, 145, 85), (171, 151, 90), (175, 160, 101), + (178, 167, 116), (174, 155, 119), (163, 143, 109), (152, 132, 100), + (142, 125, 95), (132, 118, 90), (112, 103, 85), (92, 89, 83), + (54, 50, 78), (38, 36, 75), (22, 22, 72), (15, 18, 77), + (8, 15, 82), (7, 16, 87), (6, 17, 93), (6, 23, 109), + (10, 31, 121), (20, 38, 129), (22, 39, 125), (24, 41, 122), + (23, 41, 118), (23, 41, 115), (23, 42, 107), (22, 41, 98), + (24, 33, 67), (21, 26, 51), (18, 20, 35), (15, 16, 29), + (13, 13, 23), (8, 7, 16), (4, 4, 13), (4, 3, 15), + (5, 5, 21), (4, 7, 33), (3, 6, 34), (3, 5, 35), + (4, 5, 34), (6, 5, 34), (12, 8, 38), (22, 14, 40), + (48, 23, 41), (57, 28, 39), (66, 33, 37), (69, 36, 37), + (72, 39, 37), (80, 51, 42), (85, 58, 43), (93, 65, 48), + (99, 69, 54), (105, 78, 72), (104, 82, 80), (104, 87, 88), + (96, 94, 103), (92, 101, 118), (90, 104, 128), (89, 108, 139), + (101, 114, 153), (100, 116, 157), (100, 118, 161), (98, 117, 162), + (96, 116, 163), (92, 114, 164), (89, 113, 159), (94, 111, 153), + (99, 112, 144), (107, 116, 133), (109, 117, 133), (111, 118, 133), + (113, 122, 135), (114, 126, 137), (124, 134, 139), (139, 147, 137), + (170, 171, 147), (169, 175, 155), (169, 180, 163), (162, 177, 168), + (156, 175, 174), (140, 169, 180), (130, 162, 182), (120, 150, 182), + (115, 143, 179), (90, 112, 163), (82, 105, 160), (74, 99, 157), + (61, 86, 147), (51, 74, 138), (53, 69, 129), (54, 68, 117), + (71, 67, 91), (76, 66, 82), (82, 66, 74), (91, 67, 60), + (102, 67, 48), (111, 68, 39), (119, 78, 32), (128, 87, 31), + (139, 94, 30), (146, 106, 43), (147, 106, 48), (149, 106, 53), + (151, 113, 61), (150, 120, 72), (149, 125, 80), (144, 130, 89), + (125, 132, 116), (121, 132, 120), (118, 132, 125), (112, 132, 133), + (108, 129, 134), (102, 123, 133), (95, 119, 134), (88, 112, 137), + (82, 110, 140), (85, 114, 143), (92, 123, 147), (100, 132, 150), + (109, 140, 160), (114, 145, 172), (116, 150, 179), (122, 157, 185), + (140, 177, 181), (145, 181, 178), (150, 186, 176), (155, 187, 174), + (150, 180, 166), (138, 167, 157), (127, 152, 146), (115, 139, 135), + (104, 127, 128), (96, 117, 125), (80, 103, 127), (62, 88, 128), + (46, 71, 128), (30, 55, 123), (18, 40, 119), (14, 32, 113), + (11, 28, 108), (9, 25, 102), (12, 26, 96), (20, 28, 87), + (34, 31, 76), (51, 36, 65), (70, 47, 58), (86, 58, 55), + (96, 72, 57), (109, 85, 63), (118, 98, 74), (124, 102, 84), + (131, 109, 97), (131, 113, 113), (123, 114, 131), (115, 113, 144), + (105, 114, 157), (93, 107, 159), (83, 100, 151), (74, 91, 142), + (62, 79, 130), (51, 64, 115), (46, 56, 102), (41, 49, 91), + (42, 47, 80), (49, 52, 74), (56, 60, 74), (63, 66, 76), + (70, 74, 80), (75, 82, 90), (78, 90, 102), (83, 99, 116), + (85, 110, 137), (93, 123, 160), (103, 139, 178), (114, 150, 193), + (124, 163, 204), (136, 174, 205), (141, 180, 207), (148, 184, 209), + (153, 189, 212), (159, 190, 214), (161, 191, 214), (168, 194, 205), + (177, 198, 195), (186, 199, 178), (195, 199, 164), (205, 198, 150), + (207, 190, 139), (205, 176, 125), (203, 170, 114), (205, 167, 103), + (203, 159, 92), (202, 157, 82), (199, 152, 74), (194, 139, 64) + ), + +// 412 040221-55 +((111, 80, 54), (113, 78, 51), (112, 77, 49), (111, 76, 48), + (107, 71, 44), (103, 66, 40), (105, 68, 42), (107, 71, 44), + (108, 77, 49), (106, 78, 51), (105, 80, 54), (107, 84, 58), + (110, 88, 63), (112, 93, 66), (115, 99, 69), (119, 101, 71), + (124, 104, 74), (132, 109, 75), (135, 111, 78), (139, 113, 82), + (141, 119, 85), (144, 126, 89), (148, 127, 92), (152, 129, 96), + (162, 136, 98), (162, 132, 97), (163, 129, 96), (163, 134, 101), + (163, 139, 107), (166, 142, 111), (169, 145, 116), (174, 154, 125), + (181, 163, 131), (182, 161, 125), (171, 153, 116), (161, 145, 107), + (148, 132, 97), (136, 119, 88), (130, 112, 82), (125, 105, 77), + (102, 79, 55), (87, 66, 43), (72, 53, 31), (58, 41, 21), + (44, 29, 12), (37, 24, 8), (31, 19, 4), (22, 11, 2), + (16, 6, 0), (13, 1, 1), (15, 2, 1), (17, 4, 1), + (22, 6, 1), (27, 8, 2), (30, 9, 2), (34, 10, 2), + (42, 15, 5), (44, 18, 5), (47, 22, 6), (50, 24, 6), + (53, 27, 6), (56, 27, 5), (59, 28, 5), (63, 27, 5), + (68, 27, 5), (72, 30, 6), (73, 34, 8), (74, 39, 10), + (76, 43, 13), (79, 48, 17), (87, 56, 25), (101, 65, 35), + (127, 81, 53), (132, 85, 55), (138, 90, 57), (135, 91, 57), + (133, 92, 57), (132, 92, 56), (132, 93, 56), (131, 93, 59), + (131, 91, 58), (127, 80, 52), (114, 69, 43), (102, 59, 34), + (94, 53, 28), (87, 48, 23), (74, 37, 15), (65, 26, 7), + (61, 14, 1), (62, 13, 0), (63, 12, 0), (63, 12, 0), + (63, 12, 0), (62, 12, 0), (60, 12, 0), (58, 11, 0), + (58, 11, 1), (64, 13, 3), (70, 18, 5), (77, 24, 8), + (79, 28, 11), (82, 33, 15), (88, 41, 22), (90, 47, 29), + (85, 50, 38), (80, 49, 37), (76, 48, 36), (73, 47, 36), + (71, 47, 37), (70, 47, 37), (69, 47, 38), (69, 48, 38), + (65, 45, 39), (48, 32, 29), (42, 28, 25), (37, 25, 22), + (28, 19, 16), (22, 14, 11), (22, 12, 8), (21, 11, 6), + (19, 9, 6), (17, 8, 5), (15, 8, 4), (13, 9, 4), + (12, 10, 4), (14, 11, 4), (16, 12, 4), (20, 14, 5), + (27, 15, 6), (46, 19, 6), (51, 23, 9), (57, 27, 12), + (74, 39, 20), (90, 54, 32), (108, 74, 50), (126, 94, 70), + (161, 128, 99), (176, 141, 111), (192, 154, 124), (195, 157, 128), + (198, 160, 132), (204, 170, 143), (205, 177, 157), (204, 183, 167), + (197, 184, 170), (193, 182, 168), (189, 176, 164), (186, 171, 160), + (176, 160, 148), (162, 143, 134), (148, 127, 120), (127, 108, 104), + (101, 82, 78), (97, 77, 72), (94, 72, 66), (88, 66, 57), + (81, 58, 48), (74, 51, 39), (63, 41, 30), (50, 30, 22), + (40, 20, 14), (29, 9, 3), (28, 8, 2), (27, 7, 1), + (27, 8, 0), (27, 8, 0), (29, 9, 0), (32, 10, 0), + (41, 17, 2), (44, 19, 3), (48, 21, 4), (53, 26, 6), + (56, 31, 10), (59, 34, 12), (59, 36, 15), (58, 37, 15), + (58, 39, 14), (58, 39, 14), (60, 39, 13), (61, 40, 14), + (62, 41, 15), (62, 42, 18), (59, 43, 22), (56, 45, 25), + (49, 43, 27), (47, 41, 25), (46, 40, 24), (43, 36, 21), + (42, 32, 18), (39, 29, 17), (38, 29, 17), (38, 28, 19), + (37, 29, 20), (38, 29, 21), (39, 29, 20), (41, 29, 17), + (44, 31, 16), (47, 35, 17), (51, 39, 22), (56, 45, 29), + (63, 51, 38), (70, 57, 45), (74, 61, 48), (77, 62, 49), + (78, 63, 48), (77, 63, 48), (76, 63, 47), (74, 62, 48), + (73, 59, 48), (71, 55, 47), (70, 49, 43), (71, 42, 36), + (70, 35, 28), (70, 28, 20), (71, 23, 13), (74, 19, 8), + (77, 17, 5), (81, 16, 5), (85, 17, 3), (90, 18, 3), + (95, 21, 3), (101, 28, 6), (105, 36, 13), (107, 43, 19), + (108, 49, 25), (107, 56, 32), (104, 58, 38), (99, 57, 41), + (96, 61, 44), (95, 68, 51), (98, 76, 59), (106, 86, 69), + (118, 101, 82), (130, 116, 97), (139, 127, 111), (146, 135, 121), + (148, 140, 127), (148, 142, 130), (147, 140, 130), (151, 141, 129), + (156, 141, 124), (157, 140, 120), (158, 138, 115), (152, 132, 109), + (141, 122, 99), (124, 109, 90), (112, 95, 79), (103, 82, 67), + (95, 74, 56), (96, 69, 51), (89, 58, 39), (87, 54, 32), + (86, 54, 32), (88, 56, 34), (93, 58, 37), (95, 65, 42) + ), + +// 413 040221-56 +((0, 0, 0), (0, 0, 0), (1, 1, 1), (2, 2, 2), + (4, 4, 4), (6, 6, 7), (8, 7, 9), (10, 9, 11), + (25, 20, 24), (32, 26, 33), (40, 33, 42), (53, 40, 52), + (66, 47, 63), (72, 54, 69), (79, 61, 75), (80, 62, 77), + (82, 63, 79), (77, 61, 72), (65, 53, 61), (54, 46, 50), + (44, 36, 40), (34, 26, 30), (28, 21, 25), (23, 17, 20), + (9, 7, 10), (6, 4, 7), (4, 2, 5), (3, 2, 4), + (2, 2, 4), (1, 1, 3), (1, 1, 3), (1, 1, 1), + (1, 1, 1), (0, 0, 0), (2, 1, 1), (5, 2, 3), + (10, 7, 8), (16, 13, 14), (21, 17, 19), (26, 21, 24), + (53, 47, 52), (69, 59, 66), (85, 71, 80), (98, 80, 93), + (112, 90, 106), (118, 95, 109), (124, 101, 112), (132, 102, 118), + (136, 103, 120), (137, 104, 116), (125, 99, 110), (114, 94, 105), + (103, 84, 97), (92, 74, 90), (86, 70, 87), (80, 67, 85), + (74, 58, 75), (76, 59, 78), (79, 60, 81), (88, 70, 88), + (98, 80, 95), (106, 85, 101), (114, 91, 108), (137, 107, 121), + (156, 127, 141), (202, 173, 185), (214, 186, 194), (227, 200, 203), + (223, 197, 205), (219, 195, 207), (211, 188, 194), (196, 171, 174), + (148, 128, 146), (136, 117, 133), (125, 107, 121), (116, 99, 113), + (108, 91, 106), (105, 87, 102), (102, 83, 99), (96, 82, 92), + (89, 77, 84), (74, 60, 71), (65, 54, 64), (56, 49, 58), + (54, 46, 56), (53, 43, 55), (51, 39, 57), (51, 39, 57), + (56, 40, 59), (56, 40, 59), (57, 40, 59), (56, 39, 56), + (56, 38, 53), (52, 34, 45), (45, 30, 42), (38, 26, 36), + (34, 21, 27), (21, 8, 19), (19, 6, 16), (17, 4, 13), + (16, 4, 12), (15, 5, 12), (17, 9, 13), (24, 14, 18), + (45, 32, 34), (56, 40, 43), (67, 48, 52), (72, 51, 57), + (77, 55, 62), (85, 61, 73), (88, 65, 76), (91, 71, 81), + (98, 78, 90), (111, 92, 109), (115, 97, 114), (119, 102, 119), + (128, 113, 130), (138, 121, 137), (143, 124, 142), (147, 128, 145), + (155, 131, 144), (155, 130, 144), (156, 130, 144), (163, 132, 143), + (170, 134, 143), (184, 150, 152), (188, 158, 167), (197, 160, 168), + (201, 164, 160), (177, 145, 147), (166, 135, 134), (155, 125, 122), + (132, 102, 96), (111, 86, 86), (97, 75, 74), (77, 58, 67), + (66, 55, 67), (65, 53, 67), (64, 51, 68), (66, 51, 68), + (68, 52, 69), (74, 55, 70), (78, 56, 72), (74, 53, 67), + (70, 50, 62), (48, 38, 45), (42, 33, 39), (36, 28, 34), + (25, 21, 24), (16, 15, 17), (10, 9, 11), (6, 6, 6), + (1, 1, 2), (0, 1, 1), (0, 1, 1), (0, 0, 1), + (1, 1, 2), (3, 3, 3), (5, 5, 5), (9, 9, 9), + (14, 13, 14), (25, 21, 28), (28, 23, 31), (32, 25, 34), + (37, 29, 41), (39, 31, 45), (40, 30, 44), (40, 28, 46), + (30, 21, 34), (28, 17, 31), (26, 13, 29), (20, 8, 21), + (14, 5, 14), (12, 2, 8), (8, 1, 4), (5, 1, 3), + (4, 0, 1), (3, 1, 1), (1, 1, 1), (1, 1, 1), + (1, 1, 1), (1, 1, 1), (2, 2, 2), (4, 3, 4), + (11, 7, 10), (13, 9, 12), (16, 11, 14), (26, 15, 19), + (36, 23, 29), (43, 29, 38), (51, 33, 45), (59, 42, 56), + (63, 48, 60), (62, 48, 60), (58, 46, 60), (55, 44, 56), + (48, 40, 48), (39, 32, 39), (29, 24, 32), (22, 18, 24), + (15, 13, 16), (8, 8, 10), (4, 4, 5), (2, 2, 2), + (1, 1, 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, 1, 1), (1, 2, 2), (4, 3, 5), + (8, 8, 10), (14, 13, 15), (20, 16, 23), (28, 21, 32), + (40, 29, 42), (51, 36, 52), (59, 43, 63), (70, 52, 76), + (82, 61, 84), (88, 66, 89), (90, 73, 95), (93, 76, 95), + (89, 71, 90), (80, 64, 83), (70, 58, 72), (56, 46, 59), + (43, 34, 48), (33, 24, 34), (22, 15, 21), (13, 10, 14), + (8, 5, 7), (5, 2, 3), (2, 2, 2), (1, 0, 1), + (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) + ), + +// 414 040221-57 +((22, 26, 25), (21, 24, 24), (16, 18, 18), (12, 12, 12), + (8, 7, 7), (4, 3, 3), (2, 1, 2), (1, 0, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (1, 0, 0), (3, 1, 0), (3, 1, 0), + (4, 1, 0), (17, 1, 2), (27, 2, 6), (38, 4, 10), + (41, 11, 14), (44, 19, 19), (46, 23, 19), (48, 27, 20), + (60, 47, 29), (55, 51, 36), (51, 55, 43), (52, 58, 41), + (53, 62, 40), (52, 59, 42), (52, 57, 44), (48, 47, 47), + (43, 43, 43), (33, 33, 33), (28, 28, 28), (24, 24, 23), + (19, 20, 18), (15, 16, 14), (13, 14, 13), (12, 12, 12), + (8, 6, 7), (5, 4, 5), (3, 2, 3), (2, 1, 2), + (2, 0, 1), (1, 0, 0), (1, 0, 0), (1, 0, 0), + (0, 1, 0), (0, 2, 0), (0, 2, 1), (0, 2, 2), + (1, 3, 5), (2, 5, 9), (4, 6, 10), (6, 8, 12), + (15, 16, 20), (22, 22, 26), (29, 29, 33), (36, 36, 37), + (43, 44, 42), (45, 46, 44), (47, 48, 46), (52, 51, 49), + (54, 55, 53), (59, 60, 60), (63, 67, 66), (67, 75, 73), + (70, 81, 77), (74, 87, 81), (87, 100, 82), (104, 110, 81), + (126, 131, 82), (126, 133, 87), (127, 136, 92), (131, 131, 88), + (135, 126, 84), (130, 124, 86), (126, 122, 89), (121, 126, 109), + (122, 133, 125), (154, 159, 151), (160, 161, 153), (166, 163, 155), + (173, 165, 152), (181, 168, 150), (184, 172, 150), (177, 164, 144), + (142, 121, 111), (125, 108, 97), (108, 96, 83), (98, 91, 80), + (88, 86, 78), (72, 73, 70), (57, 58, 57), (44, 47, 46), + (36, 38, 37), (23, 25, 24), (20, 22, 21), (18, 19, 18), + (18, 19, 18), (19, 19, 19), (23, 23, 23), (30, 30, 30), + (52, 53, 52), (78, 72, 61), (104, 91, 71), (119, 102, 75), + (135, 114, 80), (154, 132, 98), (170, 149, 109), (179, 161, 108), + (177, 172, 101), (147, 149, 104), (138, 140, 99), (130, 131, 95), + (101, 119, 80), (74, 98, 65), (55, 75, 59), (52, 57, 54), + (47, 47, 47), (51, 48, 47), (56, 50, 47), (66, 54, 49), + (77, 59, 52), (104, 68, 62), (123, 72, 85), (126, 68, 91), + (128, 70, 91), (133, 80, 94), (125, 77, 95), (117, 75, 97), + (95, 71, 93), (79, 70, 76), (74, 76, 73), (72, 81, 74), + (69, 84, 77), (73, 81, 76), (78, 79, 75), (78, 77, 74), + (78, 76, 73), (69, 71, 70), (62, 64, 63), (55, 57, 56), + (52, 51, 51), (42, 42, 41), (40, 40, 39), (38, 38, 37), + (33, 34, 32), (30, 30, 29), (26, 26, 26), (21, 22, 22), + (11, 14, 14), (10, 12, 12), (9, 10, 11), (6, 7, 8), + (4, 6, 6), (2, 3, 4), (1, 1, 2), (0, 0, 1), + (0, 0, 1), (2, 2, 2), (3, 3, 2), (4, 4, 3), + (4, 10, 2), (7, 13, 5), (9, 15, 8), (13, 15, 13), + (17, 23, 13), (17, 23, 14), (18, 23, 15), (18, 19, 18), + (16, 19, 18), (16, 17, 15), (15, 15, 13), (12, 12, 10), + (10, 9, 8), (8, 7, 6), (8, 5, 4), (7, 3, 2), + (7, 2, 1), (6, 1, 3), (8, 0, 5), (8, 1, 6), + (5, 2, 5), (5, 2, 6), (6, 2, 7), (6, 2, 8), + (4, 3, 7), (2, 3, 4), (1, 3, 3), (2, 3, 4), + (3, 5, 5), (5, 7, 6), (8, 10, 7), (12, 12, 10), + (20, 12, 11), (25, 13, 10), (26, 13, 10), (22, 14, 10), + (24, 12, 11), (25, 11, 8), (20, 9, 9), (12, 10, 8), + (6, 8, 9), (4, 8, 7), (3, 8, 9), (4, 10, 11), + (5, 12, 12), (7, 14, 12), (8, 17, 15), (10, 22, 23), + (13, 24, 27), (19, 26, 29), (24, 32, 30), (35, 43, 33), + (44, 46, 32), (61, 44, 32), (73, 35, 26), (94, 40, 21), + (106, 43, 13), (121, 56, 21), (117, 54, 33), (116, 56, 40), + (107, 51, 39), (103, 63, 43), (87, 67, 52), (70, 67, 58), + (54, 57, 56), (45, 51, 49), (38, 43, 42), (33, 37, 36), + (30, 33, 32), (31, 27, 30), (37, 23, 32), (44, 18, 40), + (55, 23, 52), (76, 28, 61), (101, 39, 69), (118, 45, 69), + (121, 53, 77), (122, 58, 81), (120, 64, 82), (117, 67, 71), + (101, 65, 60), (78, 57, 51), (55, 46, 45), (37, 36, 36), + (26, 27, 28), (19, 21, 21), (15, 18, 17), (13, 17, 16), + (15, 18, 17), (19, 24, 23), (22, 27, 26), (22, 28, 27) + ), + +// 415 040221-58 +((72, 172, 134), (74, 175, 141), (69, 174, 143), (64, 173, 146), + (63, 183, 154), (63, 193, 163), (64, 198, 163), (66, 204, 164), + (65, 210, 166), (59, 204, 162), (53, 198, 158), (48, 189, 155), + (44, 181, 152), (43, 172, 153), (43, 163, 154), (42, 156, 153), + (42, 149, 153), (31, 130, 147), (26, 117, 138), (22, 104, 130), + (23, 87, 122), (24, 71, 115), (24, 64, 114), (24, 57, 113), + (30, 46, 103), (35, 46, 98), (41, 47, 93), (52, 47, 90), + (63, 47, 88), (67, 48, 87), (71, 50, 86), (78, 53, 85), + (84, 55, 84), (93, 72, 83), (95, 79, 82), (98, 86, 81), + (94, 94, 82), (91, 103, 84), (88, 108, 85), (85, 114, 87), + (76, 133, 94), (75, 136, 95), (74, 139, 96), (72, 135, 95), + (70, 131, 94), (68, 127, 95), (67, 124, 97), (66, 118, 99), + (65, 109, 98), (67, 94, 91), (68, 84, 86), (70, 74, 82), + (68, 64, 81), (66, 54, 81), (64, 50, 81), (63, 46, 81), + (54, 40, 80), (52, 40, 78), (50, 40, 76), (46, 39, 73), + (42, 38, 71), (39, 38, 70), (37, 38, 70), (32, 38, 70), + (26, 36, 70), (22, 40, 70), (20, 41, 70), (18, 43, 71), + (18, 45, 71), (18, 47, 72), (18, 47, 75), (19, 49, 80), + (24, 52, 90), (25, 53, 92), (26, 55, 95), (27, 55, 95), + (28, 55, 95), (28, 54, 94), (28, 53, 94), (28, 50, 91), + (26, 46, 87), (23, 40, 73), (20, 38, 68), (18, 36, 63), + (17, 34, 61), (17, 33, 59), (13, 27, 57), (11, 22, 52), + (7, 15, 47), (9, 16, 48), (11, 17, 50), (12, 17, 52), + (14, 17, 55), (17, 17, 59), (19, 17, 62), (21, 18, 64), + (23, 21, 67), (37, 30, 69), (51, 37, 70), (65, 44, 72), + (72, 52, 74), (80, 61, 76), (92, 79, 84), (101, 102, 97), + (117, 144, 128), (129, 160, 139), (141, 177, 150), (148, 185, 155), + (155, 193, 160), (164, 212, 175), (167, 230, 189), (164, 243, 205), + (157, 244, 211), (136, 226, 205), (131, 216, 199), (126, 206, 193), + (115, 186, 178), (105, 167, 167), (95, 148, 152), (82, 132, 140), + (69, 96, 111), (66, 79, 96), (64, 62, 82), (65, 56, 76), + (67, 50, 71), (69, 43, 66), (74, 43, 63), (82, 44, 61), + (91, 47, 64), (104, 63, 67), (105, 68, 68), (106, 73, 69), + (109, 85, 72), (109, 97, 73), (107, 106, 78), (107, 112, 83), + (96, 138, 102), (95, 154, 112), (95, 170, 122), (94, 177, 127), + (94, 185, 133), (96, 194, 142), (99, 202, 152), (95, 208, 160), + (94, 215, 168), (82, 222, 180), (79, 222, 180), (76, 223, 180), + (72, 221, 179), (68, 212, 175), (65, 200, 166), (57, 185, 158), + (36, 144, 133), (31, 136, 126), (26, 128, 119), (20, 112, 107), + (18, 96, 93), (15, 82, 85), (15, 70, 80), (13, 61, 76), + (13, 60, 76), (27, 69, 75), (31, 69, 74), (35, 69, 74), + (44, 70, 77), (49, 70, 77), (53, 73, 84), (57, 76, 91), + (64, 84, 106), (65, 83, 106), (67, 83, 107), (67, 76, 103), + (65, 67, 100), (61, 59, 94), (56, 54, 95), (53, 54, 95), + (52, 54, 93), (53, 55, 91), (57, 56, 87), (61, 56, 78), + (65, 54, 74), (70, 54, 71), (74, 55, 69), (80, 59, 68), + (86, 71, 68), (86, 74, 69), (86, 78, 70), (84, 83, 77), + (79, 87, 84), (74, 89, 89), (70, 91, 91), (63, 89, 93), + (60, 88, 93), (57, 84, 94), (54, 78, 97), (54, 73, 100), + (55, 67, 99), (51, 60, 97), (50, 55, 93), (50, 50, 87), + (51, 44, 84), (58, 41, 82), (65, 40, 79), (72, 42, 76), + (79, 45, 73), (85, 50, 71), (90, 56, 69), (100, 63, 70), + (115, 71, 77), (129, 85, 81), (142, 98, 86), (154, 112, 91), + (163, 125, 93), (171, 136, 95), (183, 143, 103), (194, 154, 112), + (204, 170, 123), (209, 187, 141), (211, 202, 157), (207, 216, 168), + (203, 222, 176), (200, 218, 175), (202, 211, 166), (195, 199, 161), + (187, 186, 159), (178, 174, 158), (166, 166, 162), (155, 160, 158), + (149, 156, 146), (141, 154, 139), (133, 151, 133), (129, 149, 130), + (123, 150, 139), (123, 155, 147), (118, 162, 149), (112, 171, 154), + (103, 176, 158), (98, 174, 157), (93, 170, 159), (95, 161, 156), + (96, 150, 147), (92, 138, 136), (79, 126, 127), (69, 110, 120), + (60, 95, 113), (56, 82, 107), (57, 77, 102), (61, 79, 96), + (60, 86, 92), (61, 97, 92), (64, 107, 94), (61, 102, 97), + (56, 104, 104), (58, 115, 110), (59, 129, 117), (60, 145, 126) + ), + +// 416 040221-59 +((87, 129, 157), (98, 136, 164), (100, 139, 166), (102, 142, 168), + (101, 142, 169), (101, 142, 170), (106, 147, 175), (112, 152, 180), + (131, 169, 199), (137, 174, 203), (143, 180, 207), (145, 182, 209), + (147, 185, 212), (148, 186, 213), (150, 187, 214), (150, 187, 215), + (151, 188, 216), (153, 190, 220), (154, 191, 221), (155, 193, 223), + (157, 194, 223), (159, 195, 224), (160, 195, 224), (161, 195, 224), + (159, 192, 221), (156, 188, 217), (154, 184, 213), (147, 178, 206), + (141, 172, 200), (138, 168, 196), (135, 165, 193), (128, 159, 186), + (121, 151, 177), (111, 136, 162), (104, 128, 153), (98, 121, 145), + (90, 112, 137), (83, 104, 129), (79, 99, 125), (75, 95, 121), + (64, 80, 106), (60, 74, 100), (57, 68, 94), (53, 62, 88), + (50, 56, 83), (48, 54, 82), (47, 52, 81), (44, 49, 79), + (42, 46, 78), (38, 44, 77), (37, 45, 77), (37, 46, 78), + (38, 48, 80), (40, 51, 82), (41, 52, 84), (43, 54, 86), + (48, 59, 91), (48, 60, 92), (48, 62, 94), (46, 61, 91), + (45, 61, 89), (43, 59, 87), (42, 58, 85), (39, 54, 81), + (36, 48, 77), (27, 38, 68), (25, 35, 66), (23, 33, 65), + (22, 32, 64), (22, 31, 64), (22, 31, 63), (23, 30, 62), + (26, 34, 65), (31, 40, 70), (36, 46, 76), (46, 57, 87), + (56, 68, 99), (61, 74, 104), (67, 80, 110), (77, 90, 120), + (85, 98, 127), (89, 103, 127), (86, 102, 126), (84, 101, 125), + (82, 99, 123), (81, 98, 122), (76, 94, 119), (73, 92, 117), + (67, 82, 109), (62, 78, 104), (58, 74, 99), (55, 71, 97), + (53, 69, 95), (48, 64, 93), (43, 64, 91), (42, 64, 91), + (42, 64, 90), (47, 66, 94), (47, 67, 96), (48, 69, 98), + (46, 70, 98), (45, 71, 98), (42, 71, 97), (39, 70, 95), + (38, 63, 89), (38, 60, 86), (38, 58, 84), (38, 58, 84), + (39, 58, 85), (39, 58, 85), (41, 61, 87), (44, 65, 91), + (51, 71, 98), (69, 87, 116), (74, 93, 123), (79, 99, 131), + (88, 109, 143), (94, 118, 151), (99, 123, 155), (100, 124, 156), + (99, 124, 151), (98, 123, 151), (97, 123, 151), (95, 122, 150), + (94, 122, 150), (93, 120, 148), (90, 115, 144), (85, 110, 137), + (79, 105, 129), (75, 98, 120), (75, 97, 119), (75, 97, 119), + (76, 96, 118), (76, 95, 119), (77, 94, 117), (74, 93, 116), + (67, 91, 115), (66, 92, 115), (65, 93, 115), (65, 93, 115), + (66, 94, 115), (70, 95, 115), (74, 97, 117), (76, 98, 119), + (78, 99, 122), (78, 102, 127), (77, 103, 127), (77, 104, 128), + (77, 104, 130), (80, 105, 131), (84, 106, 132), (89, 105, 134), + (90, 103, 134), (88, 101, 132), (86, 99, 130), (79, 92, 123), + (70, 82, 114), (61, 72, 103), (51, 61, 93), (42, 52, 83), + (35, 44, 74), (24, 30, 61), (21, 27, 58), (18, 25, 55), + (14, 20, 50), (11, 15, 47), (8, 11, 44), (6, 9, 42), + (2, 8, 41), (2, 8, 41), (2, 9, 42), (3, 10, 42), + (4, 12, 44), (6, 14, 47), (9, 16, 51), (12, 20, 54), + (16, 23, 57), (17, 26, 60), (19, 28, 60), (19, 29, 61), + (19, 30, 61), (20, 30, 62), (20, 30, 64), (23, 31, 66), + (27, 33, 68), (27, 33, 67), (27, 33, 67), (27, 32, 64), + (26, 31, 62), (24, 29, 61), (24, 30, 62), (25, 32, 64), + (28, 36, 68), (33, 42, 73), (39, 51, 79), (47, 60, 87), + (53, 69, 94), (60, 78, 103), (66, 86, 111), (73, 93, 118), + (79, 98, 123), (81, 102, 126), (85, 106, 129), (88, 109, 132), + (91, 111, 134), (92, 114, 136), (94, 116, 139), (97, 117, 141), + (95, 118, 143), (95, 119, 144), (93, 120, 144), (93, 120, 145), + (91, 121, 147), (89, 123, 148), (88, 124, 149), (85, 125, 151), + (82, 127, 153), (79, 127, 152), (77, 124, 151), (74, 120, 148), + (71, 115, 143), (67, 106, 134), (61, 95, 124), (53, 86, 116), + (45, 76, 106), (39, 67, 96), (35, 61, 88), (33, 59, 84), + (34, 58, 83), (37, 57, 85), (41, 62, 90), (46, 68, 97), + (52, 75, 104), (60, 83, 111), (66, 93, 119), (75, 106, 130), + (83, 116, 141), (92, 128, 153), (101, 139, 165), (110, 148, 175), + (117, 154, 184), (120, 158, 189), (121, 161, 191), (118, 160, 190), + (113, 158, 188), (109, 154, 184), (107, 152, 180), (107, 150, 178), + (109, 151, 180), (109, 151, 179), (99, 141, 169), (89, 133, 162), + (79, 125, 154), (72, 120, 148), (68, 115, 143), (72, 117, 145) + ), + +// 417 040221-60 +((75, 85, 97), (43, 46, 51), (39, 42, 47), (36, 39, 44), + (34, 36, 38), (33, 34, 33), (32, 32, 32), (31, 31, 31), + (27, 28, 28), (25, 26, 25), (23, 24, 23), (18, 20, 19), + (14, 16, 16), (11, 12, 12), (8, 9, 8), (7, 8, 7), + (6, 7, 7), (10, 11, 13), (16, 18, 19), (23, 26, 26), + (32, 35, 35), (42, 44, 44), (46, 48, 47), (50, 53, 51), + (63, 65, 63), (65, 67, 66), (67, 69, 69), (66, 68, 69), + (65, 68, 69), (65, 68, 69), (66, 68, 70), (67, 69, 71), + (67, 71, 76), (69, 74, 82), (67, 73, 83), (65, 72, 85), + (60, 68, 82), (55, 65, 79), (52, 63, 76), (50, 61, 74), + (54, 58, 65), (58, 62, 67), (63, 67, 70), (70, 73, 74), + (78, 79, 78), (79, 81, 80), (81, 83, 83), (84, 85, 86), + (88, 89, 89), (96, 98, 100), (102, 105, 105), (109, 112, 111), + (113, 116, 116), (118, 121, 122), (119, 122, 122), (120, 123, 123), + (117, 120, 119), (114, 116, 115), (111, 113, 111), (107, 109, 107), + (103, 105, 104), (100, 102, 101), (98, 100, 99), (94, 95, 95), + (87, 89, 89), (71, 73, 72), (63, 65, 64), (55, 57, 57), + (52, 54, 54), (50, 52, 51), (49, 51, 50), (50, 51, 50), + (65, 66, 65), (77, 78, 77), (90, 91, 90), (103, 105, 104), + (117, 119, 118), (124, 126, 124), (131, 133, 131), (139, 142, 140), + (149, 154, 154), (160, 166, 171), (157, 164, 168), (154, 162, 165), + (151, 159, 164), (148, 156, 163), (142, 150, 152), (134, 138, 137), + (123, 127, 128), (116, 119, 120), (109, 111, 112), (104, 106, 107), + (100, 102, 103), (88, 89, 89), (73, 74, 74), (60, 60, 62), + (46, 48, 51), (25, 30, 37), (24, 31, 39), (24, 32, 41), + (23, 32, 43), (23, 33, 46), (22, 35, 49), (30, 39, 47), + (27, 33, 41), (27, 31, 35), (28, 29, 29), (28, 28, 28), + (28, 28, 28), (29, 30, 29), (31, 33, 31), (35, 37, 36), + (40, 42, 42), (47, 48, 49), (47, 48, 49), (47, 49, 49), + (45, 47, 48), (44, 45, 45), (41, 42, 42), (37, 38, 37), + (29, 31, 30), (26, 28, 27), (24, 25, 24), (22, 23, 22), + (20, 22, 21), (17, 19, 18), (14, 14, 14), (11, 11, 11), + (8, 9, 10), (4, 5, 12), (5, 6, 12), (7, 8, 13), + (6, 7, 15), (7, 7, 15), (9, 9, 13), (10, 10, 13), + (10, 11, 15), (12, 13, 18), (14, 16, 22), (16, 18, 24), + (19, 21, 27), (25, 28, 32), (32, 35, 39), (41, 45, 49), + (51, 57, 62), (86, 91, 98), (96, 103, 113), (107, 115, 128), + (134, 142, 152), (168, 175, 181), (185, 194, 205), (188, 198, 208), + (197, 203, 207), (184, 191, 197), (171, 179, 187), (157, 166, 176), + (150, 156, 161), (145, 150, 155), (144, 151, 158), (153, 159, 162), + (165, 167, 167), (171, 179, 185), (168, 176, 183), (166, 174, 182), + (152, 162, 170), (137, 148, 157), (123, 131, 140), (106, 112, 119), + (84, 85, 85), (78, 79, 79), (73, 74, 74), (65, 66, 66), + (61, 63, 62), (59, 60, 60), (58, 59, 59), (59, 61, 61), + (62, 63, 64), (64, 66, 66), (66, 68, 68), (68, 70, 70), + (69, 71, 73), (70, 73, 74), (73, 75, 75), (73, 76, 77), + (76, 79, 80), (76, 79, 80), (77, 79, 80), (77, 81, 82), + (78, 82, 81), (78, 80, 79), (77, 79, 77), (74, 77, 75), + (71, 72, 71), (67, 68, 67), (63, 64, 64), (59, 60, 60), + (53, 55, 54), (47, 49, 48), (44, 45, 44), (38, 40, 37), + (31, 32, 30), (26, 28, 25), (21, 23, 20), (15, 16, 14), + (9, 11, 10), (6, 7, 6), (3, 4, 3), (0, 2, 2), + (1, 2, 2), (3, 3, 3), (6, 6, 7), (9, 9, 11), + (12, 13, 14), (15, 16, 16), (18, 18, 19), (19, 20, 21), + (21, 21, 21), (21, 22, 22), (21, 22, 24), (21, 22, 24), + (19, 20, 22), (18, 19, 21), (15, 15, 17), (10, 11, 13), + (8, 9, 10), (6, 6, 6), (4, 5, 5), (5, 6, 8), + (7, 8, 11), (9, 9, 11), (11, 12, 13), (11, 12, 14), + (9, 9, 10), (7, 8, 7), (5, 6, 5), (4, 4, 4), + (5, 6, 5), (10, 11, 10), (16, 17, 16), (26, 27, 26), + (38, 40, 38), (51, 53, 51), (62, 64, 62), (73, 75, 74), + (82, 85, 85), (83, 89, 92), (85, 92, 96), (88, 96, 104), + (87, 96, 105), (88, 96, 102), (93, 101, 107), (97, 104, 112), + (102, 109, 117), (105, 113, 121), (90, 98, 104), (77, 84, 93) + ), + +// 418 040221-61 +((180, 138, 160), (170, 104, 140), (171, 86, 137), (173, 68, 134), + (158, 75, 133), (144, 82, 132), (138, 87, 130), (133, 92, 128), + (105, 93, 109), (80, 89, 100), (55, 85, 91), (39, 86, 82), + (24, 88, 74), (23, 88, 68), (23, 88, 63), (27, 85, 64), + (32, 82, 65), (59, 70, 74), (76, 63, 72), (93, 57, 71), + (114, 45, 74), (136, 34, 77), (148, 28, 80), (161, 23, 84), + (199, 13, 94), (205, 10, 96), (212, 7, 98), (211, 8, 105), + (210, 10, 112), (207, 13, 115), (204, 16, 118), (198, 20, 120), + (185, 23, 115), (159, 29, 103), (148, 31, 99), (138, 34, 95), + (124, 37, 94), (111, 41, 93), (105, 43, 90), (99, 46, 88), + (77, 61, 78), (73, 67, 81), (70, 73, 84), (81, 85, 93), + (93, 98, 103), (100, 103, 107), (107, 108, 111), (124, 123, 123), + (140, 133, 139), (184, 160, 161), (187, 162, 164), (190, 165, 168), + (182, 158, 167), (174, 151, 166), (172, 146, 165), (171, 141, 165), + (152, 102, 142), (133, 88, 128), (115, 74, 115), (103, 58, 110), + (92, 43, 105), (88, 38, 104), (85, 33, 104), (79, 36, 99), + (68, 43, 88), (37, 59, 67), (29, 61, 65), (22, 63, 64), + (22, 62, 62), (22, 62, 61), (18, 61, 57), (18, 62, 55), + (18, 58, 63), (17, 53, 71), (16, 48, 80), (14, 47, 84), + (13, 47, 88), (12, 50, 89), (11, 53, 91), (11, 60, 91), + (10, 69, 91), (11, 86, 87), (11, 96, 89), (11, 106, 92), + (12, 111, 94), (13, 117, 96), (15, 125, 96), (18, 130, 93), + (24, 127, 83), (27, 124, 82), (31, 121, 82), (33, 118, 79), + (36, 116, 77), (39, 108, 67), (44, 100, 55), (44, 94, 46), + (44, 90, 42), (47, 92, 47), (48, 100, 52), (50, 109, 57), + (50, 117, 58), (51, 125, 60), (52, 135, 68), (54, 148, 79), + (61, 141, 96), (64, 133, 97), (68, 126, 99), (72, 124, 100), + (77, 122, 102), (92, 108, 99), (107, 86, 100), (118, 61, 97), + (131, 39, 95), (154, 20, 91), (160, 18, 89), (166, 16, 88), + (174, 12, 84), (177, 9, 79), (174, 11, 73), (160, 17, 68), + (137, 28, 61), (133, 28, 57), (130, 29, 53), (127, 30, 51), + (125, 31, 49), (119, 34, 47), (121, 34, 49), (126, 34, 52), + (138, 31, 57), (153, 27, 65), (154, 28, 65), (155, 29, 66), + (154, 40, 65), (155, 55, 67), (144, 69, 76), (128, 80, 81), + (98, 83, 87), (100, 84, 82), (103, 86, 78), (102, 86, 75), + (101, 86, 73), (91, 79, 70), (78, 74, 69), (76, 68, 68), + (78, 66, 62), (74, 71, 53), (70, 76, 53), (66, 81, 53), + (54, 88, 57), (46, 97, 56), (41, 103, 53), (40, 105, 53), + (45, 99, 58), (45, 95, 59), (45, 91, 61), (46, 82, 60), + (45, 74, 60), (40, 65, 61), (39, 59, 63), (34, 52, 70), + (29, 50, 72), (23, 49, 78), (24, 48, 79), (25, 48, 81), + (34, 47, 90), (47, 47, 96), (61, 48, 100), (71, 49, 104), + (85, 49, 114), (88, 47, 117), (92, 46, 121), (97, 45, 124), + (101, 46, 124), (100, 52, 114), (97, 66, 108), (90, 77, 101), + (81, 85, 95), (76, 86, 92), (74, 82, 81), (82, 84, 73), + (88, 81, 63), (89, 82, 59), (85, 78, 60), (75, 71, 62), + (74, 56, 66), (73, 54, 66), (73, 53, 67), (72, 51, 66), + (68, 54, 65), (69, 60, 62), (74, 67, 58), (80, 68, 56), + (87, 66, 56), (93, 62, 61), (106, 56, 61), (117, 56, 61), + (126, 55, 63), (129, 54, 68), (122, 59, 78), (114, 62, 83), + (106, 71, 86), (94, 81, 89), (84, 87, 91), (74, 102, 100), + (63, 116, 104), (58, 130, 105), (55, 138, 108), (62, 131, 106), + (79, 120, 107), (94, 108, 106), (103, 97, 100), (105, 88, 91), + (109, 78, 81), (116, 68, 70), (124, 62, 61), (121, 59, 54), + (108, 62, 47), (90, 67, 47), (74, 74, 45), (67, 84, 49), + (61, 87, 58), (62, 88, 65), (63, 86, 79), (63, 80, 87), + (63, 81, 92), (62, 76, 96), (63, 70, 95), (66, 65, 101), + (68, 59, 105), (63, 61, 106), (57, 63, 106), (48, 66, 100), + (42, 69, 95), (38, 71, 91), (31, 72, 89), (29, 73, 88), + (25, 74, 87), (26, 76, 86), (25, 78, 83), (20, 80, 82), + (21, 85, 84), (24, 88, 88), (34, 96, 95), (54, 107, 101), + (71, 122, 117), (95, 144, 136), (121, 161, 154), (141, 178, 172), + (170, 191, 182), (192, 204, 196), (201, 214, 205), (200, 221, 205), + (196, 203, 203), (193, 180, 188), (196, 160, 178), (193, 132, 171) + ), + +// 419 040221-62 +((110, 59, 34), (88, 44, 25), (79, 35, 26), (70, 27, 28), + (65, 26, 30), (60, 26, 33), (58, 26, 34), (56, 27, 36), + (52, 21, 43), (54, 24, 45), (56, 28, 48), (62, 33, 50), + (68, 38, 53), (80, 45, 51), (93, 53, 50), (98, 57, 49), + (103, 61, 49), (127, 80, 43), (129, 79, 38), (132, 79, 33), + (130, 75, 27), (128, 72, 22), (124, 70, 22), (121, 68, 22), + (104, 53, 20), (100, 49, 22), (97, 46, 25), (95, 47, 28), + (93, 49, 31), (94, 49, 33), (95, 50, 35), (96, 51, 39), + (97, 49, 43), (98, 57, 50), (103, 65, 56), (109, 74, 62), + (117, 81, 66), (125, 89, 71), (128, 93, 71), (132, 98, 71), + (150, 115, 69), (156, 117, 68), (163, 119, 67), (168, 120, 63), + (174, 122, 60), (176, 124, 60), (179, 127, 61), (182, 131, 66), + (180, 131, 71), (168, 125, 81), (164, 119, 79), (161, 114, 78), + (152, 105, 75), (143, 96, 72), (139, 92, 68), (135, 88, 65), + (117, 65, 52), (107, 56, 47), (98, 48, 43), (88, 41, 41), + (78, 35, 40), (74, 33, 40), (70, 31, 40), (64, 28, 37), + (61, 28, 35), (61, 31, 36), (63, 31, 37), (65, 32, 38), + (67, 32, 38), (70, 33, 39), (75, 36, 41), (81, 39, 42), + (92, 45, 43), (96, 48, 43), (100, 52, 44), (101, 55, 45), + (102, 58, 46), (102, 57, 45), (102, 57, 44), (98, 54, 43), + (94, 49, 42), (80, 35, 32), (74, 30, 30), (69, 25, 28), + (67, 23, 27), (65, 22, 27), (64, 21, 24), (63, 20, 23), + (71, 30, 28), (82, 38, 29), (93, 46, 31), (97, 50, 32), + (102, 54, 33), (112, 62, 36), (119, 69, 41), (128, 74, 48), + (133, 79, 52), (133, 85, 56), (128, 82, 58), (124, 80, 61), + (122, 77, 59), (120, 75, 58), (115, 71, 51), (111, 66, 44), + (101, 58, 39), (100, 53, 38), (99, 49, 37), (98, 47, 38), + (97, 46, 39), (89, 44, 42), (82, 40, 45), (76, 39, 47), + (72, 35, 49), (70, 33, 51), (72, 35, 53), (74, 37, 55), + (79, 42, 60), (88, 49, 63), (103, 60, 69), (116, 70, 76), + (125, 78, 79), (126, 80, 78), (127, 82, 77), (128, 81, 73), + (130, 81, 70), (130, 79, 64), (133, 81, 62), (136, 87, 65), + (148, 98, 72), (178, 132, 101), (181, 138, 106), (185, 145, 111), + (191, 152, 122), (195, 161, 131), (199, 170, 141), (197, 173, 144), + (178, 150, 131), (168, 142, 120), (159, 134, 110), (152, 127, 103), + (146, 120, 96), (128, 100, 80), (114, 82, 62), (100, 68, 48), + (92, 55, 37), (77, 34, 24), (74, 32, 22), (71, 31, 21), + (70, 28, 25), (75, 35, 33), (80, 40, 40), (83, 46, 45), + (83, 50, 51), (83, 50, 50), (83, 51, 49), (81, 46, 43), + (78, 39, 36), (74, 36, 32), (72, 36, 31), (71, 36, 31), + (75, 37, 36), (99, 65, 57), (108, 77, 65), (118, 89, 74), + (141, 112, 100), (169, 141, 120), (192, 166, 138), (203, 184, 148), + (210, 193, 164), (211, 193, 164), (213, 193, 165), (208, 190, 161), + (205, 182, 156), (197, 174, 155), (196, 171, 154), (194, 170, 151), + (199, 171, 148), (196, 170, 144), (192, 167, 141), (186, 159, 134), + (184, 153, 120), (182, 146, 106), (176, 142, 97), (172, 136, 96), + (188, 149, 104), (196, 158, 109), (205, 167, 115), (217, 180, 127), + (222, 187, 136), (223, 190, 144), (227, 192, 144), (227, 189, 135), + (223, 178, 117), (212, 166, 105), (194, 146, 87), (172, 123, 68), + (151, 100, 49), (134, 84, 41), (116, 70, 35), (95, 55, 30), + (76, 40, 27), (63, 32, 26), (54, 27, 26), (49, 22, 25), + (47, 17, 22), (52, 17, 21), (54, 18, 23), (56, 21, 27), + (56, 20, 29), (63, 21, 31), (68, 25, 34), (73, 33, 43), + (77, 43, 52), (85, 55, 61), (94, 63, 63), (104, 69, 67), + (110, 74, 69), (112, 79, 72), (114, 79, 70), (114, 77, 68), + (113, 71, 64), (109, 67, 61), (106, 62, 59), (105, 60, 59), + (107, 62, 60), (113, 67, 60), (123, 73, 60), (134, 80, 61), + (143, 88, 61), (148, 92, 62), (154, 95, 63), (157, 99, 63), + (161, 101, 64), (161, 102, 69), (160, 102, 77), (158, 105, 84), + (160, 110, 91), (158, 115, 97), (156, 118, 101), (154, 120, 104), + (156, 123, 105), (151, 119, 98), (141, 111, 86), (130, 98, 76), + (121, 87, 67), (114, 73, 56), (108, 62, 45), (106, 54, 39), + (106, 52, 36), (109, 52, 35), (112, 55, 34), (119, 59, 36), + (129, 70, 38), (126, 68, 36), (117, 63, 32), (107, 54, 31) + ), + +// 420 040221-63 +((85, 103, 82), (86, 117, 97), (88, 122, 104), (90, 127, 111), + (88, 126, 111), (86, 126, 112), (92, 134, 119), (99, 143, 127), + (127, 168, 149), (137, 171, 152), (147, 174, 155), (146, 167, 150), + (145, 161, 146), (139, 150, 136), (133, 139, 127), (127, 132, 121), + (122, 125, 115), (105, 95, 86), (90, 77, 68), (76, 60, 51), + (62, 45, 38), (49, 31, 25), (41, 25, 20), (34, 19, 15), + (17, 8, 6), (11, 6, 3), (6, 4, 1), (5, 6, 1), + (4, 8, 2), (4, 9, 2), (5, 10, 3), (7, 12, 6), + (10, 14, 7), (13, 17, 7), (14, 17, 7), (15, 17, 7), + (14, 17, 7), (14, 18, 7), (14, 17, 7), (15, 17, 8), + (15, 20, 9), (16, 23, 12), (18, 26, 16), (19, 33, 20), + (21, 40, 25), (23, 43, 27), (25, 47, 30), (30, 54, 36), + (37, 63, 43), (61, 84, 64), (74, 99, 80), (88, 115, 96), + (101, 130, 111), (114, 146, 126), (116, 152, 131), (119, 158, 136), + (129, 169, 148), (131, 170, 152), (134, 171, 157), (134, 169, 154), + (135, 167, 152), (132, 164, 148), (129, 162, 145), (120, 154, 137), + (110, 142, 125), (88, 114, 98), (80, 101, 85), (73, 89, 73), + (69, 84, 67), (66, 80, 62), (63, 75, 57), (63, 74, 55), + (63, 79, 61), (64, 84, 67), (66, 90, 74), (67, 98, 82), + (69, 106, 90), (71, 111, 95), (74, 117, 100), (81, 131, 113), + (89, 145, 127), (104, 168, 150), (106, 173, 156), (108, 178, 162), + (108, 179, 163), (109, 180, 164), (110, 182, 165), (111, 183, 166), + (113, 186, 169), (114, 188, 171), (115, 190, 173), (115, 191, 174), + (116, 192, 176), (116, 194, 178), (117, 197, 179), (120, 199, 181), + (124, 202, 184), (127, 205, 187), (122, 204, 185), (117, 203, 183), + (113, 200, 179), (109, 197, 175), (102, 188, 163), (97, 177, 150), + (83, 151, 125), (73, 135, 111), (64, 120, 98), (56, 111, 91), + (49, 102, 84), (36, 85, 67), (24, 67, 49), (14, 51, 34), + (9, 39, 23), (10, 24, 13), (11, 25, 15), (13, 26, 18), + (19, 34, 27), (29, 44, 37), (39, 56, 48), (53, 69, 61), + (78, 96, 86), (87, 112, 100), (97, 128, 115), (103, 136, 123), + (109, 145, 132), (116, 163, 148), (127, 178, 164), (140, 191, 176), + (149, 202, 188), (160, 217, 204), (162, 220, 207), (164, 223, 211), + (165, 228, 218), (167, 232, 223), (174, 235, 227), (182, 237, 230), + (199, 241, 237), (204, 243, 239), (209, 245, 242), (209, 245, 242), + (209, 246, 243), (211, 246, 243), (211, 246, 244), (212, 245, 242), + (213, 244, 240), (214, 235, 231), (212, 231, 226), (211, 228, 222), + (205, 220, 211), (198, 212, 202), (188, 205, 194), (176, 201, 186), + (162, 192, 174), (158, 189, 171), (155, 187, 169), (150, 180, 160), + (145, 173, 153), (139, 168, 149), (132, 170, 148), (128, 173, 149), + (126, 177, 154), (121, 178, 156), (120, 175, 153), (120, 173, 151), + (119, 163, 144), (116, 154, 134), (112, 145, 125), (111, 138, 118), + (123, 127, 105), (128, 126, 104), (133, 125, 104), (142, 121, 103), + (151, 119, 100), (154, 117, 97), (154, 116, 96), (149, 113, 94), + (147, 111, 88), (148, 112, 91), (146, 118, 96), (149, 126, 104), + (151, 137, 113), (149, 146, 123), (139, 150, 128), (126, 146, 123), + (97, 127, 104), (90, 121, 98), (83, 115, 93), (71, 106, 83), + (62, 99, 78), (53, 95, 76), (47, 93, 74), (44, 91, 71), + (44, 92, 72), (51, 94, 76), (59, 98, 81), (70, 106, 88), + (82, 117, 102), (97, 129, 117), (110, 143, 131), (124, 158, 148), + (138, 174, 164), (151, 189, 179), (164, 205, 193), (175, 219, 208), + (189, 231, 221), (201, 240, 232), (211, 246, 240), (218, 250, 246), + (220, 251, 249), (219, 251, 247), (213, 249, 245), (206, 247, 241), + (202, 244, 236), (198, 239, 229), (195, 234, 222), (188, 226, 214), + (179, 213, 199), (164, 198, 184), (146, 182, 167), (130, 165, 150), + (115, 148, 132), (103, 135, 117), (92, 123, 104), (84, 113, 91), + (77, 105, 83), (69, 100, 78), (65, 97, 76), (64, 94, 76), + (67, 94, 78), (68, 95, 79), (69, 97, 79), (70, 96, 79), + (69, 95, 77), (66, 93, 75), (63, 90, 73), (63, 88, 73), + (61, 85, 71), (61, 81, 67), (59, 75, 61), (56, 67, 53), + (52, 58, 42), (47, 49, 33), (45, 41, 25), (42, 36, 20), + (44, 34, 19), (51, 38, 23), (58, 47, 30), (67, 56, 39), + (81, 75, 57), (94, 87, 69), (90, 84, 66), (83, 80, 63), + (81, 76, 61), (76, 75, 59), (68, 71, 53), (70, 80, 63) + ), + +// 421 040221-64 +((54, 109, 89), (32, 97, 71), (21, 80, 59), (11, 64, 47), + (19, 75, 44), (28, 87, 41), (38, 95, 42), (48, 104, 43), + (79, 124, 50), (84, 121, 52), (89, 118, 55), (90, 113, 53), + (91, 108, 51), (84, 96, 45), (77, 85, 39), (73, 78, 35), + (69, 72, 32), (53, 47, 19), (55, 47, 17), (57, 47, 16), + (69, 53, 13), (81, 60, 10), (84, 59, 7), (87, 59, 5), + (78, 56, 6), (74, 54, 8), (71, 53, 11), (59, 44, 12), + (47, 36, 13), (37, 31, 13), (27, 26, 14), (14, 21, 17), + (5, 20, 21), (1, 26, 31), (2, 28, 32), (3, 31, 33), + (3, 37, 29), (3, 44, 26), (3, 48, 25), (3, 52, 24), + (4, 64, 25), (10, 69, 33), (17, 75, 42), (30, 86, 57), + (44, 97, 73), (50, 102, 80), (57, 108, 88), (64, 113, 100), + (67, 109, 108), (70, 93, 115), (66, 87, 109), (63, 81, 104), + (51, 69, 88), (40, 58, 72), (34, 52, 62), (28, 46, 53), + (18, 33, 25), (22, 31, 19), (27, 29, 13), (32, 32, 11), + (38, 36, 10), (42, 39, 8), (46, 42, 7), (52, 48, 5), + (59, 48, 4), (73, 52, 7), (78, 57, 9), (83, 62, 12), + (82, 63, 13), (81, 64, 14), (82, 65, 16), (75, 68, 21), + (61, 65, 24), (52, 60, 21), (44, 56, 19), (34, 57, 19), + (24, 59, 19), (20, 59, 19), (17, 59, 19), (11, 58, 19), + (11, 56, 17), (12, 54, 22), (12, 51, 25), (12, 48, 28), + (12, 45, 30), (12, 42, 32), (10, 36, 37), (9, 33, 43), + (11, 33, 46), (13, 38, 50), (16, 43, 55), (21, 50, 61), + (26, 58, 67), (41, 71, 72), (54, 81, 71), (68, 90, 70), + (71, 90, 67), (73, 99, 67), (70, 99, 58), (68, 99, 50), + (64, 96, 46), (61, 94, 43), (51, 91, 42), (42, 89, 42), + (35, 85, 50), (39, 89, 64), (43, 94, 78), (43, 95, 83), + (44, 97, 88), (51, 94, 96), (53, 87, 101), (60, 82, 109), + (69, 82, 116), (88, 93, 114), (93, 96, 111), (99, 99, 109), + (109, 105, 104), (116, 113, 103), (126, 111, 99), (138, 113, 89), + (165, 117, 71), (164, 110, 66), (163, 103, 61), (160, 100, 59), + (157, 97, 57), (153, 93, 53), (153, 100, 53), (156, 108, 52), + (160, 111, 58), (169, 132, 81), (168, 139, 92), (168, 147, 103), + (169, 163, 123), (174, 172, 139), (171, 171, 145), (179, 172, 142), + (166, 153, 136), (151, 141, 128), (136, 130, 121), (129, 124, 110), + (123, 119, 100), (110, 110, 78), (98, 103, 67), (97, 97, 61), + (96, 101, 75), (116, 123, 107), (122, 134, 113), (129, 145, 119), + (147, 156, 130), (164, 165, 136), (172, 169, 144), (182, 168, 146), + (187, 170, 126), (185, 165, 115), (184, 161, 105), (169, 151, 85), + (148, 135, 70), (124, 120, 54), (101, 110, 46), (82, 99, 43), + (70, 93, 38), (45, 87, 43), (39, 85, 43), (34, 84, 44), + (23, 77, 49), (17, 68, 51), (12, 65, 53), (8, 60, 55), + (4, 58, 55), (6, 58, 57), (8, 59, 60), (13, 70, 71), + (12, 83, 85), (11, 96, 101), (8, 111, 110), (9, 124, 115), + (16, 137, 114), (22, 145, 116), (25, 146, 120), (20, 146, 119), + (16, 142, 120), (13, 138, 107), (16, 134, 94), (23, 126, 84), + (23, 116, 80), (21, 111, 84), (19, 107, 88), (17, 102, 89), + (18, 96, 89), (22, 100, 92), (25, 106, 90), (25, 100, 97), + (25, 89, 94), (22, 75, 88), (19, 61, 81), (17, 57, 73), + (13, 51, 70), (12, 44, 67), (10, 38, 64), (6, 28, 60), + (4, 22, 59), (4, 19, 61), (8, 22, 62), (19, 32, 63), + (31, 41, 61), (45, 50, 55), (62, 62, 52), (78, 79, 53), + (102, 104, 59), (125, 126, 69), (152, 145, 79), (167, 157, 80), + (172, 166, 87), (165, 175, 92), (149, 173, 90), (143, 168, 95), + (131, 153, 84), (121, 136, 79), (101, 118, 71), (71, 95, 56), + (46, 74, 46), (29, 52, 35), (21, 38, 34), (21, 30, 37), + (20, 27, 43), (19, 27, 49), (21, 30, 56), (20, 33, 66), + (23, 41, 74), (22, 45, 77), (23, 49, 77), (24, 55, 75), + (23, 52, 73), (23, 50, 70), (19, 43, 64), (14, 35, 57), + (9, 31, 52), (5, 28, 45), (2, 25, 41), (6, 20, 34), + (15, 14, 28), (25, 10, 24), (41, 16, 18), (49, 24, 16), + (56, 32, 16), (59, 38, 21), (61, 38, 33), (72, 45, 44), + (81, 56, 60), (90, 76, 71), (93, 104, 86), (88, 120, 104), + (73, 114, 111), (63, 102, 114), (57, 88, 106), (51, 92, 94) + ), +// 422 040221-71 +((211, 208, 193), (203, 195, 204), (204, 193, 210), (206, 191, 216), + (206, 191, 220), (207, 191, 225), (203, 190, 227), (199, 190, 229), + (187, 189, 241), (178, 185, 240), (170, 181, 239), (165, 180, 234), + (161, 180, 230), (162, 177, 218), (163, 174, 206), (163, 171, 195), + (164, 169, 185), (167, 143, 149), (158, 132, 143), (150, 122, 138), + (142, 115, 134), (134, 109, 131), (130, 104, 128), (126, 100, 126), + (115, 88, 119), (108, 91, 124), (102, 95, 130), (89, 97, 133), + (77, 100, 137), (73, 97, 135), (70, 94, 134), (63, 85, 131), + (64, 79, 125), (82, 76, 98), (87, 76, 82), (93, 77, 67), + (92, 66, 60), (92, 56, 54), (92, 52, 55), (92, 49, 56), + (103, 46, 68), (116, 55, 76), (129, 64, 84), (145, 78, 101), + (161, 92, 118), (165, 101, 128), (170, 111, 139), (182, 129, 159), + (194, 146, 180), (216, 178, 204), (223, 192, 213), (231, 207, 223), + (231, 217, 229), (231, 227, 235), (230, 230, 237), (230, 233, 240), + (220, 237, 244), (215, 235, 244), (210, 234, 245), (205, 230, 244), + (201, 226, 244), (199, 223, 241), (198, 220, 238), (191, 213, 227), + (182, 203, 210), (172, 185, 175), (174, 180, 157), (176, 176, 140), + (179, 173, 130), (182, 171, 121), (184, 164, 99), (183, 153, 77), + (166, 126, 40), (169, 126, 34), (173, 126, 29), (186, 131, 38), + (199, 136, 47), (202, 136, 54), (205, 137, 62), (203, 135, 79), + (201, 138, 90), (197, 153, 110), (207, 161, 113), (218, 169, 117), + (221, 168, 118), (224, 168, 120), (220, 158, 124), (211, 151, 126), + (180, 147, 127), (167, 148, 126), (154, 149, 125), (148, 147, 126), + (143, 145, 128), (136, 140, 137), (127, 139, 151), (113, 136, 170), + (103, 135, 188), (93, 146, 213), (95, 153, 222), (97, 161, 232), + (96, 163, 235), (95, 165, 239), (95, 165, 244), (89, 163, 245), + (107, 152, 244), (124, 151, 240), (141, 150, 236), (148, 147, 232), + (155, 145, 228), (160, 149, 218), (168, 147, 211), (179, 144, 196), + (198, 138, 185), (223, 116, 158), (227, 114, 152), (232, 113, 146), + (236, 112, 138), (237, 115, 123), (238, 116, 109), (239, 119, 91), + (226, 95, 80), (219, 88, 86), (212, 81, 93), (210, 83, 92), + (209, 86, 92), (211, 100, 78), (216, 104, 63), (217, 108, 53), + (216, 110, 52), (210, 99, 78), (206, 100, 83), (202, 102, 88), + (196, 105, 93), (188, 108, 90), (171, 111, 87), (156, 108, 92), + (125, 94, 116), (116, 99, 136), (108, 104, 157), (102, 108, 164), + (97, 112, 171), (92, 122, 181), (86, 129, 187), (83, 133, 192), + (85, 142, 202), (114, 175, 226), (124, 185, 231), (134, 195, 236), + (154, 212, 246), (172, 221, 250), (184, 228, 251), (194, 230, 251), + (208, 224, 247), (213, 221, 246), (219, 219, 245), (230, 220, 242), + (238, 223, 241), (243, 226, 241), (243, 230, 242), (237, 225, 243), + (225, 210, 241), (194, 192, 235), (186, 187, 233), (178, 183, 232), + (158, 181, 231), (145, 185, 234), (133, 182, 237), (126, 180, 239), + (125, 176, 240), (123, 174, 240), (122, 172, 240), (124, 171, 236), + (125, 171, 235), (125, 172, 233), (124, 176, 235), (127, 176, 236), + (126, 177, 241), (122, 176, 242), (116, 173, 240), (107, 172, 235), + (97, 169, 229), (89, 162, 222), (85, 160, 217), (86, 162, 216), + (98, 162, 212), (102, 165, 213), (106, 169, 215), (116, 169, 216), + (127, 171, 217), (138, 180, 218), (155, 188, 220), (167, 192, 219), + (177, 202, 225), (187, 207, 231), (196, 210, 236), (200, 217, 241), + (207, 226, 244), (212, 230, 241), (216, 237, 240), (220, 243, 237), + (227, 245, 234), (230, 247, 230), (232, 246, 227), (233, 242, 224), + (229, 237, 221), (222, 235, 218), (213, 229, 219), (203, 226, 219), + (190, 221, 217), (186, 215, 214), (182, 208, 209), (180, 208, 201), + (176, 205, 197), (176, 206, 194), (170, 206, 193), (169, 208, 195), + (171, 206, 200), (174, 208, 200), (178, 209, 201), (182, 211, 197), + (187, 209, 191), (197, 212, 175), (206, 212, 163), (213, 211, 156), + (217, 214, 161), (215, 218, 167), (212, 218, 176), (214, 219, 173), + (218, 223, 167), (225, 222, 161), (229, 225, 165), (231, 231, 176), + (227, 235, 195), (224, 236, 214), (220, 239, 226), (220, 238, 230), + (219, 235, 233), (218, 235, 234), (217, 234, 234), (216, 232, 234), + (212, 230, 233), (211, 228, 229), (209, 225, 224), (205, 223, 217), + (205, 224, 211), (207, 225, 205), (209, 226, 206), (212, 228, 206), + (213, 229, 206), (209, 226, 202), (206, 223, 196), (207, 224, 192), + (210, 225, 192), (213, 225, 191), (217, 223, 192), (217, 220, 194) + ), + +// 423 040221-74 +((142, 43, 16), (162, 53, 31), (171, 64, 43), (180, 76, 56), + (180, 86, 68), (180, 97, 80), (177, 101, 84), (175, 106, 88), + (176, 117, 102), (186, 128, 114), (196, 139, 127), (208, 154, 143), + (220, 170, 160), (226, 182, 172), (233, 194, 184), (234, 195, 186), + (236, 197, 189), (237, 197, 189), (234, 192, 185), (232, 188, 182), + (221, 181, 174), (211, 175, 167), (206, 170, 161), (202, 166, 155), + (187, 144, 128), (181, 128, 112), (176, 113, 96), (164, 94, 77), + (153, 76, 59), (145, 67, 49), (137, 59, 40), (123, 45, 26), + (111, 35, 16), (100, 26, 10), (98, 25, 10), (96, 25, 10), + (90, 26, 12), (85, 27, 14), (81, 28, 14), (78, 30, 15), + (61, 39, 21), (55, 43, 22), (50, 48, 23), (49, 49, 23), + (49, 50, 24), (49, 49, 23), (50, 49, 23), (51, 47, 21), + (50, 47, 21), (52, 44, 18), (57, 41, 17), (62, 38, 17), + (74, 33, 14), (87, 29, 12), (94, 27, 11), (102, 25, 10), + (132, 16, 5), (143, 13, 5), (154, 10, 5), (160, 11, 4), + (167, 13, 4), (169, 14, 3), (171, 15, 3), (176, 17, 2), + (180, 19, 1), (186, 19, 3), (179, 20, 5), (173, 22, 8), + (167, 24, 9), (161, 27, 10), (151, 34, 12), (141, 42, 17), + (134, 58, 27), (141, 67, 38), (149, 76, 49), (155, 88, 62), + (162, 100, 76), (166, 108, 85), (170, 116, 94), (175, 129, 109), + (181, 148, 126), (206, 176, 158), (216, 188, 173), (226, 201, 189), + (230, 206, 196), (235, 212, 203), (241, 218, 211), (241, 223, 213), + (231, 208, 199), (228, 194, 184), (225, 181, 169), (224, 173, 162), + (224, 165, 156), (226, 148, 141), (227, 135, 126), (229, 123, 110), + (225, 111, 98), (217, 95, 78), (219, 95, 82), (222, 95, 86), + (224, 99, 91), (226, 103, 96), (236, 114, 107), (240, 124, 117), + (221, 135, 130), (205, 135, 134), (189, 135, 138), (180, 134, 140), + (171, 134, 142), (156, 132, 143), (146, 128, 140), (134, 124, 132), + (124, 114, 120), (95, 85, 91), (89, 79, 84), (84, 73, 77), + (76, 65, 68), (78, 65, 66), (85, 71, 68), (100, 81, 73), + (126, 101, 88), (135, 104, 89), (145, 107, 91), (148, 107, 89), + (152, 107, 88), (156, 106, 86), (161, 104, 84), (163, 103, 82), + (161, 102, 83), (157, 88, 76), (154, 83, 70), (151, 78, 65), + (145, 67, 51), (140, 54, 38), (136, 43, 23), (132, 36, 13), + (135, 38, 10), (140, 48, 18), (145, 58, 27), (149, 64, 33), + (153, 70, 40), (161, 80, 52), (166, 82, 61), (167, 84, 63), + (166, 82, 63), (150, 83, 65), (146, 85, 66), (142, 88, 68), + (131, 98, 73), (119, 98, 81), (107, 100, 84), (95, 96, 81), + (65, 70, 66), (58, 63, 60), (51, 57, 54), (41, 51, 42), + (35, 45, 35), (32, 42, 31), (30, 42, 27), (26, 41, 27), + (27, 36, 27), (28, 26, 28), (30, 23, 26), (33, 21, 25), + (43, 16, 21), (57, 15, 15), (68, 17, 12), (83, 20, 8), + (108, 29, 18), (112, 32, 21), (116, 36, 25), (127, 43, 32), + (139, 48, 36), (150, 52, 38), (160, 57, 34), (172, 57, 30), + (181, 58, 27), (189, 60, 26), (195, 64, 27), (199, 65, 28), + (200, 64, 30), (199, 63, 28), (199, 59, 23), (199, 52, 17), + (200, 43, 6), (199, 42, 4), (199, 41, 3), (196, 38, 1), + (191, 36, 0), (182, 32, 0), (170, 29, 0), (158, 20, 0), + (145, 17, 0), (132, 15, 1), (119, 13, 1), (108, 15, 3), + (95, 17, 5), (81, 22, 7), (71, 24, 10), (62, 23, 11), + (60, 23, 12), (62, 22, 11), (69, 20, 10), (83, 17, 11), + (96, 18, 11), (113, 21, 12), (128, 22, 13), (143, 22, 13), + (158, 23, 12), (169, 22, 10), (178, 18, 9), (185, 16, 10), + (189, 16, 18), (189, 18, 27), (188, 20, 30), (188, 24, 32), + (187, 28, 31), (181, 30, 28), (174, 32, 22), (162, 32, 22), + (145, 33, 27), (131, 35, 31), (121, 36, 35), (122, 42, 40), + (130, 50, 44), (144, 61, 46), (158, 73, 51), (167, 84, 61), + (173, 96, 77), (176, 106, 92), (178, 116, 106), (184, 126, 118), + (194, 136, 129), (205, 143, 137), (211, 144, 138), (211, 144, 137), + (204, 140, 135), (190, 133, 129), (171, 123, 121), (152, 118, 114), + (137, 114, 108), (121, 107, 98), (102, 97, 87), (88, 86, 76), + (76, 75, 63), (68, 60, 48), (63, 50, 37), (65, 48, 32), + (75, 49, 29), (81, 52, 28), (98, 55, 31), (110, 57, 32), + (122, 53, 29), (130, 48, 24), (135, 43, 21), (141, 40, 18) + ), + +// 424 040221-78 +((152, 87, 41), (157, 79, 29), (147, 70, 22), (138, 62, 16), + (118, 50, 14), (99, 39, 13), (96, 38, 12), (93, 37, 11), + (90, 32, 7), (94, 31, 5), (98, 31, 3), (104, 33, 3), + (110, 35, 3), (115, 38, 3), (120, 42, 4), (122, 43, 3), + (124, 44, 3), (137, 49, 3), (145, 51, 4), (154, 54, 5), + (162, 58, 7), (171, 62, 9), (172, 62, 10), (174, 63, 11), + (165, 60, 11), (150, 56, 12), (136, 52, 13), (123, 50, 15), + (111, 48, 18), (107, 47, 20), (103, 47, 22), (100, 47, 25), + (98, 47, 26), (99, 48, 26), (102, 51, 27), (105, 54, 28), + (109, 56, 30), (114, 59, 33), (116, 60, 34), (119, 62, 35), + (128, 64, 36), (129, 64, 35), (130, 65, 35), (127, 63, 35), + (125, 61, 36), (124, 61, 36), (124, 62, 37), (124, 65, 39), + (125, 67, 41), (125, 70, 43), (119, 68, 43), (113, 66, 43), + (107, 63, 41), (102, 61, 40), (99, 60, 40), (97, 59, 40), + (95, 61, 42), (89, 58, 39), (83, 55, 37), (74, 47, 31), + (65, 39, 26), (58, 35, 24), (52, 31, 22), (42, 26, 19), + (37, 23, 18), (28, 18, 14), (29, 17, 13), (30, 16, 12), + (30, 16, 11), (31, 16, 11), (32, 17, 11), (34, 20, 14), + (46, 30, 23), (57, 36, 25), (68, 43, 28), (79, 48, 30), + (90, 54, 33), (94, 56, 33), (98, 58, 34), (102, 62, 38), + (105, 65, 41), (113, 70, 41), (116, 70, 38), (119, 71, 36), + (120, 70, 34), (121, 69, 33), (120, 68, 32), (117, 65, 33), + (112, 61, 33), (110, 59, 31), (108, 58, 30), (106, 57, 30), + (105, 57, 30), (102, 57, 30), (99, 56, 30), (94, 54, 30), + (91, 53, 32), (87, 50, 31), (86, 48, 29), (86, 46, 27), + (87, 45, 26), (88, 44, 25), (88, 40, 22), (86, 36, 19), + (82, 31, 13), (84, 31, 12), (87, 31, 11), (91, 32, 11), + (95, 34, 11), (107, 38, 14), (120, 41, 17), (132, 48, 21), + (143, 55, 25), (161, 66, 30), (165, 70, 31), (170, 75, 32), + (179, 84, 36), (188, 91, 38), (196, 96, 40), (198, 101, 43), + (192, 97, 41), (184, 92, 38), (177, 87, 35), (171, 85, 34), + (166, 83, 33), (156, 78, 29), (146, 74, 29), (136, 73, 29), + (127, 67, 28), (112, 56, 25), (109, 53, 24), (106, 51, 24), + (101, 47, 22), (97, 43, 21), (93, 44, 22), (91, 44, 23), + (86, 42, 23), (83, 41, 22), (80, 40, 21), (78, 39, 20), + (77, 38, 19), (75, 37, 18), (73, 37, 18), (72, 37, 19), + (72, 37, 20), (70, 38, 23), (69, 38, 23), (69, 38, 23), + (68, 38, 23), (68, 38, 24), (68, 39, 25), (70, 40, 25), + (69, 40, 25), (67, 39, 24), (66, 38, 24), (60, 35, 22), + (54, 32, 20), (48, 29, 18), (42, 25, 17), (38, 24, 16), + (38, 24, 16), (43, 28, 18), (45, 30, 18), (47, 32, 19), + (54, 37, 20), (64, 42, 21), (75, 48, 22), (87, 54, 25), + (112, 66, 30), (116, 67, 30), (121, 69, 31), (127, 74, 31), + (134, 77, 29), (143, 80, 28), (150, 82, 27), (156, 83, 28), + (161, 81, 29), (164, 77, 28), (162, 73, 28), (160, 71, 23), + (163, 69, 19), (168, 71, 15), (176, 76, 13), (184, 82, 15), + (195, 91, 23), (194, 90, 24), (194, 90, 25), (196, 89, 26), + (194, 87, 27), (193, 85, 24), (192, 86, 23), (192, 88, 22), + (188, 86, 21), (179, 82, 21), (172, 77, 22), (164, 71, 22), + (158, 61, 20), (154, 55, 18), (156, 54, 19), (159, 57, 19), + (163, 62, 20), (168, 69, 25), (174, 83, 37), (181, 91, 44), + (187, 98, 45), (192, 104, 51), (193, 106, 55), (195, 110, 56), + (194, 109, 54), (192, 115, 62), (188, 115, 69), (185, 117, 66), + (181, 113, 66), (176, 103, 63), (173, 94, 56), (171, 78, 43), + (169, 66, 33), (165, 54, 29), (160, 48, 23), (155, 41, 20), + (150, 33, 16), (142, 30, 13), (138, 26, 10), (133, 23, 8), + (131, 20, 8), (125, 22, 7), (119, 22, 9), (112, 21, 10), + (102, 24, 11), (94, 26, 11), (87, 27, 10), (83, 27, 10), + (80, 27, 9), (76, 30, 10), (74, 30, 11), (75, 31, 11), + (76, 32, 11), (77, 34, 11), (80, 35, 11), (83, 34, 12), + (85, 35, 12), (84, 36, 15), (83, 37, 18), (84, 39, 22), + (84, 45, 26), (88, 52, 32), (94, 59, 40), (104, 67, 45), + (117, 77, 48), (130, 86, 48), (130, 85, 48), (129, 85, 47), + (129, 83, 45), (127, 83, 46), (129, 80, 46), (132, 81, 46) + ), + +// 425 040221-80 +((59, 60, 92), (51, 53, 84), (50, 51, 83), (49, 50, 83), + (46, 47, 81), (44, 45, 80), (43, 45, 79), (43, 45, 78), + (44, 45, 75), (45, 45, 76), (46, 46, 78), (46, 46, 80), + (47, 47, 83), (45, 46, 82), (44, 45, 82), (43, 44, 79), + (42, 43, 77), (36, 37, 68), (33, 34, 65), (30, 31, 62), + (30, 30, 61), (31, 30, 60), (32, 31, 61), (33, 33, 62), + (45, 45, 71), (51, 51, 79), (57, 58, 87), (64, 65, 96), + (72, 72, 105), (75, 76, 109), (79, 80, 114), (85, 86, 121), + (94, 95, 130), (108, 109, 144), (110, 111, 147), (112, 114, 151), + (108, 110, 149), (104, 106, 147), (101, 102, 144), (98, 99, 141), + (85, 85, 125), (77, 77, 116), (70, 70, 108), (62, 62, 98), + (54, 55, 89), (50, 50, 84), (46, 46, 80), (38, 38, 72), + (31, 31, 64), (26, 25, 56), (29, 27, 55), (32, 30, 55), + (38, 37, 59), (45, 44, 64), (48, 47, 68), (51, 50, 72), + (66, 66, 90), (75, 75, 100), (84, 84, 110), (93, 93, 118), + (103, 102, 127), (105, 104, 129), (108, 107, 132), (111, 110, 137), + (114, 113, 140), (124, 123, 151), (132, 131, 158), (140, 140, 165), + (143, 143, 168), (147, 147, 171), (154, 154, 176), (157, 158, 180), + (162, 162, 182), (161, 161, 181), (160, 161, 181), (156, 158, 179), + (153, 156, 177), (149, 152, 174), (146, 149, 171), (136, 139, 160), + (127, 128, 148), (104, 104, 121), (90, 90, 107), (76, 77, 93), + (69, 70, 85), (63, 64, 78), (51, 51, 63), (41, 41, 49), + (28, 27, 29), (25, 24, 23), (22, 21, 17), (21, 20, 16), + (21, 20, 16), (21, 21, 19), (21, 22, 23), (21, 22, 27), + (22, 22, 31), (22, 22, 34), (21, 20, 33), (20, 19, 32), + (19, 18, 32), (19, 18, 32), (19, 18, 33), (19, 18, 34), + (22, 21, 38), (25, 24, 41), (29, 28, 44), (31, 30, 46), + (34, 32, 49), (40, 37, 56), (47, 43, 62), (53, 49, 68), + (57, 54, 74), (63, 60, 86), (63, 61, 88), (64, 62, 91), + (64, 62, 96), (64, 62, 98), (64, 60, 96), (60, 58, 90), + (52, 50, 77), (46, 44, 68), (40, 39, 60), (36, 36, 56), + (33, 34, 53), (28, 28, 45), (25, 24, 37), (23, 22, 34), + (24, 23, 35), (29, 29, 42), (30, 31, 46), (32, 33, 51), + (36, 37, 59), (40, 41, 66), (42, 44, 72), (47, 49, 81), + (61, 63, 100), (71, 73, 112), (81, 84, 125), (87, 90, 131), + (94, 97, 138), (105, 108, 146), (116, 119, 155), (126, 129, 161), + (135, 137, 166), (151, 154, 177), (156, 159, 180), (161, 165, 184), + (172, 176, 192), (180, 184, 198), (186, 189, 204), (189, 191, 207), + (186, 189, 205), (182, 185, 202), (178, 181, 200), (172, 175, 198), + (164, 167, 192), (154, 158, 187), (143, 146, 179), (131, 133, 167), + (118, 120, 155), (88, 88, 124), (81, 81, 116), (74, 74, 108), + (61, 61, 95), (49, 49, 83), (37, 38, 70), (29, 28, 58), + (15, 15, 36), (13, 12, 31), (11, 10, 26), (8, 7, 20), + (7, 6, 15), (6, 5, 11), (6, 5, 10), (6, 6, 9), + (6, 6, 8), (7, 7, 8), (9, 8, 8), (10, 10, 8), + (11, 11, 8), (11, 11, 8), (10, 11, 9), (10, 11, 8), + (10, 11, 8), (10, 10, 8), (10, 10, 8), (10, 10, 8), + (9, 9, 7), (8, 9, 7), (7, 8, 6), (6, 7, 5), + (6, 7, 4), (5, 6, 3), (5, 6, 3), (5, 6, 2), + (5, 6, 2), (4, 5, 2), (4, 5, 2), (3, 4, 3), + (3, 4, 4), (3, 4, 6), (4, 4, 7), (4, 5, 10), + (5, 5, 12), (5, 6, 14), (5, 5, 16), (5, 5, 18), + (5, 6, 20), (5, 6, 21), (5, 6, 22), (6, 6, 23), + (6, 6, 25), (6, 6, 25), (5, 5, 24), (5, 5, 24), + (6, 6, 24), (7, 7, 25), (9, 9, 28), (13, 13, 33), + (18, 18, 39), (22, 23, 46), (27, 28, 53), (30, 31, 59), + (33, 34, 62), (34, 35, 63), (35, 36, 63), (36, 37, 62), + (37, 38, 61), (38, 39, 61), (39, 41, 61), (40, 42, 60), + (41, 42, 60), (43, 43, 61), (47, 48, 64), (54, 54, 68), + (63, 63, 75), (74, 74, 84), (84, 86, 93), (94, 95, 103), + (103, 104, 111), (110, 110, 121), (114, 114, 129), (119, 120, 138), + (124, 125, 146), (127, 129, 152), (128, 131, 156), (129, 132, 155), + (128, 130, 156), (122, 124, 152), (114, 116, 146), (103, 106, 138), + (92, 95, 128), (81, 84, 119), (70, 73, 107), (63, 65, 99) + ), + +// 426 040221-81 +((168, 37, 1), (168, 35, 1), (168, 30, 1), (169, 25, 1), + (166, 20, 2), (163, 15, 3), (161, 14, 3), (160, 14, 3), + (160, 22, 8), (167, 32, 15), (174, 43, 22), (179, 53, 30), + (185, 64, 39), (187, 71, 41), (190, 78, 44), (192, 80, 44), + (195, 82, 44), (208, 93, 46), (213, 98, 51), (218, 103, 57), + (220, 103, 58), (222, 103, 59), (220, 99, 56), (219, 96, 54), + (205, 76, 43), (189, 70, 42), (174, 65, 41), (165, 63, 41), + (156, 61, 41), (152, 59, 39), (149, 58, 38), (148, 51, 31), + (142, 47, 23), (128, 48, 12), (134, 52, 10), (141, 56, 9), + (158, 60, 8), (175, 64, 7), (182, 65, 7), (189, 67, 7), + (204, 75, 12), (205, 76, 15), (207, 78, 19), (197, 73, 19), + (187, 69, 20), (178, 65, 20), (169, 62, 20), (150, 54, 19), + (130, 47, 20), (116, 34, 18), (109, 28, 15), (103, 23, 12), + (98, 20, 9), (94, 17, 6), (92, 17, 6), (90, 18, 6), + (112, 16, 5), (125, 16, 5), (139, 17, 6), (145, 22, 5), + (152, 28, 4), (153, 29, 5), (154, 31, 7), (154, 33, 7), + (154, 32, 8), (148, 28, 9), (136, 30, 10), (125, 33, 12), + (119, 34, 13), (113, 35, 14), (107, 39, 20), (109, 46, 29), + (127, 67, 48), (131, 79, 57), (136, 91, 66), (138, 100, 71), + (141, 110, 76), (149, 113, 75), (157, 117, 75), (174, 123, 72), + (189, 126, 70), (201, 125, 59), (198, 119, 52), (196, 114, 45), + (196, 112, 41), (196, 110, 37), (197, 108, 32), (202, 111, 33), + (206, 119, 46), (209, 126, 58), (213, 134, 70), (215, 139, 74), + (218, 144, 79), (224, 153, 88), (233, 164, 97), (239, 170, 103), + (242, 173, 108), (244, 174, 115), (246, 173, 116), (248, 172, 118), + (249, 173, 119), (250, 175, 120), (252, 178, 124), (252, 184, 132), + (252, 195, 143), (251, 194, 144), (251, 194, 146), (251, 192, 145), + (251, 190, 144), (248, 186, 143), (245, 181, 138), (242, 176, 133), + (242, 166, 124), (242, 147, 108), (242, 144, 103), (242, 141, 98), + (241, 134, 88), (238, 130, 83), (238, 122, 77), (240, 118, 75), + (241, 110, 73), (240, 115, 73), (239, 120, 73), (238, 121, 72), + (238, 123, 71), (236, 125, 68), (235, 120, 66), (232, 110, 57), + (228, 98, 49), (218, 80, 35), (216, 77, 31), (214, 75, 27), + (211, 74, 27), (209, 71, 25), (207, 68, 23), (206, 65, 25), + (212, 67, 41), (215, 79, 52), (218, 92, 64), (220, 100, 70), + (222, 108, 76), (226, 126, 88), (231, 144, 101), (238, 155, 116), + (244, 169, 127), (252, 192, 140), (252, 195, 139), (253, 199, 139), + (253, 201, 133), (252, 196, 125), (250, 185, 114), (249, 174, 101), + (243, 152, 74), (241, 148, 67), (240, 144, 61), (236, 136, 49), + (229, 125, 36), (222, 114, 25), (213, 98, 15), (206, 85, 8), + (201, 77, 4), (195, 72, 2), (195, 72, 2), (195, 73, 2), + (195, 72, 2), (192, 66, 3), (190, 59, 2), (188, 53, 2), + (184, 43, 3), (185, 43, 3), (186, 43, 3), (183, 42, 3), + (178, 40, 3), (171, 36, 3), (156, 32, 6), (138, 29, 9), + (125, 29, 14), (121, 32, 20), (120, 37, 23), (130, 45, 28), + (138, 56, 37), (144, 66, 47), (146, 80, 58), (155, 95, 73), + (176, 117, 85), (185, 121, 88), (195, 126, 91), (212, 128, 94), + (222, 129, 93), (230, 130, 93), (232, 131, 91), (231, 133, 84), + (231, 135, 78), (231, 134, 74), (228, 130, 68), (224, 117, 61), + (215, 105, 53), (197, 96, 46), (179, 89, 38), (162, 85, 35), + (146, 86, 36), (140, 81, 39), (140, 72, 38), (137, 66, 38), + (137, 61, 38), (139, 59, 40), (137, 69, 49), (144, 81, 62), + (159, 94, 72), (174, 107, 80), (192, 119, 89), (212, 130, 98), + (224, 143, 108), (235, 157, 121), (242, 172, 133), (244, 184, 141), + (245, 190, 144), (245, 194, 147), (244, 192, 146), (245, 188, 142), + (245, 185, 137), (246, 180, 129), (246, 173, 120), (245, 167, 108), + (244, 161, 97), (241, 153, 86), (236, 145, 74), (232, 138, 59), + (228, 128, 50), (226, 118, 39), (226, 110, 33), (226, 106, 32), + (225, 107, 33), (222, 111, 32), (219, 114, 33), (215, 111, 30), + (211, 101, 27), (206, 89, 27), (203, 78, 26), (200, 72, 30), + (194, 69, 31), (188, 68, 27), (181, 61, 21), (174, 50, 16), + (165, 36, 7), (157, 25, 4), (151, 17, 3), (148, 16, 3), + (146, 17, 1), (148, 24, 1), (152, 33, 0), (154, 32, 0), + (157, 32, 1), (161, 32, 2), (163, 29, 1), (164, 27, 1) + ), + +// 427 040221-84 +((129, 81, 52), (116, 71, 50), (101, 62, 46), (87, 53, 43), + (83, 49, 38), (79, 46, 34), (82, 44, 33), (85, 43, 32), + (96, 43, 28), (99, 43, 27), (103, 43, 27), (106, 43, 25), + (109, 43, 24), (109, 43, 24), (110, 44, 25), (110, 43, 25), + (111, 43, 25), (116, 43, 25), (119, 44, 23), (122, 45, 22), + (127, 47, 21), (133, 50, 21), (136, 53, 23), (140, 56, 26), + (151, 63, 30), (155, 64, 28), (160, 65, 27), (162, 66, 28), + (165, 67, 29), (165, 68, 30), (165, 70, 32), (158, 72, 34), + (152, 72, 36), (128, 65, 35), (116, 62, 36), (104, 60, 38), + (91, 62, 39), (79, 65, 41), (74, 65, 40), (69, 65, 40), + (45, 65, 40), (42, 62, 40), (39, 60, 41), (45, 60, 40), + (52, 60, 39), (53, 59, 39), (54, 59, 40), (53, 60, 40), + (54, 59, 42), (53, 59, 43), (53, 60, 43), (54, 62, 44), + (48, 64, 49), (43, 67, 55), (40, 69, 58), (38, 71, 61), + (29, 81, 69), (29, 91, 76), (29, 101, 84), (30, 104, 86), + (31, 107, 88), (31, 107, 88), (31, 108, 89), (32, 101, 82), + (39, 101, 80), (52, 102, 77), (57, 97, 70), (63, 93, 63), + (71, 86, 58), (79, 79, 54), (82, 63, 44), (87, 55, 39), + (92, 45, 31), (89, 45, 32), (86, 46, 33), (80, 51, 36), + (75, 56, 40), (72, 60, 42), (70, 64, 45), (57, 71, 49), + (48, 73, 52), (37, 74, 60), (33, 74, 62), (29, 75, 64), + (28, 74, 64), (27, 74, 64), (26, 72, 61), (27, 69, 58), + (29, 58, 52), (29, 55, 50), (30, 53, 48), (29, 52, 47), + (29, 51, 46), (29, 51, 46), (29, 51, 46), (30, 52, 47), + (30, 55, 48), (31, 62, 54), (31, 64, 57), (31, 67, 61), + (32, 67, 60), (33, 68, 60), (36, 68, 61), (38, 68, 61), + (42, 72, 60), (40, 73, 60), (39, 75, 61), (38, 75, 61), + (38, 75, 61), (37, 74, 62), (37, 75, 60), (37, 75, 60), + (35, 75, 60), (30, 75, 59), (28, 73, 59), (27, 72, 59), + (26, 71, 58), (26, 69, 56), (25, 67, 56), (26, 65, 54), + (27, 62, 53), (27, 61, 53), (27, 60, 54), (27, 60, 54), + (28, 60, 54), (28, 60, 55), (28, 61, 55), (28, 62, 54), + (28, 63, 54), (28, 65, 56), (27, 65, 57), (27, 66, 59), + (27, 67, 61), (26, 68, 61), (26, 69, 60), (26, 69, 60), + (26, 68, 59), (26, 66, 60), (27, 65, 61), (27, 64, 59), + (28, 64, 57), (29, 61, 55), (32, 59, 51), (36, 57, 45), + (43, 57, 39), (69, 55, 34), (73, 56, 33), (77, 57, 32), + (82, 58, 31), (87, 57, 32), (87, 58, 33), (87, 63, 36), + (96, 80, 44), (97, 83, 45), (98, 86, 47), (101, 86, 48), + (99, 84, 46), (91, 77, 46), (86, 75, 46), (85, 74, 46), + (84, 73, 45), (88, 63, 40), (87, 59, 37), (86, 55, 34), + (81, 48, 29), (78, 42, 27), (74, 41, 26), (73, 39, 26), + (75, 38, 26), (75, 37, 26), (75, 36, 27), (75, 38, 28), + (73, 38, 29), (69, 40, 30), (66, 42, 31), (65, 42, 32), + (66, 43, 31), (70, 44, 31), (74, 44, 30), (75, 43, 30), + (72, 42, 30), (66, 42, 31), (61, 43, 32), (58, 43, 32), + (69, 42, 28), (72, 41, 27), (76, 41, 26), (79, 41, 26), + (82, 40, 27), (82, 39, 28), (83, 40, 27), (85, 39, 28), + (87, 40, 27), (87, 40, 27), (84, 42, 28), (80, 43, 29), + (75, 45, 31), (71, 45, 34), (66, 47, 35), (61, 46, 34), + (56, 45, 34), (52, 48, 34), (52, 48, 34), (56, 47, 33), + (62, 49, 33), (72, 48, 32), (82, 48, 30), (93, 47, 27), + (104, 46, 25), (116, 47, 23), (124, 48, 21), (133, 52, 19), + (139, 55, 19), (140, 56, 20), (138, 58, 21), (133, 58, 24), + (123, 58, 27), (113, 57, 29), (106, 59, 30), (99, 57, 31), + (95, 54, 31), (93, 55, 32), (90, 54, 34), (87, 52, 35), + (89, 51, 34), (94, 49, 31), (101, 47, 27), (111, 48, 25), + (119, 48, 23), (126, 51, 25), (131, 58, 29), (136, 65, 37), + (144, 65, 40), (147, 65, 43), (149, 63, 40), (149, 60, 39), + (150, 58, 37), (145, 64, 40), (147, 63, 43), (145, 62, 46), + (143, 58, 44), (140, 53, 41), (138, 46, 33), (131, 46, 28), + (126, 45, 28), (121, 47, 29), (120, 51, 31), (123, 56, 34), + (129, 64, 37), (141, 77, 42), (153, 81, 48), (140, 82, 51), + (131, 80, 52), (122, 82, 53), (111, 77, 52), (110, 82, 50) + ), + +// 428 040221-85 +((13, 33, 5), (13, 29, 6), (13, 27, 6), (14, 26, 6), + (14, 26, 5), (15, 26, 5), (14, 25, 5), (14, 25, 6), + (19, 30, 12), (25, 35, 12), (32, 40, 13), (38, 52, 13), + (45, 64, 14), (47, 79, 12), (50, 95, 10), (49, 101, 11), + (48, 108, 13), (52, 112, 12), (53, 111, 12), (54, 111, 12), + (53, 111, 9), (52, 112, 6), (49, 112, 6), (46, 113, 6), + (37, 101, 2), (31, 86, 2), (26, 71, 2), (22, 57, 2), + (19, 43, 2), (18, 40, 2), (17, 37, 3), (17, 36, 3), + (18, 39, 2), (27, 61, 2), (30, 69, 1), (34, 78, 1), + (34, 79, 1), (35, 81, 2), (34, 79, 2), (33, 77, 3), + (33, 79, 4), (34, 82, 3), (36, 85, 3), (34, 82, 2), + (33, 79, 2), (31, 73, 2), (29, 68, 3), (24, 55, 3), + (20, 44, 6), (20, 36, 14), (27, 43, 19), (34, 51, 24), + (45, 63, 36), (56, 76, 48), (64, 83, 55), (72, 90, 63), + (101, 120, 89), (111, 127, 91), (122, 135, 94), (125, 136, 91), + (129, 138, 89), (130, 139, 92), (132, 141, 96), (131, 148, 103), + (132, 152, 113), (125, 153, 120), (115, 141, 103), (106, 130, 87), + (98, 122, 79), (91, 115, 71), (76, 104, 59), (63, 96, 52), + (47, 96, 53), (43, 92, 51), (39, 88, 50), (35, 80, 40), + (31, 72, 31), (29, 68, 26), (27, 64, 22), (23, 58, 15), + (20, 54, 7), (14, 45, 9), (13, 41, 10), (12, 37, 12), + (12, 34, 13), (13, 32, 15), (13, 28, 18), (14, 29, 20), + (22, 47, 35), (34, 64, 47), (46, 82, 59), (56, 90, 68), + (66, 99, 78), (84, 113, 97), (104, 128, 113), (122, 143, 133), + (140, 158, 149), (167, 194, 177), (179, 208, 184), (191, 223, 191), + (193, 225, 191), (195, 227, 191), (193, 221, 189), (187, 209, 181), + (160, 177, 159), (145, 163, 141), (130, 150, 123), (122, 143, 114), + (114, 137, 106), (97, 123, 91), (78, 109, 77), (60, 96, 66), + (48, 85, 61), (47, 80, 61), (50, 82, 62), (53, 84, 63), + (62, 90, 69), (71, 97, 78), (73, 100, 82), (73, 101, 86), + (74, 105, 91), (75, 104, 88), (76, 104, 85), (78, 104, 84), + (80, 105, 83), (78, 102, 76), (72, 95, 68), (64, 84, 59), + (54, 77, 49), (34, 59, 27), (31, 56, 23), (28, 54, 20), + (22, 52, 13), (19, 52, 8), (19, 50, 5), (18, 50, 4), + (20, 53, 5), (22, 54, 10), (25, 56, 15), (27, 60, 19), + (30, 65, 24), (40, 75, 35), (50, 85, 47), (62, 98, 58), + (74, 109, 69), (93, 125, 86), (94, 130, 88), (96, 135, 90), + (100, 145, 89), (102, 154, 90), (102, 160, 88), (103, 161, 84), + (99, 148, 76), (94, 142, 73), (90, 137, 71), (80, 125, 58), + (69, 116, 46), (57, 106, 33), (46, 95, 20), (36, 81, 13), + (29, 68, 7), (19, 41, 7), (17, 37, 7), (16, 33, 7), + (15, 29, 7), (14, 27, 7), (14, 27, 8), (15, 28, 9), + (16, 30, 13), (16, 31, 14), (17, 32, 16), (17, 34, 17), + (18, 36, 19), (18, 37, 20), (18, 38, 21), (20, 38, 23), + (20, 39, 25), (20, 42, 28), (20, 44, 30), (19, 46, 35), + (19, 49, 38), (20, 51, 41), (23, 55, 45), (30, 59, 52), + (57, 82, 74), (65, 90, 83), (73, 98, 92), (91, 115, 109), + (109, 131, 126), (123, 146, 140), (138, 158, 154), (153, 170, 166), + (168, 182, 177), (181, 195, 188), (193, 206, 199), (201, 214, 208), + (203, 221, 216), (202, 227, 225), (201, 231, 228), (195, 231, 230), + (185, 227, 226), (176, 222, 220), (167, 216, 213), (156, 205, 202), + (144, 195, 193), (136, 187, 184), (127, 180, 178), (118, 170, 168), + (107, 160, 157), (99, 151, 146), (91, 140, 132), (80, 125, 118), + (73, 116, 106), (67, 112, 104), (65, 107, 101), (62, 103, 98), + (58, 103, 97), (60, 106, 98), (64, 107, 99), (69, 110, 99), + (76, 118, 105), (83, 122, 114), (90, 126, 120), (90, 132, 127), + (93, 136, 131), (96, 138, 131), (98, 139, 130), (100, 142, 128), + (101, 143, 128), (104, 145, 125), (103, 147, 117), (102, 154, 107), + (98, 153, 93), (94, 152, 84), (91, 154, 80), (91, 154, 81), + (95, 157, 90), (104, 160, 100), (119, 176, 113), (131, 185, 115), + (144, 191, 108), (150, 197, 98), (151, 196, 88), (143, 186, 82), + (133, 171, 81), (126, 163, 85), (118, 153, 89), (114, 142, 86), + (109, 133, 78), (104, 126, 66), (90, 116, 48), (74, 101, 30), + (57, 85, 15), (40, 69, 8), (26, 54, 6), (17, 42, 5) + ), + +// 429 040221-86 +((134, 121, 111), (121, 114, 111), (114, 110, 106), (107, 107, 101), + (114, 114, 103), (121, 122, 106), (127, 126, 105), (133, 130, 105), + (148, 145, 99), (150, 148, 97), (153, 152, 95), (146, 144, 95), + (140, 137, 95), (131, 129, 97), (122, 121, 100), (120, 120, 101), + (118, 119, 103), (109, 112, 104), (109, 111, 103), (109, 111, 103), + (114, 110, 100), (120, 109, 98), (121, 106, 94), (123, 104, 91), + (117, 98, 77), (113, 95, 75), (110, 93, 74), (107, 85, 73), + (104, 77, 72), (102, 76, 72), (101, 75, 72), (104, 78, 75), + (112, 88, 77), (141, 109, 78), (157, 119, 82), (173, 129, 86), + (190, 141, 88), (208, 154, 91), (213, 158, 88), (218, 162, 86), + (217, 172, 91), (215, 176, 102), (214, 180, 113), (211, 177, 110), + (208, 174, 108), (204, 170, 104), (201, 167, 101), (200, 161, 99), + (199, 157, 100), (200, 144, 93), (197, 132, 81), (195, 120, 70), + (196, 119, 68), (197, 118, 66), (198, 119, 68), (199, 121, 71), + (193, 125, 79), (187, 131, 87), (182, 138, 95), (173, 140, 105), + (165, 142, 115), (160, 140, 118), (155, 138, 122), (147, 135, 125), + (145, 136, 123), (151, 134, 118), (155, 132, 119), (159, 131, 121), + (164, 134, 121), (170, 138, 122), (181, 145, 127), (193, 156, 131), + (194, 166, 142), (186, 163, 146), (179, 160, 150), (176, 164, 156), + (173, 168, 163), (173, 172, 168), (173, 176, 173), (171, 175, 176), + (169, 173, 176), (174, 174, 170), (181, 182, 172), (188, 190, 175), + (190, 191, 174), (192, 192, 173), (189, 188, 165), (185, 182, 153), + (174, 165, 134), (171, 155, 120), (169, 145, 106), (165, 139, 97), + (162, 133, 89), (156, 121, 75), (149, 107, 65), (145, 93, 53), + (142, 80, 42), (127, 57, 22), (120, 50, 16), (114, 43, 11), + (114, 43, 11), (115, 44, 12), (120, 47, 11), (124, 54, 15), + (134, 65, 21), (140, 73, 24), (146, 81, 28), (148, 84, 29), + (151, 88, 30), (155, 91, 30), (159, 91, 32), (160, 91, 33), + (162, 90, 35), (159, 91, 38), (156, 91, 41), (153, 91, 44), + (142, 89, 51), (132, 84, 57), (125, 82, 63), (118, 79, 65), + (98, 79, 76), (96, 79, 81), (95, 79, 86), (98, 78, 84), + (101, 78, 82), (105, 78, 74), (111, 77, 69), (114, 73, 64), + (125, 74, 63), (143, 78, 53), (146, 78, 50), (149, 79, 48), + (150, 77, 43), (156, 78, 43), (163, 88, 45), (168, 96, 46), + (172, 103, 47), (175, 104, 50), (178, 105, 53), (180, 107, 55), + (182, 110, 57), (186, 116, 61), (183, 119, 61), (177, 119, 61), + (170, 115, 63), (167, 108, 61), (167, 108, 60), (167, 108, 59), + (169, 115, 59), (171, 121, 66), (170, 125, 70), (170, 128, 75), + (162, 125, 83), (159, 124, 87), (157, 124, 92), (150, 120, 98), + (141, 118, 103), (129, 115, 104), (123, 110, 98), (119, 104, 92), + (116, 93, 86), (107, 73, 68), (104, 69, 63), (101, 66, 59), + (98, 62, 52), (96, 61, 51), (93, 63, 51), (91, 60, 49), + (71, 53, 50), (66, 51, 50), (61, 49, 50), (50, 48, 52), + (45, 42, 46), (40, 38, 40), (37, 34, 35), (35, 32, 32), + (37, 34, 35), (38, 35, 37), (38, 36, 40), (43, 39, 46), + (47, 44, 52), (57, 54, 62), (70, 70, 71), (83, 84, 78), + (109, 106, 87), (115, 109, 88), (121, 112, 89), (135, 121, 88), + (149, 129, 88), (161, 134, 83), (173, 137, 78), (179, 136, 74), + (181, 135, 71), (180, 131, 68), (174, 125, 63), (170, 115, 54), + (163, 103, 45), (148, 91, 40), (135, 83, 36), (123, 74, 31), + (117, 67, 25), (121, 63, 17), (120, 60, 15), (120, 65, 18), + (125, 71, 20), (134, 80, 24), (151, 95, 26), (168, 109, 33), + (180, 123, 44), (186, 137, 58), (193, 148, 76), (198, 160, 90), + (200, 167, 100), (202, 170, 108), (197, 171, 113), (195, 168, 118), + (194, 167, 122), (192, 165, 124), (191, 161, 121), (187, 157, 114), + (183, 146, 102), (178, 134, 88), (172, 124, 77), (159, 112, 72), + (146, 106, 72), (135, 100, 72), (126, 95, 70), (127, 95, 64), + (124, 91, 58), (121, 88, 54), (119, 86, 54), (116, 85, 54), + (121, 89, 53), (128, 92, 49), (127, 90, 48), (122, 84, 44), + (113, 75, 42), (102, 66, 41), (95, 63, 37), (82, 57, 39), + (71, 52, 42), (59, 50, 47), (54, 47, 51), (57, 51, 56), + (61, 56, 61), (72, 65, 66), (83, 77, 73), (97, 87, 76), + (113, 99, 82), (126, 108, 90), (142, 123, 98), (157, 137, 108), + (155, 135, 107), (149, 131, 105), (140, 122, 103), (129, 114, 102) + ), + +// 430 040221-88 +((71, 61, 35), (62, 67, 39), (60, 73, 48), (58, 79, 57), + (54, 84, 66), (51, 89, 75), (55, 93, 80), (60, 98, 85), + (70, 115, 92), (73, 122, 98), (76, 129, 104), (83, 134, 110), + (91, 139, 117), (103, 142, 124), (116, 145, 131), (121, 147, 133), + (126, 150, 135), (139, 156, 141), (138, 158, 139), (137, 161, 138), + (133, 162, 135), (130, 164, 133), (128, 164, 133), (127, 165, 133), + (125, 159, 130), (119, 152, 126), (113, 146, 123), (105, 138, 113), + (97, 130, 104), (92, 126, 99), (88, 122, 95), (83, 118, 90), + (85, 115, 86), (87, 111, 88), (87, 107, 87), (88, 104, 87), + (86, 98, 83), (84, 93, 79), (84, 90, 77), (85, 88, 75), + (85, 82, 68), (87, 78, 66), (89, 74, 65), (98, 67, 58), + (107, 61, 52), (110, 59, 52), (114, 58, 52), (117, 59, 55), + (124, 61, 58), (133, 79, 77), (144, 87, 87), (156, 95, 97), + (163, 101, 101), (170, 107, 106), (170, 108, 107), (170, 109, 109), + (151, 114, 104), (141, 115, 106), (132, 116, 108), (126, 112, 101), + (120, 108, 94), (115, 102, 90), (110, 97, 86), (98, 81, 71), + (83, 65, 53), (58, 40, 31), (51, 34, 26), (45, 28, 21), + (43, 25, 20), (41, 23, 19), (37, 18, 17), (33, 13, 14), + (27, 9, 11), (24, 8, 11), (21, 8, 11), (19, 8, 10), + (17, 9, 10), (17, 9, 9), (18, 10, 9), (20, 11, 9), + (24, 12, 7), (33, 12, 4), (36, 13, 3), (40, 14, 3), + (41, 13, 2), (42, 13, 2), (43, 13, 2), (44, 13, 3), + (49, 12, 6), (53, 12, 7), (57, 12, 9), (59, 12, 8), + (62, 12, 8), (65, 12, 7), (67, 11, 7), (69, 10, 5), + (68, 9, 7), (64, 8, 10), (64, 8, 9), (64, 8, 9), + (63, 8, 8), (62, 9, 8), (61, 10, 5), (60, 9, 4), + (54, 7, 4), (50, 5, 4), (47, 4, 4), (44, 4, 4), + (42, 5, 4), (37, 8, 3), (33, 8, 3), (32, 10, 4), + (32, 12, 5), (32, 16, 6), (32, 17, 7), (33, 19, 8), + (35, 23, 9), (38, 29, 12), (40, 37, 14), (45, 46, 16), + (58, 60, 23), (60, 61, 24), (62, 63, 26), (63, 63, 26), + (65, 63, 27), (63, 61, 27), (64, 63, 26), (66, 65, 25), + (72, 65, 26), (82, 58, 25), (85, 54, 24), (89, 51, 23), + (92, 43, 23), (93, 39, 25), (94, 41, 27), (96, 45, 32), + (100, 53, 46), (105, 53, 48), (110, 54, 50), (109, 54, 50), + (109, 55, 51), (112, 57, 51), (114, 63, 54), (115, 68, 63), + (116, 78, 73), (125, 96, 89), (124, 98, 91), (123, 101, 93), + (120, 104, 93), (118, 106, 90), (117, 108, 90), (116, 111, 92), + (124, 122, 100), (127, 123, 102), (130, 125, 104), (134, 126, 106), + (140, 121, 100), (144, 113, 91), (149, 104, 83), (146, 93, 73), + (142, 83, 63), (131, 65, 49), (128, 61, 45), (125, 57, 42), + (120, 48, 33), (121, 40, 28), (116, 35, 24), (106, 34, 27), + (85, 49, 42), (79, 57, 50), (74, 66, 59), (63, 81, 74), + (60, 91, 84), (64, 99, 90), (68, 109, 102), (78, 119, 110), + (82, 123, 115), (89, 134, 126), (92, 145, 135), (91, 146, 139), + (92, 142, 131), (90, 135, 125), (91, 127, 114), (87, 110, 96), + (81, 87, 71), (76, 80, 66), (72, 74, 62), (62, 62, 50), + (50, 49, 42), (39, 40, 33), (31, 31, 23), (26, 23, 16), + (24, 19, 11), (25, 15, 7), (28, 13, 3), (33, 10, 3), + (37, 9, 4), (41, 10, 4), (43, 11, 5), (43, 12, 6), + (43, 14, 7), (43, 18, 8), (44, 19, 8), (46, 21, 9), + (47, 23, 11), (49, 26, 13), (48, 29, 16), (48, 33, 20), + (46, 38, 24), (44, 41, 30), (46, 46, 34), (51, 52, 40), + (57, 60, 48), (64, 68, 55), (72, 75, 59), (79, 83, 63), + (83, 87, 67), (87, 90, 70), (92, 94, 72), (97, 98, 76), + (100, 100, 81), (105, 104, 81), (109, 106, 82), (108, 106, 79), + (106, 101, 75), (106, 96, 70), (106, 88, 63), (106, 79, 58), + (108, 72, 51), (112, 64, 46), (111, 58, 40), (109, 51, 34), + (107, 46, 29), (104, 39, 24), (98, 33, 18), (93, 29, 13), + (89, 23, 9), (84, 19, 4), (79, 16, 2), (75, 17, 3), + (71, 19, 5), (66, 24, 9), (62, 30, 14), (59, 36, 18), + (55, 43, 22), (52, 49, 25), (51, 50, 26), (54, 48, 25), + (60, 47, 24), (70, 47, 24), (70, 45, 24), (69, 47, 25), + (68, 51, 30), (67, 55, 32), (64, 55, 34), (62, 57, 34) + ), + +// 431 040221-89 +((25, 36, 53), (32, 40, 69), (33, 41, 74), (34, 42, 79), + (35, 43, 79), (37, 44, 80), (36, 48, 86), (35, 52, 92), + (32, 68, 120), (34, 74, 131), (37, 81, 143), (41, 84, 147), + (46, 87, 151), (49, 89, 152), (52, 92, 154), (53, 93, 155), + (55, 94, 157), (62, 106, 160), (69, 109, 163), (76, 113, 166), + (81, 115, 168), (87, 117, 171), (90, 116, 172), (94, 116, 173), + (101, 116, 171), (106, 115, 169), (111, 115, 168), (110, 115, 167), + (110, 116, 167), (108, 116, 166), (107, 116, 165), (101, 111, 163), + (95, 103, 155), (82, 82, 127), (74, 74, 117), (67, 66, 107), + (60, 68, 107), (54, 71, 108), (52, 72, 110), (50, 74, 113), + (55, 91, 130), (67, 101, 139), (79, 111, 149), (94, 126, 161), + (110, 142, 173), (116, 150, 179), (123, 158, 186), (140, 174, 199), + (154, 190, 214), (178, 202, 223), (185, 200, 218), (192, 199, 214), + (188, 186, 198), (184, 174, 183), (178, 168, 175), (173, 163, 168), + (141, 129, 135), (122, 112, 119), (103, 96, 103), (84, 78, 88), + (65, 61, 73), (58, 54, 67), (51, 48, 62), (43, 42, 56), + (42, 39, 54), (51, 56, 65), (65, 72, 80), (80, 89, 95), + (88, 97, 103), (97, 106, 112), (112, 125, 130), (128, 140, 147), + (157, 168, 175), (165, 173, 181), (174, 178, 187), (173, 174, 183), + (173, 171, 180), (169, 166, 175), (165, 161, 171), (158, 153, 159), + (144, 141, 146), (111, 110, 118), (93, 91, 100), (76, 72, 83), + (67, 62, 73), (58, 53, 64), (45, 39, 47), (34, 29, 33), + (21, 20, 20), (19, 19, 19), (18, 18, 18), (17, 18, 17), + (17, 18, 17), (18, 18, 17), (18, 18, 17), (18, 18, 16), + (17, 17, 16), (16, 18, 15), (15, 17, 15), (14, 17, 15), + (13, 16, 14), (13, 16, 13), (12, 15, 12), (12, 14, 11), + (13, 14, 12), (14, 15, 14), (16, 17, 16), (16, 17, 18), + (17, 18, 21), (19, 22, 28), (21, 28, 38), (26, 36, 51), + (32, 47, 69), (44, 71, 104), (47, 76, 112), (50, 82, 121), + (52, 88, 134), (50, 91, 141), (46, 90, 142), (45, 90, 141), + (41, 87, 136), (44, 88, 134), (47, 89, 132), (46, 90, 133), + (46, 91, 134), (42, 89, 133), (40, 87, 129), (40, 87, 127), + (45, 90, 126), (81, 109, 132), (91, 117, 137), (102, 126, 143), + (122, 144, 160), (139, 161, 177), (153, 177, 195), (163, 193, 211), + (192, 216, 236), (195, 218, 238), (199, 221, 241), (197, 219, 239), + (196, 217, 237), (187, 207, 228), (168, 192, 216), (152, 178, 200), + (137, 161, 185), (102, 127, 151), (92, 119, 143), (83, 111, 136), + (65, 93, 117), (48, 75, 100), (33, 61, 82), (24, 48, 67), + (16, 30, 42), (16, 27, 38), (16, 25, 35), (19, 22, 31), + (23, 25, 33), (30, 31, 39), (39, 38, 48), (50, 47, 61), + (60, 57, 75), (80, 74, 98), (83, 78, 102), (87, 82, 107), + (90, 88, 115), (94, 94, 120), (98, 97, 125), (99, 102, 131), + (102, 112, 145), (102, 114, 147), (102, 116, 149), (99, 118, 153), + (95, 116, 154), (89, 110, 150), (83, 102, 145), (74, 92, 138), + (70, 87, 135), (67, 82, 133), (63, 81, 134), (63, 81, 138), + (64, 80, 142), (66, 78, 143), (64, 74, 142), (63, 70, 135), + (53, 58, 115), (50, 55, 110), (48, 52, 105), (44, 48, 96), + (41, 43, 88), (39, 41, 82), (37, 40, 75), (36, 39, 69), + (35, 38, 64), (32, 37, 61), (31, 38, 59), (32, 36, 59), + (33, 35, 62), (34, 36, 65), (36, 38, 70), (43, 42, 76), + (47, 47, 86), (54, 57, 95), (65, 68, 109), (80, 85, 126), + (97, 103, 144), (112, 120, 160), (129, 134, 173), (144, 147, 184), + (156, 158, 194), (165, 164, 200), (167, 171, 204), (170, 177, 208), + (169, 181, 211), (167, 184, 212), (167, 187, 212), (169, 187, 210), + (164, 176, 205), (152, 163, 197), (137, 146, 184), (118, 129, 169), + (95, 110, 151), (74, 95, 133), (62, 84, 115), (53, 73, 101), + (49, 64, 91), (46, 56, 84), (44, 51, 79), (40, 46, 75), + (32, 45, 74), (27, 48, 75), (23, 53, 79), (21, 59, 85), + (20, 62, 92), (19, 66, 98), (20, 66, 101), (19, 65, 101), + (18, 64, 100), (16, 62, 99), (15, 60, 98), (13, 58, 96), + (11, 57, 93), (10, 52, 85), (10, 45, 74), (9, 38, 61), + (9, 30, 48), (9, 23, 37), (11, 17, 30), (14, 18, 30), + (15, 24, 37), (18, 28, 43), (21, 29, 43), (22, 30, 42), + (22, 30, 42), (21, 30, 40), (25, 28, 37), (24, 30, 41) + ), + +// 432 040221-90 +((2, 0, 1), (0, 0, 1), (0, 0, 1), (1, 0, 2), + (1, 0, 1), (2, 0, 0), (3, 0, 0), (4, 0, 0), + (8, 4, 1), (13, 9, 4), (18, 14, 7), (24, 20, 13), + (31, 27, 19), (35, 31, 23), (40, 36, 27), (40, 37, 28), + (41, 38, 30), (38, 34, 28), (32, 28, 22), (26, 23, 17), + (20, 18, 12), (15, 13, 8), (13, 11, 6), (12, 9, 4), + (14, 12, 6), (20, 17, 11), (27, 23, 17), (36, 32, 25), + (45, 41, 33), (50, 46, 37), (56, 51, 41), (62, 57, 47), + (64, 61, 49), (68, 60, 44), (65, 59, 43), (63, 58, 42), + (66, 60, 44), (70, 63, 47), (73, 66, 51), (76, 70, 55), + (92, 86, 70), (95, 90, 75), (99, 95, 80), (96, 93, 80), + (94, 91, 80), (91, 87, 76), (88, 84, 73), (81, 78, 66), + (74, 71, 59), (60, 56, 47), (58, 53, 44), (56, 51, 42), + (59, 53, 43), (62, 56, 45), (67, 60, 46), (72, 65, 47), + (104, 96, 61), (126, 115, 75), (148, 135, 89), (172, 159, 109), + (196, 184, 130), (196, 185, 139), (197, 186, 148), (188, 180, 136), + (180, 174, 126), (137, 132, 93), (133, 123, 80), (129, 114, 67), + (132, 120, 69), (135, 126, 72), (151, 141, 84), (166, 152, 98), + (168, 163, 120), (154, 149, 113), (141, 135, 106), (122, 117, 93), + (103, 99, 81), (93, 89, 70), (83, 79, 60), (70, 65, 44), + (58, 55, 31), (36, 34, 16), (31, 28, 10), (26, 23, 4), + (24, 21, 4), (22, 20, 4), (21, 18, 2), (21, 18, 1), + (22, 19, 5), (22, 19, 8), (23, 20, 11), (23, 20, 12), + (23, 21, 14), (24, 20, 16), (21, 17, 17), (19, 17, 16), + (18, 16, 15), (10, 8, 8), (9, 9, 6), (8, 11, 4), + (8, 10, 4), (9, 9, 4), (12, 13, 5), (19, 19, 6), + (43, 38, 21), (50, 46, 27), (58, 55, 33), (57, 53, 31), + (57, 52, 30), (58, 54, 40), (49, 46, 34), (36, 32, 20), + (28, 24, 15), (23, 18, 10), (22, 18, 10), (22, 18, 10), + (25, 19, 10), (28, 25, 12), (30, 28, 16), (32, 28, 18), + (33, 29, 20), (33, 28, 19), (33, 28, 19), (33, 27, 18), + (33, 27, 17), (35, 30, 15), (38, 36, 17), (43, 39, 19), + (45, 41, 20), (50, 47, 31), (50, 46, 32), (50, 46, 33), + (49, 45, 36), (49, 44, 38), (50, 45, 39), (49, 45, 37), + (52, 49, 35), (52, 49, 34), (53, 50, 33), (53, 50, 33), + (53, 51, 33), (53, 51, 35), (54, 51, 37), (55, 50, 37), + (55, 50, 35), (55, 48, 35), (54, 47, 34), (54, 47, 33), + (50, 44, 30), (47, 39, 26), (42, 37, 24), (39, 34, 22), + (39, 32, 20), (40, 33, 21), (42, 35, 23), (49, 41, 28), + (58, 51, 32), (71, 65, 39), (88, 82, 51), (108, 101, 62), + (127, 118, 76), (140, 131, 90), (139, 130, 92), (139, 130, 94), + (135, 126, 96), (117, 109, 85), (103, 99, 76), (97, 91, 71), + (85, 77, 59), (83, 75, 59), (81, 74, 59), (81, 74, 59), + (82, 75, 58), (83, 76, 61), (85, 80, 64), (89, 83, 66), + (91, 84, 68), (90, 84, 70), (89, 83, 69), (88, 81, 69), + (87, 79, 68), (83, 77, 63), (80, 73, 59), (76, 69, 53), + (59, 55, 36), (55, 50, 34), (51, 46, 32), (41, 37, 25), + (32, 28, 18), (26, 21, 18), (23, 17, 16), (21, 15, 14), + (21, 16, 14), (25, 20, 17), (31, 27, 21), (39, 34, 26), + (48, 44, 35), (56, 54, 44), (65, 62, 52), (73, 68, 58), + (76, 72, 59), (78, 74, 56), (80, 71, 54), (78, 66, 50), + (74, 66, 45), (73, 65, 42), (70, 62, 41), (66, 60, 40), + (63, 60, 37), (59, 56, 35), (54, 51, 32), (49, 43, 26), + (42, 37, 23), (37, 33, 22), (33, 28, 20), (30, 24, 20), + (29, 25, 21), (27, 24, 19), (28, 23, 19), (29, 25, 18), + (29, 26, 15), (28, 24, 12), (27, 24, 12), (26, 23, 9), + (24, 19, 6), (21, 16, 5), (16, 13, 3), (12, 9, 0), + (9, 8, 0), (5, 6, 0), (2, 3, 0), (1, 3, 0), + (2, 2, 0), (2, 1, 0), (3, 0, 0), (4, 0, 0), + (4, 0, 0), (4, 0, 0), (4, 0, 0), (5, 0, 0), + (6, 1, 0), (7, 2, 2), (8, 2, 3), (9, 4, 4), + (11, 5, 7), (12, 5, 8), (13, 8, 5), (13, 8, 5), + (12, 8, 4), (10, 9, 1), (8, 7, 0), (7, 5, 0), + (4, 3, 0), (3, 1, 0), (3, 0, 0), (2, 0, 0) + ), + +// 433 040221-91 +((118, 89, 90), (111, 85, 88), (100, 81, 83), (90, 77, 78), + (79, 75, 74), (69, 74, 70), (64, 73, 68), (59, 72, 67), + (41, 65, 61), (37, 62, 58), (33, 60, 56), (28, 59, 55), + (24, 58, 54), (20, 58, 56), (17, 59, 59), (17, 59, 59), + (17, 59, 60), (17, 62, 63), (17, 64, 67), (18, 67, 71), + (19, 65, 70), (21, 63, 69), (23, 62, 67), (25, 61, 65), + (29, 57, 58), (27, 52, 51), (25, 47, 44), (23, 40, 36), + (21, 33, 28), (21, 31, 26), (21, 30, 24), (19, 28, 20), + (17, 29, 21), (8, 28, 23), (5, 27, 23), (3, 27, 23), + (3, 27, 24), (3, 28, 25), (3, 28, 25), (4, 28, 26), + (10, 30, 29), (12, 32, 30), (15, 34, 32), (18, 39, 36), + (21, 44, 41), (24, 47, 44), (28, 51, 48), (31, 58, 56), + (36, 64, 63), (56, 82, 81), (71, 90, 88), (86, 98, 96), + (92, 98, 96), (98, 99, 96), (100, 98, 94), (102, 98, 93), + (104, 92, 88), (95, 87, 83), (86, 83, 79), (71, 74, 70), + (56, 65, 61), (48, 61, 57), (41, 57, 54), (28, 52, 50), + (17, 48, 46), (5, 38, 36), (5, 36, 33), (5, 35, 31), + (5, 35, 31), (6, 36, 31), (10, 38, 34), (16, 41, 36), + (30, 46, 43), (38, 52, 50), (46, 59, 58), (60, 67, 68), + (75, 75, 79), (81, 79, 83), (87, 84, 88), (95, 89, 91), + (96, 91, 93), (91, 92, 91), (87, 92, 90), (84, 93, 90), + (81, 91, 88), (78, 90, 86), (70, 87, 80), (64, 83, 75), + (69, 88, 81), (85, 96, 90), (101, 105, 99), (110, 111, 104), + (120, 117, 109), (140, 127, 119), (156, 138, 129), (171, 144, 138), + (182, 146, 143), (177, 141, 138), (162, 133, 128), (148, 125, 119), + (139, 118, 112), (130, 111, 106), (109, 97, 94), (85, 83, 82), + (47, 63, 59), (36, 57, 53), (25, 52, 48), (22, 50, 47), + (19, 49, 46), (17, 49, 46), (19, 49, 46), (24, 49, 47), + (32, 50, 48), (53, 59, 56), (57, 61, 58), (61, 64, 60), + (71, 67, 63), (78, 68, 62), (85, 69, 64), (89, 71, 64), + (90, 72, 66), (87, 69, 62), (85, 67, 59), (83, 65, 57), + (82, 64, 56), (75, 62, 52), (71, 61, 52), (68, 62, 51), + (67, 63, 50), (65, 65, 52), (63, 66, 53), (62, 68, 55), + (58, 72, 59), (54, 76, 61), (52, 78, 62), (50, 77, 62), + (42, 74, 62), (41, 73, 60), (41, 72, 59), (42, 70, 57), + (43, 69, 56), (45, 65, 55), (46, 61, 52), (48, 55, 47), + (49, 52, 43), (47, 46, 37), (45, 45, 37), (43, 44, 38), + (39, 42, 39), (34, 40, 40), (29, 40, 38), (26, 40, 38), + (25, 46, 46), (28, 49, 50), (31, 53, 55), (43, 64, 67), + (57, 75, 75), (76, 85, 84), (95, 95, 94), (114, 105, 103), + (135, 116, 112), (159, 124, 122), (164, 127, 125), (170, 130, 128), + (182, 134, 135), (195, 144, 142), (205, 150, 149), (210, 153, 153), + (217, 163, 167), (219, 167, 170), (221, 171, 173), (226, 178, 181), + (231, 183, 186), (237, 191, 193), (242, 198, 199), (244, 204, 203), + (244, 205, 204), (238, 201, 198), (232, 195, 192), (224, 188, 185), + (216, 181, 175), (206, 171, 165), (187, 156, 150), (166, 136, 131), + (113, 96, 91), (102, 88, 83), (92, 81, 76), (72, 68, 64), + (58, 58, 56), (48, 52, 51), (46, 52, 51), (56, 57, 56), + (70, 62, 64), (84, 71, 74), (99, 80, 83), (111, 91, 94), + (124, 106, 107), (140, 115, 118), (153, 122, 126), (162, 125, 129), + (163, 124, 128), (160, 127, 130), (154, 127, 128), (147, 124, 124), + (142, 117, 117), (133, 108, 107), (125, 99, 100), (111, 91, 92), + (97, 83, 83), (81, 76, 75), (66, 68, 68), (54, 62, 63), + (42, 58, 60), (33, 55, 58), (26, 54, 57), (22, 54, 57), + (20, 55, 57), (17, 56, 58), (13, 54, 58), (12, 52, 57), + (11, 52, 56), (12, 53, 55), (12, 54, 55), (11, 53, 55), + (12, 50, 53), (13, 50, 54), (18, 54, 56), (28, 60, 60), + (42, 69, 68), (60, 77, 76), (75, 84, 85), (90, 93, 93), + (105, 104, 104), (123, 116, 116), (145, 129, 129), (164, 137, 139), + (179, 141, 145), (186, 143, 148), (189, 143, 148), (191, 143, 148), + (186, 140, 144), (177, 133, 136), (167, 123, 126), (152, 112, 112), + (138, 101, 101), (122, 92, 89), (107, 85, 79), (94, 78, 71), + (86, 76, 67), (84, 76, 67), (92, 78, 71), (98, 81, 75), + (107, 82, 78), (114, 82, 80), (113, 84, 82), (120, 86, 87) + ), + +// 434 040221-92 +((60, 43, 7), (55, 41, 9), (50, 37, 9), (46, 34, 10), + (38, 31, 9), (31, 28, 8), (31, 28, 6), (32, 29, 5), + (35, 27, 4), (32, 24, 5), (29, 21, 7), (25, 17, 9), + (22, 14, 11), (19, 12, 11), (17, 10, 12), (16, 9, 13), + (16, 8, 14), (13, 6, 16), (10, 6, 17), (7, 6, 18), + (4, 6, 17), (2, 6, 16), (2, 5, 15), (2, 5, 14), + (5, 3, 9), (8, 3, 7), (11, 3, 6), (13, 4, 5), + (16, 6, 4), (17, 6, 3), (18, 7, 2), (20, 8, 1), + (24, 8, 0), (31, 8, 0), (35, 8, 1), (39, 8, 2), + (43, 9, 5), (47, 11, 8), (47, 12, 9), (48, 14, 10), + (51, 19, 12), (49, 17, 12), (47, 16, 13), (47, 13, 15), + (47, 11, 17), (46, 10, 17), (46, 10, 17), (47, 9, 18), + (48, 11, 16), (53, 12, 12), (52, 11, 10), (51, 10, 8), + (50, 8, 7), (49, 7, 6), (48, 7, 4), (48, 8, 3), + (54, 14, 2), (60, 18, 2), (66, 23, 2), (71, 26, 2), + (76, 29, 2), (78, 30, 2), (80, 32, 2), (83, 36, 4), + (87, 41, 6), (103, 53, 13), (111, 57, 14), (119, 61, 15), + (122, 60, 14), (125, 59, 13), (129, 58, 13), (128, 56, 11), + (122, 57, 11), (114, 57, 12), (106, 57, 13), (96, 52, 12), + (87, 47, 11), (82, 43, 11), (77, 40, 12), (68, 36, 12), + (68, 38, 19), (76, 48, 28), (80, 51, 27), (84, 55, 26), + (85, 54, 26), (87, 53, 26), (85, 50, 21), (83, 48, 24), + (94, 51, 31), (99, 57, 30), (105, 64, 30), (106, 65, 29), + (108, 67, 28), (104, 66, 19), (93, 63, 12), (81, 58, 9), + (70, 54, 7), (48, 52, 7), (41, 52, 10), (35, 53, 13), + (32, 52, 13), (30, 52, 13), (25, 49, 12), (23, 44, 11), + (13, 36, 6), (10, 35, 8), (7, 34, 11), (5, 34, 13), + (4, 34, 15), (5, 33, 18), (10, 31, 20), (16, 30, 21), + (22, 31, 19), (37, 34, 17), (39, 36, 18), (41, 38, 20), + (51, 44, 26), (63, 52, 31), (77, 61, 35), (90, 72, 38), + (122, 92, 44), (136, 98, 43), (150, 105, 43), (155, 107, 43), + (160, 110, 43), (171, 113, 44), (179, 117, 39), (179, 124, 42), + (180, 126, 40), (173, 122, 34), (168, 117, 31), (163, 113, 29), + (154, 103, 26), (146, 90, 19), (131, 80, 13), (117, 68, 8), + (85, 48, 6), (70, 39, 4), (55, 31, 3), (50, 27, 4), + (45, 23, 5), (36, 16, 9), (32, 12, 13), (27, 7, 26), + (23, 5, 41), (17, 3, 47), (15, 2, 46), (14, 2, 46), + (11, 3, 45), (11, 5, 39), (9, 7, 37), (8, 11, 48), + (14, 24, 55), (16, 26, 55), (18, 28, 55), (23, 32, 52), + (28, 38, 41), (32, 40, 25), (33, 41, 20), (34, 42, 16), + (36, 44, 15), (39, 41, 16), (39, 40, 16), (40, 40, 16), + (42, 38, 13), (42, 33, 12), (39, 27, 9), (37, 23, 6), + (29, 13, 2), (27, 10, 1), (26, 8, 0), (24, 5, 0), + (24, 3, 0), (26, 1, 0), (33, 1, 0), (43, 1, 0), + (53, 1, 2), (60, 3, 2), (64, 6, 2), (67, 7, 4), + (65, 8, 7), (66, 10, 11), (69, 13, 12), (75, 15, 17), + (83, 25, 18), (83, 28, 17), (83, 31, 17), (79, 36, 16), + (72, 38, 17), (64, 40, 16), (60, 43, 18), (59, 45, 21), + (61, 49, 21), (63, 56, 21), (66, 63, 23), (73, 67, 25), + (80, 68, 26), (83, 70, 26), (87, 71, 30), (91, 72, 28), + (94, 72, 26), (94, 75, 28), (99, 78, 31), (110, 80, 30), + (117, 80, 28), (119, 79, 30), (121, 77, 26), (118, 71, 19), + (107, 65, 14), (93, 58, 11), (87, 54, 8), (82, 47, 5), + (78, 43, 5), (76, 40, 3), (74, 38, 3), (73, 36, 4), + (68, 34, 7), (65, 37, 11), (64, 39, 15), (65, 43, 18), + (66, 50, 19), (60, 54, 19), (58, 60, 20), (57, 73, 23), + (57, 87, 26), (55, 94, 29), (53, 96, 32), (55, 101, 37), + (49, 102, 37), (42, 96, 37), (35, 100, 40), (34, 104, 48), + (26, 102, 48), (19, 93, 46), (17, 86, 49), (16, 75, 49), + (14, 57, 47), (10, 46, 45), (14, 42, 54), (15, 40, 58), + (18, 37, 57), (21, 34, 56), (23, 28, 49), (23, 20, 41), + (23, 16, 31), (26, 15, 26), (29, 17, 26), (34, 20, 25), + (46, 26, 26), (56, 30, 22), (55, 30, 21), (56, 31, 18), + (57, 31, 14), (57, 33, 11), (50, 34, 8), (52, 38, 10) + ), + +// 435 040221-93 +((186, 187, 147), (208, 206, 183), (217, 215, 198), (227, 224, 214), + (233, 231, 226), (239, 239, 238), (236, 236, 234), (234, 233, 231), + (218, 216, 205), (207, 204, 190), (197, 193, 175), (185, 183, 162), + (174, 174, 149), (162, 165, 137), (150, 156, 126), (145, 151, 119), + (140, 146, 113), (121, 129, 83), (114, 121, 69), (108, 113, 55), + (104, 110, 50), (100, 108, 46), (99, 108, 46), (99, 108, 46), + (100, 111, 46), (103, 112, 43), (106, 113, 40), (106, 114, 36), + (107, 115, 33), (106, 114, 31), (105, 114, 29), (98, 112, 28), + (93, 108, 27), (78, 99, 22), (72, 96, 19), (66, 93, 17), + (61, 91, 16), (57, 89, 16), (55, 89, 17), (53, 90, 18), + (50, 86, 23), (50, 85, 25), (51, 85, 27), (54, 86, 28), + (58, 88, 30), (60, 90, 31), (62, 93, 32), (66, 95, 36), + (70, 97, 39), (77, 99, 43), (77, 97, 40), (78, 96, 38), + (75, 94, 34), (73, 93, 30), (71, 91, 28), (69, 89, 27), + (61, 83, 23), (59, 80, 20), (58, 77, 18), (55, 75, 14), + (53, 74, 11), (51, 73, 9), (49, 72, 8), (45, 72, 7), + (44, 72, 7), (54, 80, 14), (68, 90, 23), (83, 101, 33), + (90, 109, 41), (98, 117, 50), (113, 130, 68), (126, 141, 87), + (149, 160, 115), (157, 163, 118), (165, 167, 122), (169, 170, 123), + (174, 174, 125), (174, 174, 126), (174, 174, 128), (172, 176, 132), + (173, 175, 134), (171, 168, 125), (167, 161, 113), (163, 154, 101), + (158, 150, 94), (153, 146, 87), (142, 139, 75), (133, 131, 68), + (127, 127, 64), (133, 130, 68), (139, 134, 72), (143, 136, 75), + (147, 139, 78), (154, 146, 82), (159, 153, 91), (162, 156, 101), + (165, 161, 112), (175, 175, 136), (184, 183, 148), (193, 191, 160), + (198, 197, 166), (204, 203, 172), (216, 213, 185), (224, 221, 196), + (228, 224, 201), (218, 218, 194), (208, 212, 188), (201, 206, 180), + (195, 200, 172), (183, 188, 155), (168, 178, 140), (154, 164, 125), + (142, 151, 108), (112, 126, 76), (103, 119, 68), (95, 112, 60), + (81, 99, 45), (67, 88, 34), (56, 74, 27), (48, 63, 20), + (42, 51, 12), (44, 53, 10), (46, 56, 9), (48, 59, 10), + (51, 62, 11), (56, 67, 14), (60, 71, 15), (64, 73, 17), + (68, 76, 18), (76, 85, 20), (78, 88, 20), (80, 91, 21), + (84, 98, 23), (85, 104, 22), (84, 105, 22), (82, 105, 22), + (77, 104, 22), (76, 102, 23), (76, 100, 24), (76, 100, 24), + (76, 101, 24), (75, 100, 22), (73, 98, 20), (71, 96, 18), + (67, 93, 16), (63, 84, 16), (63, 82, 17), (64, 80, 18), + (63, 76, 18), (61, 72, 18), (57, 67, 17), (54, 61, 17), + (50, 59, 19), (51, 59, 20), (53, 60, 21), (56, 62, 23), + (60, 67, 27), (64, 71, 30), (71, 74, 35), (78, 81, 42), + (88, 90, 49), (117, 114, 64), (126, 122, 69), (136, 130, 75), + (153, 146, 89), (168, 160, 104), (180, 172, 120), (191, 181, 137), + (208, 198, 165), (212, 200, 169), (216, 203, 173), (224, 211, 183), + (229, 217, 192), (233, 220, 198), (235, 220, 198), (231, 217, 196), + (224, 213, 191), (217, 205, 180), (211, 198, 168), (204, 194, 159), + (200, 189, 151), (195, 183, 139), (189, 176, 125), (181, 169, 111), + (162, 151, 82), (157, 149, 77), (153, 147, 73), (147, 145, 70), + (146, 144, 71), (147, 146, 74), (151, 150, 79), (158, 154, 85), + (162, 156, 92), (165, 159, 97), (161, 159, 98), (155, 154, 97), + (148, 149, 94), (139, 143, 89), (131, 135, 84), (124, 127, 81), + (118, 117, 78), (108, 109, 73), (95, 96, 66), (81, 84, 57), + (65, 72, 47), (49, 62, 34), (37, 54, 24), (32, 48, 18), + (31, 46, 14), (30, 44, 13), (31, 43, 15), (33, 43, 18), + (36, 46, 22), (41, 52, 26), (50, 61, 30), (61, 73, 37), + (75, 86, 45), (92, 99, 55), (107, 113, 73), (121, 126, 90), + (133, 138, 107), (144, 148, 121), (153, 156, 130), (160, 164, 134), + (169, 169, 131), (181, 177, 136), (191, 183, 142), (202, 190, 150), + (213, 198, 158), (220, 201, 163), (219, 200, 161), (215, 194, 150), + (212, 189, 138), (207, 182, 126), (205, 176, 117), (204, 176, 113), + (207, 178, 111), (208, 177, 110), (205, 176, 106), (199, 173, 99), + (190, 169, 91), (181, 161, 83), (170, 155, 78), (162, 152, 71), + (155, 148, 66), (150, 147, 61), (145, 144, 57), (140, 141, 54), + (138, 140, 52), (136, 137, 54), (142, 144, 68), (146, 151, 84), + (155, 159, 99), (163, 167, 113), (172, 176, 128), (181, 185, 142) + ), + +// 436 040221-94 +((117, 143, 160), (109, 132, 146), (97, 123, 139), (86, 115, 132), + (71, 100, 118), (56, 86, 104), (50, 81, 99), (45, 76, 94), + (24, 62, 86), (18, 55, 78), (12, 48, 71), (12, 44, 65), + (13, 41, 59), (15, 46, 64), (18, 52, 69), (21, 54, 71), + (24, 56, 73), (39, 58, 69), (39, 58, 68), (39, 58, 67), + (37, 56, 65), (36, 54, 64), (36, 52, 61), (36, 50, 58), + (31, 35, 42), (24, 32, 39), (18, 30, 37), (24, 40, 50), + (30, 51, 63), (37, 58, 71), (44, 66, 80), (60, 82, 97), + (74, 100, 117), (104, 137, 157), (119, 149, 169), (134, 161, 181), + (141, 165, 184), (149, 169, 187), (148, 169, 187), (147, 169, 187), + (134, 160, 179), (122, 150, 168), (111, 140, 157), (98, 125, 141), + (85, 110, 125), (77, 102, 118), (70, 95, 111), (57, 82, 97), + (50, 75, 90), (51, 73, 86), (56, 77, 90), (62, 81, 94), + (73, 91, 103), (84, 101, 113), (90, 107, 120), (96, 114, 128), + (116, 140, 157), (122, 144, 161), (128, 149, 165), (122, 145, 162), + (117, 142, 160), (112, 139, 158), (107, 136, 156), (97, 125, 144), + (84, 109, 126), (53, 72, 86), (40, 58, 71), (28, 45, 57), + (22, 37, 48), (17, 30, 39), (10, 17, 23), (4, 7, 9), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 1, 3), (3, 12, 14), (7, 23, 25), + (12, 31, 33), (17, 39, 41), (30, 56, 56), (43, 67, 69), + (60, 93, 98), (67, 106, 113), (75, 119, 128), (78, 121, 131), + (82, 124, 135), (84, 123, 137), (85, 122, 139), (81, 121, 142), + (84, 122, 145), (95, 129, 150), (105, 136, 157), (116, 144, 165), + (122, 150, 170), (129, 157, 176), (141, 170, 188), (152, 178, 196), + (167, 189, 207), (171, 196, 213), (176, 203, 219), (176, 204, 220), + (177, 206, 222), (172, 205, 221), (166, 197, 215), (163, 192, 209), + (162, 190, 206), (161, 188, 202), (159, 185, 199), (157, 183, 197), + (152, 178, 192), (148, 175, 191), (148, 175, 192), (148, 177, 195), + (157, 182, 198), (163, 187, 202), (170, 192, 206), (171, 193, 207), + (173, 195, 209), (173, 195, 208), (173, 192, 204), (175, 190, 201), + (175, 190, 197), (164, 183, 193), (160, 180, 190), (156, 177, 188), + (149, 170, 185), (143, 168, 182), (141, 168, 183), (138, 170, 187), + (144, 170, 187), (141, 164, 179), (139, 158, 171), (132, 151, 164), + (126, 145, 158), (109, 125, 138), (96, 108, 118), (84, 90, 97), + (71, 73, 76), (35, 37, 40), (27, 28, 32), (19, 20, 24), + (8, 15, 18), (7, 21, 21), (14, 35, 35), (25, 52, 51), + (51, 77, 80), (58, 86, 89), (66, 95, 99), (82, 112, 118), + (99, 134, 139), (117, 146, 153), (132, 156, 165), (143, 164, 175), + (153, 168, 182), (166, 177, 190), (168, 179, 191), (171, 181, 193), + (175, 186, 197), (178, 188, 201), (182, 191, 202), (183, 193, 204), + (184, 194, 204), (182, 194, 204), (181, 195, 205), (178, 196, 207), + (173, 194, 208), (168, 193, 207), (163, 186, 203), (151, 178, 195), + (138, 169, 187), (119, 155, 175), (99, 139, 162), (83, 118, 140), + (69, 97, 116), (56, 79, 95), (42, 62, 75), (26, 47, 60), + (4, 16, 24), (2, 11, 17), (1, 6, 10), (1, 1, 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, 1), + (0, 1, 2), (0, 11, 10), (2, 20, 18), (2, 27, 29), + (3, 35, 40), (6, 35, 46), (7, 43, 56), (9, 53, 62), + (8, 53, 62), (6, 52, 61), (6, 42, 53), (7, 33, 48), + (7, 33, 44), (6, 26, 33), (4, 18, 22), (6, 14, 16), + (11, 14, 18), (17, 25, 30), (24, 37, 45), (28, 49, 55), + (36, 63, 69), (49, 78, 86), (62, 95, 106), (75, 109, 126), + (79, 122, 137), (81, 130, 143), (82, 131, 144), (80, 131, 144), + (79, 125, 144), (72, 118, 138), (65, 115, 133), (61, 110, 129), + (59, 110, 125), (60, 111, 127), (61, 112, 129), (65, 116, 133), + (73, 119, 140), (85, 126, 144), (96, 136, 152), (103, 144, 160), + (108, 150, 166), (111, 150, 170), (114, 148, 170), (115, 145, 166), + (113, 144, 165), (111, 144, 165), (112, 146, 168), (110, 146, 168), + (119, 153, 174), (124, 156, 177), (124, 155, 175), (126, 156, 174) + ), + +// 437 040221-95 +((87, 115, 72), (85, 115, 74), (90, 120, 78), (95, 126, 82), + (102, 130, 85), (110, 135, 88), (110, 133, 88), (110, 131, 89), + (109, 135, 91), (112, 142, 96), (115, 149, 101), (122, 161, 109), + (130, 173, 118), (136, 182, 126), (143, 191, 135), (143, 192, 135), + (144, 194, 136), (138, 194, 133), (136, 191, 128), (134, 189, 124), + (131, 186, 120), (128, 183, 117), (125, 180, 115), (123, 177, 113), + (103, 154, 92), (92, 138, 79), (82, 123, 67), (73, 109, 54), + (65, 96, 42), (60, 93, 39), (56, 90, 36), (47, 84, 31), + (39, 78, 25), (24, 63, 21), (20, 51, 20), (17, 40, 20), + (18, 37, 22), (19, 34, 24), (20, 34, 25), (21, 34, 26), + (20, 40, 24), (20, 41, 24), (21, 42, 25), (22, 44, 27), + (24, 46, 30), (27, 47, 32), (30, 49, 34), (37, 56, 37), + (46, 63, 38), (60, 80, 42), (63, 87, 45), (67, 94, 48), + (67, 96, 49), (68, 99, 50), (68, 98, 49), (69, 97, 49), + (68, 92, 49), (67, 89, 50), (67, 86, 51), (62, 80, 52), + (57, 74, 53), (54, 71, 51), (51, 68, 50), (43, 60, 44), + (36, 50, 39), (26, 36, 26), (26, 33, 26), (26, 30, 27), + (27, 31, 28), (28, 33, 29), (30, 40, 31), (32, 47, 34), + (32, 62, 31), (33, 66, 30), (34, 70, 30), (38, 73, 31), + (42, 77, 32), (46, 82, 35), (51, 88, 38), (61, 101, 47), + (70, 112, 55), (85, 137, 75), (91, 139, 79), (98, 141, 83), + (101, 140, 83), (105, 139, 84), (110, 140, 84), (114, 136, 82), + (113, 135, 83), (110, 132, 81), (107, 130, 79), (105, 126, 76), + (103, 123, 74), (97, 116, 67), (91, 105, 57), (83, 93, 49), + (74, 85, 43), (65, 82, 39), (64, 86, 42), (63, 90, 46), + (64, 91, 47), (65, 92, 48), (66, 90, 50), (64, 86, 51), + (61, 78, 53), (58, 75, 57), (55, 73, 62), (53, 72, 62), + (52, 71, 63), (50, 67, 64), (45, 59, 64), (43, 52, 61), + (40, 45, 59), (36, 33, 56), (35, 32, 57), (35, 31, 58), + (34, 31, 60), (35, 31, 62), (40, 36, 63), (47, 46, 67), + (69, 75, 80), (80, 93, 90), (92, 111, 101), (96, 119, 105), + (100, 127, 110), (108, 140, 119), (118, 155, 129), (128, 167, 137), + (138, 182, 145), (157, 208, 163), (159, 214, 167), (162, 220, 171), + (163, 226, 175), (163, 230, 178), (162, 229, 177), (158, 226, 173), + (147, 211, 160), (137, 203, 151), (127, 195, 143), (121, 190, 137), + (116, 186, 132), (104, 174, 118), (95, 161, 105), (86, 147, 91), + (76, 132, 77), (55, 106, 55), (50, 102, 50), (46, 99, 46), + (36, 91, 38), (30, 83, 30), (29, 77, 22), (29, 72, 16), + (33, 60, 10), (34, 59, 10), (35, 59, 11), (37, 60, 12), + (37, 62, 15), (40, 64, 18), (45, 70, 20), (52, 76, 23), + (61, 84, 27), (76, 103, 43), (79, 108, 47), (83, 113, 52), + (87, 119, 61), (91, 125, 67), (93, 130, 72), (97, 136, 76), + (100, 147, 85), (101, 150, 87), (102, 153, 90), (101, 152, 93), + (98, 147, 92), (92, 138, 89), (86, 127, 83), (78, 113, 73), + (68, 99, 65), (60, 89, 59), (52, 79, 56), (45, 66, 52), + (38, 56, 47), (32, 50, 40), (26, 48, 33), (21, 48, 29), + (20, 61, 29), (21, 63, 32), (23, 66, 35), (27, 68, 40), + (31, 71, 41), (35, 74, 41), (41, 82, 43), (50, 91, 45), + (60, 103, 47), (69, 114, 55), (78, 121, 64), (86, 125, 70), + (89, 124, 72), (92, 122, 71), (95, 119, 70), (98, 117, 67), + (99, 118, 68), (100, 122, 71), (99, 127, 75), (96, 134, 78), + (92, 138, 80), (88, 141, 83), (88, 143, 84), (88, 141, 83), + (88, 140, 85), (85, 140, 85), (83, 143, 88), (81, 148, 90), + (79, 152, 97), (81, 159, 102), (85, 165, 107), (89, 165, 111), + (91, 164, 113), (92, 164, 114), (92, 164, 112), (88, 163, 108), + (86, 160, 103), (84, 157, 99), (82, 150, 94), (78, 141, 89), + (77, 133, 84), (78, 128, 80), (75, 128, 78), (76, 130, 76), + (80, 134, 76), (82, 138, 80), (85, 141, 85), (87, 141, 89), + (93, 139, 90), (98, 139, 94), (105, 144, 97), (113, 153, 101), + (121, 163, 107), (129, 175, 118), (135, 186, 129), (141, 194, 137), + (145, 198, 143), (148, 197, 144), (148, 195, 142), (146, 188, 134), + (143, 183, 127), (140, 176, 121), (134, 169, 117), (128, 165, 114), + (123, 165, 112), (117, 160, 108), (114, 161, 107), (112, 159, 103), + (108, 155, 97), (105, 147, 90), (101, 135, 82), (96, 131, 79) + ), + +// 438 040221-96 +((179, 154, 69), (165, 128, 66), (155, 118, 62), (145, 108, 59), + (144, 109, 62), (144, 110, 65), (148, 113, 68), (153, 117, 72), + (161, 126, 81), (156, 125, 80), (152, 125, 79), (150, 121, 72), + (149, 118, 65), (150, 119, 64), (152, 121, 64), (154, 122, 64), + (156, 123, 65), (164, 128, 64), (175, 130, 56), (186, 132, 49), + (200, 139, 44), (214, 146, 40), (218, 150, 41), (223, 155, 42), + (233, 176, 47), (237, 183, 48), (242, 190, 49), (246, 193, 52), + (251, 197, 56), (251, 197, 57), (252, 198, 58), (250, 201, 61), + (249, 204, 65), (235, 197, 80), (221, 186, 85), (207, 175, 90), + (186, 158, 88), (165, 142, 86), (156, 134, 83), (147, 126, 80), + (104, 94, 73), (85, 81, 66), (67, 68, 60), (52, 59, 59), + (38, 51, 59), (32, 48, 58), (27, 46, 58), (19, 39, 60), + (20, 30, 65), (33, 27, 69), (42, 32, 79), (51, 37, 89), + (58, 42, 96), (65, 47, 104), (70, 48, 101), (76, 49, 99), + (107, 58, 82), (122, 71, 75), (138, 84, 68), (146, 95, 58), + (155, 106, 49), (159, 110, 43), (163, 114, 38), (166, 118, 28), + (165, 118, 20), (153, 112, 17), (144, 106, 21), (136, 101, 26), + (133, 99, 28), (131, 97, 30), (121, 92, 37), (110, 85, 42), + (81, 63, 42), (69, 52, 42), (57, 42, 42), (55, 43, 44), + (54, 44, 46), (57, 46, 44), (60, 48, 43), (67, 54, 41), + (71, 57, 37), (73, 50, 28), (76, 51, 25), (80, 53, 23), + (86, 57, 25), (93, 61, 27), (108, 71, 30), (116, 77, 29), + (112, 79, 38), (109, 83, 44), (107, 88, 51), (109, 92, 56), + (112, 97, 62), (119, 107, 68), (125, 115, 76), (128, 122, 89), + (131, 130, 102), (152, 147, 117), (160, 153, 119), (169, 159, 122), + (170, 160, 124), (172, 161, 126), (172, 164, 133), (174, 168, 136), + (183, 167, 132), (185, 167, 132), (188, 168, 132), (187, 169, 134), + (186, 171, 137), (182, 174, 145), (176, 174, 151), (168, 168, 147), + (162, 164, 142), (151, 142, 123), (145, 136, 117), (140, 130, 112), + (128, 115, 101), (110, 98, 87), (91, 87, 72), (79, 70, 61), + (80, 58, 33), (87, 57, 25), (94, 56, 17), (98, 59, 15), + (102, 63, 14), (111, 70, 18), (127, 81, 19), (146, 92, 23), + (164, 104, 26), (194, 122, 30), (198, 125, 32), (203, 128, 34), + (208, 132, 36), (212, 134, 38), (215, 136, 38), (217, 137, 38), + (220, 139, 38), (223, 141, 39), (226, 143, 40), (227, 143, 40), + (229, 144, 40), (230, 145, 38), (230, 145, 39), (229, 144, 39), + (225, 142, 38), (218, 136, 37), (215, 134, 35), (213, 133, 34), + (204, 127, 32), (191, 118, 30), (177, 109, 27), (163, 102, 23), + (156, 97, 19), (156, 97, 18), (157, 98, 17), (159, 98, 19), + (162, 103, 20), (162, 106, 24), (166, 114, 29), (176, 128, 43), + (191, 145, 57), (220, 179, 94), (225, 185, 101), (231, 191, 108), + (237, 203, 114), (242, 214, 119), (247, 222, 120), (250, 230, 128), + (254, 240, 152), (254, 242, 156), (254, 244, 161), (253, 247, 165), + (249, 243, 160), (244, 240, 156), (240, 238, 159), (239, 236, 167), + (238, 236, 180), (241, 240, 197), (241, 242, 204), (240, 238, 204), + (236, 231, 193), (233, 221, 178), (231, 211, 163), (232, 204, 150), + (234, 195, 130), (233, 190, 123), (233, 186, 116), (229, 175, 96), + (225, 164, 76), (221, 152, 58), (216, 143, 46), (213, 138, 41), + (211, 136, 41), (207, 133, 42), (202, 132, 44), (192, 130, 51), + (179, 130, 64), (167, 129, 76), (162, 131, 83), (163, 132, 89), + (171, 135, 87), (179, 141, 87), (183, 149, 97), (183, 157, 115), + (183, 170, 134), (188, 180, 153), (199, 190, 163), (216, 200, 161), + (233, 208, 159), (244, 213, 153), (250, 221, 150), (249, 220, 149), + (243, 217, 148), (236, 208, 141), (223, 194, 140), (213, 179, 133), + (209, 170, 120), (205, 160, 104), (203, 153, 90), (202, 148, 73), + (196, 138, 64), (189, 129, 63), (188, 125, 62), (188, 126, 62), + (194, 130, 63), (202, 139, 61), (208, 148, 63), (214, 157, 72), + (217, 166, 84), (220, 174, 97), (225, 184, 111), (229, 192, 120), + (231, 200, 134), (235, 209, 151), (233, 215, 165), (231, 219, 179), + (225, 219, 187), (217, 217, 188), (208, 211, 183), (202, 206, 180), + (192, 198, 172), (192, 193, 163), (191, 183, 149), (192, 176, 133), + (193, 170, 115), (197, 168, 101), (195, 168, 91), (201, 174, 83), + (208, 177, 76), (220, 180, 69), (232, 183, 61), (220, 168, 49), + (206, 157, 45), (190, 153, 46), (174, 150, 51), (162, 144, 58) + ), + +// 439 040221-97 +((138, 99, 27), (149, 112, 31), (141, 102, 29), (134, 93, 27), + (133, 88, 24), (133, 83, 21), (132, 80, 19), (131, 78, 18), + (120, 64, 22), (107, 55, 21), (94, 46, 21), (76, 36, 19), + (58, 27, 17), (44, 25, 17), (31, 24, 17), (27, 29, 23), + (23, 34, 29), (12, 78, 51), (9, 90, 57), (6, 103, 64), + (6, 111, 80), (6, 120, 96), (7, 133, 104), (8, 147, 112), + (18, 163, 120), (18, 139, 111), (19, 116, 103), (17, 104, 96), + (15, 93, 89), (15, 90, 85), (16, 87, 81), (19, 68, 62), + (22, 50, 40), (25, 25, 15), (33, 23, 10), (41, 22, 5), + (53, 27, 4), (66, 32, 3), (72, 36, 2), (78, 41, 2), + (101, 55, 2), (112, 56, 2), (123, 57, 2), (132, 54, 2), + (142, 51, 2), (149, 49, 2), (157, 48, 2), (165, 58, 5), + (168, 63, 14), (145, 72, 31), (135, 77, 34), (125, 83, 38), + (111, 91, 43), (97, 99, 48), (87, 100, 48), (77, 101, 48), + (55, 94, 37), (54, 85, 31), (54, 77, 26), (72, 69, 17), + (91, 61, 9), (104, 59, 6), (117, 57, 3), (131, 57, 2), + (137, 54, 1), (133, 51, 1), (133, 48, 2), (134, 45, 3), + (130, 43, 3), (127, 41, 3), (118, 37, 4), (108, 36, 4), + (93, 30, 3), (84, 26, 3), (76, 22, 3), (72, 23, 3), + (68, 25, 3), (66, 27, 3), (65, 30, 4), (61, 33, 5), + (62, 35, 3), (73, 44, 4), (79, 52, 7), (85, 61, 10), + (89, 64, 9), (93, 68, 9), (102, 71, 7), (107, 76, 3), + (101, 77, 8), (87, 72, 7), (74, 67, 7), (65, 64, 5), + (57, 61, 3), (42, 54, 2), (30, 45, 4), (20, 39, 4), + (13, 31, 4), (5, 20, 0), (6, 19, 0), (7, 18, 0), + (10, 18, 0), (13, 19, 0), (21, 22, 1), (37, 26, 3), + (73, 42, 9), (86, 52, 11), (100, 63, 14), (105, 65, 15), + (110, 67, 16), (120, 69, 16), (128, 71, 14), (131, 72, 16), + (130, 73, 14), (111, 60, 11), (105, 55, 8), (99, 50, 6), + (83, 41, 2), (70, 37, 1), (58, 37, 1), (48, 42, 1), + (33, 56, 1), (29, 63, 8), (25, 70, 15), (23, 76, 17), + (22, 83, 19), (26, 89, 20), (27, 95, 15), (27, 96, 17), + (26, 89, 22), (24, 78, 25), (26, 75, 21), (28, 72, 17), + (29, 63, 11), (31, 55, 9), (32, 48, 9), (37, 47, 7), + (67, 62, 5), (85, 74, 9), (104, 86, 14), (110, 89, 14), + (117, 93, 15), (123, 99, 16), (121, 105, 18), (120, 114, 26), + (129, 133, 41), (152, 150, 55), (149, 148, 54), (147, 146, 53), + (131, 132, 48), (122, 132, 46), (124, 134, 49), (138, 135, 46), + (152, 116, 30), (150, 111, 24), (148, 107, 18), (145, 102, 11), + (144, 102, 6), (147, 100, 4), (151, 100, 4), (157, 102, 6), + (164, 105, 6), (182, 103, 4), (187, 105, 4), (192, 107, 4), + (202, 108, 9), (209, 116, 14), (215, 128, 21), (220, 128, 27), + (228, 136, 39), (229, 140, 41), (230, 144, 44), (224, 151, 51), + (209, 156, 58), (191, 161, 60), (177, 155, 60), (172, 153, 59), + (173, 144, 54), (173, 139, 53), (162, 138, 49), (155, 134, 44), + (152, 131, 42), (154, 125, 35), (165, 120, 33), (171, 118, 31), + (174, 122, 34), (173, 123, 33), (173, 124, 32), (173, 127, 34), + (177, 128, 35), (184, 132, 41), (189, 133, 49), (193, 136, 51), + (194, 139, 53), (193, 141, 52), (196, 145, 54), (196, 144, 58), + (195, 143, 59), (197, 142, 55), (194, 140, 49), (192, 139, 42), + (189, 135, 39), (185, 130, 38), (183, 123, 35), (179, 112, 31), + (173, 103, 26), (166, 93, 20), (161, 89, 18), (158, 88, 16), + (158, 88, 16), (158, 92, 18), (158, 96, 17), (162, 105, 23), + (168, 117, 32), (176, 129, 39), (184, 140, 47), (186, 146, 48), + (184, 147, 44), (179, 142, 45), (166, 130, 43), (151, 120, 41), + (134, 107, 38), (116, 93, 26), (99, 81, 17), (81, 66, 9), + (64, 57, 4), (50, 49, 2), (39, 42, 0), (32, 40, 0), + (29, 44, 0), (27, 51, 2), (29, 59, 3), (36, 64, 6), + (44, 66, 8), (52, 69, 10), (60, 73, 12), (64, 77, 15), + (74, 78, 17), (84, 75, 20), (92, 71, 19), (96, 66, 16), + (91, 63, 16), (86, 63, 18), (81, 66, 25), (74, 71, 33), + (69, 75, 38), (62, 76, 39), (54, 76, 37), (51, 77, 35), + (50, 79, 38), (61, 86, 42), (84, 102, 54), (99, 106, 53), + (106, 106, 44), (106, 99, 37), (103, 85, 22), (119, 92, 24) + ), + +// 440 040221-98 +((217, 111, 68), (225, 131, 74), (235, 144, 77), (246, 157, 81), + (248, 163, 83), (251, 169, 86), (250, 168, 85), (249, 167, 85), + (242, 154, 78), (240, 148, 77), (239, 143, 76), (239, 138, 75), + (239, 133, 74), (239, 128, 71), (240, 124, 69), (241, 123, 68), + (242, 122, 68), (242, 115, 64), (240, 112, 63), (238, 110, 62), + (238, 107, 62), (239, 105, 63), (239, 103, 63), (239, 102, 63), + (244, 95, 61), (248, 92, 60), (252, 89, 59), (252, 89, 60), + (252, 90, 62), (250, 91, 62), (248, 93, 63), (235, 96, 61), + (222, 94, 60), (198, 88, 58), (185, 81, 56), (173, 75, 55), + (162, 67, 54), (151, 60, 53), (149, 56, 54), (148, 53, 55), + (124, 43, 49), (118, 37, 46), (113, 32, 43), (112, 25, 37), + (111, 19, 32), (111, 15, 29), (111, 12, 27), (115, 6, 23), + (128, 3, 23), (147, 5, 23), (156, 10, 25), (166, 15, 27), + (178, 24, 30), (190, 34, 33), (196, 40, 35), (203, 46, 38), + (227, 72, 48), (236, 84, 52), (245, 96, 57), (247, 107, 62), + (250, 118, 67), (250, 124, 69), (251, 131, 71), (251, 144, 78), + (252, 159, 85), (252, 189, 101), (252, 201, 109), (253, 214, 118), + (253, 218, 121), (253, 223, 125), (253, 230, 132), (253, 234, 135), + (253, 237, 136), (253, 235, 133), (253, 233, 130), (250, 229, 124), + (248, 225, 118), (244, 223, 115), (240, 221, 112), (238, 212, 108), + (238, 203, 104), (238, 184, 98), (239, 180, 96), (240, 176, 94), + (240, 173, 93), (241, 171, 92), (246, 172, 90), (240, 176, 89), + (238, 178, 92), (237, 179, 96), (237, 181, 101), (237, 182, 104), + (238, 183, 108), (239, 188, 116), (242, 191, 125), (250, 196, 136), + (252, 206, 145), (252, 228, 162), (252, 236, 167), (252, 245, 173), + (252, 247, 174), (252, 249, 175), (253, 250, 176), (253, 249, 174), + (253, 245, 167), (253, 241, 163), (253, 237, 160), (252, 235, 158), + (252, 234, 157), (252, 228, 151), (252, 220, 144), (253, 210, 137), + (253, 197, 129), (253, 171, 109), (253, 164, 103), (253, 157, 98), + (254, 141, 89), (253, 128, 83), (254, 117, 77), (253, 106, 72), + (254, 85, 66), (253, 78, 62), (253, 71, 59), (253, 68, 57), + (253, 65, 56), (254, 61, 54), (254, 57, 53), (254, 56, 52), + (254, 56, 51), (252, 56, 51), (252, 56, 50), (252, 56, 50), + (251, 56, 51), (246, 57, 51), (235, 56, 52), (223, 56, 54), + (199, 54, 55), (187, 52, 54), (175, 50, 54), (169, 47, 53), + (164, 45, 52), (156, 39, 49), (157, 34, 42), (155, 27, 38), + (154, 21, 36), (152, 10, 33), (152, 8, 32), (152, 6, 31), + (152, 6, 30), (153, 7, 30), (151, 9, 31), (160, 13, 29), + (182, 20, 27), (187, 21, 27), (193, 23, 27), (205, 27, 27), + (218, 29, 26), (228, 32, 25), (239, 36, 24), (243, 39, 24), + (246, 43, 24), (249, 49, 23), (249, 50, 23), (249, 51, 24), + (250, 54, 26), (251, 54, 28), (252, 55, 30), (252, 58, 33), + (247, 70, 37), (245, 74, 38), (244, 79, 40), (243, 89, 44), + (242, 97, 47), (242, 106, 51), (243, 113, 56), (243, 120, 61), + (245, 125, 66), (248, 134, 65), (247, 142, 66), (246, 154, 65), + (245, 167, 69), (243, 178, 72), (243, 187, 76), (243, 194, 79), + (244, 196, 87), (245, 195, 87), (247, 195, 88), (249, 193, 90), + (249, 192, 88), (251, 196, 90), (250, 199, 92), (250, 203, 97), + (250, 209, 102), (250, 213, 109), (250, 213, 115), (250, 211, 120), + (247, 205, 125), (246, 196, 127), (247, 190, 125), (247, 182, 121), + (247, 176, 118), (247, 171, 116), (247, 166, 115), (248, 160, 111), + (250, 153, 106), (250, 144, 100), (249, 133, 94), (249, 120, 86), + (249, 106, 76), (249, 91, 67), (249, 77, 59), (247, 63, 53), + (247, 49, 48), (246, 39, 43), (242, 31, 39), (236, 25, 37), + (232, 20, 34), (230, 16, 32), (229, 11, 29), (230, 8, 28), + (230, 8, 27), (232, 8, 27), (233, 7, 25), (234, 8, 24), + (232, 9, 25), (230, 11, 26), (229, 15, 28), (228, 19, 28), + (229, 24, 29), (231, 33, 31), (235, 45, 34), (239, 57, 37), + (245, 70, 41), (249, 83, 45), (251, 97, 50), (252, 111, 58), + (252, 122, 64), (252, 129, 69), (252, 134, 72), (252, 137, 74), + (249, 137, 76), (243, 135, 77), (232, 131, 78), (222, 128, 78), + (217, 129, 78), (216, 133, 79), (216, 138, 83), (217, 144, 88), + (218, 146, 89), (222, 146, 89), (226, 143, 87), (225, 138, 84), + (220, 129, 81), (216, 119, 76), (215, 112, 69), (215, 107, 66) + ), + +// 441 040221-99 +((176, 74, 34), (153, 63, 28), (145, 58, 25), (137, 54, 22), + (137, 51, 20), (137, 48, 18), (139, 49, 20), (141, 51, 23), + (141, 61, 32), (142, 68, 34), (144, 75, 37), (150, 84, 41), + (157, 93, 45), (172, 102, 53), (187, 112, 62), (192, 115, 65), + (197, 118, 69), (211, 125, 77), (209, 121, 73), (208, 117, 70), + (206, 111, 66), (204, 106, 62), (203, 103, 60), (202, 100, 58), + (202, 105, 60), (202, 108, 63), (202, 111, 67), (204, 116, 72), + (207, 121, 78), (207, 122, 79), (207, 124, 81), (207, 127, 80), + (202, 133, 83), (194, 150, 99), (199, 163, 112), (204, 176, 125), + (212, 187, 137), (220, 198, 150), (221, 200, 152), (222, 203, 155), + (213, 197, 154), (203, 191, 147), (193, 186, 140), (190, 184, 138), + (188, 183, 137), (188, 182, 134), (188, 182, 132), (189, 178, 124), + (192, 173, 120), (186, 161, 104), (174, 155, 101), (163, 150, 98), + (150, 145, 94), (138, 141, 91), (135, 138, 89), (132, 136, 87), + (128, 130, 81), (127, 129, 84), (126, 128, 88), (124, 129, 90), + (122, 130, 93), (121, 129, 92), (120, 129, 91), (113, 125, 87), + (109, 120, 79), (110, 111, 70), (108, 107, 67), (106, 104, 64), + (104, 103, 61), (103, 102, 59), (99, 98, 54), (90, 91, 47), + (74, 76, 33), (69, 71, 29), (64, 66, 26), (58, 61, 23), + (52, 57, 20), (48, 54, 18), (44, 51, 17), (36, 45, 12), + (27, 37, 7), (19, 26, 2), (19, 24, 2), (20, 22, 2), + (22, 22, 2), (24, 22, 2), (32, 23, 2), (40, 24, 2), + (51, 27, 2), (52, 27, 2), (53, 27, 3), (52, 29, 3), + (51, 31, 3), (56, 35, 4), (62, 41, 6), (77, 48, 8), + (89, 54, 9), (114, 65, 16), (117, 71, 20), (120, 78, 24), + (119, 81, 27), (118, 84, 31), (120, 90, 36), (122, 93, 38), + (130, 93, 41), (134, 89, 40), (139, 85, 40), (141, 83, 41), + (144, 82, 42), (149, 83, 43), (153, 82, 42), (155, 80, 42), + (154, 76, 40), (141, 58, 29), (136, 53, 26), (131, 48, 24), + (124, 43, 20), (121, 42, 20), (124, 45, 21), (130, 53, 26), + (147, 73, 41), (150, 80, 49), (153, 88, 58), (153, 93, 64), + (153, 99, 70), (156, 111, 78), (162, 123, 88), (176, 138, 100), + (193, 154, 109), (226, 171, 122), (232, 173, 124), (238, 176, 127), + (246, 179, 127), (249, 174, 125), (249, 169, 119), (246, 163, 112), + (239, 153, 95), (238, 152, 90), (238, 151, 85), (238, 150, 85), + (239, 150, 85), (240, 148, 83), (240, 145, 83), (239, 142, 81), + (234, 142, 79), (226, 140, 79), (223, 142, 80), (220, 144, 81), + (215, 144, 84), (208, 142, 85), (202, 137, 84), (188, 131, 83), + (154, 107, 71), (144, 101, 66), (135, 95, 62), (116, 82, 54), + (99, 70, 47), (86, 62, 42), (75, 56, 39), (61, 53, 35), + (52, 47, 31), (32, 37, 22), (28, 35, 19), (25, 34, 17), + (25, 35, 16), (32, 38, 16), (42, 44, 19), (58, 51, 24), + (94, 69, 34), (101, 73, 36), (109, 78, 39), (125, 87, 45), + (140, 95, 50), (154, 100, 54), (169, 105, 56), (184, 108, 58), + (199, 111, 59), (210, 112, 61), (219, 114, 64), (228, 117, 67), + (230, 116, 69), (231, 112, 68), (227, 108, 67), (224, 105, 62), + (210, 92, 48), (208, 89, 44), (206, 86, 41), (199, 81, 37), + (191, 73, 32), (179, 67, 31), (169, 64, 30), (165, 65, 28), + (159, 63, 27), (157, 65, 25), (161, 69, 26), (167, 74, 27), + (170, 81, 33), (168, 87, 39), (169, 95, 46), (169, 100, 53), + (167, 108, 58), (169, 115, 61), (178, 123, 67), (189, 134, 74), + (196, 144, 80), (201, 153, 86), (205, 156, 91), (200, 158, 94), + (191, 155, 93), (181, 150, 92), (173, 144, 87), (165, 138, 80), + (160, 134, 77), (157, 128, 69), (151, 123, 64), (142, 116, 60), + (132, 112, 58), (122, 108, 59), (116, 106, 58), (112, 105, 61), + (108, 106, 60), (103, 104, 58), (96, 100, 57), (89, 98, 54), + (80, 98, 54), (77, 97, 53), (79, 96, 54), (83, 97, 52), + (91, 97, 50), (101, 95, 51), (109, 91, 49), (112, 87, 47), + (114, 83, 44), (119, 76, 42), (122, 71, 37), (128, 68, 31), + (136, 64, 27), (145, 61, 27), (151, 60, 28), (154, 65, 34), + (159, 71, 43), (161, 74, 49), (162, 80, 52), (162, 83, 51), + (164, 84, 51), (167, 84, 49), (167, 89, 49), (168, 97, 53), + (170, 102, 57), (173, 111, 64), (176, 113, 62), (180, 111, 60), + (185, 105, 54), (188, 97, 47), (186, 89, 41), (185, 78, 33) + ), + +// 442 040222 +((92, 110, 105), (106, 101, 96), (104, 95, 91), (102, 89, 86), + (98, 84, 84), (94, 80, 83), (94, 82, 83), (95, 84, 84), + (111, 102, 96), (125, 116, 106), (139, 131, 117), (147, 144, 127), + (155, 158, 137), (165, 169, 149), (176, 181, 162), (181, 186, 167), + (187, 191, 173), (201, 196, 185), (197, 188, 178), (193, 180, 171), + (187, 172, 162), (182, 164, 153), (181, 162, 149), (181, 161, 146), + (176, 144, 129), (174, 136, 119), (173, 129, 110), (172, 126, 104), + (171, 123, 98), (171, 122, 95), (171, 122, 93), (169, 122, 92), + (169, 119, 94), (166, 115, 96), (159, 107, 93), (153, 99, 90), + (139, 89, 81), (125, 80, 72), (117, 75, 66), (110, 70, 61), + (83, 51, 43), (74, 44, 37), (66, 37, 32), (60, 36, 30), + (55, 35, 29), (52, 35, 29), (50, 36, 29), (49, 39, 30), + (47, 47, 32), (51, 65, 36), (61, 76, 42), (72, 88, 48), + (86, 99, 60), (101, 110, 72), (106, 121, 79), (112, 133, 87), + (126, 147, 93), (134, 145, 93), (142, 144, 93), (144, 135, 93), + (147, 127, 93), (144, 125, 92), (142, 123, 92), (132, 113, 85), + (121, 103, 77), (96, 78, 55), (82, 66, 45), (69, 54, 35), + (63, 48, 30), (58, 42, 25), (47, 34, 21), (38, 31, 17), + (23, 35, 19), (20, 36, 22), (17, 37, 25), (20, 39, 31), + (23, 42, 37), (26, 43, 44), (30, 44, 52), (36, 59, 64), + (44, 71, 74), (52, 88, 92), (54, 86, 97), (56, 85, 103), + (55, 85, 105), (55, 85, 107), (59, 88, 107), (66, 89, 105), + (83, 98, 93), (92, 98, 89), (102, 99, 86), (106, 100, 85), + (110, 101, 85), (119, 98, 85), (131, 101, 81), (144, 107, 79), + (160, 117, 84), (183, 139, 98), (186, 145, 106), (190, 151, 115), + (190, 152, 116), (190, 154, 118), (193, 157, 117), (194, 161, 117), + (192, 162, 118), (184, 153, 114), (176, 144, 110), (172, 137, 105), + (168, 131, 101), (161, 123, 93), (153, 112, 84), (145, 102, 79), + (137, 92, 72), (119, 68, 60), (116, 64, 57), (113, 61, 55), + (111, 57, 50), (109, 56, 50), (107, 58, 49), (106, 61, 48), + (103, 64, 44), (103, 63, 45), (104, 63, 46), (103, 63, 47), + (102, 64, 48), (98, 66, 50), (99, 70, 55), (95, 77, 55), + (95, 80, 59), (103, 95, 72), (103, 99, 75), (104, 104, 79), + (109, 111, 86), (114, 122, 90), (115, 125, 93), (120, 128, 98), + (136, 138, 112), (148, 143, 118), (161, 148, 125), (164, 150, 128), + (167, 153, 131), (171, 155, 135), (173, 154, 136), (173, 149, 133), + (172, 144, 132), (181, 135, 124), (182, 136, 122), (183, 137, 121), + (184, 141, 120), (182, 142, 113), (177, 141, 106), (173, 136, 98), + (165, 117, 80), (161, 115, 78), (158, 113, 76), (152, 107, 73), + (143, 102, 68), (135, 99, 67), (124, 94, 66), (118, 86, 65), + (111, 79, 66), (89, 62, 62), (84, 59, 60), (79, 56, 58), + (65, 51, 55), (54, 46, 52), (50, 42, 54), (46, 40, 54), + (42, 37, 50), (40, 36, 47), (39, 35, 44), (34, 35, 35), + (34, 32, 33), (33, 33, 31), (36, 34, 31), (36, 35, 33), + (36, 35, 33), (37, 39, 31), (39, 37, 32), (40, 40, 34), + (46, 49, 42), (53, 59, 52), (65, 70, 59), (81, 85, 67), + (111, 97, 73), (117, 100, 74), (124, 103, 76), (131, 107, 79), + (142, 109, 80), (152, 114, 81), (166, 115, 87), (174, 116, 84), + (176, 115, 85), (169, 111, 79), (160, 106, 77), (147, 102, 74), + (143, 100, 78), (141, 104, 86), (142, 112, 102), (138, 122, 112), + (131, 131, 119), (122, 134, 122), (119, 134, 122), (119, 135, 122), + (126, 135, 129), (137, 139, 137), (142, 143, 142), (146, 147, 141), + (148, 147, 134), (149, 147, 120), (150, 144, 107), (153, 136, 98), + (150, 127, 93), (148, 123, 89), (146, 119, 84), (150, 117, 78), + (155, 118, 75), (162, 116, 76), (167, 116, 80), (167, 115, 89), + (165, 115, 104), (170, 122, 115), (178, 133, 126), (190, 142, 142), + (206, 156, 156), (214, 165, 166), (214, 168, 179), (211, 167, 182), + (201, 167, 173), (187, 158, 164), (176, 151, 156), (163, 141, 143), + (151, 129, 132), (141, 111, 123), (128, 94, 111), (117, 78, 98), + (111, 69, 88), (107, 64, 83), (108, 70, 83), (113, 82, 88), + (121, 95, 100), (131, 113, 114), (140, 127, 128), (142, 138, 137), + (142, 145, 149), (140, 153, 155), (132, 157, 160), (127, 167, 163), + (125, 172, 166), (128, 175, 164), (123, 175, 162), (121, 163, 152), + (111, 147, 142), (101, 133, 130), (89, 120, 118), (93, 110, 109) + ), + +// 443 040222-00 +((94, 93, 77), (85, 102, 65), (85, 100, 67), (86, 98, 69), + (99, 105, 72), (112, 113, 75), (116, 117, 79), (121, 121, 84), + (143, 124, 76), (152, 126, 75), (162, 129, 74), (176, 139, 82), + (191, 149, 91), (203, 149, 99), (215, 150, 107), (218, 152, 109), + (222, 154, 112), (221, 153, 125), (215, 139, 115), (209, 125, 106), + (192, 111, 92), (176, 98, 78), (173, 94, 74), (170, 90, 70), + (158, 91, 42), (159, 100, 36), (161, 110, 30), (162, 127, 33), + (164, 144, 37), (168, 147, 38), (172, 150, 40), (177, 144, 45), + (177, 141, 55), (167, 155, 87), (161, 154, 96), (155, 153, 106), + (141, 152, 107), (127, 152, 109), (120, 150, 107), (114, 148, 106), + (99, 125, 92), (99, 102, 83), (99, 79, 75), (100, 57, 68), + (102, 36, 61), (101, 29, 57), (100, 22, 54), (100, 17, 50), + (100, 23, 48), (88, 43, 54), (74, 46, 63), (60, 49, 72), + (60, 54, 85), (61, 59, 98), (63, 58, 105), (66, 58, 112), + (81, 62, 125), (92, 67, 127), (103, 73, 129), (120, 81, 122), + (138, 90, 115), (144, 93, 109), (151, 97, 103), (155, 97, 92), + (152, 95, 87), (134, 89, 73), (118, 72, 66), (103, 55, 60), + (97, 51, 58), (91, 48, 56), (82, 43, 54), (76, 29, 51), + (73, 4, 59), (81, 3, 64), (90, 3, 70), (101, 7, 73), + (113, 11, 76), (116, 18, 79), (119, 26, 83), (134, 39, 85), + (161, 55, 75), (190, 103, 54), (200, 118, 56), (210, 134, 58), + (216, 135, 60), (222, 137, 63), (232, 147, 63), (228, 141, 61), + (221, 108, 68), (212, 90, 66), (204, 72, 65), (200, 63, 65), + (196, 54, 65), (180, 45, 59), (172, 39, 56), (166, 37, 58), + (172, 38, 66), (175, 55, 61), (177, 64, 53), (179, 74, 45), + (175, 78, 43), (172, 83, 41), (160, 81, 37), (152, 78, 33), + (139, 60, 37), (129, 48, 46), (119, 37, 56), (116, 29, 60), + (114, 22, 65), (110, 13, 76), (103, 13, 81), (95, 24, 82), + (81, 33, 72), (45, 38, 56), (42, 45, 52), (39, 53, 48), + (45, 65, 32), (58, 59, 27), (76, 48, 17), (93, 51, 14), + (135, 70, 9), (155, 74, 8), (175, 78, 8), (171, 80, 10), + (167, 82, 13), (152, 92, 19), (143, 101, 25), (136, 106, 29), + (121, 105, 37), (106, 92, 64), (109, 86, 67), (113, 81, 70), + (117, 73, 69), (121, 73, 67), (128, 75, 71), (139, 78, 76), + (156, 99, 84), (158, 117, 93), (161, 135, 103), (160, 138, 108), + (159, 142, 114), (165, 144, 131), (172, 147, 140), (176, 153, 146), + (177, 149, 141), (184, 142, 146), (187, 151, 147), (190, 161, 149), + (200, 170, 141), (208, 169, 129), (221, 156, 122), (224, 159, 115), + (234, 153, 85), (238, 143, 80), (243, 134, 75), (245, 131, 73), + (246, 138, 71), (246, 151, 73), (242, 152, 80), (239, 152, 91), + (236, 146, 98), (231, 129, 100), (224, 123, 103), (218, 117, 106), + (198, 109, 109), (182, 107, 105), (172, 115, 100), (157, 124, 105), + (133, 159, 135), (134, 171, 140), (136, 183, 146), (139, 193, 143), + (134, 197, 145), (129, 193, 141), (131, 188, 146), (132, 178, 136), + (125, 173, 128), (118, 164, 118), (117, 158, 117), (114, 145, 109), + (109, 140, 106), (99, 133, 106), (95, 125, 110), (86, 105, 105), + (62, 79, 95), (57, 72, 95), (53, 66, 95), (46, 47, 88), + (47, 32, 70), (46, 32, 53), (44, 41, 49), (46, 50, 54), + (63, 61, 54), (84, 76, 41), (91, 95, 31), (91, 103, 27), + (100, 110, 33), (125, 102, 31), (146, 93, 26), (154, 77, 12), + (139, 69, 15), (119, 57, 23), (109, 47, 36), (113, 43, 36), + (114, 49, 49), (106, 56, 67), (105, 64, 86), (111, 77, 90), + (130, 90, 98), (142, 102, 102), (155, 116, 110), (165, 134, 113), + (177, 151, 117), (184, 169, 113), (188, 181, 105), (191, 186, 100), + (199, 181, 88), (207, 175, 74), (207, 162, 56), (195, 142, 50), + (182, 118, 39), (165, 105, 30), (151, 98, 19), (136, 97, 29), + (121, 97, 42), (106, 107, 47), (95, 115, 39), (90, 114, 36), + (81, 108, 48), (76, 113, 53), (80, 126, 55), (88, 135, 44), + (89, 142, 44), (90, 146, 50), (97, 156, 71), (108, 165, 86), + (112, 182, 93), (112, 185, 96), (107, 180, 104), (102, 168, 112), + (94, 162, 117), (88, 156, 110), (89, 155, 104), (93, 155, 98), + (98, 156, 97), (103, 158, 91), (112, 158, 83), (119, 152, 81), + (127, 140, 85), (129, 133, 89), (134, 127, 90), (132, 117, 90), + (136, 107, 89), (120, 103, 85), (108, 102, 84), (90, 95, 82) + ), + +// 444 040222-01 +((54, 94, 49), (43, 94, 43), (41, 93, 50), (39, 93, 58), + (38, 95, 61), (38, 97, 65), (37, 98, 63), (36, 99, 62), + (25, 88, 69), (21, 78, 73), (17, 68, 77), (16, 63, 66), + (15, 58, 56), (15, 54, 48), (15, 50, 41), (14, 46, 40), + (14, 43, 40), (15, 33, 44), (16, 33, 44), (18, 34, 44), + (20, 40, 45), (22, 46, 46), (24, 50, 48), (27, 55, 51), + (35, 67, 56), (35, 68, 57), (35, 70, 59), (35, 73, 61), + (36, 77, 64), (38, 78, 65), (41, 79, 66), (42, 77, 74), + (44, 73, 76), (43, 70, 95), (48, 73, 106), (53, 76, 117), + (68, 87, 123), (83, 99, 129), (93, 107, 135), (103, 115, 142), + (146, 152, 174), (163, 169, 184), (181, 186, 195), (200, 201, 200), + (220, 216, 206), (223, 219, 206), (227, 222, 206), (219, 221, 196), + (201, 214, 177), (161, 191, 136), (139, 170, 112), (118, 150, 89), + (92, 133, 69), (66, 116, 50), (57, 110, 43), (49, 105, 37), + (33, 80, 27), (29, 70, 24), (26, 60, 22), (24, 54, 19), + (23, 49, 17), (24, 47, 17), (25, 46, 17), (26, 44, 17), + (28, 44, 17), (33, 59, 21), (39, 69, 26), (45, 80, 32), + (48, 84, 34), (52, 88, 36), (60, 95, 43), (69, 101, 48), + (77, 111, 64), (73, 106, 73), (70, 102, 83), (66, 92, 88), + (62, 82, 93), (59, 78, 97), (57, 75, 101), (50, 70, 109), + (42, 69, 120), (36, 68, 131), (35, 65, 128), (34, 62, 125), + (34, 62, 120), (35, 62, 116), (36, 67, 106), (38, 72, 95), + (38, 71, 72), (37, 69, 60), (37, 68, 48), (37, 70, 44), + (37, 73, 40), (39, 81, 38), (40, 83, 45), (42, 82, 56), + (46, 82, 68), (52, 89, 95), (56, 93, 113), (60, 98, 131), + (65, 101, 139), (70, 105, 147), (82, 112, 169), (96, 124, 180), + (122, 145, 200), (134, 154, 202), (147, 164, 205), (151, 166, 203), + (155, 169, 201), (158, 171, 203), (156, 169, 209), (149, 163, 205), + (143, 157, 205), (121, 138, 182), (116, 136, 177), (111, 134, 172), + (95, 131, 161), (85, 127, 149), (77, 125, 134), (71, 113, 117), + (65, 103, 97), (61, 100, 91), (57, 98, 86), (55, 94, 84), + (54, 90, 83), (51, 81, 85), (49, 73, 94), (47, 69, 103), + (47, 68, 112), (54, 71, 124), (55, 74, 127), (57, 78, 130), + (59, 83, 135), (59, 86, 141), (57, 86, 141), (56, 84, 145), + (54, 83, 150), (49, 80, 148), (44, 77, 147), (41, 74, 143), + (39, 72, 139), (36, 65, 132), (34, 59, 121), (31, 55, 107), + (28, 51, 92), (25, 45, 61), (25, 43, 55), (25, 41, 50), + (25, 41, 39), (25, 43, 31), (25, 47, 25), (25, 53, 20), + (21, 56, 32), (21, 57, 38), (21, 59, 45), (22, 59, 61), + (22, 61, 72), (23, 64, 83), (23, 66, 90), (25, 67, 98), + (27, 71, 105), (38, 86, 105), (40, 91, 102), (43, 96, 100), + (50, 103, 97), (55, 116, 94), (62, 129, 92), (69, 143, 90), + (78, 155, 105), (80, 154, 109), (82, 153, 114), (86, 149, 125), + (87, 143, 132), (86, 141, 135), (86, 134, 141), (87, 132, 139), + (90, 129, 132), (91, 128, 125), (88, 130, 115), (88, 132, 111), + (86, 141, 106), (87, 150, 97), (86, 156, 88), (80, 158, 81), + (70, 142, 86), (68, 138, 89), (66, 134, 92), (61, 122, 91), + (54, 112, 83), (46, 101, 72), (41, 88, 65), (37, 77, 63), + (34, 63, 68), (33, 57, 69), (32, 56, 69), (30, 56, 69), + (28, 60, 64), (25, 59, 70), (23, 60, 76), (27, 68, 83), + (33, 77, 89), (39, 89, 86), (42, 100, 81), (42, 105, 76), + (45, 108, 67), (47, 110, 60), (51, 109, 51), (52, 105, 43), + (50, 97, 37), (47, 85, 30), (41, 73, 23), (36, 60, 17), + (30, 47, 12), (25, 36, 9), (21, 28, 6), (19, 25, 4), + (18, 25, 3), (17, 28, 3), (17, 29, 3), (18, 32, 4), + (19, 36, 7), (21, 40, 10), (23, 48, 14), (26, 56, 18), + (31, 65, 22), (36, 75, 26), (40, 81, 30), (42, 85, 32), + (42, 88, 32), (42, 89, 31), (41, 89, 28), (39, 86, 25), + (34, 81, 22), (32, 76, 21), (31, 73, 20), (31, 72, 22), + (32, 75, 22), (33, 79, 25), (38, 87, 31), (46, 98, 37), + (58, 113, 47), (69, 132, 55), (80, 142, 64), (89, 150, 79), + (92, 151, 95), (100, 151, 111), (109, 155, 120), (112, 151, 123), + (114, 144, 122), (106, 131, 120), (91, 114, 116), (86, 106, 111), + (77, 97, 98), (73, 91, 84), (69, 91, 70), (58, 87, 54) + ), + +// 445 040222-02 +((140, 109, 204), (117, 101, 203), (109, 100, 208), (102, 99, 213), + (98, 93, 210), (95, 88, 208), (101, 89, 205), (107, 90, 203), + (133, 104, 206), (150, 116, 217), (167, 128, 229), (184, 136, 240), + (202, 144, 252), (216, 146, 252), (230, 149, 253), (235, 149, 253), + (240, 150, 254), (247, 153, 254), (240, 150, 254), (233, 148, 254), + (218, 141, 252), (204, 134, 250), (195, 128, 244), (186, 122, 239), + (151, 98, 207), (132, 86, 188), (114, 74, 170), (96, 65, 156), + (79, 57, 143), (69, 52, 135), (59, 47, 127), (43, 39, 110), + (29, 31, 91), (8, 14, 53), (5, 9, 42), (2, 4, 32), + (2, 4, 34), (2, 5, 36), (4, 8, 43), (6, 12, 51), + (16, 28, 82), (20, 35, 97), (24, 43, 112), (23, 42, 112), + (22, 42, 113), (21, 42, 113), (21, 42, 114), (21, 42, 114), + (21, 42, 114), (24, 45, 118), (21, 41, 108), (19, 37, 99), + (14, 29, 82), (10, 21, 65), (8, 17, 57), (6, 13, 49), + (1, 3, 26), (0, 2, 24), (0, 1, 22), (0, 3, 27), + (1, 6, 33), (3, 9, 41), (5, 13, 49), (11, 21, 67), + (17, 29, 85), (29, 43, 118), (30, 47, 126), (32, 51, 134), + (32, 52, 136), (33, 53, 138), (33, 54, 139), (32, 54, 139), + (35, 55, 142), (37, 58, 149), (39, 61, 157), (45, 62, 160), + (51, 63, 164), (54, 62, 164), (57, 62, 164), (63, 60, 163), + (71, 58, 161), (90, 65, 176), (108, 75, 193), (127, 85, 211), + (138, 89, 219), (149, 94, 228), (168, 103, 241), (186, 108, 251), + (208, 114, 254), (214, 116, 254), (221, 118, 254), (222, 119, 254), + (224, 120, 254), (223, 121, 254), (219, 121, 254), (208, 119, 251), + (191, 116, 242), (156, 99, 212), (137, 88, 193), (119, 78, 175), + (110, 73, 166), (102, 68, 158), (83, 60, 144), (65, 52, 128), + (32, 35, 93), (21, 26, 74), (10, 17, 55), (7, 13, 47), + (5, 10, 40), (2, 4, 29), (1, 1, 23), (0, 0, 21), + (0, 0, 20), (0, 0, 20), (0, 0, 21), (0, 0, 22), + (1, 0, 24), (1, 2, 28), (3, 5, 35), (7, 12, 52), + (24, 28, 89), (35, 35, 107), (47, 43, 126), (52, 46, 133), + (58, 49, 140), (68, 53, 150), (76, 60, 167), (83, 67, 184), + (87, 74, 200), (88, 80, 212), (88, 79, 211), (88, 79, 210), + (85, 76, 200), (84, 73, 194), (83, 73, 194), (84, 75, 201), + (82, 77, 205), (74, 75, 200), (67, 74, 195), (62, 70, 186), + (57, 67, 178), (49, 62, 164), (45, 58, 155), (44, 55, 150), + (47, 52, 145), (47, 49, 137), (45, 46, 129), (43, 43, 122), + (34, 37, 105), (23, 29, 86), (13, 21, 66), (7, 13, 47), + (1, 3, 21), (1, 2, 18), (1, 1, 16), (1, 1, 14), + (0, 0, 12), (1, 0, 12), (1, 1, 14), (1, 1, 16), + (2, 4, 22), (8, 15, 46), (10, 18, 54), (12, 22, 63), + (18, 29, 81), (24, 37, 99), (27, 43, 114), (30, 48, 125), + (29, 49, 128), (28, 49, 128), (27, 49, 129), (28, 49, 129), + (29, 48, 129), (29, 47, 127), (29, 47, 124), (26, 41, 110), + (22, 35, 96), (15, 27, 78), (10, 20, 61), (5, 12, 46), + (2, 5, 34), (0, 2, 28), (0, 0, 23), (0, 0, 22), + (0, 0, 21), (0, 0, 21), (0, 0, 22), (0, 0, 23), + (0, 0, 24), (0, 0, 26), (0, 0, 27), (0, 1, 28), + (0, 1, 29), (0, 1, 30), (0, 2, 30), (0, 2, 30), + (0, 2, 30), (0, 2, 31), (0, 2, 32), (0, 3, 35), + (1, 6, 40), (3, 10, 51), (9, 18, 67), (18, 26, 85), + (30, 35, 103), (43, 44, 120), (54, 51, 135), (64, 56, 149), + (68, 61, 161), (69, 67, 174), (69, 71, 183), (70, 73, 188), + (71, 76, 192), (73, 79, 194), (79, 82, 200), (81, 83, 202), + (81, 85, 206), (76, 85, 210), (71, 83, 209), (65, 82, 206), + (60, 78, 199), (59, 78, 198), (60, 79, 200), (63, 82, 205), + (66, 86, 215), (66, 87, 215), (64, 85, 212), (60, 78, 198), + (55, 71, 184), (51, 64, 169), (47, 59, 158), (44, 58, 156), + (42, 59, 155), (43, 61, 158), (47, 62, 159), (55, 63, 159), + (68, 63, 158), (83, 64, 159), (96, 67, 162), (106, 73, 173), + (116, 81, 190), (125, 91, 208), (134, 100, 225), (149, 107, 239), + (168, 113, 251), (187, 119, 254), (202, 122, 254), (211, 126, 254), + (216, 131, 254), (216, 138, 254), (200, 135, 252), (186, 131, 250), + (175, 129, 247), (163, 122, 237), (151, 114, 224), (139, 105, 211) + ), + +// 446 040222-03 +((108, 61, 116), (101, 42, 124), (99, 37, 123), (98, 32, 122), + (94, 32, 122), (91, 33, 122), (90, 33, 121), (89, 33, 121), + (96, 45, 138), (103, 51, 149), (111, 58, 161), (114, 66, 165), + (118, 75, 170), (114, 82, 166), (111, 89, 162), (108, 91, 158), + (106, 93, 154), (97, 99, 138), (94, 95, 132), (92, 92, 126), + (87, 87, 120), (83, 83, 115), (79, 81, 112), (76, 80, 109), + (62, 71, 94), (57, 64, 85), (53, 57, 77), (52, 51, 69), + (51, 45, 61), (52, 43, 58), (54, 42, 56), (61, 43, 56), + (70, 48, 62), (93, 68, 82), (107, 80, 95), (121, 93, 109), + (133, 104, 120), (145, 115, 131), (151, 119, 136), (158, 123, 141), + (182, 143, 162), (193, 151, 171), (204, 160, 181), (209, 164, 186), + (214, 168, 192), (213, 169, 193), (213, 171, 195), (211, 172, 196), + (208, 172, 194), (199, 169, 189), (193, 165, 184), (187, 161, 179), + (176, 152, 171), (166, 143, 164), (160, 138, 160), (155, 134, 157), + (142, 117, 144), (137, 114, 142), (133, 112, 141), (126, 110, 140), + (119, 108, 139), (116, 106, 138), (113, 105, 138), (107, 101, 137), + (100, 100, 135), (96, 87, 126), (95, 85, 123), (95, 83, 121), + (94, 82, 118), (93, 81, 115), (90, 77, 110), (86, 76, 108), + (76, 74, 101), (74, 70, 96), (73, 67, 92), (75, 67, 90), + (78, 68, 89), (79, 67, 87), (81, 67, 86), (85, 68, 85), + (89, 68, 84), (98, 75, 89), (98, 76, 93), (98, 77, 97), + (97, 79, 98), (97, 81, 99), (96, 82, 100), (97, 82, 99), + (105, 82, 98), (109, 85, 98), (113, 89, 98), (113, 89, 99), + (113, 90, 101), (112, 92, 102), (111, 94, 103), (112, 93, 102), + (115, 91, 102), (122, 86, 100), (124, 86, 99), (127, 86, 98), + (126, 86, 98), (125, 86, 99), (121, 87, 99), (114, 86, 97), + (110, 83, 95), (110, 80, 93), (110, 77, 91), (109, 75, 91), + (109, 74, 91), (108, 70, 92), (104, 66, 96), (97, 61, 101), + (94, 57, 106), (95, 48, 120), (98, 49, 123), (102, 50, 126), + (111, 56, 134), (126, 64, 143), (139, 72, 153), (151, 82, 163), + (171, 104, 187), (181, 114, 199), (191, 124, 211), (194, 128, 213), + (198, 133, 216), (209, 143, 220), (216, 152, 223), (223, 158, 221), + (225, 162, 217), (223, 168, 206), (221, 169, 204), (219, 170, 202), + (213, 168, 196), (206, 166, 189), (200, 162, 183), (193, 156, 177), + (175, 132, 161), (165, 121, 149), (156, 110, 138), (151, 105, 132), + (146, 100, 127), (135, 90, 116), (124, 83, 105), (113, 78, 94), + (100, 74, 85), (77, 57, 74), (73, 56, 73), (69, 55, 72), + (63, 53, 69), (63, 52, 68), (64, 53, 68), (67, 56, 71), + (73, 65, 82), (73, 65, 84), (74, 65, 86), (74, 67, 93), + (73, 72, 99), (75, 75, 105), (76, 78, 109), (81, 82, 113), + (87, 87, 117), (106, 89, 133), (110, 87, 136), (115, 85, 139), + (121, 83, 144), (125, 80, 151), (126, 75, 155), (127, 69, 159), + (129, 63, 160), (129, 61, 162), (129, 60, 164), (134, 58, 169), + (140, 60, 173), (147, 67, 177), (152, 74, 180), (158, 80, 186), + (163, 89, 192), (168, 95, 197), (166, 103, 199), (166, 106, 200), + (166, 110, 201), (168, 118, 202), (170, 126, 199), (173, 137, 196), + (183, 158, 198), (184, 162, 198), (186, 167, 198), (192, 169, 199), + (196, 167, 199), (198, 165, 199), (199, 160, 197), (200, 157, 193), + (202, 156, 191), (206, 153, 192), (207, 150, 191), (207, 145, 194), + (210, 140, 198), (213, 134, 200), (215, 126, 199), (213, 118, 198), + (212, 112, 198), (210, 106, 196), (209, 102, 191), (203, 97, 185), + (195, 93, 185), (187, 92, 185), (180, 90, 184), (169, 89, 181), + (157, 88, 180), (144, 87, 174), (134, 85, 162), (126, 83, 147), + (114, 79, 136), (104, 76, 124), (96, 74, 114), (87, 73, 103), + (80, 72, 99), (70, 71, 95), (62, 68, 91), (57, 65, 83), + (54, 60, 76), (53, 57, 69), (53, 53, 65), (53, 50, 60), + (55, 49, 57), (56, 48, 57), (59, 49, 58), (61, 50, 59), + (65, 52, 63), (71, 57, 68), (78, 64, 76), (87, 71, 85), + (96, 79, 92), (106, 84, 101), (116, 89, 109), (125, 92, 114), + (134, 96, 119), (145, 100, 123), (155, 104, 129), (166, 111, 136), + (177, 119, 143), (188, 127, 152), (195, 134, 160), (198, 136, 164), + (198, 137, 165), (194, 134, 162), (191, 129, 157), (183, 123, 151), + (176, 119, 143), (169, 114, 134), (161, 109, 128), (153, 102, 120), + (143, 97, 117), (131, 89, 116), (122, 81, 113), (112, 69, 112) + ), + +// 447 040222-05 +((97, 154, 138), (60, 119, 109), (59, 117, 109), (58, 115, 109), + (65, 124, 114), (73, 133, 120), (78, 139, 123), (83, 146, 126), + (104, 166, 142), (111, 173, 147), (119, 181, 152), (122, 183, 157), + (125, 186, 162), (128, 189, 165), (131, 192, 168), (132, 193, 168), + (133, 195, 169), (142, 198, 178), (149, 202, 181), (157, 207, 184), + (162, 208, 182), (168, 209, 180), (171, 211, 180), (175, 213, 181), + (158, 191, 164), (148, 178, 155), (138, 165, 147), (118, 153, 139), + (99, 141, 131), (97, 139, 129), (95, 137, 128), (92, 136, 131), + (95, 136, 126), (94, 139, 123), (91, 132, 117), (88, 126, 111), + (76, 124, 108), (65, 122, 105), (61, 117, 102), (57, 112, 100), + (50, 106, 97), (47, 104, 94), (45, 102, 91), (43, 102, 89), + (41, 102, 87), (40, 101, 85), (39, 101, 84), (39, 99, 84), + (40, 101, 85), (45, 103, 91), (49, 107, 99), (53, 111, 107), + (58, 116, 112), (63, 122, 118), (65, 125, 120), (68, 128, 123), + (73, 134, 125), (74, 135, 125), (76, 136, 125), (72, 132, 121), + (69, 128, 117), (65, 125, 115), (62, 122, 113), (58, 117, 110), + (55, 112, 105), (55, 114, 105), (62, 118, 108), (69, 123, 111), + (74, 125, 116), (79, 127, 121), (89, 132, 127), (93, 138, 131), + (103, 147, 145), (103, 155, 149), (104, 163, 153), (108, 168, 154), + (113, 173, 156), (113, 174, 157), (114, 176, 158), (119, 179, 159), + (124, 184, 162), (132, 193, 170), (142, 199, 177), (152, 206, 184), + (156, 208, 186), (161, 211, 189), (169, 215, 191), (176, 219, 197), + (188, 220, 203), (191, 221, 205), (194, 222, 208), (191, 220, 207), + (188, 218, 206), (184, 218, 205), (174, 210, 196), (151, 197, 184), + (125, 182, 173), (87, 146, 141), (72, 130, 127), (58, 115, 113), + (53, 111, 108), (49, 107, 104), (44, 102, 95), (43, 100, 89), + (43, 106, 86), (48, 112, 90), (53, 119, 94), (55, 123, 95), + (57, 127, 96), (64, 134, 101), (69, 139, 108), (70, 144, 108), + (70, 141, 109), (72, 134, 113), (75, 131, 112), (78, 128, 111), + (84, 123, 109), (88, 119, 110), (98, 121, 109), (104, 125, 105), + (101, 135, 110), (96, 138, 111), (91, 141, 112), (88, 142, 113), + (85, 144, 115), (80, 146, 119), (78, 145, 121), (81, 146, 125), + (84, 146, 130), (96, 137, 128), (97, 136, 127), (99, 135, 126), + (87, 128, 120), (80, 120, 109), (75, 113, 100), (60, 108, 94), + (44, 104, 91), (48, 108, 94), (52, 113, 97), (55, 116, 101), + (58, 119, 105), (63, 127, 111), (71, 136, 115), (80, 145, 123), + (85, 151, 130), (95, 160, 137), (97, 162, 139), (99, 164, 141), + (101, 164, 145), (101, 166, 144), (99, 163, 141), (94, 157, 137), + (78, 139, 123), (73, 134, 120), (68, 130, 118), (63, 122, 115), + (61, 120, 114), (62, 123, 117), (70, 131, 124), (79, 140, 130), + (86, 148, 135), (99, 162, 143), (100, 163, 142), (101, 165, 141), + (99, 165, 139), (95, 161, 133), (88, 155, 127), (81, 148, 121), + (62, 124, 103), (58, 119, 99), (54, 115, 95), (48, 106, 89), + (42, 98, 84), (37, 95, 79), (35, 94, 76), (36, 94, 78), + (37, 94, 81), (42, 100, 88), (51, 111, 97), (60, 122, 109), + (73, 135, 122), (88, 152, 134), (104, 167, 145), (122, 180, 154), + (152, 199, 165), (153, 200, 165), (155, 202, 165), (154, 202, 167), + (152, 200, 165), (143, 196, 160), (131, 191, 162), (125, 187, 164), + (123, 186, 162), (123, 186, 163), (121, 183, 165), (118, 181, 162), + (115, 180, 157), (113, 179, 151), (107, 174, 146), (100, 169, 142), + (98, 168, 137), (93, 163, 131), (85, 154, 128), (81, 148, 124), + (77, 140, 121), (70, 130, 118), (65, 124, 115), (65, 122, 116), + (66, 123, 118), (68, 127, 118), (75, 136, 122), (81, 146, 127), + (87, 153, 131), (95, 161, 135), (100, 167, 141), (103, 170, 145), + (109, 174, 148), (114, 178, 152), (116, 181, 154), (121, 185, 154), + (127, 190, 154), (130, 194, 156), (134, 198, 157), (141, 202, 160), + (153, 205, 164), (152, 204, 168), (148, 203, 174), (153, 202, 175), + (149, 199, 174), (139, 196, 174), (135, 194, 171), (134, 192, 168), + (130, 191, 165), (126, 188, 162), (124, 186, 159), (121, 182, 155), + (115, 179, 152), (113, 176, 151), (112, 174, 150), (111, 175, 148), + (113, 176, 151), (116, 177, 154), (116, 179, 154), (115, 179, 157), + (115, 176, 156), (112, 170, 152), (108, 161, 150), (109, 151, 143), + (112, 143, 134), (110, 137, 136), (111, 144, 140), (121, 153, 142), + (126, 159, 150), (124, 174, 160), (112, 174, 152), (101, 160, 140) + ), + +// 448 040222-06 +((101, 0, 0), (96, 0, 1), (94, 0, 1), (92, 0, 1), + (86, 0, 0), (80, 0, 0), (78, 0, 0), (77, 0, 0), + (74, 0, 0), (71, 0, 0), (68, 0, 0), (61, 0, 2), + (55, 0, 4), (50, 0, 2), (46, 1, 0), (46, 0, 0), + (46, 0, 0), (59, 0, 0), (77, 0, 0), (96, 1, 0), + (114, 0, 0), (132, 0, 0), (138, 0, 0), (144, 0, 0), + (156, 0, 0), (153, 4, 7), (150, 9, 15), (136, 4, 7), + (122, 0, 0), (114, 0, 0), (106, 0, 0), (98, 0, 0), + (92, 1, 0), (79, 0, 0), (82, 0, 0), (86, 0, 1), + (87, 0, 0), (89, 1, 0), (85, 1, 0), (82, 1, 0), + (70, 2, 1), (64, 1, 0), (58, 0, 0), (56, 0, 0), + (55, 0, 0), (55, 0, 0), (55, 0, 0), (56, 0, 1), + (58, 0, 1), (68, 0, 1), (69, 0, 2), (71, 0, 4), + (62, 0, 3), (53, 1, 3), (48, 1, 3), (44, 2, 4), + (17, 6, 4), (9, 5, 2), (2, 4, 0), (3, 2, 0), + (4, 0, 0), (7, 0, 0), (11, 0, 0), (30, 0, 0), + (39, 0, 0), (46, 0, 0), (50, 0, 0), (54, 0, 0), + (56, 0, 0), (59, 1, 0), (67, 8, 4), (74, 15, 21), + (53, 11, 15), (50, 5, 10), (48, 0, 5), (47, 1, 4), + (46, 2, 3), (45, 1, 1), (45, 1, 0), (47, 2, 0), + (52, 1, 0), (72, 4, 3), (81, 19, 19), (90, 34, 35), + (103, 27, 26), (116, 21, 17), (122, 24, 23), (134, 5, 10), + (140, 0, 1), (132, 0, 0), (125, 0, 0), (121, 0, 0), + (117, 0, 0), (103, 0, 0), (97, 0, 0), (91, 1, 0), + (83, 1, 5), (73, 1, 4), (64, 1, 5), (56, 1, 6), + (53, 2, 5), (50, 4, 4), (47, 1, 3), (44, 0, 1), + (49, 1, 1), (53, 0, 1), (58, 0, 1), (62, 0, 1), + (66, 0, 1), (72, 0, 1), (80, 1, 0), (90, 2, 1), + (93, 0, 0), (95, 1, 0), (93, 2, 1), (91, 3, 2), + (87, 3, 1), (79, 1, 1), (69, 1, 0), (58, 0, 0), + (47, 0, 0), (44, 0, 0), (42, 0, 1), (41, 1, 1), + (40, 2, 1), (39, 0, 1), (31, 0, 0), (13, 0, 0), + (7, 0, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0), + (0, 1, 2), (0, 1, 5), (6, 0, 4), (22, 0, 0), + (59, 0, 2), (86, 2, 2), (113, 5, 3), (121, 11, 8), + (130, 18, 14), (154, 32, 29), (163, 8, 12), (173, 4, 11), + (183, 7, 17), (187, 2, 0), (180, 5, 1), (174, 9, 3), + (151, 3, 1), (136, 0, 0), (123, 1, 0), (106, 0, 0), + (74, 0, 1), (67, 0, 0), (61, 0, 0), (52, 0, 0), + (46, 0, 0), (45, 0, 0), (45, 0, 0), (45, 0, 0), + (44, 0, 0), (44, 0, 1), (42, 0, 1), (41, 1, 2), + (41, 1, 1), (41, 0, 0), (44, 0, 0), (45, 0, 0), + (53, 0, 2), (55, 0, 2), (57, 1, 2), (62, 0, 1), + (69, 0, 1), (75, 1, 2), (80, 0, 1), (85, 1, 1), + (89, 0, 0), (89, 0, 0), (81, 0, 0), (78, 0, 0), + (73, 1, 2), (67, 2, 0), (56, 0, 1), (48, 0, 0), + (33, 0, 0), (24, 0, 0), (15, 0, 0), (7, 0, 0), + (1, 0, 4), (4, 0, 4), (8, 0, 0), (15, 0, 0), + (33, 0, 0), (40, 0, 0), (43, 0, 0), (45, 0, 1), + (50, 0, 1), (54, 0, 0), (58, 0, 0), (65, 1, 0), + (68, 0, 0), (70, 0, 0), (71, 0, 0), (71, 0, 0), + (71, 1, 1), (72, 0, 1), (74, 0, 0), (74, 0, 0), + (75, 0, 0), (79, 0, 0), (85, 0, 0), (93, 0, 0), + (100, 0, 0), (108, 0, 0), (120, 15, 9), (119, 23, 25), + (97, 19, 17), (90, 5, 12), (80, 11, 14), (75, 3, 6), + (80, 0, 1), (91, 0, 0), (103, 0, 0), (115, 1, 1), + (137, 1, 1), (148, 0, 0), (171, 2, 0), (173, 0, 0), + (186, 1, 0), (195, 1, 1), (223, 13, 12), (234, 11, 12), + (236, 0, 0), (215, 0, 0), (213, 0, 0), (194, 0, 0), + (182, 0, 1), (168, 0, 0), (151, 1, 2), (138, 0, 0), + (133, 0, 1), (128, 0, 0), (123, 0, 0), (122, 2, 1), + (118, 0, 0), (114, 0, 4), (109, 0, 3), (103, 0, 1), + (100, 3, 0), (99, 3, 4), (97, 1, 2), (97, 0, 0), + (102, 0, 0), (103, 0, 0), (114, 2, 0), (108, 0, 0) + ), + +// 449 040222-07 +((91, 49, 67), (81, 45, 62), (77, 41, 58), (74, 37, 54), + (72, 33, 50), (71, 30, 47), (71, 27, 45), (72, 24, 44), + (83, 21, 49), (84, 23, 51), (86, 26, 53), (89, 30, 59), + (93, 35, 65), (102, 42, 73), (112, 50, 81), (119, 53, 86), + (127, 56, 91), (160, 73, 115), (171, 84, 126), (183, 96, 138), + (189, 107, 147), (195, 118, 156), (195, 121, 157), (195, 124, 159), + (185, 123, 154), (175, 115, 145), (166, 107, 136), (154, 100, 125), + (142, 93, 114), (135, 90, 109), (129, 87, 104), (116, 81, 93), + (101, 73, 83), (71, 55, 57), (57, 44, 45), (43, 33, 34), + (37, 27, 30), (32, 21, 26), (32, 22, 26), (33, 24, 27), + (51, 35, 45), (66, 43, 61), (82, 52, 77), (97, 61, 89), + (112, 70, 102), (120, 76, 108), (128, 82, 115), (144, 100, 132), + (155, 114, 145), (183, 140, 169), (193, 147, 181), (203, 155, 194), + (206, 155, 194), (210, 155, 194), (210, 156, 193), (211, 157, 193), + (202, 150, 184), (197, 144, 175), (193, 138, 166), (193, 129, 164), + (194, 120, 163), (192, 114, 159), (190, 109, 155), (185, 102, 146), + (178, 97, 138), (159, 80, 117), (147, 68, 104), (136, 56, 92), + (134, 51, 88), (132, 47, 84), (125, 40, 79), (119, 34, 72), + (106, 32, 61), (93, 31, 51), (81, 30, 42), (68, 24, 32), + (55, 19, 22), (49, 15, 18), (44, 12, 14), (34, 6, 8), + (27, 1, 4), (19, 0, 0), (16, 0, 0), (14, 0, 0), + (13, 0, 0), (13, 0, 0), (11, 0, 0), (8, 0, 0), + (4, 0, 0), (2, 0, 0), (1, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (1, 0, 0), (2, 0, 0), + (3, 0, 0), (5, 0, 0), (5, 0, 0), (6, 0, 0), + (6, 0, 0), (6, 0, 0), (6, 0, 0), (7, 0, 0), + (11, 1, 1), (14, 1, 4), (18, 1, 7), (19, 0, 7), + (21, 0, 8), (23, 1, 8), (23, 1, 8), (22, 2, 9), + (20, 2, 8), (17, 2, 6), (17, 2, 6), (17, 3, 7), + (17, 2, 8), (17, 2, 9), (18, 2, 9), (17, 3, 9), + (12, 3, 5), (8, 3, 3), (4, 3, 1), (3, 3, 0), + (2, 3, 0), (0, 2, 0), (0, 1, 0), (0, 1, 0), + (1, 2, 0), (5, 2, 1), (7, 2, 2), (10, 2, 3), + (15, 3, 5), (23, 7, 10), (31, 12, 17), (40, 18, 25), + (62, 31, 43), (76, 34, 52), (90, 37, 61), (98, 38, 64), + (106, 39, 68), (121, 39, 67), (129, 39, 70), (136, 42, 74), + (138, 45, 77), (133, 50, 78), (130, 48, 77), (128, 46, 76), + (123, 46, 79), (120, 41, 69), (113, 32, 61), (104, 26, 53), + (81, 18, 36), (73, 16, 31), (65, 15, 27), (49, 10, 19), + (34, 8, 19), (27, 8, 16), (24, 9, 14), (26, 11, 14), + (32, 16, 19), (53, 31, 36), (60, 34, 41), (68, 38, 47), + (83, 45, 60), (96, 52, 74), (110, 59, 88), (126, 66, 99), + (152, 85, 121), (159, 91, 127), (166, 97, 133), (180, 111, 143), + (193, 122, 152), (201, 130, 163), (207, 137, 172), (209, 138, 175), + (206, 138, 176), (199, 135, 171), (187, 130, 164), (174, 124, 152), + (159, 118, 137), (144, 108, 123), (131, 102, 112), (122, 95, 102), + (112, 84, 94), (110, 81, 93), (109, 79, 93), (105, 75, 90), + (101, 73, 87), (97, 72, 84), (92, 69, 81), (89, 67, 76), + (89, 66, 72), (92, 65, 72), (98, 68, 76), (106, 73, 81), + (117, 79, 89), (130, 89, 99), (141, 96, 110), (149, 105, 119), + (156, 112, 122), (159, 115, 124), (159, 116, 124), (158, 116, 124), + (157, 116, 121), (160, 118, 123), (165, 120, 127), (171, 125, 132), + (179, 132, 140), (186, 135, 147), (191, 139, 150), (191, 140, 152), + (187, 138, 148), (183, 134, 145), (179, 127, 140), (174, 120, 134), + (169, 115, 131), (166, 108, 128), (162, 104, 124), (156, 100, 119), + (150, 94, 111), (142, 86, 104), (134, 76, 95), (128, 66, 87), + (121, 59, 82), (120, 52, 80), (123, 45, 86), (124, 41, 93), + (131, 37, 101), (138, 33, 110), (146, 37, 120), (154, 41, 127), + (160, 44, 133), (166, 49, 135), (171, 51, 140), (174, 55, 144), + (177, 59, 147), (180, 57, 152), (179, 59, 154), (177, 60, 154), + (170, 60, 150), (162, 60, 141), (152, 61, 130), (142, 62, 119), + (131, 66, 106), (120, 65, 95), (110, 62, 86), (105, 63, 81), + (99, 63, 76), (91, 62, 69), (84, 58, 65), (82, 56, 63), + (83, 53, 61), (84, 53, 61), (83, 50, 60), (86, 48, 63) + ), + +// 450 040222-08 +((63, 75, 138), (68, 68, 145), (67, 64, 142), (67, 60, 139), + (66, 54, 133), (66, 48, 127), (65, 45, 124), (65, 43, 122), + (67, 43, 123), (67, 49, 130), (68, 55, 137), (67, 60, 140), + (66, 65, 143), (64, 66, 139), (62, 68, 136), (60, 66, 132), + (58, 65, 128), (53, 60, 109), (52, 60, 107), (52, 61, 106), + (53, 61, 109), (55, 61, 113), (57, 62, 117), (59, 63, 121), + (67, 58, 138), (72, 53, 143), (78, 49, 149), (82, 44, 153), + (86, 39, 157), (89, 37, 157), (92, 36, 158), (95, 33, 156), + (97, 34, 156), (98, 45, 163), (95, 53, 167), (93, 61, 172), + (89, 69, 177), (85, 77, 182), (85, 80, 183), (85, 84, 185), + (84, 90, 176), (85, 90, 170), (87, 91, 165), (88, 94, 165), + (90, 97, 165), (91, 99, 166), (92, 102, 167), (91, 108, 171), + (92, 111, 179), (96, 117, 194), (100, 112, 198), (105, 108, 202), + (110, 104, 209), (116, 100, 216), (119, 99, 219), (122, 98, 222), + (127, 103, 227), (124, 109, 229), (121, 115, 232), (115, 116, 227), + (109, 117, 222), (105, 114, 216), (101, 111, 211), (93, 105, 200), + (86, 97, 191), (76, 86, 166), (72, 82, 157), (68, 79, 149), + (67, 78, 146), (67, 77, 144), (66, 78, 144), (64, 77, 144), + (64, 73, 149), (68, 70, 152), (72, 67, 155), (80, 63, 156), + (89, 59, 157), (93, 57, 158), (98, 56, 160), (106, 61, 168), + (114, 67, 179), (134, 84, 204), (140, 93, 216), (146, 102, 228), + (148, 105, 232), (150, 109, 236), (153, 114, 236), (152, 113, 230), + (145, 109, 211), (140, 106, 199), (135, 104, 188), (132, 102, 182), + (129, 100, 176), (117, 97, 164), (107, 94, 155), (100, 90, 144), + (91, 82, 131), (75, 60, 106), (69, 50, 93), (63, 41, 80), + (60, 37, 75), (58, 33, 70), (53, 25, 60), (49, 19, 52), + (45, 11, 42), (46, 8, 43), (48, 6, 45), (49, 5, 48), + (51, 5, 51), (57, 6, 62), (64, 8, 76), (70, 11, 91), + (76, 13, 105), (84, 18, 129), (85, 18, 132), (86, 19, 136), + (88, 19, 139), (88, 18, 140), (88, 18, 140), (88, 18, 140), + (87, 18, 139), (83, 20, 139), (79, 23, 139), (76, 24, 138), + (74, 26, 137), (69, 27, 131), (64, 28, 123), (58, 28, 113), + (52, 28, 103), (41, 28, 81), (38, 30, 78), (36, 33, 75), + (32, 38, 72), (28, 44, 72), (26, 48, 71), (26, 51, 71), + (27, 57, 76), (29, 57, 79), (31, 58, 82), (33, 58, 83), + (36, 59, 85), (42, 61, 89), (46, 64, 97), (53, 67, 104), + (61, 70, 113), (79, 79, 129), (81, 83, 133), (84, 88, 138), + (84, 94, 145), (85, 99, 150), (86, 106, 155), (89, 107, 161), + (95, 111, 179), (98, 109, 184), (101, 107, 190), (107, 104, 198), + (112, 103, 206), (114, 102, 213), (113, 103, 214), (108, 108, 212), + (107, 108, 209), (105, 107, 205), (105, 105, 204), (106, 103, 204), + (109, 98, 202), (113, 93, 203), (118, 86, 204), (120, 80, 201), + (110, 73, 184), (107, 72, 178), (105, 71, 173), (99, 69, 161), + (93, 65, 147), (88, 64, 133), (81, 63, 123), (76, 61, 116), + (72, 61, 111), (67, 59, 107), (61, 55, 102), (56, 51, 97), + (51, 46, 93), (48, 40, 87), (43, 35, 81), (38, 29, 76), + (26, 22, 63), (24, 21, 60), (22, 21, 57), (19, 19, 51), + (17, 18, 48), (16, 15, 45), (17, 13, 44), (19, 13, 44), + (22, 10, 46), (26, 10, 48), (29, 9, 50), (32, 10, 54), + (35, 11, 56), (38, 14, 58), (41, 16, 59), (42, 19, 61), + (43, 25, 62), (43, 30, 64), (45, 32, 67), (46, 34, 67), + (45, 36, 68), (46, 37, 71), (46, 41, 75), (50, 46, 82), + (51, 53, 91), (54, 66, 104), (53, 81, 116), (55, 94, 130), + (55, 107, 140), (53, 121, 148), (49, 130, 155), (44, 137, 158), + (42, 142, 160), (40, 143, 161), (41, 146, 164), (40, 152, 167), + (42, 158, 174), (44, 164, 181), (46, 171, 188), (49, 174, 192), + (51, 176, 196), (55, 173, 196), (60, 169, 195), (65, 161, 197), + (68, 152, 197), (73, 145, 195), (77, 138, 192), (79, 134, 187), + (81, 128, 182), (81, 128, 181), (80, 128, 180), (81, 131, 179), + (81, 132, 179), (80, 131, 183), (80, 130, 184), (81, 129, 186), + (81, 128, 185), (82, 125, 181), (80, 123, 178), (76, 121, 173), + (72, 125, 168), (66, 131, 163), (61, 135, 161), (55, 138, 161), + (50, 140, 161), (46, 137, 158), (44, 131, 151), (44, 121, 144), + (47, 108, 137), (50, 97, 132), (53, 88, 131), (58, 80, 133) + ), + +// 451 040222-09 +((129, 104, 65), (88, 68, 58), (66, 46, 50), (44, 25, 42), + (35, 13, 37), (26, 1, 32), (27, 1, 31), (29, 1, 30), + (41, 0, 23), (49, 0, 18), (58, 1, 14), (67, 1, 10), + (76, 1, 6), (83, 4, 5), (91, 7, 5), (95, 10, 7), + (99, 14, 9), (128, 35, 16), (145, 51, 20), (162, 67, 24), + (173, 85, 29), (184, 103, 35), (187, 109, 38), (190, 115, 42), + (206, 121, 40), (205, 118, 36), (204, 116, 33), (191, 111, 31), + (179, 106, 29), (171, 99, 27), (163, 92, 25), (149, 75, 19), + (135, 56, 12), (103, 22, 1), (88, 14, 0), (73, 7, 0), + (66, 4, 3), (59, 1, 6), (57, 1, 8), (56, 2, 11), + (62, 10, 19), (73, 17, 22), (84, 25, 25), (100, 32, 28), + (116, 40, 32), (123, 42, 32), (131, 45, 33), (144, 54, 35), + (157, 65, 34), (179, 83, 43), (181, 86, 54), (184, 90, 65), + (174, 92, 77), (165, 94, 89), (159, 93, 90), (154, 92, 91), + (142, 87, 96), (128, 83, 109), (114, 80, 122), (92, 79, 143), + (71, 78, 164), (64, 78, 169), (58, 79, 175), (54, 78, 180), + (53, 77, 178), (52, 88, 192), (44, 96, 208), (36, 104, 225), + (34, 104, 231), (32, 105, 237), (27, 102, 242), (24, 98, 237), + (28, 83, 214), (28, 76, 203), (29, 69, 192), (32, 62, 179), + (36, 55, 167), (43, 51, 158), (50, 47, 149), (68, 44, 128), + (84, 47, 105), (115, 56, 72), (128, 60, 60), (141, 64, 49), + (146, 62, 43), (152, 60, 37), (158, 59, 25), (159, 59, 21), + (140, 56, 20), (122, 47, 25), (104, 38, 30), (94, 32, 34), + (84, 26, 38), (64, 14, 50), (44, 9, 68), (30, 10, 91), + (18, 17, 113), (5, 31, 153), (3, 37, 167), (1, 43, 181), + (1, 43, 187), (1, 43, 193), (2, 44, 201), (2, 42, 203), + (2, 39, 188), (1, 37, 174), (1, 35, 161), (1, 31, 155), + (2, 28, 149), (2, 20, 139), (2, 12, 130), (3, 4, 116), + (6, 3, 100), (21, 9, 72), (25, 9, 68), (29, 9, 64), + (34, 9, 63), (35, 8, 64), (37, 7, 61), (36, 8, 59), + (46, 10, 39), (50, 9, 33), (54, 8, 27), (57, 7, 25), + (60, 6, 23), (63, 6, 21), (70, 8, 22), (81, 13, 23), + (96, 19, 22), (119, 29, 17), (123, 31, 14), (128, 33, 12), + (137, 34, 7), (144, 34, 7), (152, 37, 6), (157, 39, 7), + (156, 37, 6), (148, 31, 4), (140, 25, 2), (135, 22, 1), + (131, 19, 0), (123, 14, 0), (119, 11, 0), (113, 8, 0), + (107, 5, 0), (99, 1, 1), (98, 0, 1), (98, 0, 1), + (102, 1, 1), (108, 3, 0), (111, 5, 0), (114, 11, 1), + (127, 23, 1), (133, 27, 1), (139, 31, 1), (154, 39, 1), + (168, 47, 1), (182, 59, 3), (194, 71, 5), (200, 80, 8), + (204, 89, 11), (202, 92, 21), (200, 92, 22), (199, 92, 24), + (197, 93, 28), (193, 88, 30), (183, 83, 29), (169, 73, 32), + (131, 49, 36), (124, 45, 38), (117, 41, 40), (112, 38, 43), + (114, 39, 42), (119, 42, 40), (131, 51, 40), (137, 58, 39), + (146, 65, 39), (154, 74, 39), (165, 81, 39), (174, 84, 35), + (184, 89, 32), (185, 88, 28), (185, 86, 23), (178, 81, 19), + (159, 64, 10), (156, 60, 8), (153, 57, 6), (142, 49, 7), + (132, 40, 9), (119, 34, 12), (105, 27, 19), (92, 21, 28), + (81, 19, 35), (74, 19, 41), (71, 19, 50), (75, 22, 54), + (80, 26, 57), (88, 32, 59), (96, 36, 58), (103, 41, 53), + (111, 47, 50), (124, 54, 44), (140, 63, 38), (159, 74, 32), + (179, 81, 24), (195, 86, 16), (204, 88, 9), (205, 84, 3), + (200, 78, 1), (187, 72, 8), (174, 66, 20), (159, 62, 32), + (142, 56, 47), (126, 47, 57), (107, 38, 62), (86, 28, 65), + (66, 18, 70), (52, 14, 75), (37, 16, 89), (32, 23, 103), + (28, 29, 120), (22, 36, 135), (15, 38, 145), (12, 34, 144), + (4, 27, 143), (7, 26, 133), (14, 24, 127), (25, 31, 124), + (40, 43, 125), (61, 52, 119), (80, 61, 113), (99, 73, 98), + (118, 80, 83), (139, 93, 67), (159, 109, 56), (181, 120, 47), + (203, 133, 41), (223, 146, 37), (237, 153, 35), (246, 159, 35), + (248, 161, 35), (245, 155, 35), (236, 143, 32), (227, 130, 29), + (220, 119, 25), (219, 113, 23), (218, 113, 23), (222, 117, 29), + (223, 124, 31), (221, 130, 40), (218, 140, 47), (198, 126, 47), + (177, 116, 48), (161, 108, 53), (145, 101, 52), (128, 92, 56) + ), + +// 452 040222-10 +((105, 97, 60), (56, 52, 35), (45, 37, 28), (35, 22, 21), + (48, 26, 19), (61, 30, 18), (65, 31, 17), (70, 33, 16), + (76, 29, 14), (74, 30, 15), (72, 31, 16), (65, 36, 18), + (59, 41, 20), (45, 40, 24), (32, 40, 28), (25, 40, 29), + (18, 40, 31), (5, 41, 34), (4, 39, 32), (4, 38, 30), + (3, 33, 26), (3, 29, 22), (4, 26, 20), (6, 24, 18), + (26, 17, 12), (39, 14, 8), (53, 11, 5), (68, 12, 6), + (83, 13, 7), (89, 13, 8), (95, 13, 9), (103, 12, 9), + (98, 9, 6), (89, 12, 9), (78, 12, 11), (67, 13, 13), + (49, 12, 13), (31, 11, 14), (25, 12, 14), (19, 14, 15), + (22, 28, 23), (31, 36, 26), (41, 45, 29), (46, 55, 32), + (52, 66, 36), (55, 71, 37), (59, 76, 39), (61, 80, 42), + (59, 79, 43), (50, 75, 40), (41, 73, 40), (33, 71, 40), + (23, 61, 39), (13, 52, 38), (9, 48, 37), (6, 44, 36), + (3, 40, 32), (2, 38, 31), (2, 37, 31), (3, 37, 31), + (4, 37, 31), (6, 38, 29), (9, 39, 28), (21, 43, 28), + (36, 49, 29), (78, 70, 42), (95, 87, 55), (112, 105, 68), + (122, 115, 73), (132, 126, 79), (147, 143, 78), (158, 153, 72), + (139, 148, 82), (124, 144, 85), (109, 140, 88), (90, 129, 74), + (71, 119, 61), (62, 110, 60), (54, 102, 59), (43, 85, 62), + (42, 76, 69), (66, 83, 70), (82, 87, 72), (99, 91, 74), + (104, 88, 74), (109, 86, 75), (118, 91, 74), (133, 93, 69), + (157, 88, 55), (155, 81, 51), (153, 75, 47), (151, 73, 46), + (149, 71, 45), (152, 70, 47), (159, 73, 48), (166, 77, 51), + (174, 92, 53), (178, 123, 62), (172, 121, 63), (166, 120, 65), + (161, 119, 62), (157, 118, 60), (138, 115, 62), (121, 121, 57), + (91, 96, 45), (84, 74, 36), (78, 52, 27), (70, 47, 24), + (62, 42, 22), (46, 32, 20), (37, 27, 17), (43, 23, 15), + (62, 22, 12), (82, 26, 14), (83, 28, 15), (84, 31, 16), + (83, 34, 20), (89, 37, 21), (100, 43, 20), (100, 45, 23), + (87, 44, 25), (75, 40, 22), (63, 36, 19), (55, 33, 18), + (48, 30, 17), (33, 24, 14), (19, 20, 13), (8, 15, 12), + (3, 14, 9), (1, 16, 10), (1, 17, 11), (2, 19, 13), + (3, 24, 17), (4, 28, 20), (5, 34, 24), (5, 41, 32), + (15, 57, 61), (30, 72, 85), (45, 88, 110), (54, 99, 122), + (64, 111, 134), (84, 127, 150), (102, 142, 165), (119, 151, 181), + (127, 153, 191), (131, 155, 194), (129, 152, 185), (127, 150, 177), + (118, 137, 157), (103, 113, 129), (74, 92, 104), (54, 68, 81), + (25, 40, 46), (21, 35, 40), (17, 31, 34), (9, 27, 25), + (6, 25, 21), (12, 24, 21), (23, 28, 22), (35, 34, 24), + (47, 41, 28), (64, 55, 34), (72, 58, 35), (80, 62, 36), + (94, 71, 38), (109, 76, 42), (113, 80, 41), (113, 81, 42), + (117, 78, 38), (120, 77, 38), (124, 76, 39), (130, 72, 38), + (133, 69, 37), (135, 67, 37), (136, 63, 36), (132, 59, 40), + (130, 60, 48), (125, 63, 58), (121, 67, 69), (123, 80, 88), + (116, 92, 108), (111, 108, 120), (107, 129, 129), (95, 133, 121), + (76, 132, 115), (69, 127, 110), (63, 122, 106), (61, 123, 102), + (53, 115, 84), (43, 105, 60), (31, 85, 46), (15, 60, 31), + (8, 43, 25), (8, 33, 22), (14, 32, 20), (26, 35, 20), + (36, 41, 23), (47, 61, 32), (62, 75, 49), (77, 94, 69), + (96, 108, 90), (113, 115, 102), (134, 131, 106), (153, 135, 110), + (167, 143, 116), (175, 141, 121), (167, 128, 119), (164, 115, 105), + (150, 93, 86), (137, 77, 69), (121, 61, 57), (95, 51, 48), + (76, 44, 41), (53, 35, 36), (35, 30, 33), (18, 26, 34), + (7, 26, 34), (2, 29, 32), (1, 31, 31), (1, 35, 30), + (2, 37, 31), (4, 39, 31), (5, 39, 32), (4, 40, 33), + (4, 39, 33), (5, 38, 32), (5, 37, 30), (6, 34, 28), + (6, 31, 26), (4, 29, 25), (4, 27, 25), (4, 27, 24), + (4, 26, 25), (4, 26, 24), (4, 27, 24), (3, 29, 26), + (5, 32, 29), (12, 39, 36), (21, 47, 47), (34, 63, 67), + (56, 85, 93), (79, 109, 117), (108, 134, 140), (134, 152, 158), + (155, 171, 178), (179, 192, 201), (198, 214, 221), (215, 231, 228), + (230, 240, 223), (235, 234, 207), (229, 222, 187), (226, 206, 169), + (192, 176, 142), (160, 155, 119), (138, 130, 95), (104, 108, 74) + ), + +// 453 040222-11 +((203, 172, 123), (209, 179, 129), (213, 183, 131), (217, 187, 134), + (219, 188, 135), (222, 190, 137), (222, 189, 137), (222, 189, 137), + (209, 175, 124), (201, 167, 116), (193, 159, 109), (185, 150, 100), + (177, 141, 91), (170, 132, 84), (163, 124, 78), (159, 119, 74), + (156, 115, 71), (143, 100, 59), (137, 94, 54), (131, 89, 49), + (128, 86, 46), (125, 84, 43), (124, 83, 43), (124, 83, 43), + (123, 83, 44), (123, 83, 44), (123, 83, 44), (121, 81, 42), + (119, 80, 41), (118, 79, 40), (117, 79, 39), (113, 76, 35), + (109, 74, 33), (105, 70, 31), (103, 68, 31), (102, 67, 31), + (100, 66, 31), (99, 65, 31), (98, 64, 30), (98, 63, 29), + (95, 61, 27), (94, 60, 27), (93, 60, 28), (92, 60, 29), + (91, 60, 30), (90, 59, 31), (90, 59, 32), (89, 57, 32), + (86, 54, 28), (79, 46, 22), (75, 42, 20), (71, 38, 18), + (66, 34, 16), (62, 31, 15), (60, 30, 15), (58, 29, 16), + (49, 25, 14), (46, 22, 11), (43, 19, 9), (40, 16, 7), + (37, 14, 6), (35, 12, 5), (33, 11, 5), (28, 9, 4), + (25, 9, 4), (22, 10, 4), (24, 11, 5), (26, 13, 6), + (28, 15, 7), (30, 17, 8), (32, 19, 10), (33, 19, 10), + (32, 19, 11), (32, 19, 10), (32, 19, 9), (36, 21, 9), + (41, 24, 9), (44, 26, 10), (48, 29, 11), (54, 33, 15), + (61, 39, 20), (71, 49, 29), (72, 50, 30), (74, 52, 31), + (74, 53, 31), (75, 54, 31), (75, 54, 31), (75, 53, 31), + (79, 56, 33), (81, 57, 34), (83, 59, 35), (83, 59, 35), + (84, 60, 36), (85, 60, 35), (83, 59, 34), (80, 56, 31), + (78, 53, 29), (74, 50, 24), (77, 51, 24), (80, 52, 25), + (84, 54, 26), (88, 56, 27), (97, 65, 33), (106, 74, 41), + (128, 96, 59), (137, 107, 68), (147, 118, 78), (151, 123, 82), + (156, 128, 86), (165, 136, 92), (173, 144, 98), (179, 151, 104), + (181, 154, 109), (182, 156, 112), (181, 155, 112), (180, 155, 112), + (175, 151, 110), (170, 147, 106), (165, 143, 101), (162, 137, 96), + (151, 124, 84), (145, 116, 77), (139, 109, 71), (135, 104, 67), + (131, 99, 64), (125, 92, 58), (118, 86, 53), (114, 82, 48), + (110, 78, 45), (107, 73, 42), (105, 72, 41), (104, 72, 41), + (100, 68, 39), (97, 65, 37), (92, 61, 34), (86, 56, 32), + (69, 43, 23), (61, 37, 19), (53, 32, 16), (49, 28, 14), + (46, 25, 13), (40, 20, 9), (36, 17, 7), (34, 15, 6), + (33, 15, 6), (37, 19, 10), (39, 21, 12), (42, 23, 14), + (48, 29, 18), (55, 34, 22), (62, 41, 26), (71, 49, 31), + (96, 71, 45), (103, 77, 49), (110, 83, 53), (124, 96, 62), + (137, 108, 71), (149, 118, 77), (157, 124, 81), (160, 126, 82), + (160, 126, 80), (152, 119, 74), (148, 117, 73), (145, 115, 72), + (138, 111, 70), (131, 107, 68), (123, 100, 65), (114, 92, 60), + (93, 74, 49), (88, 69, 45), (84, 64, 42), (77, 56, 36), + (73, 52, 33), (73, 52, 34), (76, 56, 37), (84, 62, 41), + (92, 69, 46), (99, 74, 50), (107, 80, 52), (115, 84, 53), + (122, 88, 54), (128, 91, 54), (132, 95, 56), (138, 98, 56), + (142, 101, 54), (141, 100, 53), (140, 99, 52), (138, 97, 50), + (133, 93, 48), (128, 87, 44), (122, 83, 42), (119, 81, 40), + (118, 80, 40), (119, 81, 42), (122, 86, 47), (128, 91, 53), + (134, 100, 62), (142, 110, 73), (151, 120, 84), (160, 132, 96), + (169, 143, 106), (177, 150, 113), (184, 158, 118), (190, 161, 121), + (192, 163, 122), (194, 165, 124), (194, 165, 125), (192, 165, 125), + (191, 165, 125), (187, 162, 122), (183, 157, 117), (179, 150, 111), + (174, 142, 103), (168, 133, 96), (162, 127, 88), (157, 119, 80), + (155, 115, 75), (153, 112, 71), (150, 110, 69), (149, 108, 66), + (148, 106, 63), (147, 104, 61), (148, 104, 60), (148, 105, 60), + (151, 107, 62), (157, 112, 65), (164, 120, 71), (171, 128, 79), + (177, 136, 87), (182, 144, 96), (187, 151, 105), (191, 159, 114), + (194, 166, 125), (201, 174, 134), (209, 184, 143), (218, 194, 154), + (227, 204, 164), (234, 215, 174), (241, 223, 182), (246, 230, 188), + (248, 233, 191), (248, 233, 191), (246, 230, 188), (242, 225, 181), + (237, 217, 173), (230, 209, 163), (223, 200, 153), (215, 191, 143), + (207, 182, 134), (206, 178, 129), (205, 175, 126), (205, 174, 123), + (204, 171, 121), (204, 171, 121), (206, 172, 122), (206, 173, 124) + ), + +// 454 040222-12 +((61, 63, 55), (43, 52, 51), (37, 50, 50), (31, 48, 50), + (34, 50, 53), (37, 53, 56), (39, 55, 58), (42, 57, 60), + (59, 66, 63), (65, 65, 61), (71, 65, 59), (74, 65, 57), + (77, 65, 56), (79, 65, 57), (81, 65, 58), (82, 66, 58), + (84, 67, 58), (88, 72, 62), (87, 72, 62), (87, 73, 63), + (87, 73, 62), (87, 74, 62), (88, 73, 61), (89, 73, 61), + (105, 76, 53), (115, 81, 53), (126, 87, 54), (132, 91, 57), + (138, 96, 60), (136, 98, 64), (135, 100, 68), (132, 108, 78), + (131, 113, 85), (134, 118, 92), (139, 120, 93), (145, 123, 94), + (146, 121, 93), (148, 120, 92), (144, 119, 93), (141, 118, 95), + (122, 112, 95), (114, 106, 92), (107, 101, 89), (108, 98, 83), + (110, 95, 77), (111, 93, 75), (112, 92, 73), (113, 91, 72), + (113, 94, 77), (108, 109, 92), (103, 114, 99), (99, 120, 107), + (95, 123, 110), (92, 127, 113), (89, 127, 114), (87, 128, 116), + (69, 129, 126), (61, 132, 133), (53, 135, 140), (47, 139, 148), + (42, 143, 156), (41, 143, 156), (40, 144, 157), (40, 140, 153), + (40, 134, 146), (33, 114, 124), (32, 105, 113), (32, 96, 103), + (33, 93, 99), (34, 91, 96), (34, 88, 92), (36, 85, 88), + (41, 82, 83), (41, 76, 75), (41, 70, 68), (40, 64, 61), + (40, 58, 55), (39, 56, 52), (39, 54, 50), (40, 51, 47), + (42, 50, 46), (47, 51, 48), (48, 52, 49), (49, 54, 50), + (49, 54, 50), (50, 54, 51), (52, 54, 50), (56, 55, 48), + (68, 56, 44), (75, 56, 41), (83, 57, 38), (86, 58, 37), + (89, 59, 37), (95, 62, 37), (100, 63, 36), (105, 65, 35), + (106, 66, 34), (104, 67, 31), (100, 63, 28), (97, 60, 25), + (94, 59, 24), (92, 58, 24), (87, 56, 24), (85, 55, 24), + (81, 55, 25), (80, 54, 25), (80, 53, 25), (79, 51, 24), + (78, 50, 23), (74, 48, 21), (69, 45, 20), (64, 42, 18), + (61, 39, 17), (61, 36, 18), (62, 36, 18), (64, 37, 18), + (68, 39, 18), (74, 40, 19), (81, 40, 18), (85, 41, 18), + (84, 45, 22), (79, 49, 31), (75, 54, 40), (74, 58, 45), + (73, 63, 51), (70, 74, 66), (74, 86, 79), (86, 95, 87), + (99, 105, 92), (122, 118, 98), (122, 121, 102), (122, 124, 106), + (121, 131, 115), (117, 140, 125), (110, 147, 135), (110, 148, 140), + (119, 151, 138), (126, 144, 129), (133, 138, 120), (135, 135, 116), + (137, 132, 113), (138, 130, 109), (134, 127, 106), (131, 121, 101), + (131, 117, 96), (146, 111, 79), (151, 108, 73), (157, 106, 68), + (165, 102, 60), (168, 102, 58), (168, 103, 60), (165, 105, 63), + (160, 118, 83), (158, 122, 89), (156, 127, 95), (153, 134, 102), + (151, 141, 109), (145, 147, 117), (138, 151, 124), (129, 149, 126), + (116, 145, 127), (88, 135, 130), (81, 132, 129), (75, 129, 129), + (64, 122, 125), (53, 117, 120), (44, 113, 117), (38, 103, 107), + (28, 80, 82), (26, 75, 76), (24, 70, 71), (22, 60, 62), + (22, 50, 52), (24, 44, 43), (27, 40, 38), (33, 40, 36), + (40, 44, 37), (51, 48, 38), (62, 53, 39), (74, 59, 42), + (89, 66, 45), (103, 73, 45), (114, 78, 46), (125, 82, 46), + (141, 84, 45), (143, 83, 44), (145, 82, 43), (145, 80, 41), + (144, 78, 39), (143, 75, 36), (140, 72, 34), (139, 67, 30), + (137, 67, 26), (136, 63, 23), (137, 59, 19), (139, 60, 18), + (140, 60, 16), (141, 61, 16), (143, 64, 20), (148, 68, 24), + (155, 78, 28), (163, 88, 34), (172, 94, 39), (181, 100, 43), + (192, 106, 44), (197, 109, 43), (201, 110, 42), (201, 110, 42), + (199, 110, 42), (197, 112, 44), (190, 111, 50), (180, 109, 54), + (172, 107, 57), (163, 104, 58), (156, 100, 58), (149, 95, 57), + (143, 90, 55), (145, 89, 54), (148, 92, 56), (152, 97, 62), + (156, 105, 73), (159, 114, 84), (167, 125, 97), (175, 136, 111), + (170, 145, 123), (170, 154, 135), (170, 163, 143), (171, 171, 152), + (171, 180, 163), (167, 185, 169), (162, 190, 174), (165, 193, 179), + (154, 193, 181), (141, 190, 181), (129, 184, 177), (120, 175, 170), + (113, 168, 162), (107, 159, 152), (102, 150, 140), (108, 143, 129), + (114, 135, 116), (116, 128, 105), (118, 120, 94), (120, 112, 84), + (121, 105, 75), (123, 97, 66), (123, 90, 59), (121, 84, 54), + (122, 80, 48), (118, 77, 46), (112, 74, 46), (106, 74, 48), + (97, 74, 51), (89, 73, 54), (81, 71, 56), (68, 67, 56) + ), + +// 455 040222-13 +((33, 6, 3), (26, 9, 4), (23, 11, 4), (21, 13, 5), + (31, 15, 4), (41, 18, 4), (45, 21, 3), (50, 24, 3), + (71, 39, 5), (83, 46, 10), (95, 53, 15), (108, 61, 22), + (121, 70, 30), (131, 82, 40), (141, 95, 51), (146, 100, 55), + (152, 106, 59), (181, 132, 78), (191, 142, 87), (202, 153, 96), + (210, 156, 98), (219, 159, 100), (222, 159, 100), (226, 159, 100), + (222, 151, 93), (204, 136, 86), (186, 121, 79), (166, 100, 68), + (146, 80, 57), (136, 72, 50), (127, 64, 43), (109, 53, 37), + (90, 40, 29), (68, 27, 22), (62, 26, 18), (57, 25, 15), + (53, 26, 14), (49, 28, 14), (48, 30, 16), (48, 32, 18), + (40, 36, 16), (34, 35, 15), (29, 34, 14), (26, 31, 17), + (24, 29, 21), (23, 29, 23), (22, 30, 26), (20, 28, 30), + (23, 33, 30), (44, 40, 37), (61, 47, 42), (78, 54, 47), + (96, 58, 42), (114, 62, 37), (125, 65, 33), (136, 68, 30), + (177, 91, 34), (180, 87, 32), (184, 84, 30), (171, 72, 22), + (158, 61, 15), (150, 59, 14), (143, 58, 14), (124, 58, 17), + (102, 47, 18), (53, 18, 12), (40, 14, 12), (27, 10, 13), + (25, 9, 14), (23, 9, 15), (21, 6, 12), (22, 5, 12), + (25, 6, 13), (28, 5, 11), (31, 5, 9), (30, 4, 6), + (30, 3, 3), (28, 3, 3), (26, 4, 4), (24, 5, 8), + (23, 7, 9), (29, 16, 6), (37, 23, 9), (45, 30, 12), + (51, 33, 15), (57, 36, 19), (75, 49, 26), (93, 60, 32), + (127, 88, 40), (145, 96, 48), (163, 105, 57), (171, 110, 63), + (180, 115, 70), (189, 122, 80), (195, 137, 94), (203, 145, 100), + (209, 150, 99), (223, 156, 99), (223, 166, 116), (224, 177, 133), + (225, 183, 136), (227, 190, 139), (236, 199, 134), (244, 203, 123), + (243, 207, 131), (245, 213, 139), (248, 219, 148), (251, 217, 147), + (254, 216, 147), (252, 209, 132), (244, 197, 125), (233, 184, 121), + (219, 171, 115), (185, 135, 96), (172, 126, 88), (160, 118, 81), + (136, 103, 69), (115, 90, 56), (97, 82, 46), (87, 75, 39), + (71, 74, 38), (67, 72, 37), (63, 70, 37), (62, 66, 34), + (61, 62, 32), (63, 58, 32), (64, 55, 30), (66, 48, 29), + (62, 42, 25), (53, 21, 9), (54, 19, 6), (56, 17, 3), + (65, 21, 2), (74, 28, 6), (84, 37, 13), (90, 47, 21), + (99, 60, 39), (97, 63, 48), (95, 67, 58), (91, 66, 62), + (88, 66, 67), (81, 61, 65), (69, 54, 63), (57, 45, 58), + (43, 36, 52), (23, 20, 37), (20, 17, 31), (17, 15, 26), + (15, 14, 17), (14, 13, 9), (15, 17, 7), (17, 23, 9), + (22, 34, 14), (23, 35, 14), (24, 37, 15), (26, 39, 15), + (27, 41, 16), (29, 40, 15), (31, 41, 15), (32, 39, 13), + (33, 36, 11), (29, 34, 12), (29, 35, 12), (30, 36, 13), + (35, 38, 15), (38, 38, 15), (41, 40, 15), (40, 41, 16), + (39, 41, 16), (39, 38, 15), (40, 36, 15), (42, 29, 12), + (40, 24, 9), (36, 18, 4), (32, 14, 2), (29, 10, 1), + (28, 6, 0), (26, 3, 0), (22, 1, 0), (18, 0, 0), + (16, 1, 0), (16, 3, 0), (20, 6, 1), (25, 9, 2), + (44, 21, 3), (49, 24, 2), (54, 27, 2), (64, 29, 3), + (71, 29, 5), (80, 27, 5), (85, 25, 5), (86, 26, 2), + (83, 23, 2), (76, 19, 2), (70, 12, 2), (63, 5, 2), + (56, 3, 0), (53, 2, 0), (50, 4, 0), (48, 8, 0), + (45, 9, 0), (42, 11, 1), (43, 10, 1), (44, 10, 2), + (45, 12, 2), (42, 12, 1), (36, 14, 2), (33, 13, 1), + (33, 12, 1), (35, 13, 1), (42, 15, 3), (52, 21, 7), + (63, 33, 14), (82, 46, 21), (98, 60, 29), (112, 72, 37), + (125, 78, 46), (131, 85, 57), (140, 91, 61), (139, 97, 65), + (135, 102, 66), (124, 96, 67), (111, 91, 77), (105, 86, 84), + (94, 81, 89), (83, 79, 90), (67, 70, 84), (54, 63, 84), + (52, 59, 86), (52, 56, 86), (51, 53, 85), (47, 48, 74), + (40, 40, 63), (39, 33, 56), (41, 31, 50), (41, 30, 50), + (44, 31, 51), (45, 36, 54), (52, 42, 63), (60, 50, 74), + (66, 59, 87), (71, 67, 98), (76, 76, 110), (88, 86, 115), + (96, 93, 114), (101, 95, 110), (102, 91, 99), (93, 80, 89), + (89, 73, 77), (86, 64, 62), (81, 54, 47), (79, 44, 33), + (62, 30, 21), (48, 20, 12), (38, 12, 7), (30, 7, 4) + ), + +// 456 040222-15 +((153, 104, 63), (189, 101, 74), (188, 94, 76), (188, 88, 78), + (211, 75, 65), (235, 63, 52), (240, 53, 46), (246, 44, 41), + (251, 16, 20), (240, 16, 15), (230, 16, 10), (201, 15, 7), + (173, 15, 4), (148, 19, 7), (123, 23, 11), (115, 25, 13), + (108, 28, 16), (61, 46, 26), (52, 64, 36), (43, 82, 47), + (51, 103, 68), (59, 125, 89), (63, 136, 99), (68, 147, 110), + (81, 183, 133), (78, 183, 135), (75, 184, 138), (66, 173, 135), + (57, 162, 133), (50, 152, 126), (44, 143, 120), (34, 121, 105), + (23, 98, 86), (13, 71, 63), (19, 73, 69), (26, 75, 76), + (42, 94, 95), (59, 114, 114), (66, 126, 121), (74, 138, 128), + (98, 180, 147), (122, 202, 154), (146, 224, 162), (168, 223, 162), + (191, 223, 163), (195, 213, 156), (199, 203, 149), (208, 175, 124), + (219, 156, 97), (244, 119, 68), (247, 105, 60), (251, 92, 52), + (251, 94, 50), (252, 96, 49), (250, 100, 49), (248, 105, 50), + (232, 100, 37), (220, 97, 35), (209, 95, 34), (205, 92, 37), + (202, 90, 41), (200, 80, 36), (198, 70, 31), (193, 47, 18), + (187, 23, 5), (193, 20, 2), (199, 20, 3), (205, 21, 5), + (200, 22, 4), (196, 23, 3), (176, 29, 5), (155, 40, 10), + (115, 67, 22), (97, 80, 26), (79, 94, 30), (56, 97, 35), + (34, 100, 41), (25, 97, 43), (17, 94, 45), (16, 90, 45), + (15, 84, 39), (12, 62, 35), (8, 48, 32), (5, 34, 29), + (4, 30, 26), (4, 26, 23), (4, 27, 22), (5, 38, 33), + (14, 79, 71), (21, 102, 91), (28, 125, 112), (33, 136, 123), + (38, 148, 135), (40, 169, 155), (52, 192, 179), (62, 215, 205), + (73, 231, 218), (83, 241, 230), (79, 232, 223), (75, 224, 216), + (75, 218, 212), (76, 213, 208), (79, 206, 198), (81, 197, 187), + (67, 191, 156), (66, 189, 149), (66, 188, 142), (68, 178, 147), + (71, 169, 152), (73, 152, 164), (76, 142, 173), (78, 145, 185), + (83, 161, 182), (100, 150, 173), (107, 145, 168), (114, 141, 163), + (129, 133, 168), (142, 148, 161), (163, 154, 139), (178, 154, 115), + (215, 131, 66), (218, 119, 60), (222, 107, 55), (220, 102, 52), + (219, 97, 50), (204, 79, 35), (189, 68, 28), (162, 60, 29), + (138, 64, 37), (107, 87, 58), (99, 93, 60), (91, 100, 62), + (73, 107, 64), (54, 113, 77), (50, 122, 91), (48, 127, 104), + (50, 128, 98), (57, 119, 86), (65, 111, 74), (75, 106, 68), + (85, 101, 63), (98, 90, 57), (111, 90, 49), (119, 100, 44), + (111, 109, 41), (113, 123, 25), (116, 127, 23), (119, 131, 22), + (135, 147, 37), (131, 163, 61), (123, 179, 82), (114, 189, 93), + (105, 212, 91), (107, 214, 93), (109, 216, 95), (122, 223, 107), + (139, 208, 112), (152, 196, 102), (163, 180, 90), (162, 162, 72), + (168, 155, 64), (175, 145, 79), (180, 137, 84), (186, 130, 90), + (180, 112, 103), (177, 91, 103), (171, 81, 106), (141, 86, 110), + (90, 106, 124), (80, 106, 126), (71, 106, 128), (77, 108, 135), + (70, 121, 138), (71, 135, 133), (69, 157, 141), (69, 175, 150), + (86, 189, 167), (103, 202, 187), (123, 213, 197), (143, 223, 199), + (161, 216, 196), (180, 206, 185), (198, 183, 175), (208, 160, 155), + (208, 132, 109), (202, 131, 101), (197, 131, 93), (184, 128, 87), + (169, 127, 81), (158, 133, 70), (148, 138, 66), (147, 143, 63), + (149, 146, 66), (149, 146, 67), (155, 146, 60), (160, 141, 57), + (177, 136, 50), (198, 132, 46), (204, 129, 45), (195, 127, 43), + (174, 126, 48), (150, 126, 49), (136, 125, 49), (119, 136, 53), + (99, 148, 60), (77, 160, 80), (61, 170, 100), (55, 175, 119), + (57, 184, 132), (64, 192, 139), (77, 198, 147), (98, 207, 156), + (123, 217, 164), (147, 224, 174), (167, 223, 179), (186, 213, 170), + (202, 199, 152), (221, 184, 123), (236, 172, 98), (246, 156, 82), + (251, 137, 68), (245, 118, 52), (232, 102, 37), (204, 94, 24), + (174, 86, 17), (147, 79, 16), (122, 69, 13), (106, 57, 14), + (79, 52, 18), (52, 48, 23), (28, 44, 24), (9, 40, 21), + (5, 35, 19), (4, 33, 18), (7, 35, 22), (9, 38, 25), + (11, 45, 24), (9, 53, 27), (6, 59, 27), (5, 62, 26), + (6, 61, 27), (7, 61, 26), (7, 62, 28), (7, 65, 33), + (7, 65, 35), (9, 60, 34), (10, 54, 34), (11, 48, 32), + (13, 41, 31), (20, 38, 29), (42, 39, 25), (73, 52, 27), + (73, 65, 40), (80, 74, 52), (83, 87, 61), (96, 94, 66) + ), + +// 457 040222-16 +((100, 134, 148), (88, 123, 138), (82, 116, 131), (76, 110, 125), + (73, 106, 121), (70, 102, 117), (69, 101, 115), (69, 100, 114), + (64, 97, 110), (65, 98, 112), (67, 100, 115), (68, 103, 118), + (70, 106, 122), (71, 108, 124), (72, 110, 127), (72, 110, 128), + (72, 110, 129), (72, 110, 129), (73, 111, 130), (75, 113, 131), + (78, 115, 132), (81, 118, 134), (83, 120, 136), (85, 123, 138), + (92, 130, 145), (95, 133, 147), (99, 136, 150), (100, 138, 153), + (102, 141, 157), (104, 144, 159), (106, 147, 162), (111, 154, 168), + (115, 159, 173), (125, 168, 179), (125, 167, 177), (125, 166, 176), + (121, 160, 169), (118, 154, 162), (115, 149, 157), (113, 145, 152), + (98, 123, 131), (91, 114, 122), (84, 105, 113), (79, 99, 106), + (75, 93, 99), (73, 91, 97), (72, 89, 96), (69, 86, 92), + (67, 83, 89), (68, 80, 85), (66, 76, 80), (64, 73, 76), + (60, 68, 71), (57, 64, 67), (55, 61, 65), (53, 59, 63), + (46, 52, 57), (44, 51, 55), (43, 50, 54), (44, 51, 55), + (46, 52, 56), (48, 54, 58), (51, 57, 61), (56, 64, 67), + (64, 72, 75), (83, 92, 95), (93, 102, 105), (104, 113, 115), + (108, 117, 120), (113, 122, 126), (122, 131, 134), (126, 137, 141), + (138, 149, 154), (144, 155, 159), (151, 162, 165), (159, 170, 172), + (167, 179, 180), (171, 183, 184), (175, 188, 189), (184, 197, 197), + (189, 205, 206), (202, 218, 219), (207, 223, 223), (212, 228, 228), + (213, 229, 229), (214, 231, 231), (216, 232, 233), (216, 232, 232), + (215, 231, 231), (213, 229, 229), (211, 227, 227), (210, 226, 226), + (209, 226, 225), (208, 224, 224), (208, 223, 222), (207, 222, 221), + (206, 221, 221), (204, 219, 220), (203, 218, 220), (202, 217, 220), + (202, 216, 218), (202, 215, 217), (200, 212, 214), (195, 209, 212), + (184, 199, 203), (177, 192, 196), (170, 185, 189), (166, 181, 185), + (162, 177, 182), (155, 170, 175), (147, 163, 169), (141, 158, 164), + (135, 153, 160), (122, 141, 150), (119, 140, 149), (117, 139, 149), + (114, 137, 148), (110, 137, 148), (108, 136, 148), (106, 137, 149), + (103, 136, 149), (102, 136, 149), (101, 136, 149), (100, 135, 148), + (100, 134, 148), (97, 130, 144), (95, 127, 143), (94, 126, 142), + (93, 127, 143), (98, 132, 147), (100, 134, 148), (103, 136, 150), + (107, 139, 154), (111, 143, 157), (112, 145, 159), (113, 146, 160), + (107, 139, 154), (101, 131, 146), (96, 123, 138), (91, 118, 133), + (87, 113, 128), (80, 105, 120), (74, 98, 111), (70, 91, 104), + (67, 86, 99), (63, 82, 96), (63, 82, 96), (64, 83, 97), + (66, 87, 100), (68, 90, 104), (69, 93, 108), (68, 94, 112), + (67, 96, 116), (67, 96, 116), (67, 97, 117), (67, 98, 117), + (67, 98, 117), (67, 97, 116), (65, 95, 115), (66, 95, 112), + (65, 94, 111), (63, 93, 111), (63, 93, 110), (63, 93, 110), + (63, 92, 109), (63, 92, 109), (64, 91, 107), (63, 90, 106), + (59, 83, 99), (57, 81, 96), (56, 79, 94), (53, 74, 89), + (50, 69, 83), (46, 64, 77), (42, 59, 72), (39, 54, 66), + (36, 50, 62), (35, 47, 58), (33, 45, 56), (33, 45, 55), + (33, 45, 55), (33, 45, 56), (34, 47, 59), (36, 50, 62), + (39, 55, 71), (39, 56, 73), (40, 58, 75), (42, 60, 79), + (43, 63, 82), (45, 65, 84), (47, 68, 87), (51, 72, 91), + (56, 76, 94), (61, 81, 99), (67, 87, 104), (73, 94, 110), + (79, 100, 116), (86, 107, 123), (92, 113, 129), (99, 120, 135), + (105, 125, 141), (110, 130, 145), (115, 136, 150), (122, 142, 155), + (127, 148, 160), (134, 155, 164), (140, 161, 170), (146, 167, 175), + (151, 173, 179), (156, 177, 182), (159, 179, 183), (161, 179, 181), + (158, 174, 178), (153, 169, 172), (148, 163, 166), (142, 156, 160), + (136, 150, 154), (130, 146, 150), (126, 142, 148), (123, 141, 148), + (121, 141, 149), (121, 142, 150), (120, 143, 150), (120, 141, 150), + (119, 138, 147), (118, 135, 144), (118, 133, 140), (117, 130, 137), + (116, 128, 135), (116, 127, 134), (117, 129, 135), (118, 132, 139), + (122, 137, 146), (128, 146, 153), (134, 154, 161), (142, 162, 169), + (147, 168, 175), (152, 173, 180), (156, 176, 183), (157, 177, 183), + (155, 174, 180), (152, 170, 175), (149, 164, 170), (144, 160, 166), + (142, 158, 164), (138, 155, 161), (133, 150, 156), (128, 145, 152), + (123, 142, 149), (119, 140, 148), (117, 140, 149), (115, 140, 149), + (112, 139, 149), (110, 138, 149), (104, 136, 147), (102, 135, 148) + ), + +// 458 040222-17 +((145, 86, 63), (120, 68, 49), (105, 61, 47), (90, 55, 45), + (90, 54, 45), (90, 53, 45), (90, 52, 43), (90, 51, 42), + (79, 41, 34), (73, 36, 30), (67, 32, 26), (63, 28, 23), + (59, 24, 20), (55, 20, 17), (51, 16, 14), (49, 14, 12), + (48, 13, 10), (47, 9, 7), (49, 8, 8), (51, 7, 9), + (59, 10, 11), (67, 13, 13), (71, 15, 14), (75, 17, 16), + (88, 30, 25), (95, 36, 29), (102, 42, 34), (110, 48, 40), + (119, 55, 46), (123, 60, 49), (128, 65, 53), (139, 74, 58), + (148, 82, 67), (164, 81, 73), (168, 81, 73), (173, 81, 74), + (173, 82, 75), (173, 83, 76), (171, 81, 74), (170, 79, 73), + (167, 66, 66), (157, 62, 61), (147, 58, 57), (137, 55, 51), + (128, 52, 46), (125, 50, 44), (122, 48, 43), (111, 43, 36), + (97, 34, 30), (64, 21, 17), (51, 17, 13), (39, 13, 9), + (32, 10, 6), (26, 7, 4), (25, 6, 3), (24, 5, 3), + (26, 8, 6), (31, 9, 8), (36, 11, 11), (42, 12, 13), + (49, 14, 15), (52, 14, 16), (55, 15, 17), (61, 17, 21), + (65, 22, 25), (74, 32, 31), (75, 35, 33), (76, 39, 36), + (75, 40, 38), (74, 42, 41), (73, 46, 42), (73, 48, 42), + (71, 45, 35), (70, 41, 33), (69, 37, 32), (70, 35, 31), + (71, 34, 31), (72, 34, 30), (73, 34, 30), (75, 32, 31), + (78, 34, 34), (92, 49, 50), (105, 66, 63), (119, 84, 76), + (128, 91, 81), (137, 99, 87), (150, 108, 98), (158, 112, 105), + (169, 119, 115), (175, 114, 108), (182, 110, 102), (178, 103, 96), + (175, 96, 91), (162, 83, 85), (145, 69, 78), (132, 57, 64), + (122, 45, 51), (100, 27, 29), (89, 23, 25), (78, 20, 22), + (73, 19, 21), (69, 18, 21), (61, 16, 16), (55, 13, 12), + (45, 8, 6), (45, 9, 7), (45, 11, 8), (45, 12, 9), + (46, 14, 10), (47, 18, 13), (49, 20, 14), (54, 23, 17), + (60, 26, 18), (67, 33, 23), (66, 34, 24), (65, 35, 25), + (62, 34, 27), (58, 34, 27), (56, 34, 28), (55, 34, 29), + (55, 40, 38), (57, 43, 42), (59, 47, 46), (61, 47, 47), + (63, 48, 48), (69, 49, 51), (75, 54, 55), (85, 59, 60), + (93, 63, 64), (110, 67, 66), (113, 69, 65), (116, 71, 64), + (125, 76, 64), (132, 81, 67), (136, 89, 70), (147, 93, 73), + (162, 106, 76), (162, 108, 75), (163, 110, 75), (161, 109, 74), + (160, 109, 74), (153, 104, 73), (146, 100, 72), (136, 92, 68), + (123, 84, 63), (97, 67, 50), (92, 63, 47), (87, 59, 45), + (75, 51, 39), (65, 43, 33), (58, 35, 28), (52, 29, 23), + (46, 23, 19), (44, 22, 17), (43, 21, 16), (40, 16, 15), + (37, 14, 12), (35, 11, 11), (34, 10, 11), (34, 11, 13), + (33, 12, 15), (32, 13, 17), (31, 13, 16), (30, 14, 16), + (29, 14, 17), (31, 14, 17), (33, 14, 18), (35, 12, 17), + (41, 9, 13), (43, 8, 12), (46, 8, 12), (51, 9, 15), + (58, 12, 18), (68, 15, 19), (78, 18, 21), (86, 21, 21), + (92, 25, 22), (93, 27, 22), (94, 29, 23), (96, 29, 23), + (96, 29, 23), (95, 31, 22), (88, 32, 21), (79, 29, 18), + (62, 21, 17), (58, 20, 17), (55, 19, 17), (49, 18, 19), + (44, 19, 18), (41, 18, 18), (41, 17, 18), (45, 16, 18), + (53, 16, 20), (65, 17, 22), (82, 21, 24), (99, 29, 27), + (113, 36, 29), (125, 44, 32), (134, 50, 35), (144, 55, 40), + (154, 64, 45), (157, 70, 49), (154, 77, 53), (142, 82, 54), + (131, 83, 59), (122, 83, 64), (117, 83, 67), (116, 82, 72), + (111, 84, 74), (109, 89, 78), (106, 91, 83), (106, 91, 84), + (111, 87, 87), (118, 85, 89), (126, 91, 87), (135, 99, 89), + (142, 106, 89), (148, 110, 90), (154, 111, 92), (159, 109, 88), + (163, 110, 83), (165, 107, 77), (163, 100, 69), (161, 97, 66), + (157, 91, 64), (154, 89, 61), (149, 86, 59), (145, 80, 55), + (142, 78, 54), (137, 76, 56), (134, 80, 60), (130, 85, 64), + (127, 85, 65), (125, 84, 62), (121, 80, 59), (115, 75, 56), + (108, 70, 53), (100, 62, 49), (96, 56, 42), (94, 50, 37), + (92, 46, 33), (92, 45, 32), (93, 48, 34), (97, 55, 38), + (104, 62, 42), (113, 71, 51), (121, 81, 60), (128, 90, 71), + (136, 101, 78), (147, 107, 79), (156, 107, 78), (163, 109, 78), + (154, 104, 79), (146, 103, 79), (142, 99, 77), (137, 90, 70) + ), + +// 459 040222-18 +((52, 100, 5), (50, 86, 6), (49, 74, 6), (49, 62, 7), + (43, 54, 6), (37, 47, 6), (31, 47, 5), (26, 47, 5), + (9, 53, 6), (5, 50, 5), (1, 48, 5), (4, 49, 4), + (7, 51, 3), (15, 55, 2), (24, 59, 1), (27, 58, 1), + (31, 57, 1), (36, 54, 1), (32, 53, 1), (29, 52, 1), + (29, 54, 1), (30, 56, 1), (31, 56, 1), (32, 56, 1), + (36, 50, 1), (29, 46, 1), (23, 42, 1), (14, 41, 1), + (6, 40, 1), (3, 41, 0), (1, 42, 0), (0, 42, 0), + (0, 42, 0), (0, 42, 0), (0, 42, 0), (0, 42, 0), + (0, 42, 0), (0, 42, 0), (0, 41, 0), (0, 40, 0), + (7, 32, 1), (9, 31, 1), (12, 30, 1), (12, 31, 3), + (12, 33, 6), (11, 35, 7), (11, 37, 9), (9, 40, 14), + (11, 41, 18), (17, 44, 26), (19, 47, 29), (21, 50, 33), + (20, 55, 41), (20, 61, 50), (24, 61, 59), (29, 61, 69), + (50, 56, 91), (62, 52, 94), (74, 48, 98), (82, 50, 89), + (91, 52, 80), (96, 52, 81), (102, 52, 82), (109, 56, 82), + (108, 55, 83), (108, 52, 97), (110, 49, 90), (113, 47, 84), + (112, 47, 77), (111, 47, 71), (113, 59, 58), (106, 68, 48), + (70, 78, 33), (59, 76, 37), (48, 75, 42), (45, 71, 43), + (42, 67, 44), (43, 68, 43), (44, 70, 42), (42, 72, 34), + (31, 77, 24), (16, 87, 15), (11, 87, 16), (6, 88, 17), + (8, 94, 22), (10, 100, 27), (20, 114, 46), (31, 130, 65), + (67, 154, 85), (74, 159, 77), (82, 164, 70), (82, 165, 64), + (82, 167, 59), (84, 169, 56), (76, 168, 60), (75, 166, 65), + (80, 163, 71), (81, 145, 60), (73, 130, 42), (66, 115, 24), + (57, 107, 17), (48, 99, 11), (30, 82, 2), (16, 69, 0), + (7, 43, 2), (7, 36, 5), (8, 30, 9), (9, 29, 11), + (10, 29, 13), (11, 32, 16), (11, 42, 15), (16, 50, 15), + (21, 59, 14), (27, 70, 12), (27, 71, 13), (28, 72, 14), + (27, 70, 16), (23, 75, 16), (20, 80, 15), (20, 85, 13), + (19, 94, 3), (17, 92, 2), (16, 91, 1), (13, 89, 1), + (11, 87, 1), (6, 82, 1), (3, 78, 1), (2, 73, 2), + (0, 69, 1), (0, 65, 1), (0, 64, 1), (0, 64, 1), + (0, 63, 1), (0, 64, 1), (0, 62, 1), (0, 59, 1), + (0, 51, 0), (0, 46, 1), (0, 41, 2), (0, 38, 2), + (1, 36, 3), (3, 34, 6), (3, 33, 8), (3, 33, 10), + (3, 34, 11), (1, 37, 10), (1, 36, 9), (1, 35, 9), + (3, 37, 9), (3, 38, 9), (3, 41, 10), (3, 46, 11), + (2, 65, 9), (1, 70, 8), (0, 75, 7), (1, 83, 4), + (1, 88, 2), (1, 91, 1), (0, 91, 0), (1, 92, 0), + (1, 95, 0), (1, 116, 1), (2, 123, 1), (3, 130, 1), + (7, 142, 3), (7, 148, 6), (7, 147, 8), (9, 137, 12), + (8, 123, 21), (7, 120, 22), (7, 118, 23), (12, 115, 27), + (14, 113, 29), (21, 110, 31), (32, 99, 35), (41, 86, 39), + (48, 71, 40), (50, 53, 37), (49, 42, 37), (43, 34, 31), + (41, 33, 27), (44, 33, 24), (53, 38, 22), (72, 48, 20), + (114, 72, 20), (119, 79, 20), (124, 86, 20), (133, 98, 23), + (137, 107, 25), (142, 118, 26), (151, 128, 27), (165, 133, 28), + (174, 135, 40), (174, 148, 51), (172, 162, 73), (164, 171, 91), + (152, 177, 103), (136, 184, 104), (123, 185, 90), (109, 169, 85), + (91, 160, 72), (68, 152, 71), (47, 147, 72), (32, 137, 78), + (17, 138, 80), (9, 140, 66), (6, 133, 52), (8, 123, 33), + (11, 113, 18), (21, 107, 8), (39, 100, 5), (60, 100, 8), + (80, 106, 11), (98, 117, 13), (109, 124, 14), (113, 135, 14), + (114, 139, 15), (114, 141, 15), (116, 138, 18), (117, 135, 23), + (121, 135, 28), (119, 129, 31), (112, 127, 31), (97, 120, 28), + (77, 111, 24), (56, 98, 19), (37, 84, 17), (23, 74, 16), + (15, 65, 17), (16, 64, 17), (27, 67, 16), (43, 72, 15), + (62, 80, 11), (80, 84, 10), (95, 87, 11), (108, 85, 10), + (115, 88, 11), (123, 93, 11), (129, 97, 12), (138, 105, 11), + (147, 115, 11), (152, 126, 14), (156, 126, 14), (149, 127, 16), + (137, 128, 15), (119, 125, 14), (102, 123, 12), (89, 126, 8), + (78, 136, 7), (76, 139, 4), (78, 135, 5), (80, 129, 5), + (79, 121, 6), (75, 114, 6), (68, 107, 6), (59, 101, 5) + ), + +// 460 040222-19 +((195, 72, 19), (223, 63, 7), (229, 65, 7), (235, 67, 7), + (233, 73, 16), (231, 80, 26), (228, 81, 35), (225, 82, 44), + (195, 69, 75), (177, 53, 82), (160, 38, 89), (147, 30, 88), + (135, 23, 88), (127, 20, 98), (119, 18, 108), (116, 18, 117), + (113, 19, 126), (101, 19, 172), (97, 19, 187), (93, 19, 202), + (93, 18, 199), (93, 17, 197), (96, 17, 194), (99, 17, 192), + (102, 19, 183), (102, 20, 179), (103, 21, 176), (102, 23, 169), + (101, 26, 162), (96, 25, 155), (92, 25, 149), (86, 22, 135), + (79, 22, 124), (71, 17, 93), (73, 16, 75), (76, 16, 58), + (83, 17, 42), (91, 18, 26), (97, 17, 20), (104, 17, 14), + (126, 19, 4), (138, 17, 3), (151, 15, 3), (162, 15, 3), + (173, 16, 3), (175, 16, 3), (177, 17, 3), (178, 18, 3), + (173, 17, 3), (152, 16, 4), (139, 15, 4), (127, 15, 4), + (121, 14, 4), (116, 13, 4), (113, 13, 4), (111, 13, 4), + (101, 11, 3), (89, 12, 3), (77, 13, 4), (66, 12, 7), + (55, 12, 11), (53, 11, 13), (52, 11, 16), (52, 11, 22), + (52, 11, 28), (65, 9, 55), (65, 10, 71), (65, 12, 87), + (62, 12, 95), (59, 13, 104), (50, 14, 121), (41, 15, 138), + (30, 17, 164), (35, 16, 177), (41, 16, 190), (51, 17, 189), + (61, 19, 188), (67, 19, 185), (74, 20, 183), (88, 21, 176), + (99, 22, 166), (114, 24, 138), (117, 24, 140), (121, 24, 142), + (124, 23, 141), (127, 23, 140), (133, 23, 138), (140, 22, 135), + (150, 21, 122), (159, 22, 107), (168, 23, 92), (170, 24, 91), + (173, 25, 91), (177, 27, 91), (182, 29, 92), (188, 30, 93), + (193, 30, 97), (203, 31, 94), (208, 31, 78), (213, 31, 63), + (216, 31, 55), (219, 31, 47), (226, 31, 32), (235, 32, 17), + (245, 30, 5), (247, 29, 5), (249, 29, 5), (248, 29, 5), + (247, 29, 5), (247, 29, 4), (246, 29, 4), (243, 28, 4), + (238, 27, 4), (221, 24, 5), (213, 23, 6), (206, 23, 7), + (191, 22, 11), (174, 20, 16), (159, 19, 21), (144, 18, 26), + (122, 18, 32), (118, 16, 30), (115, 14, 29), (112, 13, 28), + (110, 13, 28), (104, 12, 31), (96, 13, 43), (89, 16, 61), + (82, 15, 81), (76, 22, 116), (77, 23, 123), (79, 24, 130), + (83, 25, 140), (89, 27, 144), (94, 28, 150), (100, 31, 163), + (98, 33, 197), (89, 34, 214), (80, 35, 232), (74, 34, 239), + (69, 33, 246), (60, 30, 242), (52, 26, 231), (50, 25, 213), + (53, 24, 196), (72, 22, 160), (80, 23, 151), (89, 24, 143), + (104, 25, 133), (117, 26, 119), (125, 31, 106), (134, 46, 90), + (148, 59, 77), (148, 59, 77), (148, 60, 78), (152, 62, 79), + (155, 63, 88), (158, 57, 100), (157, 53, 117), (154, 54, 129), + (153, 67, 137), (136, 68, 171), (130, 67, 175), (125, 67, 180), + (119, 65, 180), (115, 54, 180), (112, 41, 180), (112, 27, 173), + (128, 24, 140), (133, 24, 135), (139, 24, 130), (145, 23, 121), + (152, 22, 103), (159, 21, 85), (161, 19, 67), (160, 20, 50), + (157, 19, 35), (154, 17, 22), (151, 16, 18), (141, 16, 20), + (129, 15, 22), (117, 13, 23), (105, 9, 23), (89, 11, 20), + (55, 9, 18), (48, 10, 18), (42, 12, 19), (32, 16, 22), + (23, 19, 23), (16, 21, 24), (14, 18, 27), (13, 18, 28), + (11, 16, 30), (15, 17, 39), (20, 20, 53), (28, 23, 69), + (39, 27, 85), (53, 32, 100), (65, 34, 116), (75, 35, 131), + (81, 33, 136), (93, 32, 138), (104, 28, 138), (114, 27, 138), + (126, 24, 137), (139, 26, 135), (148, 27, 131), (148, 27, 130), + (140, 24, 123), (134, 22, 115), (127, 18, 103), (118, 17, 93), + (109, 14, 86), (103, 13, 85), (102, 13, 85), (95, 13, 90), + (84, 12, 99), (70, 12, 115), (58, 13, 131), (46, 14, 141), + (33, 12, 142), (24, 10, 147), (22, 9, 151), (23, 9, 156), + (24, 9, 158), (24, 9, 158), (24, 9, 160), (27, 11, 161), + (25, 11, 148), (24, 13, 131), (25, 17, 116), (26, 21, 101), + (27, 24, 87), (26, 26, 70), (24, 24, 61), (24, 24, 61), + (23, 21, 62), (21, 19, 60), (19, 19, 59), (19, 19, 58), + (21, 21, 60), (23, 25, 57), (23, 25, 57), (29, 26, 60), + (39, 24, 59), (48, 19, 57), (57, 14, 54), (65, 9, 51), + (73, 6, 50), (90, 9, 46), (101, 20, 43), (114, 35, 44), + (130, 51, 40), (147, 65, 35), (166, 67, 29), (185, 70, 24) + ), + +// 461 040222-20 +((141, 196, 173), (149, 202, 166), (150, 200, 159), (151, 199, 152), + (155, 198, 148), (160, 197, 145), (158, 190, 138), (157, 184, 131), + (153, 167, 103), (148, 156, 88), (144, 145, 74), (136, 134, 64), + (129, 124, 54), (118, 111, 49), (107, 98, 45), (101, 93, 44), + (95, 88, 43), (73, 69, 42), (67, 64, 41), (62, 60, 40), + (61, 58, 40), (61, 56, 40), (62, 56, 40), (63, 57, 40), + (63, 57, 45), (64, 59, 46), (66, 62, 48), (69, 66, 54), + (72, 70, 60), (75, 73, 64), (79, 76, 69), (87, 85, 78), + (91, 88, 84), (92, 92, 90), (89, 94, 91), (86, 96, 93), + (87, 99, 95), (89, 103, 97), (91, 105, 95), (94, 107, 93), + (109, 117, 87), (115, 123, 86), (121, 130, 85), (123, 134, 93), + (126, 138, 101), (127, 140, 104), (129, 142, 107), (137, 151, 118), + (151, 160, 121), (183, 179, 117), (196, 181, 117), (209, 184, 117), + (211, 179, 117), (213, 175, 118), (211, 172, 117), (209, 169, 117), + (197, 159, 104), (192, 153, 95), (188, 147, 87), (184, 143, 81), + (181, 139, 76), (177, 136, 75), (173, 133, 75), (164, 132, 73), + (154, 128, 75), (132, 118, 79), (128, 119, 82), (125, 120, 86), + (126, 122, 90), (127, 125, 94), (132, 134, 102), (137, 142, 111), + (144, 151, 121), (143, 146, 119), (143, 142, 117), (140, 137, 114), + (138, 132, 111), (136, 130, 111), (135, 128, 111), (132, 125, 109), + (129, 124, 110), (119, 118, 107), (115, 116, 104), (111, 115, 101), + (110, 114, 102), (109, 113, 103), (110, 113, 105), (114, 113, 110), + (122, 121, 112), (126, 122, 109), (130, 123, 107), (130, 124, 107), + (131, 126, 107), (129, 129, 107), (129, 132, 110), (130, 131, 111), + (127, 132, 110), (116, 115, 99), (104, 105, 92), (93, 96, 85), + (86, 93, 82), (79, 91, 79), (69, 83, 75), (60, 79, 72), + (51, 73, 73), (47, 66, 72), (43, 60, 72), (41, 59, 71), + (40, 58, 71), (40, 58, 70), (40, 55, 67), (42, 53, 63), + (42, 52, 62), (45, 49, 56), (46, 49, 54), (48, 50, 53), + (55, 54, 50), (66, 57, 49), (75, 59, 46), (80, 60, 46), + (91, 65, 50), (98, 73, 50), (105, 82, 51), (113, 87, 52), + (121, 92, 53), (133, 102, 51), (141, 107, 49), (145, 111, 50), + (148, 113, 52), (148, 123, 59), (151, 127, 61), (155, 131, 63), + (164, 141, 70), (171, 148, 74), (175, 152, 80), (176, 152, 83), + (168, 148, 93), (167, 148, 94), (166, 148, 95), (168, 149, 94), + (171, 150, 94), (177, 151, 96), (183, 153, 94), (191, 158, 96), + (197, 163, 99), (193, 173, 99), (191, 173, 96), (190, 173, 94), + (186, 168, 89), (179, 160, 79), (175, 153, 69), (171, 146, 62), + (164, 147, 58), (161, 147, 59), (158, 148, 60), (149, 143, 64), + (136, 133, 62), (122, 119, 59), (102, 99, 54), (88, 83, 48), + (77, 71, 40), (60, 63, 38), (57, 63, 39), (54, 64, 40), + (55, 66, 42), (55, 65, 45), (59, 64, 50), (70, 63, 51), + (94, 70, 49), (99, 76, 50), (105, 82, 51), (117, 97, 57), + (127, 107, 64), (136, 117, 75), (147, 125, 84), (158, 127, 87), + (163, 123, 86), (168, 123, 84), (167, 124, 82), (161, 123, 80), + (151, 121, 83), (141, 120, 87), (135, 118, 91), (129, 114, 92), + (128, 111, 88), (129, 111, 86), (130, 112, 85), (133, 115, 86), + (138, 120, 90), (145, 129, 95), (151, 138, 103), (157, 151, 111), + (165, 163, 122), (170, 173, 129), (177, 181, 136), (180, 182, 139), + (180, 180, 140), (176, 173, 137), (168, 167, 132), (159, 158, 129), + (146, 150, 121), (138, 144, 116), (131, 136, 113), (124, 130, 109), + (118, 122, 103), (112, 116, 97), (103, 108, 91), (92, 101, 86), + (82, 99, 87), (78, 98, 94), (79, 101, 101), (85, 104, 106), + (93, 110, 113), (97, 114, 115), (100, 116, 113), (100, 116, 112), + (100, 116, 114), (104, 120, 118), (116, 126, 121), (133, 136, 125), + (151, 148, 126), (168, 159, 123), (182, 166, 118), (190, 170, 110), + (193, 171, 102), (194, 174, 99), (196, 177, 98), (200, 182, 98), + (205, 192, 101), (210, 204, 106), (215, 213, 112), (219, 217, 112), + (220, 219, 115), (219, 217, 116), (218, 215, 117), (216, 215, 117), + (215, 219, 122), (215, 223, 130), (221, 230, 142), (225, 236, 154), + (228, 237, 165), (233, 239, 175), (233, 238, 180), (231, 237, 182), + (228, 234, 176), (228, 235, 175), (222, 232, 174), (212, 227, 175), + (198, 220, 177), (188, 211, 176), (176, 213, 186), (165, 209, 188), + (155, 208, 188), (147, 204, 186), (148, 204, 186), (141, 205, 186) + ), + +// 462 040222-21 +((46, 7, 70), (35, 5, 85), (31, 4, 92), (28, 4, 100), + (22, 3, 103), (17, 3, 107), (18, 3, 104), (19, 3, 101), + (18, 1, 89), (17, 0, 84), (16, 0, 79), (20, 0, 72), + (25, 0, 65), (35, 0, 55), (45, 1, 45), (50, 2, 40), + (56, 3, 36), (72, 3, 18), (76, 3, 13), (81, 3, 8), + (82, 3, 6), (84, 3, 5), (84, 3, 6), (84, 4, 8), + (79, 4, 16), (74, 4, 19), (69, 4, 23), (59, 3, 24), + (50, 2, 26), (45, 2, 26), (40, 2, 27), (28, 2, 29), + (19, 2, 30), (7, 0, 31), (6, 0, 29), (5, 0, 27), + (6, 0, 23), (7, 0, 20), (8, 0, 18), (10, 0, 17), + (17, 0, 11), (22, 0, 8), (27, 0, 5), (33, 0, 3), + (39, 0, 1), (41, 0, 0), (44, 0, 0), (47, 0, 0), + (49, 0, 1), (56, 4, 1), (61, 8, 4), (67, 13, 7), + (73, 16, 7), (80, 19, 8), (82, 19, 8), (84, 20, 9), + (83, 19, 8), (77, 19, 7), (72, 19, 7), (69, 19, 7), + (67, 20, 8), (67, 20, 8), (67, 20, 9), (67, 20, 12), + (64, 15, 13), (51, 7, 16), (41, 4, 21), (32, 2, 27), + (28, 1, 29), (25, 1, 32), (20, 2, 38), (17, 2, 44), + (15, 2, 51), (14, 2, 53), (14, 2, 55), (17, 3, 52), + (20, 5, 50), (23, 6, 49), (27, 7, 48), (35, 10, 46), + (47, 12, 42), (74, 25, 36), (91, 39, 39), (109, 53, 43), + (118, 61, 46), (127, 69, 49), (143, 86, 57), (161, 104, 72), + (178, 122, 94), (173, 120, 106), (169, 119, 118), (164, 117, 124), + (159, 116, 130), (149, 110, 133), (142, 109, 145), (134, 114, 153), + (134, 117, 157), (125, 110, 154), (119, 103, 149), (114, 96, 144), + (109, 88, 140), (105, 80, 137), (96, 75, 128), (98, 77, 117), + (118, 85, 94), (131, 92, 86), (144, 100, 79), (149, 101, 78), + (155, 102, 78), (158, 102, 79), (157, 105, 76), (156, 102, 73), + (150, 96, 69), (142, 81, 55), (144, 78, 53), (146, 76, 52), + (146, 69, 51), (145, 69, 53), (143, 70, 55), (136, 68, 57), + (113, 57, 50), (103, 46, 42), (94, 35, 34), (90, 30, 32), + (87, 26, 30), (85, 22, 27), (86, 18, 25), (84, 16, 22), + (79, 15, 21), (69, 11, 15), (64, 10, 13), (60, 9, 12), + (55, 7, 11), (54, 6, 10), (54, 6, 9), (55, 7, 10), + (54, 7, 10), (49, 7, 8), (45, 7, 7), (42, 7, 6), + (39, 7, 6), (33, 5, 4), (30, 5, 4), (28, 4, 5), + (27, 3, 6), (27, 2, 11), (27, 2, 12), (27, 2, 13), + (26, 1, 13), (26, 1, 13), (27, 1, 11), (28, 1, 10), + (30, 1, 11), (30, 1, 11), (31, 2, 12), (32, 2, 14), + (33, 2, 15), (33, 2, 15), (33, 2, 13), (33, 2, 12), + (33, 2, 10), (31, 2, 8), (30, 2, 8), (29, 2, 8), + (27, 2, 8), (24, 2, 9), (21, 2, 10), (18, 1, 10), + (14, 1, 11), (14, 1, 11), (14, 1, 11), (15, 1, 11), + (17, 1, 12), (19, 1, 15), (21, 1, 19), (24, 2, 23), + (26, 1, 28), (26, 1, 33), (29, 1, 36), (32, 2, 37), + (33, 2, 40), (34, 2, 40), (36, 4, 40), (40, 4, 40), + (45, 8, 43), (46, 9, 43), (47, 10, 44), (48, 15, 47), + (50, 18, 49), (52, 20, 48), (55, 21, 45), (55, 20, 43), + (58, 20, 38), (59, 19, 35), (63, 22, 33), (68, 26, 35), + (74, 32, 37), (83, 37, 36), (90, 40, 35), (95, 40, 30), + (96, 37, 27), (95, 38, 25), (94, 36, 26), (91, 41, 31), + (95, 48, 35), (100, 59, 41), (108, 69, 45), (118, 76, 50), + (126, 85, 52), (134, 86, 56), (139, 89, 62), (146, 91, 64), + (148, 94, 67), (153, 98, 66), (159, 102, 64), (166, 106, 61), + (170, 108, 57), (174, 110, 57), (179, 109, 56), (178, 105, 57), + (175, 101, 57), (169, 100, 59), (162, 101, 62), (155, 98, 62), + (146, 97, 62), (134, 91, 67), (122, 83, 71), (109, 74, 74), + (99, 66, 78), (87, 62, 82), (77, 54, 86), (70, 51, 85), + (61, 46, 91), (53, 40, 95), (42, 30, 101), (34, 19, 109), + (25, 11, 117), (17, 5, 126), (12, 2, 131), (7, 1, 135), + (6, 1, 137), (8, 1, 142), (11, 2, 143), (14, 2, 144), + (18, 2, 142), (22, 2, 139), (25, 2, 132), (30, 5, 121), + (37, 5, 111), (45, 6, 98), (44, 7, 90), (43, 7, 85), + (47, 8, 81), (47, 6, 75), (43, 8, 73), (40, 6, 73) + ), + +// 463 040222-22 +((87, 97, 127), (91, 103, 136), (91, 102, 134), (92, 102, 133), + (93, 102, 131), (94, 102, 130), (94, 102, 129), (95, 102, 129), + (98, 104, 131), (102, 108, 135), (106, 112, 139), (110, 117, 145), + (114, 122, 152), (113, 121, 151), (113, 121, 151), (111, 119, 149), + (109, 117, 147), (99, 106, 135), (94, 101, 131), (90, 96, 127), + (91, 96, 125), (92, 96, 124), (94, 98, 125), (96, 100, 126), + (111, 117, 144), (120, 127, 153), (129, 137, 163), (136, 145, 170), + (143, 153, 178), (145, 156, 180), (148, 159, 182), (152, 163, 186), + (156, 167, 189), (165, 174, 191), (170, 179, 194), (175, 184, 197), + (180, 188, 199), (185, 192, 202), (186, 192, 202), (187, 193, 202), + (184, 188, 192), (177, 180, 183), (170, 173, 175), (160, 163, 164), + (150, 153, 153), (145, 147, 147), (140, 142, 142), (129, 131, 131), + (119, 122, 122), (99, 100, 101), (88, 89, 90), (77, 78, 80), + (66, 67, 69), (56, 56, 58), (50, 50, 53), (45, 45, 48), + (27, 26, 29), (20, 20, 23), (14, 14, 17), (12, 13, 16), + (10, 12, 15), (10, 12, 15), (10, 12, 16), (12, 13, 17), + (13, 15, 20), (14, 16, 22), (14, 16, 22), (15, 17, 23), + (15, 16, 23), (15, 16, 23), (14, 16, 22), (14, 15, 21), + (14, 15, 22), (14, 15, 22), (15, 16, 23), (15, 16, 23), + (15, 17, 24), (15, 17, 24), (16, 17, 24), (16, 18, 25), + (17, 18, 26), (18, 19, 26), (19, 19, 26), (20, 19, 26), + (20, 19, 26), (21, 20, 26), (23, 22, 27), (25, 23, 28), + (33, 30, 34), (40, 36, 40), (48, 43, 47), (52, 47, 52), + (56, 52, 57), (65, 62, 67), (75, 73, 77), (86, 83, 88), + (97, 94, 99), (120, 117, 121), (129, 126, 129), (138, 136, 138), + (142, 140, 141), (146, 144, 145), (154, 152, 153), (162, 161, 161), + (175, 176, 177), (181, 183, 184), (188, 191, 192), (190, 194, 196), + (193, 198, 200), (198, 204, 208), (202, 209, 213), (202, 211, 216), + (198, 208, 216), (184, 195, 205), (179, 190, 201), (175, 186, 197), + (166, 176, 187), (155, 166, 177), (144, 154, 166), (132, 143, 156), + (111, 120, 135), (102, 111, 125), (93, 102, 116), (88, 97, 111), + (84, 92, 106), (74, 82, 96), (64, 72, 86), (54, 61, 75), + (44, 51, 64), (27, 32, 44), (23, 27, 39), (19, 23, 35), + (12, 16, 26), (8, 10, 18), (5, 7, 14), (3, 4, 10), + (1, 2, 7), (1, 2, 6), (1, 2, 5), (1, 2, 4), + (1, 2, 4), (1, 2, 4), (1, 2, 5), (2, 4, 6), + (4, 6, 8), (14, 14, 18), (17, 17, 22), (20, 21, 26), + (28, 29, 36), (36, 38, 46), (44, 47, 57), (52, 56, 67), + (68, 74, 86), (71, 77, 90), (74, 81, 94), (78, 86, 102), + (81, 90, 108), (84, 92, 111), (85, 93, 115), (86, 95, 119), + (87, 96, 122), (90, 99, 128), (90, 100, 129), (91, 101, 130), + (94, 103, 133), (97, 106, 134), (101, 109, 137), (104, 113, 140), + (107, 115, 140), (107, 115, 140), (108, 115, 141), (109, 117, 141), + (110, 117, 141), (111, 118, 141), (112, 119, 141), (113, 120, 142), + (115, 122, 142), (119, 125, 143), (126, 131, 147), (131, 137, 152), + (139, 144, 158), (146, 151, 164), (153, 159, 172), (161, 167, 180), + (174, 182, 194), (176, 185, 197), (179, 188, 200), (182, 192, 205), + (184, 195, 209), (186, 197, 211), (185, 198, 212), (184, 196, 212), + (180, 192, 210), (173, 186, 205), (165, 178, 199), (156, 170, 191), + (147, 160, 182), (138, 150, 172), (129, 141, 162), (119, 131, 153), + (111, 122, 144), (105, 116, 136), (101, 111, 129), (98, 107, 125), + (97, 104, 121), (95, 101, 119), (93, 100, 119), (90, 98, 118), + (88, 95, 115), (86, 92, 111), (82, 87, 106), (78, 81, 99), + (73, 75, 93), (70, 71, 87), (68, 69, 83), (69, 68, 81), + (70, 68, 79), (72, 70, 80), (74, 71, 83), (75, 74, 85), + (77, 76, 87), (78, 77, 88), (78, 77, 88), (76, 75, 86), + (72, 72, 83), (67, 67, 79), (61, 62, 74), (56, 56, 68), + (53, 52, 62), (49, 48, 57), (47, 45, 55), (45, 44, 53), + (46, 45, 54), (49, 48, 57), (50, 49, 58), (50, 49, 58), + (51, 49, 57), (51, 49, 57), (51, 49, 57), (51, 49, 59), + (50, 49, 60), (51, 50, 62), (50, 50, 62), (52, 51, 63), + (55, 54, 67), (58, 58, 72), (60, 59, 73), (62, 61, 76), + (64, 63, 79), (67, 66, 83), (69, 71, 89), (72, 75, 96), + (75, 79, 103), (77, 83, 109), (78, 86, 114), (82, 90, 118) + ), + +// 464 040222-23 +((114, 119, 136), (103, 112, 130), (98, 108, 125), (93, 104, 121), + (91, 100, 116), (89, 96, 111), (88, 95, 109), (87, 94, 107), + (90, 97, 108), (95, 101, 113), (100, 106, 118), (110, 114, 126), + (120, 123, 134), (131, 133, 144), (143, 144, 155), (148, 149, 159), + (154, 155, 164), (173, 175, 180), (178, 181, 187), (184, 187, 194), + (184, 189, 197), (185, 191, 200), (184, 190, 201), (183, 190, 202), + (175, 182, 195), (167, 176, 187), (160, 170, 180), (153, 162, 170), + (147, 154, 160), (143, 150, 155), (140, 146, 151), (134, 138, 142), + (130, 131, 134), (123, 121, 126), (119, 118, 123), (115, 116, 120), + (113, 115, 119), (111, 114, 119), (111, 114, 119), (111, 115, 120), + (117, 119, 125), (119, 121, 128), (122, 124, 132), (121, 124, 133), + (120, 124, 135), (118, 123, 134), (117, 122, 133), (114, 120, 132), + (111, 118, 129), (111, 113, 124), (114, 114, 125), (117, 115, 126), + (119, 116, 126), (121, 117, 127), (121, 117, 126), (121, 117, 125), + (116, 110, 115), (114, 107, 110), (113, 104, 106), (112, 102, 104), + (112, 101, 103), (110, 101, 103), (109, 101, 104), (106, 99, 105), + (100, 96, 104), (85, 82, 89), (77, 75, 82), (69, 69, 76), + (67, 67, 74), (65, 66, 72), (62, 66, 74), (63, 70, 80), + (73, 83, 99), (81, 92, 109), (89, 101, 120), (98, 112, 131), + (108, 124, 142), (113, 130, 147), (118, 136, 152), (126, 147, 164), + (133, 158, 176), (150, 175, 195), (157, 181, 202), (165, 187, 210), + (167, 190, 213), (170, 193, 217), (176, 198, 222), (179, 203, 226), + (182, 205, 225), (183, 203, 223), (184, 201, 221), (184, 199, 219), + (185, 197, 218), (186, 197, 217), (189, 199, 219), (193, 203, 222), + (198, 207, 225), (209, 215, 230), (214, 218, 230), (220, 221, 230), + (222, 221, 229), (224, 221, 229), (226, 222, 229), (227, 224, 231), + (227, 225, 233), (224, 223, 231), (222, 222, 230), (220, 220, 228), + (219, 219, 227), (215, 214, 224), (210, 209, 219), (204, 205, 214), + (198, 200, 210), (182, 188, 201), (177, 184, 198), (172, 180, 195), + (162, 173, 188), (153, 164, 182), (143, 155, 174), (134, 147, 165), + (118, 133, 151), (109, 126, 145), (101, 120, 140), (97, 117, 136), + (93, 115, 132), (85, 106, 125), (78, 98, 117), (72, 89, 106), + (68, 82, 98), (68, 77, 89), (69, 77, 88), (70, 77, 88), + (74, 80, 89), (78, 83, 92), (82, 86, 97), (84, 88, 99), + (88, 95, 104), (90, 97, 107), (93, 99, 110), (94, 100, 111), + (95, 101, 112), (98, 103, 115), (101, 106, 120), (102, 108, 122), + (103, 109, 126), (104, 117, 136), (105, 118, 139), (107, 120, 142), + (108, 123, 146), (110, 125, 148), (113, 128, 151), (118, 130, 152), + (133, 137, 154), (136, 140, 156), (140, 143, 158), (151, 153, 166), + (162, 163, 176), (171, 173, 185), (180, 182, 194), (186, 190, 203), + (192, 196, 207), (200, 200, 211), (201, 200, 210), (202, 200, 210), + (205, 199, 211), (205, 200, 210), (205, 200, 210), (201, 199, 210), + (193, 193, 208), (191, 191, 206), (189, 190, 205), (184, 185, 201), + (181, 181, 198), (180, 177, 195), (178, 174, 193), (176, 173, 190), + (173, 171, 188), (170, 168, 183), (167, 166, 180), (162, 162, 176), + (158, 160, 174), (155, 159, 173), (152, 158, 175), (150, 158, 178), + (144, 158, 180), (142, 157, 179), (140, 156, 178), (133, 149, 172), + (125, 143, 166), (118, 137, 159), (111, 132, 154), (107, 128, 152), + (106, 127, 153), (107, 129, 155), (111, 132, 158), (115, 135, 160), + (120, 136, 160), (124, 138, 159), (128, 137, 155), (129, 136, 152), + (131, 136, 148), (135, 135, 145), (139, 135, 144), (142, 138, 144), + (145, 140, 147), (146, 144, 152), (149, 147, 157), (151, 151, 163), + (149, 156, 166), (153, 160, 171), (156, 164, 176), (161, 169, 179), + (165, 173, 183), (167, 179, 187), (173, 185, 195), (180, 191, 204), + (183, 198, 210), (187, 204, 216), (189, 208, 223), (194, 211, 226), + (198, 212, 227), (199, 212, 225), (199, 211, 222), (199, 208, 219), + (194, 201, 212), (185, 193, 203), (174, 183, 195), (162, 172, 186), + (152, 161, 177), (141, 150, 169), (130, 142, 160), (124, 135, 154), + (119, 129, 150), (115, 128, 148), (111, 127, 146), (105, 124, 144), + (101, 122, 142), (97, 119, 141), (94, 116, 138), (93, 114, 134), + (95, 113, 132), (100, 115, 131), (107, 120, 135), (113, 124, 138), + (121, 130, 143), (127, 136, 149), (131, 139, 152), (131, 139, 154), + (132, 138, 153), (131, 134, 147), (130, 131, 143), (129, 127, 139), + (127, 126, 137), (126, 124, 136), (124, 123, 135), (118, 120, 134) + ), + +// 465 040222-24 +((38, 7, 7), (42, 8, 7), (45, 7, 6), (48, 6, 6), + (49, 6, 6), (50, 6, 7), (48, 5, 6), (46, 4, 6), + (41, 1, 3), (40, 2, 4), (39, 3, 6), (41, 5, 12), + (43, 7, 19), (48, 11, 26), (53, 16, 34), (55, 16, 35), + (57, 16, 37), (57, 18, 38), (56, 17, 37), (55, 16, 36), + (53, 17, 38), (52, 19, 41), (52, 18, 40), (53, 18, 39), + (50, 19, 33), (47, 15, 25), (45, 12, 18), (40, 9, 13), + (35, 6, 9), (34, 4, 8), (33, 3, 7), (33, 5, 9), + (36, 13, 18), (58, 31, 48), (72, 42, 67), (87, 54, 86), + (100, 62, 102), (113, 70, 119), (120, 79, 124), (128, 88, 130), + (150, 115, 138), (157, 117, 136), (165, 120, 135), (162, 112, 129), + (160, 104, 124), (157, 101, 119), (154, 98, 115), (144, 93, 112), + (131, 90, 94), (107, 70, 55), (90, 54, 36), (73, 38, 17), + (56, 23, 10), (39, 8, 4), (32, 5, 4), (26, 2, 5), + (14, 7, 9), (15, 14, 15), (17, 21, 22), (23, 31, 32), + (30, 41, 42), (32, 44, 45), (35, 47, 49), (38, 52, 52), + (39, 54, 55), (54, 53, 57), (65, 57, 58), (77, 61, 59), + (84, 64, 59), (92, 67, 60), (103, 70, 57), (104, 65, 52), + (105, 48, 38), (101, 37, 28), (97, 26, 18), (99, 23, 12), + (101, 20, 7), (101, 18, 5), (101, 17, 3), (100, 17, 0), + (99, 15, 1), (97, 8, 0), (100, 9, 0), (103, 11, 0), + (105, 13, 0), (108, 16, 0), (118, 23, 1), (127, 28, 4), + (137, 29, 5), (139, 29, 5), (141, 29, 6), (139, 28, 6), + (138, 27, 6), (137, 30, 5), (135, 32, 7), (128, 34, 9), + (120, 29, 9), (99, 20, 9), (88, 14, 7), (78, 8, 6), + (76, 6, 5), (74, 4, 5), (72, 4, 4), (73, 3, 4), + (80, 3, 7), (82, 2, 6), (85, 1, 6), (85, 0, 5), + (85, 0, 5), (83, 0, 4), (81, 0, 3), (78, 0, 3), + (74, 0, 5), (65, 0, 5), (62, 0, 5), (59, 1, 5), + (52, 1, 4), (45, 1, 3), (38, 0, 1), (33, 0, 1), + (29, 0, 0), (30, 0, 0), (32, 0, 0), (33, 0, 0), + (35, 0, 0), (37, 0, 0), (39, 0, 0), (41, 0, 0), + (41, 0, 0), (39, 0, 0), (38, 0, 0), (37, 0, 0), + (35, 0, 0), (31, 0, 0), (27, 0, 0), (23, 1, 0), + (12, 2, 0), (8, 2, 0), (4, 3, 0), (3, 3, 0), + (2, 3, 0), (1, 3, 0), (0, 2, 0), (0, 2, 0), + (1, 2, 0), (5, 3, 1), (7, 3, 1), (9, 4, 1), + (13, 5, 2), (18, 5, 5), (23, 6, 9), (27, 6, 12), + (38, 5, 16), (39, 5, 16), (41, 5, 16), (45, 5, 15), + (46, 5, 15), (46, 5, 16), (45, 7, 17), (41, 7, 20), + (39, 7, 22), (33, 8, 19), (31, 9, 19), (30, 10, 19), + (27, 13, 17), (21, 18, 17), (14, 26, 20), (10, 32, 25), + (7, 37, 27), (8, 37, 27), (9, 37, 28), (12, 35, 26), + (15, 32, 25), (17, 32, 23), (19, 33, 24), (22, 34, 25), + (26, 33, 23), (31, 30, 21), (40, 24, 17), (49, 17, 13), + (59, 9, 8), (66, 5, 5), (76, 6, 3), (91, 10, 9), + (123, 31, 15), (131, 40, 22), (140, 50, 29), (158, 69, 43), + (160, 82, 60), (156, 92, 67), (151, 97, 78), (145, 99, 84), + (138, 103, 81), (134, 115, 92), (145, 133, 107), (149, 146, 129), + (144, 150, 140), (138, 145, 149), (128, 131, 149), (114, 109, 134), + (97, 86, 116), (87, 75, 99), (87, 71, 92), (84, 66, 86), + (85, 62, 86), (83, 52, 80), (81, 40, 69), (74, 23, 53), + (62, 12, 36), (51, 6, 24), (40, 3, 13), (30, 3, 9), + (22, 3, 5), (16, 3, 2), (13, 2, 1), (11, 1, 1), + (10, 1, 0), (9, 0, 0), (9, 0, 0), (10, 0, 0), + (10, 0, 0), (12, 0, 1), (14, 1, 2), (17, 1, 2), + (19, 0, 2), (21, 0, 2), (21, 0, 2), (22, 0, 2), + (22, 0, 2), (22, 0, 2), (22, 0, 3), (22, 0, 3), + (22, 0, 2), (21, 0, 2), (21, 0, 1), (20, 0, 1), + (19, 0, 0), (18, 0, 0), (17, 0, 0), (16, 1, 1), + (15, 4, 4), (14, 9, 9), (16, 13, 13), (18, 14, 14), + (19, 13, 14), (20, 13, 15), (19, 12, 13), (18, 12, 11), + (16, 13, 12), (17, 16, 15), (23, 19, 18), (27, 20, 19), + (33, 19, 20), (38, 16, 18), (40, 12, 14), (41, 9, 10) + ), + +// 466 040222-25 +((134, 105, 81), (107, 78, 57), (92, 64, 45), (77, 50, 33), + (68, 43, 28), (59, 37, 24), (56, 35, 22), (53, 34, 21), + (41, 26, 15), (38, 22, 12), (36, 18, 10), (39, 21, 13), + (43, 24, 17), (51, 31, 23), (60, 38, 30), (65, 41, 33), + (70, 45, 36), (90, 60, 45), (99, 67, 49), (108, 75, 54), + (114, 81, 58), (120, 87, 63), (121, 88, 63), (123, 89, 63), + (121, 88, 57), (118, 87, 54), (116, 86, 51), (115, 87, 54), + (115, 89, 57), (116, 90, 59), (117, 92, 62), (121, 97, 67), + (127, 103, 71), (139, 118, 80), (145, 125, 87), (151, 132, 94), + (155, 134, 97), (159, 136, 101), (158, 135, 101), (158, 134, 102), + (145, 124, 91), (134, 115, 83), (124, 107, 75), (116, 96, 68), + (109, 85, 62), (105, 81, 59), (101, 77, 57), (97, 73, 53), + (96, 74, 53), (106, 86, 57), (115, 93, 63), (125, 101, 69), + (132, 106, 76), (140, 112, 83), (142, 115, 85), (144, 118, 87), + (146, 119, 88), (142, 114, 84), (139, 109, 80), (131, 100, 76), + (124, 91, 72), (119, 86, 68), (115, 82, 65), (107, 74, 59), + (105, 67, 55), (105, 68, 55), (113, 78, 64), (121, 88, 74), + (125, 94, 79), (130, 101, 84), (142, 114, 97), (152, 126, 108), + (171, 145, 121), (178, 154, 127), (185, 164, 133), (191, 169, 135), + (197, 175, 137), (197, 175, 137), (197, 176, 138), (197, 173, 133), + (194, 170, 128), (183, 162, 115), (179, 158, 109), (176, 154, 103), + (174, 152, 101), (173, 150, 99), (169, 143, 95), (164, 137, 92), + (154, 128, 87), (154, 129, 88), (155, 131, 89), (157, 132, 91), + (160, 134, 93), (165, 139, 97), (170, 145, 103), (174, 150, 110), + (177, 155, 116), (191, 173, 130), (197, 179, 134), (204, 186, 138), + (206, 188, 139), (209, 191, 140), (209, 192, 141), (208, 191, 141), + (205, 186, 142), (200, 180, 139), (196, 175, 137), (192, 171, 135), + (189, 168, 133), (183, 161, 125), (178, 153, 117), (172, 147, 112), + (165, 138, 107), (150, 121, 98), (146, 117, 94), (142, 114, 90), + (137, 106, 82), (133, 102, 74), (131, 98, 70), (131, 98, 69), + (132, 102, 76), (135, 105, 80), (138, 109, 84), (138, 110, 85), + (139, 112, 87), (141, 113, 86), (141, 113, 85), (137, 109, 84), + (133, 106, 83), (114, 94, 72), (108, 89, 68), (102, 85, 64), + (91, 75, 53), (78, 62, 45), (67, 51, 36), (55, 39, 28), + (36, 27, 17), (31, 25, 14), (27, 23, 11), (27, 22, 11), + (27, 22, 12), (26, 19, 12), (25, 17, 11), (25, 15, 8), + (24, 15, 6), (25, 15, 6), (25, 14, 6), (25, 14, 6), + (23, 12, 7), (22, 9, 6), (19, 7, 5), (18, 6, 2), + (15, 5, 1), (14, 5, 1), (13, 5, 1), (13, 5, 1), + (12, 7, 1), (15, 8, 1), (19, 9, 1), (22, 13, 2), + (28, 16, 5), (39, 24, 10), (42, 25, 11), (45, 27, 12), + (49, 29, 14), (51, 30, 14), (53, 31, 15), (53, 31, 16), + (53, 29, 15), (52, 28, 16), (51, 28, 17), (47, 25, 16), + (45, 23, 15), (43, 22, 16), (44, 22, 16), (47, 22, 16), + (51, 23, 19), (53, 26, 21), (54, 26, 23), (55, 28, 25), + (57, 29, 26), (57, 28, 26), (59, 29, 25), (58, 30, 24), + (55, 30, 20), (55, 30, 20), (56, 31, 20), (56, 33, 20), + (60, 35, 21), (63, 41, 22), (69, 46, 23), (77, 53, 26), + (87, 62, 32), (97, 72, 38), (107, 79, 46), (114, 86, 51), + (118, 88, 53), (119, 89, 53), (120, 88, 55), (121, 89, 56), + (120, 89, 59), (120, 91, 62), (122, 93, 65), (125, 97, 70), + (132, 102, 77), (141, 112, 87), (153, 123, 97), (164, 137, 108), + (174, 148, 116), (184, 160, 126), (194, 171, 133), (205, 181, 142), + (214, 190, 151), (221, 199, 162), (226, 204, 168), (228, 208, 176), + (230, 213, 179), (231, 215, 180), (228, 211, 176), (221, 206, 173), + (212, 197, 165), (198, 182, 159), (187, 171, 150), (178, 160, 140), + (169, 150, 127), (159, 139, 114), (148, 126, 100), (133, 109, 86), + (119, 92, 72), (107, 78, 62), (100, 69, 52), (96, 64, 45), + (96, 64, 44), (100, 67, 46), (106, 74, 49), (115, 83, 57), + (124, 93, 65), (134, 103, 72), (145, 114, 80), (155, 126, 91), + (166, 138, 100), (178, 152, 110), (188, 164, 119), (197, 174, 126), + (202, 180, 130), (205, 183, 134), (206, 185, 139), (206, 186, 141), + (206, 185, 142), (204, 183, 140), (197, 176, 133), (184, 160, 120), + (171, 144, 109), (158, 131, 99), (148, 118, 91), (138, 109, 86) + ), + +// 467 040222-26 +((78, 46, 94), (49, 30, 72), (25, 15, 54), (2, 1, 37), + (2, 1, 38), (3, 1, 40), (2, 1, 40), (2, 1, 41), + (3, 2, 43), (3, 1, 44), (4, 1, 45), (3, 1, 45), + (2, 1, 46), (2, 1, 46), (2, 1, 46), (2, 1, 46), + (2, 2, 46), (4, 2, 49), (10, 4, 53), (16, 7, 57), + (28, 15, 65), (41, 23, 73), (49, 27, 78), (57, 32, 84), + (91, 52, 109), (109, 64, 120), (127, 77, 132), (146, 89, 145), + (165, 101, 158), (172, 106, 163), (179, 111, 169), (187, 117, 174), + (188, 118, 175), (177, 110, 166), (163, 102, 157), (150, 95, 149), + (131, 83, 136), (113, 71, 124), (103, 64, 117), (94, 58, 111), + (61, 38, 89), (55, 34, 86), (50, 31, 84), (59, 35, 91), + (69, 40, 98), (75, 43, 102), (82, 47, 106), (95, 56, 115), + (104, 62, 121), (118, 69, 129), (115, 66, 126), (112, 63, 123), + (99, 56, 114), (87, 49, 106), (79, 45, 100), (72, 41, 95), + (41, 22, 73), (28, 15, 64), (16, 9, 56), (11, 6, 52), + (7, 3, 49), (7, 2, 48), (7, 2, 48), (10, 3, 51), + (16, 6, 55), (41, 21, 73), (61, 32, 88), (82, 44, 103), + (94, 51, 111), (106, 59, 120), (130, 74, 137), (156, 90, 154), + (195, 116, 182), (204, 121, 188), (214, 127, 194), (207, 123, 189), + (200, 120, 184), (191, 115, 178), (183, 110, 172), (160, 97, 157), + (137, 80, 141), (88, 51, 106), (67, 39, 90), (47, 28, 74), + (39, 23, 68), (31, 18, 63), (21, 12, 57), (15, 8, 53), + (13, 7, 51), (16, 8, 53), (19, 9, 56), (20, 10, 57), + (21, 11, 59), (23, 11, 63), (23, 11, 65), (23, 11, 65), + (22, 10, 65), (18, 9, 62), (15, 8, 59), (12, 7, 57), + (10, 6, 55), (9, 5, 54), (6, 4, 50), (4, 4, 48), + (2, 3, 44), (1, 2, 43), (0, 2, 42), (0, 2, 41), + (0, 2, 41), (0, 2, 41), (0, 2, 41), (0, 2, 42), + (0, 2, 42), (1, 2, 44), (1, 2, 44), (2, 2, 45), + (3, 2, 47), (4, 2, 48), (5, 3, 49), (7, 3, 50), + (12, 6, 53), (15, 8, 57), (19, 10, 61), (22, 11, 63), + (25, 12, 65), (30, 15, 69), (34, 17, 72), (39, 20, 75), + (46, 23, 80), (59, 30, 90), (62, 32, 92), (66, 34, 95), + (72, 37, 98), (81, 42, 104), (89, 47, 110), (94, 51, 113), + (93, 52, 111), (88, 49, 107), (84, 47, 104), (80, 45, 101), + (77, 43, 99), (70, 39, 90), (61, 35, 81), (50, 31, 71), + (42, 25, 65), (32, 19, 60), (33, 18, 60), (34, 18, 61), + (40, 24, 63), (48, 29, 70), (60, 36, 81), (76, 47, 94), + (116, 72, 126), (127, 80, 134), (138, 88, 142), (160, 102, 159), + (181, 118, 175), (199, 130, 188), (215, 142, 201), (230, 151, 211), + (238, 155, 217), (243, 158, 220), (241, 156, 218), (239, 155, 217), + (238, 151, 215), (233, 146, 210), (225, 141, 203), (217, 135, 196), + (206, 127, 188), (204, 125, 187), (203, 123, 186), (195, 119, 181), + (184, 113, 173), (170, 105, 163), (155, 96, 153), (140, 85, 145), + (124, 74, 134), (106, 62, 121), (85, 51, 109), (67, 40, 96), + (50, 30, 85), (36, 20, 75), (26, 13, 66), (17, 8, 58), + (8, 5, 49), (8, 5, 47), (9, 5, 46), (9, 5, 44), + (9, 6, 42), (8, 5, 42), (7, 5, 41), (7, 6, 41), + (7, 6, 41), (6, 6, 41), (6, 6, 42), (6, 6, 42), + (7, 7, 41), (11, 9, 41), (14, 11, 42), (15, 12, 43), + (17, 13, 44), (16, 12, 44), (17, 12, 44), (17, 12, 45), + (15, 11, 46), (13, 10, 47), (9, 8, 47), (6, 5, 47), + (3, 3, 47), (1, 2, 47), (0, 1, 46), (0, 1, 45), + (0, 1, 44), (0, 1, 43), (0, 1, 42), (0, 1, 42), + (0, 1, 41), (1, 1, 41), (2, 2, 40), (5, 4, 39), + (9, 6, 39), (13, 9, 39), (17, 10, 43), (22, 13, 48), + (27, 16, 53), (34, 19, 57), (41, 24, 62), (47, 28, 68), + (49, 28, 72), (50, 28, 77), (48, 26, 78), (44, 23, 78), + (42, 23, 76), (36, 20, 70), (31, 17, 65), (25, 13, 58), + (17, 9, 51), (12, 6, 47), (7, 3, 41), (5, 2, 36), + (3, 1, 33), (2, 1, 31), (1, 1, 31), (2, 0, 32), + (3, 1, 35), (5, 1, 38), (9, 4, 43), (17, 9, 51), + (28, 15, 61), (44, 25, 73), (67, 39, 91), (85, 49, 105), + (82, 47, 101), (76, 43, 96), (65, 37, 86), (65, 38, 84) + ), + +// 468 040222-27 +((183, 145, 135), (187, 128, 111), (180, 117, 99), (173, 106, 88), + (160, 93, 76), (147, 81, 64), (141, 75, 59), (135, 69, 55), + (95, 46, 39), (74, 38, 33), (54, 30, 27), (44, 25, 21), + (35, 20, 16), (30, 17, 14), (25, 14, 12), (24, 13, 11), + (23, 13, 10), (26, 17, 14), (37, 22, 20), (49, 28, 26), + (71, 44, 42), (93, 60, 59), (104, 71, 69), (115, 82, 79), + (159, 125, 119), (179, 144, 138), (199, 164, 158), (201, 171, 163), + (204, 178, 168), (200, 176, 166), (197, 174, 165), (188, 161, 154), + (174, 143, 143), (137, 115, 115), (123, 101, 100), (110, 87, 86), + (105, 83, 85), (101, 79, 85), (100, 79, 85), (99, 79, 86), + (117, 87, 92), (133, 101, 105), (150, 115, 119), (163, 130, 132), + (177, 146, 146), (184, 154, 154), (192, 162, 162), (207, 180, 176), + (217, 193, 185), (219, 199, 188), (213, 190, 179), (207, 181, 171), + (187, 162, 152), (168, 144, 134), (157, 132, 122), (147, 120, 111), + (101, 76, 70), (79, 57, 53), (57, 38, 36), (43, 27, 26), + (29, 17, 16), (25, 14, 13), (22, 12, 11), (19, 11, 10), + (22, 14, 14), (46, 36, 36), (64, 51, 53), (82, 67, 70), + (92, 75, 78), (103, 83, 86), (125, 99, 103), (143, 116, 117), + (157, 125, 131), (152, 122, 129), (148, 120, 127), (145, 116, 121), + (142, 113, 115), (139, 110, 113), (136, 107, 112), (135, 105, 108), + (137, 105, 104), (151, 109, 99), (155, 108, 96), (160, 107, 93), + (160, 108, 93), (161, 110, 94), (163, 112, 97), (162, 112, 99), + (151, 110, 95), (143, 105, 94), (136, 101, 93), (131, 98, 91), + (126, 95, 89), (113, 89, 82), (98, 79, 74), (88, 69, 65), + (78, 58, 59), (65, 50, 50), (63, 47, 46), (62, 44, 42), + (61, 42, 40), (61, 40, 38), (57, 38, 36), (54, 35, 31), + (43, 25, 20), (36, 21, 15), (29, 17, 11), (26, 14, 10), + (23, 12, 9), (17, 8, 6), (12, 6, 4), (7, 4, 2), + (4, 2, 1), (1, 0, 0), (0, 0, 0), (0, 0, 0), + (2, 0, 1), (4, 1, 1), (7, 3, 4), (10, 6, 8), + (21, 11, 13), (24, 15, 17), (28, 19, 21), (28, 19, 21), + (28, 20, 21), (30, 20, 22), (29, 19, 20), (29, 20, 21), + (27, 19, 19), (29, 17, 16), (30, 18, 17), (32, 19, 18), + (36, 22, 20), (43, 27, 25), (52, 33, 31), (60, 42, 38), + (81, 57, 53), (89, 64, 61), (98, 72, 69), (102, 75, 73), + (106, 78, 78), (115, 85, 85), (129, 94, 97), (141, 108, 108), + (154, 122, 123), (183, 155, 155), (190, 165, 163), (198, 176, 172), + (215, 194, 190), (224, 208, 202), (230, 218, 211), (232, 223, 214), + (232, 220, 212), (231, 217, 209), (230, 214, 206), (225, 203, 198), + (221, 195, 190), (213, 185, 179), (206, 171, 165), (192, 154, 151), + (177, 138, 138), (154, 116, 108), (149, 109, 102), (144, 103, 96), + (137, 91, 89), (136, 89, 86), (141, 91, 85), (148, 100, 90), + (167, 116, 108), (171, 121, 112), (176, 126, 116), (184, 138, 125), + (189, 148, 131), (198, 156, 137), (202, 162, 144), (206, 164, 150), + (207, 169, 156), (216, 177, 163), (221, 187, 171), (225, 192, 180), + (223, 194, 184), (224, 193, 185), (220, 192, 183), (216, 188, 181), + (196, 165, 162), (188, 156, 153), (181, 148, 145), (165, 133, 131), + (151, 118, 121), (136, 103, 110), (120, 90, 96), (105, 81, 84), + (96, 74, 77), (89, 67, 73), (87, 63, 67), (90, 60, 60), + (101, 61, 56), (116, 65, 57), (124, 69, 59), (123, 68, 58), + (117, 62, 53), (117, 58, 47), (111, 54, 44), (99, 50, 43), + (77, 42, 39), (62, 35, 34), (54, 30, 33), (53, 31, 36), + (53, 32, 38), (52, 32, 37), (50, 31, 38), (49, 33, 42), + (50, 35, 44), (49, 34, 40), (46, 31, 35), (44, 29, 33), + (45, 32, 34), (49, 35, 37), (57, 40, 42), (66, 44, 46), + (74, 51, 54), (81, 59, 63), (87, 66, 73), (95, 73, 79), + (97, 76, 85), (98, 78, 86), (95, 78, 86), (94, 78, 83), + (91, 78, 79), (89, 73, 73), (87, 68, 68), (87, 66, 63), + (85, 67, 60), (87, 67, 57), (88, 65, 57), (89, 62, 57), + (87, 61, 55), (87, 60, 53), (89, 59, 52), (92, 58, 54), + (95, 59, 56), (97, 62, 57), (100, 65, 57), (105, 69, 62), + (115, 75, 67), (122, 83, 75), (126, 85, 78), (127, 88, 85), + (130, 91, 90), (137, 98, 100), (147, 105, 111), (156, 115, 121), + (163, 126, 129), (164, 127, 131), (167, 129, 133), (173, 132, 133) + ), + +// 469 040222-28 +((101, 156, 123), (83, 141, 116), (72, 130, 115), (62, 120, 114), + (62, 124, 118), (63, 128, 123), (62, 127, 123), (61, 126, 123), + (50, 116, 125), (42, 107, 121), (35, 98, 117), (28, 88, 108), + (22, 79, 100), (20, 73, 93), (19, 68, 86), (20, 64, 82), + (22, 61, 79), (28, 43, 63), (31, 39, 52), (34, 36, 42), + (40, 35, 34), (47, 35, 27), (51, 33, 26), (56, 32, 26), + (51, 34, 29), (49, 41, 35), (48, 49, 42), (50, 57, 52), + (53, 65, 63), (51, 69, 69), (50, 74, 76), (48, 79, 85), + (48, 84, 93), (50, 85, 90), (51, 82, 84), (53, 80, 79), + (56, 74, 69), (59, 69, 60), (61, 65, 55), (64, 62, 51), + (77, 67, 48), (83, 78, 54), (90, 90, 60), (93, 101, 69), + (97, 113, 78), (98, 119, 85), (100, 126, 93), (103, 140, 109), + (107, 157, 123), (110, 172, 135), (107, 171, 137), (105, 171, 139), + (101, 166, 133), (97, 162, 128), (95, 160, 124), (94, 158, 121), + (91, 149, 120), (81, 141, 116), (71, 133, 113), (58, 122, 106), + (45, 112, 100), (42, 107, 99), (40, 102, 98), (38, 92, 95), + (33, 81, 91), (17, 62, 74), (13, 53, 64), (9, 45, 55), + (8, 41, 49), (7, 37, 44), (4, 29, 33), (5, 24, 26), + (7, 23, 20), (7, 27, 19), (7, 31, 19), (11, 34, 18), + (15, 37, 18), (17, 37, 16), (19, 37, 15), (21, 37, 14), + (20, 36, 14), (18, 33, 15), (18, 29, 12), (19, 25, 9), + (18, 22, 8), (17, 20, 8), (16, 13, 10), (15, 9, 16), + (21, 7, 21), (23, 7, 20), (26, 8, 20), (26, 8, 21), + (27, 9, 22), (33, 14, 23), (39, 17, 22), (44, 22, 17), + (43, 25, 13), (35, 27, 9), (33, 30, 11), (32, 34, 13), + (32, 37, 15), (32, 41, 17), (31, 43, 20), (26, 44, 24), + (16, 38, 37), (17, 38, 41), (18, 39, 45), (19, 40, 43), + (21, 42, 42), (23, 45, 39), (29, 48, 37), (38, 52, 33), + (52, 62, 33), (80, 86, 39), (82, 92, 43), (85, 98, 47), + (88, 104, 53), (88, 110, 58), (92, 114, 64), (101, 115, 64), + (100, 107, 65), (92, 102, 59), (85, 97, 54), (86, 95, 49), + (88, 94, 44), (99, 99, 34), (109, 105, 29), (119, 115, 29), + (126, 128, 38), (130, 146, 63), (130, 149, 69), (130, 152, 75), + (124, 159, 89), (122, 164, 103), (115, 166, 115), (112, 166, 125), + (104, 159, 135), (100, 150, 131), (96, 142, 128), (96, 137, 123), + (96, 133, 119), (96, 124, 113), (96, 118, 111), (89, 118, 118), + (81, 112, 119), (70, 106, 110), (69, 104, 107), (68, 103, 105), + (62, 110, 113), (55, 114, 124), (55, 119, 134), (59, 130, 141), + (82, 151, 141), (85, 155, 142), (89, 159, 143), (97, 161, 146), + (104, 163, 146), (113, 167, 138), (124, 170, 125), (130, 170, 110), + (133, 165, 96), (126, 143, 81), (123, 138, 74), (120, 133, 68), + (114, 123, 53), (110, 111, 38), (103, 97, 29), (97, 82, 30), + (82, 66, 37), (81, 66, 40), (80, 67, 43), (78, 74, 50), + (80, 79, 59), (79, 84, 70), (79, 88, 79), (78, 87, 89), + (77, 88, 96), (75, 93, 98), (71, 96, 95), (64, 97, 90), + (56, 90, 88), (48, 78, 85), (41, 69, 81), (38, 64, 74), + (41, 82, 64), (46, 85, 63), (51, 88, 63), (64, 96, 63), + (76, 103, 63), (92, 112, 60), (103, 129, 58), (116, 137, 52), + (124, 136, 42), (126, 126, 34), (123, 112, 27), (111, 101, 23), + (98, 94, 20), (84, 80, 18), (69, 63, 16), (58, 48, 14), + (48, 38, 13), (44, 36, 11), (44, 38, 9), (43, 40, 11), + (45, 45, 14), (46, 54, 22), (46, 62, 26), (47, 65, 30), + (46, 67, 36), (44, 66, 41), (40, 71, 50), (37, 78, 56), + (37, 80, 62), (37, 80, 64), (41, 73, 62), (43, 71, 59), + (46, 73, 54), (51, 79, 54), (54, 86, 54), (60, 89, 56), + (61, 90, 55), (59, 87, 52), (57, 84, 51), (51, 82, 51), + (48, 82, 55), (44, 82, 58), (41, 82, 59), (41, 81, 61), + (41, 79, 60), (42, 78, 63), (42, 82, 68), (44, 89, 70), + (53, 96, 70), (62, 101, 68), (74, 101, 64), (79, 99, 62), + (78, 99, 64), (79, 99, 65), (78, 99, 70), (83, 100, 75), + (84, 97, 78), (84, 100, 89), (81, 103, 99), (81, 107, 111), + (85, 122, 126), (89, 139, 137), (104, 159, 144), (113, 171, 151), + (120, 176, 153), (127, 180, 153), (126, 186, 152), (136, 197, 148), + (129, 186, 136), (120, 173, 128), (111, 157, 122), (97, 146, 117) + ), + +// 470 040222-29 +((202, 107, 147), (191, 91, 132), (188, 88, 128), (186, 85, 125), + (185, 84, 125), (185, 83, 125), (184, 83, 126), (184, 84, 128), + (182, 88, 130), (182, 90, 131), (182, 92, 132), (185, 98, 137), + (188, 104, 142), (194, 112, 149), (201, 121, 157), (204, 126, 162), + (208, 131, 167), (220, 153, 186), (224, 158, 190), (228, 163, 194), + (229, 162, 193), (230, 162, 192), (230, 159, 190), (230, 157, 188), + (226, 144, 176), (221, 137, 170), (216, 130, 164), (212, 123, 158), + (209, 116, 153), (208, 112, 150), (207, 109, 148), (205, 103, 144), + (205, 96, 139), (203, 84, 129), (201, 77, 124), (200, 70, 119), + (196, 64, 115), (193, 59, 111), (191, 57, 109), (190, 56, 107), + (189, 53, 105), (190, 55, 107), (191, 58, 109), (194, 61, 111), + (197, 65, 114), (197, 67, 115), (197, 69, 116), (196, 71, 116), + (194, 73, 117), (189, 71, 114), (186, 68, 111), (183, 65, 109), + (178, 62, 105), (173, 60, 101), (170, 59, 98), (167, 58, 96), + (154, 57, 91), (148, 56, 88), (143, 55, 85), (141, 55, 84), + (139, 55, 84), (138, 55, 85), (138, 55, 86), (138, 55, 85), + (136, 53, 83), (131, 49, 77), (126, 46, 73), (122, 43, 70), + (121, 43, 69), (120, 43, 68), (119, 44, 69), (120, 48, 71), + (132, 60, 84), (139, 68, 92), (146, 77, 100), (152, 83, 107), + (158, 90, 115), (160, 92, 117), (162, 94, 120), (165, 99, 124), + (168, 103, 127), (175, 110, 134), (180, 115, 139), (185, 120, 144), + (188, 122, 147), (192, 125, 151), (198, 130, 157), (205, 133, 163), + (215, 137, 171), (218, 136, 171), (222, 135, 172), (222, 132, 171), + (222, 130, 170), (219, 123, 165), (214, 115, 157), (208, 107, 149), + (199, 99, 140), (181, 83, 123), (171, 75, 114), (162, 68, 105), + (158, 64, 101), (155, 60, 97), (146, 53, 88), (136, 43, 79), + (118, 27, 59), (111, 20, 52), (104, 14, 45), (101, 12, 42), + (98, 11, 40), (96, 11, 38), (99, 14, 40), (105, 19, 45), + (114, 25, 53), (132, 41, 71), (135, 45, 75), (139, 50, 79), + (148, 56, 87), (154, 64, 96), (159, 71, 102), (164, 77, 107), + (174, 85, 116), (179, 90, 121), (184, 95, 127), (185, 98, 129), + (187, 101, 132), (190, 106, 137), (193, 111, 143), (193, 115, 145), + (191, 118, 146), (184, 115, 141), (181, 113, 138), (179, 111, 136), + (175, 106, 131), (170, 101, 126), (167, 99, 122), (167, 97, 122), + (172, 101, 127), (178, 105, 131), (184, 109, 136), (186, 111, 138), + (189, 113, 140), (193, 115, 143), (195, 116, 145), (197, 118, 146), + (198, 120, 149), (204, 130, 159), (206, 134, 162), (208, 138, 166), + (214, 145, 173), (220, 150, 179), (226, 154, 184), (230, 155, 186), + (234, 147, 184), (233, 143, 181), (233, 140, 179), (229, 132, 172), + (225, 125, 164), (219, 120, 157), (212, 113, 149), (207, 106, 141), + (197, 99, 132), (178, 78, 112), (173, 72, 106), (168, 66, 100), + (157, 53, 88), (147, 40, 75), (136, 31, 64), (125, 23, 55), + (116, 18, 45), (114, 18, 44), (113, 19, 44), (112, 21, 46), + (113, 25, 50), (115, 30, 56), (120, 36, 61), (125, 43, 68), + (129, 48, 74), (137, 52, 81), (145, 56, 88), (154, 63, 97), + (164, 69, 104), (174, 76, 114), (183, 85, 124), (194, 95, 134), + (214, 121, 158), (217, 126, 162), (221, 131, 167), (226, 139, 175), + (231, 146, 183), (235, 151, 186), (236, 152, 188), (236, 153, 189), + (235, 152, 189), (234, 152, 188), (232, 154, 187), (231, 155, 186), + (230, 156, 186), (229, 156, 187), (228, 156, 185), (225, 152, 182), + (223, 147, 176), (219, 140, 170), (215, 131, 164), (209, 122, 155), + (203, 113, 146), (196, 105, 139), (190, 99, 133), (184, 95, 128), + (178, 92, 123), (173, 88, 117), (169, 85, 113), (164, 83, 110), + (160, 81, 106), (156, 79, 102), (151, 77, 100), (148, 75, 97), + (145, 74, 95), (143, 75, 95), (140, 74, 95), (139, 74, 95), + (138, 75, 95), (136, 75, 93), (135, 73, 91), (131, 68, 87), + (127, 64, 83), (123, 59, 78), (120, 55, 75), (120, 52, 73), + (121, 51, 73), (122, 53, 75), (125, 56, 78), (131, 60, 83), + (135, 62, 86), (139, 66, 90), (143, 71, 94), (145, 74, 97), + (150, 76, 100), (155, 81, 105), (160, 86, 112), (166, 93, 119), + (176, 102, 129), (187, 111, 139), (197, 119, 150), (207, 126, 159), + (213, 133, 166), (219, 137, 170), (224, 139, 174), (228, 140, 176), + (231, 142, 179), (233, 142, 181), (234, 142, 181), (233, 140, 180), + (229, 135, 177), (224, 131, 173), (218, 125, 167), (212, 118, 159) + ), + +// 471 040223 +((183, 89, 57), (215, 132, 89), (229, 149, 101), (243, 166, 113), + (242, 165, 110), (242, 164, 108), (239, 162, 105), (236, 161, 103), + (227, 148, 89), (220, 133, 76), (214, 118, 63), (202, 109, 57), + (190, 100, 52), (187, 106, 55), (185, 112, 59), (188, 114, 58), + (191, 117, 57), (203, 124, 65), (201, 133, 82), (199, 142, 100), + (189, 155, 108), (180, 168, 117), (174, 169, 115), (168, 170, 113), + (142, 151, 104), (134, 147, 108), (127, 144, 112), (118, 140, 107), + (109, 137, 102), (106, 135, 99), (104, 134, 97), (101, 134, 88), + (103, 133, 90), (105, 117, 87), (104, 110, 82), (104, 103, 78), + (106, 95, 66), (108, 87, 55), (111, 82, 51), (115, 78, 48), + (146, 78, 48), (157, 84, 45), (169, 90, 43), (177, 93, 44), + (186, 97, 46), (186, 99, 49), (187, 102, 52), (175, 106, 59), + (161, 103, 61), (141, 86, 48), (144, 71, 41), (148, 57, 35), + (145, 44, 29), (142, 32, 24), (139, 29, 21), (137, 27, 18), + (129, 21, 9), (117, 20, 5), (106, 19, 2), (87, 17, 1), + (68, 15, 1), (60, 15, 1), (52, 15, 1), (38, 14, 1), + (28, 16, 2), (25, 16, 4), (33, 16, 7), (42, 16, 10), + (45, 18, 14), (49, 21, 18), (56, 30, 29), (63, 39, 36), + (84, 49, 36), (88, 47, 34), (93, 45, 33), (91, 43, 32), + (89, 42, 31), (87, 39, 28), (85, 36, 26), (81, 29, 15), + (75, 19, 7), (62, 5, 0), (51, 3, 0), (41, 1, 0), + (36, 2, 0), (31, 4, 0), (22, 8, 1), (18, 13, 4), + (11, 25, 15), (12, 35, 22), (14, 45, 30), (17, 51, 33), + (20, 58, 37), (24, 69, 42), (29, 77, 44), (40, 78, 45), + (50, 75, 43), (70, 63, 36), (78, 56, 29), (87, 49, 22), + (90, 43, 18), (94, 37, 15), (98, 25, 7), (95, 14, 5), + (81, 2, 5), (71, 1, 6), (61, 0, 7), (55, 0, 8), + (49, 1, 9), (39, 1, 6), (31, 1, 6), (24, 1, 7), + (21, 1, 6), (32, 1, 4), (37, 1, 3), (42, 1, 2), + (50, 3, 4), (56, 7, 7), (66, 16, 15), (81, 29, 26), + (123, 71, 53), (131, 93, 67), (140, 116, 82), (143, 125, 91), + (146, 135, 101), (150, 148, 107), (158, 161, 114), (166, 169, 118), + (171, 173, 120), (183, 172, 124), (183, 167, 120), (184, 162, 116), + (191, 154, 106), (197, 141, 98), (207, 136, 92), (216, 128, 85), + (209, 112, 63), (196, 109, 59), (184, 106, 56), (176, 106, 56), + (168, 106, 57), (152, 100, 52), (135, 96, 51), (115, 97, 53), + (102, 108, 68), (79, 118, 97), (75, 114, 98), (71, 110, 99), + (64, 93, 87), (62, 94, 76), (54, 86, 81), (52, 82, 79), + (41, 64, 68), (38, 66, 58), (36, 69, 48), (25, 70, 39), + (23, 76, 36), (20, 83, 40), (28, 89, 54), (40, 100, 64), + (51, 105, 67), (87, 112, 66), (94, 112, 66), (102, 112, 67), + (116, 113, 71), (126, 105, 71), (131, 100, 66), (138, 93, 64), + (121, 81, 45), (115, 74, 41), (110, 68, 37), (88, 58, 28), + (72, 47, 25), (55, 37, 20), (36, 28, 16), (27, 18, 11), + (21, 11, 7), (20, 8, 4), (22, 11, 4), (27, 13, 6), + (32, 18, 7), (41, 22, 8), (51, 24, 10), (64, 28, 8), + (88, 27, 7), (92, 26, 7), (97, 26, 8), (104, 24, 8), + (112, 21, 6), (120, 15, 5), (130, 11, 2), (137, 9, 2), + (140, 10, 2), (143, 13, 1), (145, 14, 2), (150, 15, 1), + (151, 14, 2), (148, 12, 3), (141, 19, 6), (130, 23, 10), + (117, 29, 18), (100, 30, 23), (81, 25, 25), (64, 24, 26), + (55, 26, 27), (50, 34, 32), (46, 46, 36), (38, 56, 40), + (32, 62, 39), (32, 59, 41), (37, 56, 42), (49, 52, 42), + (55, 53, 42), (58, 59, 40), (56, 57, 41), (53, 52, 43), + (51, 42, 45), (45, 35, 44), (40, 33, 39), (32, 30, 34), + (28, 29, 28), (23, 24, 25), (18, 21, 23), (18, 19, 20), + (19, 17, 17), (28, 13, 13), (43, 11, 8), (59, 9, 5), + (78, 10, 3), (93, 12, 1), (104, 11, 2), (113, 15, 3), + (117, 18, 8), (120, 21, 11), (121, 24, 12), (115, 25, 15), + (108, 27, 16), (97, 30, 22), (83, 35, 28), (75, 38, 35), + (72, 44, 36), (72, 46, 33), (76, 46, 28), (73, 45, 24), + (67, 42, 24), (62, 39, 22), (59, 34, 20), (64, 29, 14), + (70, 23, 6), (73, 16, 2), (76, 9, 0), (81, 4, 1), + (95, 19, 13), (117, 41, 26), (142, 61, 37), (164, 82, 53) + ), + +// 472 040224 +((164, 132, 113), (149, 103, 81), (146, 85, 63), (144, 68, 46), + (133, 54, 31), (122, 40, 17), (113, 34, 13), (105, 29, 9), + (73, 10, 1), (60, 6, 0), (47, 2, 0), (38, 1, 0), + (30, 1, 0), (25, 1, 0), (20, 2, 0), (18, 2, 0), + (16, 2, 0), (10, 2, 0), (7, 2, 0), (5, 2, 0), + (4, 3, 0), (3, 4, 0), (3, 4, 0), (3, 5, 0), + (6, 5, 0), (12, 4, 0), (18, 4, 0), (25, 3, 1), + (32, 3, 2), (35, 3, 2), (38, 4, 3), (40, 7, 4), + (40, 12, 6), (41, 29, 13), (43, 37, 18), (45, 45, 24), + (51, 47, 27), (57, 50, 31), (60, 50, 30), (63, 50, 30), + (79, 55, 33), (86, 59, 36), (94, 64, 40), (108, 66, 47), + (122, 68, 55), (128, 67, 55), (135, 66, 55), (149, 66, 52), + (164, 61, 49), (192, 62, 36), (204, 68, 37), (217, 75, 39), + (224, 90, 43), (231, 105, 47), (233, 112, 47), (235, 119, 48), + (229, 135, 40), (213, 136, 39), (197, 138, 39), (179, 144, 51), + (162, 150, 63), (153, 152, 71), (145, 154, 80), (133, 157, 86), + (125, 156, 92), (88, 141, 90), (67, 131, 84), (47, 122, 79), + (37, 117, 81), (27, 112, 84), (13, 107, 85), (13, 103, 87), + (11, 81, 83), (9, 73, 76), (7, 66, 70), (7, 69, 68), + (8, 73, 67), (7, 78, 72), (7, 83, 78), (19, 92, 91), + (39, 98, 103), (78, 96, 117), (99, 92, 116), (120, 89, 116), + (122, 88, 120), (125, 88, 124), (133, 91, 127), (140, 94, 128), + (147, 87, 118), (152, 79, 103), (157, 72, 88), (153, 68, 83), + (150, 64, 79), (141, 60, 73), (130, 63, 76), (113, 76, 79), + (106, 85, 90), (109, 106, 81), (116, 112, 76), (124, 118, 72), + (132, 118, 73), (141, 118, 74), (150, 125, 72), (159, 130, 90), + (190, 130, 112), (203, 119, 107), (216, 108, 103), (221, 98, 97), + (227, 88, 92), (231, 72, 73), (224, 59, 62), (221, 54, 59), + (216, 51, 62), (213, 53, 64), (213, 58, 66), (214, 64, 68), + (217, 75, 65), (216, 87, 63), (216, 95, 61), (215, 102, 62), + (211, 108, 54), (212, 112, 51), (213, 116, 48), (214, 120, 49), + (216, 124, 50), (215, 125, 52), (209, 123, 53), (197, 119, 50), + (186, 103, 43), (171, 76, 23), (172, 75, 19), (174, 75, 15), + (180, 78, 10), (185, 84, 12), (167, 91, 14), (154, 89, 19), + (128, 81, 22), (123, 74, 20), (119, 68, 19), (129, 67, 19), + (140, 67, 20), (131, 71, 19), (123, 69, 21), (105, 65, 22), + (87, 60, 20), (44, 40, 15), (45, 36, 12), (46, 33, 10), + (47, 32, 8), (47, 29, 9), (42, 28, 8), (36, 30, 8), + (35, 40, 9), (37, 44, 7), (39, 49, 6), (51, 60, 8), + (65, 66, 9), (82, 69, 8), (95, 72, 9), (108, 73, 13), + (120, 68, 16), (133, 67, 12), (135, 66, 12), (137, 66, 12), + (138, 66, 12), (136, 68, 13), (129, 74, 18), (119, 77, 25), + (97, 82, 26), (91, 83, 26), (86, 84, 27), (73, 93, 26), + (58, 106, 24), (46, 122, 28), (32, 133, 37), (24, 147, 49), + (16, 156, 56), (12, 158, 59), (12, 154, 59), (10, 148, 51), + (12, 145, 46), (9, 134, 41), (8, 126, 40), (6, 116, 42), + (9, 86, 45), (10, 77, 43), (12, 68, 41), (19, 54, 33), + (26, 40, 24), (33, 28, 14), (37, 18, 7), (41, 12, 5), + (44, 8, 5), (44, 7, 4), (46, 5, 4), (48, 5, 4), + (50, 4, 4), (50, 2, 2), (49, 2, 0), (48, 1, 1), + (47, 2, 0), (49, 3, 2), (53, 3, 1), (57, 3, 2), + (62, 3, 2), (71, 2, 2), (79, 2, 2), (88, 2, 3), + (96, 3, 4), (107, 4, 3), (117, 4, 3), (124, 4, 4), + (131, 4, 4), (136, 5, 2), (140, 7, 3), (142, 8, 3), + (144, 9, 3), (146, 10, 3), (146, 10, 4), (144, 11, 7), + (141, 10, 7), (136, 12, 9), (131, 12, 10), (124, 12, 10), + (115, 12, 8), (107, 10, 6), (100, 11, 7), (94, 11, 7), + (86, 11, 9), (79, 10, 10), (72, 9, 11), (64, 9, 10), + (56, 8, 6), (49, 8, 7), (43, 11, 9), (37, 13, 11), + (33, 15, 12), (30, 17, 12), (30, 18, 12), (32, 20, 11), + (40, 21, 11), (55, 25, 19), (75, 29, 28), (93, 38, 39), + (105, 51, 57), (112, 67, 74), (108, 86, 87), (110, 102, 100), + (116, 119, 113), (137, 123, 121), (160, 128, 122), (183, 132, 127), + (203, 134, 130), (200, 139, 124), (196, 138, 122), (177, 140, 120) + ), + +// 473 040225 +((174, 52, 5), (173, 60, 7), (171, 58, 6), (169, 56, 5), + (155, 51, 5), (142, 47, 5), (136, 46, 5), (130, 45, 5), + (112, 44, 6), (113, 47, 9), (115, 50, 12), (113, 53, 18), + (112, 57, 24), (106, 55, 28), (101, 53, 32), (98, 51, 30), + (95, 49, 29), (99, 46, 28), (106, 49, 30), (113, 52, 32), + (118, 49, 31), (124, 47, 31), (124, 43, 28), (124, 39, 25), + (119, 22, 13), (116, 19, 10), (113, 17, 8), (110, 17, 8), + (107, 18, 9), (107, 19, 8), (107, 20, 8), (112, 18, 8), + (116, 16, 6), (124, 7, 2), (128, 6, 1), (133, 6, 0), + (147, 12, 1), (161, 19, 2), (170, 23, 3), (179, 28, 4), + (209, 46, 7), (214, 52, 9), (219, 58, 11), (214, 60, 10), + (210, 62, 10), (208, 65, 10), (206, 68, 10), (204, 79, 12), + (197, 84, 13), (190, 91, 17), (185, 85, 17), (180, 79, 17), + (176, 76, 16), (172, 73, 16), (174, 76, 17), (176, 79, 18), + (176, 86, 22), (179, 85, 25), (183, 84, 29), (179, 83, 32), + (176, 82, 36), (170, 80, 35), (165, 78, 34), (158, 72, 32), + (153, 69, 30), (160, 65, 32), (162, 65, 32), (164, 66, 33), + (165, 64, 32), (166, 63, 32), (172, 63, 30), (180, 65, 28), + (184, 90, 34), (185, 109, 45), (187, 128, 56), (195, 145, 71), + (203, 162, 87), (200, 169, 90), (197, 176, 93), (187, 192, 97), + (181, 196, 98), (173, 191, 98), (179, 178, 96), (186, 166, 94), + (186, 162, 88), (187, 158, 83), (189, 145, 73), (181, 129, 55), + (195, 99, 40), (203, 89, 35), (211, 79, 30), (212, 79, 29), + (214, 79, 28), (217, 81, 28), (221, 86, 31), (224, 94, 35), + (229, 102, 41), (237, 110, 45), (241, 112, 45), (246, 115, 45), + (246, 116, 44), (247, 117, 43), (249, 120, 42), (248, 121, 39), + (226, 114, 32), (214, 106, 29), (202, 98, 26), (197, 96, 27), + (193, 94, 28), (188, 93, 29), (181, 95, 29), (171, 97, 28), + (163, 99, 26), (144, 103, 30), (143, 105, 32), (143, 107, 35), + (152, 112, 40), (164, 119, 45), (177, 125, 47), (188, 131, 47), + (197, 136, 52), (205, 134, 53), (213, 133, 54), (216, 130, 54), + (220, 128, 54), (226, 125, 53), (229, 120, 56), (224, 117, 52), + (218, 108, 47), (208, 89, 34), (205, 85, 31), (202, 82, 28), + (196, 73, 24), (189, 67, 20), (182, 62, 16), (177, 58, 13), + (181, 54, 5), (186, 53, 5), (191, 52, 5), (194, 53, 5), + (198, 55, 6), (200, 59, 8), (203, 67, 9), (211, 76, 10), + (219, 84, 12), (236, 92, 19), (237, 93, 22), (239, 95, 25), + (230, 106, 34), (222, 118, 40), (215, 128, 43), (204, 131, 41), + (177, 113, 34), (166, 107, 34), (156, 102, 35), (134, 96, 37), + (118, 90, 36), (106, 88, 33), (99, 89, 29), (96, 83, 24), + (94, 83, 25), (91, 101, 40), (93, 108, 47), (95, 116, 54), + (106, 135, 64), (115, 150, 73), (127, 169, 79), (139, 182, 85), + (161, 186, 96), (166, 184, 96), (171, 183, 97), (174, 168, 92), + (175, 155, 85), (177, 138, 71), (175, 115, 58), (179, 92, 47), + (185, 71, 37), (188, 50, 28), (188, 36, 22), (187, 27, 13), + (181, 19, 7), (176, 12, 4), (175, 8, 2), (175, 4, 2), + (176, 1, 1), (176, 0, 1), (176, 0, 1), (175, 0, 0), + (175, 1, 1), (176, 3, 1), (176, 6, 1), (177, 10, 1), + (179, 14, 1), (181, 18, 2), (182, 23, 4), (186, 29, 8), + (191, 36, 11), (196, 43, 15), (200, 49, 17), (203, 52, 19), + (203, 52, 19), (204, 53, 21), (207, 54, 23), (208, 55, 24), + (211, 58, 24), (212, 58, 23), (209, 55, 19), (204, 50, 14), + (201, 46, 12), (196, 40, 10), (193, 38, 7), (190, 38, 5), + (185, 38, 4), (174, 36, 3), (163, 35, 3), (154, 35, 6), + (145, 32, 8), (142, 30, 7), (144, 32, 7), (145, 32, 8), + (148, 35, 7), (153, 43, 11), (157, 50, 16), (163, 54, 18), + (175, 58, 19), (185, 60, 18), (196, 58, 14), (205, 57, 11), + (210, 57, 11), (216, 61, 12), (221, 64, 13), (222, 67, 12), + (224, 69, 10), (224, 66, 7), (217, 61, 4), (210, 56, 2), + (203, 52, 1), (194, 47, 2), (186, 45, 2), (180, 43, 2), + (171, 39, 1), (162, 33, 2), (159, 28, 0), (154, 21, 1), + (150, 15, 1), (148, 12, 1), (147, 12, 1), (146, 14, 2), + (153, 18, 1), (164, 24, 1), (175, 30, 1), (184, 33, 2), + (190, 37, 2), (188, 40, 2), (183, 42, 3), (177, 47, 5) + ), + +// 474 040226 +((49, 78, 48), (42, 93, 55), (38, 103, 59), (34, 113, 63), + (29, 114, 64), (25, 115, 65), (23, 114, 63), (22, 114, 61), + (23, 109, 56), (21, 100, 51), (20, 92, 47), (15, 81, 38), + (10, 71, 30), (13, 61, 26), (16, 52, 22), (21, 49, 21), + (26, 46, 21), (57, 41, 18), (78, 42, 18), (99, 44, 19), + (108, 46, 21), (118, 48, 23), (118, 48, 24), (119, 49, 25), + (120, 57, 27), (110, 56, 27), (101, 55, 27), (83, 49, 25), + (66, 43, 24), (60, 41, 23), (54, 40, 23), (45, 38, 25), + (38, 38, 26), (34, 45, 29), (34, 52, 34), (35, 60, 39), + (34, 69, 42), (34, 79, 46), (32, 82, 47), (31, 85, 49), + (28, 87, 53), (32, 86, 53), (36, 85, 54), (38, 83, 51), + (41, 82, 48), (41, 81, 47), (42, 80, 46), (53, 74, 49), + (69, 72, 51), (108, 80, 53), (120, 87, 52), (132, 94, 52), + (135, 94, 49), (139, 95, 46), (138, 92, 45), (137, 90, 44), + (117, 76, 34), (100, 73, 29), (84, 70, 25), (63, 63, 21), + (42, 56, 17), (34, 50, 15), (26, 45, 13), (16, 37, 13), + (11, 36, 12), (5, 42, 15), (3, 42, 15), (2, 42, 15), + (2, 40, 15), (3, 38, 15), (5, 32, 14), (7, 30, 15), + (11, 29, 16), (14, 26, 16), (18, 23, 16), (21, 19, 15), + (25, 15, 14), (27, 14, 13), (29, 14, 13), (33, 15, 14), + (40, 18, 15), (59, 22, 15), (62, 22, 14), (66, 23, 13), + (65, 24, 13), (65, 25, 14), (66, 28, 15), (69, 33, 18), + (64, 47, 22), (54, 49, 23), (45, 51, 25), (42, 50, 27), + (40, 50, 30), (36, 52, 32), (34, 53, 32), (32, 53, 32), + (30, 50, 27), (31, 38, 21), (35, 32, 17), (39, 27, 13), + (42, 24, 11), (45, 22, 9), (51, 19, 7), (56, 19, 4), + (70, 18, 2), (73, 16, 1), (77, 14, 1), (76, 13, 0), + (75, 13, 0), (70, 14, 1), (66, 14, 1), (62, 11, 1), + (57, 10, 2), (38, 6, 1), (33, 6, 1), (29, 6, 2), + (22, 6, 4), (20, 7, 5), (17, 9, 5), (14, 9, 3), + (8, 11, 4), (10, 13, 7), (13, 16, 10), (16, 17, 10), + (19, 18, 11), (28, 21, 10), (40, 24, 9), (56, 28, 10), + (78, 32, 10), (114, 42, 10), (118, 43, 10), (123, 44, 10), + (125, 46, 12), (123, 45, 11), (123, 44, 13), (118, 43, 11), + (105, 45, 16), (107, 51, 28), (109, 58, 41), (113, 69, 48), + (117, 80, 55), (117, 103, 76), (135, 121, 95), (151, 132, 101), + (178, 134, 109), (214, 160, 100), (221, 168, 102), (228, 177, 104), + (229, 190, 106), (234, 193, 111), (245, 183, 102), (243, 178, 87), + (245, 163, 62), (246, 163, 63), (247, 163, 64), (243, 159, 68), + (236, 157, 74), (229, 138, 70), (227, 118, 57), (228, 96, 43), + (227, 84, 32), (218, 81, 26), (215, 82, 25), (213, 83, 24), + (216, 78, 21), (218, 80, 20), (218, 84, 21), (210, 93, 27), + (175, 95, 31), (165, 92, 32), (156, 90, 34), (144, 81, 33), + (130, 79, 38), (107, 75, 38), (87, 66, 36), (65, 54, 35), + (56, 42, 28), (55, 33, 24), (58, 30, 20), (63, 29, 15), + (67, 30, 16), (75, 33, 14), (84, 35, 14), (92, 39, 13), + (102, 39, 13), (102, 39, 13), (103, 39, 14), (102, 38, 15), + (101, 39, 16), (99, 37, 17), (100, 35, 15), (102, 34, 13), + (104, 33, 13), (115, 40, 13), (130, 50, 14), (146, 62, 12), + (166, 73, 10), (179, 81, 13), (193, 86, 19), (205, 91, 26), + (210, 100, 31), (208, 101, 33), (191, 112, 42), (171, 118, 52), + (155, 118, 63), (140, 127, 68), (134, 120, 67), (124, 131, 72), + (106, 146, 80), (86, 158, 90), (70, 175, 97), (65, 172, 95), + (70, 169, 91), (70, 161, 86), (59, 153, 81), (45, 141, 77), + (31, 125, 69), (24, 106, 62), (23, 84, 51), (19, 65, 39), + (16, 47, 27), (14, 31, 16), (14, 20, 10), (14, 11, 7), + (11, 6, 6), (10, 5, 5), (8, 6, 5), (9, 7, 6), + (10, 11, 5), (11, 17, 7), (12, 24, 7), (14, 32, 10), + (16, 40, 13), (20, 51, 19), (26, 60, 24), (29, 70, 28), + (38, 79, 32), (47, 82, 34), (57, 85, 39), (68, 83, 44), + (72, 80, 47), (78, 78, 48), (87, 76, 45), (98, 72, 44), + (110, 71, 45), (120, 66, 45), (125, 63, 44), (125, 64, 40), + (124, 60, 37), (119, 61, 38), (116, 60, 39), (114, 57, 40), + (111, 57, 40), (100, 63, 41), (83, 67, 44), (65, 72, 45) + ), + +// 475 040227 +((180, 72, 104), (178, 67, 104), (177, 66, 100), (177, 66, 97), + (187, 60, 96), (197, 55, 95), (201, 54, 94), (205, 54, 94), + (211, 65, 90), (204, 81, 87), (198, 97, 85), (184, 119, 86), + (171, 141, 88), (151, 154, 98), (131, 168, 108), (124, 165, 110), + (118, 163, 113), (102, 138, 125), (84, 130, 136), (67, 122, 147), + (61, 99, 163), (56, 76, 179), (63, 62, 185), (71, 48, 191), + (84, 45, 208), (79, 62, 209), (74, 80, 211), (71, 98, 205), + (68, 117, 199), (68, 124, 196), (68, 132, 194), (60, 131, 195), + (56, 133, 187), (32, 123, 169), (29, 110, 167), (26, 97, 165), + (40, 76, 161), (54, 55, 157), (63, 50, 153), (72, 46, 149), + (103, 64, 132), (107, 84, 122), (111, 105, 113), (107, 123, 117), + (104, 142, 121), (105, 149, 127), (106, 157, 133), (104, 175, 139), + (100, 196, 149), (77, 213, 177), (81, 204, 194), (85, 195, 211), + (102, 191, 217), (119, 188, 223), (125, 189, 224), (132, 191, 226), + (146, 197, 228), (149, 193, 224), (153, 189, 220), (168, 176, 212), + (183, 164, 205), (184, 159, 200), (186, 155, 195), (179, 142, 189), + (171, 129, 180), (170, 97, 155), (174, 75, 146), (179, 54, 137), + (177, 44, 136), (176, 34, 136), (175, 25, 140), (178, 24, 134), + (186, 19, 109), (189, 12, 99), (192, 6, 89), (200, 6, 84), + (209, 7, 80), (212, 7, 75), (215, 8, 70), (205, 9, 57), + (192, 6, 51), (179, 5, 55), (179, 5, 69), (179, 6, 83), + (175, 6, 91), (172, 6, 99), (166, 13, 109), (168, 21, 121), + (167, 44, 157), (159, 52, 173), (151, 60, 190), (145, 61, 193), + (140, 63, 196), (144, 69, 196), (146, 77, 191), (151, 82, 183), + (152, 96, 190), (136, 100, 199), (128, 107, 196), (121, 115, 193), + (120, 123, 193), (119, 131, 194), (118, 146, 203), (115, 143, 207), + (89, 139, 214), (88, 141, 201), (87, 143, 188), (94, 139, 176), + (101, 136, 164), (111, 132, 133), (113, 128, 118), (112, 122, 103), + (123, 120, 83), (163, 120, 41), (171, 120, 39), (179, 121, 38), + (180, 125, 42), (181, 124, 49), (190, 122, 58), (203, 119, 66), + (233, 96, 102), (230, 86, 111), (227, 76, 121), (226, 74, 121), + (225, 72, 122), (226, 66, 124), (231, 50, 128), (228, 35, 128), + (226, 21, 130), (225, 17, 126), (228, 18, 125), (231, 19, 125), + (233, 23, 120), (233, 23, 124), (230, 25, 127), (228, 31, 130), + (229, 53, 139), (227, 78, 153), (226, 104, 168), (222, 113, 169), + (219, 123, 171), (214, 130, 170), (209, 123, 160), (212, 122, 162), + (213, 121, 167), (202, 108, 152), (192, 97, 139), (182, 87, 127), + (165, 61, 104), (155, 42, 87), (141, 29, 74), (137, 26, 65), + (121, 41, 59), (116, 45, 60), (112, 50, 62), (93, 53, 68), + (90, 57, 70), (93, 64, 73), (106, 64, 72), (121, 64, 70), + (122, 57, 72), (135, 50, 71), (142, 45, 69), (150, 41, 67), + (166, 36, 63), (170, 27, 58), (171, 22, 55), (171, 28, 62), + (185, 35, 85), (187, 35, 90), (189, 36, 96), (186, 40, 100), + (177, 51, 104), (177, 64, 109), (184, 73, 117), (199, 78, 130), + (211, 80, 141), (212, 84, 147), (216, 88, 152), (219, 89, 154), + (228, 86, 155), (241, 78, 152), (245, 70, 143), (247, 59, 135), + (240, 44, 120), (238, 41, 114), (237, 39, 109), (236, 34, 93), + (230, 32, 81), (220, 36, 72), (206, 35, 70), (188, 39, 70), + (174, 35, 62), (164, 31, 54), (157, 31, 47), (157, 29, 46), + (161, 33, 57), (166, 34, 68), (171, 32, 77), (174, 32, 92), + (184, 33, 105), (201, 42, 123), (215, 56, 136), (221, 76, 140), + (212, 96, 145), (197, 115, 156), (185, 134, 172), (174, 154, 183), + (160, 174, 173), (141, 190, 153), (127, 194, 133), (116, 195, 127), + (118, 184, 135), (123, 166, 135), (122, 148, 138), (125, 120, 131), + (123, 101, 127), (126, 80, 133), (136, 59, 134), (140, 44, 141), + (142, 31, 146), (133, 28, 145), (125, 31, 142), (127, 39, 129), + (136, 60, 114), (151, 89, 102), (154, 118, 88), (153, 139, 79), + (137, 151, 71), (127, 165, 67), (123, 184, 67), (123, 196, 69), + (138, 196, 70), (135, 184, 74), (127, 162, 77), (115, 148, 80), + (107, 127, 81), (120, 104, 73), (141, 84, 64), (159, 74, 53), + (165, 79, 50), (165, 84, 54), (163, 84, 59), (164, 75, 66), + (169, 68, 72), (170, 69, 78), (174, 74, 84), (181, 79, 92), + (188, 74, 99), (197, 61, 106), (203, 51, 110), (202, 44, 109), + (203, 47, 105), (188, 60, 101), (184, 68, 98), (185, 75, 98) + ), + +// 476 040228 +((20, 32, 20), (21, 27, 20), (20, 25, 20), (20, 23, 20), + (20, 23, 20), (21, 23, 20), (20, 22, 20), (20, 22, 20), + (20, 22, 20), (20, 22, 20), (20, 22, 20), (20, 22, 20), + (20, 22, 20), (20, 22, 20), (20, 22, 20), (20, 21, 20), + (20, 21, 20), (22, 20, 20), (22, 20, 20), (23, 21, 20), + (22, 21, 20), (22, 22, 20), (22, 22, 20), (22, 23, 21), + (21, 25, 25), (20, 26, 28), (20, 28, 31), (21, 34, 41), + (22, 40, 52), (23, 43, 59), (25, 47, 66), (27, 56, 81), + (29, 67, 94), (33, 89, 114), (34, 88, 112), (35, 87, 111), + (31, 79, 100), (28, 72, 89), (28, 68, 81), (29, 64, 73), + (24, 39, 45), (22, 31, 37), (20, 23, 30), (20, 21, 27), + (20, 20, 25), (20, 20, 24), (20, 20, 24), (20, 20, 24), + (20, 20, 24), (20, 20, 24), (20, 20, 24), (20, 20, 25), + (20, 20, 24), (21, 20, 23), (21, 20, 22), (21, 21, 22), + (21, 24, 21), (21, 26, 20), (21, 29, 20), (20, 29, 21), + (20, 29, 23), (20, 29, 26), (20, 29, 30), (20, 29, 43), + (20, 27, 63), (24, 39, 83), (30, 41, 87), (36, 43, 92), + (37, 45, 90), (39, 47, 88), (52, 55, 80), (67, 75, 72), + (93, 111, 83), (109, 132, 97), (125, 153, 111), (128, 173, 137), + (131, 194, 164), (124, 192, 170), (118, 191, 177), (106, 188, 185), + (95, 183, 176), (80, 179, 189), (84, 174, 179), (89, 169, 169), + (100, 173, 165), (112, 177, 161), (140, 178, 150), (174, 173, 123), + (212, 156, 90), (200, 140, 68), (188, 124, 46), (176, 114, 36), + (164, 104, 26), (140, 89, 23), (116, 82, 26), (101, 90, 29), + (87, 94, 32), (100, 114, 58), (128, 134, 71), (157, 154, 84), + (165, 156, 85), (173, 159, 87), (169, 161, 100), (169, 169, 108), + (162, 157, 102), (154, 150, 89), (147, 143, 76), (144, 138, 71), + (142, 133, 66), (134, 123, 65), (133, 125, 67), (139, 128, 70), + (133, 129, 68), (131, 153, 113), (144, 162, 132), (158, 172, 152), + (173, 189, 172), (173, 201, 188), (177, 216, 191), (175, 210, 199), + (141, 161, 184), (115, 133, 155), (89, 105, 126), (70, 89, 110), + (52, 74, 94), (26, 44, 74), (20, 30, 55), (21, 21, 43), + (22, 21, 35), (23, 21, 29), (23, 21, 28), (24, 21, 28), + (24, 22, 28), (24, 22, 30), (24, 22, 30), (23, 21, 30), + (21, 21, 29), (20, 20, 30), (20, 20, 32), (21, 20, 34), + (23, 21, 37), (31, 27, 41), (48, 35, 42), (76, 45, 43), + (102, 46, 44), (116, 51, 40), (120, 51, 39), (124, 52, 39), + (146, 48, 32), (174, 51, 31), (181, 52, 30), (177, 59, 29), + (184, 79, 29), (185, 83, 38), (187, 88, 47), (181, 100, 59), + (173, 110, 64), (153, 116, 66), (121, 109, 74), (91, 96, 77), + (71, 81, 72), (48, 60, 58), (42, 54, 53), (37, 48, 48), + (29, 36, 36), (25, 27, 28), (23, 23, 26), (22, 21, 25), + (22, 21, 24), (22, 21, 24), (22, 22, 24), (22, 22, 25), + (21, 24, 25), (20, 25, 24), (20, 26, 24), (20, 28, 25), + (20, 28, 26), (20, 30, 27), (20, 29, 32), (20, 31, 37), + (25, 37, 43), (34, 48, 47), (46, 56, 57), (55, 64, 64), + (71, 83, 83), (70, 87, 87), (69, 92, 91), (64, 99, 97), + (63, 104, 99), (66, 101, 99), (65, 97, 89), (68, 97, 82), + (71, 103, 69), (83, 98, 58), (90, 87, 43), (93, 76, 35), + (89, 74, 28), (83, 68, 24), (75, 59, 22), (67, 45, 23), + (65, 37, 23), (81, 36, 22), (106, 41, 22), (133, 44, 22), + (152, 48, 21), (170, 52, 20), (171, 51, 20), (161, 46, 20), + (140, 47, 20), (124, 48, 21), (94, 40, 22), (62, 28, 24), + (34, 21, 26), (25, 21, 30), (22, 20, 36), (22, 23, 46), + (22, 38, 57), (21, 53, 64), (20, 56, 66), (22, 47, 69), + (22, 47, 70), (22, 56, 70), (20, 58, 60), (21, 45, 52), + (22, 30, 43), (22, 23, 37), (22, 22, 29), (23, 22, 25), + (25, 23, 23), (31, 24, 22), (40, 24, 21), (59, 27, 20), + (87, 41, 20), (122, 62, 20), (149, 84, 31), (173, 110, 49), + (197, 142, 76), (219, 174, 96), (234, 194, 112), (243, 216, 125), + (247, 233, 128), (244, 237, 127), (235, 224, 115), (216, 203, 109), + (200, 191, 93), (183, 175, 84), (170, 158, 71), (137, 131, 67), + (102, 115, 67), (75, 100, 72), (62, 89, 69), (49, 74, 58), + (36, 64, 47), (29, 55, 39), (24, 45, 31), (22, 37, 24) + ), + +// 477 10000 +((52, 44, 62), (50, 38, 55), (43, 38, 52), (36, 39, 50), + (30, 38, 48), (25, 37, 47), (23, 35, 44), (22, 34, 42), + (23, 21, 32), (28, 14, 26), (33, 7, 20), (36, 7, 21), + (40, 7, 23), (39, 12, 25), (38, 17, 28), (37, 19, 31), + (37, 21, 34), (44, 22, 37), (52, 23, 40), (61, 24, 43), + (69, 31, 46), (77, 39, 49), (78, 46, 52), (80, 53, 56), + (93, 76, 68), (106, 82, 71), (120, 88, 75), (132, 91, 74), + (144, 94, 74), (147, 97, 75), (150, 100, 76), (155, 105, 79), + (158, 110, 81), (160, 111, 87), (156, 107, 85), (152, 103, 83), + (140, 97, 78), (128, 91, 74), (120, 86, 72), (113, 82, 70), + (83, 70, 68), (74, 65, 66), (65, 60, 65), (61, 54, 61), + (58, 49, 57), (57, 47, 55), (57, 45, 54), (57, 43, 53), + (57, 42, 53), (56, 38, 54), (55, 33, 50), (55, 28, 46), + (54, 23, 41), (53, 19, 37), (53, 17, 35), (53, 16, 34), + (52, 19, 38), (51, 23, 40), (51, 27, 43), (53, 33, 48), + (55, 40, 53), (55, 42, 56), (56, 45, 60), (58, 53, 68), + (58, 61, 76), (60, 75, 93), (70, 83, 97), (81, 92, 101), + (87, 96, 104), (94, 101, 107), (115, 113, 113), (126, 122, 119), + (127, 126, 122), (122, 122, 116), (117, 119, 110), (116, 117, 105), + (115, 116, 100), (116, 117, 100), (117, 119, 101), (118, 120, 101), + (114, 119, 103), (101, 110, 103), (88, 103, 100), (75, 96, 97), + (71, 95, 97), (67, 95, 98), (63, 94, 100), (66, 95, 100), + (88, 109, 104), (100, 115, 106), (113, 122, 109), (119, 128, 112), + (125, 134, 116), (135, 144, 127), (149, 154, 136), (163, 166, 145), + (177, 177, 149), (201, 185, 146), (204, 185, 145), (207, 185, 144), + (205, 181, 143), (203, 177, 142), (197, 172, 145), (190, 167, 147), + (179, 158, 140), (172, 153, 134), (166, 148, 129), (162, 142, 125), + (159, 137, 122), (151, 128, 112), (141, 115, 107), (132, 103, 99), + (121, 92, 90), (102, 80, 77), (99, 77, 76), (96, 75, 76), + (91, 72, 68), (81, 65, 62), (73, 54, 54), (63, 42, 43), + (40, 18, 18), (31, 10, 12), (22, 3, 6), (18, 2, 4), + (15, 1, 2), (11, 0, 1), (10, 0, 1), (8, 0, 2), + (9, 2, 3), (9, 9, 9), (8, 11, 11), (8, 14, 13), + (7, 19, 18), (7, 23, 23), (5, 27, 27), (5, 29, 31), + (10, 34, 33), (13, 34, 34), (16, 35, 35), (18, 35, 35), + (21, 35, 35), (25, 35, 36), (29, 33, 37), (32, 35, 38), + (37, 37, 38), (40, 42, 43), (40, 43, 44), (41, 45, 46), + (44, 49, 51), (48, 50, 56), (52, 55, 65), (58, 63, 73), + (62, 80, 92), (61, 84, 96), (60, 88, 101), (57, 95, 108), + (54, 97, 113), (56, 95, 114), (63, 92, 114), (71, 87, 111), + (78, 81, 106), (88, 70, 97), (87, 68, 95), (86, 66, 93), + (86, 59, 86), (87, 53, 80), (89, 48, 72), (90, 41, 63), + (88, 27, 43), (85, 25, 40), (82, 24, 38), (74, 22, 35), + (65, 22, 34), (59, 26, 36), (53, 31, 40), (48, 37, 44), + (44, 40, 45), (39, 44, 45), (34, 43, 44), (29, 39, 42), + (26, 37, 39), (25, 34, 40), (26, 35, 43), (32, 35, 46), + (44, 35, 51), (46, 33, 50), (49, 31, 50), (52, 25, 45), + (50, 19, 39), (49, 14, 33), (48, 9, 30), (52, 6, 27), + (53, 8, 27), (54, 11, 29), (54, 15, 33), (51, 20, 38), + (47, 28, 43), (43, 36, 51), (45, 46, 62), (50, 57, 72), + (58, 69, 80), (66, 77, 85), (76, 81, 89), (86, 84, 90), + (90, 84, 91), (95, 83, 93), (99, 84, 97), (106, 86, 101), + (111, 89, 103), (117, 89, 101), (123, 87, 96), (126, 84, 89), + (125, 78, 80), (120, 71, 72), (117, 64, 67), (110, 60, 65), + (104, 57, 63), (102, 56, 62), (102, 57, 63), (102, 58, 64), + (100, 61, 65), (99, 62, 63), (98, 62, 60), (94, 58, 56), + (90, 53, 51), (88, 48, 47), (86, 44, 45), (84, 41, 46), + (81, 40, 48), (81, 43, 48), (76, 47, 51), (71, 52, 54), + (66, 54, 55), (61, 58, 58), (55, 59, 63), (51, 59, 68), + (49, 58, 70), (44, 60, 73), (41, 64, 76), (39, 66, 78), + (36, 72, 82), (32, 76, 86), (28, 78, 88), (27, 76, 88), + (24, 72, 84), (26, 66, 79), (29, 57, 72), (34, 50, 66), + (40, 45, 64), (46, 43, 62), (51, 44, 64), (51, 48, 66), + (51, 51, 69), (50, 52, 70), (51, 50, 69), (51, 48, 66) + ), + +// 478 Apophysis-040208-115d +((0, 0, 0), (3, 0, 5), (1, 0, 12), (0, 1, 19), + (2, 5, 26), (4, 9, 33), (6, 12, 36), (9, 16, 40), + (15, 23, 54), (17, 26, 61), (20, 30, 68), (22, 33, 74), + (24, 37, 81), (25, 37, 88), (26, 37, 95), (26, 38, 99), + (27, 39, 104), (31, 41, 120), (32, 43, 127), (34, 45, 134), + (35, 45, 138), (36, 45, 142), (36, 43, 142), (36, 41, 142), + (34, 35, 142), (35, 35, 142), (37, 36, 142), (38, 37, 142), + (40, 39, 142), (41, 40, 142), (43, 42, 142), (42, 41, 142), + (38, 37, 142), (36, 33, 142), (34, 30, 140), (33, 28, 138), + (32, 26, 134), (31, 24, 131), (31, 23, 129), (31, 23, 127), + (31, 22, 120), (31, 21, 115), (32, 20, 110), (27, 17, 105), + (23, 15, 101), (22, 14, 98), (22, 14, 95), (23, 13, 88), + (23, 13, 82), (20, 10, 67), (18, 8, 58), (17, 7, 50), + (15, 5, 43), (14, 3, 36), (14, 2, 34), (14, 2, 32), + (12, 0, 22), (11, 0, 18), (10, 0, 15), (9, 0, 13), + (8, 0, 12), (7, 0, 11), (7, 0, 11), (7, 0, 10), + (7, 0, 11), (5, 2, 18), (13, 11, 23), (22, 20, 29), + (26, 24, 32), (30, 29, 36), (39, 38, 41), (48, 48, 48), + (57, 57, 57), (62, 62, 62), (68, 68, 68), (72, 71, 74), + (76, 74, 81), (75, 73, 83), (75, 72, 85), (77, 73, 92), + (80, 74, 98), (82, 77, 113), (83, 78, 120), (85, 80, 127), + (86, 81, 130), (88, 83, 134), (92, 90, 141), (99, 97, 142), + (112, 109, 142), (115, 112, 142), (118, 116, 142), (116, 115, 142), + (115, 114, 142), (114, 114, 142), (110, 110, 142), (104, 105, 142), + (98, 101, 142), (82, 87, 132), (71, 76, 127), (60, 66, 123), + (54, 60, 120), (49, 54, 118), (41, 48, 117), (34, 43, 116), + (30, 44, 115), (30, 48, 114), (31, 53, 113), (31, 53, 113), + (31, 54, 113), (31, 56, 115), (33, 59, 115), (33, 59, 113), + (32, 58, 111), (32, 56, 101), (32, 56, 99), (33, 57, 97), + (31, 51, 90), (28, 47, 85), (24, 42, 80), (20, 36, 73), + (15, 28, 64), (18, 29, 62), (21, 31, 60), (23, 32, 60), + (26, 34, 60), (33, 41, 64), (43, 50, 69), (52, 58, 76), + (60, 67, 83), (76, 81, 92), (79, 82, 93), (82, 84, 94), + (87, 89, 94), (90, 90, 92), (89, 89, 89), (88, 88, 88), + (87, 87, 87), (86, 86, 86), (85, 85, 85), (85, 85, 85), + (85, 85, 85), (81, 81, 81), (80, 80, 80), (80, 80, 80), + (81, 81, 81), (90, 90, 90), (93, 93, 93), (97, 97, 97), + (103, 103, 103), (104, 106, 106), (104, 109, 111), (107, 113, 116), + (110, 121, 128), (110, 123, 131), (110, 125, 134), (110, 127, 137), + (110, 129, 141), (109, 130, 142), (108, 129, 142), (107, 129, 142), + (104, 126, 142), (95, 118, 142), (93, 116, 142), (92, 115, 142), + (90, 112, 142), (87, 107, 142), (86, 106, 142), (86, 105, 142), + (87, 103, 142), (87, 103, 142), (87, 103, 142), (90, 106, 142), + (92, 107, 142), (95, 109, 141), (98, 110, 138), (99, 109, 134), + (100, 107, 127), (101, 106, 122), (99, 102, 116), (99, 100, 111), + (96, 97, 106), (93, 93, 104), (89, 89, 101), (87, 87, 99), + (78, 77, 92), (76, 74, 91), (74, 72, 90), (68, 66, 89), + (64, 61, 89), (61, 56, 89), (56, 51, 89), (53, 48, 89), + (51, 45, 89), (48, 44, 89), (49, 43, 89), (46, 41, 89), + (46, 41, 89), (44, 40, 92), (40, 36, 97), (37, 34, 101), + (32, 33, 105), (30, 31, 110), (25, 28, 113), (20, 23, 116), + (18, 23, 121), (14, 21, 126), (13, 22, 130), (15, 27, 134), + (16, 30, 139), (17, 31, 142), (17, 31, 142), (17, 29, 142), + (17, 29, 142), (17, 29, 142), (17, 25, 142), (17, 23, 142), + (17, 23, 142), (17, 23, 142), (17, 23, 142), (17, 25, 142), + (17, 27, 141), (15, 25, 136), (13, 22, 128), (10, 21, 121), + (8, 18, 113), (5, 14, 104), (2, 12, 95), (0, 9, 85), + (0, 11, 76), (0, 8, 67), (0, 9, 60), (0, 7, 51), + (0, 5, 43), (0, 3, 34), (0, 0, 27), (0, 0, 18), + (3, 0, 10), (2, 0, 3), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0) + ), + +// 479 Apophysis-040208-115e +((0, 0, 0), (5, 1, 0), (12, 0, 3), (19, 0, 7), + (26, 2, 13), (33, 4, 19), (36, 6, 22), (40, 9, 26), + (54, 15, 36), (61, 17, 41), (68, 20, 46), (74, 22, 51), + (81, 24, 56), (88, 25, 58), (95, 26, 60), (99, 26, 62), + (104, 27, 65), (120, 31, 71), (127, 32, 75), (134, 34, 79), + (138, 35, 79), (142, 36, 80), (142, 36, 78), (142, 36, 76), + (142, 34, 72), (142, 35, 70), (142, 36, 69), (142, 37, 70), + (142, 39, 71), (142, 40, 72), (142, 42, 73), (142, 41, 73), + (142, 37, 70), (142, 33, 65), (140, 30, 62), (138, 28, 59), + (134, 26, 55), (131, 24, 52), (129, 23, 50), (127, 23, 49), + (120, 22, 45), (115, 21, 41), (110, 20, 38), (105, 17, 36), + (101, 15, 35), (98, 14, 34), (95, 14, 33), (88, 13, 28), + (82, 13, 25), (67, 10, 18), (58, 8, 14), (50, 7, 10), + (43, 5, 6), (36, 3, 3), (34, 3, 2), (32, 4, 2), + (22, 5, 0), (18, 5, 0), (15, 5, 0), (13, 4, 0), + (12, 4, 0), (11, 4, 0), (11, 4, 0), (10, 3, 0), + (11, 4, 0), (18, 2, 4), (23, 11, 12), (29, 20, 20), + (32, 24, 24), (36, 29, 29), (41, 38, 38), (48, 48, 48), + (57, 57, 57), (62, 62, 62), (68, 68, 68), (74, 71, 71), + (81, 74, 74), (83, 73, 73), (85, 72, 73), (92, 73, 75), + (98, 74, 76), (113, 77, 83), (120, 78, 87), (127, 80, 91), + (130, 81, 93), (134, 83, 95), (141, 90, 104), (142, 97, 110), + (142, 109, 117), (142, 112, 119), (142, 116, 122), (142, 115, 122), + (142, 114, 122), (142, 114, 123), (142, 110, 121), (142, 104, 118), + (142, 98, 116), (132, 82, 104), (127, 71, 95), (123, 60, 87), + (120, 54, 82), (118, 49, 78), (117, 41, 74), (116, 34, 71), + (115, 30, 72), (114, 30, 76), (113, 31, 80), (113, 31, 80), + (113, 31, 81), (115, 31, 84), (115, 33, 86), (113, 33, 86), + (111, 32, 84), (101, 32, 79), (99, 32, 79), (97, 33, 79), + (90, 31, 71), (85, 28, 66), (80, 24, 61), (73, 20, 53), + (64, 15, 44), (62, 18, 44), (60, 21, 44), (60, 23, 44), + (60, 26, 45), (64, 33, 51), (69, 43, 59), (76, 52, 66), + (83, 60, 74), (92, 76, 86), (93, 79, 87), (94, 82, 88), + (94, 87, 91), (92, 90, 91), (89, 89, 89), (88, 88, 88), + (87, 87, 87), (86, 86, 86), (85, 85, 85), (85, 85, 85), + (85, 85, 85), (81, 81, 81), (80, 80, 80), (80, 80, 80), + (81, 81, 81), (90, 90, 90), (93, 93, 93), (97, 97, 97), + (103, 103, 103), (106, 104, 106), (110, 104, 111), (116, 107, 116), + (128, 110, 127), (131, 110, 130), (134, 110, 133), (137, 110, 136), + (141, 110, 139), (142, 109, 141), (142, 108, 140), (142, 107, 140), + (142, 104, 139), (142, 95, 133), (142, 93, 132), (142, 92, 132), + (142, 90, 129), (142, 87, 125), (142, 86, 125), (142, 86, 123), + (142, 87, 122), (142, 87, 122), (142, 87, 122), (142, 90, 123), + (142, 92, 124), (141, 95, 124), (138, 98, 123), (134, 99, 121), + (127, 100, 116), (122, 101, 113), (116, 99, 108), (111, 99, 105), + (106, 96, 100), (104, 93, 97), (101, 89, 93), (99, 87, 90), + (92, 77, 80), (91, 74, 77), (90, 72, 75), (89, 66, 72), + (89, 61, 66), (89, 56, 62), (89, 51, 58), (89, 48, 56), + (89, 45, 54), (89, 44, 54), (89, 43, 52), (89, 41, 51), + (89, 41, 51), (92, 40, 53), (97, 36, 52), (101, 34, 53), + (105, 32, 57), (110, 30, 58), (113, 25, 57), (116, 20, 55), + (121, 18, 57), (126, 14, 59), (130, 13, 61), (134, 15, 66), + (139, 16, 71), (142, 17, 73), (142, 17, 73), (142, 17, 71), + (142, 17, 71), (142, 17, 71), (142, 17, 67), (142, 17, 65), + (142, 17, 65), (142, 17, 65), (142, 17, 65), (142, 17, 67), + (141, 17, 68), (136, 15, 65), (128, 13, 61), (121, 10, 58), + (113, 8, 53), (104, 5, 48), (95, 2, 44), (85, 0, 38), + (76, 0, 36), (67, 0, 31), (60, 0, 29), (51, 0, 24), + (43, 0, 19), (34, 0, 14), (27, 0, 9), (18, 0, 6), + (10, 0, 0), (3, 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) + ), + +// 480 Apophysis-040208-115g +((0, 0, 0), (5, 3, 0), (12, 1, 0), (19, 0, 1), + (26, 0, 3), (33, 0, 5), (36, 0, 7), (40, 1, 9), + (54, 5, 14), (61, 6, 16), (68, 7, 19), (74, 8, 21), + (81, 9, 24), (88, 8, 22), (95, 8, 21), (99, 8, 21), + (104, 8, 22), (120, 9, 20), (127, 9, 21), (134, 9, 22), + (138, 9, 20), (142, 10, 19), (142, 10, 16), (142, 10, 14), + (142, 8, 8), (142, 11, 9), (142, 14, 10), (142, 15, 11), + (142, 17, 13), (142, 18, 14), (142, 20, 16), (142, 19, 15), + (142, 15, 11), (142, 13, 7), (140, 12, 5), (138, 11, 3), + (134, 11, 1), (131, 11, 0), (129, 11, 0), (127, 12, 0), + (120, 13, 0), (115, 14, 0), (110, 16, 0), (105, 13, 0), + (101, 11, 0), (98, 10, 0), (95, 10, 0), (88, 12, 0), + (82, 13, 0), (67, 12, 0), (58, 12, 0), (50, 12, 0), + (43, 12, 0), (36, 12, 0), (34, 12, 0), (32, 12, 0), + (22, 12, 0), (18, 11, 0), (15, 10, 0), (13, 9, 0), + (12, 8, 0), (11, 7, 0), (11, 7, 0), (10, 7, 0), + (11, 7, 0), (18, 3, 0), (23, 10, 7), (29, 18, 14), + (32, 22, 18), (36, 26, 22), (41, 34, 30), (48, 39, 39), + (57, 46, 46), (62, 50, 50), (68, 55, 55), (74, 60, 57), + (81, 65, 59), (83, 64, 57), (85, 63, 56), (92, 66, 56), + (98, 67, 56), (113, 66, 56), (120, 65, 56), (127, 64, 57), + (130, 65, 58), (134, 67, 59), (141, 69, 64), (142, 76, 71), + (142, 90, 83), (142, 93, 86), (142, 96, 90), (142, 94, 89), + (142, 92, 88), (142, 90, 88), (142, 84, 84), (142, 78, 80), + (142, 72, 75), (132, 58, 64), (127, 48, 54), (123, 38, 44), + (120, 32, 38), (118, 27, 33), (117, 20, 27), (116, 13, 23), + (115, 9, 24), (114, 9, 29), (113, 10, 35), (113, 10, 36), + (113, 10, 38), (115, 10, 40), (115, 12, 42), (113, 12, 42), + (111, 12, 43), (101, 13, 43), (99, 14, 43), (97, 15, 44), + (90, 14, 39), (85, 12, 35), (80, 9, 31), (73, 6, 25), + (64, 3, 18), (62, 6, 19), (60, 10, 21), (60, 12, 22), + (60, 15, 24), (64, 21, 31), (69, 30, 41), (76, 38, 46), + (83, 45, 55), (92, 59, 67), (93, 62, 68), (94, 65, 70), + (94, 70, 77), (92, 73, 73), (89, 73, 73), (88, 72, 72), + (87, 71, 71), (86, 70, 70), (85, 69, 69), (85, 69, 69), + (85, 69, 69), (81, 66, 66), (80, 65, 65), (80, 65, 65), + (81, 66, 66), (90, 74, 74), (93, 76, 76), (97, 79, 79), + (103, 84, 84), (106, 85, 95), (111, 84, 103), (116, 86, 103), + (128, 87, 112), (131, 86, 114), (134, 86, 116), (137, 85, 118), + (141, 84, 119), (142, 83, 119), (142, 82, 117), (142, 81, 118), + (142, 78, 115), (142, 69, 103), (142, 67, 101), (142, 66, 100), + (142, 64, 96), (142, 61, 89), (142, 60, 89), (142, 60, 86), + (142, 61, 83), (142, 61, 83), (142, 61, 83), (142, 64, 87), + (142, 66, 87), (141, 69, 90), (138, 73, 91), (134, 75, 92), + (127, 77, 90), (122, 79, 89), (116, 78, 85), (111, 79, 82), + (106, 77, 80), (104, 74, 74), (101, 71, 71), (99, 69, 69), + (92, 64, 60), (91, 62, 58), (90, 61, 56), (89, 53, 50), + (89, 51, 45), (89, 47, 40), (89, 43, 35), (89, 40, 32), + (89, 37, 29), (89, 34, 28), (89, 36, 27), (89, 33, 25), + (89, 33, 25), (92, 30, 23), (97, 25, 18), (101, 20, 15), + (105, 13, 13), (110, 10, 10), (113, 4, 5), (116, 0, 1), + (121, 0, 3), (126, 0, 5), (130, 0, 7), (134, 0, 11), + (139, 0, 13), (142, 0, 13), (142, 0, 13), (142, 0, 11), + (142, 0, 11), (142, 0, 11), (142, 0, 6), (142, 0, 4), + (142, 0, 4), (142, 0, 4), (142, 0, 4), (142, 0, 6), + (141, 0, 9), (136, 0, 9), (128, 0, 7), (121, 0, 9), + (113, 0, 8), (104, 0, 8), (95, 0, 9), (85, 0, 8), + (76, 0, 10), (67, 0, 7), (60, 0, 8), (51, 0, 6), + (43, 0, 4), (34, 0, 2), (27, 0, 0), (18, 0, 0), + (10, 3, 0), (3, 2, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0) + ), + +// 481 Apophysis-040208-115h +((0, 0, 0), (5, 5, 0), (12, 5, 0), (19, 6, 0), + (26, 7, 0), (33, 8, 0), (36, 8, 0), (40, 8, 1), + (54, 15, 5), (61, 17, 6), (68, 19, 7), (74, 21, 8), + (81, 23, 9), (88, 26, 8), (95, 29, 8), (99, 30, 8), + (104, 32, 8), (120, 42, 9), (127, 44, 9), (134, 46, 9), + (138, 50, 9), (142, 54, 10), (142, 56, 10), (142, 58, 10), + (142, 61, 8), (142, 64, 9), (142, 67, 10), (142, 68, 11), + (142, 69, 13), (142, 69, 14), (142, 70, 16), (142, 70, 15), + (142, 68, 11), (142, 68, 7), (140, 67, 5), (138, 66, 3), + (134, 64, 1), (131, 63, 0), (129, 63, 0), (127, 63, 0), + (120, 60, 0), (115, 60, 0), (110, 60, 0), (105, 56, 0), + (101, 52, 0), (98, 49, 0), (95, 47, 0), (88, 47, 0), + (82, 46, 0), (67, 39, 0), (58, 35, 0), (50, 31, 0), + (43, 28, 0), (36, 26, 0), (34, 25, 0), (32, 24, 0), + (22, 20, 0), (18, 17, 0), (14, 15, 0), (12, 13, 0), + (11, 12, 0), (10, 11, 0), (10, 11, 0), (9, 10, 0), + (10, 11, 0), (18, 10, 0), (23, 17, 7), (29, 24, 14), + (32, 27, 18), (36, 31, 22), (41, 38, 30), (48, 42, 39), + (57, 50, 46), (62, 55, 50), (68, 60, 55), (74, 66, 57), + (81, 73, 59), (83, 73, 57), (85, 74, 56), (92, 80, 56), + (98, 84, 56), (113, 89, 56), (120, 90, 56), (127, 92, 57), + (130, 94, 58), (134, 96, 59), (141, 100, 64), (142, 104, 71), + (142, 113, 83), (142, 115, 86), (142, 117, 90), (142, 115, 89), + (142, 113, 88), (142, 111, 88), (142, 107, 84), (142, 101, 78), + (142, 96, 72), (132, 81, 58), (127, 73, 48), (123, 66, 38), + (120, 61, 32), (118, 57, 27), (117, 52, 20), (116, 44, 13), + (115, 37, 9), (114, 31, 9), (113, 25, 10), (113, 24, 10), + (113, 23, 10), (115, 22, 10), (115, 24, 12), (113, 22, 12), + (111, 20, 12), (101, 18, 13), (99, 18, 14), (97, 19, 15), + (90, 19, 14), (85, 18, 12), (80, 14, 9), (73, 13, 6), + (64, 12, 3), (62, 15, 6), (60, 19, 10), (60, 21, 12), + (60, 24, 15), (64, 28, 21), (69, 34, 30), (76, 45, 38), + (83, 50, 45), (92, 64, 59), (93, 68, 62), (94, 72, 65), + (94, 72, 70), (92, 80, 73), (89, 79, 73), (88, 78, 72), + (87, 77, 71), (86, 76, 70), (85, 75, 69), (85, 75, 69), + (85, 75, 69), (81, 72, 66), (80, 71, 65), (80, 71, 65), + (81, 72, 66), (90, 80, 74), (93, 83, 76), (97, 86, 79), + (103, 91, 84), (106, 85, 87), (111, 84, 92), (116, 86, 91), + (128, 87, 96), (131, 86, 96), (134, 86, 97), (137, 85, 97), + (141, 84, 96), (142, 83, 96), (142, 82, 93), (142, 81, 93), + (142, 78, 90), (142, 69, 74), (142, 67, 72), (142, 66, 70), + (142, 64, 65), (142, 65, 61), (142, 64, 60), (142, 67, 60), + (142, 72, 61), (142, 72, 61), (142, 72, 61), (142, 72, 64), + (142, 75, 66), (141, 76, 69), (138, 80, 73), (134, 82, 75), + (127, 83, 77), (122, 86, 79), (116, 86, 78), (111, 88, 79), + (106, 86, 77), (104, 86, 74), (101, 83, 71), (99, 81, 69), + (92, 77, 60), (91, 75, 58), (90, 74, 56), (89, 69, 50), + (89, 68, 45), (89, 67, 40), (89, 64, 35), (89, 62, 32), + (89, 61, 29), (89, 58, 28), (89, 61, 27), (89, 59, 25), + (89, 59, 25), (92, 57, 23), (97, 56, 18), (101, 53, 15), + (105, 49, 13), (110, 50, 10), (113, 45, 4), (116, 44, 0), + (121, 46, 0), (126, 46, 0), (130, 45, 0), (134, 42, 0), + (139, 41, 0), (142, 45, 0), (142, 45, 0), (142, 45, 0), + (142, 45, 0), (142, 45, 0), (142, 49, 0), (142, 52, 0), + (142, 52, 0), (142, 52, 0), (142, 52, 0), (142, 49, 0), + (141, 47, 0), (136, 45, 0), (128, 44, 0), (121, 40, 0), + (113, 37, 0), (104, 33, 0), (95, 28, 0), (85, 25, 0), + (76, 20, 0), (67, 20, 0), (60, 16, 0), (51, 14, 0), + (43, 12, 0), (34, 11, 0), (27, 10, 0), (18, 7, 0), + (10, 7, 0), (2, 3, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0) + ), + +// 482 Apophysis-040208-115i +((0, 0, 0), (3, 5, 0), (11, 9, 0), (19, 13, 0), + (26, 16, 0), (33, 19, 0), (36, 20, 0), (40, 22, 1), + (54, 32, 5), (61, 36, 6), (68, 40, 7), (74, 43, 8), + (81, 47, 9), (88, 53, 8), (95, 60, 8), (99, 62, 8), + (104, 65, 8), (120, 81, 9), (127, 85, 9), (134, 90, 9), + (138, 95, 9), (142, 100, 10), (142, 102, 10), (142, 105, 10), + (142, 108, 8), (142, 110, 9), (142, 113, 10), (142, 113, 11), + (142, 114, 13), (142, 114, 14), (142, 115, 16), (142, 114, 15), + (142, 114, 11), (142, 115, 7), (140, 114, 5), (138, 113, 3), + (134, 111, 1), (131, 109, 0), (129, 108, 0), (127, 108, 0), + (120, 102, 0), (115, 100, 0), (110, 99, 0), (105, 93, 0), + (101, 87, 0), (98, 84, 0), (95, 81, 0), (88, 78, 0), + (82, 75, 0), (67, 62, 0), (58, 55, 0), (50, 49, 0), + (41, 42, 0), (33, 36, 0), (30, 34, 0), (27, 32, 0), + (15, 22, 0), (11, 18, 0), (8, 15, 0), (7, 13, 0), + (7, 12, 0), (6, 11, 0), (6, 11, 0), (5, 10, 0), + (6, 11, 0), (18, 16, 0), (23, 22, 7), (28, 29, 14), + (31, 32, 18), (35, 36, 22), (39, 41, 30), (48, 45, 39), + (57, 54, 46), (62, 59, 50), (68, 65, 55), (74, 73, 57), + (80, 81, 59), (82, 82, 57), (85, 84, 56), (91, 92, 56), + (97, 98, 56), (113, 109, 56), (120, 112, 56), (127, 116, 57), + (130, 119, 58), (134, 123, 59), (141, 127, 64), (142, 129, 71), + (142, 134, 83), (142, 134, 86), (142, 135, 90), (142, 133, 89), + (142, 132, 88), (142, 130, 88), (142, 127, 84), (142, 124, 78), + (142, 121, 72), (132, 107, 58), (127, 101, 48), (123, 96, 38), + (120, 92, 32), (118, 89, 27), (117, 86, 20), (116, 80, 13), + (115, 74, 9), (114, 67, 9), (113, 61, 10), (113, 60, 10), + (113, 60, 10), (115, 59, 10), (115, 60, 12), (113, 57, 12), + (111, 55, 12), (101, 49, 13), (99, 48, 14), (97, 47, 15), + (90, 45, 14), (85, 43, 12), (80, 39, 9), (73, 37, 6), + (64, 33, 3), (62, 34, 6), (60, 36, 10), (60, 37, 12), + (60, 39, 15), (64, 43, 21), (69, 48, 30), (76, 58, 38), + (83, 63, 45), (92, 75, 59), (93, 78, 62), (94, 82, 65), + (94, 81, 70), (92, 87, 73), (89, 85, 73), (88, 84, 72), + (87, 83, 71), (86, 82, 70), (85, 81, 69), (85, 81, 69), + (85, 81, 69), (81, 77, 66), (80, 76, 65), (80, 76, 65), + (81, 77, 66), (90, 86, 74), (93, 89, 76), (97, 92, 79), + (103, 98, 84), (106, 90, 85), (111, 85, 84), (116, 91, 86), + (128, 92, 87), (131, 92, 86), (134, 92, 86), (137, 91, 85), + (141, 91, 84), (142, 91, 83), (142, 92, 82), (142, 90, 81), + (142, 89, 78), (142, 90, 69), (142, 89, 67), (142, 89, 66), + (142, 90, 64), (142, 93, 61), (142, 93, 60), (142, 95, 60), + (142, 100, 61), (142, 100, 61), (142, 100, 61), (142, 99, 64), + (142, 101, 66), (141, 103, 69), (138, 103, 73), (134, 102, 75), + (127, 101, 77), (122, 101, 79), (116, 99, 78), (111, 100, 79), + (106, 96, 77), (104, 96, 74), (101, 93, 71), (99, 91, 69), + (92, 88, 60), (91, 87, 58), (90, 86, 56), (89, 82, 50), + (89, 84, 45), (89, 84, 40), (89, 83, 35), (89, 82, 32), + (89, 82, 29), (89, 80, 28), (89, 83, 27), (89, 81, 25), + (89, 81, 25), (92, 81, 23), (97, 84, 18), (101, 84, 15), + (105, 82, 13), (110, 85, 10), (113, 84, 4), (116, 85, 0), + (121, 89, 0), (126, 90, 0), (130, 91, 0), (134, 89, 0), + (139, 90, 0), (142, 95, 0), (142, 95, 0), (142, 95, 0), + (142, 95, 0), (142, 95, 0), (142, 99, 0), (142, 102, 0), + (142, 102, 0), (142, 102, 0), (142, 102, 0), (142, 99, 0), + (141, 96, 0), (136, 93, 0), (128, 89, 0), (121, 83, 0), + (113, 77, 0), (104, 69, 0), (95, 61, 0), (85, 55, 0), + (76, 47, 0), (67, 43, 0), (60, 37, 0), (51, 32, 0), + (43, 28, 0), (34, 23, 0), (27, 20, 0), (18, 13, 0), + (9, 10, 0), (1, 3, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0) + ), + +// 483 Apophysis-040208-115j +((0, 0, 0), (0, 5, 1), (3, 12, 0), (7, 19, 0), + (11, 26, 0), (16, 33, 0), (18, 36, 0), (21, 40, 1), + (30, 54, 5), (34, 61, 6), (39, 68, 7), (43, 74, 8), + (47, 81, 9), (48, 88, 8), (50, 95, 8), (52, 99, 8), + (54, 104, 8), (57, 120, 9), (60, 127, 9), (63, 134, 9), + (63, 138, 9), (63, 142, 10), (60, 142, 10), (58, 142, 10), + (52, 142, 8), (50, 142, 9), (49, 142, 10), (50, 142, 11), + (51, 142, 13), (52, 142, 14), (54, 142, 16), (53, 142, 15), + (50, 142, 11), (45, 142, 7), (42, 140, 5), (39, 138, 3), + (35, 134, 1), (32, 131, 0), (30, 129, 0), (29, 127, 0), + (28, 120, 0), (24, 115, 0), (20, 110, 0), (20, 105, 0), + (21, 101, 0), (21, 98, 0), (22, 95, 0), (17, 88, 0), + (13, 82, 0), (10, 67, 0), (7, 58, 0), (5, 50, 0), + (2, 43, 0), (0, 36, 0), (0, 34, 0), (0, 32, 1), + (0, 22, 4), (0, 18, 4), (0, 15, 5), (0, 13, 4), + (0, 12, 4), (0, 11, 3), (0, 11, 3), (0, 10, 3), + (0, 11, 3), (3, 18, 0), (9, 23, 7), (15, 29, 14), + (18, 32, 18), (22, 36, 22), (30, 41, 30), (42, 48, 39), + (49, 57, 46), (54, 62, 50), (59, 68, 55), (59, 74, 57), + (60, 81, 59), (59, 83, 57), (59, 85, 56), (58, 92, 56), + (59, 98, 56), (64, 113, 56), (68, 120, 56), (73, 127, 57), + (74, 130, 58), (76, 134, 59), (84, 141, 64), (90, 142, 71), + (96, 142, 83), (98, 142, 86), (101, 142, 90), (101, 142, 89), + (102, 142, 88), (104, 142, 88), (103, 142, 84), (101, 142, 78), + (99, 142, 72), (89, 132, 58), (80, 127, 48), (72, 123, 38), + (67, 120, 32), (63, 118, 27), (59, 117, 20), (57, 116, 13), + (58, 115, 9), (64, 114, 9), (70, 113, 10), (71, 113, 10), + (72, 113, 10), (75, 115, 10), (75, 115, 12), (76, 113, 12), + (76, 111, 12), (71, 101, 13), (71, 99, 14), (71, 97, 15), + (64, 90, 14), (59, 85, 12), (55, 80, 9), (47, 73, 6), + (38, 64, 3), (37, 62, 6), (37, 60, 10), (38, 60, 12), + (39, 60, 15), (45, 64, 21), (54, 69, 30), (59, 76, 38), + (68, 83, 45), (78, 92, 59), (78, 93, 62), (79, 94, 65), + (85, 94, 70), (79, 92, 73), (78, 89, 73), (77, 88, 72), + (76, 87, 71), (75, 86, 70), (74, 85, 69), (74, 85, 69), + (74, 85, 69), (71, 81, 66), (70, 80, 65), (70, 80, 65), + (71, 81, 66), (79, 90, 74), (82, 93, 76), (85, 97, 79), + (90, 103, 84), (102, 106, 85), (111, 110, 84), (113, 116, 86), + (126, 128, 87), (129, 131, 86), (132, 134, 86), (135, 137, 85), + (138, 141, 84), (139, 142, 83), (137, 142, 82), (138, 142, 81), + (137, 142, 78), (127, 142, 69), (126, 142, 67), (126, 142, 66), + (122, 142, 64), (116, 142, 61), (116, 142, 60), (113, 142, 60), + (110, 142, 61), (110, 142, 61), (110, 142, 61), (113, 142, 64), + (113, 142, 66), (115, 141, 69), (113, 138, 73), (111, 134, 75), + (107, 127, 77), (103, 122, 79), (98, 116, 78), (93, 111, 79), + (89, 106, 77), (84, 104, 74), (81, 101, 71), (79, 99, 69), + (66, 92, 60), (64, 91, 58), (62, 90, 56), (59, 89, 50), + (54, 89, 45), (49, 89, 40), (45, 89, 35), (43, 89, 32), + (41, 89, 29), (42, 89, 28), (38, 89, 27), (37, 89, 25), + (37, 89, 25), (39, 92, 23), (37, 97, 18), (39, 101, 15), + (43, 105, 13), (43, 110, 10), (42, 113, 4), (40, 116, 0), + (42, 121, 0), (46, 126, 0), (50, 130, 0), (56, 134, 0), + (60, 139, 0), (59, 142, 0), (59, 142, 0), (59, 142, 0), + (59, 142, 0), (59, 142, 0), (54, 142, 0), (52, 142, 0), + (52, 142, 0), (52, 142, 0), (52, 142, 0), (54, 142, 0), + (56, 141, 0), (54, 136, 0), (49, 128, 0), (48, 121, 0), + (45, 113, 0), (43, 104, 0), (41, 95, 0), (36, 85, 0), + (35, 76, 0), (29, 67, 0), (28, 60, 0), (23, 51, 0), + (18, 43, 0), (13, 34, 0), (9, 27, 0), (6, 18, 0), + (0, 10, 0), (0, 3, 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) + ), + +// 484 Apophysis-040208-115k +((81, 81, 81), (81, 81, 81), (78, 78, 78), (75, 75, 75), + (72, 72, 72), (70, 70, 70), (67, 67, 67), (65, 65, 65), + (51, 51, 51), (44, 44, 44), (38, 38, 38), (33, 33, 33), + (28, 28, 28), (23, 23, 23), (19, 19, 19), (19, 19, 19), + (19, 19, 19), (12, 12, 12), (6, 6, 6), (1, 1, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (1, 1, 1), (6, 6, 6), (12, 12, 12), (18, 18, 18), + (24, 24, 24), (24, 24, 24), (24, 24, 24), (22, 22, 22), + (19, 19, 19), (14, 14, 14), (8, 8, 8), (3, 3, 3), + (1, 1, 1), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (2, 2, 2), (5, 5, 5), (8, 8, 8), + (12, 12, 12), (13, 13, 13), (14, 14, 14), (12, 12, 12), + (12, 12, 12), (12, 12, 12), (10, 10, 10), (8, 8, 8), + (11, 11, 11), (14, 14, 14), (16, 16, 16), (19, 19, 19), + (33, 33, 33), (35, 35, 35), (38, 38, 38), (39, 39, 39), + (40, 40, 40), (40, 40, 40), (40, 40, 40), (38, 38, 38), + (38, 38, 38), (38, 38, 38), (39, 39, 39), (40, 40, 40), + (40, 40, 40), (40, 40, 40), (40, 40, 40), (40, 40, 40), + (38, 38, 38), (33, 33, 33), (28, 28, 28), (22, 22, 22), + (17, 17, 17), (14, 14, 14), (12, 12, 12), (12, 12, 12), + (8, 8, 8), (8, 8, 8), (13, 13, 13), (19, 19, 19), + (20, 20, 20), (22, 22, 22), (28, 28, 28), (30, 30, 30), + (35, 35, 35), (35, 35, 35), (35, 35, 35), (35, 35, 35), + (35, 35, 35), (35, 35, 35), (35, 35, 35), (38, 38, 38), + (40, 40, 40), (56, 56, 56), (64, 64, 64), (72, 72, 72), + (76, 76, 76), (81, 81, 81), (84, 84, 84), (86, 86, 86), + (89, 89, 89), (89, 89, 89), (89, 89, 89), (89, 89, 89), + (89, 89, 89), (89, 89, 89), (91, 91, 91), (97, 97, 97), + (102, 102, 102), (118, 118, 118), (122, 122, 122), (126, 126, 126), + (132, 132, 132), (137, 137, 137), (142, 142, 142), (146, 146, 146), + (156, 156, 156), (160, 160, 160), (164, 164, 164), (166, 166, 166), + (169, 169, 169), (172, 172, 172), (180, 180, 180), (185, 185, 185), + (190, 190, 190), (199, 199, 199), (200, 200, 200), (201, 201, 201), + (206, 206, 206), (209, 209, 209), (206, 206, 206), (201, 201, 201), + (190, 190, 190), (185, 185, 185), (180, 180, 180), (176, 176, 176), + (172, 172, 172), (169, 169, 169), (169, 169, 169), (169, 169, 169), + (169, 169, 169), (164, 164, 164), (161, 161, 161), (158, 158, 158), + (156, 156, 156), (148, 148, 148), (146, 146, 146), (139, 139, 139), + (132, 132, 132), (129, 129, 129), (126, 126, 126), (121, 121, 121), + (118, 118, 118), (113, 113, 113), (111, 111, 111), (113, 113, 113), + (118, 118, 118), (116, 116, 116), (113, 113, 113), (111, 111, 111), + (111, 111, 111), (105, 105, 105), (97, 97, 97), (91, 91, 91), + (84, 84, 84), (84, 84, 84), (84, 84, 84), (84, 84, 84), + (84, 84, 84), (86, 86, 86), (89, 89, 89), (89, 89, 89), + (89, 89, 89), (86, 86, 86), (84, 84, 84), (86, 86, 86), + (86, 86, 86), (84, 84, 84), (84, 84, 84), (81, 81, 81), + (75, 75, 75), (75, 75, 75), (75, 75, 75), (79, 79, 79), + (79, 79, 79), (79, 79, 79), (81, 81, 81), (81, 81, 81), + (79, 79, 79), (79, 79, 79), (75, 75, 75), (72, 72, 72), + (72, 72, 72), (70, 70, 70), (65, 65, 65), (65, 65, 65), + (63, 63, 63), (65, 65, 65), (67, 67, 67), (72, 72, 72), + (72, 72, 72), (79, 79, 79), (81, 81, 81), (81, 81, 81), + (81, 81, 81), (81, 81, 81), (81, 81, 81), (75, 75, 75), + (72, 72, 72), (72, 72, 72), (75, 75, 75), (79, 79, 79), + (81, 81, 81), (84, 84, 84), (86, 86, 86), (89, 89, 89), + (89, 89, 89), (89, 89, 89), (89, 89, 89), (89, 89, 89), + (91, 91, 91), (91, 91, 91), (89, 89, 89), (86, 86, 86), + (86, 86, 86), (84, 84, 84), (81, 81, 81), (72, 72, 72), + (67, 67, 67), (65, 65, 65), (59, 59, 59), (56, 56, 56), + (59, 59, 59), (65, 65, 65), (70, 70, 70), (72, 72, 72), + (81, 81, 81), (89, 89, 89), (97, 97, 97), (102, 102, 102), + (102, 102, 102), (105, 105, 105), (105, 105, 105), (102, 102, 102), + (97, 97, 97), (95, 95, 95), (95, 95, 95), (95, 95, 95), + (91, 91, 91), (89, 89, 89), (81, 81, 81), (81, 81, 81) + ), + +// 485 A_Bit_Confused +((219, 140, 152), (243, 165, 171), (237, 167, 192), (232, 169, 213), + (213, 157, 212), (194, 146, 212), (184, 134, 199), (175, 122, 187), + (131, 84, 156), (111, 64, 145), (91, 44, 135), (78, 37, 115), + (66, 30, 96), (54, 35, 90), (42, 40, 84), (39, 42, 86), + (36, 44, 89), (39, 60, 127), (53, 70, 136), (68, 80, 145), + (88, 88, 136), (108, 97, 127), (117, 99, 126), (127, 101, 126), + (171, 102, 108), (184, 89, 87), (197, 77, 67), (192, 76, 60), + (188, 76, 54), (180, 74, 52), (172, 72, 51), (156, 53, 55), + (136, 41, 55), (106, 31, 53), (100, 31, 50), (94, 31, 47), + (105, 24, 40), (116, 17, 34), (126, 15, 28), (136, 13, 23), + (172, 26, 16), (180, 31, 22), (188, 36, 28), (187, 43, 26), + (186, 51, 25), (186, 57, 28), (187, 63, 32), (187, 71, 48), + (189, 75, 73), (178, 92, 113), (181, 108, 131), (184, 124, 150), + (199, 125, 164), (215, 126, 179), (222, 124, 180), (230, 122, 181), + (243, 116, 191), (235, 110, 180), (228, 105, 170), (204, 103, 155), + (181, 102, 140), (176, 99, 140), (171, 96, 141), (167, 93, 138), + (174, 85, 140), (167, 84, 114), (172, 81, 104), (178, 79, 94), + (185, 77, 92), (193, 75, 90), (205, 57, 81), (205, 47, 70), + (201, 33, 55), (190, 35, 59), (179, 38, 64), (157, 39, 66), + (136, 40, 69), (128, 42, 69), (121, 44, 70), (118, 46, 73), + (116, 46, 73), (106, 39, 59), (98, 38, 58), (90, 37, 58), + (88, 36, 59), (86, 35, 61), (79, 34, 62), (74, 31, 59), + (56, 21, 69), (47, 19, 76), (39, 17, 84), (35, 16, 85), + (31, 16, 86), (25, 16, 84), (23, 15, 79), (23, 17, 72), + (27, 17, 68), (48, 19, 69), (68, 26, 73), (89, 34, 78), + (98, 42, 84), (108, 51, 91), (113, 65, 108), (112, 75, 130), + (110, 81, 154), (119, 85, 156), (129, 90, 159), (135, 93, 162), + (142, 97, 165), (150, 103, 160), (154, 101, 157), (158, 93, 140), + (170, 87, 136), (221, 85, 150), (232, 87, 157), (243, 90, 165), + (253, 94, 172), (254, 108, 182), (254, 117, 187), (254, 130, 182), + (224, 144, 161), (201, 145, 143), (179, 146, 125), (170, 144, 115), + (161, 142, 105), (147, 145, 93), (130, 153, 84), (119, 150, 83), + (117, 147, 76), (119, 110, 71), (117, 107, 72), (115, 104, 73), + (112, 96, 75), (119, 101, 66), (130, 96, 57), (138, 87, 46), + (125, 54, 37), (107, 47, 45), (90, 41, 53), (86, 44, 60), + (83, 47, 68), (77, 59, 78), (74, 62, 84), (70, 58, 93), + (54, 54, 95), (30, 65, 88), (25, 70, 82), (21, 76, 76), + (19, 82, 67), (14, 81, 56), (14, 76, 45), (14, 72, 33), + (27, 63, 20), (32, 60, 19), (37, 58, 18), (48, 57, 22), + (61, 52, 21), (81, 44, 28), (106, 42, 33), (134, 49, 40), + (157, 67, 54), (194, 109, 75), (202, 115, 81), (210, 121, 88), + (222, 137, 110), (221, 152, 137), (209, 173, 156), (194, 198, 174), + (180, 218, 197), (180, 214, 204), (180, 211, 212), (177, 210, 228), + (169, 217, 236), (174, 231, 232), (175, 231, 210), (176, 216, 194), + (181, 206, 190), (173, 196, 190), (176, 191, 188), (171, 172, 163), + (156, 141, 139), (141, 112, 124), (124, 98, 125), (121, 94, 135), + (122, 84, 135), (123, 81, 134), (124, 79, 133), (119, 83, 139), + (128, 88, 144), (130, 95, 147), (120, 98, 148), (112, 105, 143), + (93, 106, 141), (85, 101, 135), (87, 95, 124), (80, 81, 109), + (76, 72, 89), (70, 65, 76), (62, 61, 69), (65, 61, 66), + (71, 65, 63), (85, 70, 62), (110, 79, 66), (134, 95, 88), + (153, 112, 117), (157, 127, 138), (150, 131, 161), (140, 121, 169), + (131, 111, 185), (133, 112, 200), (129, 104, 199), (121, 99, 196), + (103, 81, 174), (76, 52, 154), (57, 43, 131), (50, 29, 104), + (51, 26, 80), (63, 28, 56), (66, 21, 38), (64, 22, 25), + (62, 18, 20), (57, 15, 20), (61, 15, 21), (60, 14, 22), + (55, 14, 25), (47, 16, 30), (38, 19, 41), (33, 30, 49), + (32, 37, 53), (29, 41, 53), (23, 41, 46), (17, 36, 45), + (13, 37, 40), (17, 37, 37), (21, 37, 35), (21, 33, 27), + (20, 27, 20), (25, 24, 11), (34, 27, 8), (49, 35, 5), + (65, 39, 8), (72, 43, 12), (89, 48, 13), (106, 54, 14), + (122, 62, 14), (139, 59, 12), (144, 52, 15), (149, 42, 18), + (156, 34, 18), (163, 34, 27), (170, 35, 32), (177, 39, 45), + (182, 50, 60), (187, 68, 76), (196, 93, 106), (207, 120, 131) + ), + +// 486 Afternoon_Shadows +((86, 73, 63), (76, 68, 62), (72, 65, 60), (68, 63, 58), + (62, 58, 54), (56, 53, 50), (49, 47, 46), (43, 41, 43), + (29, 32, 34), (25, 29, 29), (21, 26, 25), (17, 20, 19), + (13, 14, 13), (10, 10, 9), (8, 7, 6), (8, 6, 6), + (8, 6, 6), (11, 10, 11), (18, 18, 16), (26, 26, 21), + (37, 36, 29), (49, 47, 37), (55, 53, 41), (62, 60, 45), + (88, 82, 63), (97, 88, 70), (106, 94, 77), (114, 99, 77), + (122, 104, 78), (124, 104, 79), (126, 105, 80), (130, 106, 83), + (132, 109, 85), (133, 113, 89), (130, 110, 91), (127, 108, 93), + (119, 102, 88), (111, 96, 84), (106, 91, 81), (101, 86, 78), + (77, 64, 65), (65, 55, 59), (53, 47, 53), (46, 45, 53), + (40, 43, 53), (39, 46, 56), (39, 49, 59), (45, 58, 65), + (54, 69, 75), (80, 93, 98), (93, 105, 108), (107, 118, 119), + (117, 125, 125), (127, 133, 132), (132, 137, 136), (137, 142, 140), + (157, 160, 151), (168, 168, 156), (180, 176, 162), (191, 185, 169), + (203, 195, 176), (207, 198, 177), (212, 201, 179), (217, 204, 182), + (219, 204, 184), (216, 206, 182), (212, 202, 178), (208, 199, 174), + (204, 194, 171), (200, 190, 168), (192, 184, 162), (181, 176, 154), + (159, 156, 139), (151, 148, 132), (143, 141, 126), (140, 138, 122), + (138, 135, 118), (137, 132, 115), (136, 130, 113), (135, 126, 110), + (133, 124, 105), (120, 111, 95), (113, 102, 88), (106, 93, 81), + (104, 89, 77), (103, 85, 74), (105, 83, 68), (110, 83, 67), + (126, 94, 75), (135, 102, 82), (144, 111, 89), (145, 113, 92), + (147, 116, 95), (145, 116, 98), (139, 112, 97), (132, 106, 90), + (124, 98, 84), (109, 81, 71), (108, 81, 70), (108, 81, 70), + (108, 83, 72), (109, 85, 74), (112, 90, 81), (117, 96, 89), + (126, 107, 100), (128, 108, 101), (131, 110, 103), (132, 111, 102), + (133, 113, 102), (139, 119, 106), (145, 127, 113), (153, 137, 124), + (167, 150, 135), (196, 178, 158), (202, 184, 164), (208, 191, 170), + (218, 200, 179), (224, 207, 184), (228, 212, 187), (228, 211, 185), + (222, 204, 180), (216, 198, 175), (211, 192, 170), (208, 188, 168), + (206, 185, 167), (200, 178, 163), (192, 168, 157), (182, 160, 148), + (171, 147, 134), (149, 121, 108), (143, 115, 103), (137, 109, 98), + (124, 97, 86), (112, 84, 76), (101, 75, 69), (91, 64, 63), + (72, 53, 53), (65, 47, 48), (59, 41, 44), (57, 39, 43), + (56, 38, 42), (55, 37, 42), (55, 36, 41), (55, 36, 40), + (54, 35, 42), (45, 35, 43), (43, 33, 42), (41, 32, 41), + (39, 30, 39), (34, 27, 35), (34, 26, 36), (35, 26, 37), + (41, 30, 41), (42, 32, 42), (44, 34, 44), (47, 37, 45), + (49, 41, 47), (51, 44, 49), (51, 43, 48), (50, 41, 47), + (49, 38, 46), (46, 32, 42), (45, 31, 41), (45, 31, 41), + (43, 29, 39), (43, 29, 36), (42, 30, 36), (42, 30, 37), + (44, 31, 38), (43, 30, 37), (42, 29, 36), (40, 26, 35), + (37, 23, 33), (31, 19, 29), (27, 14, 23), (22, 12, 19), + (20, 11, 15), (19, 10, 13), (18, 9, 10), (17, 8, 8), + (17, 7, 7), (17, 7, 8), (17, 7, 7), (16, 6, 6), + (15, 7, 7), (15, 7, 7), (16, 8, 8), (17, 8, 9), + (17, 9, 8), (18, 8, 9), (17, 8, 10), (17, 10, 12), + (18, 13, 15), (21, 19, 20), (28, 28, 29), (38, 40, 39), + (50, 52, 50), (62, 65, 59), (76, 78, 69), (88, 89, 78), + (101, 100, 88), (115, 110, 95), (124, 121, 103), (136, 134, 113), + (149, 146, 125), (162, 159, 136), (175, 171, 147), (188, 183, 157), + (196, 190, 164), (200, 194, 168), (201, 190, 165), (193, 182, 157), + (181, 172, 147), (168, 161, 137), (155, 149, 127), (142, 137, 117), + (130, 126, 107), (118, 114, 99), (106, 104, 92), (94, 93, 84), + (82, 80, 73), (69, 67, 62), (56, 54, 51), (43, 41, 39), + (31, 29, 30), (23, 19, 20), (18, 13, 16), (19, 11, 16), + (25, 16, 21), (34, 22, 26), (46, 30, 32), (58, 38, 35), + (69, 47, 38), (76, 54, 41), (81, 62, 42), (86, 67, 42), + (91, 68, 43), (95, 70, 45), (97, 72, 47), (101, 75, 52), + (109, 77, 51), (115, 81, 51), (120, 81, 51), (121, 85, 52), + (119, 89, 52), (122, 92, 53), (127, 97, 56), (125, 97, 57), + (116, 91, 58), (110, 84, 59), (105, 81, 59), (104, 76, 61), + (100, 72, 61), (93, 71, 62), (84, 66, 60), (83, 69, 61) + ), + +// 487 Air +((87, 148, 201), (88, 148, 200), (88, 148, 200), (88, 148, 200), + (89, 149, 201), (91, 151, 203), (92, 153, 204), (94, 155, 205), + (117, 160, 206), (135, 162, 209), (153, 165, 213), (166, 173, 219), + (179, 181, 225), (190, 183, 225), (202, 185, 226), (202, 183, 226), + (202, 181, 226), (187, 183, 230), (177, 183, 229), (167, 184, 229), + (149, 177, 224), (131, 171, 219), (123, 169, 217), (116, 167, 215), + (102, 163, 212), (100, 162, 212), (99, 161, 212), (98, 160, 211), + (98, 160, 210), (98, 159, 209), (98, 159, 209), (98, 158, 209), + (107, 156, 206), (126, 140, 192), (122, 130, 180), (119, 120, 168), + (112, 110, 157), (105, 100, 146), (101, 95, 141), (98, 90, 136), + (82, 70, 118), (72, 69, 117), (63, 69, 117), (70, 73, 124), + (77, 77, 131), (83, 80, 135), (89, 84, 140), (88, 93, 147), + (94, 104, 159), (110, 126, 179), (114, 131, 184), (119, 136, 190), + (112, 138, 190), (105, 141, 190), (102, 138, 186), (100, 135, 182), + (90, 115, 161), (81, 109, 156), (72, 104, 152), (74, 100, 148), + (76, 97, 145), (75, 95, 143), (74, 94, 141), (64, 93, 142), + (55, 95, 143), (49, 95, 147), (46, 91, 143), (44, 88, 139), + (41, 84, 134), (39, 81, 129), (34, 67, 112), (27, 54, 95), + (12, 30, 63), (8, 23, 54), (4, 16, 46), (3, 13, 40), + (3, 10, 34), (4, 12, 32), (6, 14, 30), (7, 22, 29), + (8, 30, 31), (9, 39, 47), (13, 50, 58), (17, 61, 69), + (20, 67, 75), (23, 74, 82), (32, 90, 95), (39, 93, 113), + (47, 105, 143), (52, 112, 154), (58, 119, 166), (60, 119, 168), + (63, 119, 170), (61, 115, 166), (55, 105, 153), (50, 94, 137), + (45, 82, 124), (34, 67, 109), (34, 63, 104), (35, 59, 99), + (43, 58, 99), (52, 58, 99), (66, 65, 104), (77, 77, 114), + (82, 109, 149), (95, 120, 164), (109, 131, 180), (114, 136, 182), + (120, 142, 185), (117, 150, 192), (107, 156, 196), (100, 157, 199), + (94, 154, 202), (89, 148, 197), (87, 146, 196), (86, 145, 195), + (84, 142, 192), (82, 139, 189), (79, 135, 186), (75, 131, 182), + (66, 118, 171), (60, 110, 163), (55, 102, 155), (52, 98, 151), + (50, 94, 148), (46, 91, 143), (43, 88, 142), (44, 89, 142), + (46, 90, 144), (51, 97, 150), (53, 100, 153), (55, 104, 156), + (61, 113, 164), (67, 122, 173), (72, 128, 178), (76, 132, 182), + (77, 134, 185), (77, 135, 186), (77, 136, 187), (78, 136, 187), + (79, 137, 188), (81, 138, 191), (83, 141, 193), (85, 144, 195), + (88, 147, 198), (94, 153, 203), (95, 154, 204), (96, 156, 205), + (95, 156, 206), (94, 154, 205), (91, 151, 201), (86, 144, 196), + (69, 121, 174), (63, 113, 166), (58, 105, 158), (48, 91, 141), + (39, 76, 124), (31, 62, 109), (22, 51, 96), (16, 41, 86), + (11, 36, 80), (13, 40, 82), (16, 45, 87), (20, 50, 93), + (29, 63, 108), (39, 79, 126), (48, 92, 140), (57, 106, 155), + (79, 135, 184), (84, 140, 189), (89, 146, 194), (102, 152, 199), + (118, 155, 202), (136, 156, 204), (152, 156, 207), (164, 158, 211), + (173, 160, 211), (184, 162, 212), (197, 163, 211), (195, 161, 212), + (191, 161, 214), (180, 163, 216), (165, 165, 216), (161, 168, 216), + (128, 164, 212), (120, 162, 210), (112, 160, 209), (97, 156, 206), + (84, 138, 180), (72, 119, 159), (60, 101, 140), (48, 85, 123), + (47, 87, 132), (40, 78, 119), (35, 70, 109), (30, 64, 103), + (27, 58, 96), (32, 67, 112), (35, 76, 124), (39, 82, 133), + (38, 85, 137), (38, 86, 137), (43, 85, 136), (55, 85, 136), + (72, 88, 140), (84, 92, 143), (92, 93, 144), (93, 92, 140), + (96, 86, 134), (100, 86, 126), (99, 86, 124), (97, 84, 123), + (87, 80, 117), (72, 67, 107), (56, 55, 85), (35, 42, 67), + (19, 29, 50), (8, 20, 38), (2, 10, 32), (1, 7, 26), + (0, 4, 25), (4, 4, 28), (6, 8, 33), (8, 13, 40), + (10, 18, 47), (7, 24, 56), (10, 25, 64), (11, 28, 72), + (12, 33, 79), (15, 39, 85), (13, 46, 91), (14, 49, 96), + (17, 53, 101), (22, 60, 109), (29, 69, 119), (37, 81, 130), + (45, 93, 144), (54, 104, 156), (63, 115, 169), (72, 127, 181), + (81, 138, 191), (88, 148, 199), (94, 154, 205), (98, 159, 209), + (100, 161, 212), (102, 163, 212), (103, 163, 213), (103, 163, 213), + (102, 163, 212), (101, 161, 211), (98, 159, 210), (97, 157, 209), + (95, 155, 207), (93, 153, 205), (90, 150, 203), (88, 148, 202) + ), + +// 488 Angora +((87, 50, 73), (92, 61, 79), (107, 72, 90), (122, 84, 101), + (135, 98, 119), (148, 113, 137), (156, 118, 144), (164, 124, 152), + (183, 132, 158), (180, 135, 160), (177, 138, 163), (171, 133, 153), + (165, 128, 143), (153, 120, 132), (142, 112, 122), (137, 108, 118), + (133, 105, 114), (122, 94, 114), (120, 88, 111), (119, 83, 108), + (120, 84, 110), (122, 85, 113), (123, 87, 116), (124, 90, 120), + (142, 103, 131), (152, 112, 140), (163, 122, 150), (171, 124, 154), + (179, 127, 159), (179, 126, 157), (179, 125, 155), (173, 120, 151), + (161, 108, 139), (136, 76, 108), (117, 62, 93), (99, 49, 78), + (88, 40, 71), (78, 31, 64), (75, 28, 62), (72, 26, 61), + (64, 26, 59), (64, 26, 60), (65, 26, 61), (68, 29, 64), + (72, 33, 67), (75, 35, 69), (78, 38, 72), (86, 45, 78), + (95, 53, 86), (114, 68, 102), (119, 71, 106), (125, 74, 111), + (124, 72, 109), (124, 70, 108), (119, 65, 104), (115, 60, 100), + (99, 47, 87), (93, 45, 83), (87, 44, 80), (85, 45, 82), + (83, 46, 84), (87, 48, 86), (91, 50, 89), (96, 54, 91), + (98, 54, 93), (100, 54, 96), (99, 52, 90), (98, 51, 84), + (95, 49, 79), (92, 47, 75), (87, 43, 69), (86, 42, 65), + (79, 39, 53), (78, 35, 50), (77, 32, 47), (76, 31, 47), + (76, 31, 48), (75, 31, 48), (74, 31, 49), (73, 29, 48), + (72, 29, 48), (67, 25, 46), (65, 24, 45), (64, 24, 44), + (64, 24, 44), (65, 25, 45), (66, 27, 49), (69, 32, 54), + (82, 51, 75), (89, 57, 86), (97, 63, 98), (99, 65, 101), + (102, 68, 104), (105, 70, 105), (105, 72, 102), (106, 68, 99), + (104, 61, 93), (98, 49, 71), (98, 48, 67), (98, 48, 63), + (100, 50, 65), (102, 52, 67), (107, 58, 70), (114, 66, 75), + (130, 79, 92), (133, 79, 95), (136, 79, 99), (131, 75, 97), + (126, 72, 95), (122, 69, 97), (126, 70, 104), (141, 79, 117), + (145, 89, 126), (164, 125, 160), (175, 136, 171), (187, 148, 182), + (206, 165, 199), (220, 177, 212), (224, 186, 217), (223, 191, 215), + (221, 181, 210), (220, 178, 206), (219, 175, 203), (216, 174, 202), + (214, 174, 201), (211, 170, 203), (212, 166, 200), (209, 163, 194), + (203, 159, 183), (190, 150, 164), (186, 147, 159), (183, 144, 155), + (174, 137, 142), (166, 127, 133), (161, 123, 128), (159, 120, 128), + (150, 113, 124), (148, 108, 123), (146, 103, 122), (147, 102, 122), + (148, 101, 122), (149, 98, 121), (148, 97, 121), (146, 98, 123), + (149, 99, 127), (158, 100, 132), (158, 102, 132), (158, 104, 133), + (157, 110, 134), (157, 111, 131), (157, 112, 125), (155, 109, 119), + (136, 98, 105), (132, 95, 101), (128, 93, 98), (120, 88, 93), + (113, 81, 89), (105, 74, 86), (101, 70, 84), (96, 69, 82), + (93, 68, 80), (90, 63, 74), (89, 62, 74), (89, 62, 74), + (89, 63, 73), (95, 66, 77), (106, 69, 81), (121, 78, 89), + (149, 96, 114), (155, 98, 119), (161, 101, 124), (174, 109, 129), + (180, 113, 131), (180, 113, 134), (170, 109, 136), (163, 105, 134), + (156, 99, 126), (149, 94, 118), (138, 89, 113), (131, 86, 110), + (127, 83, 105), (122, 80, 98), (117, 76, 92), (112, 72, 89), + (107, 66, 85), (107, 63, 83), (107, 61, 82), (109, 57, 82), + (111, 55, 81), (109, 52, 82), (104, 45, 79), (104, 40, 76), + (102, 37, 71), (97, 35, 69), (86, 30, 65), (77, 26, 59), + (71, 24, 54), (68, 24, 52), (65, 25, 54), (61, 25, 55), + (60, 27, 55), (60, 28, 54), (65, 28, 55), (65, 29, 59), + (67, 31, 61), (67, 32, 63), (70, 33, 63), (73, 34, 64), + (76, 37, 65), (79, 39, 66), (84, 43, 69), (88, 41, 72), + (92, 43, 75), (93, 45, 77), (96, 48, 77), (96, 44, 78), + (95, 40, 78), (95, 38, 77), (97, 41, 77), (98, 44, 77), + (100, 48, 77), (106, 50, 78), (115, 56, 81), (122, 64, 86), + (126, 74, 94), (132, 82, 98), (136, 87, 100), (138, 88, 103), + (134, 89, 104), (132, 88, 103), (126, 85, 97), (121, 82, 92), + (114, 79, 89), (110, 74, 88), (104, 68, 86), (103, 66, 84), + (103, 67, 84), (111, 70, 90), (120, 69, 98), (128, 72, 104), + (133, 79, 111), (140, 90, 116), (148, 100, 123), (153, 111, 129), + (158, 121, 132), (157, 127, 127), (151, 129, 123), (142, 130, 121), + (138, 130, 116), (136, 120, 104), (128, 106, 97), (114, 89, 92), + (103, 79, 87), (96, 66, 78), (92, 57, 75), (89, 51, 73) + ), + +// 489 Antique +((60, 18, 38), (72, 25, 55), (76, 31, 62), (81, 37, 69), + (82, 38, 73), (83, 39, 77), (82, 38, 77), (81, 38, 77), + (78, 33, 75), (80, 32, 73), (82, 31, 72), (84, 33, 71), + (87, 36, 71), (88, 38, 69), (90, 41, 67), (90, 41, 65), + (90, 42, 64), (86, 36, 59), (85, 34, 58), (85, 32, 58), + (86, 31, 59), (88, 30, 61), (88, 31, 62), (89, 32, 63), + (89, 38, 67), (87, 39, 67), (86, 41, 68), (83, 40, 66), + (80, 39, 65), (78, 36, 63), (77, 34, 62), (73, 30, 57), + (69, 26, 52), (61, 24, 42), (57, 23, 36), (54, 22, 31), + (52, 21, 28), (51, 21, 25), (51, 20, 23), (51, 20, 22), + (49, 16, 18), (48, 15, 17), (47, 14, 17), (46, 13, 17), + (45, 13, 17), (44, 13, 17), (44, 13, 17), (43, 13, 18), + (42, 13, 19), (41, 13, 19), (39, 13, 17), (38, 13, 16), + (36, 12, 16), (34, 12, 16), (34, 12, 16), (35, 13, 16), + (39, 17, 21), (44, 21, 25), (49, 25, 29), (51, 27, 31), + (54, 30, 33), (54, 30, 34), (55, 30, 35), (55, 31, 36), + (56, 31, 37), (57, 30, 39), (60, 31, 40), (63, 32, 42), + (64, 31, 43), (65, 31, 44), (64, 31, 46), (63, 30, 46), + (61, 26, 45), (60, 26, 47), (60, 26, 49), (66, 29, 55), + (72, 32, 62), (71, 31, 61), (71, 31, 61), (71, 31, 62), + (72, 31, 62), (76, 33, 64), (80, 37, 67), (85, 42, 70), + (90, 46, 75), (96, 51, 80), (101, 55, 82), (103, 57, 82), + (102, 53, 79), (95, 46, 72), (89, 40, 65), (86, 38, 62), + (84, 37, 60), (87, 41, 63), (94, 45, 66), (102, 51, 65), + (109, 60, 66), (126, 77, 72), (130, 80, 74), (135, 84, 77), + (135, 84, 77), (135, 85, 77), (135, 86, 79), (135, 84, 76), + (133, 85, 69), (133, 85, 67), (134, 86, 65), (133, 86, 64), + (132, 86, 64), (127, 84, 62), (121, 80, 62), (112, 71, 58), + (101, 60, 50), (76, 37, 34), (71, 32, 31), (66, 28, 28), + (58, 22, 25), (54, 18, 25), (54, 15, 29), (57, 16, 36), + (70, 26, 53), (76, 30, 61), (83, 35, 70), (84, 36, 72), + (86, 38, 75), (87, 40, 76), (88, 39, 75), (89, 39, 74), + (88, 37, 74), (92, 43, 75), (94, 44, 77), (96, 46, 79), + (98, 49, 81), (95, 49, 79), (91, 47, 75), (86, 42, 69), + (74, 30, 56), (71, 28, 53), (69, 27, 50), (70, 27, 51), + (71, 27, 52), (71, 27, 54), (71, 27, 56), (71, 28, 56), + (70, 26, 56), (70, 24, 52), (70, 23, 51), (70, 23, 51), + (72, 25, 52), (76, 29, 54), (78, 32, 56), (81, 36, 57), + (82, 38, 57), (81, 38, 56), (81, 38, 55), (79, 37, 52), + (78, 35, 51), (78, 36, 49), (79, 38, 50), (80, 40, 51), + (82, 43, 51), (83, 45, 54), (82, 44, 54), (82, 44, 54), + (79, 40, 52), (76, 35, 49), (73, 31, 44), (70, 28, 39), + (65, 26, 31), (65, 25, 30), (65, 25, 29), (65, 25, 28), + (64, 24, 28), (64, 23, 29), (65, 22, 28), (66, 22, 28), + (68, 22, 28), (72, 24, 28), (75, 26, 28), (77, 26, 28), + (77, 26, 28), (76, 26, 28), (75, 26, 28), (75, 27, 29), + (82, 34, 34), (85, 38, 35), (89, 43, 37), (99, 52, 43), + (107, 61, 48), (115, 69, 53), (119, 74, 58), (120, 76, 65), + (122, 78, 73), (126, 81, 84), (132, 89, 95), (142, 99, 109), + (152, 109, 122), (163, 119, 136), (173, 128, 144), (176, 130, 152), + (176, 129, 155), (173, 123, 156), (168, 117, 153), (159, 110, 148), + (150, 102, 142), (140, 95, 136), (132, 91, 127), (123, 84, 118), + (112, 75, 107), (102, 65, 95), (91, 55, 83), (79, 45, 69), + (69, 36, 56), (58, 28, 44), (48, 21, 32), (40, 16, 24), + (33, 11, 18), (29, 8, 15), (26, 6, 14), (25, 5, 14), + (25, 5, 15), (26, 6, 16), (28, 6, 17), (29, 7, 18), + (31, 7, 19), (32, 8, 21), (33, 9, 22), (34, 9, 22), + (34, 9, 23), (35, 10, 23), (36, 10, 24), (36, 11, 24), + (37, 10, 24), (38, 10, 25), (39, 10, 26), (39, 10, 26), + (39, 10, 27), (38, 11, 27), (38, 10, 27), (36, 10, 25), + (35, 9, 23), (34, 9, 21), (34, 8, 20), (34, 8, 19), + (34, 7, 18), (34, 8, 18), (35, 8, 17), (37, 9, 17), + (38, 10, 16), (39, 10, 16), (41, 10, 16), (43, 11, 17), + (45, 12, 19), (47, 13, 22), (50, 14, 26), (54, 16, 31) + ), + +// 490 Arizona +((205, 130, 107), (212, 138, 114), (211, 136, 116), (210, 135, 119), + (217, 145, 142), (224, 155, 166), (221, 151, 166), (218, 148, 166), + (199, 104, 186), (173, 84, 199), (148, 64, 213), (134, 45, 210), + (120, 27, 208), (110, 22, 200), (100, 17, 193), (96, 14, 189), + (92, 11, 185), (94, 6, 162), (96, 7, 143), (99, 8, 125), + (97, 9, 114), (95, 11, 104), (93, 10, 99), (92, 10, 94), + (87, 7, 81), (85, 8, 80), (84, 9, 79), (82, 7, 79), + (81, 6, 79), (80, 6, 78), (79, 6, 77), (79, 4, 73), + (76, 3, 70), (58, 3, 61), (52, 2, 57), (46, 1, 54), + (42, 0, 55), (39, 0, 57), (38, 0, 58), (38, 0, 60), + (49, 1, 67), (53, 0, 69), (58, 0, 71), (59, 0, 68), + (60, 0, 66), (60, 0, 64), (61, 0, 62), (60, 0, 57), + (57, 0, 51), (58, 2, 52), (65, 3, 57), (73, 4, 63), + (85, 10, 70), (97, 17, 77), (102, 21, 80), (107, 25, 84), + (119, 37, 79), (123, 44, 73), (127, 52, 68), (115, 51, 57), + (103, 51, 47), (97, 46, 42), (92, 41, 37), (85, 36, 36), + (82, 29, 41), (69, 14, 49), (72, 9, 55), (75, 4, 62), + (78, 4, 64), (81, 4, 66), (86, 4, 71), (91, 4, 77), + (92, 8, 87), (92, 7, 97), (93, 6, 107), (97, 6, 112), + (102, 7, 118), (102, 7, 119), (103, 8, 120), (99, 6, 117), + (102, 2, 115), (103, 5, 95), (95, 4, 83), (87, 3, 72), + (82, 2, 67), (78, 2, 63), (64, 2, 53), (56, 3, 48), + (50, 1, 40), (49, 0, 35), (49, 0, 31), (51, 1, 28), + (53, 3, 26), (64, 7, 23), (77, 16, 20), (97, 24, 19), + (105, 32, 15), (104, 41, 5), (108, 44, 12), (113, 47, 19), + (111, 43, 23), (110, 40, 27), (100, 30, 33), (92, 26, 37), + (91, 14, 54), (101, 24, 58), (112, 34, 62), (123, 48, 61), + (135, 62, 60), (156, 86, 61), (177, 103, 59), (184, 109, 55), + (197, 122, 49), (192, 131, 57), (181, 121, 58), (171, 112, 59), + (154, 89, 61), (136, 73, 68), (118, 59, 78), (106, 44, 84), + (104, 29, 94), (105, 26, 97), (107, 23, 101), (110, 22, 104), + (114, 22, 108), (121, 23, 115), (129, 25, 122), (134, 27, 129), + (142, 28, 141), (140, 20, 157), (139, 19, 154), (139, 18, 151), + (136, 17, 144), (129, 14, 139), (115, 7, 132), (104, 4, 122), + (86, 5, 116), (80, 3, 118), (75, 2, 121), (78, 7, 118), + (82, 12, 116), (90, 25, 111), (108, 39, 100), (127, 59, 89), + (156, 89, 79), (196, 125, 42), (199, 125, 31), (202, 126, 20), + (205, 128, 16), (204, 133, 21), (194, 118, 20), (172, 91, 17), + (127, 54, 35), (123, 51, 42), (120, 49, 50), (118, 43, 63), + (112, 40, 76), (104, 38, 80), (104, 41, 85), (115, 47, 81), + (124, 57, 77), (132, 63, 62), (131, 61, 58), (131, 59, 54), + (127, 52, 51), (125, 49, 47), (123, 41, 49), (120, 33, 49), + (111, 22, 45), (112, 22, 44), (113, 23, 44), (117, 24, 44), + (123, 30, 36), (125, 38, 26), (121, 45, 22), (113, 42, 23), + (105, 37, 29), (99, 32, 33), (89, 30, 37), (80, 27, 43), + (76, 24, 57), (85, 23, 75), (95, 28, 96), (105, 37, 113), + (133, 54, 143), (140, 55, 148), (148, 56, 154), (154, 50, 154), + (167, 53, 141), (166, 46, 133), (159, 40, 128), (143, 26, 120), + (143, 18, 97), (137, 10, 79), (126, 7, 72), (111, 7, 74), + (107, 8, 80), (105, 7, 82), (104, 6, 81), (101, 8, 75), + (100, 13, 71), (96, 18, 64), (90, 22, 56), (81, 25, 45), + (73, 27, 32), (70, 25, 24), (64, 22, 18), (56, 18, 18), + (49, 23, 15), (48, 22, 11), (47, 22, 12), (44, 16, 17), + (41, 16, 22), (41, 16, 23), (41, 18, 25), (49, 17, 32), + (57, 14, 43), (70, 15, 56), (86, 12, 66), (107, 15, 83), + (128, 14, 100), (138, 18, 111), (148, 16, 109), (152, 21, 112), + (158, 21, 122), (146, 16, 126), (130, 10, 121), (119, 12, 115), + (117, 18, 114), (115, 17, 114), (111, 15, 118), (111, 13, 127), + (117, 15, 130), (124, 18, 131), (127, 23, 132), (125, 25, 142), + (120, 20, 149), (116, 16, 154), (113, 17, 159), (106, 18, 166), + (104, 16, 172), (110, 14, 176), (120, 19, 180), (119, 21, 180), + (113, 20, 179), (103, 17, 180), (100, 22, 175), (97, 26, 168), + (97, 28, 153), (94, 29, 148), (102, 41, 136), (125, 67, 128), + (154, 97, 113), (162, 92, 104), (166, 82, 99), (172, 87, 100) + ), + +// 491 Autumn_Garden +((87, 71, 62), (91, 74, 71), (90, 75, 73), (90, 76, 76), + (90, 78, 81), (91, 81, 86), (88, 77, 82), (85, 74, 78), + (81, 70, 76), (84, 72, 78), (87, 75, 80), (90, 84, 85), + (93, 93, 90), (99, 99, 91), (105, 106, 92), (108, 108, 91), + (111, 111, 91), (120, 113, 86), (120, 112, 83), (120, 112, 81), + (119, 111, 73), (119, 110, 66), (119, 108, 60), (119, 107, 55), + (117, 102, 41), (118, 98, 38), (120, 95, 36), (119, 88, 32), + (119, 82, 28), (120, 78, 27), (121, 75, 26), (122, 70, 24), + (126, 68, 21), (133, 71, 22), (136, 76, 22), (139, 81, 22), + (141, 85, 26), (143, 89, 31), (143, 92, 33), (144, 95, 35), + (143, 106, 55), (147, 115, 63), (152, 125, 72), (152, 129, 71), + (153, 134, 70), (152, 135, 66), (152, 137, 63), (146, 133, 58), + (138, 132, 54), (129, 122, 55), (126, 114, 52), (123, 106, 49), + (117, 97, 39), (112, 88, 29), (104, 81, 23), (96, 75, 17), + (76, 58, 4), (71, 53, 2), (66, 48, 1), (65, 47, 4), + (65, 46, 7), (62, 44, 7), (59, 43, 7), (57, 44, 11), + (58, 43, 12), (63, 44, 12), (68, 45, 12), (74, 47, 12), + (75, 48, 12), (77, 49, 12), (80, 49, 12), (83, 48, 14), + (92, 51, 17), (98, 56, 17), (104, 62, 17), (109, 68, 21), + (115, 74, 26), (116, 75, 29), (118, 76, 33), (120, 77, 35), + (121, 76, 40), (121, 81, 44), (121, 87, 45), (121, 94, 46), + (120, 97, 47), (120, 100, 49), (117, 104, 50), (115, 103, 53), + (107, 99, 51), (102, 96, 44), (98, 94, 37), (95, 93, 34), + (93, 93, 32), (88, 94, 27), (83, 94, 26), (77, 93, 27), + (72, 91, 29), (65, 87, 35), (62, 86, 39), (59, 85, 44), + (57, 84, 45), (56, 84, 47), (53, 82, 51), (51, 78, 56), + (45, 75, 62), (44, 75, 64), (44, 76, 66), (46, 76, 67), + (48, 77, 69), (53, 76, 70), (59, 68, 72), (68, 62, 68), + (70, 57, 60), (71, 53, 43), (72, 54, 41), (73, 56, 39), + (77, 61, 36), (85, 67, 34), (102, 74, 35), (114, 83, 32), + (134, 101, 27), (139, 109, 27), (144, 117, 28), (144, 120, 27), + (145, 124, 26), (150, 134, 29), (155, 141, 30), (161, 150, 26), + (169, 159, 26), (176, 164, 21), (173, 161, 19), (171, 158, 17), + (161, 153, 16), (150, 143, 15), (139, 134, 10), (130, 127, 8), + (120, 119, 3), (117, 115, 3), (115, 112, 4), (112, 110, 4), + (110, 108, 5), (105, 105, 5), (101, 102, 7), (98, 102, 9), + (96, 101, 14), (95, 103, 29), (96, 105, 33), (97, 108, 37), + (99, 111, 46), (105, 115, 54), (107, 118, 60), (111, 119, 64), + (112, 116, 70), (111, 116, 71), (110, 116, 72), (109, 115, 77), + (110, 119, 78), (112, 123, 76), (114, 126, 73), (118, 125, 68), + (118, 121, 61), (113, 109, 43), (112, 106, 40), (111, 103, 37), + (111, 101, 30), (110, 101, 24), (112, 101, 19), (111, 101, 19), + (107, 96, 22), (106, 92, 24), (105, 89, 27), (103, 83, 31), + (100, 80, 36), (102, 78, 40), (102, 79, 44), (103, 78, 50), + (106, 77, 56), (107, 77, 61), (106, 76, 63), (104, 74, 64), + (103, 73, 64), (102, 75, 61), (100, 76, 56), (99, 73, 52), + (97, 71, 41), (95, 69, 37), (94, 68, 34), (90, 65, 30), + (85, 65, 27), (82, 65, 24), (79, 67, 21), (76, 71, 20), + (75, 74, 20), (75, 76, 20), (73, 76, 24), (72, 77, 29), + (74, 76, 36), (75, 75, 43), (74, 76, 50), (76, 79, 56), + (81, 80, 58), (84, 81, 63), (89, 82, 70), (94, 85, 75), + (99, 86, 82), (102, 87, 90), (105, 91, 99), (115, 94, 106), + (119, 95, 110), (122, 97, 120), (124, 101, 125), (134, 109, 127), + (142, 118, 136), (145, 127, 140), (154, 136, 144), (160, 141, 138), + (162, 143, 136), (158, 141, 132), (158, 140, 119), (153, 139, 112), + (147, 137, 102), (145, 137, 94), (143, 131, 83), (140, 126, 72), + (133, 117, 64), (123, 105, 52), (111, 96, 43), (99, 87, 40), + (89, 81, 37), (78, 74, 36), (67, 70, 34), (58, 64, 35), + (50, 58, 36), (46, 54, 40), (43, 51, 42), (41, 51, 46), + (39, 50, 51), (38, 52, 52), (38, 53, 53), (39, 55, 53), + (40, 56, 51), (44, 55, 48), (47, 57, 45), (53, 57, 44), + (59, 58, 42), (64, 58, 43), (68, 60, 46), (71, 62, 51), + (73, 64, 55), (75, 64, 54), (84, 74, 65), (92, 81, 70), + (94, 84, 71), (95, 83, 72), (96, 83, 72), (96, 83, 74) + ), + +// 492 Autumn_Leaves +((151, 96, 34), (130, 130, 63), (125, 127, 57), (120, 124, 51), + (104, 107, 50), (88, 90, 50), (79, 79, 50), (71, 69, 50), + (41, 46, 33), (35, 40, 27), (30, 35, 22), (32, 35, 19), + (35, 36, 16), (43, 39, 25), (52, 43, 34), (58, 49, 39), + (64, 56, 44), (86, 80, 70), (97, 90, 74), (108, 101, 78), + (114, 103, 79), (121, 105, 80), (125, 104, 77), (129, 103, 75), + (141, 113, 61), (134, 119, 56), (128, 126, 52), (108, 125, 40), + (89, 125, 29), (79, 122, 28), (70, 119, 27), (57, 101, 21), + (50, 84, 15), (39, 47, 10), (39, 37, 10), (39, 27, 11), + (39, 24, 11), (39, 21, 12), (41, 24, 12), (44, 28, 12), + (59, 39, 19), (63, 40, 15), (67, 41, 11), (74, 39, 8), + (81, 37, 6), (81, 30, 4), (81, 23, 2), (74, 20, 4), + (68, 18, 8), (47, 6, 13), (38, 8, 12), (29, 11, 12), + (36, 13, 9), (44, 16, 6), (52, 19, 8), (60, 22, 11), + (87, 38, 20), (95, 39, 20), (104, 41, 21), (96, 37, 16), + (89, 34, 12), (81, 31, 13), (74, 28, 15), (56, 20, 18), + (42, 15, 21), (22, 22, 46), (34, 39, 49), (46, 57, 52), + (52, 67, 55), (58, 78, 59), (76, 94, 62), (103, 112, 60), + (141, 122, 55), (156, 119, 56), (172, 117, 57), (174, 116, 58), + (177, 116, 60), (172, 122, 60), (167, 129, 61), (160, 128, 74), + (151, 131, 88), (139, 131, 91), (139, 122, 94), (139, 114, 98), + (135, 107, 92), (132, 101, 87), (115, 89, 76), (106, 76, 72), + (80, 56, 63), (69, 51, 57), (59, 46, 51), (61, 42, 48), + (63, 38, 46), (67, 38, 38), (77, 39, 34), (95, 41, 31), + (106, 49, 30), (139, 70, 42), (149, 80, 46), (159, 91, 50), + (160, 94, 54), (162, 97, 58), (155, 93, 55), (152, 86, 50), + (129, 81, 54), (116, 76, 53), (104, 71, 53), (99, 71, 54), + (95, 72, 55), (86, 70, 54), (81, 72, 46), (80, 80, 41), + (80, 83, 48), (86, 88, 41), (90, 89, 43), (95, 90, 46), + (102, 87, 48), (112, 83, 45), (114, 75, 41), (119, 71, 36), + (110, 67, 38), (107, 61, 40), (105, 55, 42), (99, 55, 42), + (94, 56, 43), (90, 49, 47), (87, 42, 49), (79, 39, 43), + (76, 34, 37), (63, 33, 28), (64, 33, 28), (66, 34, 29), + (65, 41, 33), (67, 51, 41), (77, 62, 52), (88, 75, 60), + (116, 93, 57), (127, 93, 50), (139, 93, 43), (139, 91, 38), + (140, 89, 33), (132, 79, 27), (120, 66, 25), (108, 59, 25), + (93, 51, 30), (64, 43, 27), (62, 41, 27), (60, 39, 28), + (58, 39, 27), (56, 37, 17), (52, 37, 11), (51, 42, 10), + (41, 35, 5), (38, 34, 5), (35, 33, 6), (25, 33, 3), + (21, 25, 3), (18, 14, 3), (15, 9, 1), (15, 6, 0), + (22, 2, 0), (32, 0, 9), (38, 0, 10), (44, 0, 12), + (51, 0, 17), (61, 2, 24), (77, 7, 22), (83, 12, 18), + (93, 32, 13), (94, 36, 10), (95, 41, 7), (93, 47, 7), + (91, 53, 10), (91, 61, 17), (93, 63, 21), (90, 60, 21), + (85, 61, 28), (78, 63, 31), (69, 57, 27), (66, 53, 28), + (62, 56, 30), (56, 55, 29), (58, 52, 33), (58, 52, 32), + (57, 34, 32), (56, 29, 33), (55, 24, 34), (51, 16, 26), + (45, 8, 20), (39, 5, 19), (35, 6, 14), (34, 12, 7), + (34, 19, 5), (34, 22, 8), (41, 25, 9), (48, 27, 6), + (50, 24, 7), (51, 22, 8), (51, 15, 4), (46, 10, 2), + (39, 11, 1), (34, 8, 0), (32, 7, 3), (30, 12, 9), + (27, 22, 17), (25, 33, 29), (29, 47, 53), (44, 66, 70), + (60, 83, 68), (65, 103, 71), (77, 107, 70), (93, 98, 52), + (97, 100, 41), (91, 92, 37), (85, 75, 35), (83, 74, 42), + (74, 78, 51), (62, 79, 59), (62, 88, 61), (47, 86, 47), + (29, 77, 40), (26, 73, 39), (19, 61, 20), (19, 56, 5), + (26, 55, 11), (33, 53, 18), (51, 60, 20), (74, 66, 34), + (90, 71, 46), (105, 79, 51), (125, 90, 64), (141, 105, 71), + (149, 131, 77), (154, 147, 82), (154, 156, 76), (162, 168, 76), + (164, 168, 72), (161, 149, 60), (169, 130, 47), (162, 124, 40), + (155, 113, 38), (154, 98, 34), (135, 93, 37), (120, 90, 43), + (120, 92, 49), (113, 93, 59), (108, 87, 67), (117, 86, 64), + (121, 92, 61), (129, 93, 62), (143, 88, 54), (150, 87, 41), + (156, 88, 33), (165, 85, 28), (157, 90, 41), (148, 93, 50) + ), + +// 493 Autumn_Mountains +((189, 156, 127), (195, 167, 135), (187, 158, 123), (179, 150, 112), + (172, 141, 107), (165, 133, 102), (160, 128, 97), (155, 123, 93), + (133, 99, 75), (119, 82, 53), (106, 66, 32), (101, 60, 27), + (97, 55, 23), (99, 57, 26), (102, 59, 30), (104, 61, 31), + (107, 64, 33), (124, 82, 42), (132, 90, 45), (140, 98, 48), + (141, 100, 50), (143, 103, 52), (143, 102, 52), (143, 102, 52), + (135, 95, 54), (131, 94, 55), (128, 93, 57), (128, 93, 58), + (128, 93, 60), (129, 94, 61), (130, 96, 62), (135, 96, 68), + (139, 102, 73), (151, 115, 86), (156, 121, 88), (162, 127, 91), + (167, 130, 92), (172, 133, 94), (174, 134, 92), (177, 135, 91), + (176, 131, 83), (172, 127, 78), (169, 124, 73), (163, 120, 68), + (158, 116, 63), (156, 114, 60), (155, 113, 58), (153, 110, 52), + (151, 106, 49), (146, 103, 48), (143, 102, 47), (140, 101, 46), + (136, 96, 44), (133, 91, 42), (132, 89, 41), (132, 87, 40), + (125, 74, 41), (123, 70, 38), (121, 67, 35), (120, 62, 31), + (119, 58, 27), (119, 57, 25), (119, 56, 24), (117, 53, 22), + (117, 52, 21), (123, 61, 30), (128, 65, 34), (134, 70, 38), + (135, 72, 39), (136, 74, 40), (136, 73, 38), (135, 73, 37), + (127, 69, 34), (122, 64, 32), (118, 59, 31), (112, 51, 26), + (106, 44, 21), (103, 42, 17), (101, 40, 14), (95, 39, 10), + (92, 38, 10), (88, 41, 14), (87, 44, 21), (87, 47, 29), + (87, 49, 32), (87, 52, 36), (91, 55, 43), (96, 61, 46), + (98, 71, 54), (96, 75, 59), (95, 79, 64), (95, 79, 65), + (95, 79, 67), (98, 76, 67), (104, 73, 62), (105, 70, 59), + (105, 67, 55), (103, 64, 52), (105, 63, 49), (107, 63, 46), + (108, 63, 44), (110, 63, 42), (111, 62, 37), (112, 60, 34), + (109, 54, 31), (107, 53, 28), (105, 52, 25), (103, 52, 23), + (102, 52, 21), (100, 53, 18), (100, 52, 15), (101, 52, 17), + (103, 53, 20), (108, 58, 27), (109, 60, 29), (111, 62, 31), + (114, 67, 34), (117, 72, 40), (121, 78, 46), (126, 85, 51), + (134, 97, 62), (137, 100, 65), (140, 104, 69), (140, 104, 69), + (141, 105, 69), (145, 106, 67), (148, 110, 65), (156, 119, 73), + (162, 123, 75), (161, 123, 75), (159, 120, 72), (157, 117, 70), + (146, 104, 55), (142, 101, 53), (137, 94, 48), (131, 87, 47), + (114, 71, 41), (103, 59, 29), (92, 47, 18), (89, 43, 14), + (87, 40, 10), (85, 39, 6), (85, 37, 5), (86, 38, 7), + (87, 42, 8), (97, 53, 15), (101, 58, 17), (105, 63, 20), + (111, 70, 27), (115, 77, 37), (119, 83, 43), (122, 89, 50), + (131, 101, 58), (134, 103, 59), (137, 105, 60), (139, 108, 65), + (141, 110, 67), (142, 109, 63), (140, 106, 57), (139, 102, 51), + (138, 97, 42), (131, 83, 33), (129, 78, 30), (127, 73, 27), + (120, 64, 19), (110, 53, 13), (100, 42, 6), (89, 32, 3), + (77, 18, 3), (76, 17, 3), (76, 16, 4), (75, 16, 7), + (74, 18, 10), (71, 19, 15), (66, 23, 18), (66, 26, 21), + (69, 30, 22), (71, 31, 22), (75, 34, 22), (73, 35, 21), + (67, 35, 24), (62, 35, 26), (63, 35, 27), (65, 34, 24), + (78, 39, 17), (79, 40, 16), (81, 41, 16), (81, 44, 20), + (85, 46, 24), (89, 48, 27), (98, 50, 29), (108, 55, 29), + (117, 62, 29), (125, 71, 33), (131, 77, 40), (134, 85, 47), + (137, 88, 53), (140, 90, 57), (144, 95, 62), (151, 104, 66), + (158, 112, 73), (171, 132, 93), (183, 150, 115), (192, 165, 135), + (202, 180, 155), (213, 194, 172), (218, 199, 176), (227, 213, 193), + (237, 225, 209), (243, 236, 224), (249, 245, 239), (254, 254, 252), + (254, 254, 252), (254, 254, 253), (255, 253, 252), (254, 253, 251), + (247, 242, 239), (240, 231, 226), (231, 220, 214), (221, 207, 202), + (211, 195, 189), (208, 193, 186), (199, 182, 174), (192, 170, 161), + (184, 160, 146), (175, 150, 135), (165, 137, 120), (163, 135, 114), + (160, 132, 108), (159, 126, 102), (158, 123, 97), (158, 121, 96), + (155, 120, 94), (155, 120, 94), (153, 119, 91), (151, 115, 85), + (148, 111, 78), (145, 107, 74), (140, 103, 70), (136, 101, 71), + (132, 100, 71), (131, 100, 69), (130, 100, 66), (130, 99, 62), + (129, 96, 54), (129, 95, 52), (128, 92, 52), (130, 92, 52), + (134, 94, 56), (138, 97, 61), (142, 102, 65), (148, 108, 73), + (153, 113, 79), (159, 118, 84), (167, 126, 92), (179, 141, 110) + ), + +// 494 Awakening +((214, 197, 29), (211, 204, 88), (207, 201, 110), (204, 198, 132), + (203, 189, 153), (203, 181, 174), (208, 173, 176), (214, 166, 179), + (215, 131, 158), (210, 118, 144), (206, 105, 130), (206, 101, 133), + (206, 98, 136), (204, 122, 146), (203, 147, 157), (197, 152, 157), + (191, 157, 158), (172, 177, 168), (168, 174, 164), (164, 171, 160), + (162, 162, 154), (160, 154, 149), (159, 155, 149), (159, 156, 149), + (179, 167, 167), (187, 181, 180), (195, 195, 194), (195, 205, 196), + (195, 215, 199), (193, 214, 194), (191, 214, 189), (175, 209, 165), + (162, 196, 134), (134, 172, 86), (122, 165, 60), (110, 159, 34), + (123, 162, 22), (137, 165, 11), (145, 168, 10), (153, 171, 9), + (181, 177, 29), (197, 169, 41), (213, 161, 53), (203, 167, 77), + (193, 174, 102), (188, 169, 97), (183, 165, 93), (187, 145, 81), + (190, 154, 68), (185, 175, 63), (179, 170, 37), (174, 165, 12), + (163, 158, 8), (152, 152, 5), (141, 151, 5), (131, 150, 6), + (96, 140, 3), (98, 135, 1), (100, 130, 0), (106, 132, 3), + (113, 134, 7), (116, 137, 9), (119, 141, 11), (118, 141, 13), + (116, 135, 16), (81, 129, 29), (61, 119, 30), (41, 109, 31), + (33, 103, 32), (25, 97, 33), (12, 88, 33), (3, 80, 31), + (3, 75, 19), (8, 80, 16), (13, 86, 14), (19, 91, 10), + (25, 96, 6), (26, 98, 4), (27, 100, 3), (32, 104, 3), + (37, 106, 5), (37, 102, 9), (45, 104, 17), (53, 107, 26), + (64, 105, 33), (76, 103, 41), (99, 90, 55), (121, 73, 56), + (133, 82, 63), (141, 80, 59), (149, 79, 56), (149, 79, 50), + (150, 80, 44), (137, 95, 31), (120, 116, 31), (106, 126, 25), + (101, 128, 18), (86, 125, 16), (70, 119, 19), (54, 113, 22), + (45, 109, 23), (36, 106, 25), (24, 102, 32), (16, 97, 34), + (7, 84, 41), (7, 79, 43), (8, 74, 45), (14, 71, 42), + (20, 69, 40), (37, 75, 32), (59, 83, 27), (80, 97, 21), + (106, 101, 16), (144, 125, 9), (147, 130, 7), (150, 136, 5), + (148, 134, 6), (128, 128, 9), (110, 121, 12), (87, 112, 12), + (40, 91, 17), (25, 89, 19), (11, 87, 22), (11, 89, 22), + (11, 92, 22), (13, 95, 22), (18, 99, 22), (20, 100, 25), + (27, 103, 27), (25, 109, 26), (23, 107, 26), (21, 106, 27), + (20, 98, 29), (16, 90, 30), (8, 86, 29), (4, 84, 29), + (23, 88, 21), (42, 97, 17), (62, 107, 14), (74, 113, 12), + (86, 120, 11), (114, 138, 8), (139, 157, 4), (153, 169, 2), + (158, 166, 2), (147, 164, 3), (138, 161, 2), (130, 158, 2), + (108, 140, 2), (91, 123, 0), (76, 115, 3), (70, 115, 5), + (74, 113, 14), (77, 116, 17), (80, 120, 21), (93, 133, 28), + (111, 145, 44), (125, 152, 62), (124, 157, 76), (124, 159, 79), + (128, 161, 77), (111, 155, 70), (102, 152, 68), (94, 149, 66), + (85, 143, 57), (77, 137, 38), (65, 129, 23), (55, 125, 17), + (53, 120, 17), (54, 118, 15), (55, 116, 14), (57, 118, 10), + (60, 122, 8), (62, 126, 8), (63, 123, 7), (59, 119, 7), + (54, 115, 7), (46, 113, 12), (39, 106, 15), (28, 95, 19), + (20, 82, 21), (11, 71, 24), (6, 61, 25), (2, 54, 27), + (0, 47, 29), (0, 47, 27), (0, 47, 25), (4, 51, 21), + (12, 60, 16), (21, 73, 16), (27, 84, 15), (34, 94, 18), + (41, 102, 17), (49, 111, 18), (55, 118, 20), (61, 123, 23), + (64, 124, 26), (63, 124, 24), (64, 126, 25), (69, 130, 29), + (74, 130, 38), (74, 128, 46), (76, 132, 55), (78, 134, 63), + (72, 133, 68), (59, 124, 71), (52, 122, 73), (49, 118, 75), + (46, 115, 70), (42, 113, 60), (45, 116, 50), (61, 118, 48), + (75, 120, 48), (86, 125, 45), (90, 129, 41), (94, 130, 40), + (95, 128, 38), (87, 122, 36), (75, 115, 32), (60, 107, 29), + (45, 104, 27), (32, 96, 24), (25, 91, 22), (22, 91, 20), + (18, 96, 21), (21, 101, 23), (28, 103, 27), (45, 108, 32), + (63, 115, 46), (83, 127, 66), (101, 142, 91), (121, 157, 110), + (141, 163, 118), (152, 169, 127), (150, 173, 133), (137, 175, 134), + (124, 168, 119), (113, 157, 101), (100, 149, 87), (86, 141, 73), + (73, 135, 63), (77, 133, 54), (87, 134, 63), (108, 136, 82), + (128, 146, 103), (142, 160, 109), (152, 169, 98), (165, 164, 88), + (191, 167, 85), (204, 177, 79), (210, 189, 61), (209, 186, 33), + (220, 186, 12), (229, 193, 1), (234, 198, 1), (226, 199, 9) + ), + +// 495 Baby +((168, 150, 133), (195, 153, 148), (200, 157, 153), (205, 162, 159), + (202, 161, 152), (200, 161, 145), (196, 163, 146), (193, 165, 147), + (179, 168, 150), (166, 161, 146), (154, 155, 142), (149, 147, 128), + (145, 140, 115), (139, 133, 107), (134, 127, 99), (133, 124, 95), + (133, 122, 91), (124, 120, 91), (118, 119, 90), (112, 119, 90), + (110, 119, 94), (109, 119, 99), (108, 122, 101), (107, 126, 104), + (124, 136, 118), (124, 145, 132), (125, 154, 146), (118, 168, 158), + (112, 182, 170), (111, 186, 173), (111, 191, 176), (104, 202, 179), + (105, 210, 180), (127, 205, 179), (142, 194, 181), (157, 184, 183), + (155, 180, 183), (154, 176, 184), (154, 173, 184), (154, 171, 184), + (152, 178, 171), (156, 179, 164), (160, 180, 158), (171, 176, 148), + (182, 172, 138), (182, 166, 136), (183, 161, 135), (178, 156, 134), + (172, 139, 133), (142, 112, 120), (137, 102, 117), (133, 93, 114), + (130, 96, 117), (127, 99, 121), (126, 104, 123), (126, 110, 126), + (93, 126, 142), (83, 131, 143), (73, 137, 145), (66, 130, 139), + (59, 124, 133), (65, 124, 128), (71, 124, 124), (80, 126, 106), + (83, 126, 101), (97, 124, 101), (100, 124, 110), (104, 125, 120), + (107, 125, 123), (111, 125, 126), (118, 123, 139), (126, 121, 141), + (133, 126, 145), (134, 126, 138), (135, 126, 132), (132, 122, 125), + (130, 119, 119), (130, 119, 114), (130, 119, 109), (130, 116, 97), + (133, 112, 90), (133, 98, 74), (131, 91, 68), (130, 84, 63), + (128, 79, 64), (126, 74, 66), (124, 70, 69), (123, 70, 75), + (140, 92, 97), (144, 103, 106), (149, 114, 115), (149, 122, 118), + (149, 131, 122), (146, 145, 131), (134, 159, 145), (117, 173, 158), + (102, 189, 172), (98, 190, 189), (107, 182, 180), (116, 175, 172), + (127, 169, 168), (138, 164, 164), (152, 152, 152), (162, 146, 146), + (162, 146, 149), (146, 152, 158), (130, 159, 167), (121, 166, 171), + (112, 173, 176), (93, 177, 173), (72, 180, 168), (57, 193, 165), + (45, 187, 157), (38, 175, 142), (37, 170, 142), (37, 166, 142), + (38, 163, 146), (37, 160, 149), (37, 154, 152), (37, 151, 152), + (37, 154, 148), (51, 152, 143), (65, 151, 139), (72, 150, 136), + (80, 149, 134), (85, 148, 130), (106, 140, 122), (124, 130, 114), + (124, 128, 103), (127, 122, 89), (128, 124, 87), (129, 126, 85), + (128, 127, 81), (129, 125, 86), (129, 123, 93), (129, 122, 98), + (121, 104, 116), (122, 106, 130), (124, 109, 144), (123, 110, 146), + (123, 112, 149), (126, 114, 155), (128, 107, 155), (131, 104, 143), + (130, 100, 134), (123, 81, 102), (123, 83, 99), (123, 86, 97), + (118, 92, 97), (107, 104, 97), (96, 118, 104), (83, 129, 113), + (57, 158, 125), (51, 157, 127), (45, 156, 130), (47, 158, 128), + (60, 158, 128), (71, 151, 130), (81, 140, 131), (96, 134, 128), + (110, 129, 120), (119, 127, 115), (118, 127, 113), (118, 128, 111), + (122, 134, 110), (117, 147, 120), (106, 158, 132), (101, 168, 152), + (87, 179, 178), (87, 177, 182), (87, 176, 186), (97, 181, 191), + (100, 174, 190), (100, 169, 186), (107, 176, 177), (106, 180, 172), + (88, 175, 162), (77, 170, 150), (81, 169, 152), (85, 164, 145), + (87, 150, 137), (98, 149, 141), (117, 154, 142), (134, 155, 143), + (140, 167, 142), (141, 172, 143), (143, 178, 144), (136, 183, 148), + (122, 179, 151), (105, 175, 153), (83, 172, 155), (68, 170, 157), + (61, 161, 156), (63, 157, 156), (71, 164, 160), (82, 160, 162), + (103, 153, 159), (118, 156, 154), (123, 154, 152), (129, 141, 147), + (133, 136, 139), (133, 129, 133), (131, 119, 130), (127, 109, 126), + (122, 99, 122), (121, 95, 120), (118, 90, 112), (115, 92, 100), + (114, 94, 87), (118, 89, 71), (123, 90, 58), (122, 93, 48), + (121, 93, 39), (121, 96, 46), (125, 101, 56), (124, 108, 65), + (120, 113, 85), (123, 119, 104), (130, 130, 112), (143, 138, 121), + (163, 136, 141), (184, 140, 155), (203, 151, 156), (220, 153, 157), + (225, 147, 158), (219, 144, 152), (211, 146, 139), (198, 143, 131), + (187, 137, 127), (181, 135, 123), (179, 139, 125), (180, 140, 127), + (179, 135, 122), (175, 134, 117), (169, 132, 113), (160, 126, 105), + (151, 118, 96), (146, 115, 89), (136, 114, 81), (130, 107, 75), + (129, 100, 69), (129, 97, 66), (127, 91, 65), (125, 83, 65), + (123, 82, 64), (119, 84, 62), (118, 86, 56), (115, 95, 50), + (116, 109, 52), (121, 120, 56), (121, 128, 55), (125, 135, 66), + (134, 143, 88), (136, 142, 97), (144, 136, 99), (162, 144, 117) + ), + +// 496 Banana +((199, 176, 153), (195, 176, 150), (205, 186, 162), (216, 196, 174), + (213, 194, 172), (211, 192, 170), (210, 191, 170), (209, 191, 170), + (216, 194, 171), (218, 198, 176), (221, 202, 181), (221, 202, 181), + (221, 203, 181), (220, 203, 183), (219, 204, 185), (217, 204, 186), + (216, 204, 188), (213, 203, 189), (217, 205, 191), (221, 208, 194), + (226, 212, 197), (232, 217, 201), (232, 216, 200), (233, 216, 200), + (234, 213, 192), (228, 205, 182), (223, 198, 172), (216, 188, 160), + (209, 178, 148), (207, 173, 139), (205, 169, 131), (204, 160, 113), + (207, 157, 98), (212, 160, 92), (211, 157, 89), (211, 155, 86), + (209, 157, 92), (208, 160, 99), (206, 158, 102), (204, 157, 105), + (193, 148, 108), (191, 147, 108), (190, 147, 109), (192, 150, 112), + (194, 154, 115), (195, 157, 118), (197, 160, 122), (197, 166, 130), + (199, 170, 137), (203, 179, 150), (200, 179, 153), (197, 180, 156), + (196, 179, 157), (196, 179, 158), (196, 179, 158), (197, 180, 159), + (198, 184, 166), (202, 188, 170), (206, 192, 175), (208, 195, 178), + (211, 198, 181), (211, 198, 180), (212, 198, 180), (213, 195, 174), + (214, 190, 165), (214, 181, 149), (211, 175, 141), (209, 170, 134), + (208, 167, 129), (208, 165, 125), (206, 159, 118), (197, 151, 110), + (179, 140, 103), (177, 138, 102), (176, 137, 102), (173, 138, 105), + (171, 139, 109), (173, 141, 112), (176, 144, 116), (181, 149, 123), + (185, 152, 125), (181, 151, 124), (174, 144, 115), (168, 137, 106), + (164, 132, 99), (161, 128, 93), (155, 119, 82), (148, 113, 72), + (149, 105, 58), (151, 102, 46), (154, 100, 35), (159, 101, 33), + (165, 103, 32), (173, 106, 35), (178, 109, 35), (178, 111, 35), + (183, 115, 40), (189, 125, 65), (187, 129, 77), (185, 134, 90), + (186, 135, 95), (188, 137, 100), (189, 140, 108), (189, 144, 112), + (190, 147, 118), (191, 150, 118), (193, 154, 119), (193, 154, 120), + (194, 155, 121), (196, 156, 120), (198, 156, 121), (198, 158, 121), + (197, 159, 122), (195, 159, 123), (195, 159, 125), (195, 160, 127), + (196, 163, 130), (197, 164, 132), (198, 166, 132), (198, 166, 133), + (204, 167, 132), (205, 166, 131), (207, 166, 131), (206, 167, 132), + (206, 169, 134), (206, 171, 139), (208, 174, 145), (209, 177, 150), + (210, 183, 159), (211, 194, 172), (211, 194, 172), (212, 195, 172), + (212, 193, 170), (211, 189, 164), (209, 181, 150), (204, 170, 134), + (184, 143, 98), (173, 128, 80), (162, 113, 62), (154, 106, 56), + (146, 100, 51), (137, 95, 48), (130, 93, 48), (134, 98, 54), + (136, 105, 70), (149, 129, 102), (155, 135, 107), (161, 142, 113), + (173, 152, 126), (184, 162, 137), (190, 169, 142), (194, 175, 146), + (202, 180, 152), (203, 181, 152), (205, 183, 153), (208, 184, 152), + (209, 185, 151), (209, 184, 150), (207, 181, 148), (206, 175, 140), + (205, 167, 126), (199, 150, 95), (196, 145, 89), (193, 140, 83), + (189, 129, 68), (189, 125, 56), (193, 122, 42), (192, 124, 41), + (191, 127, 57), (193, 129, 59), (195, 132, 62), (197, 138, 74), + (201, 146, 86), (197, 149, 102), (193, 154, 112), (192, 157, 123), + (194, 162, 130), (194, 165, 137), (192, 170, 142), (192, 172, 148), + (193, 175, 152), (195, 177, 156), (198, 180, 157), (199, 181, 161), + (200, 183, 165), (201, 185, 166), (203, 187, 168), (208, 192, 174), + (211, 198, 182), (215, 204, 189), (221, 210, 196), (228, 217, 203), + (235, 225, 212), (238, 229, 217), (238, 232, 220), (240, 232, 220), + (240, 232, 221), (238, 229, 217), (232, 224, 213), (228, 219, 206), + (226, 216, 203), (224, 213, 198), (221, 210, 197), (218, 209, 195), + (217, 207, 194), (218, 206, 192), (217, 204, 189), (215, 201, 184), + (211, 194, 175), (208, 186, 163), (204, 177, 151), (200, 167, 136), + (193, 156, 122), (189, 148, 111), (186, 146, 107), (188, 145, 106), + (184, 143, 105), (185, 143, 107), (186, 147, 112), (192, 154, 118), + (196, 158, 122), (199, 161, 127), (202, 165, 131), (208, 170, 135), + (215, 175, 137), (217, 179, 142), (217, 184, 150), (218, 188, 159), + (221, 194, 165), (222, 198, 172), (220, 203, 181), (220, 208, 190), + (223, 212, 197), (227, 217, 202), (228, 220, 206), (231, 223, 211), + (231, 223, 212), (231, 222, 210), (229, 219, 206), (227, 216, 201), + (223, 210, 194), (220, 201, 187), (216, 193, 176), (213, 187, 166), + (208, 183, 156), (208, 176, 149), (206, 169, 143), (206, 165, 138), + (201, 166, 136), (199, 166, 136), (195, 162, 135), (193, 158, 133), + (186, 155, 131), (179, 150, 124), (184, 159, 133), (193, 166, 142) + ), + +// 497 Beach +((131, 111, 158), (173, 150, 160), (177, 158, 172), (182, 167, 185), + (194, 179, 196), (206, 191, 208), (214, 198, 212), (223, 205, 217), + (240, 230, 231), (236, 229, 232), (233, 229, 234), (229, 214, 230), + (226, 199, 226), (223, 193, 223), (220, 187, 220), (217, 187, 219), + (215, 188, 218), (211, 180, 213), (207, 173, 212), (204, 167, 211), + (194, 162, 210), (184, 157, 210), (182, 156, 210), (180, 156, 210), + (178, 147, 194), (172, 138, 184), (166, 129, 175), (167, 129, 158), + (168, 130, 142), (173, 136, 136), (179, 143, 131), (190, 155, 124), + (193, 164, 127), (198, 179, 139), (202, 188, 145), (206, 197, 151), + (207, 200, 153), (209, 204, 156), (208, 203, 156), (208, 203, 157), + (202, 188, 157), (191, 172, 145), (181, 156, 133), (163, 140, 123), + (145, 125, 113), (136, 117, 113), (128, 110, 114), (113, 95, 122), + (102, 79, 122), (81, 65, 131), (76, 68, 145), (71, 72, 160), + (78, 81, 170), (86, 91, 180), (91, 96, 184), (96, 102, 188), + (126, 131, 204), (142, 147, 206), (159, 163, 208), (170, 172, 197), + (181, 181, 187), (185, 183, 182), (190, 185, 178), (201, 189, 173), + (204, 190, 171), (191, 174, 167), (179, 162, 168), (167, 151, 170), + (159, 146, 173), (151, 142, 177), (138, 130, 187), (125, 120, 198), + (107, 109, 213), (105, 111, 214), (104, 114, 215), (115, 121, 216), + (126, 129, 217), (132, 132, 216), (139, 135, 215), (149, 137, 211), + (151, 132, 203), (157, 110, 172), (153, 101, 160), (150, 93, 149), + (143, 88, 145), (136, 84, 142), (120, 68, 141), (106, 54, 131), + (80, 40, 128), (71, 43, 138), (63, 47, 148), (61, 49, 153), + (60, 51, 159), (61, 55, 163), (62, 58, 166), (63, 62, 169), + (65, 64, 173), (65, 67, 179), (66, 65, 179), (67, 63, 180), + (66, 62, 179), (66, 62, 178), (65, 60, 174), (61, 56, 168), + (56, 44, 156), (57, 43, 153), (58, 43, 150), (59, 45, 150), + (60, 47, 150), (65, 51, 150), (71, 58, 153), (77, 66, 159), + (84, 74, 164), (93, 91, 186), (96, 93, 190), (99, 96, 195), + (102, 100, 202), (108, 98, 200), (113, 90, 200), (118, 87, 199), + (125, 91, 209), (127, 93, 210), (130, 96, 212), (131, 97, 212), + (133, 98, 212), (139, 102, 214), (144, 113, 219), (153, 132, 226), + (161, 148, 231), (172, 172, 235), (174, 175, 236), (176, 178, 237), + (183, 182, 238), (185, 179, 239), (183, 177, 236), (176, 172, 229), + (158, 149, 217), (153, 135, 210), (148, 121, 203), (146, 116, 197), + (145, 111, 191), (137, 106, 185), (136, 106, 178), (139, 105, 178), + (140, 109, 182), (146, 113, 187), (145, 115, 186), (144, 118, 185), + (141, 117, 187), (138, 119, 187), (137, 117, 185), (137, 115, 181), + (139, 114, 156), (142, 116, 148), (145, 118, 141), (151, 120, 125), + (155, 124, 111), (158, 126, 97), (155, 123, 88), (152, 117, 83), + (150, 114, 80), (156, 120, 75), (157, 123, 73), (158, 127, 72), + (159, 126, 74), (161, 128, 76), (162, 130, 80), (168, 136, 83), + (173, 147, 85), (172, 146, 85), (172, 146, 86), (167, 142, 91), + (165, 139, 97), (163, 133, 106), (158, 120, 112), (154, 102, 116), + (146, 84, 123), (137, 74, 124), (134, 71, 125), (123, 64, 123), + (113, 53, 116), (98, 36, 113), (81, 24, 110), (74, 24, 97), + (50, 21, 79), (44, 18, 77), (38, 16, 75), (26, 11, 83), + (25, 14, 82), (31, 20, 87), (40, 30, 98), (52, 43, 113), + (67, 59, 131), (85, 77, 145), (105, 97, 155), (123, 116, 160), + (136, 128, 165), (148, 137, 164), (155, 141, 160), (155, 141, 158), + (154, 139, 152), (147, 132, 147), (140, 127, 145), (138, 122, 140), + (136, 119, 135), (138, 120, 131), (143, 126, 122), (149, 135, 120), + (158, 147, 118), (169, 157, 111), (179, 164, 102), (190, 174, 92), + (193, 178, 85), (192, 180, 85), (185, 171, 95), (169, 156, 102), + (157, 142, 111), (140, 128, 122), (129, 121, 132), (120, 111, 151), + (108, 101, 166), (101, 92, 172), (94, 86, 173), (91, 83, 163), + (94, 84, 158), (96, 84, 156), (101, 80, 160), (108, 77, 161), + (109, 76, 158), (108, 76, 157), (102, 75, 154), (96, 69, 157), + (92, 58, 162), (85, 52, 164), (79, 48, 167), (70, 46, 166), + (64, 46, 166), (61, 44, 166), (57, 43, 161), (54, 42, 157), + (51, 41, 152), (52, 39, 145), (54, 39, 139), (56, 36, 131), + (59, 34, 120), (62, 31, 113), (63, 33, 103), (65, 39, 103), + (71, 45, 105), (80, 51, 106), (95, 57, 110), (111, 72, 107), + (124, 92, 109), (119, 96, 121), (116, 100, 135), (120, 104, 151) + ), + +// 498 Beautiful +((215, 129, 52), (194, 131, 15), (204, 142, 14), (214, 153, 13), + (233, 147, 29), (252, 142, 45), (235, 142, 69), (219, 143, 94), + (190, 147, 174), (134, 139, 168), (79, 132, 163), (71, 113, 153), + (64, 94, 144), (65, 78, 135), (67, 62, 126), (65, 64, 125), + (64, 66, 125), (106, 108, 97), (153, 117, 88), (200, 126, 79), + (220, 131, 63), (240, 136, 47), (243, 139, 52), (246, 142, 57), + (219, 188, 71), (216, 173, 77), (214, 158, 83), (206, 136, 66), + (199, 114, 50), (190, 115, 36), (182, 116, 22), (155, 121, 0), + (136, 108, 8), (147, 144, 49), (130, 139, 63), (114, 135, 78), + (93, 101, 102), (72, 68, 127), (66, 69, 126), (61, 70, 125), + (38, 140, 154), (44, 150, 166), (51, 161, 178), (45, 156, 178), + (40, 151, 178), (33, 148, 159), (26, 145, 141), (52, 155, 125), + (96, 142, 78), (173, 127, 33), (187, 141, 62), (201, 156, 91), + (195, 156, 134), (190, 157, 178), (192, 161, 183), (195, 166, 188), + (183, 153, 187), (124, 162, 195), (66, 171, 203), (48, 174, 194), + (30, 177, 185), (26, 169, 185), (23, 162, 185), (37, 139, 177), + (70, 113, 155), (147, 96, 93), (170, 109, 75), (193, 122, 58), + (197, 122, 58), (202, 122, 59), (203, 122, 56), (205, 123, 47), + (255, 138, 38), (253, 141, 42), (252, 144, 46), (242, 172, 45), + (233, 200, 45), (227, 194, 68), (222, 188, 91), (211, 176, 156), + (194, 156, 177), (191, 144, 176), (184, 151, 161), (177, 159, 147), + (187, 156, 116), (198, 153, 86), (212, 142, 83), (200, 123, 69), + (166, 108, 88), (170, 74, 117), (174, 41, 146), (166, 40, 145), + (159, 39, 145), (147, 30, 134), (157, 19, 114), (134, 32, 132), + (82, 52, 126), (66, 72, 130), (60, 108, 142), (54, 144, 155), + (49, 144, 166), (44, 144, 178), (40, 153, 185), (49, 174, 204), + (77, 144, 170), (104, 134, 132), (131, 124, 95), (139, 118, 94), + (148, 113, 93), (144, 104, 112), (144, 106, 119), (96, 118, 132), + (54, 139, 178), (48, 99, 178), (65, 93, 162), (82, 88, 146), + (128, 57, 137), (156, 46, 143), (151, 43, 144), (134, 37, 130), + (71, 60, 129), (59, 84, 127), (47, 108, 126), (51, 113, 121), + (56, 118, 117), (66, 133, 149), (75, 132, 161), (152, 133, 163), + (182, 140, 190), (84, 143, 173), (74, 141, 170), (64, 139, 168), + (84, 132, 146), (151, 125, 128), (175, 114, 86), (204, 123, 58), + (208, 123, 40), (196, 122, 27), (184, 121, 15), (183, 118, 18), + (182, 116, 22), (143, 137, 39), (109, 119, 66), (103, 115, 69), + (68, 108, 71), (35, 80, 122), (39, 79, 125), (43, 79, 129), + (40, 67, 122), (44, 56, 114), (61, 40, 109), (74, 51, 119), + (103, 24, 116), (99, 26, 116), (95, 29, 116), (85, 34, 111), + (60, 30, 104), (60, 39, 106), (47, 58, 112), (43, 63, 113), + (49, 66, 109), (67, 41, 112), (86, 31, 123), (106, 22, 134), + (126, 21, 175), (186, 17, 196), (190, 6, 192), (157, 0, 159), + (122, 36, 143), (100, 55, 141), (79, 74, 140), (82, 102, 161), + (72, 150, 188), (73, 159, 184), (81, 160, 177), (149, 164, 143), + (172, 189, 83), (135, 201, 91), (101, 206, 166), (55, 168, 184), + (57, 160, 179), (49, 156, 172), (45, 141, 163), (31, 128, 135), + (46, 66, 116), (48, 55, 110), (50, 44, 104), (48, 39, 94), + (46, 11, 77), (21, 19, 82), (36, 21, 90), (39, 34, 92), + (54, 34, 103), (65, 45, 108), (102, 48, 126), (143, 38, 141), + (169, 41, 138), (185, 95, 97), (151, 102, 98), (143, 95, 91), + (85, 58, 93), (50, 55, 111), (40, 48, 110), (31, 56, 110), + (37, 46, 101), (36, 34, 109), (47, 35, 109), (48, 41, 108), + (63, 59, 118), (119, 85, 118), (143, 104, 87), (153, 118, 90), + (155, 149, 53), (165, 152, 58), (185, 176, 71), (187, 179, 80), + (206, 159, 77), (203, 154, 88), (183, 161, 85), (171, 168, 87), + (161, 162, 82), (171, 161, 76), (173, 128, 95), (178, 131, 105), + (187, 146, 160), (171, 117, 153), (154, 53, 183), (146, 50, 176), + (159, 64, 184), (188, 135, 177), (186, 152, 189), (189, 156, 185), + (186, 156, 194), (63, 190, 222), (23, 220, 239), (23, 220, 239), + (54, 177, 210), (57, 154, 187), (58, 144, 167), (49, 86, 138), + (69, 66, 133), (74, 66, 123), (105, 115, 62), (174, 122, 13), + (199, 119, 20), (208, 137, 0), (209, 144, 14), (203, 151, 13), + (206, 143, 12), (200, 136, 13), (191, 124, 17), (179, 113, 17), + (165, 124, 0), (177, 133, 0), (213, 155, 12), (197, 144, 2) + ), + +// 499 Before_Dawn +((85, 88, 111), (80, 81, 94), (91, 90, 103), (102, 100, 113), + (118, 117, 129), (135, 134, 145), (139, 138, 149), (144, 143, 154), + (143, 142, 158), (134, 134, 150), (126, 126, 142), (107, 108, 125), + (88, 91, 109), (73, 75, 90), (58, 59, 71), (49, 51, 62), + (41, 43, 54), (16, 18, 27), (11, 12, 19), (6, 7, 12), + (5, 5, 8), (4, 4, 4), (3, 3, 3), (3, 3, 3), + (2, 3, 2), (1, 2, 2), (1, 2, 3), (1, 1, 2), + (1, 0, 2), (0, 0, 2), (0, 0, 2), (0, 0, 3), + (0, 0, 4), (0, 0, 6), (0, 0, 7), (0, 1, 9), + (1, 2, 12), (3, 4, 15), (4, 6, 17), (6, 8, 20), + (16, 20, 34), (24, 28, 46), (32, 37, 58), (36, 43, 68), + (40, 50, 79), (40, 50, 79), (41, 50, 79), (40, 48, 78), + (36, 46, 78), (25, 35, 67), (20, 28, 53), (15, 22, 40), + (12, 18, 36), (10, 15, 33), (10, 14, 31), (10, 13, 29), + (9, 12, 20), (7, 10, 19), (6, 8, 18), (4, 6, 16), + (3, 5, 14), (2, 4, 13), (2, 4, 13), (1, 3, 12), + (1, 3, 11), (1, 2, 8), (1, 2, 8), (1, 2, 9), + (1, 2, 10), (2, 3, 11), (4, 5, 15), (5, 7, 20), + (8, 12, 27), (9, 13, 30), (10, 14, 33), (10, 14, 32), + (10, 15, 32), (10, 14, 29), (10, 14, 27), (10, 13, 24), + (9, 12, 23), (11, 15, 26), (13, 17, 30), (16, 19, 35), + (18, 21, 38), (20, 24, 42), (25, 30, 49), (28, 34, 56), + (42, 48, 74), (51, 56, 82), (60, 64, 90), (62, 66, 94), + (64, 69, 99), (66, 73, 102), (66, 72, 103), (65, 69, 98), + (60, 64, 92), (40, 46, 70), (31, 36, 56), (23, 26, 42), + (20, 22, 36), (18, 19, 30), (11, 14, 24), (9, 12, 22), + (13, 15, 26), (20, 23, 36), (28, 32, 47), (33, 37, 53), + (38, 42, 60), (46, 52, 79), (50, 59, 95), (51, 60, 103), + (51, 58, 99), (42, 50, 88), (35, 43, 82), (29, 37, 77), + (20, 25, 59), (13, 15, 38), (8, 10, 23), (4, 5, 15), + (2, 2, 10), (4, 4, 13), (6, 7, 16), (8, 9, 20), + (10, 12, 24), (17, 19, 34), (27, 30, 49), (40, 43, 65), + (51, 56, 82), (71, 80, 112), (77, 85, 118), (83, 91, 124), + (93, 100, 132), (97, 104, 132), (98, 106, 132), (95, 101, 125), + (84, 85, 105), (77, 77, 93), (71, 69, 82), (66, 65, 77), + (62, 61, 73), (56, 54, 68), (54, 52, 67), (56, 52, 64), + (58, 55, 67), (69, 69, 91), (73, 72, 97), (77, 76, 103), + (84, 84, 113), (94, 94, 124), (105, 107, 139), (116, 117, 149), + (125, 126, 150), (123, 126, 148), (122, 126, 147), (115, 118, 141), + (105, 108, 128), (90, 92, 111), (72, 75, 92), (52, 55, 74), + (35, 37, 56), (13, 14, 24), (10, 10, 19), (7, 7, 14), + (3, 3, 7), (1, 0, 3), (0, 0, 1), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 1, 1), (1, 2, 2), (2, 3, 3), (5, 6, 7), + (10, 11, 13), (17, 19, 24), (29, 30, 38), (45, 46, 56), + (65, 65, 76), (84, 84, 100), (106, 106, 125), (126, 130, 154), + (169, 173, 199), (177, 181, 205), (186, 189, 211), (197, 200, 223), + (212, 217, 238), (224, 228, 248), (233, 236, 247), (234, 235, 245), + (236, 237, 246), (238, 236, 245), (236, 235, 241), (225, 226, 236), + (214, 215, 230), (209, 208, 224), (208, 205, 218), (202, 202, 216), + (195, 195, 211), (191, 191, 207), (192, 192, 205), (191, 193, 205), + (188, 189, 204), (182, 183, 201), (175, 176, 194), (163, 166, 185), + (151, 154, 175), (133, 138, 162), (116, 120, 146), (94, 98, 122), + (74, 77, 101), (52, 57, 82), (35, 41, 64), (21, 25, 44), + (10, 13, 29), (3, 5, 20), (0, 2, 15), (0, 1, 10), + (2, 2, 7), (4, 4, 8), (7, 8, 13), (13, 14, 20), + (22, 23, 29), (35, 37, 42), (51, 54, 62), (71, 73, 84), + (90, 93, 107), (108, 111, 127), (125, 129, 146), (142, 145, 164), + (155, 156, 175), (162, 162, 183), (165, 166, 187), (164, 165, 189), + (157, 159, 184), (146, 148, 174), (135, 138, 162), (123, 127, 153), + (104, 111, 139), (82, 90, 120), (63, 72, 99), (50, 58, 82), + (38, 45, 66), (26, 33, 53), (19, 26, 45), (19, 25, 43), + (23, 28, 46), (33, 37, 55), (45, 51, 69), (61, 68, 88), + (74, 81, 104), (68, 74, 95), (64, 68, 87), (65, 69, 89) + ), + +// 500 Beginning_to_Thaw +((205, 239, 212), (205, 231, 216), (202, 226, 212), (200, 222, 209), + (191, 210, 195), (182, 198, 181), (175, 189, 171), (168, 180, 161), + (131, 153, 115), (119, 141, 97), (107, 130, 80), (112, 123, 79), + (117, 116, 79), (128, 124, 83), (139, 132, 87), (145, 137, 89), + (151, 142, 92), (179, 162, 122), (185, 169, 136), (191, 177, 151), + (191, 188, 158), (191, 199, 165), (191, 202, 169), (191, 205, 173), + (187, 191, 178), (181, 185, 163), (176, 179, 149), (169, 168, 142), + (163, 157, 135), (161, 150, 134), (160, 144, 134), (155, 138, 117), + (152, 140, 106), (151, 140, 103), (156, 139, 114), (162, 138, 126), + (170, 147, 132), (178, 156, 138), (180, 159, 137), (183, 163, 137), + (176, 148, 129), (159, 135, 114), (143, 123, 100), (121, 110, 81), + (99, 98, 63), (87, 91, 54), (76, 84, 46), (57, 77, 28), + (41, 66, 17), (31, 66, 8), (38, 70, 8), (46, 75, 9), + (51, 79, 11), (56, 83, 14), (59, 86, 19), (62, 90, 25), + (86, 120, 51), (97, 126, 60), (109, 133, 70), (106, 132, 82), + (103, 132, 94), (99, 134, 105), (96, 136, 116), (101, 147, 138), + (105, 159, 156), (117, 166, 169), (113, 158, 170), (110, 151, 172), + (110, 149, 172), (111, 147, 172), (116, 142, 169), (128, 140, 156), + (135, 117, 124), (138, 105, 109), (141, 93, 94), (137, 88, 86), + (133, 83, 79), (134, 82, 77), (135, 81, 76), (142, 84, 83), + (154, 93, 96), (167, 121, 128), (166, 128, 139), (166, 135, 151), + (169, 137, 155), (173, 139, 159), (182, 142, 161), (188, 146, 156), + (180, 135, 128), (173, 120, 108), (166, 106, 89), (162, 102, 80), + (158, 98, 72), (153, 87, 56), (144, 82, 44), (142, 80, 37), + (142, 78, 37), (144, 81, 53), (134, 80, 60), (125, 80, 68), + (119, 81, 68), (113, 83, 68), (101, 84, 67), (96, 82, 67), + (86, 77, 72), (82, 91, 79), (78, 105, 86), (77, 112, 89), + (77, 120, 93), (84, 137, 100), (99, 152, 107), (115, 172, 126), + (138, 197, 144), (164, 229, 171), (167, 231, 170), (171, 234, 169), + (169, 234, 159), (165, 224, 151), (161, 211, 143), (150, 192, 135), + (134, 153, 106), (127, 133, 85), (120, 114, 64), (115, 102, 56), + (111, 91, 49), (100, 74, 38), (93, 58, 31), (86, 53, 23), + (86, 54, 16), (92, 61, 18), (92, 63, 21), (93, 65, 24), + (95, 78, 34), (105, 99, 48), (122, 119, 61), (138, 140, 80), + (151, 166, 115), (157, 175, 129), (164, 184, 143), (165, 186, 147), + (167, 189, 151), (163, 187, 150), (144, 178, 149), (126, 165, 145), + (116, 151, 141), (113, 141, 140), (112, 140, 140), (111, 139, 141), + (107, 141, 142), (112, 145, 144), (124, 153, 149), (146, 169, 156), + (183, 196, 180), (188, 201, 185), (193, 207, 191), (199, 216, 201), + (205, 224, 203), (215, 226, 202), (221, 228, 200), (223, 227, 200), + (217, 229, 207), (200, 223, 215), (198, 221, 215), (196, 220, 215), + (193, 219, 216), (188, 225, 219), (182, 226, 220), (180, 222, 218), + (188, 215, 209), (189, 216, 208), (191, 217, 208), (195, 219, 204), + (204, 218, 200), (206, 211, 192), (215, 205, 182), (218, 201, 178), + (215, 199, 177), (218, 199, 179), (212, 194, 181), (207, 191, 183), + (203, 190, 186), (196, 189, 186), (195, 190, 184), (196, 190, 183), + (195, 204, 187), (195, 208, 190), (195, 213, 194), (195, 221, 197), + (203, 224, 201), (205, 229, 207), (211, 237, 214), (216, 246, 226), + (216, 250, 233), (221, 249, 239), (225, 243, 241), (231, 239, 240), + (236, 239, 241), (237, 240, 240), (235, 242, 242), (230, 239, 243), + (227, 234, 240), (223, 228, 233), (222, 224, 225), (218, 221, 219), + (212, 213, 212), (209, 205, 204), (208, 194, 196), (212, 186, 189), + (218, 181, 188), (224, 178, 185), (229, 180, 181), (232, 184, 176), + (238, 191, 173), (241, 200, 179), (241, 209, 187), (237, 216, 195), + (231, 225, 199), (224, 230, 199), (220, 233, 201), (214, 232, 203), + (210, 227, 206), (207, 221, 207), (206, 216, 208), (209, 214, 209), + (211, 212, 211), (217, 214, 213), (218, 215, 210), (224, 219, 207), + (232, 223, 206), (238, 227, 208), (240, 230, 214), (232, 233, 219), + (220, 233, 218), (210, 229, 215), (200, 224, 211), (196, 213, 208), + (186, 202, 202), (176, 189, 194), (172, 178, 188), (170, 167, 178), + (176, 160, 175), (179, 156, 170), (183, 152, 162), (192, 152, 161), + (204, 152, 157), (216, 155, 159), (227, 164, 160), (231, 175, 154), + (231, 186, 153), (231, 196, 156), (223, 202, 159), (219, 208, 164), + (214, 215, 169), (211, 224, 175), (210, 233, 188), (207, 237, 203) + ), + +// 501 Beige +((106, 95, 83), (97, 88, 77), (89, 81, 72), (81, 74, 67), + (69, 64, 60), (57, 54, 53), (55, 53, 52), (53, 52, 51), + (50, 50, 49), (50, 50, 49), (51, 51, 49), (53, 52, 50), + (56, 54, 51), (59, 56, 53), (62, 58, 56), (62, 59, 56), + (63, 60, 57), (63, 61, 58), (63, 61, 58), (63, 61, 59), + (64, 62, 59), (66, 63, 60), (67, 63, 60), (68, 63, 61), + (67, 62, 60), (67, 62, 59), (67, 62, 59), (68, 63, 60), + (70, 65, 62), (72, 66, 64), (74, 68, 66), (77, 70, 69), + (79, 72, 71), (83, 74, 72), (83, 74, 72), (83, 75, 72), + (84, 75, 72), (85, 76, 73), (85, 76, 73), (85, 77, 74), + (88, 78, 74), (90, 79, 74), (92, 80, 74), (94, 81, 74), + (96, 83, 75), (97, 84, 75), (98, 85, 75), (102, 88, 76), + (107, 91, 77), (120, 98, 82), (123, 100, 84), (127, 103, 87), + (126, 104, 88), (126, 106, 89), (125, 106, 89), (125, 106, 89), + (123, 104, 87), (122, 102, 86), (121, 100, 85), (116, 97, 83), + (112, 95, 81), (109, 93, 80), (106, 91, 79), (99, 86, 76), + (95, 82, 73), (89, 76, 67), (89, 75, 66), (90, 75, 66), + (90, 75, 66), (91, 76, 67), (93, 78, 69), (96, 81, 73), + (105, 89, 80), (110, 93, 84), (115, 98, 88), (118, 101, 91), + (121, 105, 94), (122, 106, 95), (123, 107, 97), (122, 108, 99), + (120, 107, 99), (114, 102, 94), (107, 97, 89), (100, 92, 85), + (96, 89, 82), (92, 86, 80), (84, 79, 74), (76, 72, 68), + (65, 61, 57), (61, 56, 53), (58, 52, 49), (57, 51, 48), + (56, 50, 47), (55, 49, 46), (55, 49, 46), (56, 49, 46), + (58, 50, 46), (65, 54, 46), (69, 56, 47), (73, 58, 48), + (74, 59, 48), (75, 60, 49), (77, 62, 52), (80, 65, 54), + (90, 74, 60), (97, 79, 64), (104, 84, 68), (107, 86, 70), + (110, 89, 73), (117, 95, 78), (122, 101, 83), (125, 105, 88), + (128, 109, 93), (133, 114, 100), (133, 115, 101), (133, 116, 102), + (134, 116, 104), (133, 115, 103), (129, 114, 101), (124, 110, 98), + (112, 101, 91), (106, 97, 88), (100, 93, 85), (98, 91, 83), + (97, 89, 81), (94, 86, 78), (91, 83, 73), (88, 79, 70), + (84, 76, 68), (76, 71, 63), (75, 70, 62), (74, 70, 62), + (73, 69, 63), (73, 69, 62), (74, 69, 62), (74, 69, 62), + (76, 70, 63), (78, 71, 64), (81, 72, 66), (82, 73, 67), + (84, 75, 68), (88, 78, 70), (94, 84, 75), (103, 91, 82), + (115, 100, 91), (148, 127, 112), (157, 135, 118), (166, 143, 125), + (180, 157, 136), (191, 167, 145), (197, 172, 150), (198, 174, 152), + (195, 170, 149), (194, 169, 148), (193, 168, 148), (189, 166, 143), + (183, 162, 139), (173, 153, 133), (161, 142, 124), (143, 128, 113), + (125, 112, 100), (94, 85, 76), (88, 80, 72), (82, 76, 69), + (72, 68, 63), (66, 62, 59), (60, 58, 56), (56, 55, 53), + (52, 53, 52), (52, 53, 52), (52, 53, 52), (53, 53, 52), + (53, 53, 52), (54, 53, 52), (55, 54, 53), (58, 55, 53), + (60, 57, 55), (63, 59, 57), (67, 61, 59), (71, 65, 63), + (78, 70, 67), (85, 75, 72), (93, 83, 78), (103, 91, 86), + (119, 103, 97), (121, 105, 99), (123, 107, 101), (125, 109, 102), + (125, 109, 101), (124, 108, 100), (123, 109, 102), (122, 107, 100), + (121, 106, 98), (117, 103, 95), (111, 98, 91), (104, 91, 85), + (94, 84, 77), (84, 77, 71), (75, 70, 65), (69, 65, 61), + (64, 61, 57), (60, 58, 55), (58, 55, 54), (57, 54, 53), + (57, 54, 52), (57, 54, 52), (57, 54, 52), (57, 53, 52), + (56, 53, 52), (56, 53, 52), (56, 52, 51), (56, 52, 50), + (56, 51, 50), (56, 51, 49), (57, 52, 49), (57, 52, 50), + (59, 54, 51), (60, 55, 52), (63, 58, 54), (67, 61, 55), + (71, 64, 58), (76, 68, 61), (81, 73, 64), (84, 76, 68), + (88, 79, 71), (90, 81, 73), (92, 83, 74), (93, 83, 75), + (92, 83, 74), (93, 83, 73), (91, 82, 73), (89, 80, 71), + (85, 77, 69), (81, 73, 66), (76, 69, 63), (70, 64, 59), + (65, 60, 56), (61, 56, 53), (57, 53, 51), (55, 52, 49), + (54, 51, 48), (56, 52, 48), (58, 54, 49), (61, 57, 51), + (65, 61, 54), (70, 66, 57), (77, 71, 62), (86, 79, 67), + (96, 87, 73), (108, 98, 80), (110, 100, 82), (111, 101, 83), + (111, 100, 83), (108, 97, 82), (105, 95, 81), (101, 90, 80) + ), + +// 502 Berry_Bush +((160, 10, 24), (195, 13, 23), (194, 17, 27), (193, 22, 31), + (180, 30, 34), (168, 38, 38), (162, 42, 41), (156, 46, 44), + (141, 61, 52), (132, 71, 55), (124, 82, 59), (110, 86, 58), + (96, 91, 58), (83, 86, 58), (70, 82, 58), (67, 79, 59), + (65, 76, 60), (73, 70, 59), (86, 66, 52), (100, 62, 46), + (108, 53, 44), (117, 44, 43), (120, 41, 43), (124, 39, 43), + (149, 38, 34), (167, 45, 29), (185, 52, 24), (198, 63, 26), + (211, 74, 28), (212, 79, 28), (213, 85, 28), (208, 97, 28), + (200, 111, 28), (190, 140, 35), (190, 151, 39), (190, 162, 43), + (186, 168, 40), (183, 175, 38), (177, 176, 39), (171, 178, 40), + (131, 192, 59), (117, 193, 66), (104, 195, 74), (95, 188, 67), + (87, 182, 61), (82, 178, 58), (78, 175, 56), (72, 174, 57), + (69, 170, 67), (42, 160, 64), (36, 147, 55), (31, 135, 46), + (44, 123, 47), (57, 112, 49), (58, 109, 51), (60, 107, 53), + (52, 120, 71), (40, 126, 74), (29, 132, 77), (35, 126, 78), + (42, 121, 79), (43, 123, 78), (44, 126, 77), (39, 133, 75), + (34, 148, 72), (31, 181, 66), (45, 177, 53), (59, 173, 41), + (65, 165, 36), (71, 157, 31), (78, 140, 22), (77, 134, 16), + (66, 115, 16), (68, 104, 19), (71, 93, 23), (77, 79, 26), + (83, 65, 29), (83, 57, 30), (84, 50, 32), (84, 41, 27), + (80, 36, 23), (97, 44, 22), (108, 55, 23), (120, 66, 25), + (123, 69, 25), (127, 73, 26), (125, 72, 21), (121, 68, 19), + (104, 60, 13), (96, 63, 16), (88, 66, 19), (79, 65, 19), + (71, 64, 19), (54, 62, 19), (38, 57, 22), (20, 48, 22), + (14, 45, 19), (18, 53, 28), (29, 60, 34), (41, 67, 41), + (47, 71, 46), (53, 76, 51), (67, 83, 59), (81, 97, 63), + (110, 116, 71), (119, 126, 72), (129, 137, 73), (129, 142, 76), + (130, 147, 80), (122, 163, 84), (116, 176, 90), (108, 181, 100), + (98, 174, 94), (77, 154, 78), (67, 151, 74), (58, 149, 70), + (41, 153, 61), (26, 164, 68), (16, 168, 64), (11, 164, 58), + (27, 130, 44), (44, 118, 34), (61, 107, 24), (71, 109, 22), + (81, 111, 20), (99, 119, 16), (114, 128, 15), (128, 128, 21), + (148, 125, 30), (179, 130, 75), (177, 134, 83), (175, 138, 92), + (166, 154, 107), (147, 168, 120), (125, 181, 124), (115, 196, 141), + (89, 214, 168), (75, 220, 169), (61, 227, 170), (55, 224, 160), + (49, 222, 150), (47, 215, 136), (50, 209, 119), (54, 207, 109), + (57, 205, 93), (50, 210, 71), (52, 210, 67), (55, 210, 64), + (54, 206, 58), (50, 202, 55), (49, 201, 50), (40, 198, 45), + (27, 196, 40), (26, 191, 40), (25, 186, 40), (22, 177, 42), + (24, 174, 45), (25, 173, 47), (22, 172, 55), (22, 177, 60), + (22, 180, 67), (19, 183, 86), (18, 186, 92), (18, 190, 99), + (15, 196, 118), (13, 204, 133), (11, 211, 144), (10, 217, 149), + (21, 214, 145), (28, 209, 143), (35, 204, 141), (51, 191, 135), + (69, 170, 126), (87, 150, 110), (101, 133, 98), (118, 118, 82), + (137, 101, 70), (153, 89, 59), (170, 74, 49), (181, 58, 39), + (182, 46, 35), (176, 39, 33), (164, 33, 35), (151, 35, 36), + (119, 48, 39), (110, 56, 41), (101, 65, 43), (82, 83, 54), + (61, 99, 68), (43, 115, 82), (30, 131, 95), (19, 142, 101), + (14, 157, 108), (10, 176, 117), (6, 191, 128), (6, 203, 138), + (10, 214, 146), (17, 216, 147), (31, 207, 145), (48, 199, 137), + (66, 188, 124), (86, 171, 109), (102, 156, 96), (112, 146, 82), + (122, 135, 76), (135, 127, 74), (142, 118, 68), (149, 107, 60), + (156, 92, 53), (154, 82, 45), (143, 76, 40), (134, 78, 43), + (118, 83, 47), (100, 94, 55), (86, 108, 63), (75, 116, 70), + (61, 122, 70), (51, 129, 70), (42, 134, 67), (33, 135, 64), + (28, 139, 62), (23, 142, 61), (20, 147, 61), (17, 153, 60), + (14, 158, 58), (10, 156, 57), (10, 151, 52), (14, 139, 46), + (20, 130, 42), (29, 119, 39), (39, 115, 38), (49, 117, 44), + (59, 121, 50), (76, 113, 55), (91, 104, 57), (109, 91, 58), + (119, 79, 58), (126, 71, 57), (122, 71, 55), (119, 68, 53), + (111, 62, 50), (109, 56, 48), (100, 49, 49), (91, 41, 50), + (77, 37, 56), (62, 39, 56), (45, 34, 54), (35, 30, 51), + (34, 26, 45), (46, 24, 38), (64, 18, 41), (85, 17, 41), + (105, 12, 40), (119, 10, 39), (126, 7, 34), (143, 10, 27) + ), + +// 503 Biology_Class +((157, 53, 16), (163, 96, 4), (158, 117, 4), (154, 138, 4), + (145, 159, 7), (136, 181, 10), (132, 189, 11), (129, 198, 12), + (103, 216, 9), (83, 213, 10), (64, 210, 11), (49, 198, 11), + (35, 186, 12), (27, 169, 15), (19, 152, 19), (14, 141, 20), + (10, 131, 22), (3, 86, 22), (3, 68, 23), (4, 50, 24), + (11, 48, 24), (19, 46, 25), (24, 50, 22), (30, 55, 19), + (43, 77, 8), (46, 86, 4), (50, 95, 1), (50, 100, 0), + (50, 106, 0), (48, 105, 2), (46, 105, 4), (47, 102, 10), + (44, 92, 19), (35, 60, 39), (36, 46, 50), (38, 33, 62), + (51, 26, 77), (64, 20, 92), (73, 19, 99), (83, 19, 106), + (113, 15, 127), (126, 15, 134), (139, 15, 141), (144, 16, 146), + (150, 17, 151), (148, 18, 151), (146, 19, 152), (137, 22, 149), + (126, 22, 152), (93, 18, 153), (77, 17, 142), (61, 16, 132), + (51, 15, 122), (41, 15, 112), (38, 15, 106), (35, 16, 101), + (27, 19, 74), (24, 22, 67), (21, 25, 60), (19, 31, 58), + (17, 38, 57), (15, 43, 56), (13, 48, 55), (7, 56, 49), + (3, 69, 45), (13, 96, 40), (20, 105, 37), (27, 115, 34), + (28, 116, 29), (29, 117, 24), (32, 116, 15), (35, 114, 10), + (45, 106, 28), (44, 97, 39), (44, 88, 50), (37, 78, 56), + (30, 68, 62), (27, 63, 65), (25, 59, 68), (20, 55, 73), + (18, 53, 80), (15, 52, 82), (13, 52, 79), (11, 53, 76), + (10, 54, 72), (9, 55, 69), (8, 60, 59), (11, 70, 51), + (29, 101, 42), (36, 119, 35), (44, 137, 28), (47, 144, 24), + (50, 152, 20), (56, 164, 15), (66, 173, 18), (77, 179, 26), + (86, 179, 34), (94, 160, 48), (91, 142, 51), (88, 124, 55), + (86, 118, 55), (84, 112, 56), (77, 99, 54), (67, 92, 51), + (42, 91, 39), (35, 99, 35), (28, 107, 32), (25, 111, 31), + (23, 115, 31), (25, 127, 30), (36, 138, 29), (49, 145, 31), + (62, 149, 34), (86, 144, 38), (93, 140, 38), (101, 136, 39), + (114, 125, 39), (122, 110, 38), (130, 97, 33), (131, 82, 30), + (128, 53, 37), (125, 39, 47), (122, 26, 57), (120, 21, 60), + (119, 16, 64), (110, 8, 69), (96, 5, 76), (81, 3, 85), + (70, 7, 95), (47, 21, 105), (40, 25, 102), (34, 30, 100), + (19, 36, 92), (8, 44, 83), (4, 55, 71), (3, 70, 62), + (19, 104, 46), (31, 118, 39), (43, 132, 32), (48, 139, 28), + (53, 146, 25), (63, 159, 21), (70, 167, 18), (78, 169, 21), + (83, 168, 24), (84, 153, 27), (83, 145, 27), (83, 138, 28), + (84, 120, 29), (87, 101, 29), (89, 80, 31), (97, 61, 32), + (110, 32, 30), (112, 27, 27), (115, 23, 24), (113, 20, 19), + (112, 19, 17), (109, 21, 12), (103, 27, 12), (97, 31, 8), + (87, 34, 4), (72, 43, 0), (72, 49, 0), (72, 56, 0), + (77, 71, 0), (83, 81, 0), (84, 85, 3), (81, 87, 6), + (67, 97, 13), (64, 100, 14), (61, 104, 16), (55, 106, 20), + (45, 106, 23), (33, 103, 25), (19, 98, 27), (8, 93, 33), + (2, 86, 42), (1, 80, 51), (1, 73, 60), (3, 61, 62), + (12, 50, 66), (25, 41, 76), (40, 33, 81), (53, 26, 86), + (66, 7, 75), (69, 4, 71), (73, 2, 67), (80, 4, 58), + (88, 15, 50), (94, 31, 45), (95, 49, 39), (90, 63, 32), + (81, 72, 26), (74, 83, 21), (68, 92, 19), (66, 100, 20), + (64, 102, 20), (60, 95, 19), (61, 86, 22), (61, 73, 27), + (63, 58, 34), (62, 45, 41), (55, 29, 42), (49, 19, 47), + (45, 15, 54), (42, 15, 63), (41, 18, 77), (36, 22, 85), + (25, 25, 93), (14, 30, 99), (4, 36, 104), (0, 43, 110), + (0, 50, 114), (0, 53, 117), (3, 55, 117), (10, 55, 113), + (19, 56, 105), (30, 58, 93), (40, 58, 79), (48, 60, 64), + (56, 58, 53), (61, 56, 45), (66, 57, 43), (66, 55, 44), + (63, 58, 49), (59, 62, 57), (50, 66, 67), (41, 76, 81), + (29, 83, 91), (19, 89, 96), (13, 98, 96), (8, 105, 91), + (7, 117, 87), (12, 127, 82), (22, 128, 72), (32, 122, 59), + (44, 111, 43), (53, 99, 28), (67, 90, 23), (88, 82, 21), + (108, 70, 25), (126, 61, 37), (139, 50, 44), (150, 39, 53), + (163, 34, 62), (173, 27, 68), (179, 25, 78), (181, 23, 84), + (180, 20, 86), (179, 17, 85), (177, 10, 77), (175, 5, 66), + (170, 3, 54), (165, 7, 42), (160, 17, 31), (157, 33, 23) + ), + +// 504 Birthday_Party +((55, 78, 72), (63, 106, 50), (58, 130, 45), (53, 155, 41), + (60, 159, 59), (68, 164, 78), (74, 164, 86), (80, 164, 95), + (98, 167, 109), (109, 167, 131), (121, 168, 154), (129, 163, 171), + (138, 158, 188), (142, 162, 186), (147, 167, 185), (148, 165, 184), + (149, 164, 184), (154, 169, 196), (154, 173, 199), (155, 178, 202), + (153, 173, 193), (152, 169, 184), (152, 164, 177), (152, 160, 170), + (144, 123, 153), (143, 105, 142), (142, 87, 131), (144, 71, 116), + (147, 56, 102), (148, 51, 99), (150, 47, 96), (156, 41, 92), + (162, 36, 93), (165, 39, 82), (169, 43, 73), (173, 48, 65), + (179, 47, 60), (186, 46, 55), (185, 44, 51), (185, 43, 47), + (178, 32, 35), (180, 27, 40), (183, 23, 46), (189, 20, 58), + (196, 18, 71), (199, 19, 76), (202, 20, 81), (201, 25, 93), + (203, 33, 100), (209, 53, 112), (212, 58, 121), (215, 63, 131), + (204, 63, 131), (193, 64, 131), (184, 64, 125), (175, 65, 120), + (150, 94, 102), (140, 99, 94), (131, 104, 87), (129, 105, 73), + (128, 106, 59), (127, 109, 54), (127, 113, 49), (133, 118, 55), + (137, 108, 59), (151, 77, 65), (151, 64, 78), (152, 51, 92), + (150, 43, 98), (149, 35, 105), (155, 25, 102), (149, 20, 98), + (125, 32, 80), (123, 49, 79), (121, 66, 78), (124, 88, 70), + (127, 111, 63), (127, 120, 60), (127, 130, 58), (119, 144, 64), + (114, 154, 75), (132, 172, 96), (139, 177, 105), (147, 183, 115), + (141, 181, 118), (136, 180, 121), (131, 166, 121), (125, 158, 115), + (129, 137, 103), (129, 122, 103), (130, 108, 104), (132, 102, 105), + (135, 97, 106), (135, 90, 113), (138, 84, 120), (144, 82, 133), + (144, 82, 151), (147, 95, 187), (138, 112, 196), (129, 130, 205), + (125, 137, 206), (121, 145, 207), (116, 155, 205), (121, 156, 204), + (126, 158, 185), (131, 155, 177), (136, 152, 169), (140, 146, 168), + (145, 140, 167), (147, 125, 164), (144, 109, 160), (136, 99, 152), + (126, 88, 141), (107, 79, 120), (104, 74, 118), (101, 69, 116), + (93, 65, 112), (87, 67, 106), (88, 75, 103), (96, 88, 99), + (125, 94, 120), (140, 95, 135), (155, 97, 150), (160, 100, 153), + (166, 103, 157), (176, 108, 155), (183, 108, 158), (192, 110, 161), + (196, 109, 164), (207, 133, 151), (201, 140, 148), (195, 148, 145), + (186, 165, 140), (165, 173, 150), (148, 183, 164), (136, 196, 173), + (102, 218, 178), (85, 216, 176), (69, 215, 175), (64, 215, 174), + (60, 215, 174), (51, 202, 175), (62, 193, 164), (84, 182, 149), + (108, 165, 136), (146, 144, 129), (155, 139, 129), (164, 135, 129), + (186, 126, 128), (204, 114, 127), (213, 107, 122), (212, 102, 120), + (191, 100, 104), (186, 96, 98), (182, 93, 92), (167, 95, 77), + (152, 93, 65), (139, 93, 53), (130, 91, 50), (131, 85, 55), + (131, 90, 59), (116, 111, 79), (112, 114, 84), (109, 118, 89), + (110, 115, 107), (118, 109, 128), (131, 106, 150), (134, 114, 165), + (138, 121, 176), (139, 120, 178), (140, 119, 180), (150, 106, 189), + (154, 97, 193), (157, 91, 198), (151, 88, 203), (139, 83, 192), + (131, 75, 187), (120, 61, 179), (121, 48, 160), (116, 39, 155), + (116, 27, 131), (120, 21, 109), (126, 20, 94), (146, 24, 79), + (170, 46, 79), (171, 52, 79), (172, 58, 80), (168, 72, 84), + (169, 83, 96), (163, 98, 119), (155, 110, 136), (142, 118, 156), + (128, 126, 169), (119, 128, 173), (112, 130, 179), (109, 125, 170), + (99, 112, 162), (92, 99, 151), (91, 85, 135), (90, 79, 122), + (102, 71, 103), (107, 59, 83), (116, 49, 64), (129, 44, 50), + (138, 58, 45), (154, 78, 44), (169, 101, 52), (181, 109, 57), + (191, 110, 67), (198, 115, 76), (202, 111, 85), (208, 119, 108), + (211, 110, 127), (215, 97, 139), (215, 86, 145), (214, 69, 136), + (210, 62, 128), (200, 49, 122), (194, 43, 108), (191, 37, 99), + (197, 36, 81), (207, 45, 67), (204, 42, 59), (195, 43, 50), + (186, 37, 47), (187, 33, 45), (199, 40, 52), (213, 51, 65), + (218, 65, 77), (208, 79, 94), (197, 93, 108), (179, 102, 119), + (164, 118, 132), (150, 125, 138), (133, 131, 142), (118, 131, 149), + (103, 125, 161), (91, 125, 172), (78, 122, 184), (76, 132, 185), + (75, 138, 184), (80, 147, 188), (83, 156, 188), (84, 156, 190), + (86, 160, 182), (85, 156, 167), (87, 151, 161), (77, 148, 149), + (72, 133, 138), (66, 113, 127), (68, 90, 109), (71, 63, 102), + (67, 59, 93), (63, 62, 80), (49, 70, 79), (55, 81, 75) + ), + +// 505 Bistro +((181, 69, 63), (185, 79, 72), (191, 77, 72), (197, 76, 72), + (196, 67, 65), (195, 58, 58), (191, 53, 54), (188, 48, 50), + (173, 41, 43), (171, 42, 46), (169, 44, 49), (171, 48, 51), + (174, 52, 53), (175, 58, 54), (176, 65, 55), (176, 66, 53), + (177, 67, 51), (183, 76, 48), (190, 83, 47), (197, 91, 46), + (204, 109, 39), (211, 127, 33), (211, 131, 30), (211, 136, 27), + (196, 129, 17), (186, 120, 16), (176, 111, 15), (168, 112, 16), + (161, 114, 17), (156, 113, 19), (152, 112, 21), (140, 104, 25), + (128, 91, 30), (112, 68, 44), (113, 72, 51), (115, 77, 58), + (124, 92, 69), (133, 107, 80), (137, 112, 84), (142, 117, 89), + (165, 138, 104), (173, 142, 106), (181, 147, 109), (180, 145, 108), + (179, 144, 107), (175, 139, 105), (171, 135, 103), (164, 123, 95), + (157, 106, 85), (154, 81, 66), (152, 73, 61), (150, 65, 57), + (151, 62, 58), (152, 60, 60), (154, 61, 61), (157, 62, 62), + (162, 65, 62), (162, 64, 62), (162, 63, 63), (160, 61, 62), + (158, 59, 62), (157, 59, 60), (156, 60, 59), (147, 56, 54), + (134, 49, 47), (101, 34, 28), (91, 32, 22), (81, 30, 17), + (80, 32, 16), (80, 34, 16), (84, 36, 16), (90, 39, 21), + (109, 50, 35), (117, 57, 37), (126, 64, 40), (137, 69, 36), + (149, 75, 32), (158, 80, 31), (168, 85, 31), (188, 96, 33), + (205, 115, 40), (225, 140, 56), (224, 144, 54), (223, 149, 53), + (223, 148, 49), (224, 148, 45), (228, 158, 38), (231, 165, 44), + (229, 181, 70), (226, 178, 76), (223, 175, 82), (224, 173, 73), + (225, 171, 64), (229, 166, 49), (232, 161, 40), (232, 160, 38), + (225, 156, 48), (208, 141, 49), (197, 133, 37), (186, 126, 26), + (181, 122, 22), (176, 118, 18), (158, 108, 15), (144, 95, 16), + (113, 68, 18), (104, 61, 15), (96, 54, 13), (93, 52, 10), + (91, 51, 8), (93, 47, 6), (94, 44, 6), (99, 43, 8), + (105, 41, 10), (123, 40, 15), (126, 38, 16), (130, 37, 18), + (138, 35, 20), (146, 36, 22), (152, 37, 25), (158, 40, 27), + (167, 43, 32), (172, 43, 34), (178, 43, 37), (179, 43, 39), + (180, 43, 41), (179, 43, 41), (175, 43, 38), (165, 43, 39), + (154, 45, 38), (148, 66, 45), (148, 73, 47), (149, 81, 50), + (148, 93, 55), (146, 102, 62), (142, 105, 67), (139, 105, 72), + (158, 121, 87), (171, 134, 94), (185, 147, 102), (189, 151, 104), + (194, 156, 107), (194, 156, 108), (193, 146, 107), (192, 138, 105), + (185, 128, 100), (165, 118, 82), (158, 117, 77), (151, 117, 73), + (141, 108, 62), (134, 98, 53), (124, 88, 46), (120, 77, 40), + (110, 58, 27), (106, 54, 25), (103, 50, 23), (96, 41, 21), + (89, 38, 20), (86, 34, 21), (86, 31, 21), (88, 29, 19), + (90, 27, 18), (74, 22, 17), (68, 21, 16), (62, 20, 15), + (51, 20, 15), (45, 19, 15), (50, 18, 14), (57, 18, 12), + (71, 19, 9), (72, 19, 9), (74, 20, 9), (74, 20, 9), + (75, 20, 9), (77, 18, 10), (76, 17, 9), (77, 16, 9), + (75, 15, 8), (71, 13, 6), (65, 13, 5), (58, 13, 6), + (48, 12, 6), (40, 10, 7), (32, 10, 6), (24, 9, 6), + (16, 12, 6), (15, 12, 6), (15, 13, 7), (17, 14, 9), + (18, 15, 10), (22, 15, 12), (24, 15, 14), (25, 16, 15), + (25, 18, 15), (27, 20, 15), (27, 22, 13), (31, 23, 13), + (38, 23, 14), (46, 23, 15), (58, 24, 14), (72, 23, 14), + (83, 21, 11), (93, 22, 9), (101, 22, 7), (104, 21, 7), + (104, 22, 7), (102, 23, 9), (102, 22, 11), (104, 23, 12), + (106, 22, 12), (105, 20, 14), (101, 21, 15), (95, 21, 18), + (89, 24, 21), (88, 28, 26), (94, 33, 31), (103, 40, 36), + (115, 49, 41), (131, 58, 49), (142, 71, 56), (152, 87, 65), + (164, 100, 76), (174, 117, 87), (184, 139, 97), (196, 154, 106), + (205, 165, 114), (213, 175, 120), (223, 182, 130), (226, 186, 138), + (232, 200, 147), (235, 210, 156), (236, 215, 161), (237, 213, 159), + (238, 205, 156), (228, 188, 147), (224, 176, 136), (217, 166, 126), + (209, 159, 117), (203, 150, 104), (197, 141, 93), (185, 127, 79), + (177, 109, 61), (168, 93, 44), (162, 76, 31), (162, 61, 18), + (164, 53, 15), (164, 48, 15), (162, 45, 15), (159, 47, 17), + (153, 48, 21), (152, 47, 21), (153, 43, 25), (163, 56, 40), + (172, 65, 49), (182, 69, 58), (186, 74, 65), (189, 80, 69) + ), + +// 506 Blossoms +((153, 135, 91), (143, 145, 101), (148, 139, 97), (153, 134, 93), + (165, 127, 89), (178, 121, 85), (187, 118, 85), (196, 116, 86), + (217, 118, 99), (222, 119, 102), (228, 121, 106), (231, 117, 104), + (234, 114, 103), (235, 116, 106), (236, 118, 109), (234, 120, 110), + (232, 123, 112), (220, 147, 123), (211, 156, 122), (202, 165, 122), + (192, 167, 119), (183, 169, 117), (179, 167, 116), (175, 165, 115), + (142, 158, 109), (125, 157, 106), (108, 156, 104), (98, 147, 99), + (88, 138, 94), (87, 132, 91), (87, 127, 89), (90, 114, 79), + (93, 110, 73), (96, 107, 62), (106, 106, 60), (116, 106, 59), + (133, 106, 61), (151, 106, 64), (160, 108, 67), (169, 111, 70), + (190, 118, 85), (195, 123, 92), (200, 128, 100), (199, 128, 106), + (198, 129, 112), (196, 126, 113), (195, 124, 115), (186, 117, 117), + (181, 109, 120), (165, 97, 110), (160, 94, 99), (156, 92, 88), + (157, 89, 77), (158, 86, 66), (162, 86, 62), (166, 86, 59), + (181, 85, 49), (186, 84, 45), (192, 84, 41), (194, 86, 39), + (196, 88, 38), (199, 90, 38), (202, 92, 39), (207, 100, 41), + (212, 109, 45), (212, 112, 63), (202, 113, 69), (193, 114, 75), + (189, 115, 74), (185, 117, 73), (176, 122, 73), (175, 129, 74), + (185, 128, 82), (190, 124, 85), (195, 120, 88), (193, 116, 85), + (191, 113, 83), (190, 109, 81), (189, 106, 80), (187, 99, 76), + (189, 89, 79), (191, 80, 85), (188, 82, 89), (186, 85, 93), + (183, 88, 94), (181, 92, 95), (181, 94, 98), (187, 102, 102), + (185, 113, 114), (182, 124, 119), (180, 136, 125), (179, 142, 126), + (178, 148, 128), (186, 163, 135), (199, 177, 140), (209, 187, 147), + (220, 192, 153), (221, 203, 162), (218, 202, 162), (215, 201, 162), + (217, 199, 159), (219, 197, 157), (228, 191, 151), (237, 183, 152), + (239, 170, 148), (237, 165, 145), (236, 160, 143), (237, 159, 140), + (238, 158, 138), (238, 155, 134), (240, 155, 135), (238, 155, 136), + (235, 159, 137), (228, 180, 141), (225, 187, 139), (222, 194, 138), + (219, 202, 134), (218, 205, 134), (220, 203, 135), (219, 203, 139), + (216, 197, 145), (202, 186, 136), (188, 175, 128), (183, 167, 124), + (179, 159, 120), (170, 144, 111), (169, 131, 106), (171, 126, 103), + (173, 122, 97), (159, 110, 78), (152, 109, 73), (146, 108, 68), + (128, 108, 60), (113, 117, 54), (106, 130, 51), (108, 143, 52), + (134, 170, 87), (143, 181, 110), (152, 192, 133), (153, 198, 141), + (154, 204, 149), (158, 214, 156), (166, 213, 163), (181, 212, 167), + (196, 206, 170), (221, 187, 166), (223, 184, 159), (226, 181, 153), + (226, 173, 134), (230, 169, 114), (228, 165, 93), (215, 159, 74), + (192, 144, 45), (184, 141, 41), (177, 139, 37), (170, 137, 32), + (173, 140, 27), (168, 144, 25), (162, 147, 23), (159, 144, 26), + (151, 143, 29), (152, 131, 34), (157, 131, 33), (162, 131, 33), + (173, 135, 30), (185, 134, 31), (197, 137, 28), (206, 135, 28), + (222, 120, 30), (227, 117, 30), (232, 115, 30), (240, 112, 32), + (246, 113, 36), (247, 115, 41), (249, 119, 47), (248, 115, 53), + (248, 109, 58), (248, 106, 58), (249, 106, 58), (243, 108, 61), + (240, 116, 66), (235, 121, 74), (226, 120, 82), (219, 113, 83), + (215, 99, 79), (214, 98, 79), (214, 98, 79), (216, 99, 83), + (215, 96, 90), (215, 90, 94), (214, 84, 93), (219, 82, 91), + (223, 85, 85), (231, 97, 77), (239, 105, 76), (244, 109, 72), + (246, 107, 67), (246, 105, 65), (243, 103, 62), (239, 110, 54), + (237, 118, 51), (231, 123, 47), (227, 120, 41), (225, 116, 38), + (219, 110, 38), (211, 103, 37), (204, 100, 40), (192, 99, 44), + (182, 99, 45), (172, 97, 44), (164, 98, 42), (152, 92, 37), + (142, 86, 34), (130, 81, 37), (119, 85, 44), (111, 92, 53), + (106, 108, 62), (102, 119, 70), (103, 124, 71), (105, 121, 69), + (107, 121, 69), (114, 120, 70), (121, 125, 73), (128, 133, 81), + (136, 138, 86), (146, 136, 86), (154, 132, 89), (164, 128, 89), + (175, 127, 89), (185, 130, 95), (194, 139, 103), (203, 146, 111), + (211, 155, 121), (218, 163, 129), (225, 169, 134), (231, 171, 139), + (235, 170, 139), (236, 166, 139), (235, 161, 137), (231, 155, 133), + (226, 147, 125), (223, 139, 116), (225, 130, 102), (227, 117, 89), + (227, 106, 76), (227, 98, 68), (224, 92, 62), (220, 92, 61), + (214, 100, 63), (208, 111, 68), (204, 119, 71), (189, 118, 73), + (175, 117, 72), (166, 115, 74), (156, 114, 75), (147, 120, 82) + ), + +// 507 Blue_Velvet +((55, 47, 96), (55, 48, 95), (55, 47, 93), (55, 47, 91), + (53, 45, 86), (52, 44, 81), (51, 42, 78), (50, 41, 76), + (46, 38, 68), (45, 37, 66), (45, 36, 64), (44, 35, 62), + (43, 35, 61), (43, 34, 59), (43, 34, 58), (43, 33, 57), + (43, 33, 57), (44, 35, 57), (44, 35, 58), (44, 36, 59), + (44, 35, 58), (45, 35, 58), (45, 35, 57), (46, 35, 57), + (47, 36, 58), (48, 37, 60), (49, 39, 62), (50, 40, 64), + (51, 41, 66), (51, 42, 67), (52, 43, 69), (52, 46, 74), + (55, 50, 81), (65, 67, 102), (66, 72, 110), (68, 77, 118), + (68, 77, 121), (68, 78, 124), (68, 78, 124), (69, 79, 124), + (70, 78, 121), (66, 71, 114), (63, 65, 108), (60, 59, 101), + (58, 54, 95), (56, 52, 93), (55, 51, 91), (52, 47, 87), + (51, 45, 85), (51, 45, 88), (50, 46, 90), (49, 47, 92), + (49, 47, 93), (49, 47, 94), (49, 47, 94), (50, 48, 95), + (53, 49, 95), (53, 48, 94), (54, 48, 93), (53, 48, 90), + (53, 48, 88), (52, 48, 86), (52, 48, 85), (52, 47, 83), + (52, 46, 83), (53, 48, 84), (53, 49, 84), (53, 50, 85), + (53, 50, 86), (53, 51, 87), (54, 52, 90), (55, 52, 92), + (56, 51, 92), (55, 50, 92), (55, 49, 92), (55, 48, 91), + (55, 48, 91), (56, 48, 91), (57, 48, 92), (58, 49, 94), + (59, 50, 97), (62, 59, 105), (65, 67, 113), (69, 76, 121), + (73, 81, 125), (77, 86, 129), (86, 97, 140), (101, 112, 149), + (138, 148, 174), (149, 157, 178), (160, 166, 182), (162, 167, 181), + (164, 168, 180), (160, 164, 178), (161, 168, 183), (154, 162, 181), + (146, 155, 175), (113, 128, 156), (99, 120, 153), (85, 113, 151), + (81, 111, 150), (78, 109, 150), (75, 106, 151), (76, 106, 151), + (82, 110, 154), (87, 114, 155), (92, 118, 157), (94, 119, 157), + (97, 121, 158), (96, 124, 161), (97, 125, 162), (99, 125, 162), + (99, 124, 160), (91, 111, 152), (88, 107, 149), (85, 104, 147), + (79, 95, 142), (75, 89, 137), (70, 81, 131), (65, 72, 124), + (57, 58, 111), (55, 55, 107), (53, 53, 103), (52, 52, 101), + (52, 52, 99), (50, 50, 94), (50, 48, 87), (49, 45, 79), + (48, 42, 71), (46, 37, 57), (45, 35, 53), (45, 34, 50), + (44, 32, 46), (44, 30, 43), (43, 30, 40), (43, 30, 40), + (44, 32, 45), (45, 34, 50), (47, 37, 56), (47, 37, 58), + (48, 38, 60), (49, 39, 63), (51, 41, 65), (53, 43, 69), + (55, 45, 73), (56, 46, 77), (55, 45, 77), (55, 45, 77), + (54, 45, 76), (54, 43, 76), (52, 42, 74), (51, 42, 75), + (49, 41, 75), (49, 40, 75), (49, 40, 75), (48, 40, 76), + (48, 42, 80), (49, 44, 85), (51, 50, 91), (56, 58, 100), + (60, 66, 108), (69, 86, 128), (72, 90, 132), (75, 95, 136), + (81, 105, 146), (85, 114, 154), (87, 121, 160), (86, 127, 164), + (90, 132, 168), (93, 134, 169), (96, 136, 170), (102, 139, 172), + (107, 143, 176), (116, 145, 174), (124, 148, 172), (135, 152, 169), + (139, 152, 165), (138, 152, 167), (137, 150, 166), (133, 144, 162), + (129, 137, 156), (119, 127, 147), (105, 114, 139), (90, 102, 134), + (68, 82, 125), (64, 78, 122), (61, 74, 120), (58, 68, 116), + (56, 63, 114), (55, 61, 111), (56, 60, 111), (57, 60, 111), + (57, 60, 112), (59, 61, 113), (61, 64, 117), (66, 70, 120), + (70, 77, 125), (75, 82, 129), (79, 87, 131), (82, 91, 134), + (85, 93, 134), (84, 95, 133), (83, 93, 132), (82, 91, 129), + (80, 88, 124), (78, 81, 118), (70, 73, 110), (64, 64, 103), + (57, 56, 97), (54, 52, 92), (53, 49, 87), (52, 46, 83), + (51, 45, 80), (51, 44, 79), (51, 45, 79), (53, 46, 80), + (54, 46, 81), (55, 47, 83), (56, 48, 86), (56, 49, 89), + (57, 49, 91), (57, 49, 93), (57, 49, 94), (57, 48, 95), + (56, 47, 95), (55, 47, 93), (54, 47, 90), (54, 46, 88), + (54, 46, 87), (54, 45, 86), (54, 47, 87), (55, 48, 87), + (55, 50, 90), (56, 53, 94), (58, 56, 99), (59, 60, 104), + (59, 63, 109), (60, 64, 112), (60, 66, 115), (61, 67, 117), + (62, 67, 119), (62, 66, 119), (62, 65, 118), (61, 64, 116), + (59, 62, 113), (58, 60, 109), (58, 57, 107), (57, 54, 104), + (55, 53, 102), (54, 51, 100), (53, 50, 98), (53, 49, 98), + (53, 49, 98), (53, 48, 98), (54, 47, 99), (54, 47, 98) + ), + +// 508 Bluebells +((51, 31, 24), (40, 29, 26), (37, 28, 32), (35, 28, 39), + (37, 27, 52), (39, 27, 66), (41, 29, 73), (44, 31, 80), + (49, 40, 109), (44, 45, 119), (40, 50, 129), (35, 51, 136), + (30, 52, 144), (34, 53, 145), (38, 55, 147), (44, 60, 150), + (51, 66, 153), (87, 102, 178), (88, 115, 184), (90, 128, 190), + (88, 133, 191), (87, 139, 192), (93, 143, 191), (100, 148, 191), + (150, 179, 208), (169, 195, 218), (188, 211, 228), (189, 217, 238), + (191, 223, 248), (183, 219, 246), (176, 215, 244), (160, 204, 238), + (155, 195, 232), (151, 173, 215), (145, 162, 208), (139, 152, 202), + (120, 139, 197), (101, 126, 192), (91, 123, 191), (82, 120, 190), + (48, 96, 186), (36, 84, 178), (25, 73, 170), (22, 63, 154), + (19, 54, 139), (18, 53, 133), (17, 53, 128), (16, 53, 120), + (19, 53, 118), (25, 59, 118), (32, 59, 107), (39, 60, 97), + (39, 61, 85), (40, 62, 73), (40, 62, 71), (41, 63, 70), + (37, 69, 89), (37, 72, 100), (37, 76, 112), (36, 78, 113), + (35, 81, 115), (34, 80, 113), (33, 79, 111), (31, 76, 107), + (26, 69, 106), (14, 55, 115), (10, 46, 112), (7, 38, 109), + (5, 34, 103), (4, 30, 98), (3, 22, 82), (2, 14, 65), + (2, 5, 46), (2, 4, 43), (2, 3, 41), (3, 5, 42), + (5, 7, 43), (5, 9, 43), (5, 11, 43), (7, 17, 45), + (11, 23, 49), (19, 34, 60), (21, 35, 62), (24, 37, 65), + (24, 36, 65), (25, 35, 65), (25, 37, 66), (27, 39, 68), + (36, 50, 79), (41, 57, 85), (47, 64, 91), (54, 69, 94), + (62, 74, 98), (79, 88, 107), (95, 102, 115), (108, 110, 118), + (122, 118, 115), (119, 115, 109), (124, 117, 110), (129, 120, 111), + (138, 129, 119), (147, 138, 128), (164, 158, 151), (186, 175, 163), + (206, 192, 178), (201, 186, 172), (196, 180, 167), (195, 179, 167), + (194, 179, 168), (198, 188, 183), (208, 201, 200), (228, 220, 218), + (241, 236, 234), (239, 246, 250), (229, 240, 249), (220, 235, 248), + (200, 223, 246), (179, 207, 239), (159, 190, 228), (140, 172, 217), + (124, 156, 204), (112, 149, 199), (101, 143, 194), (100, 143, 195), + (99, 144, 196), (99, 144, 196), (99, 141, 194), (111, 146, 195), + (128, 150, 187), (147, 152, 160), (152, 153, 157), (157, 154, 154), + (166, 158, 150), (170, 160, 148), (170, 164, 154), (170, 162, 157), + (155, 152, 146), (143, 139, 127), (131, 126, 108), (124, 119, 97), + (118, 112, 86), (104, 105, 74), (92, 98, 70), (80, 92, 72), + (69, 88, 78), (53, 78, 86), (50, 75, 86), (47, 72, 86), + (44, 65, 85), (41, 62, 78), (39, 57, 71), (34, 50, 68), + (24, 36, 65), (22, 35, 65), (21, 34, 66), (21, 33, 68), + (22, 33, 66), (23, 37, 62), (25, 38, 55), (25, 36, 44), + (24, 33, 34), (25, 35, 17), (28, 35, 16), (31, 36, 16), + (36, 43, 15), (42, 51, 20), (46, 55, 25), (45, 55, 29), + (41, 43, 31), (41, 39, 31), (41, 36, 32), (40, 33, 29), + (45, 30, 28), (50, 30, 29), (51, 33, 30), (55, 32, 32), + (53, 29, 31), (49, 23, 33), (42, 19, 34), (37, 14, 36), + (33, 11, 37), (28, 12, 40), (27, 14, 44), (26, 17, 48), + (19, 26, 69), (17, 30, 75), (16, 34, 81), (17, 43, 95), + (19, 54, 109), (26, 68, 127), (47, 88, 140), (69, 106, 151), + (88, 122, 164), (106, 139, 176), (126, 157, 189), (144, 172, 199), + (152, 185, 212), (172, 202, 223), (193, 217, 231), (212, 229, 240), + (227, 239, 247), (242, 249, 253), (254, 254, 254), (251, 253, 249), + (241, 243, 238), (226, 233, 220), (211, 217, 200), (193, 197, 180), + (173, 176, 160), (156, 158, 146), (142, 147, 135), (126, 130, 125), + (107, 116, 113), (88, 100, 101), (69, 82, 89), (48, 62, 78), + (31, 46, 75), (21, 43, 79), (19, 43, 89), (22, 48, 99), + (26, 56, 107), (36, 61, 111), (46, 65, 113), (55, 66, 114), + (58, 67, 116), (58, 67, 117), (60, 71, 119), (59, 77, 124), + (64, 84, 126), (70, 90, 124), (88, 99, 122), (107, 113, 128), + (123, 121, 133), (136, 132, 140), (144, 143, 154), (152, 155, 168), + (155, 164, 183), (162, 175, 190), (180, 193, 206), (198, 210, 218), + (217, 225, 227), (233, 238, 236), (246, 245, 237), (246, 240, 233), + (236, 226, 219), (221, 209, 202), (202, 190, 183), (182, 170, 162), + (162, 152, 147), (146, 138, 132), (129, 122, 113), (114, 103, 94), + (99, 85, 76), (82, 66, 58), (67, 49, 41), (57, 37, 29) + ), + + +// 509 Blush +((245, 172, 163), (249, 180, 171), (248, 185, 177), (248, 191, 183), + (248, 200, 191), (249, 209, 199), (249, 214, 201), (249, 220, 204), + (252, 237, 213), (252, 241, 217), (252, 246, 222), (251, 247, 224), + (251, 248, 227), (251, 248, 228), (252, 249, 229), (252, 249, 230), + (253, 250, 231), (253, 249, 240), (252, 245, 239), (252, 241, 238), + (252, 234, 231), (252, 228, 224), (251, 223, 221), (251, 219, 218), + (250, 211, 213), (250, 209, 212), (250, 207, 212), (250, 207, 211), + (250, 208, 210), (250, 208, 209), (250, 209, 209), (248, 212, 213), + (246, 215, 217), (246, 219, 221), (241, 216, 212), (237, 214, 203), + (232, 202, 190), (227, 190, 178), (225, 182, 171), (223, 174, 165), + (224, 151, 143), (223, 141, 130), (223, 131, 118), (220, 120, 104), + (218, 110, 91), (217, 104, 86), (216, 99, 82), (216, 92, 78), + (213, 91, 79), (217, 93, 88), (217, 94, 88), (217, 95, 89), + (211, 91, 86), (205, 87, 84), (200, 85, 83), (195, 84, 82), + (175, 78, 85), (163, 75, 84), (152, 72, 83), (133, 64, 73), + (115, 56, 64), (108, 50, 58), (101, 45, 52), (81, 37, 41), + (68, 30, 32), (59, 21, 23), (58, 17, 18), (58, 13, 14), + (56, 11, 12), (54, 10, 10), (44, 7, 5), (42, 5, 4), + (44, 4, 3), (45, 5, 3), (46, 6, 4), (35, 5, 4), + (25, 5, 4), (20, 4, 3), (15, 3, 3), (7, 1, 2), + (1, 0, 1), (0, 0, 0), (0, 0, 0), (0, 0, 1), + (0, 0, 1), (0, 1, 1), (0, 0, 1), (0, 1, 1), + (10, 11, 11), (29, 20, 21), (48, 29, 31), (60, 37, 38), + (72, 45, 45), (93, 59, 60), (116, 81, 82), (130, 101, 101), + (144, 105, 106), (185, 126, 127), (205, 140, 141), (225, 155, 156), + (232, 170, 170), (240, 185, 184), (241, 195, 193), (240, 201, 198), + (240, 202, 200), (244, 211, 209), (248, 221, 218), (249, 227, 225), + (251, 234, 232), (253, 243, 240), (254, 249, 245), (254, 251, 248), + (254, 252, 249), (253, 251, 245), (253, 249, 242), (253, 247, 240), + (253, 241, 230), (253, 230, 217), (252, 217, 202), (252, 203, 189), + (246, 184, 171), (245, 180, 164), (245, 177, 157), (245, 175, 153), + (246, 174, 150), (246, 170, 145), (246, 163, 142), (245, 160, 142), + (241, 158, 142), (229, 151, 135), (224, 147, 130), (219, 144, 126), + (205, 130, 115), (188, 115, 103), (166, 102, 91), (145, 83, 77), + (103, 51, 47), (87, 35, 33), (72, 19, 19), (67, 14, 15), + (62, 10, 11), (59, 7, 9), (62, 11, 14), (73, 20, 24), + (84, 31, 35), (127, 55, 62), (136, 60, 68), (146, 65, 74), + (166, 74, 84), (185, 84, 94), (196, 91, 101), (205, 98, 108), + (211, 104, 115), (210, 103, 113), (209, 102, 112), (204, 97, 107), + (197, 91, 99), (188, 80, 87), (178, 71, 76), (167, 62, 65), + (157, 53, 55), (146, 41, 42), (145, 39, 40), (145, 38, 39), + (146, 38, 40), (148, 43, 43), (151, 48, 50), (158, 57, 61), + (175, 90, 93), (178, 98, 101), (182, 106, 109), (194, 124, 121), + (205, 141, 135), (215, 157, 150), (227, 172, 165), (236, 186, 183), + (239, 197, 198), (242, 206, 206), (242, 212, 209), (239, 215, 208), + (236, 210, 201), (234, 198, 189), (228, 182, 176), (223, 165, 161), + (207, 141, 139), (204, 140, 135), (202, 139, 132), (201, 139, 124), + (202, 139, 120), (207, 138, 117), (209, 140, 114), (212, 144, 121), + (214, 150, 132), (219, 162, 145), (226, 171, 157), (235, 179, 167), + (241, 181, 170), (245, 180, 172), (246, 176, 173), (245, 173, 173), + (246, 168, 174), (245, 165, 173), (246, 161, 172), (245, 158, 169), + (245, 159, 167), (246, 164, 167), (245, 172, 175), (245, 181, 182), + (247, 188, 189), (247, 190, 193), (246, 190, 192), (245, 187, 185), + (244, 183, 177), (242, 178, 169), (241, 172, 163), (241, 165, 159), + (241, 159, 157), (242, 151, 151), (242, 145, 146), (242, 142, 140), + (241, 142, 138), (244, 151, 140), (246, 163, 149), (248, 174, 159), + (248, 186, 170), (245, 193, 177), (239, 193, 178), (233, 192, 175), + (226, 184, 166), (220, 174, 153), (211, 162, 139), (203, 148, 126), + (192, 132, 113), (179, 117, 102), (165, 97, 88), (152, 78, 74), + (130, 57, 55), (114, 38, 38), (97, 24, 24), (79, 18, 16), + (67, 12, 11), (59, 10, 11), (47, 9, 12), (41, 8, 13), + (43, 13, 17), (50, 22, 24), (64, 40, 37), (86, 58, 52), + (108, 72, 65), (125, 86, 78), (145, 95, 85), (166, 99, 89), + (187, 113, 104), (208, 129, 120), (227, 143, 134), (239, 159, 151) + ), + +// 510 Bluster +((65, 45, 53), (74, 53, 57), (71, 49, 54), (69, 46, 52), + (71, 46, 53), (73, 47, 54), (72, 47, 54), (72, 48, 54), + (62, 45, 52), (52, 43, 52), (42, 41, 53), (33, 42, 55), + (25, 43, 58), (21, 47, 62), (17, 51, 67), (15, 53, 70), + (14, 55, 74), (9, 63, 85), (10, 67, 89), (11, 71, 93), + (12, 71, 93), (14, 71, 94), (13, 71, 93), (12, 71, 93), + (11, 62, 82), (14, 57, 75), (18, 52, 69), (21, 48, 64), + (25, 44, 59), (26, 42, 57), (28, 41, 56), (34, 41, 56), + (41, 44, 60), (49, 53, 71), (53, 59, 77), (58, 65, 84), + (62, 71, 92), (67, 78, 100), (64, 79, 102), (61, 80, 105), + (47, 80, 104), (46, 79, 101), (45, 78, 99), (43, 75, 98), + (41, 73, 97), (42, 73, 97), (43, 74, 98), (45, 76, 101), + (50, 80, 106), (58, 85, 112), (65, 85, 112), (72, 85, 112), + (78, 86, 113), (84, 87, 114), (84, 87, 112), (85, 87, 111), + (75, 73, 92), (69, 63, 81), (64, 54, 70), (60, 49, 61), + (57, 44, 53), (54, 41, 49), (51, 38, 46), (47, 34, 42), + (44, 33, 42), (49, 39, 52), (56, 47, 62), (63, 56, 72), + (68, 61, 77), (73, 66, 83), (85, 79, 99), (94, 87, 112), + (104, 104, 135), (105, 108, 139), (107, 113, 143), (105, 110, 141), + (103, 108, 140), (97, 106, 139), (92, 104, 138), (82, 100, 133), + (71, 95, 127), (61, 85, 113), (59, 83, 108), (58, 81, 104), + (58, 80, 101), (58, 80, 99), (60, 79, 94), (64, 77, 89), + (78, 77, 82), (86, 76, 76), (95, 75, 71), (96, 74, 69), + (97, 74, 68), (95, 73, 70), (88, 75, 76), (80, 77, 80), + (78, 78, 83), (76, 86, 99), (64, 89, 107), (53, 92, 116), + (47, 91, 115), (42, 90, 115), (35, 87, 111), (37, 83, 108), + (35, 75, 100), (26, 70, 93), (18, 65, 87), (17, 61, 83), + (16, 58, 79), (16, 54, 74), (20, 50, 67), (24, 47, 63), + (25, 47, 62), (26, 46, 61), (26, 45, 61), (27, 45, 61), + (28, 47, 63), (27, 50, 65), (30, 52, 68), (32, 52, 69), + (31, 46, 63), (26, 43, 58), (21, 40, 54), (20, 37, 51), + (19, 35, 48), (18, 30, 41), (18, 23, 32), (16, 14, 23), + (11, 10, 17), (5, 8, 14), (5, 8, 14), (6, 9, 14), + (7, 9, 16), (12, 11, 18), (18, 15, 23), (24, 20, 30), + (38, 36, 45), (43, 44, 53), (49, 52, 61), (50, 54, 65), + (51, 57, 69), (51, 64, 78), (49, 69, 87), (47, 76, 94), + (47, 82, 100), (44, 86, 104), (43, 85, 103), (43, 85, 103), + (43, 84, 101), (48, 83, 98), (53, 82, 95), (63, 83, 92), + (77, 80, 85), (78, 78, 82), (80, 76, 80), (80, 69, 74), + (79, 63, 69), (78, 57, 62), (77, 53, 59), (79, 50, 59), + (84, 48, 56), (95, 42, 46), (96, 41, 43), (98, 41, 40), + (100, 43, 44), (104, 49, 48), (107, 57, 56), (112, 61, 62), + (120, 72, 76), (123, 77, 85), (127, 83, 95), (136, 98, 115), + (147, 106, 130), (154, 113, 143), (160, 111, 144), (161, 114, 149), + (159, 118, 153), (159, 115, 147), (152, 110, 141), (142, 93, 123), + (125, 79, 104), (100, 66, 89), (78, 54, 71), (59, 45, 56), + (38, 25, 32), (34, 21, 28), (30, 17, 24), (24, 12, 18), + (18, 9, 13), (13, 8, 10), (11, 6, 8), (12, 6, 7), + (11, 6, 8), (10, 7, 9), (7, 9, 11), (6, 11, 16), + (8, 15, 20), (13, 19, 25), (18, 23, 31), (22, 27, 35), + (24, 29, 39), (27, 31, 42), (31, 33, 44), (36, 35, 48), + (39, 38, 51), (38, 39, 54), (36, 42, 58), (32, 46, 61), + (30, 49, 67), (30, 55, 74), (30, 60, 81), (33, 65, 90), + (34, 71, 96), (32, 74, 102), (33, 78, 105), (32, 79, 106), + (34, 80, 108), (38, 79, 104), (38, 74, 100), (39, 68, 92), + (38, 63, 86), (36, 63, 85), (39, 63, 85), (42, 63, 84), + (46, 60, 80), (50, 55, 74), (49, 50, 68), (48, 48, 65), + (46, 46, 62), (43, 43, 59), (41, 37, 51), (37, 30, 41), + (32, 23, 31), (27, 17, 23), (22, 13, 19), (20, 10, 16), + (20, 10, 15), (23, 10, 15), (27, 12, 15), (29, 13, 17), + (30, 15, 20), (30, 16, 23), (33, 18, 25), (37, 20, 28), + (40, 22, 30), (41, 23, 31), (41, 24, 33), (41, 25, 34), + (43, 25, 35), (46, 26, 37), (51, 32, 41), (52, 36, 44), + (49, 34, 43), (49, 34, 42), (47, 30, 40), (54, 36, 45) + ), + +// 511 Boquet_of_Roses +((154, 14, 6), (150, 22, 9), (145, 26, 10), (141, 30, 12), + (139, 35, 14), (138, 41, 17), (137, 44, 18), (136, 47, 19), + (138, 61, 31), (144, 74, 42), (151, 87, 53), (155, 95, 66), + (159, 104, 80), (159, 99, 74), (160, 95, 69), (158, 94, 66), + (157, 93, 64), (155, 101, 79), (154, 101, 75), (153, 101, 71), + (160, 118, 89), (168, 136, 107), (170, 143, 117), (173, 151, 127), + (184, 173, 146), (187, 175, 151), (190, 178, 157), (183, 173, 151), + (177, 169, 146), (174, 165, 142), (172, 161, 138), (166, 151, 128), + (158, 138, 114), (145, 110, 83), (139, 99, 69), (133, 88, 55), + (132, 74, 43), (131, 60, 32), (130, 55, 28), (129, 50, 24), + (127, 40, 14), (127, 38, 16), (128, 37, 18), (126, 38, 23), + (124, 40, 29), (123, 43, 29), (122, 46, 30), (117, 53, 32), + (113, 56, 38), (107, 62, 46), (103, 64, 44), (100, 67, 43), + (96, 65, 44), (92, 64, 45), (92, 63, 44), (92, 62, 44), + (80, 49, 35), (81, 41, 30), (83, 34, 25), (86, 26, 19), + (89, 18, 13), (90, 15, 11), (92, 12, 9), (99, 10, 6), + (108, 8, 5), (119, 3, 0), (125, 4, 1), (131, 6, 2), + (133, 7, 2), (135, 9, 2), (138, 10, 2), (140, 16, 5), + (143, 34, 12), (145, 44, 17), (147, 54, 22), (151, 68, 29), + (155, 83, 37), (154, 88, 42), (154, 93, 47), (154, 100, 58), + (159, 109, 66), (164, 123, 84), (159, 124, 91), (154, 125, 99), + (154, 125, 100), (155, 125, 102), (156, 118, 98), (153, 111, 89), + (142, 89, 69), (141, 71, 55), (140, 54, 41), (138, 46, 34), + (136, 39, 28), (133, 29, 17), (130, 20, 11), (130, 14, 7), + (131, 12, 7), (135, 20, 12), (134, 24, 14), (134, 28, 17), + (133, 27, 17), (133, 27, 17), (129, 30, 20), (122, 38, 23), + (114, 45, 26), (114, 53, 35), (114, 62, 45), (114, 70, 50), + (114, 78, 56), (116, 88, 62), (121, 95, 71), (126, 99, 78), + (129, 102, 78), (130, 104, 73), (132, 102, 70), (134, 101, 68), + (139, 95, 62), (143, 93, 58), (147, 93, 57), (152, 90, 51), + (156, 79, 46), (159, 82, 53), (163, 85, 60), (165, 87, 63), + (168, 90, 67), (168, 96, 73), (169, 107, 85), (176, 123, 104), + (187, 138, 118), (192, 154, 128), (192, 155, 129), (193, 156, 131), + (195, 152, 120), (190, 136, 105), (182, 115, 84), (174, 91, 67), + (161, 52, 31), (151, 34, 19), (142, 17, 7), (140, 12, 4), + (138, 8, 2), (137, 4, 1), (137, 9, 5), (139, 18, 10), + (141, 31, 19), (148, 68, 47), (152, 78, 55), (156, 88, 64), + (163, 105, 82), (164, 119, 95), (168, 127, 100), (171, 130, 99), + (168, 123, 94), (166, 120, 91), (164, 117, 89), (163, 112, 79), + (161, 105, 71), (153, 100, 63), (145, 94, 60), (145, 87, 55), + (147, 81, 51), (142, 64, 38), (141, 60, 35), (140, 57, 32), + (138, 52, 29), (133, 49, 25), (122, 46, 24), (117, 46, 24), + (121, 44, 20), (120, 41, 18), (120, 38, 17), (122, 31, 13), + (130, 24, 9), (143, 18, 5), (152, 12, 2), (159, 11, 2), + (163, 13, 5), (166, 14, 6), (163, 13, 7), (161, 15, 7), + (160, 20, 9), (161, 24, 11), (158, 27, 14), (154, 31, 13), + (161, 59, 21), (164, 65, 26), (168, 72, 31), (176, 87, 42), + (183, 105, 51), (194, 125, 58), (199, 134, 62), (199, 136, 68), + (195, 133, 70), (193, 131, 68), (182, 122, 62), (169, 109, 57), + (154, 97, 54), (144, 89, 50), (136, 85, 51), (134, 83, 54), + (133, 85, 62), (131, 88, 65), (130, 91, 67), (127, 92, 69), + (125, 91, 68), (115, 88, 64), (107, 79, 56), (101, 69, 47), + (104, 53, 36), (106, 41, 26), (111, 28, 16), (120, 21, 11), + (134, 12, 6), (152, 6, 4), (170, 1, 1), (187, 1, 1), + (193, 3, 2), (199, 8, 3), (199, 9, 4), (202, 9, 5), + (198, 11, 6), (193, 21, 9), (184, 33, 15), (178, 48, 23), + (178, 66, 35), (179, 88, 50), (176, 104, 67), (171, 120, 77), + (169, 134, 88), (167, 143, 99), (158, 141, 106), (147, 131, 100), + (133, 118, 89), (125, 106, 79), (117, 93, 68), (113, 83, 56), + (111, 77, 50), (117, 80, 51), (129, 86, 55), (143, 96, 66), + (154, 111, 84), (167, 130, 102), (179, 144, 109), (192, 154, 114), + (199, 160, 118), (199, 161, 121), (191, 147, 109), (185, 128, 90), + (182, 103, 67), (177, 82, 51), (169, 59, 38), (160, 40, 27), + (159, 22, 15), (158, 13, 6), (158, 11, 3), (155, 14, 4) + ), + +// 512 Brushed_Silver +((184, 191, 195), (182, 187, 191), (183, 187, 190), (184, 188, 190), + (185, 189, 191), (186, 191, 193), (187, 192, 195), (188, 193, 197), + (192, 200, 210), (190, 202, 213), (188, 205, 216), (179, 199, 211), + (170, 194, 206), (158, 182, 195), (146, 171, 184), (140, 165, 178), + (134, 159, 172), (114, 139, 150), (107, 131, 143), (101, 123, 136), + (95, 119, 131), (90, 116, 126), (86, 113, 123), (83, 110, 120), + (69, 96, 103), (60, 84, 91), (52, 73, 79), (44, 62, 66), + (36, 52, 54), (33, 46, 49), (31, 41, 45), (29, 34, 36), + (30, 33, 35), (35, 37, 41), (40, 42, 46), (46, 48, 52), + (52, 55, 58), (59, 62, 64), (62, 65, 67), (65, 68, 71), + (82, 83, 85), (92, 93, 95), (102, 104, 106), (112, 115, 118), + (122, 127, 130), (126, 132, 135), (130, 137, 141), (138, 145, 151), + (146, 155, 159), (161, 169, 174), (166, 173, 176), (172, 177, 179), + (174, 178, 178), (177, 179, 178), (177, 178, 176), (178, 178, 175), + (169, 168, 166), (160, 160, 158), (151, 153, 150), (142, 145, 143), + (133, 137, 136), (129, 133, 132), (126, 130, 129), (119, 123, 122), + (115, 118, 115), (110, 114, 109), (106, 111, 107), (103, 109, 106), + (100, 106, 104), (98, 104, 102), (92, 99, 97), (87, 94, 93), + (77, 84, 85), (74, 80, 80), (71, 77, 75), (70, 76, 74), + (69, 76, 73), (68, 76, 73), (68, 76, 74), (67, 76, 75), + (65, 75, 74), (59, 69, 68), (54, 65, 65), (50, 62, 63), + (49, 60, 61), (48, 59, 60), (47, 56, 57), (47, 55, 55), + (49, 57, 57), (53, 62, 61), (58, 68, 66), (62, 71, 69), + (66, 75, 72), (75, 83, 79), (83, 90, 89), (93, 99, 98), + (104, 109, 107), (123, 125, 124), (128, 130, 131), (134, 136, 139), + (135, 138, 142), (136, 140, 145), (138, 144, 149), (139, 146, 151), + (141, 148, 154), (144, 150, 156), (148, 153, 158), (149, 154, 160), + (151, 156, 162), (154, 158, 165), (154, 160, 169), (153, 160, 173), + (151, 160, 173), (145, 159, 174), (144, 158, 173), (143, 157, 173), + (142, 157, 172), (143, 158, 172), (145, 159, 172), (150, 162, 173), + (159, 167, 176), (163, 168, 174), (168, 169, 173), (168, 168, 171), + (168, 168, 170), (165, 165, 167), (162, 162, 164), (158, 158, 158), + (153, 152, 152), (145, 143, 139), (142, 140, 137), (140, 138, 135), + (137, 135, 132), (135, 131, 128), (131, 128, 123), (122, 126, 120), + (105, 119, 115), (96, 112, 109), (87, 105, 104), (82, 101, 101), + (78, 98, 98), (69, 92, 94), (62, 88, 93), (59, 86, 94), + (63, 86, 95), (70, 94, 105), (73, 98, 108), (77, 103, 112), + (85, 111, 120), (93, 119, 129), (100, 126, 135), (106, 131, 139), + (114, 137, 145), (117, 137, 145), (120, 138, 145), (126, 138, 145), + (129, 137, 145), (131, 136, 145), (133, 136, 143), (134, 136, 142), + (134, 135, 140), (133, 130, 133), (132, 129, 131), (131, 129, 130), + (128, 127, 127), (126, 124, 125), (122, 122, 123), (117, 118, 122), + (109, 114, 123), (106, 113, 122), (104, 112, 121), (101, 110, 120), + (98, 108, 117), (97, 107, 115), (98, 108, 115), (101, 109, 115), + (104, 113, 119), (107, 116, 123), (114, 121, 129), (120, 128, 137), + (124, 134, 145), (130, 140, 153), (134, 144, 158), (137, 148, 162), + (146, 156, 168), (148, 158, 169), (151, 160, 170), (155, 162, 171), + (159, 163, 170), (164, 166, 171), (168, 168, 173), (173, 170, 175), + (179, 173, 174), (182, 174, 173), (183, 175, 173), (183, 175, 172), + (182, 174, 170), (179, 172, 169), (175, 170, 167), (172, 168, 166), + (169, 168, 166), (168, 169, 168), (171, 171, 169), (174, 173, 168), + (177, 175, 170), (179, 175, 171), (180, 177, 172), (180, 176, 172), + (178, 175, 171), (174, 171, 169), (166, 166, 166), (157, 161, 165), + (149, 157, 164), (143, 154, 162), (139, 150, 159), (137, 147, 157), + (136, 145, 153), (136, 143, 148), (136, 139, 142), (136, 137, 137), + (136, 134, 134), (134, 133, 131), (133, 131, 129), (131, 130, 128), + (129, 128, 127), (128, 128, 127), (126, 127, 126), (123, 126, 125), + (122, 123, 121), (120, 120, 116), (120, 118, 113), (122, 119, 112), + (125, 121, 112), (128, 123, 114), (132, 126, 118), (137, 131, 124), + (142, 137, 133), (147, 144, 142), (151, 149, 148), (153, 151, 152), + (153, 151, 154), (152, 151, 155), (152, 152, 154), (151, 151, 153), + (149, 151, 153), (147, 151, 151), (145, 149, 150), (144, 148, 149), + (149, 153, 155), (155, 159, 160), (159, 165, 168), (164, 171, 175), + (169, 177, 181), (174, 181, 185), (179, 184, 189), (182, 188, 192) + ), + +// 513 Bubblegum +((194, 37, 79), (193, 49, 97), (193, 50, 99), (193, 52, 101), + (196, 51, 101), (199, 50, 102), (202, 50, 104), (205, 50, 107), + (206, 46, 110), (207, 46, 116), (208, 46, 122), (206, 44, 124), + (205, 43, 127), (200, 38, 126), (195, 33, 125), (192, 30, 123), + (190, 28, 122), (188, 29, 124), (188, 38, 132), (189, 48, 140), + (189, 61, 146), (190, 75, 152), (191, 82, 157), (192, 90, 162), + (191, 108, 172), (191, 117, 176), (192, 126, 180), (193, 135, 184), + (194, 145, 189), (195, 149, 189), (196, 154, 189), (199, 163, 193), + (198, 166, 193), (199, 161, 185), (201, 157, 185), (203, 154, 186), + (202, 150, 187), (202, 147, 188), (203, 144, 188), (205, 142, 189), + (206, 119, 171), (208, 104, 160), (211, 89, 150), (210, 80, 147), + (209, 71, 145), (207, 69, 145), (205, 68, 146), (203, 70, 154), + (197, 69, 154), (188, 59, 147), (188, 51, 138), (188, 43, 130), + (185, 43, 125), (183, 43, 120), (181, 48, 123), (180, 53, 127), + (170, 83, 143), (168, 90, 151), (166, 98, 160), (172, 103, 168), + (179, 108, 177), (183, 109, 181), (187, 111, 186), (196, 116, 194), + (201, 123, 196), (204, 138, 193), (204, 135, 196), (205, 133, 199), + (205, 129, 198), (206, 125, 197), (204, 115, 192), (200, 102, 189), + (189, 81, 169), (181, 72, 152), (173, 63, 135), (170, 54, 128), + (167, 46, 121), (167, 42, 118), (168, 38, 116), (169, 34, 115), + (168, 32, 114), (171, 47, 132), (170, 55, 140), (169, 64, 148), + (172, 64, 155), (175, 65, 162), (182, 66, 178), (191, 66, 193), + (198, 66, 200), (200, 67, 201), (203, 68, 203), (199, 68, 200), + (196, 69, 198), (194, 69, 196), (192, 66, 194), (191, 63, 197), + (197, 59, 199), (201, 47, 188), (198, 43, 176), (196, 39, 165), + (193, 37, 158), (191, 36, 152), (187, 26, 136), (187, 20, 129), + (194, 15, 125), (200, 14, 124), (207, 13, 123), (209, 13, 122), + (212, 13, 122), (214, 13, 117), (214, 14, 114), (213, 14, 110), + (211, 16, 110), (211, 15, 106), (212, 15, 105), (213, 15, 104), + (216, 18, 104), (217, 23, 100), (217, 33, 100), (216, 46, 103), + (214, 72, 119), (215, 82, 133), (216, 92, 148), (218, 97, 154), + (220, 102, 161), (223, 111, 173), (225, 121, 184), (226, 134, 194), + (223, 149, 205), (208, 157, 215), (200, 156, 213), (192, 156, 212), + (182, 152, 211), (171, 142, 212), (164, 131, 213), (166, 128, 216), + (157, 127, 213), (152, 129, 211), (147, 131, 209), (148, 135, 207), + (149, 139, 206), (152, 140, 197), (149, 131, 192), (158, 125, 192), + (168, 117, 193), (173, 101, 186), (172, 96, 184), (172, 92, 182), + (176, 95, 176), (170, 98, 158), (168, 94, 147), (169, 82, 137), + (176, 54, 125), (177, 47, 122), (179, 41, 119), (182, 32, 122), + (183, 26, 123), (183, 23, 124), (182, 20, 123), (184, 20, 124), + (189, 19, 127), (201, 21, 132), (203, 24, 134), (206, 27, 137), + (210, 35, 143), (215, 45, 153), (218, 56, 161), (220, 70, 170), + (222, 94, 188), (222, 96, 191), (223, 99, 194), (221, 106, 196), + (219, 114, 197), (218, 122, 199), (217, 130, 201), (219, 139, 206), + (220, 148, 211), (221, 155, 218), (218, 158, 222), (210, 161, 221), + (204, 163, 218), (198, 165, 216), (191, 163, 213), (195, 164, 215), + (204, 167, 218), (205, 167, 219), (206, 168, 221), (206, 169, 222), + (206, 170, 223), (205, 173, 224), (197, 171, 223), (194, 171, 223), + (195, 170, 225), (201, 168, 228), (206, 163, 231), (211, 156, 234), + (217, 150, 233), (219, 142, 229), (216, 133, 222), (211, 124, 214), + (206, 115, 206), (201, 107, 197), (199, 101, 189), (198, 97, 183), + (195, 96, 172), (190, 87, 159), (180, 75, 140), (167, 64, 122), + (153, 55, 110), (139, 46, 95), (129, 40, 89), (122, 35, 81), + (120, 34, 75), (119, 33, 76), (118, 31, 67), (114, 33, 65), + (111, 39, 71), (110, 45, 75), (113, 55, 88), (113, 64, 97), + (118, 72, 109), (123, 73, 125), (132, 80, 137), (142, 88, 146), + (146, 91, 154), (156, 98, 163), (169, 103, 175), (182, 107, 183), + (188, 108, 187), (189, 107, 188), (191, 107, 188), (192, 107, 185), + (190, 101, 181), (190, 96, 178), (191, 90, 176), (196, 87, 171), + (199, 76, 162), (199, 63, 149), (196, 51, 136), (192, 41, 124), + (188, 34, 116), (186, 29, 105), (187, 24, 95), (191, 23, 93), + (198, 22, 92), (205, 21, 94), (206, 19, 94), (205, 19, 93), + (199, 21, 92), (197, 27, 98), (196, 26, 88), (195, 28, 83), + (194, 30, 82), (196, 32, 78), (197, 33, 79), (199, 35, 81) + ), + +// 514 California +((80, 121, 173), (83, 126, 183), (81, 124, 185), (79, 123, 187), + (72, 120, 188), (65, 118, 190), (60, 116, 189), (56, 114, 188), + (46, 114, 192), (50, 116, 194), (54, 118, 197), (64, 123, 199), + (75, 129, 202), (87, 132, 197), (100, 136, 193), (105, 135, 189), + (111, 134, 186), (134, 128, 166), (152, 127, 158), (170, 126, 150), + (183, 122, 145), (196, 119, 141), (202, 117, 138), (209, 115, 136), + (219, 96, 122), (219, 88, 120), (220, 80, 119), (214, 77, 127), + (208, 74, 136), (204, 74, 141), (200, 75, 146), (198, 73, 156), + (194, 68, 161), (185, 58, 174), (181, 52, 179), (178, 46, 184), + (164, 47, 190), (150, 48, 196), (144, 49, 197), (138, 51, 198), + (122, 59, 197), (126, 53, 190), (131, 48, 183), (132, 47, 175), + (134, 47, 168), (131, 46, 166), (129, 45, 164), (119, 44, 158), + (111, 51, 153), (100, 63, 147), (111, 66, 141), (122, 69, 135), + (134, 66, 131), (146, 64, 127), (151, 63, 126), (156, 62, 125), + (154, 64, 127), (154, 62, 132), (154, 61, 137), (154, 64, 141), + (155, 68, 146), (155, 68, 147), (156, 68, 148), (158, 69, 153), + (156, 74, 156), (150, 78, 164), (153, 81, 163), (157, 85, 162), + (158, 85, 160), (159, 86, 159), (157, 85, 160), (153, 81, 165), + (130, 76, 177), (125, 73, 176), (120, 71, 176), (122, 68, 170), + (125, 65, 164), (125, 61, 162), (126, 57, 161), (127, 47, 162), + (112, 40, 169), (82, 35, 179), (73, 39, 175), (64, 44, 171), + (63, 48, 167), (62, 52, 163), (66, 58, 158), (66, 61, 155), + (62, 63, 161), (58, 64, 166), (54, 65, 171), (54, 65, 172), + (55, 65, 174), (58, 63, 176), (62, 60, 178), (67, 61, 175), + (69, 58, 175), (63, 60, 171), (61, 63, 171), (60, 67, 171), + (59, 66, 172), (59, 66, 173), (62, 66, 169), (64, 65, 168), + (61, 73, 155), (58, 82, 156), (56, 92, 157), (55, 96, 160), + (55, 100, 164), (55, 102, 171), (57, 101, 179), (59, 101, 187), + (57, 100, 189), (57, 97, 196), (58, 98, 197), (59, 99, 199), + (66, 98, 202), (75, 96, 202), (82, 90, 203), (88, 83, 200), + (87, 73, 193), (79, 70, 190), (72, 67, 187), (70, 66, 186), + (69, 66, 185), (69, 63, 182), (77, 59, 178), (91, 55, 173), + (103, 53, 167), (123, 51, 155), (126, 52, 153), (130, 53, 152), + (129, 56, 149), (126, 60, 147), (130, 63, 146), (131, 70, 146), + (148, 84, 151), (156, 91, 152), (164, 98, 154), (164, 97, 154), + (165, 97, 154), (166, 94, 152), (165, 94, 149), (164, 92, 150), + (162, 92, 153), (162, 97, 166), (162, 95, 169), (162, 94, 173), + (159, 89, 177), (157, 85, 180), (159, 81, 181), (161, 81, 181), + (165, 90, 193), (167, 93, 194), (169, 96, 196), (168, 99, 195), + (167, 98, 194), (164, 94, 194), (161, 93, 195), (157, 96, 200), + (149, 97, 209), (143, 97, 218), (141, 94, 216), (140, 92, 215), + (134, 86, 206), (128, 77, 198), (121, 72, 194), (110, 68, 190), + (94, 74, 208), (92, 76, 212), (90, 79, 217), (88, 86, 223), + (91, 91, 225), (95, 98, 227), (103, 109, 222), (112, 122, 218), + (125, 133, 216), (139, 145, 215), (153, 155, 218), (162, 163, 222), + (166, 170, 231), (168, 178, 235), (172, 186, 238), (175, 188, 239), + (177, 193, 236), (175, 191, 234), (174, 190, 233), (168, 183, 234), + (154, 175, 233), (142, 168, 230), (131, 159, 227), (122, 146, 224), + (116, 134, 219), (113, 123, 215), (111, 115, 211), (106, 108, 210), + (102, 103, 209), (98, 101, 207), (93, 96, 207), (88, 88, 206), + (83, 82, 207), (80, 78, 204), (75, 78, 204), (74, 81, 205), + (74, 88, 208), (75, 98, 212), (75, 104, 215), (74, 109, 222), + (75, 111, 225), (71, 110, 224), (67, 110, 223), (64, 107, 221), + (63, 109, 218), (62, 109, 212), (63, 110, 209), (66, 112, 209), + (73, 109, 206), (82, 108, 203), (89, 99, 199), (96, 91, 198), + (98, 83, 193), (99, 75, 185), (95, 72, 181), (90, 67, 178), + (89, 68, 176), (87, 66, 175), (87, 64, 177), (84, 63, 180), + (82, 61, 180), (78, 63, 177), (71, 63, 174), (65, 61, 170), + (60, 60, 160), (57, 62, 156), (55, 69, 156), (56, 74, 160), + (61, 82, 164), (68, 93, 168), (75, 98, 174), (84, 100, 175), + (91, 100, 175), (96, 103, 173), (99, 105, 172), (98, 107, 174), + (96, 114, 176), (93, 119, 181), (93, 124, 186), (95, 125, 193), + (96, 129, 195), (101, 133, 195), (102, 136, 193), (99, 132, 186), + (94, 128, 179), (88, 127, 172), (84, 123, 171), (81, 123, 171) + ), + +// 515 Canyon +((195, 147, 118), (190, 144, 108), (181, 123, 90), (172, 103, 73), + (179, 117, 79), (186, 131, 85), (190, 139, 88), (195, 148, 92), + (202, 155, 111), (201, 160, 115), (200, 166, 119), (184, 161, 123), + (168, 156, 128), (154, 139, 124), (141, 123, 120), (132, 116, 113), + (124, 110, 106), (86, 90, 82), (75, 76, 76), (65, 63, 71), + (59, 56, 72), (54, 50, 74), (54, 47, 77), (55, 44, 81), + (49, 63, 98), (58, 69, 106), (67, 75, 115), (76, 90, 121), + (86, 106, 127), (89, 112, 127), (92, 118, 127), (102, 120, 125), + (103, 124, 122), (106, 124, 118), (105, 124, 112), (105, 124, 106), + (96, 113, 96), (88, 102, 86), (86, 93, 79), (85, 84, 72), + (60, 62, 46), (49, 47, 36), (38, 32, 27), (32, 28, 27), + (27, 25, 28), (29, 28, 29), (31, 31, 30), (37, 35, 35), + (47, 43, 43), (75, 50, 52), (82, 49, 45), (90, 48, 39), + (99, 52, 39), (108, 56, 39), (110, 53, 34), (113, 51, 30), + (112, 61, 28), (121, 70, 41), (131, 80, 54), (131, 89, 60), + (132, 99, 67), (133, 100, 70), (135, 102, 73), (138, 111, 80), + (135, 118, 88), (123, 120, 86), (113, 110, 77), (104, 100, 69), + (99, 94, 65), (94, 88, 62), (86, 68, 53), (81, 54, 49), + (80, 56, 63), (85, 62, 67), (90, 69, 72), (97, 87, 85), + (105, 106, 98), (111, 113, 102), (118, 120, 107), (125, 125, 111), + (126, 128, 107), (128, 125, 85), (121, 112, 73), (114, 100, 62), + (108, 92, 54), (103, 84, 47), (90, 66, 33), (84, 62, 23), + (92, 62, 30), (102, 71, 41), (112, 81, 52), (123, 92, 56), + (135, 103, 61), (163, 133, 78), (186, 152, 87), (209, 166, 96), + (222, 168, 91), (222, 163, 89), (217, 153, 87), (212, 143, 86), + (205, 135, 85), (199, 127, 85), (183, 120, 91), (168, 116, 101), + (152, 122, 114), (143, 132, 125), (135, 143, 137), (133, 147, 142), + (132, 152, 147), (139, 158, 145), (146, 167, 146), (153, 168, 143), + (153, 164, 136), (175, 147, 99), (182, 136, 89), (189, 126, 79), + (182, 103, 59), (168, 87, 48), (145, 83, 39), (134, 68, 34), + (100, 41, 18), (79, 47, 18), (59, 54, 19), (55, 54, 23), + (52, 55, 27), (50, 48, 25), (45, 45, 23), (43, 54, 22), + (47, 62, 36), (66, 73, 60), (73, 79, 64), (80, 85, 68), + (96, 97, 82), (109, 113, 88), (122, 126, 98), (140, 139, 104), + (157, 156, 115), (157, 162, 126), (157, 168, 138), (162, 169, 145), + (168, 171, 152), (169, 186, 167), (172, 194, 174), (170, 194, 178), + (179, 178, 171), (178, 169, 151), (172, 162, 140), (166, 156, 130), + (153, 130, 105), (139, 112, 90), (130, 105, 79), (123, 99, 71), + (116, 98, 74), (118, 103, 74), (120, 108, 74), (130, 119, 73), + (138, 129, 78), (152, 134, 92), (162, 143, 98), (171, 153, 102), + (170, 160, 102), (166, 147, 110), (164, 143, 110), (162, 140, 110), + (159, 134, 98), (161, 122, 82), (159, 107, 64), (153, 95, 56), + (142, 78, 43), (141, 78, 44), (140, 78, 46), (135, 83, 60), + (130, 85, 77), (117, 84, 91), (106, 85, 102), (97, 92, 112), + (94, 92, 127), (82, 93, 144), (81, 95, 146), (78, 103, 141), + (86, 113, 138), (78, 115, 160), (80, 118, 170), (83, 120, 168), + (112, 142, 156), (116, 140, 157), (120, 138, 158), (128, 124, 147), + (149, 118, 122), (172, 117, 100), (186, 111, 86), (198, 102, 75), + (206, 89, 64), (213, 86, 56), (209, 88, 53), (202, 91, 54), + (184, 84, 53), (164, 84, 51), (142, 84, 46), (121, 86, 44), + (104, 83, 36), (91, 83, 32), (81, 84, 27), (74, 84, 37), + (66, 90, 48), (62, 98, 68), (61, 109, 78), (72, 112, 88), + (81, 118, 93), (92, 124, 95), (100, 128, 88), (112, 127, 84), + (122, 122, 82), (130, 118, 81), (133, 111, 71), (123, 101, 68), + (106, 91, 73), (91, 82, 90), (85, 80, 96), (82, 77, 98), + (83, 82, 93), (93, 82, 95), (112, 87, 101), (133, 87, 101), + (155, 94, 97), (173, 100, 86), (192, 107, 81), (199, 104, 74), + (198, 102, 72), (188, 102, 71), (178, 107, 64), (169, 107, 59), + (155, 104, 60), (138, 100, 69), (126, 102, 75), (126, 104, 83), + (129, 108, 90), (128, 111, 98), (129, 118, 101), (136, 126, 111), + (152, 134, 118), (165, 144, 125), (172, 149, 125), (175, 153, 124), + (182, 148, 120), (191, 150, 111), (201, 149, 100), (205, 148, 90), + (212, 142, 85), (215, 141, 90), (223, 150, 99), (227, 157, 106), + (235, 173, 115), (238, 181, 128), (227, 173, 127), (210, 152, 120) + ), + +// 516 Carnations +((152, 48, 49), (153, 50, 49), (148, 40, 42), (143, 30, 35), + (147, 31, 37), (152, 32, 39), (155, 35, 44), (158, 39, 50), + (180, 58, 71), (187, 67, 79), (195, 76, 87), (196, 84, 89), + (197, 92, 92), (194, 95, 82), (192, 99, 72), (188, 95, 69), + (185, 92, 66), (180, 88, 61), (178, 89, 58), (177, 90, 55), + (177, 89, 63), (178, 88, 72), (178, 89, 71), (179, 90, 71), + (167, 91, 73), (154, 89, 71), (141, 87, 69), (139, 80, 62), + (138, 74, 56), (135, 69, 54), (132, 64, 52), (130, 55, 42), + (135, 42, 31), (146, 26, 18), (138, 21, 13), (131, 17, 9), + (117, 20, 9), (103, 23, 10), (95, 27, 11), (88, 31, 13), + (61, 42, 23), (61, 47, 26), (62, 53, 30), (64, 59, 33), + (66, 66, 36), (69, 68, 36), (72, 70, 37), (77, 73, 38), + (74, 73, 38), (72, 71, 35), (66, 64, 32), (60, 57, 29), + (54, 51, 24), (49, 45, 20), (47, 42, 18), (45, 39, 17), + (34, 34, 13), (32, 38, 14), (30, 43, 15), (33, 48, 18), + (37, 53, 21), (39, 56, 23), (42, 59, 25), (46, 61, 30), + (50, 64, 35), (48, 65, 37), (46, 61, 33), (44, 58, 29), + (40, 55, 26), (37, 53, 24), (29, 48, 22), (25, 47, 18), + (24, 39, 6), (26, 34, 7), (28, 30, 9), (34, 27, 8), + (40, 25, 8), (46, 23, 7), (53, 22, 7), (67, 18, 10), + (77, 17, 10), (85, 11, 7), (84, 13, 10), (84, 15, 14), + (83, 17, 15), (82, 19, 16), (77, 17, 19), (75, 18, 21), + (77, 25, 28), (90, 28, 31), (104, 31, 34), (114, 33, 35), + (125, 36, 37), (143, 47, 39), (160, 58, 49), (170, 67, 56), + (179, 75, 66), (193, 98, 74), (186, 100, 79), (179, 103, 85), + (175, 102, 85), (172, 101, 85), (170, 98, 82), (169, 88, 74), + (163, 72, 65), (157, 65, 57), (152, 59, 50), (147, 56, 45), + (142, 53, 41), (134, 47, 36), (120, 51, 37), (105, 57, 38), + (87, 63, 40), (70, 68, 46), (68, 72, 47), (66, 77, 49), + (64, 84, 52), (70, 89, 56), (81, 86, 58), (98, 90, 60), + (129, 111, 61), (141, 109, 64), (154, 108, 67), (156, 106, 66), + (159, 104, 65), (160, 106, 59), (149, 102, 55), (134, 90, 48), + (116, 75, 40), (77, 52, 22), (67, 47, 18), (58, 42, 14), + (42, 33, 7), (30, 24, 3), (24, 21, 1), (21, 21, 0), + (14, 21, 8), (18, 24, 11), (23, 28, 15), (27, 31, 16), + (32, 34, 17), (41, 38, 23), (53, 41, 28), (66, 43, 32), + (80, 42, 33), (103, 39, 31), (104, 40, 31), (105, 41, 31), + (100, 41, 31), (93, 43, 27), (86, 45, 23), (81, 50, 22), + (72, 53, 14), (74, 50, 12), (76, 47, 11), (91, 47, 14), + (103, 48, 18), (116, 49, 22), (126, 44, 25), (140, 47, 34), + (148, 55, 41), (149, 74, 46), (145, 76, 48), (142, 79, 51), + (133, 84, 55), (117, 83, 52), (101, 84, 44), (84, 78, 37), + (56, 63, 34), (51, 61, 32), (47, 60, 30), (45, 58, 25), + (54, 56, 26), (69, 58, 31), (89, 63, 37), (108, 73, 44), + (129, 81, 55), (149, 89, 67), (165, 98, 77), (187, 109, 78), + (200, 125, 85), (215, 141, 93), (215, 150, 103), (225, 147, 104), + (217, 144, 101), (212, 143, 100), (207, 143, 99), (205, 132, 95), + (188, 116, 92), (173, 102, 82), (162, 93, 73), (157, 87, 65), + (152, 81, 59), (143, 73, 51), (135, 65, 45), (126, 59, 41), + (121, 52, 37), (113, 44, 30), (102, 39, 22), (92, 41, 21), + (90, 44, 24), (91, 42, 28), (91, 43, 30), (93, 47, 35), + (96, 54, 41), (101, 52, 43), (103, 47, 40), (103, 36, 36), + (97, 34, 30), (89, 29, 26), (79, 25, 17), (74, 14, 11), + (69, 10, 5), (72, 10, 6), (78, 12, 12), (94, 14, 19), + (112, 21, 26), (130, 34, 34), (147, 44, 46), (160, 52, 54), + (172, 60, 63), (177, 71, 66), (181, 77, 69), (177, 77, 68), + (178, 73, 65), (175, 65, 62), (180, 56, 56), (182, 43, 49), + (185, 33, 40), (184, 23, 33), (186, 17, 26), (184, 10, 22), + (173, 7, 20), (159, 12, 17), (146, 26, 18), (133, 39, 22), + (120, 48, 32), (110, 61, 38), (114, 81, 49), (124, 107, 66), + (135, 123, 85), (140, 126, 87), (150, 122, 83), (161, 121, 83), + (170, 122, 92), (169, 113, 90), (162, 98, 78), (154, 81, 64), + (145, 71, 61), (141, 59, 60), (140, 54, 58), (144, 52, 55), + (148, 56, 59), (155, 61, 66), (153, 57, 62), (154, 53, 56) + ), + +// 517 Carnival +((203, 92, 124), (201, 82, 109), (200, 79, 105), (199, 77, 101), + (197, 75, 96), (196, 73, 92), (195, 73, 89), (194, 73, 87), + (186, 72, 78), (183, 70, 75), (181, 69, 73), (177, 69, 76), + (173, 69, 79), (169, 68, 80), (166, 68, 81), (164, 69, 83), + (163, 71, 85), (164, 72, 97), (167, 77, 111), (170, 82, 125), + (171, 92, 139), (173, 102, 154), (173, 106, 160), (174, 110, 166), + (182, 126, 186), (188, 132, 196), (194, 139, 206), (196, 146, 212), + (199, 154, 219), (199, 157, 220), (200, 160, 221), (201, 159, 218), + (200, 155, 213), (201, 140, 187), (198, 128, 172), (195, 117, 158), + (190, 106, 148), (185, 95, 138), (184, 90, 134), (183, 86, 130), + (181, 81, 117), (181, 83, 115), (181, 85, 113), (182, 90, 121), + (183, 96, 129), (184, 100, 133), (186, 104, 138), (191, 115, 149), + (196, 122, 158), (203, 136, 166), (204, 138, 170), (206, 141, 174), + (206, 141, 176), (206, 141, 178), (206, 139, 177), (207, 137, 176), + (202, 129, 166), (199, 124, 159), (196, 119, 153), (195, 114, 145), + (195, 110, 138), (194, 106, 133), (193, 102, 129), (191, 95, 119), + (187, 86, 108), (178, 69, 91), (176, 64, 85), (174, 60, 80), + (174, 60, 80), (174, 60, 81), (173, 60, 83), (171, 64, 91), + (172, 75, 124), (175, 82, 141), (178, 89, 158), (183, 95, 171), + (188, 102, 185), (190, 106, 191), (193, 110, 198), (196, 117, 210), + (197, 122, 219), (201, 123, 228), (200, 119, 223), (199, 116, 218), + (198, 114, 213), (197, 113, 208), (194, 110, 195), (190, 111, 181), + (189, 113, 155), (186, 114, 151), (184, 115, 148), (183, 114, 149), + (183, 113, 151), (178, 112, 154), (182, 112, 156), (185, 111, 159), + (189, 111, 164), (192, 115, 186), (192, 115, 199), (192, 116, 213), + (193, 116, 216), (195, 116, 219), (196, 114, 215), (193, 112, 206), + (178, 101, 189), (168, 98, 185), (158, 96, 181), (155, 94, 176), + (153, 92, 171), (152, 89, 158), (149, 86, 147), (152, 80, 140), + (149, 75, 139), (149, 75, 153), (153, 77, 155), (157, 79, 158), + (164, 89, 163), (174, 96, 168), (184, 104, 177), (193, 113, 187), + (199, 122, 208), (199, 126, 215), (200, 131, 222), (200, 134, 225), + (200, 137, 228), (201, 143, 232), (199, 148, 233), (198, 150, 234), + (193, 147, 236), (193, 145, 236), (193, 145, 235), (193, 146, 235), + (193, 149, 230), (194, 153, 224), (192, 150, 217), (192, 145, 209), + (194, 132, 194), (193, 124, 188), (193, 117, 182), (191, 114, 179), + (189, 112, 176), (184, 102, 168), (180, 94, 158), (178, 85, 150), + (178, 78, 139), (177, 67, 132), (177, 64, 131), (177, 61, 130), + (175, 59, 130), (174, 58, 131), (175, 61, 127), (178, 62, 124), + (191, 79, 124), (194, 84, 127), (197, 89, 130), (201, 98, 142), + (203, 107, 155), (204, 115, 167), (203, 127, 176), (202, 136, 183), + (204, 144, 188), (205, 154, 199), (205, 154, 201), (206, 154, 204), + (206, 153, 209), (204, 151, 214), (199, 146, 217), (194, 142, 217), + (190, 132, 217), (190, 128, 217), (191, 125, 217), (195, 122, 220), + (198, 115, 224), (199, 111, 225), (198, 109, 228), (198, 113, 228), + (198, 112, 226), (202, 117, 224), (208, 119, 225), (212, 121, 223), + (212, 123, 223), (212, 130, 221), (209, 135, 219), (206, 143, 216), + (203, 151, 214), (202, 151, 213), (201, 152, 213), (201, 151, 212), + (197, 149, 208), (194, 147, 204), (193, 142, 200), (192, 139, 196), + (193, 137, 195), (193, 133, 195), (193, 126, 194), (194, 120, 192), + (195, 111, 193), (194, 103, 190), (192, 96, 184), (190, 90, 179), + (189, 85, 170), (189, 84, 160), (191, 80, 153), (193, 79, 145), + (193, 73, 131), (191, 68, 117), (189, 63, 101), (187, 63, 85), + (190, 66, 74), (195, 75, 72), (201, 84, 74), (205, 90, 80), + (207, 97, 86), (207, 102, 95), (210, 109, 105), (212, 116, 117), + (214, 125, 134), (217, 132, 152), (219, 137, 169), (217, 140, 184), + (217, 142, 197), (216, 142, 208), (217, 142, 216), (216, 143, 220), + (218, 142, 222), (217, 143, 218), (215, 141, 213), (213, 140, 209), + (214, 142, 207), (213, 144, 206), (213, 146, 205), (213, 150, 203), + (211, 151, 198), (208, 148, 195), (207, 146, 191), (205, 140, 185), + (202, 133, 183), (199, 128, 179), (198, 124, 172), (196, 118, 168), + (195, 114, 163), (197, 112, 159), (198, 110, 156), (198, 109, 156), + (202, 111, 151), (202, 113, 149), (202, 115, 147), (203, 119, 147), + (204, 121, 146), (202, 121, 151), (206, 121, 153), (207, 118, 155), + (208, 115, 155), (208, 109, 151), (207, 105, 142), (204, 96, 134) + ), + +// 518 Carpenter +((143, 159, 149), (98, 114, 104), (77, 91, 82), (57, 68, 60), + (48, 59, 52), (39, 50, 44), (39, 49, 43), (39, 48, 43), + (41, 50, 47), (44, 55, 49), (47, 60, 51), (65, 62, 47), + (83, 65, 43), (95, 71, 43), (108, 78, 44), (105, 80, 51), + (103, 83, 58), (87, 98, 92), (108, 102, 84), (130, 107, 76), + (147, 112, 67), (164, 118, 58), (158, 112, 52), (152, 106, 47), + (109, 71, 26), (102, 66, 22), (95, 62, 19), (107, 70, 24), + (119, 79, 30), (123, 85, 36), (127, 91, 43), (148, 111, 59), + (165, 123, 73), (195, 138, 69), (180, 128, 61), (166, 118, 54), + (149, 105, 49), (133, 93, 44), (130, 91, 44), (127, 90, 45), + (120, 88, 47), (113, 90, 59), (107, 92, 71), (101, 102, 86), + (95, 112, 102), (96, 116, 105), (98, 120, 108), (98, 120, 108), + (93, 115, 103), (80, 93, 84), (75, 87, 76), (71, 82, 68), + (61, 73, 62), (52, 65, 56), (51, 64, 55), (51, 64, 55), + (49, 62, 53), (50, 63, 54), (52, 65, 56), (59, 74, 65), + (67, 84, 74), (72, 86, 78), (77, 88, 82), (82, 98, 87), + (92, 110, 98), (107, 127, 116), (132, 127, 102), (157, 127, 89), + (164, 128, 84), (171, 129, 79), (163, 113, 50), (152, 105, 49), + (88, 71, 45), (72, 66, 51), (56, 62, 58), (68, 72, 59), + (80, 82, 61), (94, 88, 68), (109, 94, 75), (147, 117, 79), + (167, 133, 88), (193, 139, 75), (179, 128, 65), (165, 117, 55), + (154, 111, 57), (144, 106, 59), (119, 99, 72), (94, 104, 96), + (90, 103, 94), (87, 100, 91), (84, 97, 88), (93, 96, 80), + (102, 96, 72), (108, 94, 68), (113, 94, 64), (136, 95, 51), + (155, 108, 52), (131, 95, 59), (120, 106, 86), (109, 118, 113), + (114, 125, 118), (120, 133, 124), (129, 140, 132), (135, 155, 144), + (140, 156, 146), (158, 149, 121), (176, 142, 96), (180, 143, 95), + (184, 144, 95), (194, 147, 93), (193, 148, 89), (176, 139, 87), + (159, 118, 72), (113, 93, 66), (107, 94, 72), (102, 95, 79), + (97, 110, 103), (95, 112, 102), (100, 117, 107), (102, 122, 110), + (129, 123, 107), (147, 128, 100), (165, 133, 94), (166, 134, 95), + (168, 136, 97), (168, 135, 92), (162, 127, 87), (159, 125, 87), + (152, 111, 65), (131, 95, 47), (129, 92, 44), (127, 89, 42), + (122, 88, 40), (107, 74, 29), (103, 73, 39), (96, 66, 28), + (95, 62, 19), (93, 63, 27), (92, 65, 35), (88, 69, 42), + (85, 73, 49), (91, 84, 68), (97, 108, 100), (102, 122, 111), + (112, 128, 117), (124, 144, 133), (120, 141, 129), (116, 138, 126), + (111, 128, 118), (98, 114, 103), (82, 95, 86), (66, 82, 72), + (50, 63, 56), (47, 59, 53), (45, 56, 50), (45, 54, 49), + (44, 50, 48), (44, 53, 48), (52, 54, 41), (69, 49, 24), + (75, 51, 23), (92, 61, 17), (93, 61, 17), (94, 61, 18), + (90, 65, 34), (74, 73, 55), (83, 78, 58), (93, 73, 48), + (114, 80, 43), (114, 81, 43), (115, 83, 44), (101, 84, 58), + (78, 91, 82), (79, 92, 83), (74, 90, 80), (69, 80, 72), + (59, 72, 63), (53, 62, 57), (47, 58, 50), (44, 55, 47), + (52, 54, 41), (73, 55, 35), (74, 50, 22), (82, 54, 15), + (84, 54, 16), (81, 53, 16), (78, 52, 17), (74, 51, 20), + (70, 48, 24), (72, 48, 20), (71, 46, 16), (71, 47, 21), + (66, 49, 23), (56, 47, 30), (48, 48, 38), (41, 50, 45), + (36, 45, 40), (34, 40, 36), (41, 42, 28), (58, 42, 19), + (64, 44, 19), (68, 44, 18), (60, 45, 24), (51, 52, 38), + (41, 52, 44), (43, 54, 48), (41, 50, 47), (40, 46, 42), + (60, 44, 21), (64, 46, 24), (74, 51, 20), (90, 58, 20), + (94, 68, 33), (103, 82, 55), (105, 89, 66), (121, 97, 69), + (154, 122, 83), (168, 137, 93), (186, 150, 102), (198, 157, 101), + (199, 159, 107), (195, 158, 106), (199, 152, 100), (197, 150, 94), + (196, 151, 96), (194, 152, 102), (186, 149, 105), (183, 146, 101), + (182, 146, 98), (182, 145, 93), (183, 139, 92), (198, 140, 76), + (194, 145, 87), (180, 140, 91), (169, 137, 96), (121, 132, 124), + (127, 140, 133), (126, 143, 133), (134, 150, 140), (137, 153, 143), + (139, 155, 145), (136, 153, 143), (123, 145, 132), (121, 141, 130), + (119, 132, 123), (115, 131, 121), (104, 124, 113), (105, 118, 109), + (105, 116, 108), (102, 118, 108), (104, 124, 113), (106, 123, 113), + (115, 137, 124), (126, 142, 132), (139, 150, 142), (179, 145, 100) + ), + +// 519 Cellist +((141, 91, 68), (93, 57, 37), (80, 47, 29), (68, 37, 21), + (65, 36, 20), (63, 35, 20), (59, 33, 19), (55, 32, 18), + (43, 26, 14), (40, 25, 14), (37, 24, 14), (36, 23, 12), + (35, 23, 11), (38, 25, 12), (41, 27, 14), (43, 27, 14), + (46, 28, 15), (55, 36, 19), (60, 41, 22), (65, 46, 26), + (73, 52, 30), (81, 58, 34), (86, 63, 38), (92, 68, 43), + (109, 92, 68), (111, 98, 77), (113, 104, 87), (117, 102, 84), + (121, 101, 81), (116, 99, 79), (112, 98, 78), (106, 93, 78), + (105, 79, 62), (105, 66, 41), (110, 65, 40), (115, 64, 39), + (116, 64, 38), (117, 65, 37), (116, 65, 37), (115, 66, 38), + (105, 59, 35), (94, 54, 30), (83, 50, 26), (75, 48, 27), + (68, 47, 28), (68, 47, 29), (69, 47, 30), (75, 50, 33), + (88, 63, 39), (131, 100, 63), (150, 115, 73), (169, 131, 83), + (190, 152, 100), (212, 174, 117), (218, 179, 120), (224, 185, 124), + (231, 184, 123), (231, 183, 120), (232, 183, 117), (225, 170, 104), + (218, 157, 92), (215, 154, 90), (213, 151, 88), (206, 146, 80), + (194, 137, 74), (181, 121, 66), (175, 116, 64), (169, 112, 62), + (165, 109, 60), (162, 107, 58), (159, 101, 57), (159, 98, 53), + (143, 91, 48), (134, 85, 45), (126, 80, 43), (116, 77, 41), + (107, 74, 40), (102, 71, 39), (98, 69, 38), (91, 63, 36), + (87, 58, 34), (83, 54, 30), (80, 51, 29), (78, 48, 28), + (77, 47, 27), (76, 46, 27), (71, 43, 25), (66, 42, 24), + (55, 37, 22), (49, 32, 19), (44, 28, 16), (42, 26, 15), + (40, 24, 15), (38, 23, 14), (37, 22, 13), (38, 23, 13), + (41, 27, 15), (59, 39, 24), (75, 47, 30), (92, 56, 37), + (101, 59, 40), (111, 63, 43), (131, 72, 51), (153, 83, 58), + (192, 97, 71), (200, 109, 77), (209, 121, 84), (212, 124, 85), + (215, 128, 87), (208, 126, 85), (194, 120, 81), (176, 118, 77), + (160, 114, 72), (124, 90, 53), (115, 83, 49), (107, 77, 45), + (94, 66, 39), (85, 60, 33), (81, 57, 30), (79, 54, 29), + (71, 48, 26), (68, 47, 24), (66, 46, 23), (66, 45, 23), + (66, 44, 24), (64, 45, 24), (63, 45, 24), (64, 46, 25), + (68, 48, 27), (79, 53, 30), (81, 54, 31), (83, 55, 32), + (87, 58, 34), (92, 60, 36), (98, 65, 37), (104, 67, 37), + (123, 72, 42), (135, 73, 44), (147, 75, 47), (153, 77, 47), + (159, 80, 48), (170, 86, 54), (181, 95, 60), (188, 101, 67), + (190, 104, 69), (188, 104, 70), (186, 103, 68), (185, 102, 67), + (172, 98, 62), (155, 84, 54), (141, 71, 44), (132, 60, 35), + (104, 48, 24), (97, 46, 22), (91, 45, 20), (87, 45, 20), + (88, 49, 23), (91, 53, 29), (96, 59, 33), (106, 70, 38), + (115, 79, 46), (121, 84, 54), (123, 85, 53), (125, 87, 52), + (130, 89, 53), (132, 87, 52), (127, 78, 48), (119, 71, 42), + (111, 64, 34), (109, 62, 34), (107, 61, 34), (97, 59, 36), + (89, 59, 40), (82, 62, 46), (85, 66, 49), (92, 68, 50), + (100, 71, 52), (103, 74, 58), (107, 76, 57), (112, 73, 50), + (119, 69, 42), (119, 66, 39), (114, 63, 36), (107, 58, 31), + (92, 47, 21), (89, 45, 20), (87, 44, 19), (82, 41, 18), + (77, 38, 18), (73, 36, 17), (69, 35, 16), (67, 33, 15), + (67, 34, 16), (71, 36, 16), (77, 40, 19), (87, 48, 24), + (100, 60, 32), (117, 75, 39), (134, 89, 47), (151, 104, 57), + (163, 117, 70), (167, 122, 79), (164, 120, 84), (162, 118, 78), + (156, 114, 75), (146, 104, 69), (133, 90, 66), (125, 80, 56), + (123, 75, 47), (127, 71, 42), (139, 68, 42), (153, 68, 46), + (168, 73, 50), (177, 78, 56), (185, 85, 64), (189, 87, 70), + (199, 95, 73), (199, 104, 73), (195, 112, 75), (184, 113, 78), + (182, 114, 77), (177, 114, 71), (168, 111, 64), (152, 102, 60), + (138, 95, 57), (127, 88, 53), (114, 81, 48), (101, 74, 43), + (88, 66, 38), (79, 60, 34), (72, 53, 32), (67, 48, 29), + (61, 43, 25), (56, 39, 23), (51, 34, 21), (48, 32, 19), + (45, 30, 17), (45, 31, 17), (45, 34, 19), (47, 37, 21), + (49, 40, 23), (52, 40, 22), (54, 41, 23), (56, 43, 26), + (59, 45, 29), (63, 45, 29), (68, 46, 29), (76, 52, 32), + (88, 61, 37), (103, 73, 44), (119, 86, 50), (143, 100, 71), + (163, 111, 81), (154, 106, 77), (137, 96, 60), (128, 87, 62) + ), + +// 520 Cherry +((179, 49, 37), (185, 76, 61), (196, 103, 83), (208, 130, 106), + (220, 138, 116), (233, 146, 126), (236, 145, 125), (239, 145, 125), + (239, 129, 112), (236, 106, 94), (233, 84, 76), (224, 68, 61), + (216, 53, 47), (205, 47, 43), (194, 41, 39), (188, 38, 35), + (182, 35, 31), (141, 27, 18), (126, 21, 13), (112, 16, 8), + (104, 13, 5), (96, 11, 2), (96, 10, 3), (97, 10, 4), + (118, 20, 13), (138, 25, 18), (158, 31, 24), (166, 37, 33), + (174, 43, 42), (178, 47, 47), (183, 51, 52), (192, 59, 56), + (193, 58, 58), (179, 58, 54), (174, 52, 47), (169, 47, 41), + (171, 38, 35), (174, 29, 29), (174, 23, 25), (174, 18, 21), + (179, 9, 21), (185, 10, 23), (191, 12, 25), (191, 13, 25), + (191, 14, 26), (188, 18, 26), (186, 22, 27), (183, 31, 28), + (182, 36, 32), (181, 51, 41), (183, 65, 50), (186, 80, 59), + (199, 91, 70), (213, 103, 82), (217, 107, 86), (221, 112, 91), + (226, 116, 94), (228, 112, 93), (231, 108, 92), (232, 111, 96), + (234, 115, 100), (235, 117, 102), (237, 120, 105), (235, 122, 108), + (229, 116, 105), (219, 113, 98), (199, 98, 86), (180, 84, 74), + (165, 71, 63), (151, 59, 53), (117, 41, 34), (93, 27, 22), + (66, 4, 8), (55, 2, 5), (45, 0, 2), (51, 0, 2), + (57, 1, 3), (59, 1, 2), (62, 2, 1), (64, 2, 0), + (66, 3, 1), (77, 8, 4), (87, 10, 5), (98, 12, 7), + (104, 12, 7), (110, 13, 8), (129, 16, 14), (144, 18, 19), + (157, 15, 16), (155, 14, 17), (153, 13, 18), (149, 11, 17), + (146, 9, 17), (133, 6, 13), (118, 6, 10), (103, 5, 7), + (91, 2, 3), (77, 0, 3), (73, 0, 1), (70, 0, 0), + (68, 0, 0), (66, 0, 0), (64, 0, 0), (61, 0, 0), + (59, 1, 1), (59, 1, 1), (59, 2, 1), (59, 2, 0), + (59, 2, 0), (58, 1, 0), (60, 2, 1), (62, 2, 1), + (64, 2, 1), (71, 1, 0), (73, 1, 0), (76, 1, 0), + (81, 3, 0), (90, 3, 0), (101, 4, 0), (113, 3, 3), + (131, 2, 6), (140, 2, 6), (150, 3, 7), (150, 2, 7), + (151, 2, 7), (146, 1, 7), (142, 2, 6), (139, 2, 4), + (134, 1, 2), (121, 2, 0), (118, 2, 0), (116, 3, 0), + (112, 2, 0), (110, 1, 0), (111, 1, 0), (110, 1, 0), + (114, 1, 0), (119, 4, 1), (125, 7, 3), (128, 10, 5), + (132, 14, 8), (140, 25, 15), (146, 33, 21), (146, 37, 25), + (144, 37, 23), (136, 37, 23), (132, 35, 23), (128, 33, 23), + (119, 25, 17), (112, 16, 11), (108, 9, 4), (104, 4, 2), + (96, 2, 2), (95, 1, 1), (95, 1, 1), (94, 1, 0), + (93, 1, 0), (92, 1, 0), (92, 1, 0), (92, 1, 0), + (93, 2, 1), (100, 5, 5), (104, 6, 6), (108, 8, 8), + (117, 11, 10), (123, 17, 12), (130, 23, 17), (136, 28, 20), + (143, 28, 16), (141, 27, 15), (140, 27, 15), (132, 25, 14), + (125, 19, 10), (118, 13, 6), (111, 9, 3), (103, 5, 1), + (97, 2, 0), (93, 1, 0), (90, 2, 0), (91, 3, 0), + (93, 5, 1), (98, 6, 4), (103, 9, 8), (108, 15, 12), + (131, 30, 22), (138, 33, 26), (146, 37, 31), (157, 44, 40), + (169, 53, 46), (187, 56, 49), (199, 58, 50), (209, 57, 52), + (213, 57, 54), (216, 56, 54), (208, 57, 51), (201, 58, 53), + (192, 66, 62), (192, 71, 66), (186, 78, 65), (187, 77, 61), + (181, 86, 70), (184, 88, 69), (182, 86, 64), (182, 72, 47), + (173, 61, 41), (164, 51, 31), (151, 43, 25), (135, 31, 16), + (123, 20, 11), (113, 11, 5), (105, 6, 3), (97, 3, 1), + (90, 1, 0), (83, 0, 0), (79, 0, 0), (79, 0, 0), + (79, 0, 0), (79, 0, 0), (81, 1, 0), (87, 2, 0), + (94, 4, 0), (102, 7, 0), (109, 10, 4), (114, 12, 7), + (116, 15, 9), (115, 17, 8), (112, 21, 11), (111, 20, 13), + (110, 22, 13), (115, 20, 11), (120, 19, 11), (132, 19, 15), + (147, 23, 18), (165, 27, 22), (180, 26, 25), (193, 26, 29), + (202, 26, 32), (203, 27, 33), (198, 22, 30), (189, 18, 26), + (179, 13, 22), (164, 9, 17), (149, 4, 12), (137, 1, 9), + (131, 0, 9), (127, 0, 7), (124, 0, 7), (123, 0, 8), + (125, 2, 8), (131, 4, 9), (138, 7, 9), (155, 14, 17), + (164, 20, 21), (160, 22, 19), (151, 21, 12), (162, 34, 21) + ), + +// 521 Circus +((43, 95, 52), (58, 92, 51), (71, 87, 46), (85, 83, 41), + (95, 73, 37), (105, 63, 34), (111, 58, 35), (117, 53, 36), + (144, 35, 38), (153, 25, 33), (163, 15, 28), (168, 10, 29), + (173, 5, 30), (173, 8, 35), (173, 11, 41), (172, 14, 44), + (171, 18, 48), (164, 30, 70), (157, 35, 84), (151, 40, 98), + (143, 46, 108), (136, 53, 118), (137, 57, 124), (138, 61, 131), + (144, 63, 156), (142, 65, 157), (141, 68, 158), (140, 74, 147), + (139, 80, 136), (140, 82, 130), (141, 85, 125), (143, 94, 115), + (140, 104, 103), (125, 123, 68), (124, 129, 54), (123, 135, 40), + (123, 140, 34), (123, 146, 28), (121, 147, 27), (120, 148, 26), + (117, 144, 31), (119, 137, 34), (121, 131, 38), (117, 123, 47), + (113, 115, 57), (110, 110, 63), (107, 106, 69), (109, 100, 80), + (112, 92, 90), (125, 72, 111), (123, 64, 118), (122, 56, 126), + (120, 51, 128), (119, 47, 130), (118, 44, 129), (118, 42, 128), + (100, 33, 117), (87, 35, 111), (75, 38, 105), (66, 42, 101), + (58, 47, 97), (55, 48, 94), (53, 50, 91), (53, 52, 85), + (58, 54, 78), (77, 58, 67), (88, 57, 61), (99, 56, 55), + (105, 53, 50), (112, 50, 46), (126, 44, 35), (138, 37, 25), + (153, 26, 13), (155, 24, 10), (157, 22, 7), (155, 21, 4), + (154, 20, 2), (153, 18, 1), (152, 16, 1), (149, 13, 2), + (143, 10, 7), (130, 13, 18), (124, 13, 22), (119, 14, 26), + (117, 14, 30), (116, 14, 34), (115, 14, 46), (111, 17, 58), + (96, 26, 68), (88, 32, 70), (80, 38, 73), (77, 41, 76), + (74, 45, 79), (69, 53, 84), (63, 59, 86), (55, 64, 87), + (47, 67, 87), (36, 72, 92), (33, 74, 96), (30, 76, 100), + (29, 74, 101), (28, 73, 102), (25, 67, 103), (20, 59, 103), + (11, 48, 103), (9, 42, 101), (8, 37, 99), (9, 34, 97), + (11, 31, 96), (17, 27, 95), (28, 26, 97), (38, 27, 100), + (49, 28, 103), (70, 32, 99), (76, 32, 97), (83, 33, 95), + (96, 33, 90), (104, 31, 86), (107, 30, 76), (103, 30, 68), + (92, 28, 43), (86, 24, 33), (81, 21, 24), (77, 20, 20), + (73, 19, 17), (64, 19, 11), (58, 17, 7), (54, 18, 7), + (52, 17, 9), (49, 19, 20), (48, 18, 23), (48, 18, 26), + (45, 17, 32), (42, 16, 39), (41, 19, 49), (41, 26, 61), + (42, 36, 82), (44, 39, 88), (47, 42, 95), (51, 45, 99), + (56, 48, 103), (69, 57, 113), (85, 66, 124), (100, 74, 131), + (115, 80, 135), (145, 86, 134), (153, 87, 134), (162, 89, 135), + (174, 93, 136), (184, 96, 139), (191, 96, 143), (195, 92, 140), + (201, 76, 124), (201, 72, 120), (201, 69, 117), (199, 64, 118), + (195, 58, 115), (190, 51, 108), (181, 43, 91), (174, 40, 70), + (169, 43, 56), (162, 64, 40), (158, 69, 36), (155, 74, 32), + (151, 86, 24), (148, 97, 20), (148, 111, 19), (147, 126, 23), + (138, 145, 37), (136, 144, 41), (135, 143, 45), (135, 135, 51), + (136, 123, 55), (132, 110, 56), (128, 102, 55), (128, 91, 57), + (132, 76, 60), (142, 60, 65), (151, 45, 73), (156, 36, 79), + (161, 32, 85), (165, 30, 92), (170, 26, 99), (176, 24, 110), + (182, 27, 134), (181, 28, 138), (181, 29, 142), (181, 29, 146), + (182, 27, 145), (180, 24, 141), (177, 21, 137), (171, 18, 134), + (163, 16, 132), (156, 12, 129), (148, 8, 122), (139, 5, 113), + (127, 2, 103), (112, 1, 94), (97, 2, 88), (82, 2, 84), + (67, 3, 80), (56, 4, 77), (45, 6, 73), (35, 7, 70), + (25, 9, 69), (16, 12, 69), (10, 14, 71), (6, 16, 74), + (4, 16, 76), (2, 14, 76), (1, 13, 75), (2, 13, 73), + (7, 14, 73), (16, 17, 72), (25, 18, 69), (32, 16, 63), + (37, 14, 55), (42, 13, 48), (49, 18, 44), (57, 25, 41), + (62, 30, 39), (64, 31, 35), (62, 28, 33), (57, 27, 33), + (50, 27, 35), (43, 30, 40), (36, 31, 43), (32, 31, 51), + (27, 28, 57), (20, 26, 64), (14, 26, 72), (7, 27, 78), + (4, 28, 85), (3, 30, 91), (4, 34, 97), (5, 37, 101), + (7, 41, 105), (8, 42, 108), (10, 42, 110), (12, 42, 112), + (15, 44, 112), (17, 47, 112), (17, 48, 111), (16, 47, 111), + (14, 46, 111), (15, 45, 109), (16, 49, 107), (19, 55, 104), + (20, 60, 100), (20, 65, 96), (18, 69, 92), (18, 73, 87), + (22, 78, 80), (29, 84, 70), (37, 90, 61), (41, 94, 53) + ), + +// 522 City_Street +((73, 45, 53), (42, 26, 29), (32, 16, 16), (22, 6, 4), + (28, 10, 6), (34, 14, 8), (39, 19, 10), (44, 24, 13), + (72, 51, 39), (86, 63, 51), (100, 76, 64), (109, 85, 71), + (118, 94, 78), (121, 95, 86), (124, 96, 94), (122, 94, 96), + (121, 93, 98), (104, 86, 96), (96, 82, 93), (89, 78, 90), + (85, 71, 84), (81, 64, 79), (79, 62, 77), (78, 60, 75), + (75, 65, 76), (74, 65, 72), (73, 65, 68), (71, 56, 58), + (70, 48, 48), (69, 44, 43), (69, 41, 39), (67, 35, 32), + (63, 30, 27), (56, 23, 16), (54, 17, 10), (52, 12, 5), + (49, 8, 3), (46, 5, 1), (44, 5, 1), (42, 5, 1), + (32, 6, 2), (31, 5, 1), (30, 5, 1), (31, 6, 0), + (33, 7, 0), (33, 7, 0), (33, 8, 1), (34, 9, 1), + (35, 9, 1), (43, 14, 3), (45, 17, 6), (47, 21, 10), + (47, 26, 14), (47, 31, 18), (47, 32, 19), (47, 34, 20), + (42, 34, 24), (39, 32, 25), (36, 31, 26), (35, 27, 23), + (34, 23, 20), (33, 20, 18), (33, 18, 16), (35, 14, 12), + (37, 10, 9), (44, 3, 4), (48, 2, 3), (52, 2, 2), + (54, 2, 1), (57, 3, 1), (59, 3, 1), (61, 2, 0), + (64, 2, 0), (64, 2, 0), (64, 3, 0), (65, 4, 0), + (66, 6, 0), (67, 6, 0), (69, 6, 0), (73, 6, 1), + (76, 5, 3), (75, 10, 5), (75, 17, 8), (76, 25, 12), + (76, 28, 16), (77, 31, 20), (78, 37, 25), (79, 42, 29), + (80, 55, 29), (83, 59, 30), (86, 64, 32), (89, 65, 34), + (92, 66, 36), (96, 68, 38), (98, 71, 40), (103, 78, 43), + (110, 83, 47), (133, 101, 65), (141, 113, 77), (150, 126, 90), + (153, 130, 95), (156, 134, 100), (159, 139, 107), (160, 140, 109), + (152, 129, 95), (146, 118, 85), (140, 108, 76), (137, 102, 71), + (135, 96, 66), (123, 81, 51), (112, 65, 37), (108, 50, 22), + (103, 37, 13), (108, 23, 4), (105, 21, 4), (103, 19, 4), + (96, 14, 5), (86, 10, 8), (79, 8, 12), (78, 11, 16), + (79, 21, 19), (81, 27, 23), (83, 34, 27), (87, 41, 30), + (91, 49, 34), (101, 63, 42), (116, 77, 47), (126, 90, 51), + (134, 93, 54), (137, 93, 51), (135, 90, 49), (134, 88, 48), + (127, 83, 44), (116, 74, 41), (108, 61, 34), (94, 51, 29), + (67, 32, 23), (63, 31, 25), (60, 31, 28), (62, 34, 30), + (64, 37, 32), (70, 45, 36), (70, 55, 45), (72, 62, 53), + (73, 67, 59), (80, 68, 55), (78, 66, 53), (77, 65, 51), + (73, 61, 49), (69, 59, 49), (66, 56, 47), (67, 57, 45), + (79, 65, 46), (84, 69, 48), (89, 73, 50), (96, 79, 56), + (101, 84, 60), (105, 90, 64), (108, 91, 68), (113, 90, 70), + (117, 94, 77), (109, 94, 84), (106, 94, 87), (103, 94, 90), + (103, 91, 93), (108, 98, 100), (115, 104, 106), (123, 113, 111), + (131, 126, 123), (133, 127, 124), (135, 128, 126), (136, 125, 126), + (136, 117, 119), (135, 110, 112), (130, 98, 95), (123, 85, 79), + (118, 70, 64), (113, 53, 52), (111, 39, 41), (110, 29, 29), + (106, 23, 16), (100, 17, 6), (95, 11, 2), (89, 4, 0), + (75, 4, 0), (69, 5, 1), (64, 6, 3), (55, 8, 5), + (47, 10, 9), (44, 10, 13), (45, 12, 18), (49, 19, 28), + (59, 32, 41), (73, 51, 59), (89, 71, 78), (110, 91, 98), + (131, 112, 119), (154, 133, 139), (172, 157, 163), (184, 182, 185), + (193, 204, 203), (206, 222, 221), (221, 234, 229), (233, 241, 235), + (234, 242, 239), (223, 236, 234), (211, 227, 227), (199, 216, 217), + (193, 200, 199), (182, 182, 181), (162, 158, 157), (139, 135, 131), + (116, 112, 107), (97, 91, 86), (82, 72, 66), (69, 54, 48), + (58, 38, 31), (48, 29, 19), (45, 25, 13), (46, 24, 10), + (50, 22, 8), (55, 20, 5), (57, 20, 4), (60, 24, 6), + (63, 29, 11), (65, 34, 16), (67, 36, 19), (63, 36, 20), + (56, 35, 23), (52, 35, 25), (48, 36, 30), (51, 36, 36), + (52, 36, 42), (48, 36, 47), (47, 34, 49), (44, 31, 47), + (47, 29, 45), (50, 27, 42), (50, 26, 40), (46, 25, 39), + (39, 22, 35), (32, 19, 29), (26, 16, 24), (23, 15, 18), + (23, 18, 17), (26, 22, 18), (33, 29, 21), (40, 35, 28), + (52, 44, 38), (67, 52, 50), (80, 60, 62), (91, 67, 68), + (86, 65, 63), (82, 63, 59), (78, 55, 55), (72, 47, 51) + ), + +// 523 Clash +((85, 129, 75), (24, 79, 141), (27, 75, 124), (31, 72, 108), + (35, 62, 102), (39, 53, 97), (40, 51, 90), (41, 49, 84), + (33, 46, 59), (32, 48, 49), (31, 51, 39), (30, 46, 35), + (30, 41, 32), (40, 34, 30), (51, 28, 29), (56, 25, 26), + (61, 22, 23), (63, 15, 18), (52, 14, 24), (41, 13, 30), + (33, 12, 44), (26, 12, 58), (25, 10, 59), (25, 8, 60), + (23, 12, 70), (27, 13, 72), (31, 14, 75), (30, 16, 85), + (29, 19, 95), (26, 20, 100), (23, 22, 105), (19, 24, 115), + (22, 23, 116), (30, 28, 100), (48, 34, 87), (66, 40, 74), + (71, 41, 73), (77, 43, 73), (74, 42, 76), (71, 42, 79), + (51, 24, 109), (36, 19, 119), (21, 15, 130), (21, 22, 127), + (21, 29, 124), (22, 36, 117), (23, 43, 110), (28, 72, 91), + (31, 86, 62), (49, 94, 32), (61, 92, 27), (73, 91, 22), + (85, 79, 40), (98, 67, 59), (103, 61, 64), (108, 55, 70), + (84, 28, 123), (72, 18, 126), (60, 9, 130), (55, 7, 129), + (51, 6, 129), (54, 12, 121), (58, 19, 114), (78, 37, 97), + (98, 44, 75), (121, 84, 48), (122, 89, 36), (124, 94, 24), + (117, 91, 29), (110, 88, 35), (88, 78, 37), (63, 60, 36), + (26, 47, 40), (27, 62, 31), (28, 77, 23), (43, 106, 17), + (59, 135, 11), (74, 143, 9), (90, 152, 8), (108, 160, 10), + (119, 166, 12), (128, 160, 16), (124, 150, 18), (120, 141, 21), + (117, 136, 21), (114, 132, 21), (104, 122, 11), (102, 118, 16), + (120, 126, 15), (128, 133, 17), (136, 141, 20), (141, 140, 21), + (146, 139, 23), (135, 129, 29), (116, 118, 52), (101, 95, 83), + (88, 75, 92), (81, 54, 114), (99, 52, 99), (117, 51, 84), + (124, 57, 73), (131, 63, 63), (141, 63, 42), (144, 58, 34), + (104, 65, 15), (89, 61, 19), (74, 57, 23), (65, 55, 19), + (57, 54, 16), (51, 40, 16), (46, 32, 18), (40, 26, 17), + (35, 19, 23), (19, 4, 51), (14, 5, 58), (10, 6, 65), + (10, 15, 75), (13, 24, 77), (7, 39, 75), (13, 60, 60), + (16, 72, 40), (25, 70, 44), (34, 68, 48), (37, 56, 54), + (41, 44, 60), (60, 33, 69), (89, 40, 65), (109, 53, 60), + (120, 70, 51), (131, 101, 17), (121, 102, 12), (111, 104, 8), + (90, 101, 15), (79, 87, 23), (66, 66, 26), (50, 50, 41), + (59, 25, 57), (58, 20, 67), (57, 15, 78), (57, 11, 81), + (58, 7, 84), (54, 13, 94), (54, 16, 105), (49, 19, 114), + (45, 18, 126), (59, 23, 146), (61, 22, 151), (63, 21, 156), + (66, 17, 175), (75, 15, 186), (74, 15, 193), (57, 14, 199), + (37, 7, 202), (30, 7, 196), (24, 8, 191), (17, 11, 178), + (13, 16, 166), (8, 19, 147), (13, 25, 133), (16, 27, 118), + (9, 24, 99), (12, 26, 80), (10, 22, 75), (9, 19, 71), + (11, 17, 76), (9, 15, 78), (10, 9, 74), (16, 9, 76), + (32, 11, 84), (42, 15, 87), (53, 19, 91), (70, 32, 100), + (73, 42, 117), (78, 42, 134), (85, 40, 139), (76, 47, 145), + (58, 42, 144), (49, 31, 131), (46, 29, 113), (41, 25, 93), + (39, 19, 79), (37, 14, 73), (32, 8, 70), (32, 5, 76), + (18, 3, 104), (15, 7, 107), (12, 11, 111), (18, 18, 103), + (20, 25, 90), (35, 47, 72), (54, 68, 47), (74, 88, 27), + (97, 114, 15), (105, 132, 6), (109, 133, 4), (113, 132, 4), + (95, 126, 5), (72, 107, 14), (68, 91, 28), (56, 86, 36), + (34, 81, 43), (33, 81, 51), (39, 95, 45), (41, 101, 36), + (53, 108, 36), (50, 129, 51), (56, 128, 80), (63, 118, 106), + (42, 114, 147), (31, 96, 186), (26, 79, 198), (18, 64, 198), + (9, 52, 186), (4, 53, 167), (12, 53, 145), (11, 53, 134), + (11, 57, 131), (17, 53, 126), (19, 44, 137), (34, 39, 160), + (46, 44, 174), (37, 58, 196), (48, 58, 210), (70, 73, 197), + (69, 105, 181), (80, 118, 147), (103, 129, 105), (120, 142, 76), + (126, 150, 44), (125, 157, 47), (121, 151, 78), (101, 142, 81), + (79, 147, 84), (63, 144, 88), (60, 131, 71), (60, 130, 50), + (61, 138, 26), (75, 142, 14), (67, 144, 33), (53, 144, 61), + (60, 122, 94), (38, 109, 126), (14, 101, 140), (20, 68, 159), + (20, 45, 160), (17, 41, 139), (27, 32, 116), (39, 27, 89), + (50, 44, 68), (65, 59, 49), (82, 73, 28), (98, 103, 14), + (117, 127, 11), (131, 141, 7), (105, 132, 49), (78, 122, 91) + ), + +// 524 Clouds +((135, 182, 203), (158, 189, 207), (169, 188, 207), (181, 188, 207), + (192, 188, 205), (203, 188, 204), (207, 187, 202), (211, 186, 200), + (205, 180, 193), (199, 176, 192), (193, 172, 191), (190, 171, 192), + (187, 170, 194), (186, 170, 194), (185, 170, 195), (183, 170, 196), + (181, 170, 198), (172, 172, 207), (172, 173, 209), (173, 174, 212), + (174, 175, 212), (175, 176, 213), (174, 175, 213), (174, 175, 214), + (162, 170, 211), (156, 162, 203), (151, 155, 196), (148, 144, 180), + (145, 133, 165), (142, 129, 161), (140, 126, 157), (140, 124, 153), + (143, 127, 153), (155, 135, 156), (160, 136, 154), (166, 137, 153), + (166, 142, 159), (167, 147, 166), (164, 151, 171), (162, 156, 177), + (149, 166, 189), (135, 161, 183), (122, 156, 178), (104, 147, 168), + (87, 138, 159), (78, 132, 153), (69, 127, 148), (55, 115, 136), + (43, 103, 126), (34, 89, 111), (34, 88, 110), (34, 87, 109), + (40, 92, 115), (46, 98, 121), (51, 101, 126), (56, 105, 132), + (77, 126, 157), (84, 135, 167), (91, 144, 177), (94, 149, 183), + (98, 155, 189), (100, 156, 191), (103, 157, 193), (107, 160, 197), + (108, 159, 197), (107, 162, 197), (107, 163, 196), (107, 164, 195), + (107, 164, 195), (107, 164, 195), (105, 163, 194), (104, 162, 193), + (95, 168, 192), (90, 167, 190), (86, 167, 188), (80, 161, 184), + (74, 156, 180), (70, 152, 176), (66, 148, 173), (59, 144, 167), + (52, 141, 161), (51, 136, 156), (55, 135, 157), (59, 135, 159), + (62, 136, 161), (66, 138, 164), (76, 144, 170), (84, 149, 176), + (104, 158, 187), (108, 156, 188), (112, 154, 190), (110, 151, 186), + (109, 148, 183), (102, 141, 176), (94, 131, 168), (88, 123, 158), + (85, 113, 144), (77, 87, 113), (64, 76, 100), (52, 65, 88), + (46, 62, 86), (40, 60, 84), (37, 60, 82), (44, 63, 86), + (71, 77, 100), (77, 87, 113), (84, 98, 127), (86, 104, 133), + (88, 110, 140), (91, 121, 155), (97, 133, 166), (106, 143, 178), + (111, 152, 187), (115, 165, 199), (113, 166, 199), (112, 168, 199), + (105, 167, 196), (98, 168, 194), (88, 167, 189), (79, 163, 184), + (63, 153, 169), (59, 148, 163), (55, 144, 158), (55, 144, 157), + (56, 145, 157), (60, 147, 159), (66, 149, 163), (72, 151, 169), + (79, 152, 172), (96, 156, 182), (101, 159, 185), (106, 162, 189), + (118, 167, 196), (126, 172, 204), (130, 173, 209), (132, 169, 209), + (127, 162, 202), (123, 156, 196), (120, 151, 190), (119, 149, 188), + (119, 148, 186), (120, 142, 178), (131, 136, 165), (139, 128, 150), + (140, 116, 131), (125, 97, 108), (118, 95, 108), (111, 94, 109), + (106, 96, 109), (113, 103, 112), (117, 107, 113), (116, 111, 112), + (103, 116, 129), (98, 120, 135), (94, 124, 142), (97, 136, 155), + (107, 148, 169), (118, 159, 177), (130, 166, 181), (136, 168, 183), + (140, 162, 176), (141, 142, 144), (139, 136, 137), (137, 130, 130), + (132, 117, 117), (117, 111, 111), (102, 99, 103), (83, 84, 89), + (53, 59, 60), (50, 53, 54), (48, 47, 49), (41, 45, 48), + (38, 49, 56), (37, 57, 69), (39, 66, 81), (43, 75, 93), + (53, 83, 103), (63, 89, 109), (70, 94, 115), (73, 100, 121), + (75, 106, 128), (74, 111, 137), (76, 114, 146), (80, 116, 147), + (88, 105, 132), (88, 101, 126), (88, 98, 121), (85, 91, 113), + (84, 88, 111), (84, 90, 113), (89, 94, 117), (92, 98, 119), + (97, 103, 123), (99, 108, 126), (100, 115, 134), (96, 114, 135), + (94, 115, 141), (91, 116, 146), (87, 117, 149), (83, 115, 150), + (80, 122, 156), (72, 117, 148), (65, 109, 136), (57, 99, 126), + (47, 85, 112), (40, 69, 98), (36, 63, 92), (32, 57, 86), + (28, 52, 79), (23, 51, 74), (17, 50, 73), (14, 48, 71), + (11, 47, 69), (9, 42, 64), (10, 38, 60), (11, 35, 57), + (15, 35, 57), (19, 36, 55), (25, 38, 56), (33, 39, 56), + (39, 40, 53), (39, 38, 52), (39, 37, 55), (37, 37, 53), + (35, 38, 56), (36, 41, 61), (40, 47, 63), (39, 52, 69), + (36, 59, 78), (28, 66, 86), (19, 73, 93), (11, 79, 101), + (9, 86, 106), (10, 90, 111), (12, 91, 112), (14, 93, 113), + (17, 93, 113), (21, 93, 115), (24, 96, 116), (27, 98, 119), + (30, 99, 120), (33, 99, 123), (32, 100, 123), (34, 100, 124), + (38, 102, 126), (42, 105, 128), (45, 111, 133), (52, 118, 140), + (54, 125, 146), (55, 132, 152), (59, 138, 160), (65, 144, 166), + (72, 150, 174), (87, 159, 182), (104, 167, 190), (120, 176, 198) + ), + +// 525 Copper +((255, 217, 186), (255, 202, 167), (255, 188, 153), (255, 175, 140), + (243, 161, 124), (232, 147, 108), (225, 140, 99), (218, 134, 91), + (191, 106, 65), (181, 97, 58), (171, 88, 51), (163, 82, 47), + (155, 77, 44), (151, 78, 44), (148, 79, 44), (149, 79, 44), + (151, 80, 45), (165, 89, 56), (172, 97, 61), (179, 106, 67), + (186, 110, 69), (194, 114, 71), (194, 114, 70), (195, 114, 69), + (179, 102, 63), (164, 92, 55), (150, 83, 48), (131, 71, 39), + (112, 59, 31), (101, 53, 26), (91, 47, 22), (75, 39, 16), + (61, 29, 12), (59, 24, 9), (70, 32, 14), (81, 41, 20), + (101, 54, 30), (122, 67, 41), (133, 74, 48), (144, 81, 55), + (190, 111, 80), (207, 125, 91), (225, 139, 102), (233, 147, 108), + (241, 155, 115), (242, 154, 115), (244, 154, 115), (244, 152, 114), + (240, 147, 111), (228, 140, 98), (220, 131, 89), (213, 122, 80), + (203, 116, 73), (194, 110, 67), (188, 106, 64), (182, 103, 61), + (159, 83, 48), (147, 76, 42), (135, 69, 37), (121, 62, 31), + (108, 56, 25), (102, 52, 22), (96, 49, 20), (85, 41, 14), + (76, 35, 10), (55, 20, 2), (47, 14, 1), (40, 9, 0), + (39, 9, 0), (39, 9, 0), (36, 6, 0), (32, 2, 0), + (26, 1, 0), (25, 3, 0), (25, 5, 0), (24, 4, 0), + (24, 4, 0), (23, 3, 0), (22, 2, 0), (18, 0, 0), + (14, 0, 0), (6, 0, 0), (5, 0, 0), (4, 0, 0), + (4, 0, 0), (4, 0, 0), (2, 0, 0), (2, 0, 0), + (4, 0, 0), (8, 1, 0), (13, 2, 0), (16, 3, 0), + (20, 4, 0), (25, 6, 0), (31, 6, 0), (33, 10, 0), + (36, 13, 1), (43, 14, 1), (46, 14, 1), (49, 14, 1), + (51, 15, 1), (53, 16, 2), (59, 21, 6), (68, 28, 10), + (100, 48, 25), (119, 61, 35), (138, 75, 45), (148, 81, 50), + (158, 87, 56), (177, 104, 68), (197, 118, 79), (213, 130, 92), + (228, 144, 107), (248, 169, 132), (250, 173, 136), (253, 178, 140), + (255, 179, 146), (255, 182, 148), (255, 183, 150), (255, 185, 147), + (249, 174, 139), (240, 164, 129), (232, 155, 120), (225, 149, 113), + (218, 144, 107), (203, 135, 95), (190, 118, 84), (175, 111, 73), + (166, 99, 63), (148, 85, 55), (147, 85, 55), (147, 85, 56), + (144, 87, 56), (146, 84, 53), (148, 85, 55), (154, 85, 55), + (171, 94, 61), (175, 98, 61), (179, 103, 61), (180, 102, 58), + (181, 102, 56), (177, 98, 52), (174, 89, 51), (167, 87, 48), + (163, 85, 47), (155, 80, 40), (154, 79, 41), (154, 79, 43), + (154, 80, 47), (160, 88, 52), (170, 94, 59), (181, 104, 67), + (205, 126, 83), (209, 131, 87), (214, 136, 92), (222, 139, 98), + (223, 142, 98), (218, 136, 94), (209, 131, 89), (194, 123, 83), + (177, 110, 73), (136, 77, 48), (127, 70, 42), (118, 64, 37), + (102, 51, 28), (87, 45, 25), (77, 40, 20), (73, 37, 18), + (75, 32, 10), (73, 34, 11), (72, 36, 13), (71, 36, 17), + (72, 36, 18), (73, 37, 20), (77, 36, 14), (76, 33, 12), + (76, 33, 10), (77, 31, 12), (77, 37, 17), (84, 39, 18), + (91, 40, 17), (96, 40, 17), (100, 44, 16), (100, 43, 17), + (95, 43, 17), (93, 42, 16), (91, 41, 16), (91, 43, 14), + (91, 40, 13), (91, 40, 17), (94, 45, 18), (98, 48, 22), + (106, 52, 25), (115, 56, 26), (122, 61, 32), (128, 65, 35), + (132, 71, 37), (135, 68, 36), (131, 65, 33), (122, 61, 33), + (112, 57, 31), (106, 53, 29), (103, 48, 26), (102, 48, 25), + (104, 47, 25), (108, 53, 26), (116, 60, 32), (130, 65, 36), + (142, 73, 41), (156, 79, 44), (167, 87, 48), (173, 92, 49), + (174, 91, 49), (169, 88, 49), (163, 87, 45), (155, 79, 41), + (146, 73, 37), (140, 71, 33), (135, 67, 33), (139, 72, 39), + (144, 80, 43), (155, 89, 52), (171, 104, 65), (187, 122, 81), + (209, 138, 99), (230, 154, 114), (248, 173, 132), (255, 186, 150), + (255, 206, 170), (255, 217, 185), (255, 226, 191), (255, 222, 195), + (255, 228, 197), (255, 223, 199), (255, 222, 199), (255, 223, 193), + (255, 219, 182), (255, 207, 174), (255, 199, 165), (255, 197, 159), + (255, 189, 151), (255, 189, 148), (255, 186, 147), (255, 187, 148), + (255, 190, 152), (255, 193, 156), (255, 198, 163), (255, 202, 169), + (255, 206, 174), (255, 207, 179), (255, 214, 182), (255, 215, 189), + (255, 217, 193), (255, 218, 197), (255, 225, 195), (255, 217, 193) + ), + +// 526 Coral +((155, 66, 54), (138, 51, 35), (140, 52, 36), (143, 54, 37), + (141, 52, 35), (139, 51, 34), (137, 50, 32), (136, 50, 30), + (127, 41, 24), (123, 38, 20), (119, 36, 16), (109, 31, 12), + (99, 26, 8), (89, 20, 6), (80, 15, 4), (75, 13, 2), + (71, 11, 1), (76, 5, 0), (86, 11, 4), (97, 18, 8), + (114, 24, 10), (131, 30, 13), (135, 33, 16), (140, 37, 20), + (154, 39, 20), (153, 36, 17), (153, 34, 15), (147, 35, 14), + (142, 37, 13), (140, 35, 12), (139, 33, 11), (133, 35, 12), + (129, 38, 13), (125, 38, 16), (125, 39, 17), (126, 41, 18), + (126, 45, 21), (127, 49, 24), (130, 49, 26), (133, 50, 29), + (142, 60, 37), (152, 65, 43), (162, 70, 50), (177, 78, 58), + (193, 86, 66), (200, 87, 69), (207, 89, 73), (222, 94, 79), + (229, 95, 79), (226, 93, 76), (215, 85, 69), (204, 78, 63), + (188, 70, 54), (172, 63, 46), (168, 59, 42), (165, 55, 39), + (147, 46, 29), (141, 44, 26), (135, 43, 24), (127, 40, 18), + (120, 37, 13), (119, 34, 11), (118, 31, 10), (118, 28, 6), + (114, 27, 3), (121, 24, 3), (125, 28, 7), (130, 33, 12), + (131, 34, 14), (133, 36, 16), (138, 40, 23), (142, 45, 28), + (143, 50, 32), (143, 51, 33), (143, 53, 34), (142, 52, 33), + (142, 51, 33), (140, 50, 32), (139, 50, 32), (134, 47, 31), + (131, 45, 30), (119, 44, 28), (120, 46, 29), (121, 49, 31), + (123, 50, 35), (125, 52, 40), (136, 58, 49), (145, 69, 57), + (165, 80, 74), (168, 84, 75), (172, 88, 77), (172, 88, 77), + (173, 88, 77), (171, 81, 75), (168, 75, 70), (162, 72, 65), + (155, 67, 59), (146, 54, 41), (140, 52, 37), (134, 50, 34), + (133, 49, 32), (133, 49, 31), (134, 50, 28), (138, 52, 26), + (149, 48, 26), (153, 48, 23), (158, 48, 21), (159, 47, 22), + (160, 47, 24), (163, 49, 27), (164, 51, 32), (164, 56, 38), + (167, 61, 43), (171, 67, 51), (170, 67, 52), (170, 67, 53), + (167, 67, 49), (163, 65, 45), (159, 62, 44), (155, 60, 42), + (154, 63, 45), (161, 69, 50), (169, 75, 56), (174, 79, 58), + (179, 84, 60), (190, 90, 66), (196, 96, 76), (206, 109, 93), + (220, 114, 97), (225, 110, 102), (225, 108, 101), (226, 107, 101), + (223, 94, 76), (211, 81, 64), (205, 72, 59), (197, 63, 48), + (188, 62, 47), (187, 67, 52), (187, 72, 58), (184, 74, 60), + (182, 77, 63), (176, 80, 62), (169, 77, 60), (160, 71, 54), + (148, 64, 46), (134, 51, 31), (133, 48, 28), (132, 46, 25), + (131, 44, 24), (131, 45, 24), (136, 45, 25), (143, 47, 28), + (152, 51, 33), (156, 53, 35), (160, 55, 37), (167, 60, 42), + (175, 65, 45), (184, 72, 50), (191, 78, 57), (195, 84, 66), + (195, 89, 70), (185, 86, 73), (179, 84, 73), (173, 83, 73), + (161, 76, 65), (153, 68, 55), (142, 60, 46), (131, 52, 36), + (112, 38, 19), (106, 33, 14), (101, 29, 10), (97, 25, 6), + (96, 30, 9), (100, 34, 16), (113, 42, 26), (131, 61, 42), + (155, 78, 59), (174, 84, 68), (182, 88, 75), (190, 91, 77), + (196, 85, 70), (187, 76, 60), (178, 68, 49), (176, 60, 41), + (171, 56, 35), (170, 54, 33), (169, 53, 31), (168, 52, 32), + (168, 54, 34), (166, 55, 33), (165, 55, 32), (164, 59, 35), + (161, 63, 38), (160, 64, 41), (158, 68, 46), (154, 72, 49), + (153, 71, 50), (151, 67, 50), (151, 65, 48), (155, 65, 44), + (158, 62, 41), (163, 59, 39), (168, 62, 39), (171, 62, 43), + (170, 61, 46), (169, 64, 48), (171, 65, 52), (168, 65, 52), + (168, 66, 50), (170, 68, 50), (170, 67, 47), (172, 66, 46), + (171, 65, 46), (166, 64, 45), (161, 62, 44), (157, 62, 45), + (152, 63, 46), (148, 63, 46), (141, 60, 43), (132, 58, 40), + (124, 55, 37), (119, 52, 34), (111, 46, 27), (103, 38, 19), + (100, 35, 14), (102, 29, 10), (105, 25, 5), (101, 23, 2), + (99, 20, 1), (103, 22, 2), (103, 25, 3), (98, 26, 5), + (98, 28, 9), (100, 31, 11), (104, 33, 14), (106, 33, 16), + (108, 35, 19), (115, 37, 22), (121, 38, 22), (126, 42, 24), + (129, 46, 26), (132, 48, 26), (137, 50, 28), (138, 52, 28), + (138, 52, 26), (139, 50, 28), (141, 50, 28), (143, 48, 27), + (143, 48, 29), (146, 49, 32), (152, 50, 34), (157, 56, 42), + (161, 63, 51), (166, 68, 55), (158, 64, 50), (152, 61, 49) + ), + +// 527 Cotton_Flower +((100, 160, 186), (126, 177, 195), (134, 183, 199), (143, 189, 203), + (148, 189, 198), (153, 190, 194), (155, 191, 192), (158, 193, 191), + (174, 202, 200), (174, 203, 201), (174, 204, 202), (164, 193, 187), + (154, 183, 172), (149, 171, 157), (144, 160, 142), (142, 156, 139), + (141, 153, 137), (125, 142, 136), (110, 135, 132), (96, 129, 129), + (85, 119, 124), (75, 109, 119), (74, 106, 112), (74, 103, 106), + (74, 95, 104), (81, 94, 101), (88, 94, 99), (95, 88, 91), + (102, 82, 83), (101, 78, 75), (101, 74, 67), (101, 63, 53), + (98, 58, 41), (98, 49, 23), (95, 48, 21), (92, 47, 19), + (84, 50, 24), (77, 53, 29), (70, 55, 35), (63, 57, 41), + (51, 71, 75), (48, 76, 88), (46, 82, 101), (46, 82, 101), + (46, 83, 102), (46, 83, 101), (47, 83, 100), (46, 79, 98), + (43, 76, 95), (36, 66, 88), (37, 64, 74), (38, 62, 61), + (44, 59, 48), (51, 57, 36), (54, 57, 32), (58, 57, 29), + (64, 58, 27), (65, 61, 29), (66, 64, 32), (69, 67, 37), + (73, 70, 42), (74, 69, 44), (76, 69, 47), (76, 68, 51), + (72, 67, 55), (57, 58, 53), (50, 55, 55), (44, 52, 57), + (43, 51, 57), (43, 50, 57), (42, 51, 57), (42, 51, 57), + (43, 50, 51), (42, 48, 50), (42, 47, 49), (40, 47, 48), + (39, 47, 48), (39, 47, 46), (40, 47, 44), (45, 48, 39), + (48, 51, 39), (53, 53, 35), (51, 53, 32), (50, 53, 30), + (49, 52, 27), (48, 51, 25), (46, 50, 23), (44, 48, 18), + (44, 47, 13), (44, 48, 14), (44, 50, 15), (44, 51, 16), + (44, 52, 18), (44, 52, 20), (43, 52, 20), (44, 50, 20), + (48, 48, 21), (64, 51, 24), (77, 53, 25), (90, 56, 26), + (95, 56, 25), (101, 57, 24), (110, 57, 22), (117, 59, 21), + (121, 64, 18), (123, 67, 17), (126, 70, 16), (125, 69, 15), + (125, 69, 15), (123, 68, 15), (118, 68, 14), (112, 70, 16), + (113, 72, 18), (121, 68, 15), (121, 64, 15), (122, 61, 15), + (122, 52, 11), (117, 44, 12), (112, 40, 12), (114, 39, 10), + (113, 39, 7), (105, 34, 4), (97, 29, 2), (88, 27, 3), + (80, 26, 4), (68, 27, 9), (60, 32, 13), (55, 37, 16), + (51, 41, 17), (42, 43, 17), (40, 43, 18), (38, 43, 19), + (34, 43, 22), (34, 42, 23), (34, 39, 24), (33, 38, 21), + (26, 33, 12), (22, 32, 11), (18, 31, 10), (17, 29, 9), + (17, 27, 9), (19, 29, 8), (22, 32, 7), (28, 36, 6), + (31, 41, 7), (35, 45, 8), (35, 45, 7), (36, 46, 7), + (42, 49, 9), (50, 53, 9), (59, 57, 10), (67, 58, 11), + (70, 54, 14), (69, 53, 14), (68, 53, 15), (66, 54, 18), + (65, 55, 19), (65, 58, 22), (67, 60, 25), (67, 63, 29), + (68, 65, 30), (62, 67, 32), (59, 67, 32), (57, 67, 33), + (53, 66, 35), (50, 65, 39), (50, 64, 38), (50, 64, 37), + (49, 61, 34), (48, 59, 33), (47, 58, 33), (43, 57, 34), + (40, 55, 34), (37, 52, 31), (36, 50, 26), (33, 47, 22), + (31, 45, 20), (30, 44, 19), (28, 46, 20), (27, 47, 19), + (28, 48, 18), (29, 46, 16), (29, 46, 15), (29, 44, 16), + (29, 45, 20), (30, 46, 20), (31, 47, 21), (35, 47, 20), + (39, 47, 19), (44, 47, 17), (47, 46, 17), (51, 46, 18), + (53, 48, 22), (55, 53, 29), (53, 58, 42), (52, 61, 54), + (52, 68, 69), (55, 76, 82), (59, 83, 95), (65, 95, 105), + (70, 106, 119), (72, 114, 130), (74, 121, 143), (77, 129, 152), + (82, 135, 160), (89, 141, 161), (103, 145, 159), (115, 147, 153), + (121, 143, 147), (126, 138, 136), (130, 132, 125), (126, 127, 119), + (126, 123, 115), (129, 123, 114), (121, 122, 119), (113, 118, 122), + (104, 113, 120), (97, 109, 115), (89, 102, 107), (91, 102, 95), + (90, 103, 93), (88, 105, 91), (81, 104, 90), (81, 103, 87), + (81, 97, 80), (88, 92, 64), (95, 88, 50), (104, 84, 36), + (109, 79, 25), (114, 76, 19), (117, 70, 15), (120, 66, 12), + (121, 62, 12), (118, 58, 9), (116, 57, 10), (112, 56, 10), + (109, 56, 10), (106, 57, 9), (104, 57, 11), (102, 56, 8), + (101, 56, 9), (96, 56, 12), (91, 60, 14), (86, 64, 19), + (82, 68, 26), (77, 71, 35), (75, 78, 50), (75, 82, 65), + (77, 90, 79), (76, 99, 95), (79, 108, 110), (76, 115, 123), + (74, 124, 139), (76, 132, 156), (81, 139, 168), (89, 149, 177) + ), + +// 528 Country_Garden +((64, 127, 54), (64, 145, 64), (54, 140, 73), (44, 136, 82), + (44, 115, 95), (44, 94, 108), (45, 89, 112), (46, 85, 116), + (44, 63, 112), (46, 44, 111), (49, 26, 111), (60, 19, 111), + (72, 12, 111), (86, 12, 103), (100, 13, 96), (104, 15, 92), + (109, 18, 89), (118, 46, 68), (131, 63, 65), (145, 80, 62), + (156, 90, 68), (168, 101, 74), (167, 110, 75), (167, 119, 77), + (179, 139, 68), (179, 135, 69), (179, 132, 70), (172, 122, 68), + (165, 113, 66), (163, 105, 63), (161, 97, 61), (147, 88, 59), + (130, 77, 57), (104, 61, 46), (102, 49, 43), (101, 38, 41), + (96, 34, 43), (92, 31, 45), (87, 31, 43), (83, 31, 42), + (63, 26, 31), (55, 34, 28), (48, 42, 25), (44, 51, 22), + (40, 60, 19), (42, 59, 17), (45, 59, 15), (52, 59, 11), + (61, 57, 13), (85, 52, 14), (104, 49, 11), (123, 47, 9), + (137, 45, 10), (152, 44, 11), (152, 46, 12), (153, 48, 14), + (137, 50, 11), (125, 53, 20), (114, 57, 29), (102, 55, 41), + (90, 54, 54), (83, 52, 57), (76, 50, 60), (61, 52, 70), + (54, 53, 80), (46, 50, 99), (52, 56, 100), (59, 63, 102), + (66, 68, 102), (73, 73, 102), (88, 87, 98), (104, 89, 91), + (137, 90, 65), (152, 82, 56), (168, 75, 48), (173, 65, 41), + (179, 56, 35), (179, 53, 33), (180, 50, 32), (171, 44, 32), + (163, 36, 29), (130, 31, 22), (107, 40, 24), (84, 50, 26), + (75, 54, 27), (67, 58, 28), (61, 70, 25), (57, 80, 20), + (47, 93, 16), (48, 89, 24), (49, 86, 33), (57, 83, 39), + (66, 80, 45), (86, 76, 56), (109, 74, 71), (124, 72, 89), + (133, 71, 101), (152, 60, 110), (148, 54, 115), (145, 49, 121), + (136, 50, 123), (127, 51, 126), (114, 52, 120), (101, 46, 111), + (77, 27, 94), (60, 19, 85), (44, 12, 76), (40, 10, 70), + (36, 9, 64), (41, 13, 54), (51, 14, 47), (62, 23, 38), + (69, 31, 31), (72, 57, 20), (72, 64, 22), (72, 71, 24), + (80, 83, 34), (92, 89, 45), (108, 83, 47), (124, 80, 48), + (150, 95, 38), (163, 102, 40), (177, 109, 42), (182, 107, 40), + (188, 105, 39), (202, 108, 32), (207, 111, 18), (202, 124, 19), + (187, 129, 17), (141, 124, 27), (130, 119, 27), (120, 114, 28), + (104, 105, 46), (92, 90, 55), (87, 74, 62), (91, 71, 70), + (102, 78, 87), (111, 77, 106), (120, 77, 126), (127, 74, 133), + (135, 72, 140), (141, 82, 138), (135, 99, 126), (126, 114, 113), + (105, 127, 105), (77, 119, 103), (71, 121, 92), (65, 123, 82), + (60, 127, 60), (52, 136, 39), (53, 139, 27), (58, 130, 28), + (88, 102, 22), (94, 95, 23), (101, 88, 25), (112, 73, 22), + (121, 61, 23), (126, 50, 22), (130, 37, 17), (131, 30, 18), + (129, 24, 17), (118, 26, 18), (113, 26, 18), (109, 26, 19), + (94, 28, 21), (78, 29, 23), (64, 34, 23), (56, 40, 27), + (49, 38, 39), (47, 38, 41), (45, 39, 43), (42, 46, 43), + (40, 60, 48), (47, 71, 46), (65, 72, 47), (88, 75, 43), + (116, 79, 38), (135, 92, 40), (150, 113, 42), (157, 119, 44), + (161, 119, 42), (163, 107, 38), (157, 93, 31), (147, 87, 30), + (111, 77, 29), (104, 74, 30), (97, 71, 31), (78, 63, 25), + (65, 55, 22), (56, 53, 20), (49, 52, 16), (52, 57, 18), + (51, 66, 18), (53, 71, 21), (52, 81, 24), (51, 88, 23), + (53, 92, 24), (52, 99, 27), (49, 96, 32), (44, 90, 42), + (39, 86, 44), (39, 82, 44), (42, 86, 44), (49, 92, 43), + (56, 94, 48), (68, 97, 47), (82, 99, 45), (95, 103, 38), + (110, 113, 30), (118, 123, 26), (126, 132, 19), (130, 138, 16), + (127, 141, 12), (119, 142, 8), (105, 146, 10), (91, 148, 17), + (73, 143, 26), (55, 143, 34), (37, 135, 40), (21, 131, 42), + (14, 123, 46), (11, 107, 51), (12, 92, 55), (16, 75, 61), + (21, 62, 62), (30, 48, 56), (40, 37, 53), (48, 27, 49), + (56, 18, 52), (64, 16, 64), (72, 18, 83), (74, 30, 103), + (76, 41, 119), (83, 45, 122), (85, 43, 120), (91, 37, 125), + (85, 40, 125), (75, 48, 135), (71, 50, 133), (68, 49, 120), + (73, 38, 108), (72, 32, 90), (63, 33, 85), (52, 38, 80), + (41, 45, 72), (33, 50, 69), (28, 50, 62), (23, 51, 54), + (19, 57, 48), (21, 66, 36), (28, 79, 28), (38, 83, 24), + (36, 94, 21), (31, 106, 27), (37, 116, 34), (44, 128, 43) + ), + +// 529 Creamsicle +((255, 175, 47), (255, 163, 47), (255, 154, 46), (255, 145, 45), + (255, 131, 45), (255, 118, 45), (255, 113, 45), (255, 108, 45), + (255, 92, 45), (255, 87, 45), (255, 83, 45), (255, 83, 45), + (255, 83, 45), (255, 88, 45), (255, 94, 45), (255, 96, 45), + (255, 98, 45), (255, 108, 45), (255, 116, 45), (255, 124, 45), + (255, 131, 45), (255, 139, 45), (255, 142, 45), (255, 146, 45), + (247, 162, 43), (231, 166, 41), (215, 171, 39), (200, 172, 37), + (186, 174, 36), (180, 171, 34), (174, 168, 33), (163, 158, 31), + (150, 146, 29), (147, 124, 47), (165, 109, 68), (183, 95, 89), + (194, 82, 117), (206, 69, 146), (211, 65, 161), (216, 62, 177), + (247, 50, 223), (251, 47, 237), (255, 45, 251), (255, 45, 253), + (255, 46, 255), (255, 48, 255), (255, 51, 255), (255, 61, 255), + (255, 74, 253), (255, 101, 239), (255, 118, 229), (255, 135, 220), + (255, 146, 191), (255, 157, 162), (255, 158, 148), (255, 159, 135), + (255, 155, 98), (255, 144, 80), (255, 134, 62), (255, 124, 67), + (255, 115, 72), (255, 109, 76), (255, 104, 80), (255, 91, 89), + (255, 79, 99), (255, 65, 114), (255, 58, 120), (255, 52, 126), + (255, 49, 129), (255, 47, 133), (255, 45, 139), (249, 44, 146), + (239, 42, 165), (236, 42, 167), (233, 42, 170), (205, 43, 160), + (177, 44, 151), (171, 46, 145), (166, 49, 140), (168, 55, 126), + (162, 60, 103), (129, 69, 63), (144, 80, 54), (159, 91, 45), + (172, 96, 41), (185, 102, 38), (200, 109, 35), (204, 113, 40), + (233, 129, 71), (244, 132, 90), (255, 135, 109), (255, 130, 118), + (255, 126, 128), (255, 116, 154), (255, 104, 177), (255, 93, 197), + (255, 82, 211), (255, 59, 223), (255, 52, 222), (255, 45, 222), + (255, 45, 219), (255, 45, 217), (255, 45, 208), (255, 45, 194), + (255, 45, 161), (255, 49, 150), (255, 53, 139), (255, 57, 133), + (255, 62, 127), (255, 70, 109), (255, 78, 93), (255, 89, 81), + (255, 101, 76), (255, 118, 70), (255, 121, 72), (255, 124, 75), + (255, 127, 88), (255, 128, 106), (252, 124, 126), (244, 118, 153), + (229, 101, 205), (217, 94, 219), (206, 88, 233), (199, 85, 238), + (192, 83, 244), (185, 73, 252), (186, 66, 255), (191, 61, 255), + (198, 62, 250), (216, 54, 219), (222, 51, 208), (229, 48, 198), + (242, 49, 176), (251, 54, 150), (255, 59, 121), (255, 63, 95), + (255, 75, 62), (255, 81, 57), (255, 87, 52), (255, 90, 55), + (255, 93, 58), (255, 97, 66), (255, 99, 72), (255, 101, 79), + (255, 102, 89), (255, 109, 103), (255, 110, 102), (255, 112, 102), + (255, 112, 97), (255, 113, 90), (255, 117, 82), (255, 122, 75), + (255, 126, 57), (255, 125, 53), (255, 124, 50), (255, 123, 46), + (255, 123, 45), (255, 124, 45), (255, 123, 45), (255, 121, 45), + (255, 120, 45), (255, 124, 49), (255, 125, 50), (255, 126, 51), + (255, 128, 52), (255, 128, 52), (255, 128, 52), (255, 128, 52), + (255, 126, 50), (255, 124, 48), (255, 123, 47), (255, 121, 45), + (255, 119, 45), (255, 121, 45), (255, 124, 45), (255, 129, 45), + (255, 135, 45), (248, 145, 43), (236, 157, 42), (220, 166, 46), + (209, 168, 60), (194, 162, 75), (175, 159, 82), (155, 156, 85), + (133, 131, 110), (133, 121, 113), (133, 111, 117), (141, 91, 115), + (156, 81, 112), (173, 73, 111), (183, 63, 109), (185, 48, 108), + (180, 43, 106), (174, 48, 102), (163, 58, 98), (150, 63, 99), + (132, 69, 101), (114, 84, 102), (103, 104, 100), (105, 123, 93), + (116, 138, 83), (133, 151, 77), (151, 165, 75), (170, 178, 69), + (188, 187, 56), (205, 186, 44), (221, 181, 40), (236, 175, 42), + (245, 169, 43), (247, 160, 43), (245, 146, 43), (245, 132, 43), + (244, 119, 43), (244, 110, 43), (243, 101, 43), (245, 93, 43), + (247, 86, 43), (250, 82, 44), (253, 80, 44), (254, 80, 45), + (255, 82, 45), (255, 86, 45), (255, 90, 45), (255, 92, 45), + (255, 90, 45), (255, 87, 45), (255, 87, 45), (255, 87, 45), + (255, 86, 45), (255, 81, 45), (255, 74, 45), (255, 67, 45), + (255, 65, 45), (255, 63, 45), (255, 60, 47), (255, 55, 51), + (255, 49, 57), (255, 47, 60), (255, 48, 64), (255, 48, 69), + (255, 47, 76), (255, 46, 81), (255, 49, 84), (255, 56, 84), + (255, 65, 80), (255, 71, 76), (255, 80, 73), (255, 92, 71), + (255, 107, 64), (255, 122, 57), (255, 134, 51), (255, 144, 50), + (255, 154, 50), (255, 164, 48), (255, 173, 46), (255, 176, 46) + ), + +// 530 Cricket_Music +((112, 38, 168), (104, 37, 182), (102, 36, 188), (100, 36, 194), + (94, 31, 177), (88, 26, 160), (82, 23, 153), (77, 20, 146), + (57, 28, 102), (57, 35, 81), (57, 43, 61), (44, 54, 42), + (32, 65, 24), (32, 71, 24), (32, 78, 24), (37, 77, 35), + (43, 76, 46), (54, 57, 84), (70, 47, 105), (86, 38, 126), + (96, 26, 145), (106, 14, 165), (108, 11, 173), (110, 8, 182), + (86, 0, 198), (71, 3, 211), (56, 6, 224), (42, 4, 227), + (28, 2, 230), (24, 1, 224), (21, 0, 218), (4, 0, 215), + (0, 4, 211), (0, 12, 179), (0, 17, 158), (0, 23, 137), + (0, 31, 117), (0, 39, 98), (0, 38, 85), (0, 38, 73), + (0, 52, 44), (0, 44, 42), (0, 36, 40), (0, 24, 50), + (0, 12, 61), (1, 11, 65), (3, 10, 70), (15, 7, 76), + (26, 5, 80), (29, 0, 77), (28, 1, 61), (27, 3, 45), + (21, 9, 37), (16, 16, 30), (15, 16, 31), (14, 16, 32), + (15, 10, 45), (21, 16, 55), (28, 22, 65), (36, 24, 77), + (45, 27, 89), (45, 28, 91), (46, 30, 94), (38, 36, 93), + (31, 49, 89), (23, 64, 84), (14, 55, 85), (6, 47, 86), + (5, 41, 90), (4, 35, 94), (2, 23, 102), (6, 12, 106), + (30, 0, 124), (30, 2, 122), (31, 5, 120), (33, 2, 118), + (35, 0, 117), (32, 0, 110), (29, 0, 104), (19, 8, 91), + (3, 6, 80), (0, 0, 55), (0, 5, 42), (0, 10, 30), + (0, 16, 26), (0, 22, 23), (0, 28, 8), (0, 27, 0), + (0, 44, 0), (0, 57, 7), (0, 71, 15), (3, 75, 19), + (6, 80, 24), (11, 89, 40), (14, 93, 59), (6, 93, 72), + (3, 89, 89), (6, 71, 102), (5, 61, 102), (4, 52, 103), + (7, 45, 110), (10, 39, 117), (29, 39, 135), (47, 44, 142), + (87, 35, 171), (106, 27, 185), (125, 20, 199), (129, 19, 199), + (134, 19, 200), (127, 14, 184), (112, 8, 160), (92, 11, 132), + (75, 27, 101), (39, 44, 54), (33, 44, 50), (27, 45, 46), + (22, 47, 46), (28, 42, 47), (32, 36, 64), (47, 31, 86), + (62, 4, 111), (59, 8, 114), (57, 13, 117), (52, 20, 110), + (48, 27, 104), (26, 27, 86), (14, 42, 61), (5, 62, 51), + (4, 65, 36), (7, 48, 0), (13, 45, 0), (19, 43, 0), + (40, 37, 14), (48, 13, 32), (65, 0, 63), (78, 0, 81), + (86, 0, 114), (85, 0, 121), (84, 0, 129), (80, 0, 121), + (76, 0, 114), (76, 0, 102), (89, 0, 98), (106, 0, 106), + (106, 0, 103), (112, 7, 128), (120, 7, 138), (128, 8, 149), + (140, 12, 162), (141, 15, 169), (144, 12, 174), (154, 8, 179), + (163, 13, 181), (169, 11, 179), (175, 10, 177), (183, 6, 181), + (194, 4, 194), (192, 20, 207), (184, 24, 199), (183, 37, 178), + (165, 44, 146), (141, 53, 154), (137, 51, 149), (133, 49, 144), + (122, 45, 117), (109, 53, 121), (91, 47, 130), (80, 42, 152), + (87, 45, 170), (90, 47, 171), (94, 49, 173), (100, 54, 185), + (106, 51, 190), (117, 49, 193), (122, 42, 185), (138, 32, 184), + (137, 23, 178), (133, 15, 176), (124, 8, 173), (121, 0, 177), + (111, 0, 178), (95, 0, 178), (80, 2, 183), (83, 4, 192), + (98, 2, 218), (97, 2, 224), (96, 2, 230), (93, 2, 231), + (88, 4, 233), (91, 0, 228), (84, 0, 224), (73, 0, 209), + (65, 0, 199), (59, 0, 183), (51, 0, 170), (49, 2, 153), + (49, 7, 149), (52, 11, 143), (51, 18, 141), (46, 28, 137), + (31, 28, 134), (29, 34, 129), (38, 44, 134), (38, 46, 144), + (38, 55, 156), (29, 54, 157), (42, 60, 167), (59, 54, 183), + (93, 63, 200), (97, 44, 199), (109, 32, 195), (127, 20, 198), + (144, 11, 206), (157, 5, 207), (163, 4, 195), (160, 8, 181), + (142, 15, 167), (117, 35, 156), (95, 53, 134), (77, 69, 110), + (54, 75, 80), (36, 93, 64), (20, 96, 44), (10, 97, 42), + (6, 89, 45), (3, 80, 53), (0, 63, 60), (0, 42, 69), + (0, 31, 91), (0, 26, 109), (0, 16, 122), (0, 8, 133), + (0, 0, 142), (12, 7, 152), (40, 19, 162), (59, 20, 174), + (77, 5, 184), (92, 0, 199), (101, 0, 208), (104, 7, 215), + (98, 15, 215), (92, 23, 210), (70, 37, 191), (31, 34, 171), + (18, 49, 148), (7, 59, 122), (0, 71, 92), (0, 93, 87), + (0, 88, 77), (0, 79, 69), (7, 71, 69), (28, 69, 65), + (38, 51, 72), (53, 49, 92), (67, 44, 130), (96, 48, 156) + ), + +// 531 Dark_Rainbow +((90, 148, 72), (141, 187, 70), (162, 176, 67), (183, 165, 65), + (202, 148, 55), (221, 132, 45), (222, 124, 41), (224, 117, 38), + (188, 66, 18), (169, 48, 14), (151, 30, 11), (127, 24, 11), + (103, 19, 12), (80, 29, 13), (58, 39, 15), (49, 42, 18), + (41, 45, 22), (20, 40, 46), (14, 40, 51), (9, 40, 56), + (8, 38, 59), (8, 37, 62), (6, 32, 63), (5, 28, 64), + (10, 11, 61), (18, 8, 53), (27, 5, 45), (39, 5, 35), + (52, 5, 26), (58, 5, 23), (64, 5, 21), (77, 4, 19), + (92, 6, 21), (116, 7, 30), (112, 5, 32), (108, 3, 34), + (95, 3, 36), (83, 4, 38), (78, 4, 40), (73, 5, 42), + (52, 22, 48), (44, 34, 60), (36, 47, 72), (37, 55, 71), + (39, 64, 70), (43, 70, 64), (48, 77, 58), (61, 92, 56), + (72, 101, 58), (73, 108, 52), (67, 111, 37), (62, 115, 23), + (65, 108, 25), (69, 101, 28), (67, 93, 33), (65, 85, 38), + (46, 68, 56), (37, 64, 80), (29, 61, 105), (33, 42, 129), + (37, 24, 154), (34, 18, 153), (32, 13, 153), (20, 13, 149), + (12, 13, 146), (7, 6, 142), (18, 3, 121), (30, 0, 101), + (39, 0, 87), (49, 1, 74), (68, 2, 49), (83, 2, 34), + (114, 4, 14), (121, 9, 15), (128, 15, 17), (119, 27, 24), + (111, 40, 32), (104, 45, 33), (97, 51, 34), (80, 57, 35), + (67, 58, 41), (55, 56, 62), (55, 55, 68), (56, 54, 74), + (58, 53, 72), (61, 53, 70), (71, 43, 64), (76, 33, 60), + (79, 17, 61), (75, 16, 58), (71, 16, 55), (65, 16, 53), + (60, 17, 52), (49, 19, 53), (33, 12, 61), (22, 13, 78), + (18, 14, 96), (28, 16, 141), (34, 15, 152), (41, 14, 163), + (47, 16, 163), (53, 19, 163), (65, 24, 163), (85, 29, 157), + (110, 27, 131), (115, 27, 110), (121, 28, 90), (121, 29, 79), + (122, 31, 69), (121, 42, 53), (111, 59, 46), (100, 82, 45), + (102, 104, 44), (123, 137, 35), (125, 140, 32), (128, 143, 30), + (121, 152, 33), (115, 160, 35), (117, 166, 41), (126, 168, 44), + (143, 135, 43), (144, 115, 40), (146, 95, 38), (149, 87, 39), + (153, 80, 41), (158, 66, 37), (166, 54, 36), (176, 43, 29), + (186, 39, 18), (207, 26, 8), (208, 24, 8), (209, 22, 9), + (205, 17, 15), (197, 21, 17), (193, 28, 19), (189, 32, 18), + (186, 49, 18), (191, 67, 23), (197, 86, 28), (202, 95, 31), + (207, 104, 35), (192, 115, 45), (167, 122, 66), (149, 115, 89), + (127, 112, 114), (117, 99, 142), (101, 94, 143), (86, 90, 145), + (67, 70, 150), (39, 45, 148), (27, 29, 152), (26, 15, 138), + (18, 9, 92), (18, 6, 80), (18, 3, 69), (18, 6, 62), + (17, 10, 58), (14, 15, 58), (12, 23, 62), (15, 27, 63), + (23, 28, 60), (25, 30, 54), (25, 30, 54), (26, 31, 54), + (26, 33, 57), (39, 31, 58), (43, 27, 57), (50, 24, 64), + (37, 17, 88), (40, 16, 93), (44, 16, 99), (51, 13, 112), + (72, 19, 123), (89, 34, 129), (98, 44, 132), (107, 55, 126), + (106, 57, 121), (114, 52, 115), (119, 55, 105), (126, 57, 97), + (132, 59, 86), (136, 63, 76), (140, 57, 69), (141, 49, 57), + (155, 40, 43), (161, 42, 43), (167, 44, 43), (180, 55, 44), + (198, 65, 37), (213, 74, 34), (221, 74, 29), (227, 71, 22), + (226, 70, 21), (227, 70, 19), (228, 74, 19), (224, 72, 22), + (221, 67, 19), (214, 59, 15), (209, 53, 9), (209, 56, 3), + (208, 58, 3), (204, 62, 6), (197, 63, 8), (185, 65, 14), + (183, 73, 13), (184, 84, 17), (188, 99, 21), (200, 117, 26), + (198, 135, 41), (200, 153, 42), (200, 170, 43), (194, 180, 39), + (194, 191, 43), (184, 200, 58), (173, 202, 77), (163, 201, 103), + (148, 188, 120), (136, 173, 134), (128, 156, 146), (121, 134, 158), + (114, 111, 172), (111, 90, 180), (107, 70, 178), (112, 58, 165), + (120, 48, 148), (121, 38, 127), (121, 29, 106), (105, 17, 84), + (92, 8, 59), (79, 6, 44), (64, 6, 36), (56, 7, 34), + (42, 8, 30), (34, 6, 25), (22, 13, 21), (17, 23, 23), + (23, 38, 33), (32, 53, 50), (49, 66, 60), (74, 82, 67), + (101, 94, 66), (126, 113, 61), (144, 125, 66), (147, 136, 71), + (151, 149, 84), (153, 141, 92), (152, 135, 89), (141, 117, 78), + (117, 97, 66), (87, 95, 63), (61, 93, 67), (48, 95, 73), + (40, 102, 74), (38, 106, 74), (46, 108, 74), (64, 128, 73) + ), + +// 532 Dark_Rose +((92, 63, 80), (75, 57, 74), (70, 54, 69), (66, 51, 65), + (62, 48, 60), (59, 45, 55), (57, 43, 51), (56, 42, 48), + (54, 42, 47), (55, 52, 48), (57, 63, 49), (61, 74, 55), + (66, 86, 62), (81, 94, 69), (97, 102, 77), (102, 92, 77), + (107, 82, 78), (129, 72, 98), (132, 64, 96), (136, 56, 95), + (132, 50, 93), (129, 45, 91), (125, 42, 85), (122, 39, 80), + (104, 39, 66), (91, 40, 61), (78, 42, 56), (71, 41, 51), + (64, 40, 47), (61, 40, 44), (58, 41, 41), (55, 41, 41), + (53, 42, 47), (42, 51, 39), (46, 44, 40), (50, 38, 41), + (50, 36, 37), (50, 35, 33), (49, 33, 32), (48, 31, 31), + (46, 25, 32), (42, 24, 29), (39, 23, 26), (35, 23, 28), + (32, 23, 31), (30, 22, 29), (28, 21, 27), (18, 18, 24), + (17, 22, 17), (12, 20, 12), (13, 19, 12), (15, 19, 13), + (18, 22, 15), (21, 26, 17), (21, 27, 19), (22, 29, 22), + (27, 37, 34), (29, 39, 34), (31, 42, 35), (31, 40, 37), + (31, 38, 39), (30, 38, 36), (29, 38, 34), (27, 37, 34), + (27, 35, 31), (35, 31, 27), (38, 30, 31), (41, 30, 35), + (42, 30, 36), (44, 31, 38), (48, 31, 36), (51, 32, 35), + (55, 30, 41), (54, 29, 38), (53, 28, 35), (49, 25, 31), + (45, 23, 27), (43, 22, 26), (42, 22, 25), (38, 21, 22), + (33, 19, 22), (24, 19, 15), (22, 15, 14), (21, 12, 13), + (20, 10, 14), (19, 9, 15), (17, 8, 13), (15, 7, 11), + (16, 6, 12), (15, 7, 11), (15, 8, 11), (16, 9, 11), + (18, 10, 11), (23, 16, 14), (29, 17, 22), (34, 19, 23), + (39, 21, 25), (50, 27, 38), (54, 27, 41), (58, 27, 44), + (59, 26, 43), (60, 26, 43), (61, 27, 47), (61, 28, 46), + (64, 29, 47), (65, 31, 46), (66, 34, 46), (67, 34, 46), + (68, 35, 47), (69, 39, 51), (72, 43, 55), (75, 49, 58), + (78, 52, 58), (80, 56, 60), (82, 56, 62), (85, 57, 65), + (92, 59, 70), (97, 60, 73), (104, 61, 75), (113, 65, 83), + (131, 79, 98), (142, 80, 104), (154, 81, 111), (156, 82, 111), + (158, 84, 111), (149, 86, 106), (145, 82, 108), (140, 75, 105), + (135, 67, 100), (104, 54, 72), (97, 52, 70), (90, 51, 68), + (80, 49, 64), (72, 49, 59), (67, 47, 49), (65, 47, 49), + (60, 49, 45), (59, 47, 47), (58, 45, 49), (58, 44, 49), + (59, 43, 50), (57, 39, 47), (57, 34, 47), (57, 30, 47), + (58, 27, 44), (63, 21, 42), (65, 19, 41), (68, 18, 41), + (74, 18, 46), (77, 20, 47), (80, 24, 51), (85, 27, 53), + (97, 31, 65), (97, 33, 65), (98, 35, 66), (99, 41, 72), + (99, 43, 70), (100, 46, 73), (97, 47, 69), (94, 50, 70), + (86, 53, 69), (69, 76, 57), (66, 77, 54), (63, 79, 52), + (60, 78, 49), (55, 76, 48), (51, 71, 46), (52, 69, 45), + (61, 55, 45), (58, 47, 43), (56, 40, 42), (54, 36, 44), + (50, 34, 36), (51, 44, 36), (50, 54, 36), (50, 55, 35), + (43, 54, 30), (44, 54, 30), (41, 52, 30), (44, 49, 30), + (43, 39, 27), (38, 22, 23), (36, 18, 24), (34, 18, 27), + (31, 13, 22), (30, 13, 22), (29, 13, 23), (26, 15, 25), + (22, 14, 24), (22, 15, 21), (24, 15, 20), (27, 16, 28), + (30, 20, 32), (33, 26, 38), (42, 37, 48), (66, 50, 65), + (86, 67, 80), (103, 80, 84), (113, 94, 89), (118, 88, 99), + (123, 88, 95), (126, 88, 94), (119, 86, 87), (104, 73, 82), + (89, 59, 68), (76, 51, 52), (70, 54, 49), (65, 62, 49), + (62, 58, 47), (62, 56, 46), (65, 49, 46), (75, 42, 53), + (89, 37, 62), (95, 30, 66), (92, 27, 61), (87, 22, 56), + (87, 18, 52), (82, 13, 51), (70, 11, 42), (53, 11, 28), + (45, 13, 23), (42, 14, 24), (44, 11, 24), (44, 10, 21), + (47, 13, 26), (54, 16, 33), (61, 17, 40), (65, 18, 41), + (69, 23, 48), (71, 29, 51), (73, 32, 56), (72, 32, 52), + (74, 32, 58), (73, 32, 54), (73, 32, 56), (70, 32, 55), + (68, 30, 54), (64, 30, 52), (62, 29, 51), (58, 30, 51), + (54, 28, 48), (49, 27, 43), (44, 26, 34), (42, 26, 33), + (40, 27, 31), (40, 34, 30), (40, 44, 31), (46, 50, 35), + (56, 57, 40), (63, 54, 44), (68, 55, 49), (80, 56, 58), + (90, 59, 65), (90, 58, 65), (83, 57, 67), (86, 60, 71) + ), + +// 533 Dark_Turquoise +((38, 116, 114), (38, 115, 113), (37, 104, 104), (37, 93, 95), + (33, 80, 82), (30, 67, 70), (28, 60, 64), (27, 54, 58), + (25, 34, 40), (25, 32, 37), (26, 30, 35), (27, 34, 39), + (28, 38, 43), (30, 48, 52), (33, 59, 62), (34, 66, 67), + (36, 73, 73), (44, 105, 103), (47, 116, 113), (50, 127, 124), + (55, 131, 127), (61, 136, 130), (62, 139, 134), (63, 143, 138), + (61, 155, 150), (60, 153, 147), (60, 151, 145), (60, 148, 143), + (61, 146, 142), (59, 148, 145), (58, 151, 148), (53, 160, 156), + (52, 166, 162), (56, 169, 165), (57, 171, 168), (59, 174, 171), + (59, 180, 178), (60, 187, 185), (61, 189, 187), (62, 191, 190), + (63, 195, 195), (63, 195, 195), (63, 195, 195), (63, 188, 188), + (63, 182, 181), (63, 175, 174), (63, 168, 167), (60, 153, 151), + (58, 137, 136), (49, 105, 105), (47, 89, 89), (45, 74, 73), + (41, 65, 64), (37, 56, 56), (35, 53, 54), (34, 51, 53), + (34, 46, 49), (33, 45, 48), (33, 45, 47), (32, 45, 46), + (31, 45, 45), (31, 43, 44), (32, 42, 44), (32, 38, 40), + (30, 34, 37), (26, 29, 31), (25, 28, 30), (25, 28, 30), + (25, 28, 30), (26, 28, 31), (26, 30, 34), (27, 33, 39), + (27, 46, 53), (28, 59, 64), (30, 73, 76), (33, 86, 88), + (36, 99, 100), (35, 102, 102), (35, 105, 105), (32, 106, 107), + (32, 106, 107), (34, 101, 102), (32, 91, 92), (30, 82, 82), + (28, 76, 76), (27, 70, 70), (25, 59, 61), (26, 53, 56), + (33, 54, 55), (35, 58, 57), (38, 63, 60), (38, 63, 61), + (38, 64, 62), (36, 64, 65), (36, 64, 66), (38, 63, 67), + (41, 63, 68), (46, 65, 71), (51, 65, 73), (56, 66, 76), + (57, 66, 77), (59, 67, 78), (62, 70, 79), (60, 76, 75), + (64, 72, 73), (60, 66, 69), (57, 61, 66), (52, 59, 61), + (47, 58, 57), (40, 53, 52), (35, 45, 45), (32, 40, 41), + (32, 39, 41), (34, 46, 49), (34, 48, 50), (34, 50, 52), + (35, 53, 56), (36, 56, 60), (37, 59, 63), (37, 61, 64), + (34, 55, 60), (31, 52, 58), (29, 49, 57), (28, 49, 58), + (28, 49, 59), (27, 52, 60), (28, 58, 66), (31, 70, 75), + (33, 85, 89), (40, 117, 123), (41, 125, 131), (43, 134, 139), + (48, 151, 155), (51, 170, 171), (57, 184, 186), (60, 194, 197), + (61, 201, 204), (61, 200, 203), (61, 200, 202), (61, 199, 201), + (61, 198, 200), (60, 194, 195), (58, 185, 185), (53, 174, 172), + (48, 158, 158), (45, 127, 128), (44, 118, 119), (44, 109, 111), + (41, 95, 94), (35, 79, 79), (32, 64, 65), (29, 52, 53), + (34, 39, 42), (35, 40, 42), (37, 42, 43), (44, 50, 51), + (52, 63, 61), (72, 83, 81), (75, 102, 99), (75, 119, 114), + (77, 134, 132), (85, 158, 157), (84, 162, 161), (84, 167, 165), + (76, 169, 165), (66, 160, 159), (45, 139, 142), (40, 123, 128), + (35, 95, 99), (33, 87, 91), (31, 80, 83), (28, 66, 71), + (25, 58, 65), (25, 54, 63), (27, 59, 67), (30, 71, 75), + (34, 84, 87), (36, 98, 102), (38, 112, 115), (38, 119, 122), + (39, 124, 125), (40, 125, 125), (39, 121, 122), (39, 116, 118), + (33, 91, 95), (32, 83, 87), (32, 76, 80), (29, 61, 65), + (27, 48, 54), (26, 37, 45), (25, 31, 38), (26, 27, 34), + (26, 25, 31), (27, 25, 29), (28, 27, 29), (29, 29, 31), + (31, 33, 35), (35, 37, 41), (38, 44, 47), (42, 51, 53), + (43, 56, 59), (43, 61, 64), (43, 63, 70), (43, 67, 75), + (43, 69, 77), (42, 70, 77), (38, 67, 72), (34, 61, 66), + (31, 57, 62), (28, 53, 59), (27, 52, 57), (27, 52, 57), + (26, 52, 56), (25, 57, 59), (25, 63, 64), (25, 68, 69), + (26, 74, 77), (25, 76, 82), (26, 76, 85), (27, 79, 89), + (26, 76, 86), (26, 73, 82), (25, 67, 75), (25, 58, 67), + (26, 51, 61), (26, 44, 54), (26, 38, 47), (25, 33, 40), + (25, 30, 34), (25, 28, 31), (26, 26, 30), (27, 26, 29), + (27, 26, 28), (26, 26, 27), (26, 27, 26), (26, 27, 26), + (27, 28, 26), (27, 28, 26), (26, 28, 26), (25, 28, 26), + (25, 29, 26), (25, 28, 26), (25, 28, 27), (25, 27, 27), + (25, 26, 28), (25, 26, 28), (25, 27, 28), (25, 29, 30), + (25, 33, 33), (26, 39, 41), (28, 51, 52), (30, 66, 67), + (33, 81, 81), (36, 94, 91), (39, 102, 102), (40, 110, 109) + ), + +// 534 Dark_Waters +((40, 9, 84), (36, 5, 75), (37, 2, 65), (39, 0, 56), + (21, 0, 42), (4, 0, 28), (2, 7, 14), (0, 14, 0), + (0, 14, 0), (0, 14, 0), (0, 14, 0), (0, 14, 0), + (0, 14, 0), (0, 7, 8), (0, 0, 17), (0, 0, 17), + (0, 0, 18), (0, 0, 31), (0, 2, 41), (0, 4, 52), + (0, 13, 64), (0, 22, 76), (0, 27, 82), (0, 32, 89), + (0, 48, 110), (0, 52, 118), (0, 57, 127), (0, 61, 133), + (0, 65, 140), (0, 66, 141), (0, 67, 142), (0, 63, 142), + (0, 61, 140), (0, 56, 124), (0, 48, 115), (0, 41, 106), + (0, 36, 96), (0, 31, 87), (0, 24, 83), (0, 17, 79), + (0, 5, 71), (0, 2, 71), (0, 0, 71), (0, 0, 73), + (0, 0, 76), (0, 2, 79), (0, 5, 83), (0, 0, 88), + (10, 4, 92), (13, 4, 100), (11, 4, 101), (9, 4, 102), + (7, 4, 99), (5, 4, 96), (7, 4, 94), (10, 4, 92), + (22, 4, 76), (23, 2, 67), (25, 0, 59), (25, 0, 50), + (25, 0, 41), (23, 0, 38), (22, 0, 35), (22, 0, 26), + (21, 0, 1), (0, 14, 0), (0, 14, 0), (0, 14, 0), + (0, 14, 0), (0, 14, 0), (0, 14, 0), (0, 14, 0), + (0, 0, 18), (9, 0, 24), (18, 0, 31), (24, 0, 41), + (31, 0, 52), (39, 0, 58), (48, 0, 65), (61, 5, 83), + (45, 17, 106), (28, 40, 158), (32, 55, 175), (36, 71, 193), + (38, 79, 198), (40, 88, 203), (36, 84, 210), (36, 79, 210), + (35, 83, 203), (31, 86, 200), (28, 89, 198), (25, 88, 194), + (22, 87, 190), (21, 88, 181), (14, 92, 166), (5, 75, 150), + (0, 56, 123), (0, 26, 83), (0, 22, 72), (0, 18, 61), + (0, 17, 60), (0, 17, 59), (0, 22, 59), (0, 21, 65), + (0, 28, 65), (0, 22, 65), (0, 17, 65), (0, 17, 63), + (0, 18, 61), (0, 18, 61), (0, 25, 59), (0, 25, 61), + (0, 25, 59), (0, 21, 53), (0, 17, 49), (0, 14, 45), + (0, 13, 39), (0, 8, 28), (0, 1, 21), (0, 17, 0), + (0, 14, 0), (0, 14, 0), (0, 14, 0), (0, 14, 0), + (0, 14, 0), (0, 14, 0), (0, 14, 0), (0, 14, 0), + (0, 14, 0), (0, 14, 0), (0, 14, 0), (0, 14, 0), + (0, 14, 0), (0, 14, 0), (0, 0, 17), (0, 1, 17), + (0, 0, 21), (0, 0, 21), (0, 0, 21), (0, 0, 19), + (0, 1, 18), (0, 1, 18), (0, 0, 18), (0, 0, 18), + (0, 0, 18), (0, 0, 25), (0, 0, 25), (0, 0, 26), + (0, 0, 26), (0, 0, 26), (1, 0, 26), (14, 0, 26), + (28, 0, 22), (24, 0, 27), (21, 0, 32), (22, 0, 39), + (36, 0, 45), (32, 0, 56), (26, 0, 67), (41, 1, 76), + (41, 8, 84), (45, 14, 107), (57, 18, 115), (69, 22, 123), + (73, 32, 146), (102, 45, 171), (135, 57, 201), (154, 73, 232), + (206, 107, 255), (208, 114, 255), (210, 122, 255), (255, 127, 255), + (255, 131, 255), (255, 136, 255), (255, 132, 255), (255, 128, 255), + (232, 131, 255), (198, 127, 255), (158, 123, 255), (118, 115, 255), + (106, 118, 255), (94, 119, 255), (83, 100, 255), (65, 79, 242), + (28, 40, 177), (22, 38, 162), (17, 36, 148), (4, 36, 123), + (0, 32, 107), (0, 36, 96), (0, 26, 84), (0, 17, 75), + (0, 4, 67), (0, 4, 57), (0, 0, 52), (0, 0, 49), + (0, 0, 49), (0, 0, 56), (0, 4, 61), (0, 25, 69), + (0, 32, 79), (0, 44, 87), (0, 52, 98), (5, 49, 111), + (10, 61, 128), (21, 67, 154), (32, 79, 181), (44, 80, 206), + (52, 84, 223), (53, 100, 233), (56, 106, 238), (53, 106, 241), + (52, 98, 241), (49, 111, 245), (49, 115, 255), (56, 122, 255), + (67, 124, 255), (79, 127, 255), (92, 138, 255), (94, 163, 255), + (92, 173, 255), (88, 183, 255), (79, 170, 255), (65, 181, 255), + (59, 181, 255), (57, 177, 255), (61, 159, 255), (63, 170, 255), + (71, 163, 255), (71, 162, 255), (69, 136, 255), (59, 124, 255), + (45, 118, 233), (31, 94, 202), (21, 65, 170), (10, 48, 140), + (8, 26, 118), (4, 17, 100), (1, 9, 87), (0, 0, 75), + (14, 0, 63), (32, 0, 56), (14, 0, 48), (13, 0, 45), + (14, 0, 48), (18, 0, 53), (14, 0, 63), (35, 4, 75), + (41, 9, 87), (40, 9, 84), (40, 5, 83), (49, 4, 80), + (44, 4, 79), (36, 5, 76), (21, 1, 75), (35, 4, 75) + ), + +// 535 Darkness +((51, 35, 40), (48, 23, 29), (46, 20, 21), (45, 17, 13), + (38, 16, 12), (32, 16, 11), (28, 17, 9), (25, 18, 8), + (24, 21, 24), (24, 27, 34), (25, 33, 45), (23, 41, 62), + (22, 49, 80), (25, 51, 88), (29, 53, 96), (33, 54, 98), + (38, 56, 101), (49, 46, 116), (53, 45, 108), (57, 44, 100), + (52, 41, 90), (48, 39, 81), (45, 37, 72), (42, 35, 63), + (31, 27, 38), (25, 22, 32), (19, 18, 26), (18, 16, 23), + (17, 15, 20), (17, 15, 19), (18, 15, 19), (19, 15, 17), + (20, 16, 17), (21, 16, 15), (20, 16, 14), (19, 16, 14), + (17, 14, 14), (16, 13, 14), (13, 11, 12), (11, 10, 11), + (7, 7, 8), (7, 7, 8), (7, 8, 9), (17, 12, 13), + (28, 17, 18), (37, 20, 21), (46, 24, 24), (62, 26, 41), + (82, 30, 50), (121, 68, 60), (114, 74, 61), (107, 80, 63), + (91, 80, 60), (75, 80, 57), (65, 75, 56), (56, 70, 56), + (33, 39, 57), (29, 35, 59), (26, 31, 61), (28, 31, 69), + (31, 32, 77), (31, 32, 80), (32, 32, 84), (25, 29, 92), + (26, 29, 91), (19, 21, 79), (19, 22, 68), (20, 23, 58), + (23, 25, 56), (27, 27, 54), (33, 33, 59), (39, 36, 62), + (55, 46, 68), (53, 45, 66), (52, 45, 65), (48, 42, 58), + (45, 39, 51), (39, 36, 50), (34, 33, 49), (29, 29, 48), + (25, 27, 45), (13, 22, 49), (15, 22, 54), (17, 23, 59), + (18, 22, 65), (19, 22, 71), (21, 18, 81), (25, 20, 87), + (29, 20, 92), (25, 21, 82), (22, 22, 73), (22, 21, 67), + (23, 21, 61), (20, 21, 51), (16, 20, 44), (15, 19, 39), + (17, 18, 37), (19, 19, 33), (20, 18, 29), (22, 18, 26), + (22, 18, 25), (23, 19, 24), (23, 18, 21), (23, 17, 18), + (21, 16, 19), (21, 16, 19), (21, 16, 20), (22, 17, 21), + (23, 18, 23), (25, 20, 26), (31, 24, 32), (36, 29, 37), + (36, 31, 39), (40, 33, 41), (37, 31, 38), (35, 30, 36), + (29, 25, 32), (26, 23, 27), (22, 20, 23), (18, 17, 21), + (14, 16, 18), (13, 16, 20), (12, 17, 22), (12, 16, 23), + (13, 16, 24), (13, 19, 27), (15, 20, 29), (20, 20, 31), + (27, 24, 33), (45, 24, 25), (50, 26, 26), (56, 28, 28), + (78, 30, 38), (102, 24, 39), (108, 26, 42), (113, 33, 54), + (112, 28, 38), (107, 31, 45), (102, 34, 53), (102, 34, 56), + (102, 35, 59), (110, 41, 72), (111, 47, 83), (102, 47, 95), + (97, 43, 85), (54, 39, 60), (45, 34, 55), (37, 30, 50), + (29, 25, 38), (22, 21, 30), (19, 18, 26), (18, 17, 25), + (16, 14, 20), (16, 14, 19), (16, 14, 18), (16, 11, 17), + (15, 10, 16), (14, 12, 16), (14, 11, 16), (13, 10, 16), + (13, 11, 16), (12, 12, 17), (12, 12, 17), (13, 12, 17), + (13, 12, 17), (14, 12, 18), (14, 13, 19), (14, 14, 21), + (14, 15, 24), (14, 15, 25), (14, 16, 26), (14, 16, 27), + (13, 15, 28), (11, 15, 30), (12, 18, 33), (13, 20, 39), + (16, 22, 45), (18, 28, 58), (19, 37, 74), (29, 39, 76), + (37, 40, 76), (39, 45, 77), (44, 44, 71), (45, 39, 58), + (35, 30, 41), (32, 27, 41), (30, 25, 41), (30, 25, 40), + (31, 30, 44), (36, 32, 48), (43, 37, 50), (53, 40, 50), + (65, 42, 46), (74, 57, 48), (93, 52, 46), (114, 35, 33), + (113, 43, 27), (109, 45, 27), (110, 38, 25), (96, 39, 22), + (73, 40, 22), (60, 45, 34), (57, 53, 42), (56, 53, 45), + (59, 55, 45), (62, 59, 44), (58, 57, 49), (60, 57, 49), + (71, 63, 55), (77, 64, 72), (84, 57, 84), (89, 53, 103), + (85, 58, 109), (94, 57, 107), (82, 48, 109), (64, 45, 107), + (67, 47, 111), (75, 47, 113), (86, 55, 139), (94, 53, 151), + (101, 36, 126), (101, 45, 127), (88, 42, 111), (71, 17, 74), + (52, 15, 50), (33, 16, 33), (20, 10, 27), (16, 10, 24), + (13, 11, 22), (10, 9, 18), (9, 8, 13), (6, 7, 13), + (7, 6, 13), (8, 8, 12), (8, 9, 12), (10, 10, 15), + (12, 12, 19), (13, 14, 21), (16, 15, 23), (18, 17, 24), + (19, 18, 27), (19, 18, 27), (20, 18, 26), (19, 18, 26), + (16, 17, 24), (15, 16, 22), (15, 15, 22), (15, 14, 20), + (16, 16, 21), (19, 17, 23), (23, 19, 25), (27, 23, 28), + (32, 28, 33), (39, 35, 39), (37, 36, 40), (39, 32, 39) + ), + +// 536 Davinci +((210, 157, 143), (233, 209, 178), (220, 210, 184), (207, 212, 190), + (181, 200, 172), (156, 189, 155), (151, 175, 164), (146, 161, 173), + (90, 107, 141), (105, 94, 145), (120, 81, 150), (130, 71, 134), + (140, 62, 118), (138, 41, 96), (137, 20, 74), (130, 15, 68), + (123, 11, 63), (86, 12, 41), (81, 31, 53), (77, 50, 66), + (77, 66, 77), (77, 82, 89), (80, 94, 101), (83, 106, 113), + (73, 84, 100), (66, 68, 90), (59, 52, 81), (56, 42, 74), + (53, 32, 68), (58, 30, 61), (64, 28, 55), (65, 36, 39), + (61, 56, 52), (38, 87, 51), (32, 101, 68), (27, 115, 86), + (30, 124, 89), (34, 133, 92), (43, 129, 92), (53, 126, 92), + (116, 146, 93), (160, 172, 115), (205, 198, 137), (217, 191, 135), + (229, 185, 134), (221, 177, 132), (213, 169, 130), (205, 128, 97), + (184, 83, 70), (155, 43, 50), (148, 28, 41), (142, 14, 33), + (146, 21, 49), (150, 29, 65), (152, 35, 73), (154, 42, 81), + (177, 82, 126), (184, 104, 146), (191, 127, 167), (186, 130, 157), + (182, 133, 147), (179, 137, 152), (176, 141, 157), (169, 123, 145), + (163, 102, 122), (150, 60, 67), (157, 66, 65), (164, 73, 63), + (172, 80, 63), (181, 87, 64), (192, 110, 69), (185, 101, 73), + (194, 75, 45), (178, 49, 29), (162, 23, 13), (162, 38, 16), + (162, 54, 19), (152, 67, 29), (143, 81, 40), (150, 118, 58), + (152, 147, 70), (114, 147, 73), (125, 147, 81), (137, 147, 89), + (141, 139, 91), (145, 131, 94), (147, 98, 73), (144, 55, 47), + (140, 36, 48), (141, 33, 42), (142, 30, 37), (139, 35, 44), + (137, 41, 52), (129, 49, 62), (125, 43, 50), (118, 40, 39), + (104, 41, 43), (99, 55, 43), (98, 48, 45), (98, 41, 47), + (97, 40, 48), (97, 39, 50), (104, 36, 49), (115, 36, 45), + (112, 52, 63), (115, 84, 77), (118, 116, 92), (106, 117, 95), + (95, 119, 98), (98, 138, 123), (99, 138, 108), (97, 144, 99), + (113, 149, 111), (174, 159, 114), (173, 149, 108), (172, 139, 102), + (165, 109, 83), (148, 81, 66), (115, 57, 63), (96, 53, 66), + (59, 43, 68), (38, 39, 57), (18, 35, 47), (14, 24, 41), + (11, 13, 35), (16, 7, 41), (34, 17, 44), (47, 12, 24), + (62, 6, 20), (109, 34, 20), (120, 51, 28), (131, 69, 36), + (136, 88, 56), (139, 118, 77), (138, 135, 81), (125, 130, 75), + (84, 105, 47), (70, 86, 33), (57, 67, 20), (49, 58, 19), + (41, 49, 18), (20, 33, 12), (8, 27, 7), (16, 39, 34), + (30, 61, 52), (54, 114, 66), (70, 127, 82), (86, 140, 98), + (101, 159, 97), (96, 181, 95), (109, 177, 109), (112, 165, 109), + (134, 147, 109), (134, 131, 105), (135, 115, 102), (138, 92, 91), + (156, 79, 81), (159, 74, 95), (161, 81, 100), (176, 92, 97), + (181, 109, 107), (177, 142, 116), (172, 144, 117), (168, 147, 118), + (150, 141, 116), (140, 138, 100), (108, 112, 83), (77, 82, 68), + (65, 66, 41), (66, 61, 40), (67, 56, 39), (83, 48, 31), + (90, 59, 35), (102, 79, 43), (137, 85, 42), (143, 89, 51), + (136, 109, 69), (150, 118, 71), (151, 103, 71), (148, 97, 82), + (142, 99, 91), (131, 90, 87), (132, 85, 83), (136, 107, 98), + (145, 150, 100), (145, 154, 109), (145, 158, 119), (135, 164, 122), + (139, 165, 119), (158, 168, 137), (161, 155, 148), (148, 126, 126), + (150, 120, 112), (147, 99, 97), (140, 83, 89), (142, 75, 82), + (149, 62, 70), (152, 53, 54), (152, 65, 56), (158, 78, 64), + (168, 109, 86), (175, 153, 115), (185, 183, 131), (179, 191, 144), + (177, 194, 150), (195, 198, 162), (193, 182, 163), (184, 173, 149), + (180, 153, 130), (176, 134, 117), (172, 144, 119), (174, 155, 118), + (169, 160, 117), (141, 154, 112), (122, 147, 111), (121, 146, 108), + (110, 137, 106), (115, 135, 119), (123, 127, 117), (127, 121, 111), + (124, 111, 110), (117, 112, 122), (110, 109, 119), (120, 109, 121), + (116, 105, 124), (126, 97, 116), (127, 74, 93), (116, 55, 68), + (117, 40, 40), (108, 33, 28), (83, 20, 12), (67, 26, 10), + (51, 31, 12), (31, 19, 5), (21, 11, 3), (13, 4, 4), + (11, 7, 10), (12, 9, 13), (7, 5, 11), (4, 9, 12), + (5, 17, 19), (2, 14, 18), (4, 19, 20), (8, 23, 21), + (9, 18, 21), (21, 22, 20), (39, 40, 26), (50, 53, 32), + (72, 71, 45), (98, 95, 59), (117, 126, 63), (146, 151, 78), + (165, 152, 101), (180, 167, 109), (207, 182, 114), (218, 162, 124) + ), + +// 537 Daylight_Fading +((80, 105, 154), (70, 95, 136), (64, 82, 120), (58, 70, 105), + (50, 62, 94), (42, 54, 83), (39, 51, 78), (36, 49, 74), + (34, 44, 65), (38, 44, 63), (43, 44, 61), (47, 44, 62), + (52, 45, 63), (57, 47, 67), (62, 50, 71), (67, 53, 73), + (73, 56, 76), (99, 72, 86), (105, 75, 87), (112, 79, 88), + (114, 80, 91), (117, 82, 94), (120, 84, 96), (123, 87, 98), + (141, 88, 93), (148, 84, 92), (155, 80, 91), (165, 86, 99), + (175, 92, 108), (182, 98, 113), (190, 105, 119), (203, 112, 124), + (213, 113, 126), (210, 108, 123), (198, 111, 126), (186, 115, 129), + (170, 111, 128), (155, 107, 127), (147, 102, 124), (140, 97, 121), + (121, 93, 118), (126, 96, 122), (131, 100, 127), (142, 104, 126), + (153, 109, 126), (153, 109, 125), (154, 110, 125), (160, 107, 122), + (161, 101, 113), (150, 89, 93), (135, 80, 85), (121, 71, 77), + (104, 60, 70), (88, 50, 64), (82, 47, 61), (77, 45, 58), + (69, 43, 57), (68, 44, 58), (67, 46, 60), (64, 46, 60), + (62, 46, 61), (61, 45, 61), (60, 45, 61), (58, 45, 59), + (55, 45, 57), (45, 40, 53), (40, 38, 51), (36, 36, 50), + (36, 36, 49), (36, 37, 49), (37, 36, 50), (40, 35, 51), + (42, 36, 52), (43, 36, 52), (44, 37, 53), (46, 35, 53), + (49, 34, 53), (49, 33, 51), (49, 33, 50), (49, 32, 46), + (46, 30, 43), (39, 26, 37), (38, 26, 35), (37, 26, 33), + (39, 26, 32), (41, 27, 32), (46, 28, 32), (52, 29, 35), + (70, 41, 50), (83, 51, 61), (96, 62, 72), (103, 65, 76), + (110, 69, 81), (129, 79, 89), (144, 86, 97), (156, 95, 107), + (159, 102, 116), (139, 102, 117), (131, 95, 108), (124, 89, 99), + (121, 85, 95), (118, 81, 92), (102, 71, 88), (88, 62, 78), + (73, 41, 56), (84, 41, 56), (96, 42, 57), (106, 44, 60), + (117, 46, 63), (135, 53, 68), (152, 57, 74), (166, 63, 80), + (180, 73, 91), (193, 87, 115), (193, 89, 118), (193, 91, 121), + (184, 91, 121), (175, 94, 117), (159, 90, 113), (142, 87, 110), + (109, 77, 102), (96, 74, 97), (84, 72, 93), (79, 70, 90), + (75, 68, 88), (66, 65, 84), (60, 61, 80), (55, 59, 79), + (50, 56, 79), (49, 50, 76), (50, 48, 72), (51, 47, 68), + (54, 44, 61), (55, 41, 56), (57, 39, 57), (62, 38, 58), + (74, 42, 62), (79, 43, 63), (84, 45, 65), (86, 45, 66), + (89, 45, 68), (95, 49, 69), (100, 52, 71), (102, 52, 71), + (103, 52, 69), (109, 49, 64), (111, 48, 63), (114, 48, 62), + (119, 45, 60), (124, 43, 55), (126, 41, 55), (128, 41, 54), + (130, 43, 55), (130, 43, 55), (130, 44, 55), (128, 46, 56), + (124, 50, 61), (117, 54, 67), (107, 58, 72), (97, 61, 77), + (87, 64, 82), (76, 70, 92), (74, 71, 93), (72, 72, 95), + (69, 74, 96), (67, 73, 96), (69, 70, 94), (71, 69, 92), + (77, 67, 86), (79, 66, 84), (81, 65, 83), (87, 61, 81), + (90, 57, 78), (92, 52, 75), (92, 51, 72), (91, 52, 66), + (92, 56, 67), (93, 61, 67), (96, 62, 71), (98, 69, 79), + (100, 75, 85), (100, 81, 92), (97, 86, 93), (97, 84, 93), + (99, 82, 94), (98, 80, 95), (98, 79, 97), (93, 75, 94), + (88, 67, 88), (82, 58, 79), (82, 51, 71), (83, 49, 70), + (86, 49, 70), (91, 52, 73), (95, 54, 76), (101, 55, 77), + (107, 56, 80), (118, 59, 83), (131, 62, 85), (141, 65, 87), + (149, 63, 82), (150, 58, 77), (149, 53, 72), (147, 49, 66), + (142, 46, 62), (133, 41, 59), (122, 36, 54), (106, 31, 49), + (91, 28, 44), (77, 28, 41), (64, 27, 41), (55, 29, 44), + (49, 33, 48), (50, 39, 51), (59, 46, 55), (77, 50, 60), + (74, 49, 58), (70, 49, 57), (64, 46, 52), (57, 45, 50), + (78, 47, 56), (76, 43, 53), (71, 38, 49), (60, 31, 43), + (42, 26, 38), (43, 27, 39), (43, 29, 41), (43, 28, 42), + (41, 26, 41), (39, 25, 40), (37, 24, 37), (36, 25, 35), + (36, 26, 33), (33, 24, 33), (32, 23, 33), (34, 23, 34), + (38, 25, 35), (45, 29, 40), (51, 35, 47), (56, 41, 57), + (62, 49, 67), (67, 55, 75), (74, 62, 86), (81, 68, 92), + (85, 74, 99), (91, 77, 102), (94, 78, 103), (93, 83, 111), + (95, 86, 117), (96, 93, 126), (99, 98, 132), (102, 108, 142), + (101, 111, 147), (98, 111, 152), (93, 111, 156), (89, 102, 150) + ), + +// 538 Dinosaurs +((27, 168, 193), (15, 167, 195), (12, 154, 194), (10, 141, 193), + (7, 133, 179), (4, 125, 165), (7, 118, 154), (10, 112, 144), + (12, 84, 92), (17, 80, 74), (23, 76, 56), (26, 77, 43), + (30, 78, 30), (41, 79, 43), (53, 81, 57), (55, 79, 67), + (57, 78, 77), (64, 92, 106), (67, 80, 114), (71, 69, 122), + (80, 62, 117), (89, 56, 112), (92, 56, 101), (96, 56, 91), + (91, 37, 68), (94, 40, 50), (98, 44, 33), (86, 52, 30), + (75, 61, 27), (75, 58, 26), (75, 56, 26), (77, 54, 23), + (71, 55, 23), (69, 80, 54), (68, 88, 71), (68, 96, 89), + (61, 116, 101), (55, 136, 113), (48, 141, 118), (41, 146, 124), + (33, 146, 139), (35, 130, 137), (37, 114, 135), (52, 94, 143), + (68, 74, 152), (82, 65, 155), (96, 56, 158), (104, 49, 165), + (104, 62, 170), (123, 82, 169), (109, 82, 154), (96, 83, 139), + (77, 83, 115), (59, 83, 92), (53, 81, 84), (47, 79, 76), + (24, 64, 40), (20, 70, 29), (16, 76, 19), (12, 90, 16), + (9, 104, 14), (8, 109, 17), (7, 114, 21), (9, 124, 27), + (11, 131, 34), (14, 136, 46), (14, 133, 55), (14, 131, 64), + (15, 126, 65), (17, 121, 66), (17, 112, 59), (22, 99, 51), + (24, 99, 36), (26, 107, 27), (28, 116, 18), (29, 132, 19), + (31, 148, 20), (28, 152, 24), (26, 157, 28), (25, 164, 27), + (24, 171, 23), (23, 161, 27), (32, 150, 25), (42, 139, 23), + (50, 136, 27), (59, 133, 32), (69, 121, 42), (85, 113, 58), + (117, 95, 61), (121, 80, 61), (126, 65, 61), (127, 62, 58), + (129, 60, 55), (142, 55, 44), (149, 48, 34), (152, 35, 33), + (155, 30, 43), (169, 48, 71), (165, 46, 75), (162, 44, 80), + (159, 42, 80), (157, 40, 80), (146, 56, 80), (133, 75, 75), + (138, 95, 71), (122, 103, 74), (107, 112, 77), (109, 115, 85), + (112, 119, 93), (120, 127, 121), (110, 133, 147), (84, 135, 156), + (63, 132, 160), (49, 136, 168), (46, 139, 161), (43, 142, 155), + (40, 142, 128), (52, 134, 105), (72, 116, 80), (99, 98, 62), + (144, 71, 22), (148, 58, 17), (153, 46, 13), (155, 39, 13), + (157, 33, 14), (153, 33, 14), (137, 33, 13), (114, 33, 14), + (94, 28, 13), (60, 18, 24), (55, 18, 28), (51, 18, 33), + (40, 19, 42), (31, 16, 51), (18, 12, 53), (13, 18, 56), + (10, 36, 63), (13, 39, 59), (17, 42, 55), (16, 44, 54), + (16, 47, 53), (15, 51, 61), (18, 64, 81), (20, 75, 100), + (21, 83, 116), (21, 93, 138), (20, 100, 138), (19, 107, 139), + (12, 117, 133), (12, 121, 122), (10, 117, 105), (15, 115, 82), + (8, 110, 48), (6, 105, 43), (5, 101, 38), (17, 94, 32), + (30, 93, 27), (44, 90, 23), (51, 82, 22), (66, 68, 23), + (79, 64, 28), (98, 44, 23), (106, 38, 23), (115, 32, 23), + (124, 26, 32), (133, 16, 48), (142, 10, 60), (163, 11, 73), + (186, 15, 107), (189, 16, 111), (192, 17, 115), (200, 24, 116), + (204, 27, 108), (195, 34, 103), (181, 43, 103), (164, 50, 107), + (160, 51, 102), (153, 53, 86), (152, 62, 70), (135, 64, 103), + (121, 66, 131), (101, 69, 145), (99, 82, 117), (100, 83, 134), + (102, 79, 176), (104, 78, 169), (106, 77, 163), (116, 72, 148), + (129, 63, 141), (147, 54, 127), (156, 40, 109), (152, 35, 87), + (134, 31, 76), (114, 28, 76), (95, 24, 81), (77, 28, 82), + (59, 44, 88), (43, 54, 90), (33, 58, 94), (29, 58, 85), + (34, 64, 79), (46, 66, 61), (50, 63, 46), (48, 57, 29), + (41, 50, 27), (42, 46, 29), (41, 37, 41), (46, 33, 55), + (51, 31, 79), (61, 35, 97), (72, 43, 116), (84, 54, 128), + (90, 72, 143), (95, 86, 146), (94, 104, 138), (89, 119, 123), + (70, 144, 113), (49, 161, 106), (35, 170, 100), (31, 164, 89), + (27, 158, 82), (26, 152, 71), (27, 144, 69), (31, 138, 64), + (33, 135, 61), (37, 134, 55), (39, 126, 50), (39, 122, 42), + (39, 123, 34), (36, 125, 32), (32, 128, 40), (27, 127, 47), + (30, 135, 45), (31, 144, 38), (30, 154, 38), (20, 154, 43), + (18, 150, 49), (19, 146, 47), (26, 137, 43), (24, 119, 36), + (24, 98, 36), (27, 79, 45), (37, 66, 60), (42, 56, 70), + (42, 53, 69), (44, 53, 70), (47, 63, 82), (47, 84, 100), + (42, 100, 112), (41, 110, 118), (43, 118, 128), (43, 138, 140), + (38, 159, 153), (36, 171, 163), (36, 170, 182), (34, 167, 191) + ), + +// 539 Dragon +((148, 29, 29), (138, 15, 31), (124, 16, 40), (111, 17, 50), + (95, 26, 55), (79, 35, 61), (73, 39, 60), (67, 44, 60), + (71, 68, 51), (88, 75, 41), (106, 82, 32), (119, 76, 23), + (133, 70, 14), (145, 65, 9), (157, 61, 4), (158, 56, 5), + (159, 51, 6), (153, 47, 13), (148, 46, 14), (143, 46, 16), + (142, 51, 18), (141, 56, 21), (141, 59, 18), (141, 62, 16), + (135, 65, 14), (124, 75, 10), (113, 85, 7), (94, 99, 6), + (75, 113, 5), (68, 116, 7), (61, 120, 9), (45, 123, 9), + (26, 129, 8), (12, 124, 11), (9, 114, 9), (7, 104, 7), + (7, 100, 9), (8, 96, 11), (8, 95, 11), (9, 94, 11), + (9, 90, 13), (9, 98, 15), (10, 106, 18), (9, 107, 21), + (8, 108, 25), (7, 108, 26), (7, 109, 28), (7, 112, 29), + (8, 116, 28), (17, 118, 39), (25, 119, 44), (34, 121, 49), + (41, 117, 50), (48, 113, 52), (59, 104, 54), (70, 96, 57), + (107, 68, 52), (119, 57, 43), (131, 46, 34), (142, 42, 28), + (153, 39, 22), (152, 39, 19), (151, 40, 16), (139, 43, 9), + (120, 49, 7), (86, 51, 13), (72, 43, 22), (58, 35, 31), + (52, 34, 37), (46, 33, 43), (36, 32, 48), (34, 23, 55), + (35, 10, 61), (31, 10, 63), (28, 10, 66), (27, 10, 61), + (26, 11, 57), (25, 11, 53), (25, 12, 49), (26, 13, 45), + (21, 17, 45), (22, 36, 35), (21, 43, 37), (21, 50, 40), + (24, 54, 45), (27, 58, 50), (28, 69, 57), (27, 85, 63), + (23, 101, 70), (27, 102, 65), (32, 103, 60), (34, 100, 55), + (37, 98, 50), (49, 89, 41), (71, 79, 33), (94, 68, 27), + (111, 59, 29), (145, 52, 26), (155, 60, 25), (165, 69, 25), + (164, 72, 27), (163, 76, 29), (160, 74, 34), (157, 74, 33), + (140, 78, 41), (134, 76, 47), (128, 75, 54), (125, 77, 52), + (123, 80, 51), (121, 90, 43), (116, 110, 37), (120, 127, 33), + (119, 138, 28), (107, 142, 15), (103, 144, 15), (100, 147, 16), + (89, 145, 22), (71, 131, 30), (54, 118, 31), (40, 112, 29), + (28, 100, 29), (29, 96, 27), (30, 93, 26), (35, 90, 23), + (41, 88, 21), (47, 86, 23), (50, 85, 31), (56, 84, 41), + (70, 79, 42), (95, 82, 39), (98, 86, 39), (102, 91, 39), + (115, 103, 32), (125, 113, 26), (136, 123, 21), (139, 125, 20), + (141, 112, 23), (134, 98, 32), (127, 85, 41), (121, 77, 46), + (115, 70, 52), (101, 54, 58), (90, 45, 63), (82, 44, 58), + (78, 47, 51), (76, 68, 43), (74, 74, 38), (73, 80, 34), + (75, 83, 22), (79, 83, 13), (78, 93, 11), (70, 106, 12), + (70, 104, 12), (71, 101, 11), (72, 98, 11), (72, 97, 11), + (79, 89, 9), (87, 77, 8), (94, 62, 9), (93, 56, 11), + (97, 49, 10), (80, 54, 9), (72, 56, 10), (65, 59, 12), + (64, 60, 12), (58, 62, 15), (46, 66, 22), (34, 68, 33), + (34, 68, 45), (35, 68, 49), (36, 68, 53), (39, 69, 63), + (40, 78, 69), (56, 92, 64), (77, 104, 57), (94, 110, 45), + (99, 114, 39), (106, 121, 33), (114, 129, 31), (113, 130, 26), + (98, 122, 22), (80, 111, 21), (66, 104, 24), (53, 99, 24), + (23, 68, 22), (18, 60, 26), (13, 53, 30), (15, 42, 37), + (19, 38, 41), (20, 30, 42), (14, 31, 45), (15, 33, 48), + (17, 43, 53), (19, 51, 53), (23, 63, 52), (32, 77, 45), + (50, 91, 40), (64, 101, 36), (80, 100, 35), (96, 104, 36), + (116, 105, 35), (130, 106, 34), (132, 100, 29), (131, 105, 28), + (123, 115, 33), (115, 124, 37), (108, 126, 36), (107, 129, 31), + (102, 123, 36), (87, 114, 42), (72, 98, 40), (62, 88, 32), + (58, 64, 26), (52, 39, 27), (44, 19, 26), (37, 13, 25), + (36, 13, 19), (49, 18, 14), (69, 34, 11), (88, 50, 14), + (99, 67, 20), (108, 86, 23), (115, 105, 23), (118, 126, 20), + (115, 143, 20), (101, 155, 24), (81, 156, 27), (63, 153, 24), + (55, 146, 17), (46, 138, 14), (32, 132, 15), (22, 123, 17), + (24, 116, 16), (33, 105, 17), (40, 103, 17), (47, 104, 15), + (57, 110, 15), (70, 114, 14), (79, 120, 14), (80, 126, 15), + (76, 130, 16), (72, 134, 19), (69, 135, 27), (58, 137, 34), + (44, 137, 38), (29, 136, 36), (24, 132, 40), (21, 124, 44), + (23, 117, 48), (25, 111, 47), (35, 102, 42), (53, 92, 38), + (76, 74, 36), (97, 60, 37), (115, 46, 35), (133, 38, 32) + ), + +// 540 Dust_Bunny +((103, 105, 94), (100, 104, 95), (100, 104, 96), (101, 104, 97), + (104, 107, 101), (107, 111, 105), (107, 112, 107), (107, 113, 110), + (106, 115, 115), (105, 115, 114), (105, 115, 114), (105, 114, 113), + (106, 113, 113), (104, 111, 112), (103, 110, 112), (101, 108, 111), + (99, 107, 110), (91, 96, 104), (86, 92, 100), (82, 88, 97), + (76, 82, 92), (70, 76, 87), (67, 73, 84), (64, 70, 81), + (59, 63, 75), (57, 63, 75), (56, 63, 75), (57, 63, 74), + (58, 63, 73), (59, 64, 73), (60, 65, 74), (62, 68, 78), + (65, 71, 83), (71, 75, 83), (72, 75, 80), (73, 75, 77), + (72, 73, 75), (71, 71, 73), (71, 69, 71), (71, 68, 70), + (67, 60, 58), (65, 56, 53), (64, 53, 49), (63, 52, 49), + (63, 52, 49), (62, 51, 49), (62, 51, 49), (63, 51, 49), + (64, 51, 51), (68, 58, 57), (70, 61, 63), (73, 65, 69), + (74, 69, 74), (76, 74, 80), (76, 76, 82), (76, 78, 84), + (79, 80, 83), (78, 79, 81), (78, 78, 79), (73, 75, 77), + (69, 73, 75), (67, 71, 72), (66, 70, 70), (64, 67, 66), + (64, 64, 64), (63, 60, 61), (64, 60, 60), (65, 60, 59), + (67, 61, 59), (69, 63, 60), (74, 68, 64), (80, 73, 69), + (98, 88, 78), (108, 97, 85), (119, 107, 93), (125, 114, 100), + (131, 122, 108), (134, 125, 110), (137, 129, 113), (141, 131, 114), + (143, 132, 115), (137, 128, 112), (131, 122, 107), (125, 117, 103), + (120, 114, 101), (116, 111, 99), (110, 106, 95), (102, 101, 91), + (90, 89, 85), (85, 83, 83), (80, 78, 81), (77, 76, 79), + (75, 74, 78), (71, 69, 75), (67, 64, 71), (64, 59, 68), + (61, 55, 64), (56, 50, 54), (53, 48, 51), (50, 47, 48), + (49, 46, 48), (48, 46, 48), (48, 49, 49), (49, 51, 50), + (55, 58, 57), (58, 62, 63), (61, 67, 69), (63, 70, 72), + (65, 73, 75), (70, 77, 80), (74, 80, 83), (77, 81, 85), + (78, 79, 85), (74, 74, 81), (72, 73, 79), (71, 72, 78), + (69, 69, 75), (68, 65, 70), (68, 63, 66), (70, 64, 66), + (76, 74, 73), (82, 79, 75), (89, 84, 78), (94, 88, 80), + (99, 92, 83), (109, 99, 88), (115, 106, 90), (118, 109, 92), + (119, 109, 90), (123, 109, 88), (122, 107, 85), (121, 105, 83), + (115, 99, 77), (107, 92, 71), (99, 85, 65), (96, 82, 62), + (91, 76, 58), (89, 76, 59), (87, 76, 61), (86, 77, 62), + (86, 78, 63), (84, 80, 67), (85, 80, 69), (85, 82, 71), + (85, 81, 72), (81, 79, 74), (79, 77, 74), (78, 76, 75), + (77, 76, 77), (78, 76, 79), (81, 78, 82), (87, 83, 87), + (101, 95, 97), (104, 98, 99), (108, 101, 101), (112, 106, 106), + (114, 110, 109), (113, 112, 113), (112, 113, 113), (113, 113, 111), + (112, 112, 108), (104, 107, 103), (101, 105, 102), (98, 104, 102), + (93, 101, 98), (91, 99, 95), (90, 95, 91), (87, 91, 87), + (83, 81, 79), (82, 79, 76), (81, 77, 73), (79, 73, 68), + (77, 68, 62), (76, 65, 57), (77, 64, 55), (82, 66, 55), + (86, 71, 56), (92, 76, 59), (96, 80, 59), (99, 83, 61), + (101, 86, 63), (101, 86, 65), (101, 85, 67), (97, 82, 66), + (85, 72, 61), (81, 68, 59), (77, 65, 57), (70, 58, 53), + (62, 51, 52), (56, 47, 50), (53, 45, 49), (52, 47, 48), + (53, 47, 47), (56, 49, 48), (58, 51, 50), (63, 53, 53), + (66, 59, 56), (72, 65, 59), (79, 71, 60), (87, 76, 62), + (94, 80, 64), (97, 83, 67), (97, 86, 72), (97, 89, 75), + (95, 90, 78), (93, 90, 79), (90, 87, 78), (83, 81, 76), + (76, 76, 73), (69, 69, 69), (61, 63, 65), (57, 58, 60), + (53, 52, 54), (54, 50, 48), (56, 48, 44), (58, 48, 42), + (61, 50, 42), (64, 55, 45), (69, 60, 50), (75, 67, 57), + (81, 72, 65), (87, 79, 73), (90, 85, 79), (94, 90, 83), + (99, 94, 86), (103, 97, 88), (109, 100, 91), (115, 106, 95), + (120, 110, 96), (125, 113, 96), (129, 116, 95), (133, 117, 95), + (135, 120, 98), (135, 121, 103), (132, 121, 106), (128, 120, 107), + (122, 117, 107), (115, 112, 104), (108, 106, 103), (99, 98, 100), + (89, 92, 96), (81, 86, 92), (76, 82, 86), (74, 79, 81), + (74, 75, 78), (73, 75, 76), (74, 76, 77), (75, 80, 80), + (79, 85, 82), (84, 89, 87), (88, 92, 88), (90, 94, 90), + (89, 95, 90), (91, 97, 90), (95, 99, 91), (98, 101, 92) + ), + +// 541 Dynasty +((85, 96, 61), (34, 91, 51), (21, 89, 49), (8, 88, 48), + (8, 82, 35), (8, 77, 22), (7, 73, 19), (6, 69, 17), + (10, 51, 18), (16, 38, 14), (22, 25, 11), (36, 18, 14), + (51, 12, 17), (62, 12, 15), (74, 13, 14), (79, 13, 12), + (85, 13, 10), (88, 9, 23), (86, 11, 28), (84, 14, 33), + (80, 17, 42), (76, 21, 52), (76, 27, 58), (77, 33, 65), + (93, 55, 79), (94, 71, 80), (96, 88, 81), (95, 90, 68), + (95, 92, 56), (94, 87, 53), (94, 83, 50), (95, 70, 41), + (101, 58, 26), (123, 39, 4), (144, 33, 4), (166, 28, 5), + (176, 37, 11), (186, 47, 17), (185, 52, 26), (185, 57, 35), + (187, 70, 55), (178, 75, 54), (169, 80, 54), (162, 78, 57), + (156, 77, 60), (154, 74, 54), (152, 72, 49), (142, 72, 42), + (130, 70, 45), (101, 57, 51), (80, 48, 53), (59, 39, 56), + (46, 33, 51), (33, 28, 46), (27, 24, 41), (22, 20, 37), + (9, 19, 17), (15, 21, 13), (21, 24, 9), (28, 34, 8), + (35, 45, 7), (42, 45, 5), (49, 46, 4), (65, 43, 8), + (80, 46, 11), (98, 58, 12), (95, 62, 18), (93, 67, 25), + (90, 69, 30), (88, 72, 35), (73, 76, 36), (57, 88, 38), + (33, 99, 47), (30, 99, 56), (28, 99, 66), (28, 87, 73), + (29, 76, 80), (34, 69, 84), (39, 63, 88), (45, 58, 78), + (35, 56, 83), (26, 50, 68), (26, 54, 50), (26, 59, 32), + (29, 61, 27), (32, 63, 22), (51, 70, 15), (70, 69, 14), + (122, 50, 7), (143, 44, 9), (164, 38, 11), (170, 37, 11), + (177, 37, 11), (182, 38, 13), (183, 37, 14), (168, 37, 21), + (154, 42, 28), (144, 60, 29), (141, 65, 33), (138, 70, 38), + (135, 72, 44), (132, 74, 50), (128, 79, 50), (122, 84, 47), + (107, 98, 46), (96, 93, 44), (86, 88, 42), (81, 85, 42), + (77, 82, 42), (72, 74, 47), (71, 62, 47), (76, 54, 47), + (83, 51, 51), (86, 47, 50), (85, 50, 48), (84, 54, 46), + (90, 61, 44), (96, 71, 32), (96, 78, 21), (93, 88, 20), + (113, 95, 43), (126, 99, 52), (139, 104, 61), (142, 103, 67), + (145, 103, 73), (146, 107, 81), (147, 112, 86), (146, 112, 88), + (132, 99, 85), (89, 74, 63), (82, 69, 59), (76, 65, 56), + (67, 49, 49), (67, 33, 47), (79, 25, 41), (96, 23, 35), + (146, 16, 26), (169, 17, 22), (193, 18, 19), (199, 18, 18), + (205, 18, 17), (208, 16, 12), (203, 19, 8), (184, 23, 4), + (162, 26, 4), (119, 33, 5), (109, 35, 5), (100, 38, 5), + (88, 44, 10), (78, 58, 19), (75, 64, 33), (71, 68, 46), + (78, 79, 69), (83, 85, 76), (89, 91, 84), (90, 97, 94), + (91, 95, 99), (87, 84, 96), (89, 77, 93), (86, 66, 81), + (86, 57, 65), (80, 31, 44), (76, 27, 39), (72, 23, 35), + (61, 17, 25), (56, 18, 16), (55, 19, 13), (57, 30, 14), + (71, 52, 28), (78, 55, 34), (85, 59, 40), (103, 73, 50), + (125, 84, 63), (147, 97, 74), (168, 103, 83), (178, 102, 83), + (177, 97, 80), (172, 89, 74), (168, 81, 65), (160, 67, 54), + (143, 58, 44), (125, 49, 36), (116, 45, 26), (115, 38, 19), + (127, 32, 28), (136, 31, 29), (145, 31, 30), (163, 38, 25), + (178, 40, 28), (182, 49, 35), (189, 48, 52), (193, 63, 63), + (191, 71, 69), (175, 87, 67), (152, 89, 72), (128, 100, 74), + (107, 98, 72), (91, 95, 62), (76, 83, 53), (56, 77, 45), + (38, 65, 41), (29, 57, 35), (26, 48, 31), (24, 42, 25), + (19, 36, 24), (22, 36, 23), (33, 47, 25), (47, 58, 27), + (54, 63, 31), (52, 62, 34), (53, 65, 42), (57, 69, 49), + (66, 62, 55), (63, 49, 55), (61, 36, 57), (63, 29, 58), + (73, 25, 55), (85, 17, 48), (98, 10, 44), (118, 6, 46), + (131, 11, 43), (142, 13, 36), (145, 9, 29), (156, 6, 26), + (165, 6, 21), (172, 9, 18), (169, 7, 14), (164, 6, 18), + (162, 3, 19), (163, 5, 19), (155, 9, 20), (135, 11, 26), + (112, 12, 29), (98, 18, 26), (86, 31, 21), (75, 48, 18), + (67, 58, 17), (70, 64, 13), (83, 72, 10), (97, 79, 7), + (114, 78, 7), (126, 66, 5), (138, 58, 7), (145, 50, 13), + (151, 45, 19), (152, 33, 19), (151, 29, 15), (151, 31, 16), + (154, 42, 20), (163, 53, 22), (172, 65, 20), (167, 70, 25), + (162, 81, 29), (137, 85, 37), (125, 95, 43), (91, 94, 56) + ), + +// 542 Easter +((178, 165, 213), (177, 160, 215), (176, 158, 215), (175, 156, 216), + (175, 154, 216), (176, 153, 217), (176, 151, 217), (177, 150, 217), + (178, 151, 217), (179, 154, 217), (180, 158, 217), (180, 158, 216), + (180, 159, 215), (180, 159, 214), (180, 159, 214), (179, 160, 214), + (179, 161, 214), (178, 164, 218), (177, 163, 219), (177, 163, 220), + (175, 164, 223), (173, 166, 226), (174, 167, 226), (175, 168, 227), + (182, 171, 227), (180, 170, 227), (178, 170, 227), (176, 164, 221), + (174, 158, 215), (173, 152, 210), (173, 147, 206), (167, 134, 196), + (158, 121, 186), (134, 89, 157), (120, 72, 143), (106, 56, 130), + (98, 46, 122), (91, 36, 115), (90, 33, 112), (89, 31, 109), + (90, 30, 111), (95, 35, 116), (100, 40, 121), (108, 47, 126), + (116, 54, 132), (118, 55, 135), (120, 57, 139), (122, 59, 141), + (121, 57, 140), (112, 51, 130), (104, 44, 126), (97, 37, 122), + (93, 31, 118), (89, 25, 115), (89, 25, 113), (89, 25, 112), + (95, 33, 119), (107, 48, 131), (119, 63, 144), (129, 79, 156), + (139, 96, 169), (141, 101, 172), (144, 106, 176), (158, 130, 193), + (169, 142, 202), (182, 169, 224), (182, 177, 227), (183, 185, 230), + (185, 188, 231), (188, 192, 232), (193, 196, 234), (197, 200, 237), + (199, 207, 240), (199, 206, 238), (199, 205, 237), (197, 199, 235), + (195, 193, 233), (193, 189, 232), (192, 185, 231), (185, 174, 228), + (180, 162, 225), (168, 143, 218), (166, 136, 214), (164, 129, 211), + (163, 125, 209), (163, 122, 208), (160, 117, 205), (158, 114, 200), + (156, 110, 190), (156, 107, 187), (157, 105, 184), (156, 104, 182), + (156, 103, 181), (155, 100, 178), (152, 99, 177), (150, 97, 178), + (149, 98, 180), (152, 103, 184), (155, 109, 187), (158, 115, 190), + (158, 119, 192), (158, 124, 195), (160, 132, 198), (163, 138, 201), + (170, 142, 199), (169, 142, 196), (169, 142, 194), (167, 140, 192), + (166, 139, 191), (164, 131, 188), (160, 120, 184), (155, 108, 177), + (148, 97, 170), (136, 78, 156), (131, 73, 153), (127, 69, 151), + (120, 60, 144), (113, 52, 139), (107, 46, 132), (106, 42, 127), + (105, 45, 126), (110, 50, 131), (116, 56, 137), (121, 61, 141), + (126, 67, 145), (136, 81, 155), (146, 96, 168), (155, 111, 180), + (163, 124, 193), (176, 150, 215), (178, 155, 218), (181, 161, 222), + (184, 169, 228), (185, 175, 233), (185, 177, 235), (185, 177, 237), + (186, 177, 236), (186, 175, 234), (186, 173, 232), (185, 170, 231), + (184, 168, 230), (182, 162, 227), (179, 156, 222), (178, 151, 218), + (177, 148, 214), (174, 139, 206), (172, 134, 203), (170, 129, 201), + (166, 121, 196), (164, 115, 191), (162, 110, 187), (159, 107, 182), + (148, 85, 173), (144, 78, 169), (141, 72, 166), (134, 64, 160), + (128, 58, 153), (120, 53, 144), (114, 45, 138), (105, 37, 130), + (94, 33, 122), (88, 32, 113), (89, 35, 114), (90, 39, 116), + (96, 45, 122), (98, 55, 129), (104, 65, 136), (113, 73, 144), + (136, 94, 171), (141, 100, 178), (146, 107, 185), (154, 119, 196), + (161, 127, 204), (164, 134, 212), (167, 139, 217), (168, 144, 221), + (171, 148, 223), (174, 152, 224), (175, 155, 225), (176, 155, 225), + (176, 154, 224), (175, 152, 221), (175, 149, 217), (173, 145, 212), + (162, 139, 210), (161, 139, 211), (160, 139, 213), (161, 140, 215), + (166, 144, 216), (166, 144, 217), (162, 147, 220), (161, 149, 223), + (163, 151, 228), (169, 155, 230), (173, 155, 229), (170, 152, 230), + (167, 150, 227), (166, 148, 228), (166, 147, 228), (168, 148, 226), + (167, 146, 226), (165, 146, 225), (166, 145, 225), (166, 144, 223), + (169, 144, 220), (171, 142, 218), (170, 140, 215), (169, 137, 212), + (166, 132, 209), (163, 127, 206), (160, 123, 205), (158, 122, 204), + (159, 123, 204), (161, 124, 204), (162, 125, 204), (163, 127, 205), + (164, 132, 207), (165, 137, 208), (170, 143, 210), (172, 146, 212), + (175, 147, 213), (174, 148, 215), (173, 148, 215), (173, 147, 216), + (172, 143, 216), (170, 135, 215), (168, 128, 214), (166, 124, 211), + (164, 122, 209), (165, 122, 207), (166, 119, 207), (166, 119, 207), + (167, 122, 207), (167, 126, 208), (169, 133, 209), (172, 139, 211), + (176, 147, 214), (179, 154, 218), (181, 162, 222), (185, 170, 226), + (188, 178, 228), (193, 186, 231), (198, 192, 233), (199, 198, 234), + (199, 200, 235), (197, 199, 235), (195, 199, 234), (193, 197, 233), + (192, 195, 230), (189, 191, 227), (185, 185, 225), (183, 179, 222), + (179, 175, 220), (178, 172, 217), (177, 170, 215), (177, 168, 213) + ), + +// 543 Easter_2 +((145, 146, 202), (154, 169, 210), (159, 183, 215), (165, 198, 220), + (173, 210, 225), (181, 222, 230), (187, 224, 232), (193, 227, 234), + (220, 240, 243), (229, 243, 246), (238, 247, 249), (239, 247, 249), + (241, 248, 250), (233, 244, 247), (226, 241, 244), (220, 236, 242), + (215, 232, 240), (185, 203, 229), (171, 186, 220), (157, 169, 211), + (148, 151, 203), (139, 134, 196), (135, 128, 193), (132, 122, 190), + (122, 101, 179), (110, 84, 172), (99, 67, 165), (89, 52, 154), + (79, 37, 144), (74, 29, 140), (70, 22, 136), (64, 12, 131), + (65, 8, 131), (93, 27, 143), (105, 38, 151), (118, 50, 160), + (125, 65, 165), (133, 81, 170), (134, 87, 171), (136, 93, 172), + (149, 120, 187), (161, 136, 197), (174, 153, 207), (190, 169, 217), + (207, 185, 228), (214, 193, 232), (221, 202, 237), (232, 217, 242), + (240, 228, 245), (246, 244, 251), (249, 248, 252), (252, 252, 254), + (250, 252, 253), (249, 252, 252), (246, 250, 251), (243, 249, 250), + (227, 242, 244), (217, 237, 241), (208, 233, 238), (200, 230, 235), + (193, 227, 233), (190, 226, 232), (187, 225, 231), (182, 223, 230), + (178, 221, 228), (176, 220, 227), (176, 220, 227), (176, 221, 227), + (177, 221, 227), (179, 221, 228), (184, 223, 230), (190, 225, 232), + (202, 226, 237), (209, 224, 239), (217, 223, 241), (224, 219, 243), + (231, 216, 245), (233, 214, 246), (236, 212, 247), (239, 207, 247), + (241, 200, 246), (236, 180, 243), (230, 168, 239), (225, 156, 236), + (222, 150, 235), (220, 144, 234), (215, 132, 230), (209, 123, 227), + (201, 104, 221), (196, 96, 218), (191, 89, 215), (188, 86, 213), + (186, 83, 212), (181, 78, 209), (178, 73, 207), (174, 72, 206), + (173, 71, 205), (172, 73, 204), (172, 76, 204), (173, 79, 204), + (174, 81, 204), (175, 83, 205), (178, 88, 206), (180, 93, 208), + (182, 104, 211), (176, 111, 210), (171, 118, 209), (167, 122, 209), + (164, 126, 209), (159, 133, 208), (156, 141, 208), (156, 151, 210), + (160, 160, 212), (172, 177, 218), (174, 181, 219), (176, 185, 221), + (177, 194, 223), (178, 201, 224), (179, 209, 226), (183, 217, 229), + (197, 229, 235), (209, 234, 239), (222, 240, 243), (227, 242, 245), + (233, 244, 247), (241, 244, 250), (246, 241, 251), (247, 235, 251), + (245, 226, 249), (235, 205, 242), (233, 200, 240), (232, 195, 239), + (229, 186, 237), (227, 179, 236), (225, 173, 236), (222, 164, 235), + (215, 150, 231), (207, 147, 227), (200, 144, 224), (197, 144, 223), + (195, 144, 222), (193, 148, 223), (196, 156, 225), (199, 164, 228), + (204, 173, 230), (215, 187, 237), (215, 190, 237), (216, 193, 238), + (215, 195, 236), (212, 195, 235), (207, 200, 234), (199, 204, 233), + (180, 204, 228), (176, 203, 227), (172, 202, 226), (166, 200, 223), + (160, 197, 221), (155, 190, 218), (149, 187, 216), (143, 185, 214), + (137, 184, 212), (121, 183, 207), (117, 184, 206), (113, 185, 205), + (108, 188, 204), (108, 190, 204), (113, 192, 206), (123, 193, 207), + (146, 190, 213), (150, 187, 214), (155, 184, 215), (160, 175, 214), + (160, 162, 211), (165, 165, 213), (165, 168, 215), (166, 171, 214), + (164, 172, 213), (162, 174, 214), (161, 175, 214), (160, 173, 215), + (153, 150, 208), (151, 143, 209), (147, 138, 213), (144, 138, 216), + (130, 148, 213), (126, 153, 213), (122, 158, 213), (114, 170, 214), + (102, 166, 207), (96, 157, 202), (87, 143, 198), (86, 128, 195), + (87, 115, 191), (87, 112, 189), (85, 113, 188), (81, 117, 187), + (75, 125, 185), (73, 136, 181), (67, 139, 180), (65, 140, 179), + (68, 131, 177), (78, 125, 177), (87, 120, 177), (94, 112, 177), + (98, 107, 176), (105, 108, 175), (107, 108, 174), (104, 108, 172), + (97, 102, 167), (97, 93, 160), (97, 82, 153), (96, 71, 147), + (96, 59, 143), (103, 51, 144), (111, 42, 144), (117, 36, 145), + (120, 34, 147), (123, 37, 149), (128, 44, 153), (133, 53, 156), + (137, 64, 159), (145, 79, 167), (156, 95, 176), (169, 109, 188), + (183, 122, 200), (196, 133, 211), (207, 143, 222), (216, 151, 230), + (224, 156, 234), (228, 162, 237), (230, 170, 238), (226, 180, 239), + (217, 186, 237), (206, 188, 234), (193, 188, 230), (179, 185, 226), + (167, 180, 222), (157, 174, 219), (152, 168, 217), (151, 164, 213), + (148, 159, 211), (145, 155, 209), (140, 150, 206), (134, 144, 202), + (127, 136, 197), (121, 128, 193), (117, 123, 191), (118, 118, 189), + (118, 118, 188), (120, 119, 190), (121, 122, 191), (124, 125, 193), + (127, 125, 194), (132, 126, 195), (133, 130, 197), (140, 135, 199) + ), + +// 544 Easter_3 +((216, 166, 226), (229, 189, 237), (235, 199, 242), (241, 210, 247), + (244, 216, 250), (247, 223, 253), (247, 223, 253), (247, 224, 253), + (243, 219, 250), (236, 213, 246), (229, 208, 242), (219, 199, 238), + (210, 190, 234), (200, 176, 231), (191, 162, 228), (187, 153, 225), + (184, 145, 223), (158, 118, 206), (146, 110, 198), (135, 102, 191), + (128, 96, 185), (122, 90, 179), (123, 88, 176), (124, 86, 174), + (129, 84, 165), (130, 84, 166), (132, 85, 167), (137, 89, 172), + (142, 93, 178), (148, 96, 180), (154, 100, 183), (166, 108, 187), + (176, 111, 191), (174, 106, 193), (166, 103, 191), (158, 100, 190), + (151, 98, 183), (145, 96, 176), (141, 93, 171), (138, 91, 167), + (111, 71, 146), (97, 62, 137), (83, 54, 128), (73, 49, 120), + (63, 44, 113), (60, 42, 111), (58, 41, 109), (55, 38, 106), + (52, 35, 104), (51, 34, 104), (50, 33, 104), (50, 32, 104), + (51, 33, 105), (52, 35, 106), (53, 35, 107), (54, 36, 109), + (63, 42, 121), (68, 47, 127), (74, 53, 133), (79, 57, 139), + (84, 62, 145), (86, 63, 149), (88, 64, 153), (94, 66, 161), + (101, 68, 168), (108, 74, 178), (109, 74, 177), (110, 75, 176), + (108, 73, 174), (107, 72, 172), (105, 68, 169), (103, 66, 165), + (105, 67, 167), (110, 72, 171), (116, 77, 176), (125, 87, 181), + (134, 98, 186), (138, 104, 189), (143, 110, 192), (155, 121, 202), + (170, 132, 212), (203, 155, 235), (214, 168, 242), (225, 181, 249), + (228, 184, 251), (232, 188, 253), (234, 191, 251), (234, 190, 248), + (226, 179, 237), (215, 172, 230), (205, 165, 224), (199, 160, 220), + (194, 156, 217), (184, 147, 213), (180, 138, 209), (177, 133, 210), + (174, 131, 209), (177, 134, 214), (179, 134, 216), (181, 134, 219), + (183, 135, 223), (185, 136, 227), (190, 137, 233), (193, 139, 239), + (193, 138, 243), (188, 133, 240), (184, 128, 237), (181, 124, 235), + (178, 120, 234), (172, 114, 231), (169, 113, 228), (165, 112, 226), + (165, 113, 224), (165, 115, 226), (167, 116, 226), (169, 117, 227), + (177, 122, 228), (186, 131, 230), (197, 139, 231), (204, 144, 230), + (201, 143, 222), (191, 136, 214), (181, 129, 206), (178, 126, 201), + (176, 124, 197), (173, 118, 191), (168, 112, 185), (164, 109, 181), + (158, 104, 175), (141, 99, 168), (139, 96, 168), (137, 94, 169), + (136, 91, 171), (140, 90, 176), (146, 92, 181), (153, 96, 183), + (165, 107, 186), (169, 107, 187), (173, 108, 188), (175, 108, 190), + (177, 109, 193), (180, 112, 196), (180, 112, 197), (183, 116, 201), + (184, 119, 205), (197, 123, 210), (202, 126, 212), (207, 130, 215), + (210, 130, 219), (209, 130, 221), (203, 129, 221), (194, 126, 215), + (179, 111, 199), (174, 108, 194), (170, 105, 189), (161, 97, 180), + (147, 90, 169), (132, 84, 159), (114, 74, 149), (100, 64, 139), + (87, 57, 131), (69, 45, 121), (67, 44, 119), (65, 43, 117), + (62, 43, 116), (61, 43, 116), (62, 43, 116), (62, 43, 117), + (67, 46, 123), (68, 47, 124), (70, 49, 126), (73, 51, 130), + (75, 53, 133), (75, 52, 134), (75, 51, 135), (75, 50, 136), + (78, 53, 137), (85, 57, 137), (97, 66, 141), (111, 73, 146), + (127, 83, 153), (142, 91, 159), (154, 101, 167), (167, 108, 171), + (193, 131, 186), (199, 135, 191), (206, 139, 197), (219, 150, 207), + (229, 160, 219), (236, 168, 227), (239, 177, 234), (241, 187, 238), + (240, 192, 243), (239, 196, 246), (239, 194, 246), (238, 193, 244), + (233, 191, 241), (228, 190, 235), (221, 190, 232), (212, 189, 228), + (203, 180, 222), (194, 167, 213), (180, 152, 204), (164, 133, 192), + (146, 118, 180), (131, 109, 172), (119, 100, 165), (110, 92, 160), + (106, 87, 159), (104, 78, 159), (102, 72, 160), (104, 70, 164), + (109, 71, 170), (116, 74, 177), (125, 83, 186), (137, 90, 197), + (147, 98, 206), (160, 108, 217), (172, 118, 224), (184, 125, 231), + (194, 136, 236), (205, 142, 242), (213, 147, 244), (221, 154, 248), + (229, 162, 249), (234, 166, 248), (238, 170, 246), (239, 170, 243), + (238, 165, 238), (233, 160, 233), (227, 156, 228), (219, 150, 225), + (210, 149, 221), (203, 148, 217), (198, 146, 215), (192, 142, 214), + (186, 139, 213), (178, 132, 213), (166, 127, 209), (156, 124, 204), + (149, 120, 198), (143, 116, 194), (141, 114, 192), (142, 111, 194), + (143, 107, 196), (143, 107, 196), (146, 107, 193), (147, 106, 188), + (150, 105, 181), (152, 109, 182), (158, 111, 185), (171, 121, 196), + (185, 133, 206), (197, 143, 216), (210, 150, 221), (216, 161, 228) + ), + +// 545 Egg_Hunt +((119, 124, 148), (130, 119, 106), (148, 117, 90), (167, 116, 75), + (173, 123, 73), (180, 130, 71), (177, 135, 70), (175, 141, 70), + (159, 152, 77), (157, 153, 75), (155, 155, 74), (146, 160, 67), + (138, 165, 61), (128, 174, 64), (118, 183, 67), (119, 183, 62), + (121, 183, 58), (162, 187, 23), (179, 191, 18), (196, 196, 14), + (204, 192, 14), (212, 188, 15), (214, 182, 14), (216, 176, 13), + (225, 153, 22), (228, 146, 33), (232, 139, 45), (231, 133, 53), + (230, 128, 62), (229, 127, 63), (229, 127, 64), (229, 131, 69), + (230, 138, 64), (231, 145, 55), (229, 154, 47), (227, 164, 39), + (218, 173, 38), (209, 182, 38), (200, 178, 43), (192, 175, 48), + (164, 174, 75), (144, 181, 98), (125, 188, 122), (106, 187, 136), + (88, 186, 150), (86, 183, 147), (85, 180, 144), (80, 178, 130), + (73, 180, 131), (68, 187, 125), (86, 185, 104), (105, 183, 84), + (116, 177, 76), (127, 172, 68), (130, 169, 72), (133, 166, 77), + (160, 143, 94), (166, 127, 84), (172, 112, 75), (166, 111, 68), + (160, 111, 62), (161, 116, 61), (162, 121, 60), (166, 117, 55), + (165, 124, 40), (161, 151, 16), (170, 167, 14), (180, 184, 12), + (185, 188, 11), (191, 193, 11), (201, 196, 13), (208, 199, 21), + (230, 201, 44), (233, 198, 58), (237, 196, 73), (226, 189, 90), + (215, 183, 108), (205, 179, 110), (195, 176, 113), (177, 168, 111), + (154, 159, 113), (110, 153, 132), (98, 150, 121), (87, 147, 111), + (83, 142, 99), (79, 138, 88), (73, 135, 72), (77, 137, 68), + (121, 149, 61), (143, 143, 47), (165, 137, 34), (169, 129, 29), + (173, 121, 25), (170, 108, 25), (170, 92, 30), (167, 83, 45), + (162, 79, 58), (138, 66, 66), (119, 62, 64), (100, 59, 63), + (92, 64, 67), (85, 69, 72), (83, 75, 72), (86, 90, 67), + (117, 124, 33), (134, 139, 31), (151, 154, 29), (156, 156, 32), + (161, 159, 35), (175, 165, 47), (195, 169, 65), (213, 175, 84), + (232, 181, 104), (248, 179, 127), (248, 177, 131), (249, 175, 135), + (252, 172, 138), (253, 172, 141), (249, 169, 143), (247, 170, 143), + (243, 163, 142), (240, 154, 143), (238, 145, 144), (238, 138, 150), + (239, 132, 157), (238, 120, 177), (239, 107, 192), (235, 97, 199), + (232, 95, 205), (217, 100, 212), (211, 101, 211), (206, 102, 211), + (187, 99, 194), (164, 94, 176), (136, 89, 153), (112, 93, 129), + (76, 110, 87), (66, 109, 68), (57, 109, 49), (56, 106, 41), + (56, 103, 33), (64, 107, 25), (82, 124, 26), (101, 143, 34), + (122, 168, 55), (146, 188, 98), (147, 188, 106), (149, 189, 115), + (137, 186, 124), (123, 186, 132), (108, 180, 126), (98, 173, 126), + (83, 145, 102), (79, 142, 95), (75, 140, 88), (69, 133, 60), + (71, 134, 45), (92, 131, 31), (119, 133, 22), (148, 143, 22), + (171, 149, 17), (199, 164, 21), (206, 167, 24), (214, 171, 27), + (226, 179, 38), (233, 184, 48), (234, 184, 52), (232, 183, 54), + (239, 183, 56), (240, 184, 61), (241, 185, 66), (238, 186, 74), + (234, 186, 88), (236, 188, 98), (241, 186, 110), (247, 185, 123), + (248, 184, 133), (245, 181, 150), (244, 182, 164), (241, 185, 178), + (237, 187, 190), (224, 186, 193), (208, 180, 199), (195, 168, 197), + (153, 154, 192), (142, 153, 188), (131, 153, 185), (111, 150, 183), + (113, 142, 174), (111, 131, 179), (118, 125, 178), (129, 124, 186), + (135, 130, 196), (159, 142, 197), (181, 154, 207), (205, 166, 208), + (228, 170, 214), (240, 173, 218), (251, 170, 209), (254, 174, 196), + (254, 182, 171), (254, 185, 145), (239, 180, 138), (226, 166, 125), + (220, 160, 110), (219, 160, 89), (233, 169, 53), (230, 173, 42), + (224, 173, 37), (219, 176, 40), (219, 180, 43), (233, 189, 30), + (244, 195, 23), (248, 197, 17), (242, 196, 21), (233, 195, 29), + (227, 191, 45), (228, 177, 65), (231, 158, 78), (229, 143, 92), + (211, 137, 98), (189, 138, 106), (177, 139, 118), (181, 131, 124), + (197, 118, 128), (198, 116, 123), (187, 124, 115), (170, 139, 111), + (158, 153, 108), (160, 157, 103), (166, 160, 95), (173, 167, 92), + (177, 172, 103), (175, 177, 115), (170, 178, 121), (165, 165, 113), + (152, 150, 94), (140, 134, 81), (131, 129, 81), (120, 131, 79), + (111, 134, 71), (95, 129, 57), (79, 117, 38), (71, 113, 34), + (77, 112, 37), (95, 122, 43), (111, 129, 62), (122, 135, 82), + (126, 146, 108), (134, 147, 131), (145, 139, 147), (150, 129, 156), + (154, 117, 158), (150, 116, 162), (141, 121, 159), (130, 121, 157) + ), + +// 546 Elements +((191, 131, 50), (184, 126, 50), (178, 119, 45), (172, 113, 40), + (170, 111, 37), (168, 109, 35), (167, 108, 35), (167, 107, 35), + (169, 108, 39), (163, 115, 50), (158, 122, 62), (144, 131, 78), + (131, 140, 94), (122, 136, 95), (113, 133, 97), (102, 128, 95), + (91, 124, 94), (49, 100, 86), (36, 86, 75), (23, 72, 64), + (16, 58, 52), (9, 44, 41), (7, 42, 38), (5, 40, 35), + (8, 46, 36), (6, 53, 44), (5, 61, 52), (4, 74, 60), + (4, 87, 69), (5, 90, 73), (6, 94, 77), (9, 98, 83), + (10, 100, 88), (15, 120, 104), (24, 132, 117), (34, 145, 131), + (53, 152, 136), (72, 160, 141), (84, 162, 138), (96, 165, 135), + (138, 173, 124), (139, 186, 142), (141, 199, 161), (145, 201, 162), + (149, 204, 163), (153, 199, 155), (158, 195, 147), (135, 190, 153), + (115, 180, 153), (104, 166, 142), (112, 158, 124), (120, 150, 106), + (121, 131, 83), (122, 113, 61), (126, 104, 49), (130, 96, 37), + (145, 82, 9), (140, 77, 6), (135, 72, 4), (127, 66, 3), + (119, 61, 2), (115, 57, 1), (111, 53, 1), (102, 45, 0), + (94, 39, 0), (85, 33, 0), (84, 32, 0), (83, 31, 0), + (82, 31, 0), (82, 31, 0), (81, 32, 0), (83, 34, 0), + (90, 42, 0), (95, 45, 0), (101, 48, 0), (106, 52, 0), + (111, 56, 1), (113, 57, 1), (115, 58, 1), (117, 59, 0), + (118, 58, 0), (114, 54, 1), (103, 51, 1), (93, 49, 1), + (86, 48, 3), (79, 48, 5), (65, 47, 12), (54, 43, 15), + (47, 32, 13), (49, 34, 14), (51, 37, 15), (52, 39, 15), + (54, 42, 16), (64, 45, 17), (77, 45, 13), (89, 43, 6), + (99, 43, 3), (102, 44, 0), (99, 42, 0), (96, 40, 1), + (92, 37, 1), (88, 35, 1), (81, 29, 1), (72, 22, 1), + (61, 13, 1), (60, 11, 1), (59, 10, 1), (59, 11, 1), + (60, 12, 1), (64, 15, 0), (69, 19, 0), (76, 25, 1), + (84, 30, 2), (100, 43, 7), (103, 46, 7), (107, 49, 8), + (113, 55, 7), (117, 59, 6), (120, 61, 6), (124, 65, 9), + (134, 74, 15), (141, 81, 18), (148, 88, 22), (152, 92, 26), + (157, 97, 30), (167, 106, 40), (178, 117, 50), (186, 125, 57), + (190, 128, 58), (188, 123, 52), (186, 121, 51), (185, 120, 50), + (180, 116, 47), (174, 109, 40), (164, 100, 29), (155, 91, 19), + (143, 82, 13), (143, 81, 15), (143, 81, 17), (144, 81, 18), + (145, 82, 19), (145, 84, 19), (146, 87, 20), (151, 90, 23), + (157, 94, 26), (165, 99, 30), (166, 101, 31), (168, 103, 32), + (171, 107, 35), (180, 112, 36), (187, 119, 40), (193, 124, 44), + (199, 132, 55), (200, 133, 55), (201, 134, 56), (202, 135, 56), + (203, 134, 55), (201, 133, 56), (196, 129, 55), (188, 124, 51), + (177, 115, 47), (152, 90, 34), (145, 82, 31), (139, 75, 29), + (123, 62, 22), (106, 50, 18), (88, 39, 12), (70, 27, 7), + (45, 7, 1), (42, 4, 0), (39, 2, 0), (35, 2, 0), + (35, 3, 0), (36, 5, 0), (38, 7, 1), (41, 12, 4), + (40, 19, 13), (42, 32, 26), (42, 53, 42), (46, 75, 60), + (52, 97, 78), (53, 114, 99), (53, 125, 118), (60, 132, 123), + (85, 144, 114), (92, 143, 109), (100, 143, 105), (102, 136, 102), + (107, 119, 88), (114, 101, 66), (119, 85, 41), (126, 73, 20), + (124, 67, 11), (119, 64, 8), (115, 61, 6), (114, 57, 4), + (112, 55, 3), (109, 52, 1), (107, 50, 1), (104, 48, 1), + (101, 43, 2), (98, 38, 2), (93, 33, 1), (86, 27, 1), + (79, 23, 0), (72, 19, 0), (68, 16, 0), (66, 14, 0), + (63, 13, 0), (61, 12, 0), (58, 10, 0), (55, 9, 0), + (56, 9, 0), (56, 11, 0), (57, 15, 3), (53, 20, 6), + (46, 24, 9), (39, 31, 13), (34, 37, 17), (34, 46, 24), + (41, 55, 29), (46, 57, 29), (52, 60, 28), (59, 62, 23), + (61, 65, 23), (75, 67, 24), (90, 66, 20), (104, 64, 16), + (119, 62, 8), (124, 63, 4), (127, 66, 3), (129, 68, 4), + (128, 70, 5), (127, 70, 7), (124, 68, 7), (115, 72, 12), + (103, 79, 22), (87, 86, 32), (74, 90, 42), (69, 79, 40), + (66, 70, 37), (64, 63, 37), (59, 62, 35), (54, 65, 41), + (56, 60, 37), (64, 50, 30), (77, 42, 22), (92, 41, 13), + (106, 46, 13), (119, 58, 15), (132, 70, 19), (145, 83, 25), + (154, 94, 33), (164, 104, 38), (175, 115, 44), (183, 123, 48) + ), + +// 547 Embers +((180, 74, 13), (214, 89, 4), (209, 92, 3), (205, 95, 2), + (187, 87, 2), (169, 80, 2), (157, 73, 1), (145, 67, 1), + (112, 46, 0), (109, 41, 1), (106, 36, 2), (103, 36, 5), + (101, 37, 9), (100, 41, 16), (99, 46, 24), (101, 51, 32), + (103, 56, 40), (102, 84, 67), (105, 96, 79), (109, 108, 91), + (116, 116, 98), (124, 124, 105), (120, 122, 102), (116, 120, 99), + (94, 100, 73), (85, 88, 64), (76, 76, 56), (74, 62, 44), + (72, 48, 33), (78, 44, 29), (84, 40, 26), (94, 37, 22), + (101, 37, 17), (115, 32, 19), (110, 35, 19), (106, 38, 20), + (97, 39, 28), (88, 41, 37), (80, 40, 40), (73, 39, 44), + (60, 43, 57), (57, 41, 59), (55, 40, 62), (55, 41, 61), + (56, 42, 61), (60, 45, 62), (64, 48, 64), (67, 53, 67), + (70, 58, 71), (72, 68, 73), (69, 67, 70), (66, 67, 68), + (61, 62, 59), (57, 58, 50), (53, 56, 45), (50, 55, 41), + (39, 35, 28), (35, 31, 24), (32, 28, 20), (30, 24, 21), + (28, 20, 22), (27, 19, 22), (26, 18, 23), (24, 16, 23), + (22, 16, 22), (25, 15, 19), (28, 15, 18), (31, 15, 18), + (31, 16, 19), (32, 17, 20), (35, 20, 21), (40, 21, 23), + (38, 25, 36), (37, 26, 37), (36, 27, 39), (34, 27, 41), + (33, 27, 43), (31, 26, 41), (30, 25, 40), (27, 23, 35), + (26, 20, 29), (22, 16, 23), (22, 16, 19), (22, 17, 16), + (25, 17, 14), (28, 18, 12), (36, 20, 11), (41, 21, 9), + (53, 27, 5), (57, 27, 5), (62, 28, 5), (62, 27, 6), + (63, 27, 8), (64, 29, 10), (59, 33, 13), (60, 39, 18), + (61, 47, 24), (64, 59, 26), (62, 63, 26), (60, 68, 26), + (60, 68, 25), (61, 68, 25), (64, 64, 22), (72, 58, 17), + (87, 47, 8), (105, 44, 7), (124, 41, 7), (131, 42, 5), + (139, 44, 3), (151, 44, 2), (159, 46, 0), (166, 48, 0), + (169, 51, 0), (161, 49, 1), (157, 47, 1), (153, 46, 1), + (149, 40, 0), (145, 36, 3), (143, 33, 7), (137, 31, 12), + (109, 25, 29), (99, 26, 34), (90, 27, 40), (81, 27, 40), + (73, 27, 41), (54, 25, 45), (38, 23, 44), (33, 21, 41), + (30, 20, 34), (29, 16, 23), (32, 16, 21), (35, 17, 20), + (54, 24, 15), (67, 33, 15), (81, 48, 29), (89, 65, 46), + (123, 96, 61), (126, 109, 77), (130, 122, 93), (130, 126, 101), + (131, 131, 110), (135, 123, 97), (139, 108, 85), (140, 91, 65), + (138, 79, 58), (154, 55, 27), (158, 48, 18), (162, 42, 10), + (165, 35, 7), (165, 35, 1), (162, 33, 2), (158, 31, 0), + (135, 26, 4), (126, 24, 6), (117, 23, 8), (100, 22, 11), + (86, 21, 22), (74, 23, 27), (68, 23, 30), (69, 27, 31), + (77, 33, 38), (92, 56, 59), (97, 64, 62), (102, 72, 66), + (115, 87, 72), (126, 94, 79), (130, 106, 92), (129, 116, 103), + (118, 114, 102), (112, 108, 98), (106, 102, 95), (95, 86, 89), + (81, 73, 76), (67, 59, 65), (53, 46, 52), (43, 34, 44), + (36, 28, 32), (34, 26, 23), (34, 26, 16), (36, 24, 12), + (39, 23, 8), (41, 24, 6), (41, 25, 6), (38, 23, 8), + (33, 14, 9), (31, 13, 11), (29, 13, 13), (25, 14, 18), + (25, 15, 25), (28, 16, 30), (35, 18, 31), (42, 21, 29), + (54, 23, 29), (65, 29, 29), (77, 30, 25), (82, 31, 19), + (84, 28, 16), (79, 28, 12), (76, 26, 10), (67, 24, 8), + (56, 20, 12), (43, 17, 14), (34, 15, 16), (28, 14, 16), + (26, 14, 14), (25, 13, 12), (24, 15, 10), (23, 16, 11), + (22, 14, 9), (24, 13, 10), (23, 14, 9), (20, 15, 11), + (16, 13, 13), (16, 12, 17), (17, 12, 18), (22, 13, 18), + (33, 17, 16), (45, 23, 12), (59, 32, 14), (74, 43, 15), + (90, 57, 18), (104, 74, 27), (113, 88, 44), (117, 93, 47), + (117, 95, 40), (116, 93, 38), (110, 89, 46), (99, 82, 46), + (88, 78, 36), (84, 77, 27), (92, 81, 36), (95, 87, 48), + (98, 96, 61), (98, 107, 68), (112, 113, 80), (132, 112, 82), + (154, 109, 77), (168, 110, 68), (181, 105, 61), (194, 96, 48), + (204, 82, 31), (208, 81, 23), (213, 76, 19), (209, 72, 19), + (201, 62, 12), (185, 61, 12), (174, 58, 10), (158, 54, 13), + (138, 50, 15), (118, 46, 17), (107, 48, 19), (108, 46, 20), + (110, 44, 22), (115, 41, 21), (128, 50, 20), (153, 62, 16) + ), + +// 548 Etomchek-040328-005 +((166, 201, 227), (169, 199, 225), (169, 198, 224), (170, 197, 223), + (167, 197, 224), (165, 197, 225), (164, 197, 225), (164, 197, 226), + (148, 187, 222), (148, 185, 220), (148, 183, 218), (147, 181, 217), + (147, 179, 217), (143, 176, 213), (139, 174, 210), (134, 170, 205), + (130, 167, 201), (107, 142, 173), (100, 132, 158), (93, 122, 144), + (86, 111, 130), (80, 101, 117), (76, 95, 111), (73, 90, 106), + (56, 75, 92), (49, 69, 87), (43, 63, 83), (45, 63, 81), + (47, 64, 80), (50, 66, 82), (54, 68, 84), (61, 76, 92), + (70, 87, 102), (86, 111, 131), (92, 122, 147), (98, 133, 164), + (109, 148, 178), (120, 163, 193), (128, 171, 200), (136, 179, 208), + (167, 205, 228), (177, 213, 232), (188, 221, 237), (190, 224, 241), + (193, 227, 245), (193, 227, 244), (193, 228, 243), (193, 226, 240), + (191, 221, 235), (181, 208, 221), (173, 195, 206), (166, 182, 192), + (153, 167, 176), (141, 152, 161), (134, 144, 153), (127, 137, 145), + (96, 106, 113), (80, 91, 101), (64, 76, 89), (50, 64, 81), + (36, 53, 74), (31, 49, 71), (26, 45, 69), (20, 41, 68), + (18, 40, 69), (21, 46, 78), (22, 50, 85), (24, 55, 93), + (25, 57, 98), (27, 60, 103), (27, 61, 105), (27, 61, 105), + (28, 61, 103), (26, 58, 98), (25, 55, 94), (27, 58, 96), + (29, 61, 99), (31, 63, 101), (33, 65, 104), (39, 70, 107), + (46, 75, 111), (70, 93, 120), (82, 100, 123), (94, 108, 126), + (100, 115, 132), (107, 122, 138), (120, 136, 155), (129, 148, 168), + (139, 165, 194), (143, 171, 201), (147, 177, 209), (147, 177, 210), + (147, 177, 211), (146, 176, 211), (143, 174, 210), (138, 169, 205), + (128, 160, 195), (97, 127, 163), (80, 110, 145), (64, 93, 127), + (57, 85, 118), (51, 78, 110), (40, 65, 96), (33, 56, 86), + (24, 50, 82), (24, 50, 82), (25, 50, 82), (27, 51, 83), + (29, 53, 84), (33, 59, 90), (38, 66, 96), (45, 75, 101), + (52, 88, 113), (64, 114, 146), (66, 119, 153), (69, 125, 161), + (75, 135, 175), (80, 144, 189), (83, 148, 201), (86, 152, 206), + (88, 156, 205), (85, 154, 204), (83, 153, 203), (82, 152, 202), + (81, 151, 201), (79, 149, 202), (75, 145, 204), (70, 137, 202), + (68, 131, 199), (66, 124, 193), (66, 123, 191), (66, 122, 190), + (71, 124, 190), (77, 128, 192), (87, 137, 198), (96, 144, 204), + (111, 157, 213), (114, 158, 213), (118, 160, 214), (118, 160, 212), + (118, 160, 211), (118, 158, 209), (119, 159, 209), (120, 161, 212), + (123, 164, 216), (124, 170, 220), (123, 170, 219), (122, 170, 219), + (120, 170, 218), (118, 169, 217), (117, 170, 216), (117, 173, 217), + (128, 182, 225), (130, 184, 226), (132, 186, 228), (133, 186, 228), + (130, 184, 225), (127, 178, 220), (122, 172, 213), (116, 166, 205), + (115, 162, 200), (116, 156, 193), (115, 154, 190), (115, 152, 188), + (109, 145, 182), (101, 135, 175), (88, 121, 163), (71, 102, 145), + (42, 71, 113), (37, 66, 106), (33, 61, 99), (28, 53, 87), + (25, 46, 76), (24, 43, 71), (22, 40, 64), (19, 34, 54), + (15, 27, 44), (12, 24, 41), (11, 23, 42), (10, 22, 42), + (10, 22, 42), (9, 22, 41), (9, 22, 41), (9, 22, 41), + (8, 17, 32), (10, 19, 35), (12, 22, 39), (18, 30, 51), + (28, 46, 70), (37, 61, 89), (49, 76, 107), (63, 94, 124), + (78, 108, 134), (89, 116, 135), (103, 125, 140), (117, 134, 146), + (133, 149, 158), (148, 165, 173), (163, 180, 191), (178, 198, 209), + (192, 215, 226), (199, 226, 236), (205, 232, 244), (208, 236, 248), + (210, 237, 249), (206, 233, 248), (199, 227, 247), (191, 221, 247), + (182, 216, 244), (170, 208, 240), (157, 198, 238), (144, 190, 235), + (133, 183, 231), (121, 174, 227), (110, 165, 222), (100, 156, 218), + (92, 149, 213), (86, 143, 207), (79, 135, 201), (72, 128, 197), + (68, 125, 194), (65, 122, 194), (63, 123, 195), (62, 123, 197), + (63, 124, 199), (67, 127, 200), (70, 129, 199), (74, 130, 195), + (78, 130, 189), (80, 127, 184), (81, 129, 182), (82, 129, 183), + (81, 129, 184), (82, 130, 185), (83, 132, 187), (86, 135, 189), + (90, 137, 188), (93, 135, 183), (96, 134, 177), (99, 135, 174), + (100, 134, 173), (102, 134, 173), (102, 136, 177), (104, 141, 182), + (107, 148, 189), (112, 153, 195), (117, 157, 197), (121, 161, 200), + (126, 164, 201), (138, 172, 206), (147, 179, 210), (157, 187, 215), + (161, 194, 221), (165, 200, 226), (170, 204, 228), (172, 206, 230) + ), + +// 549 Etomchek-040328-006 +((181, 166, 227), (185, 169, 225), (185, 169, 224), (186, 170, 223), + (184, 167, 224), (182, 165, 225), (182, 164, 225), (182, 164, 226), + (169, 148, 222), (169, 148, 220), (170, 148, 218), (171, 147, 217), + (173, 147, 217), (167, 143, 213), (162, 139, 210), (156, 134, 205), + (151, 130, 201), (126, 107, 173), (116, 100, 158), (106, 93, 144), + (97, 86, 130), (89, 80, 117), (86, 76, 111), (83, 73, 106), + (66, 56, 92), (60, 49, 87), (55, 43, 83), (56, 45, 81), + (57, 47, 80), (60, 50, 82), (64, 54, 84), (71, 61, 92), + (79, 70, 102), (98, 86, 131), (107, 92, 147), (117, 98, 164), + (127, 109, 178), (137, 120, 193), (144, 128, 200), (152, 136, 208), + (179, 167, 228), (187, 177, 232), (196, 188, 237), (199, 190, 241), + (202, 193, 245), (200, 193, 244), (199, 193, 243), (199, 193, 240), + (197, 191, 235), (187, 181, 221), (179, 173, 206), (171, 166, 192), + (158, 153, 176), (146, 141, 161), (139, 134, 153), (132, 127, 145), + (100, 96, 113), (86, 80, 101), (72, 64, 89), (61, 50, 81), + (50, 36, 74), (45, 31, 71), (41, 26, 69), (38, 20, 68), + (37, 18, 69), (43, 21, 78), (46, 22, 85), (49, 24, 93), + (52, 25, 98), (56, 27, 103), (57, 27, 105), (57, 27, 105), + (56, 28, 103), (53, 26, 98), (51, 25, 94), (52, 27, 96), + (54, 29, 99), (56, 31, 101), (59, 33, 104), (64, 39, 107), + (70, 46, 111), (87, 70, 120), (96, 82, 123), (106, 94, 126), + (111, 100, 132), (117, 107, 138), (133, 120, 155), (142, 129, 168), + (158, 139, 194), (163, 143, 201), (168, 147, 209), (169, 147, 210), + (170, 147, 211), (169, 146, 211), (167, 143, 210), (162, 138, 205), + (150, 128, 195), (121, 97, 163), (103, 80, 145), (86, 64, 127), + (79, 57, 118), (72, 51, 110), (60, 40, 96), (53, 33, 86), + (45, 24, 82), (46, 24, 82), (47, 25, 82), (48, 27, 83), + (50, 29, 84), (54, 33, 90), (57, 38, 96), (61, 45, 101), + (66, 52, 113), (80, 64, 146), (83, 66, 153), (87, 69, 161), + (97, 75, 175), (105, 80, 189), (114, 83, 201), (118, 86, 206), + (115, 88, 205), (113, 85, 204), (111, 83, 203), (110, 82, 202), + (109, 81, 201), (110, 79, 202), (109, 75, 204), (112, 70, 202), + (112, 68, 199), (113, 66, 193), (112, 66, 191), (111, 66, 190), + (115, 71, 190), (119, 77, 192), (128, 87, 198), (136, 96, 204), + (148, 111, 213), (151, 114, 213), (155, 118, 214), (153, 118, 212), + (152, 118, 211), (153, 118, 209), (152, 119, 209), (154, 120, 212), + (159, 123, 216), (156, 124, 220), (154, 123, 219), (153, 122, 219), + (149, 120, 218), (148, 118, 217), (145, 117, 216), (142, 117, 217), + (154, 128, 225), (155, 130, 226), (156, 132, 228), (158, 133, 228), + (154, 130, 225), (152, 127, 220), (146, 122, 213), (138, 116, 205), + (138, 115, 200), (139, 116, 193), (138, 115, 190), (138, 115, 188), + (132, 109, 182), (127, 101, 175), (117, 88, 163), (100, 71, 145), + (70, 42, 113), (64, 37, 106), (59, 33, 99), (51, 28, 87), + (45, 25, 76), (43, 24, 71), (38, 22, 64), (32, 19, 54), + (26, 15, 44), (23, 12, 41), (24, 11, 42), (23, 10, 42), + (23, 10, 42), (22, 9, 41), (22, 9, 41), (22, 9, 41), + (18, 8, 32), (21, 10, 35), (24, 12, 39), (32, 18, 51), + (44, 28, 70), (55, 37, 89), (69, 49, 107), (82, 63, 124), + (94, 78, 134), (100, 89, 135), (111, 103, 140), (124, 117, 146), + (138, 133, 158), (151, 148, 173), (169, 163, 191), (183, 178, 209), + (197, 192, 226), (202, 199, 236), (210, 205, 244), (213, 208, 248), + (215, 210, 249), (213, 206, 248), (211, 199, 247), (207, 191, 247), + (199, 182, 244), (189, 170, 240), (183, 157, 238), (173, 144, 235), + (163, 133, 231), (155, 121, 227), (147, 110, 222), (141, 100, 218), + (134, 92, 213), (128, 86, 207), (122, 79, 201), (118, 72, 197), + (114, 68, 194), (112, 65, 194), (111, 63, 195), (111, 62, 197), + (113, 63, 199), (116, 67, 200), (117, 70, 199), (116, 74, 195), + (117, 78, 189), (118, 80, 184), (115, 81, 182), (117, 82, 183), + (117, 81, 184), (118, 82, 185), (119, 83, 187), (120, 86, 189), + (123, 90, 188), (124, 93, 183), (124, 96, 177), (124, 99, 174), + (126, 100, 173), (128, 102, 173), (130, 102, 177), (131, 104, 182), + (133, 107, 189), (138, 112, 195), (142, 117, 197), (146, 121, 200), + (150, 126, 201), (160, 138, 206), (167, 147, 210), (175, 157, 215), + (177, 161, 221), (180, 165, 226), (184, 170, 228), (186, 172, 230) + ), + +// 550 Etomchek-040328-007 +((219, 166, 227), (220, 169, 225), (219, 169, 224), (219, 170, 223), + (219, 167, 224), (219, 165, 225), (219, 164, 225), (220, 164, 226), + (215, 148, 222), (214, 148, 220), (214, 148, 218), (215, 147, 217), + (216, 147, 217), (211, 143, 213), (206, 139, 210), (200, 134, 205), + (195, 130, 201), (167, 107, 173), (152, 100, 158), (137, 93, 144), + (124, 86, 130), (112, 80, 117), (107, 76, 111), (103, 73, 106), + (88, 56, 92), (84, 49, 87), (80, 43, 83), (78, 45, 81), + (77, 47, 80), (80, 50, 82), (83, 54, 84), (90, 61, 92), + (99, 70, 102), (126, 86, 131), (142, 92, 147), (158, 98, 164), + (170, 109, 178), (182, 120, 193), (189, 128, 200), (196, 136, 208), + (217, 167, 228), (221, 177, 232), (226, 188, 237), (230, 190, 241), + (234, 193, 245), (232, 193, 244), (230, 193, 243), (228, 193, 240), + (224, 191, 235), (212, 181, 221), (199, 173, 206), (187, 166, 192), + (173, 153, 176), (159, 141, 161), (151, 134, 153), (143, 127, 145), + (110, 96, 113), (99, 80, 101), (88, 64, 89), (80, 50, 81), + (73, 36, 74), (70, 31, 71), (68, 26, 69), (68, 20, 68), + (69, 18, 69), (78, 21, 78), (85, 22, 85), (92, 24, 93), + (97, 25, 98), (103, 27, 103), (105, 27, 105), (105, 27, 105), + (103, 28, 103), (98, 26, 98), (94, 25, 94), (96, 27, 96), + (98, 29, 99), (100, 31, 101), (103, 33, 104), (106, 39, 107), + (110, 46, 111), (118, 70, 120), (122, 82, 123), (126, 94, 126), + (131, 100, 132), (136, 107, 138), (155, 120, 155), (166, 129, 168), + (192, 139, 194), (199, 143, 201), (206, 147, 209), (207, 147, 210), + (209, 147, 211), (209, 146, 211), (208, 143, 210), (203, 138, 205), + (192, 128, 195), (162, 97, 163), (143, 80, 145), (125, 64, 127), + (117, 57, 118), (109, 51, 110), (95, 40, 96), (86, 33, 86), + (81, 24, 82), (81, 24, 82), (82, 25, 82), (83, 27, 83), + (84, 29, 84), (89, 33, 90), (93, 38, 96), (95, 45, 101), + (104, 52, 113), (131, 64, 146), (137, 66, 153), (144, 69, 161), + (158, 75, 175), (173, 80, 189), (187, 83, 201), (192, 86, 206), + (188, 88, 205), (186, 85, 204), (185, 83, 203), (184, 82, 202), + (183, 81, 201), (186, 79, 202), (189, 75, 204), (193, 70, 202), + (193, 68, 199), (191, 66, 193), (189, 66, 191), (188, 66, 190), + (188, 71, 190), (190, 77, 192), (196, 87, 198), (202, 96, 204), + (212, 111, 213), (213, 114, 213), (214, 118, 214), (212, 118, 212), + (210, 118, 211), (209, 118, 209), (208, 119, 209), (211, 120, 212), + (216, 123, 216), (216, 124, 220), (214, 123, 219), (213, 122, 219), + (210, 120, 218), (209, 118, 217), (206, 117, 216), (204, 117, 217), + (214, 128, 225), (215, 130, 226), (216, 132, 228), (217, 133, 228), + (213, 130, 225), (209, 127, 220), (203, 122, 213), (193, 116, 205), + (190, 115, 200), (187, 116, 193), (185, 115, 190), (183, 115, 188), + (177, 109, 182), (173, 101, 175), (163, 88, 163), (145, 71, 144), + (113, 42, 112), (106, 37, 105), (99, 33, 98), (87, 28, 86), + (76, 25, 75), (71, 24, 69), (64, 22, 64), (54, 19, 54), + (44, 15, 43), (41, 12, 40), (42, 11, 40), (42, 10, 40), + (42, 10, 40), (41, 9, 40), (41, 9, 40), (41, 9, 40), + (32, 8, 30), (35, 10, 33), (39, 12, 37), (51, 18, 48), + (70, 28, 70), (87, 37, 89), (105, 49, 107), (120, 63, 124), + (128, 78, 134), (128, 89, 135), (134, 103, 140), (142, 117, 146), + (153, 133, 158), (167, 148, 173), (187, 163, 191), (203, 178, 209), + (218, 192, 226), (225, 199, 236), (234, 205, 244), (238, 208, 248), + (239, 210, 249), (239, 206, 248), (240, 199, 247), (242, 191, 247), + (237, 182, 244), (232, 170, 240), (233, 157, 238), (229, 144, 235), + (223, 133, 231), (220, 121, 227), (217, 110, 222), (214, 100, 218), + (209, 92, 213), (203, 86, 207), (197, 79, 201), (195, 72, 197), + (192, 68, 194), (192, 65, 194), (193, 63, 195), (195, 62, 197), + (197, 63, 199), (198, 67, 200), (197, 70, 199), (191, 74, 195), + (186, 78, 189), (182, 80, 184), (177, 81, 182), (180, 82, 183), + (181, 81, 184), (182, 82, 185), (184, 83, 187), (184, 86, 189), + (183, 90, 188), (180, 93, 183), (174, 96, 177), (170, 99, 174), + (171, 100, 173), (172, 102, 173), (176, 102, 177), (180, 104, 182), + (184, 107, 189), (190, 112, 195), (192, 117, 197), (195, 121, 200), + (196, 126, 201), (202, 138, 206), (206, 147, 210), (210, 157, 215), + (214, 161, 221), (218, 165, 226), (220, 170, 228), (222, 172, 230) + ), + +// 551 Etomchek-040328-008 +((227, 166, 191), (225, 169, 188), (224, 169, 188), (223, 170, 189), + (224, 167, 188), (225, 165, 187), (225, 164, 187), (226, 164, 187), + (222, 148, 175), (220, 148, 172), (218, 148, 170), (217, 147, 168), + (217, 147, 167), (213, 143, 164), (210, 139, 162), (205, 134, 158), + (201, 130, 155), (173, 107, 130), (158, 100, 121), (144, 93, 113), + (130, 86, 104), (117, 80, 95), (111, 76, 89), (106, 73, 84), + (92, 56, 70), (87, 49, 63), (83, 43, 56), (81, 45, 57), + (80, 47, 58), (82, 50, 60), (84, 54, 63), (92, 61, 71), + (102, 70, 82), (131, 86, 103), (147, 92, 112), (164, 98, 121), + (178, 109, 136), (193, 120, 151), (200, 128, 159), (208, 136, 167), + (228, 167, 195), (232, 177, 203), (237, 188, 211), (241, 190, 214), + (245, 193, 218), (244, 193, 219), (243, 193, 220), (240, 193, 217), + (235, 191, 214), (221, 181, 201), (206, 173, 189), (192, 166, 178), + (176, 153, 163), (161, 141, 148), (153, 134, 141), (145, 127, 134), + (113, 96, 104), (101, 80, 87), (89, 64, 71), (81, 50, 59), + (74, 36, 47), (71, 31, 42), (69, 26, 38), (68, 20, 32), + (69, 18, 31), (78, 21, 36), (85, 22, 39), (93, 24, 43), + (98, 25, 45), (103, 27, 47), (105, 27, 47), (105, 27, 47), + (103, 28, 48), (98, 26, 45), (94, 25, 43), (96, 27, 46), + (99, 29, 49), (101, 31, 51), (104, 33, 53), (107, 39, 58), + (111, 46, 64), (120, 70, 85), (123, 82, 93), (126, 94, 102), + (132, 100, 109), (138, 107, 117), (155, 120, 129), (168, 129, 141), + (194, 139, 156), (201, 143, 161), (209, 147, 167), (210, 147, 166), + (211, 147, 166), (211, 146, 166), (210, 143, 163), (205, 138, 158), + (195, 128, 149), (163, 97, 116), (145, 80, 99), (127, 64, 83), + (118, 57, 75), (110, 51, 67), (96, 40, 56), (86, 33, 47), + (82, 24, 40), (82, 24, 40), (82, 25, 40), (83, 27, 41), + (84, 29, 43), (90, 33, 49), (96, 38, 56), (101, 45, 65), + (113, 52, 77), (146, 64, 101), (153, 66, 105), (161, 69, 110), + (175, 75, 118), (189, 80, 125), (201, 83, 128), (206, 86, 132), + (205, 88, 137), (204, 85, 135), (203, 83, 133), (202, 82, 132), + (201, 81, 131), (202, 79, 128), (204, 75, 124), (202, 70, 114), + (199, 68, 109), (193, 66, 102), (191, 66, 101), (190, 66, 101), + (190, 71, 105), (192, 77, 110), (198, 87, 118), (204, 96, 127), + (213, 111, 140), (213, 114, 142), (214, 118, 144), (212, 118, 144), + (211, 118, 144), (209, 118, 142), (209, 119, 145), (212, 120, 146), + (216, 123, 148), (220, 124, 153), (219, 123, 153), (219, 122, 154), + (218, 120, 154), (217, 118, 153), (216, 117, 153), (217, 117, 157), + (225, 128, 165), (226, 130, 168), (228, 132, 171), (228, 133, 170), + (225, 130, 168), (220, 127, 163), (213, 122, 157), (205, 116, 152), + (200, 115, 148), (193, 116, 143), (190, 115, 141), (188, 115, 139), + (182, 109, 133), (175, 101, 123), (163, 88, 108), (145, 71, 89), + (113, 42, 59), (106, 37, 54), (99, 33, 49), (87, 28, 42), + (76, 25, 37), (71, 24, 33), (64, 22, 33), (54, 19, 28), + (44, 15, 21), (41, 12, 18), (42, 11, 17), (42, 10, 16), + (42, 10, 16), (41, 9, 16), (41, 9, 16), (41, 9, 16), + (32, 8, 12), (35, 10, 14), (39, 12, 17), (51, 18, 24), + (70, 28, 39), (89, 37, 52), (107, 49, 66), (124, 63, 83), + (134, 78, 98), (135, 89, 108), (140, 103, 119), (146, 117, 129), + (158, 133, 145), (173, 148, 161), (191, 163, 175), (209, 178, 193), + (226, 192, 209), (236, 199, 220), (244, 205, 225), (248, 208, 229), + (249, 210, 230), (248, 206, 227), (247, 199, 219), (247, 191, 210), + (244, 182, 206), (240, 170, 197), (238, 157, 184), (235, 144, 175), + (231, 133, 167), (227, 121, 156), (222, 110, 146), (218, 100, 135), + (213, 92, 128), (207, 86, 122), (201, 79, 116), (197, 72, 107), + (194, 68, 104), (194, 65, 101), (195, 63, 100), (197, 62, 100), + (199, 63, 101), (200, 67, 105), (199, 70, 106), (195, 74, 110), + (189, 78, 111), (184, 80, 109), (182, 81, 113), (183, 82, 112), + (184, 81, 112), (185, 82, 113), (187, 83, 114), (189, 86, 119), + (188, 90, 121), (183, 93, 120), (177, 96, 120), (174, 99, 123), + (173, 100, 122), (173, 102, 122), (177, 102, 123), (182, 104, 127), + (189, 107, 134), (195, 112, 140), (197, 117, 144), (200, 121, 147), + (201, 126, 151), (206, 138, 161), (210, 147, 168), (215, 157, 177), + (221, 161, 184), (226, 165, 190), (228, 170, 192), (230, 172, 194) + ), + +// 552 Etomchek-040328-009 +((227, 180, 166), (225, 186, 169), (224, 185, 169), (223, 185, 170), + (224, 183, 167), (225, 181, 165), (225, 181, 164), (226, 181, 164), + (222, 168, 148), (220, 169, 148), (218, 170, 148), (217, 171, 147), + (217, 172, 147), (213, 167, 143), (210, 162, 139), (205, 156, 134), + (201, 150, 130), (173, 126, 107), (158, 115, 100), (144, 105, 93), + (130, 96, 86), (117, 88, 80), (111, 85, 76), (106, 82, 73), + (92, 65, 56), (87, 60, 49), (83, 55, 43), (81, 55, 45), + (80, 56, 47), (82, 60, 50), (84, 64, 54), (92, 70, 61), + (102, 78, 70), (131, 97, 86), (147, 107, 92), (164, 117, 98), + (178, 126, 109), (193, 136, 120), (200, 143, 128), (208, 150, 136), + (228, 178, 167), (232, 187, 177), (237, 196, 188), (241, 198, 190), + (245, 201, 193), (244, 199, 193), (243, 198, 193), (240, 200, 193), + (235, 196, 191), (221, 187, 181), (206, 179, 173), (192, 171, 166), + (176, 158, 153), (161, 146, 141), (153, 139, 134), (145, 132, 127), + (113, 99, 96), (101, 85, 80), (89, 72, 64), (81, 60, 50), + (74, 48, 36), (71, 44, 31), (69, 41, 26), (68, 37, 20), + (69, 36, 18), (78, 42, 21), (85, 45, 22), (93, 48, 24), + (98, 51, 25), (103, 55, 27), (105, 55, 27), (105, 55, 27), + (103, 55, 28), (98, 52, 26), (94, 50, 25), (96, 51, 27), + (99, 53, 29), (101, 55, 31), (104, 58, 33), (107, 63, 39), + (111, 69, 46), (120, 87, 70), (123, 96, 82), (126, 106, 94), + (132, 111, 100), (138, 116, 107), (155, 133, 120), (168, 141, 129), + (194, 157, 139), (201, 162, 143), (209, 167, 147), (210, 167, 147), + (211, 168, 147), (211, 168, 146), (210, 165, 143), (205, 160, 138), + (195, 149, 128), (163, 120, 97), (145, 102, 80), (127, 85, 64), + (118, 78, 57), (110, 71, 51), (96, 59, 40), (86, 52, 33), + (82, 44, 24), (82, 45, 24), (82, 46, 25), (83, 47, 27), + (84, 49, 29), (90, 53, 33), (96, 56, 38), (101, 60, 45), + (113, 65, 52), (146, 79, 64), (153, 82, 66), (161, 86, 69), + (175, 95, 75), (189, 104, 80), (201, 112, 83), (206, 116, 86), + (205, 113, 88), (204, 111, 85), (203, 109, 83), (202, 108, 82), + (201, 107, 81), (202, 108, 79), (204, 107, 75), (202, 110, 70), + (199, 109, 68), (193, 110, 66), (191, 109, 66), (190, 109, 66), + (190, 113, 71), (192, 117, 77), (198, 126, 87), (204, 134, 96), + (213, 147, 111), (213, 150, 114), (214, 153, 118), (212, 152, 118), + (211, 151, 118), (209, 151, 118), (209, 151, 119), (212, 152, 120), + (216, 157, 123), (220, 156, 124), (219, 153, 123), (219, 151, 122), + (218, 148, 120), (217, 146, 118), (216, 143, 117), (217, 140, 117), + (225, 152, 128), (226, 153, 130), (228, 155, 132), (228, 157, 133), + (225, 152, 130), (220, 150, 127), (213, 145, 122), (205, 137, 116), + (200, 136, 115), (193, 138, 116), (190, 137, 115), (188, 137, 115), + (182, 131, 109), (175, 126, 101), (163, 115, 88), (145, 99, 71), + (113, 69, 42), (106, 63, 37), (99, 58, 33), (87, 50, 28), + (76, 44, 25), (71, 44, 24), (64, 37, 22), (54, 31, 19), + (44, 26, 15), (41, 23, 12), (42, 24, 11), (42, 23, 10), + (42, 23, 10), (41, 21, 9), (41, 21, 9), (41, 21, 9), + (32, 18, 8), (35, 20, 10), (39, 23, 12), (51, 32, 18), + (70, 43, 28), (89, 54, 37), (107, 68, 49), (124, 81, 63), + (134, 93, 78), (135, 99, 89), (140, 110, 103), (146, 124, 117), + (158, 137, 133), (173, 151, 148), (191, 169, 163), (209, 183, 178), + (226, 197, 192), (236, 202, 199), (244, 211, 205), (248, 213, 208), + (249, 216, 210), (248, 213, 206), (247, 210, 199), (247, 208, 191), + (244, 198, 182), (240, 188, 170), (238, 182, 157), (235, 171, 144), + (231, 161, 133), (227, 153, 121), (222, 146, 110), (218, 139, 100), + (213, 132, 92), (207, 126, 86), (201, 120, 79), (197, 116, 72), + (194, 112, 68), (194, 110, 65), (195, 109, 63), (197, 109, 62), + (199, 111, 63), (200, 113, 67), (199, 115, 70), (195, 114, 74), + (189, 115, 78), (184, 116, 80), (182, 113, 81), (183, 116, 82), + (184, 115, 81), (185, 116, 82), (187, 118, 83), (189, 119, 86), + (188, 121, 90), (183, 123, 93), (177, 123, 96), (174, 123, 99), + (173, 124, 100), (173, 127, 102), (177, 128, 102), (182, 130, 104), + (189, 132, 107), (195, 137, 112), (197, 141, 117), (200, 145, 121), + (201, 149, 126), (206, 159, 138), (210, 166, 147), (215, 174, 157), + (221, 176, 161), (226, 179, 165), (228, 185, 170), (230, 187, 172) + ), + +// 553 Etomchek-040328-010 +((205, 227, 166), (201, 225, 169), (201, 224, 169), (201, 223, 170), + (201, 224, 167), (201, 225, 165), (201, 225, 164), (201, 226, 164), + (193, 222, 148), (190, 220, 148), (187, 218, 148), (185, 217, 147), + (183, 217, 147), (180, 213, 143), (178, 210, 139), (175, 205, 134), + (172, 201, 130), (146, 173, 107), (135, 158, 100), (125, 144, 93), + (114, 130, 86), (103, 117, 80), (97, 111, 76), (92, 106, 73), + (78, 92, 56), (71, 87, 49), (65, 83, 43), (65, 81, 45), + (66, 80, 47), (68, 82, 50), (70, 84, 54), (78, 92, 61), + (89, 102, 70), (114, 131, 86), (125, 147, 92), (137, 164, 98), + (152, 178, 109), (168, 193, 120), (176, 200, 128), (184, 208, 136), + (209, 228, 167), (216, 232, 177), (223, 237, 188), (227, 241, 190), + (231, 245, 193), (231, 244, 193), (232, 243, 193), (228, 240, 193), + (224, 235, 191), (211, 221, 181), (197, 206, 173), (184, 192, 166), + (168, 176, 153), (153, 161, 141), (145, 153, 134), (138, 145, 127), + (108, 113, 96), (92, 101, 80), (77, 89, 64), (66, 81, 50), + (56, 74, 36), (52, 71, 31), (48, 69, 26), (44, 68, 20), + (43, 69, 18), (49, 78, 21), (54, 85, 22), (59, 93, 24), + (62, 98, 25), (65, 103, 27), (66, 105, 27), (66, 105, 27), + (65, 103, 28), (62, 98, 26), (59, 94, 25), (62, 96, 27), + (65, 99, 29), (67, 101, 31), (69, 104, 33), (74, 107, 39), + (79, 111, 46), (97, 120, 70), (103, 123, 82), (110, 126, 94), + (117, 132, 100), (125, 138, 107), (138, 155, 120), (151, 168, 129), + (168, 194, 139), (174, 201, 143), (181, 209, 147), (181, 210, 147), + (181, 211, 147), (181, 211, 146), (179, 210, 143), (174, 205, 138), + (165, 195, 128), (131, 163, 97), (114, 145, 80), (97, 127, 64), + (89, 118, 57), (81, 110, 51), (69, 96, 40), (59, 86, 33), + (54, 82, 24), (53, 82, 24), (53, 82, 25), (54, 83, 27), + (56, 84, 29), (62, 90, 33), (70, 96, 38), (78, 101, 45), + (92, 113, 52), (120, 146, 64), (126, 153, 66), (132, 161, 69), + (142, 175, 75), (151, 189, 80), (156, 201, 83), (160, 206, 86), + (164, 205, 88), (162, 204, 85), (161, 203, 83), (160, 202, 82), + (159, 201, 81), (157, 202, 79), (155, 204, 75), (145, 202, 70), + (140, 199, 68), (132, 193, 66), (131, 191, 66), (130, 190, 66), + (133, 190, 71), (136, 192, 77), (144, 198, 87), (152, 204, 96), + (164, 213, 111), (165, 213, 114), (166, 214, 118), (166, 212, 118), + (166, 211, 118), (164, 209, 118), (166, 209, 119), (168, 212, 120), + (170, 216, 123), (175, 220, 124), (176, 219, 123), (177, 219, 122), + (177, 218, 120), (176, 217, 118), (177, 216, 117), (181, 217, 117), + (188, 225, 128), (190, 226, 130), (193, 228, 132), (192, 228, 133), + (190, 225, 130), (185, 220, 127), (178, 213, 122), (173, 205, 116), + (168, 200, 115), (161, 193, 116), (158, 190, 115), (156, 188, 115), + (150, 182, 109), (141, 175, 101), (125, 163, 88), (107, 145, 71), + (76, 113, 42), (70, 106, 37), (65, 99, 33), (56, 87, 28), + (49, 76, 25), (44, 71, 24), (43, 64, 22), (36, 54, 19), + (28, 44, 15), (25, 41, 12), (24, 42, 11), (23, 42, 10), + (23, 42, 10), (24, 41, 9), (24, 41, 9), (24, 41, 9), + (18, 32, 8), (20, 35, 10), (23, 39, 12), (31, 51, 18), + (49, 70, 28), (64, 89, 37), (80, 107, 49), (97, 124, 63), + (112, 134, 78), (119, 135, 89), (128, 140, 103), (135, 146, 117), + (151, 158, 133), (166, 173, 148), (181, 191, 163), (200, 209, 178), + (217, 226, 192), (229, 236, 199), (234, 244, 205), (238, 248, 208), + (239, 249, 210), (237, 248, 206), (231, 247, 199), (223, 247, 191), + (221, 244, 182), (214, 240, 170), (203, 238, 157), (196, 235, 144), + (190, 231, 133), (181, 227, 121), (172, 222, 110), (163, 218, 100), + (157, 213, 92), (151, 207, 86), (144, 201, 79), (137, 197, 72), + (133, 194, 68), (132, 194, 65), (131, 195, 63), (132, 197, 62), + (133, 199, 63), (136, 200, 67), (137, 199, 70), (139, 195, 74), + (137, 189, 78), (134, 184, 80), (137, 182, 81), (136, 183, 82), + (136, 184, 81), (137, 185, 82), (139, 187, 83), (143, 189, 86), + (144, 188, 90), (141, 183, 93), (139, 177, 96), (140, 174, 99), + (139, 173, 100), (139, 173, 102), (141, 177, 102), (146, 182, 104), + (154, 189, 107), (159, 195, 112), (162, 197, 117), (166, 200, 121), + (169, 201, 126), (177, 206, 138), (183, 210, 147), (191, 215, 157), + (198, 221, 161), (204, 226, 165), (206, 228, 170), (208, 230, 172) + ), + +// 554 Etomchek-040328-011 +((166, 227, 182), (169, 225, 188), (169, 224, 187), (170, 223, 187), + (167, 224, 185), (165, 225, 183), (164, 225, 183), (164, 226, 183), + (148, 222, 170), (148, 220, 171), (148, 218, 173), (147, 217, 173), + (147, 217, 174), (143, 213, 169), (139, 210, 164), (134, 205, 158), + (130, 201, 153), (107, 173, 128), (100, 158, 117), (93, 144, 107), + (86, 130, 98), (80, 117, 90), (76, 111, 86), (73, 106, 83), + (56, 92, 66), (49, 87, 61), (43, 83, 56), (45, 81, 56), + (47, 80, 57), (50, 82, 61), (54, 84, 65), (61, 92, 71), + (70, 102, 79), (86, 131, 99), (92, 147, 109), (98, 164, 119), + (109, 178, 128), (120, 193, 138), (128, 200, 145), (136, 208, 153), + (167, 228, 180), (177, 232, 189), (188, 237, 198), (190, 241, 200), + (193, 245, 203), (193, 244, 201), (193, 243, 200), (193, 240, 201), + (191, 235, 198), (181, 221, 188), (173, 206, 179), (166, 192, 171), + (153, 176, 159), (141, 161, 147), (134, 153, 139), (127, 145, 132), + (96, 113, 100), (80, 101, 86), (64, 89, 73), (50, 81, 61), + (36, 74, 50), (31, 71, 46), (26, 69, 42), (20, 68, 39), + (18, 69, 38), (21, 78, 43), (22, 85, 46), (24, 93, 50), + (25, 98, 53), (27, 103, 57), (27, 105, 58), (27, 105, 58), + (28, 103, 58), (26, 98, 55), (25, 94, 52), (27, 96, 54), + (29, 99, 56), (31, 101, 58), (33, 104, 60), (39, 107, 65), + (46, 111, 71), (70, 120, 88), (82, 123, 97), (94, 126, 107), + (100, 132, 112), (107, 138, 117), (120, 155, 134), (129, 168, 143), + (139, 194, 159), (143, 201, 164), (147, 209, 169), (147, 210, 170), + (147, 211, 171), (146, 211, 170), (143, 210, 168), (138, 205, 163), + (128, 195, 152), (97, 163, 122), (80, 145, 104), (64, 127, 87), + (57, 118, 80), (51, 110, 73), (40, 96, 61), (33, 86, 54), + (24, 82, 46), (24, 82, 46), (25, 82, 47), (27, 83, 49), + (29, 84, 51), (33, 90, 55), (38, 96, 58), (45, 101, 62), + (52, 113, 67), (64, 146, 82), (66, 153, 85), (69, 161, 89), + (75, 175, 98), (80, 189, 107), (83, 201, 116), (86, 206, 120), + (88, 205, 117), (85, 204, 115), (83, 203, 113), (82, 202, 112), + (81, 201, 111), (79, 202, 112), (75, 204, 111), (70, 202, 114), + (68, 199, 114), (66, 193, 115), (66, 191, 114), (66, 190, 113), + (71, 190, 117), (77, 192, 121), (87, 198, 130), (96, 204, 137), + (111, 213, 150), (114, 213, 153), (118, 214, 157), (118, 212, 155), + (118, 211, 154), (118, 209, 155), (119, 209, 154), (120, 212, 155), + (123, 216, 160), (124, 220, 159), (123, 219, 156), (122, 219, 154), + (120, 218, 151), (118, 217, 149), (117, 216, 147), (117, 217, 144), + (128, 225, 156), (130, 226, 157), (132, 228, 158), (133, 228, 160), + (130, 225, 155), (127, 220, 153), (122, 213, 148), (116, 205, 140), + (115, 200, 139), (116, 193, 140), (115, 190, 139), (115, 188, 139), + (109, 182, 133), (101, 175, 128), (88, 163, 118), (71, 145, 102), + (42, 113, 71), (37, 106, 65), (33, 99, 60), (28, 87, 52), + (25, 76, 46), (24, 71, 46), (22, 64, 38), (19, 54, 33), + (15, 44, 27), (12, 41, 24), (11, 42, 25), (10, 42, 25), + (10, 42, 25), (9, 41, 22), (9, 41, 22), (9, 41, 22), + (8, 32, 19), (10, 35, 21), (12, 39, 24), (18, 51, 34), + (28, 70, 44), (37, 89, 56), (49, 107, 70), (63, 124, 83), + (78, 134, 95), (89, 135, 100), (103, 140, 112), (117, 146, 125), + (133, 158, 138), (148, 173, 152), (163, 191, 170), (178, 209, 184), + (192, 226, 198), (199, 236, 203), (205, 244, 212), (208, 248, 214), + (210, 249, 217), (206, 248, 214), (199, 247, 211), (191, 247, 210), + (182, 244, 200), (170, 240, 190), (157, 238, 184), (144, 235, 175), + (133, 231, 164), (121, 227, 156), (110, 222, 149), (100, 218, 143), + (92, 213, 136), (86, 207, 130), (79, 201, 124), (72, 197, 120), + (68, 194, 116), (65, 194, 114), (63, 195, 114), (62, 197, 114), + (63, 199, 115), (67, 200, 118), (70, 199, 119), (74, 195, 118), + (78, 189, 119), (80, 184, 120), (81, 182, 116), (82, 183, 119), + (81, 184, 119), (82, 185, 120), (83, 187, 121), (86, 189, 122), + (90, 188, 124), (93, 183, 126), (96, 177, 126), (99, 174, 125), + (100, 173, 127), (102, 173, 129), (102, 177, 131), (104, 182, 133), + (107, 189, 134), (112, 195, 140), (117, 197, 144), (121, 200, 147), + (126, 201, 151), (138, 206, 161), (147, 210, 168), (157, 215, 176), + (161, 221, 178), (165, 226, 181), (170, 228, 187), (172, 230, 189) + ), + +// 555 Evening_Sunshine +((24, 79, 66), (49, 87, 56), (53, 88, 53), (57, 90, 51), + (64, 97, 56), (72, 104, 62), (80, 108, 62), (89, 112, 63), + (113, 122, 57), (110, 117, 54), (108, 112, 52), (99, 105, 48), + (90, 98, 45), (84, 91, 39), (79, 85, 33), (75, 80, 29), + (71, 76, 25), (55, 53, 17), (50, 53, 19), (46, 53, 21), + (48, 58, 25), (51, 63, 29), (51, 63, 30), (52, 63, 32), + (58, 78, 53), (54, 91, 66), (51, 104, 80), (41, 102, 88), + (32, 100, 97), (27, 96, 99), (23, 93, 102), (16, 88, 106), + (13, 91, 108), (18, 99, 110), (30, 100, 105), (42, 102, 100), + (62, 106, 89), (82, 110, 78), (93, 115, 72), (105, 120, 66), + (153, 137, 50), (172, 144, 41), (192, 152, 32), (202, 149, 21), + (213, 147, 11), (216, 145, 10), (219, 144, 9), (221, 142, 11), + (224, 136, 12), (209, 112, 5), (192, 95, 4), (175, 79, 4), + (165, 67, 5), (156, 56, 6), (153, 57, 6), (150, 59, 7), + (134, 73, 8), (140, 85, 6), (146, 97, 5), (158, 117, 5), + (170, 138, 5), (175, 146, 7), (180, 155, 9), (196, 172, 8), + (206, 178, 8), (200, 178, 15), (183, 168, 26), (166, 159, 37), + (155, 154, 43), (144, 149, 49), (123, 140, 62), (100, 133, 74), + (61, 117, 93), (47, 110, 97), (33, 104, 102), (29, 102, 104), + (25, 100, 106), (24, 100, 105), (23, 100, 105), (18, 98, 102), + (14, 93, 99), (15, 93, 99), (15, 94, 101), (16, 95, 103), + (14, 92, 102), (12, 90, 101), (9, 86, 101), (10, 85, 102), + (18, 89, 95), (28, 89, 88), (39, 89, 81), (48, 90, 77), + (57, 91, 74), (76, 92, 66), (98, 98, 56), (115, 102, 47), + (136, 107, 39), (166, 124, 30), (178, 129, 24), (190, 134, 18), + (192, 133, 15), (195, 133, 12), (196, 133, 13), (188, 136, 16), + (165, 142, 21), (150, 135, 23), (135, 129, 26), (126, 123, 29), + (117, 118, 32), (95, 108, 35), (78, 100, 39), (62, 90, 38), + (42, 77, 37), (13, 48, 32), (9, 44, 30), (5, 40, 28), + (3, 31, 23), (1, 24, 19), (0, 18, 18), (0, 15, 16), + (1, 19, 22), (1, 21, 26), (2, 24, 31), (2, 25, 31), + (2, 26, 32), (2, 26, 32), (1, 27, 31), (2, 28, 30), + (3, 27, 30), (3, 28, 32), (2, 28, 34), (2, 29, 36), + (2, 31, 39), (4, 36, 41), (4, 40, 44), (5, 44, 49), + (3, 47, 59), (4, 50, 62), (6, 54, 65), (6, 55, 67), + (6, 57, 69), (6, 60, 77), (4, 59, 84), (6, 60, 91), + (9, 66, 95), (12, 77, 107), (10, 79, 109), (9, 81, 111), + (9, 81, 112), (15, 81, 106), (23, 80, 99), (40, 78, 84), + (76, 72, 58), (83, 71, 51), (91, 71, 44), (102, 74, 41), + (109, 80, 40), (113, 85, 47), (113, 90, 56), (109, 93, 60), + (106, 98, 66), (96, 107, 71), (96, 107, 72), (97, 108, 74), + (99, 107, 74), (103, 108, 68), (106, 111, 58), (112, 111, 51), + (120, 111, 48), (117, 110, 48), (115, 110, 49), (103, 107, 55), + (88, 104, 64), (70, 100, 76), (56, 99, 91), (43, 99, 103), + (31, 97, 111), (25, 96, 116), (25, 94, 115), (37, 100, 107), + (56, 109, 99), (74, 123, 88), (96, 139, 78), (110, 149, 70), + (134, 157, 50), (135, 155, 50), (136, 154, 50), (136, 156, 52), + (130, 157, 62), (119, 154, 72), (106, 152, 80), (88, 140, 93), + (68, 129, 105), (50, 123, 117), (37, 120, 128), (30, 124, 135), + (29, 125, 139), (26, 122, 139), (25, 121, 140), (22, 121, 143), + (24, 126, 144), (27, 131, 145), (28, 132, 140), (38, 130, 131), + (51, 129, 123), (76, 129, 109), (102, 133, 98), (124, 136, 85), + (144, 135, 69), (163, 137, 57), (188, 139, 41), (212, 141, 30), + (227, 141, 20), (232, 134, 14), (221, 120, 13), (200, 110, 10), + (176, 96, 11), (149, 84, 10), (128, 71, 8), (105, 49, 7), + (79, 35, 5), (53, 20, 6), (31, 12, 6), (16, 7, 5), + (10, 2, 4), (12, 2, 3), (20, 5, 2), (32, 9, 2), + (51, 15, 3), (72, 23, 4), (91, 33, 6), (116, 48, 8), + (137, 61, 7), (162, 74, 8), (188, 82, 11), (202, 88, 11), + (213, 95, 13), (214, 94, 9), (200, 93, 6), (187, 82, 7), + (164, 69, 7), (139, 61, 12), (119, 53, 19), (94, 48, 27), + (71, 44, 36), (47, 37, 45), (25, 36, 53), (13, 41, 63), + (6, 47, 75), (4, 54, 82), (5, 61, 88), (8, 65, 88), + (8, 61, 80), (7, 60, 74), (8, 60, 67), (11, 65, 64) + ), + +// 556 Evensong +((26, 31, 51), (23, 27, 42), (18, 23, 36), (14, 19, 31), + (14, 18, 29), (15, 17, 28), (14, 16, 26), (13, 15, 24), + (8, 10, 15), (6, 7, 12), (4, 5, 10), (5, 7, 12), + (6, 9, 15), (7, 11, 18), (9, 14, 22), (10, 16, 24), + (11, 18, 27), (14, 21, 31), (16, 22, 32), (18, 24, 34), + (24, 29, 34), (31, 34, 35), (34, 37, 38), (37, 41, 41), + (62, 62, 51), (70, 70, 61), (79, 79, 72), (81, 84, 73), + (84, 89, 75), (80, 86, 76), (76, 83, 77), (69, 75, 75), + (55, 62, 67), (34, 41, 49), (28, 33, 44), (22, 26, 40), + (20, 24, 37), (18, 22, 34), (17, 22, 33), (17, 22, 33), + (18, 24, 35), (19, 26, 37), (21, 28, 39), (22, 29, 42), + (24, 30, 46), (24, 31, 47), (24, 32, 48), (24, 33, 50), + (25, 33, 50), (21, 29, 45), (20, 28, 42), (20, 27, 40), + (18, 25, 38), (17, 24, 36), (16, 23, 35), (16, 23, 35), + (17, 22, 33), (17, 21, 33), (18, 21, 33), (18, 20, 32), + (18, 20, 32), (17, 20, 31), (16, 20, 31), (14, 19, 31), + (13, 19, 31), (6, 11, 22), (4, 8, 18), (3, 6, 14), + (1, 4, 11), (0, 2, 9), (0, 0, 7), (2, 2, 9), + (8, 10, 22), (13, 16, 29), (19, 23, 36), (22, 27, 43), + (26, 32, 51), (27, 34, 53), (29, 36, 55), (30, 38, 56), + (31, 37, 58), (31, 39, 57), (30, 37, 55), (29, 36, 54), + (28, 35, 53), (28, 35, 53), (27, 34, 53), (26, 33, 52), + (24, 29, 49), (21, 26, 45), (19, 23, 42), (16, 20, 38), + (14, 18, 34), (10, 12, 25), (10, 11, 20), (13, 16, 14), + (22, 22, 15), (55, 58, 50), (82, 84, 69), (110, 110, 89), + (127, 129, 109), (145, 149, 130), (182, 186, 166), (206, 207, 174), + (229, 233, 197), (220, 223, 186), (212, 214, 175), (202, 204, 165), + (193, 194, 156), (164, 163, 130), (144, 144, 121), (137, 137, 118), + (133, 132, 117), (139, 137, 112), (143, 142, 113), (148, 148, 115), + (154, 157, 116), (148, 148, 108), (133, 132, 101), (116, 120, 95), + (69, 70, 65), (55, 58, 59), (41, 46, 54), (37, 43, 53), + (34, 40, 52), (32, 37, 54), (35, 41, 56), (41, 46, 59), + (46, 49, 65), (58, 60, 64), (61, 63, 63), (64, 67, 63), + (65, 68, 61), (63, 68, 56), (61, 67, 51), (55, 59, 44), + (40, 44, 35), (33, 36, 31), (26, 29, 28), (23, 27, 28), + (21, 25, 29), (19, 24, 32), (19, 23, 33), (18, 24, 35), + (18, 25, 36), (24, 28, 39), (27, 31, 41), (30, 34, 43), + (35, 39, 45), (42, 45, 48), (49, 49, 54), (49, 55, 59), + (51, 56, 71), (49, 56, 72), (47, 56, 74), (45, 56, 78), + (43, 53, 80), (43, 53, 80), (43, 53, 80), (48, 60, 80), + (66, 74, 78), (94, 100, 85), (105, 110, 85), (116, 120, 86), + (126, 125, 83), (119, 120, 81), (107, 108, 76), (91, 92, 68), + (48, 51, 41), (40, 43, 38), (33, 36, 36), (26, 28, 28), + (18, 20, 20), (13, 16, 20), (11, 14, 21), (10, 13, 19), + (12, 15, 22), (15, 18, 27), (17, 21, 31), (20, 24, 35), + (22, 27, 38), (24, 28, 43), (25, 31, 44), (26, 33, 45), + (31, 37, 44), (32, 38, 43), (34, 40, 43), (37, 42, 42), + (40, 44, 43), (41, 44, 44), (38, 41, 45), (37, 40, 46), + (35, 39, 49), (32, 37, 51), (31, 37, 54), (33, 40, 60), + (36, 44, 66), (37, 46, 70), (38, 48, 72), (38, 47, 70), + (35, 44, 65), (31, 38, 57), (23, 29, 45), (17, 20, 33), + (12, 13, 22), (6, 7, 14), (3, 2, 8), (2, 1, 5), + (3, 3, 5), (6, 7, 10), (7, 10, 15), (9, 14, 17), + (11, 18, 22), (13, 19, 27), (14, 20, 27), (13, 20, 28), + (14, 20, 30), (16, 20, 33), (16, 22, 35), (17, 23, 37), + (19, 25, 39), (19, 25, 40), (19, 26, 40), (21, 27, 38), + (21, 27, 37), (20, 27, 37), (20, 27, 35), (20, 26, 34), + (19, 27, 35), (18, 26, 35), (18, 25, 35), (18, 25, 35), + (20, 26, 35), (22, 27, 34), (23, 26, 34), (21, 25, 31), + (20, 23, 28), (20, 22, 26), (18, 20, 26), (15, 19, 25), + (15, 19, 25), (16, 19, 27), (16, 18, 28), (16, 18, 29), + (16, 19, 29), (17, 19, 30), (17, 19, 31), (17, 20, 32), + (19, 22, 34), (21, 23, 36), (21, 26, 39), (24, 29, 44), + (28, 32, 50), (32, 36, 57), (38, 42, 63), (32, 38, 56) + ), + +// 557 Exceding_Expectations +((111, 93, 84), (86, 52, 41), (85, 46, 35), (85, 41, 29), + (103, 54, 35), (121, 67, 41), (127, 73, 44), (134, 79, 47), + (166, 111, 85), (176, 131, 100), (186, 151, 115), (183, 158, 124), + (181, 166, 134), (170, 161, 135), (160, 156, 136), (153, 150, 130), + (147, 145, 125), (113, 109, 90), (98, 88, 72), (83, 68, 54), + (72, 53, 45), (61, 38, 36), (60, 33, 33), (60, 29, 30), + (69, 27, 31), (80, 39, 45), (91, 51, 60), (105, 66, 68), + (120, 82, 76), (124, 88, 79), (129, 95, 83), (141, 111, 92), + (155, 124, 101), (168, 129, 103), (167, 129, 105), (167, 130, 108), + (169, 130, 109), (171, 130, 111), (172, 130, 111), (174, 131, 111), + (171, 138, 115), (169, 139, 117), (167, 141, 120), (165, 145, 124), + (163, 150, 128), (161, 153, 134), (159, 157, 140), (159, 166, 157), + (163, 174, 167), (169, 186, 175), (174, 186, 177), (179, 187, 180), + (179, 179, 172), (179, 171, 164), (174, 166, 157), (170, 161, 151), + (156, 144, 143), (150, 136, 139), (144, 129, 136), (135, 128, 139), + (127, 127, 142), (124, 127, 143), (122, 128, 144), (123, 129, 149), + (123, 131, 150), (119, 132, 144), (120, 124, 132), (121, 116, 120), + (118, 111, 113), (116, 107, 106), (107, 94, 88), (97, 79, 77), + (87, 50, 49), (89, 48, 44), (91, 47, 39), (100, 52, 44), + (109, 57, 50), (111, 59, 50), (114, 61, 51), (114, 69, 54), + (123, 79, 63), (133, 103, 82), (131, 110, 93), (129, 117, 104), + (136, 125, 105), (143, 134, 106), (151, 146, 112), (154, 149, 116), + (144, 134, 114), (133, 123, 98), (123, 113, 83), (114, 103, 76), + (106, 94, 70), (93, 78, 61), (79, 64, 48), (71, 56, 36), + (66, 49, 28), (62, 46, 24), (60, 45, 24), (59, 45, 24), + (60, 45, 25), (62, 46, 26), (63, 49, 34), (66, 58, 47), + (87, 83, 77), (101, 99, 96), (115, 115, 116), (123, 125, 125), + (132, 135, 135), (147, 154, 147), (158, 166, 157), (160, 171, 165), + (163, 173, 166), (160, 172, 165), (155, 169, 166), (151, 166, 168), + (142, 159, 168), (136, 152, 164), (135, 151, 159), (134, 150, 159), + (130, 148, 151), (127, 142, 140), (124, 136, 130), (123, 134, 126), + (123, 133, 122), (122, 128, 119), (123, 124, 117), (121, 118, 113), + (121, 120, 113), (121, 128, 123), (119, 128, 122), (117, 128, 121), + (111, 126, 117), (104, 126, 112), (102, 122, 109), (101, 115, 101), + (109, 108, 86), (116, 104, 78), (123, 100, 71), (123, 96, 67), + (123, 92, 63), (118, 87, 57), (114, 85, 51), (108, 79, 48), + (96, 69, 46), (78, 74, 62), (79, 80, 68), (81, 87, 75), + (87, 97, 89), (89, 113, 104), (103, 131, 121), (122, 155, 138), + (142, 174, 157), (143, 173, 156), (144, 173, 155), (146, 177, 156), + (146, 175, 155), (137, 164, 150), (129, 144, 135), (116, 123, 116), + (102, 100, 101), (69, 66, 78), (64, 59, 70), (59, 52, 63), + (51, 34, 52), (42, 25, 49), (34, 22, 51), (32, 30, 56), + (34, 45, 60), (35, 47, 62), (37, 49, 65), (42, 57, 76), + (44, 63, 84), (43, 66, 82), (49, 62, 77), (58, 66, 81), + (65, 68, 93), (67, 79, 102), (77, 80, 106), (91, 93, 112), + (105, 103, 125), (121, 127, 143), (139, 145, 157), (154, 163, 166), + (172, 176, 164), (176, 179, 162), (180, 182, 161), (189, 188, 163), + (196, 191, 162), (203, 193, 160), (207, 198, 160), (209, 202, 162), + (213, 202, 167), (215, 199, 168), (213, 206, 172), (209, 216, 176), + (206, 221, 178), (202, 212, 177), (194, 205, 174), (185, 201, 174), + (173, 197, 177), (159, 180, 171), (145, 160, 159), (126, 133, 143), + (106, 111, 132), (85, 88, 115), (69, 69, 97), (57, 49, 79), + (48, 38, 64), (46, 33, 51), (48, 36, 43), (52, 36, 38), + (54, 38, 33), (58, 44, 28), (63, 49, 28), (68, 53, 31), + (71, 55, 29), (74, 59, 30), (87, 65, 35), (107, 73, 43), + (127, 82, 46), (143, 92, 48), (159, 100, 54), (177, 105, 62), + (191, 108, 66), (201, 113, 68), (199, 113, 72), (193, 117, 77), + (182, 119, 81), (180, 127, 88), (182, 131, 95), (181, 143, 107), + (179, 153, 119), (180, 163, 127), (188, 168, 130), (194, 170, 130), + (199, 167, 132), (198, 162, 131), (199, 157, 123), (199, 148, 110), + (199, 138, 98), (197, 129, 91), (194, 122, 81), (193, 117, 77), + (187, 113, 75), (179, 110, 78), (171, 110, 81), (167, 113, 88), + (162, 123, 101), (155, 127, 114), (152, 134, 126), (149, 138, 130), + (149, 147, 136), (134, 131, 123), (124, 114, 108), (108, 94, 87) + ), + +// 558 Explosion +((129, 90, 16), (80, 46, 17), (66, 28, 16), (53, 10, 15), + (77, 20, 12), (102, 31, 10), (114, 36, 9), (126, 41, 9), + (166, 58, 6), (179, 59, 5), (192, 61, 4), (182, 59, 5), + (173, 57, 7), (155, 52, 11), (138, 47, 15), (128, 43, 19), + (118, 39, 23), (73, 22, 40), (55, 18, 44), (38, 15, 48), + (34, 14, 47), (30, 14, 47), (31, 15, 48), (33, 16, 50), + (41, 13, 45), (49, 9, 37), (57, 6, 29), (79, 9, 22), + (101, 13, 15), (111, 18, 14), (122, 24, 13), (140, 37, 11), + (155, 49, 9), (197, 82, 4), (213, 98, 5), (230, 115, 7), + (237, 132, 14), (244, 150, 21), (245, 158, 25), (246, 166, 29), + (247, 187, 45), (248, 194, 55), (250, 202, 66), (250, 207, 70), + (251, 213, 74), (250, 214, 73), (250, 215, 72), (250, 215, 70), + (251, 214, 64), (253, 207, 52), (253, 204, 47), (253, 202, 43), + (253, 204, 42), (253, 206, 42), (253, 207, 43), (254, 209, 45), + (244, 205, 59), (226, 190, 57), (208, 176, 55), (184, 155, 50), + (160, 134, 45), (152, 127, 46), (144, 121, 48), (127, 109, 54), + (109, 93, 55), (68, 55, 52), (59, 49, 57), (51, 43, 62), + (51, 45, 65), (52, 47, 68), (49, 48, 76), (46, 46, 78), + (35, 35, 68), (29, 29, 61), (23, 23, 54), (18, 19, 48), + (14, 15, 42), (12, 13, 39), (11, 11, 36), (9, 8, 31), + (8, 6, 26), (7, 3, 19), (6, 3, 17), (6, 3, 15), + (5, 2, 14), (5, 2, 14), (5, 2, 13), (5, 1, 13), + (5, 2, 15), (4, 2, 16), (4, 3, 18), (4, 3, 19), + (5, 4, 20), (5, 4, 20), (5, 4, 20), (6, 4, 20), + (6, 4, 20), (6, 3, 19), (6, 2, 17), (6, 2, 16), + (6, 2, 15), (6, 2, 15), (7, 2, 14), (9, 1, 14), + (18, 2, 17), (23, 7, 21), (29, 12, 25), (32, 16, 27), + (35, 21, 30), (47, 30, 34), (64, 47, 44), (90, 67, 48), + (113, 89, 58), (153, 132, 71), (162, 142, 75), (171, 153, 80), + (194, 173, 83), (216, 192, 91), (231, 210, 99), (243, 219, 102), + (252, 222, 93), (253, 222, 87), (254, 222, 81), (254, 220, 78), + (254, 218, 76), (254, 211, 68), (253, 203, 57), (253, 199, 46), + (253, 194, 39), (252, 189, 33), (251, 187, 35), (251, 186, 38), + (251, 192, 47), (251, 198, 60), (251, 204, 75), (252, 209, 84), + (246, 212, 98), (229, 203, 103), (212, 194, 108), (200, 185, 108), + (188, 176, 109), (162, 156, 103), (142, 136, 93), (117, 114, 79), + (92, 89, 66), (46, 42, 47), (42, 34, 43), (38, 26, 40), + (39, 16, 32), (49, 12, 23), (70, 11, 14), (90, 16, 10), + (113, 17, 9), (112, 15, 9), (112, 13, 9), (110, 12, 9), + (109, 15, 10), (107, 19, 10), (95, 19, 16), (74, 14, 21), + (51, 8, 26), (20, 4, 28), (16, 4, 28), (13, 5, 29), + (10, 7, 34), (12, 12, 41), (20, 20, 46), (37, 35, 55), + (83, 77, 76), (95, 89, 83), (108, 102, 91), (130, 123, 99), + (157, 145, 106), (181, 163, 110), (204, 178, 109), (225, 186, 106), + (233, 179, 95), (227, 163, 81), (210, 139, 68), (183, 115, 54), + (159, 94, 42), (139, 73, 30), (116, 49, 19), (93, 27, 14), + (53, 2, 13), (52, 1, 14), (51, 1, 15), (65, 7, 13), + (85, 19, 11), (108, 34, 9), (133, 52, 7), (153, 68, 12), + (178, 87, 17), (202, 112, 26), (223, 139, 41), (241, 165, 53), + (248, 185, 71), (252, 200, 86), (253, 214, 102), (253, 226, 120), + (254, 233, 131), (254, 236, 140), (248, 231, 143), (234, 218, 139), + (213, 193, 128), (201, 168, 111), (200, 148, 92), (205, 136, 75), + (208, 130, 61), (192, 116, 49), (167, 94, 43), (148, 72, 38), + (136, 57, 34), (129, 53, 30), (124, 54, 25), (104, 51, 24), + (84, 43, 29), (66, 33, 34), (52, 21, 37), (63, 18, 33), + (79, 25, 23), (102, 38, 17), (127, 55, 14), (143, 72, 17), + (170, 92, 27), (195, 117, 41), (219, 143, 56), (238, 169, 70), + (244, 188, 80), (243, 197, 91), (235, 201, 108), (221, 198, 122), + (203, 190, 134), (186, 180, 142), (166, 161, 137), (144, 139, 129), + (118, 114, 115), (91, 87, 98), (72, 68, 86), (58, 50, 74), + (48, 36, 61), (43, 23, 48), (41, 12, 34), (48, 7, 23), + (69, 9, 17), (93, 19, 12), (119, 34, 9), (142, 54, 9), + (162, 71, 9), (184, 86, 10), (206, 104, 10), (225, 121, 8), + (209, 120, 9), (186, 114, 12), (157, 104, 13), (129, 88, 16) + ), + +// 559 Faded_Denim +((33, 54, 95), (31, 53, 96), (39, 58, 110), (47, 63, 124), + (57, 72, 140), (68, 82, 156), (72, 84, 156), (76, 86, 156), + (88, 97, 158), (88, 97, 159), (89, 98, 160), (88, 96, 156), + (88, 95, 152), (84, 90, 139), (80, 86, 126), (75, 81, 118), + (71, 76, 111), (45, 55, 89), (38, 49, 84), (32, 43, 80), + (32, 43, 80), (32, 43, 80), (33, 44, 82), (34, 45, 84), + (37, 50, 95), (41, 54, 99), (45, 59, 103), (50, 62, 107), + (55, 66, 111), (55, 67, 111), (56, 68, 112), (58, 69, 112), + (59, 68, 111), (58, 66, 108), (57, 67, 110), (56, 68, 112), + (61, 72, 120), (66, 76, 128), (68, 78, 133), (71, 81, 138), + (78, 88, 148), (71, 84, 142), (65, 80, 136), (58, 73, 125), + (52, 66, 115), (51, 63, 110), (50, 61, 106), (45, 56, 98), + (40, 50, 88), (23, 33, 69), (17, 26, 60), (11, 20, 51), + (8, 16, 46), (6, 13, 41), (5, 12, 42), (4, 12, 43), + (4, 11, 43), (3, 9, 41), (3, 7, 39), (3, 5, 36), + (3, 3, 33), (3, 3, 34), (3, 4, 36), (4, 8, 40), + (5, 13, 48), (19, 27, 69), (29, 36, 82), (40, 45, 95), + (47, 51, 100), (54, 58, 106), (60, 66, 111), (62, 72, 112), + (59, 76, 115), (60, 76, 116), (61, 76, 118), (64, 78, 119), + (68, 80, 120), (65, 78, 118), (63, 77, 116), (58, 76, 115), + (48, 68, 111), (43, 60, 112), (41, 56, 109), (39, 52, 107), + (37, 50, 105), (35, 49, 103), (32, 47, 99), (28, 48, 100), + (23, 51, 108), (23, 52, 112), (24, 53, 116), (24, 53, 115), + (24, 54, 115), (25, 56, 118), (29, 63, 124), (33, 68, 134), + (41, 75, 150), (57, 86, 173), (60, 90, 176), (63, 94, 179), + (64, 95, 179), (65, 97, 179), (65, 100, 182), (66, 102, 187), + (71, 108, 195), (70, 107, 194), (70, 107, 194), (68, 106, 191), + (66, 105, 189), (63, 103, 186), (62, 99, 181), (59, 96, 178), + (58, 92, 174), (58, 92, 169), (61, 92, 169), (64, 92, 170), + (73, 93, 171), (80, 98, 174), (94, 107, 181), (100, 115, 189), + (111, 125, 203), (113, 125, 206), (116, 125, 209), (120, 127, 210), + (124, 130, 211), (121, 128, 211), (115, 126, 209), (107, 120, 203), + (99, 113, 197), (85, 96, 181), (83, 93, 178), (81, 91, 175), + (76, 88, 170), (72, 85, 165), (69, 81, 159), (69, 79, 158), + (71, 79, 160), (75, 81, 163), (80, 84, 167), (82, 86, 168), + (84, 88, 169), (88, 93, 175), (93, 96, 179), (91, 98, 183), + (88, 100, 189), (80, 103, 190), (79, 103, 189), (78, 103, 189), + (79, 104, 189), (77, 103, 186), (75, 105, 189), (70, 106, 193), + (59, 107, 198), (58, 107, 200), (57, 108, 203), (59, 109, 205), + (66, 113, 209), (72, 120, 214), (81, 129, 222), (87, 135, 232), + (95, 144, 241), (119, 163, 254), (121, 165, 254), (124, 167, 255), + (131, 170, 254), (135, 168, 252), (127, 162, 246), (136, 162, 245), + (126, 151, 237), (121, 147, 234), (117, 144, 232), (103, 132, 225), + (85, 118, 217), (77, 112, 213), (76, 108, 211), (74, 110, 214), + (75, 114, 218), (75, 118, 221), (77, 119, 223), (75, 121, 223), + (73, 118, 222), (73, 118, 222), (74, 117, 218), (74, 114, 213), + (74, 112, 197), (71, 108, 191), (69, 104, 186), (62, 97, 178), + (57, 91, 169), (52, 82, 158), (47, 78, 150), (43, 74, 143), + (41, 72, 138), (39, 69, 134), (38, 66, 130), (37, 62, 126), + (37, 60, 120), (33, 56, 116), (31, 53, 114), (27, 51, 111), + (24, 48, 108), (27, 47, 110), (29, 49, 114), (33, 53, 120), + (35, 60, 131), (40, 67, 143), (48, 75, 154), (56, 81, 163), + (62, 89, 173), (65, 93, 178), (66, 98, 186), (63, 100, 190), + (62, 98, 189), (61, 96, 185), (60, 93, 177), (60, 89, 166), + (59, 85, 158), (51, 79, 150), (47, 75, 143), (41, 70, 138), + (38, 66, 132), (36, 64, 126), (37, 61, 122), (33, 57, 116), + (33, 53, 110), (30, 47, 102), (23, 42, 94), (16, 35, 83), + (9, 29, 72), (6, 25, 64), (5, 20, 55), (4, 16, 45), + (3, 12, 39), (3, 7, 31), (2, 3, 25), (2, 3, 24), + (2, 4, 26), (3, 10, 32), (4, 15, 41), (5, 24, 53), + (8, 30, 64), (12, 32, 72), (16, 34, 80), (17, 34, 79), + (17, 36, 79), (21, 40, 80), (25, 45, 83), (28, 48, 84), + (29, 50, 85), (29, 49, 81), (28, 47, 73), (24, 39, 60), + (26, 43, 64), (28, 45, 72), (29, 47, 77), (30, 50, 85) + ), + +// 560 Fading_Away +((101, 104, 121), (111, 104, 130), (115, 107, 129), (120, 111, 128), + (121, 110, 125), (122, 110, 123), (121, 105, 124), (121, 101, 125), + (129, 93, 125), (132, 97, 124), (136, 102, 123), (142, 113, 128), + (148, 124, 133), (151, 137, 128), (155, 151, 124), (154, 154, 124), + (154, 158, 125), (145, 161, 129), (140, 154, 123), (135, 147, 118), + (133, 143, 114), (132, 140, 111), (133, 138, 110), (134, 136, 109), + (134, 135, 107), (128, 137, 108), (123, 139, 110), (113, 144, 114), + (103, 150, 118), (96, 152, 120), (89, 154, 122), (79, 154, 126), + (64, 147, 131), (51, 131, 130), (51, 122, 130), (51, 114, 131), + (57, 105, 128), (63, 96, 126), (70, 94, 125), (78, 93, 125), + (99, 110, 123), (108, 117, 123), (117, 124, 124), (125, 127, 123), + (133, 130, 122), (132, 131, 120), (131, 133, 119), (125, 133, 118), + (124, 130, 114), (124, 127, 101), (119, 125, 100), (115, 124, 99), + (113, 124, 100), (111, 124, 102), (110, 125, 102), (109, 126, 103), + (92, 128, 114), (85, 125, 119), (78, 122, 124), (80, 121, 120), + (83, 121, 117), (83, 120, 114), (84, 120, 111), (89, 120, 101), + (100, 115, 91), (126, 110, 74), (130, 111, 63), (135, 112, 52), + (138, 110, 47), (141, 109, 42), (152, 102, 42), (159, 104, 44), + (164, 111, 44), (166, 116, 46), (169, 121, 48), (165, 127, 53), + (161, 134, 58), (157, 137, 65), (154, 141, 72), (146, 152, 84), + (144, 155, 96), (146, 160, 125), (147, 169, 136), (149, 178, 147), + (154, 178, 146), (159, 178, 145), (165, 163, 146), (165, 152, 140), + (163, 136, 129), (163, 123, 122), (163, 110, 116), (164, 105, 110), + (166, 100, 104), (162, 99, 98), (156, 101, 94), (149, 109, 94), + (145, 114, 90), (138, 125, 85), (135, 125, 82), (132, 125, 80), + (132, 123, 79), (133, 122, 78), (140, 121, 81), (143, 124, 82), + (140, 118, 79), (136, 116, 85), (133, 114, 92), (131, 110, 96), + (130, 107, 100), (124, 100, 108), (122, 88, 115), (127, 81, 125), + (137, 76, 132), (141, 69, 132), (145, 68, 134), (149, 67, 137), + (158, 73, 143), (159, 83, 148), (148, 101, 150), (137, 112, 162), + (130, 135, 171), (127, 135, 172), (124, 136, 173), (120, 130, 175), + (116, 125, 177), (112, 112, 167), (111, 102, 155), (108, 92, 143), + (105, 83, 141), (105, 75, 124), (104, 78, 121), (103, 82, 119), + (104, 96, 121), (105, 107, 119), (111, 113, 113), (113, 115, 110), + (118, 112, 116), (122, 106, 117), (127, 100, 118), (127, 99, 116), + (127, 98, 115), (128, 94, 117), (128, 89, 127), (124, 80, 135), + (108, 76, 135), (77, 70, 137), (73, 67, 140), (69, 65, 143), + (61, 62, 143), (54, 63, 140), (51, 60, 140), (55, 56, 143), + (61, 51, 140), (62, 50, 138), (63, 50, 137), (72, 50, 137), + (74, 53, 139), (79, 59, 140), (76, 66, 138), (86, 77, 136), + (94, 85, 133), (93, 98, 132), (91, 96, 133), (89, 95, 134), + (82, 87, 136), (76, 76, 136), (68, 71, 135), (65, 64, 133), + (70, 60, 137), (73, 64, 138), (76, 68, 139), (84, 78, 143), + (95, 95, 155), (108, 108, 165), (117, 126, 177), (129, 135, 184), + (139, 143, 198), (154, 148, 201), (157, 162, 204), (164, 164, 194), + (164, 161, 183), (165, 154, 167), (156, 161, 155), (140, 166, 146), + (119, 159, 138), (120, 161, 140), (121, 163, 142), (121, 174, 154), + (126, 181, 168), (137, 183, 182), (150, 184, 191), (158, 188, 194), + (161, 192, 198), (164, 195, 201), (165, 195, 204), (158, 193, 203), + (146, 190, 200), (131, 187, 199), (128, 177, 204), (129, 169, 207), + (135, 162, 208), (140, 159, 203), (147, 149, 200), (153, 149, 186), + (158, 151, 168), (167, 157, 154), (179, 154, 150), (186, 154, 155), + (181, 156, 160), (178, 159, 167), (181, 162, 173), (190, 165, 186), + (191, 165, 193), (187, 167, 195), (179, 171, 185), (171, 180, 176), + (166, 184, 161), (160, 182, 152), (154, 175, 146), (143, 168, 145), + (137, 165, 144), (134, 155, 143), (136, 146, 147), (134, 137, 150), + (134, 137, 150), (133, 136, 144), (137, 137, 137), (140, 133, 128), + (147, 136, 116), (149, 136, 105), (152, 141, 94), (150, 139, 86), + (152, 142, 80), (154, 141, 73), (155, 146, 74), (144, 151, 79), + (132, 156, 90), (123, 166, 99), (120, 173, 108), (124, 181, 122), + (126, 179, 133), (126, 176, 141), (120, 169, 140), (124, 161, 140), + (133, 146, 140), (138, 129, 139), (130, 119, 133), (117, 105, 127), + (105, 93, 125), (96, 82, 125), (91, 83, 119), (88, 89, 113), + (83, 91, 112), (83, 84, 124), (83, 79, 127), (94, 89, 128) + ), + +// 561 Fiery_Sky +((163, 95, 49), (175, 86, 48), (180, 83, 47), (186, 80, 47), + (171, 76, 42), (156, 73, 38), (150, 68, 35), (144, 64, 33), + (105, 55, 40), (87, 59, 46), (69, 64, 53), (53, 57, 63), + (37, 50, 73), (37, 51, 78), (37, 52, 84), (45, 53, 83), + (53, 55, 82), (89, 63, 71), (107, 70, 60), (126, 78, 49), + (143, 82, 38), (160, 87, 28), (167, 86, 25), (175, 86, 23), + (189, 61, 16), (200, 47, 18), (212, 33, 21), (214, 25, 23), + (217, 17, 26), (212, 16, 27), (207, 15, 28), (204, 13, 37), + (201, 6, 50), (173, 13, 52), (154, 12, 55), (136, 12, 58), + (119, 11, 62), (102, 11, 66), (91, 11, 63), (80, 11, 60), + (47, 14, 61), (47, 12, 56), (48, 10, 51), (58, 10, 43), + (69, 11, 36), (73, 14, 35), (77, 18, 35), (82, 22, 25), + (86, 28, 20), (83, 30, 15), (69, 31, 16), (55, 33, 18), + (48, 31, 25), (42, 30, 32), (43, 29, 32), (44, 28, 33), + (55, 24, 24), (64, 29, 30), (73, 35, 36), (83, 40, 37), + (94, 46, 39), (96, 46, 40), (98, 47, 42), (97, 47, 53), + (94, 43, 68), (89, 36, 81), (90, 28, 75), (91, 21, 69), + (94, 20, 64), (98, 19, 60), (105, 17, 51), (109, 21, 41), + (124, 24, 15), (122, 25, 17), (121, 27, 20), (119, 27, 17), + (118, 28, 15), (112, 27, 15), (107, 27, 16), (95, 23, 26), + (86, 18, 33), (64, 12, 22), (53, 12, 25), (42, 12, 29), + (37, 11, 32), (32, 10, 36), (18, 7, 40), (10, 9, 39), + (12, 22, 54), (15, 19, 66), (19, 16, 78), (22, 18, 82), + (26, 21, 86), (40, 25, 94), (56, 28, 97), (67, 21, 97), + (81, 18, 94), (105, 21, 93), (105, 20, 84), (106, 19, 75), + (112, 21, 71), (118, 24, 67), (134, 41, 66), (140, 54, 65), + (166, 73, 46), (178, 86, 39), (190, 99, 33), (190, 102, 32), + (191, 106, 32), (177, 103, 28), (156, 91, 23), (131, 78, 25), + (104, 70, 39), (63, 50, 56), (58, 44, 56), (54, 39, 56), + (53, 35, 57), (57, 40, 55), (72, 44, 52), (91, 49, 43), + (113, 55, 19), (115, 53, 23), (118, 51, 27), (112, 49, 33), + (107, 47, 39), (91, 38, 48), (69, 28, 59), (52, 20, 70), + (38, 19, 73), (15, 29, 58), (14, 34, 55), (13, 39, 53), + (28, 51, 44), (49, 58, 27), (73, 65, 13), (87, 71, 8), + (116, 73, 10), (122, 71, 9), (129, 69, 9), (122, 67, 9), + (116, 65, 9), (105, 66, 12), (102, 80, 13), (109, 93, 13), + (109, 97, 15), (128, 97, 22), (137, 102, 22), (146, 108, 23), + (158, 116, 26), (164, 117, 29), (168, 119, 26), (173, 125, 23), + (174, 135, 27), (172, 139, 25), (171, 143, 24), (176, 153, 21), + (186, 157, 19), (197, 156, 33), (190, 153, 37), (176, 159, 48), + (160, 158, 54), (151, 125, 62), (146, 122, 60), (142, 119, 59), + (123, 116, 55), (122, 101, 62), (130, 82, 57), (149, 69, 52), + (165, 73, 55), (166, 76, 57), (167, 80, 59), (178, 85, 63), + (182, 89, 60), (185, 96, 59), (178, 103, 52), (177, 114, 44), + (172, 113, 36), (170, 108, 29), (167, 99, 23), (171, 95, 15), + (172, 86, 12), (172, 73, 11), (176, 60, 17), (184, 60, 19), + (207, 72, 17), (212, 69, 17), (217, 66, 17), (218, 63, 17), + (220, 60, 19), (216, 63, 15), (212, 57, 12), (199, 50, 7), + (190, 42, 5), (176, 39, 5), (165, 34, 12), (150, 36, 17), + (146, 39, 22), (141, 43, 25), (139, 41, 31), (136, 40, 40), + (133, 40, 52), (129, 41, 60), (133, 49, 68), (142, 49, 72), + (152, 49, 81), (153, 41, 82), (162, 52, 86), (176, 63, 78), + (191, 77, 71), (190, 79, 54), (187, 88, 44), (189, 100, 33), + (196, 112, 25), (197, 124, 20), (187, 131, 19), (174, 132, 23), + (162, 118, 29), (152, 101, 46), (133, 87, 62), (112, 77, 76), + (86, 63, 85), (64, 47, 97), (43, 33, 100), (39, 24, 101), + (43, 21, 94), (51, 18, 86), (59, 15, 71), (76, 13, 62), + (95, 13, 57), (111, 12, 55), (123, 9, 48), (132, 9, 43), + (140, 12, 38), (149, 22, 39), (158, 32, 35), (168, 45, 33), + (177, 56, 20), (190, 68, 14), (198, 73, 11), (204, 77, 22), + (204, 73, 29), (200, 68, 36), (183, 54, 48), (166, 43, 65), + (145, 31, 78), (123, 22, 84), (96, 12, 92), (77, 8, 97), + (69, 10, 93), (64, 16, 85), (67, 22, 78), (67, 40, 76), + (79, 49, 65), (96, 59, 62), (130, 61, 54), (152, 84, 58) + ), + +// 562 Fiesta +((84, 124, 123), (56, 94, 149), (36, 79, 163), (16, 64, 177), + (17, 63, 165), (18, 62, 153), (23, 64, 150), (29, 66, 148), + (54, 85, 153), (57, 97, 135), (60, 110, 118), (72, 116, 91), + (85, 122, 65), (96, 117, 51), (108, 113, 38), (110, 110, 34), + (113, 107, 30), (123, 85, 16), (127, 71, 9), (131, 57, 3), + (137, 50, 2), (144, 44, 1), (146, 46, 1), (148, 49, 1), + (141, 60, 15), (124, 61, 40), (107, 62, 65), (91, 65, 92), + (75, 68, 119), (69, 73, 129), (64, 79, 139), (54, 94, 161), + (40, 107, 188), (10, 105, 235), (6, 96, 242), (2, 88, 250), + (3, 92, 249), (4, 96, 248), (6, 99, 244), (9, 102, 241), + (20, 103, 212), (23, 108, 195), (27, 113, 179), (29, 123, 154), + (31, 134, 129), (33, 135, 115), (36, 137, 101), (44, 127, 71), + (56, 118, 51), (78, 94, 25), (91, 84, 17), (105, 75, 10), + (121, 76, 16), (138, 78, 22), (143, 83, 29), (148, 88, 37), + (149, 121, 49), (152, 132, 50), (156, 144, 51), (152, 163, 68), + (149, 182, 85), (143, 188, 89), (138, 194, 94), (130, 193, 84), + (117, 184, 71), (89, 158, 61), (80, 151, 60), (71, 144, 60), + (64, 143, 55), (58, 143, 51), (48, 134, 42), (37, 124, 37), + (46, 98, 35), (62, 101, 38), (78, 105, 41), (93, 116, 51), + (108, 127, 61), (114, 130, 67), (121, 133, 73), (123, 139, 81), + (126, 145, 86), (118, 161, 99), (112, 173, 114), (106, 186, 129), + (104, 187, 133), (102, 188, 137), (97, 191, 131), (102, 188, 119), + (136, 185, 112), (153, 167, 102), (171, 150, 93), (177, 140, 81), + (184, 131, 69), (198, 124, 54), (214, 113, 39), (222, 98, 33), + (225, 80, 23), (214, 56, 7), (210, 60, 6), (207, 64, 6), + (203, 66, 7), (200, 68, 8), (185, 79, 14), (169, 88, 24), + (126, 98, 66), (108, 105, 88), (91, 113, 111), (84, 123, 117), + (78, 133, 124), (66, 145, 132), (51, 152, 142), (46, 147, 147), + (38, 142, 144), (32, 134, 105), (31, 131, 93), (31, 128, 81), + (33, 116, 61), (33, 111, 43), (28, 108, 27), (20, 105, 15), + (4, 87, 2), (4, 78, 1), (5, 70, 0), (9, 69, 1), + (14, 69, 2), (29, 72, 2), (49, 69, 2), (67, 57, 1), + (86, 44, 1), (128, 24, 1), (140, 24, 1), (153, 25, 1), + (174, 29, 0), (188, 34, 2), (198, 33, 2), (204, 30, 2), + (206, 27, 3), (197, 26, 4), (188, 26, 5), (183, 22, 4), + (179, 19, 4), (175, 14, 5), (173, 10, 3), (169, 9, 6), + (165, 9, 6), (162, 10, 10), (161, 14, 13), (161, 19, 16), + (159, 30, 26), (147, 42, 39), (135, 57, 51), (122, 68, 60), + (108, 92, 71), (99, 96, 74), (91, 100, 77), (72, 105, 82), + (47, 102, 94), (34, 94, 103), (31, 84, 110), (28, 71, 114), + (26, 63, 107), (7, 42, 85), (5, 37, 81), (3, 32, 78), + (6, 23, 76), (20, 27, 72), (33, 40, 57), (40, 58, 46), + (30, 91, 58), (30, 100, 71), (31, 109, 85), (36, 124, 109), + (40, 145, 127), (39, 160, 135), (28, 163, 142), (19, 162, 146), + (19, 145, 142), (27, 127, 133), (41, 109, 113), (59, 89, 87), + (76, 77, 63), (90, 63, 41), (105, 45, 27), (116, 28, 15), + (129, 13, 5), (124, 17, 4), (120, 21, 4), (106, 30, 8), + (94, 36, 11), (87, 38, 14), (88, 34, 11), (90, 36, 7), + (92, 39, 7), (93, 45, 7), (107, 52, 11), (123, 54, 11), + (144, 57, 8), (163, 57, 7), (176, 56, 6), (193, 53, 9), + (205, 51, 10), (213, 47, 6), (216, 45, 6), (217, 46, 6), + (219, 45, 9), (223, 42, 10), (227, 34, 7), (232, 28, 6), + (236, 24, 4), (238, 27, 3), (239, 30, 4), (238, 31, 2), + (235, 33, 5), (235, 37, 14), (232, 54, 29), (228, 76, 47), + (217, 91, 76), (195, 101, 90), (167, 99, 115), (139, 97, 145), + (114, 103, 151), (95, 100, 169), (77, 99, 151), (62, 84, 135), + (54, 66, 130), (51, 58, 111), (56, 51, 103), (61, 59, 83), + (63, 72, 60), (65, 82, 52), (64, 93, 53), (65, 97, 62), + (62, 102, 73), (52, 110, 78), (45, 121, 86), (34, 133, 94), + (26, 139, 104), (20, 142, 115), (13, 139, 120), (12, 143, 130), + (13, 153, 143), (18, 161, 160), (20, 171, 181), (16, 177, 193), + (9, 178, 206), (5, 176, 220), (6, 172, 231), (7, 171, 239), + (15, 168, 234), (31, 168, 222), (53, 169, 208), (76, 165, 188), + (74, 165, 189), (68, 157, 179), (68, 149, 164), (66, 141, 150) + ), + +// 563 First_Love +((218, 159, 144), (232, 175, 163), (230, 176, 159), (228, 177, 156), + (227, 177, 154), (227, 178, 152), (229, 178, 151), (231, 178, 151), + (233, 179, 149), (233, 183, 151), (234, 188, 154), (235, 191, 156), + (236, 194, 158), (235, 195, 163), (235, 196, 168), (235, 197, 170), + (235, 199, 172), (240, 204, 180), (239, 206, 185), (239, 208, 190), + (239, 208, 190), (240, 208, 191), (241, 205, 188), (243, 202, 186), + (245, 194, 175), (242, 188, 165), (240, 182, 156), (236, 169, 144), + (232, 156, 133), (228, 150, 127), (225, 144, 122), (219, 126, 110), + (213, 112, 105), (210, 99, 107), (208, 101, 109), (207, 104, 111), + (206, 105, 113), (205, 107, 116), (208, 109, 118), (211, 112, 120), + (226, 134, 128), (228, 143, 131), (230, 153, 134), (230, 158, 135), + (231, 163, 136), (230, 162, 135), (230, 161, 135), (228, 158, 134), + (226, 157, 133), (217, 157, 129), (204, 151, 123), (192, 145, 118), + (187, 139, 114), (183, 134, 110), (184, 134, 110), (186, 134, 111), + (186, 142, 124), (190, 150, 135), (194, 158, 147), (206, 170, 159), + (219, 182, 171), (223, 186, 175), (228, 190, 179), (233, 193, 182), + (238, 197, 186), (242, 200, 186), (240, 191, 175), (238, 182, 164), + (236, 176, 157), (234, 171, 150), (232, 160, 138), (228, 151, 124), + (212, 121, 100), (203, 105, 93), (194, 90, 87), (187, 80, 81), + (181, 70, 76), (177, 65, 76), (173, 61, 77), (167, 58, 76), + (164, 61, 83), (166, 81, 108), (167, 89, 114), (168, 98, 121), + (168, 98, 120), (168, 98, 119), (164, 98, 112), (156, 95, 110), + (135, 78, 100), (123, 62, 88), (112, 47, 76), (107, 41, 73), + (103, 36, 70), (99, 27, 67), (94, 24, 65), (92, 21, 61), + (91, 19, 61), (99, 22, 73), (103, 24, 78), (107, 26, 84), + (108, 26, 85), (109, 27, 86), (112, 27, 90), (117, 34, 95), + (132, 59, 109), (145, 72, 112), (158, 85, 115), (165, 90, 116), + (173, 96, 118), (187, 110, 121), (199, 119, 121), (210, 130, 122), + (218, 139, 120), (230, 138, 107), (230, 135, 102), (230, 133, 98), + (227, 123, 92), (217, 113, 85), (207, 103, 85), (198, 91, 81), + (188, 71, 75), (183, 63, 72), (179, 55, 69), (178, 54, 69), + (178, 53, 69), (180, 49, 73), (186, 51, 81), (191, 50, 85), + (193, 48, 87), (193, 62, 85), (192, 67, 85), (192, 72, 86), + (196, 81, 89), (195, 85, 95), (196, 86, 98), (194, 92, 104), + (185, 98, 100), (177, 94, 97), (170, 91, 94), (165, 86, 94), + (161, 81, 95), (148, 70, 88), (132, 58, 81), (113, 45, 74), + (96, 35, 68), (72, 20, 63), (70, 17, 61), (68, 15, 59), + (70, 12, 55), (72, 11, 52), (74, 11, 53), (77, 13, 57), + (78, 14, 64), (78, 12, 62), (78, 11, 60), (78, 11, 56), + (77, 11, 52), (74, 12, 54), (69, 14, 59), (66, 11, 62), + (61, 12, 60), (56, 10, 53), (55, 10, 52), (54, 10, 51), + (54, 7, 47), (53, 7, 44), (50, 4, 35), (54, 2, 33), + (67, 3, 30), (72, 4, 31), (78, 6, 33), (84, 11, 34), + (97, 16, 42), (112, 26, 55), (128, 41, 68), (143, 51, 84), + (153, 57, 90), (164, 65, 91), (172, 75, 97), (183, 94, 103), + (190, 112, 113), (199, 120, 119), (208, 124, 117), (215, 127, 116), + (226, 149, 122), (227, 153, 127), (229, 158, 133), (231, 162, 140), + (232, 165, 144), (233, 169, 148), (234, 172, 151), (232, 173, 153), + (230, 174, 156), (228, 175, 157), (228, 176, 158), (229, 175, 157), + (229, 171, 155), (225, 166, 153), (224, 160, 150), (222, 158, 146), + (223, 157, 143), (224, 156, 141), (223, 154, 142), (225, 151, 141), + (225, 152, 140), (227, 153, 139), (229, 158, 136), (229, 161, 135), + (229, 160, 132), (227, 157, 127), (223, 150, 121), (221, 145, 114), + (215, 135, 109), (208, 124, 103), (202, 114, 98), (194, 105, 91), + (194, 102, 88), (195, 103, 91), (195, 104, 94), (194, 106, 99), + (190, 108, 100), (188, 109, 101), (187, 110, 106), (185, 107, 107), + (178, 102, 109), (169, 94, 102), (161, 85, 95), (153, 76, 90), + (151, 66, 82), (155, 62, 79), (156, 58, 76), (157, 55, 74), + (155, 53, 77), (154, 50, 75), (157, 52, 71), (162, 53, 68), + (161, 51, 67), (154, 48, 72), (144, 42, 76), (132, 35, 77), + (122, 33, 74), (114, 28, 71), (105, 23, 68), (102, 23, 67), + (98, 20, 68), (95, 21, 71), (95, 20, 73), (95, 20, 74), + (109, 32, 74), (120, 37, 72), (137, 56, 81), (157, 74, 93), + (167, 84, 107), (188, 111, 120), (194, 121, 124), (205, 142, 132) + ), + +// 564 Flame +((132, 76, 52), (110, 62, 38), (101, 57, 31), (93, 52, 25), + (108, 66, 34), (124, 80, 43), (136, 90, 50), (148, 100, 58), + (189, 135, 84), (200, 141, 88), (211, 148, 92), (213, 144, 91), + (215, 141, 90), (209, 126, 84), (204, 112, 79), (201, 105, 74), + (198, 98, 70), (178, 77, 47), (171, 70, 38), (164, 63, 29), + (163, 63, 27), (162, 63, 26), (160, 64, 25), (158, 66, 24), + (148, 73, 25), (145, 68, 25), (143, 64, 26), (139, 54, 23), + (135, 45, 20), (133, 42, 19), (132, 40, 19), (130, 40, 19), + (134, 41, 23), (151, 53, 27), (162, 67, 28), (174, 82, 30), + (187, 99, 39), (201, 116, 48), (207, 125, 55), (214, 135, 62), + (230, 169, 81), (234, 176, 90), (239, 183, 99), (238, 185, 106), + (237, 187, 113), (234, 186, 115), (231, 186, 117), (229, 184, 117), + (226, 178, 113), (230, 168, 96), (226, 161, 87), (223, 155, 79), + (218, 146, 68), (213, 138, 57), (211, 133, 51), (209, 128, 45), + (188, 113, 37), (176, 103, 31), (165, 94, 25), (151, 82, 21), + (137, 70, 18), (129, 66, 17), (121, 62, 17), (106, 53, 16), + (93, 46, 11), (82, 34, 9), (82, 33, 9), (82, 33, 10), + (84, 34, 9), (86, 36, 8), (94, 41, 10), (107, 49, 11), + (139, 70, 14), (151, 77, 19), (164, 85, 25), (171, 87, 30), + (178, 89, 36), (179, 88, 35), (181, 88, 35), (177, 84, 33), + (172, 74, 31), (155, 48, 31), (144, 38, 26), (134, 28, 22), + (130, 25, 20), (126, 22, 18), (118, 18, 17), (113, 19, 17), + (110, 26, 20), (114, 33, 24), (119, 40, 29), (122, 45, 32), + (126, 50, 36), (136, 61, 43), (145, 69, 46), (149, 71, 47), + (153, 70, 45), (154, 60, 40), (149, 56, 38), (145, 52, 36), + (141, 50, 34), (138, 48, 33), (128, 44, 30), (124, 41, 26), + (125, 44, 29), (131, 54, 34), (137, 65, 40), (141, 72, 42), + (146, 79, 45), (154, 88, 49), (161, 95, 52), (167, 99, 50), + (174, 98, 47), (176, 87, 41), (174, 83, 39), (172, 79, 38), + (162, 70, 31), (155, 63, 24), (147, 54, 21), (141, 42, 18), + (130, 22, 13), (128, 20, 11), (126, 19, 10), (126, 18, 10), + (127, 18, 11), (128, 14, 10), (135, 11, 8), (148, 13, 5), + (158, 16, 5), (170, 25, 11), (170, 26, 13), (170, 28, 15), + (172, 34, 15), (173, 37, 17), (171, 40, 20), (164, 42, 24), + (139, 39, 26), (125, 36, 23), (111, 33, 21), (105, 30, 20), + (100, 28, 19), (96, 26, 17), (94, 21, 15), (95, 17, 12), + (99, 17, 8), (114, 16, 4), (120, 16, 4), (126, 17, 4), + (135, 22, 4), (140, 31, 3), (144, 34, 3), (144, 35, 3), + (151, 31, 4), (146, 32, 5), (142, 33, 7), (132, 32, 8), + (116, 29, 10), (108, 25, 8), (106, 20, 9), (103, 20, 12), + (106, 26, 16), (119, 50, 31), (124, 57, 35), (129, 65, 40), + (141, 81, 48), (153, 96, 52), (166, 109, 58), (179, 120, 65), + (191, 133, 76), (192, 133, 75), (193, 133, 75), (194, 134, 68), + (197, 131, 62), (192, 126, 59), (190, 121, 58), (190, 119, 60), + (196, 124, 65), (208, 133, 70), (217, 144, 79), (223, 152, 88), + (227, 161, 96), (232, 172, 108), (239, 186, 120), (246, 200, 132), + (251, 217, 150), (251, 218, 151), (252, 220, 152), (251, 221, 154), + (252, 221, 153), (253, 223, 155), (253, 221, 154), (253, 218, 151), + (251, 207, 142), (245, 196, 128), (239, 184, 113), (231, 171, 97), + (225, 162, 87), (218, 149, 75), (211, 136, 63), (204, 124, 50), + (198, 114, 39), (194, 109, 34), (190, 104, 32), (185, 99, 36), + (183, 93, 37), (179, 86, 37), (177, 84, 36), (174, 83, 35), + (168, 80, 38), (163, 80, 40), (158, 78, 42), (155, 80, 42), + (154, 83, 41), (151, 84, 41), (149, 84, 39), (147, 85, 38), + (146, 87, 38), (148, 92, 37), (150, 94, 38), (150, 92, 37), + (149, 90, 37), (145, 87, 36), (143, 87, 35), (140, 88, 36), + (138, 87, 35), (135, 86, 37), (132, 84, 38), (130, 80, 35), + (128, 77, 35), (128, 74, 31), (127, 72, 31), (130, 72, 35), + (133, 75, 35), (140, 80, 40), (151, 88, 44), (159, 97, 50), + (168, 107, 59), (169, 114, 64), (171, 116, 68), (173, 117, 69), + (172, 112, 69), (172, 105, 67), (166, 95, 62), (160, 83, 57), + (155, 77, 52), (152, 72, 49), (154, 71, 47), (158, 69, 51), + (164, 69, 55), (173, 76, 60), (183, 89, 66), (191, 105, 69), + (180, 103, 67), (166, 95, 63), (148, 83, 58), (132, 70, 51) + ), + +// 565 Flying_a_Kite +((90, 150, 101), (83, 161, 102), (69, 169, 104), (56, 177, 107), + (69, 175, 117), (83, 174, 127), (91, 170, 124), (99, 166, 122), + (116, 171, 78), (118, 164, 58), (121, 158, 38), (110, 155, 30), + (100, 152, 23), (101, 153, 26), (103, 154, 29), (105, 150, 36), + (108, 147, 43), (104, 173, 67), (113, 185, 77), (122, 197, 88), + (127, 203, 83), (132, 210, 78), (134, 214, 77), (136, 218, 77), + (135, 202, 68), (126, 200, 58), (118, 199, 49), (110, 203, 57), + (103, 208, 66), (111, 212, 76), (119, 216, 86), (116, 221, 104), + (109, 207, 108), (125, 172, 95), (127, 144, 93), (129, 117, 92), + (132, 96, 68), (136, 75, 45), (135, 72, 34), (135, 70, 24), + (147, 76, 27), (144, 93, 23), (142, 110, 20), (143, 108, 25), + (144, 107, 31), (140, 100, 31), (136, 93, 31), (112, 89, 36), + (103, 74, 49), (94, 58, 53), (76, 70, 65), (58, 82, 78), + (53, 98, 90), (48, 114, 102), (40, 122, 96), (33, 131, 90), + (28, 150, 85), (30, 144, 83), (32, 138, 81), (32, 134, 59), + (32, 131, 37), (28, 120, 34), (25, 110, 31), (28, 86, 37), + (25, 79, 31), (30, 81, 20), (40, 90, 37), (51, 99, 54), + (50, 104, 59), (50, 110, 65), (51, 121, 74), (59, 131, 86), + (82, 138, 115), (86, 117, 123), (90, 97, 132), (114, 84, 127), + (139, 71, 123), (148, 70, 115), (157, 69, 107), (181, 79, 95), + (199, 100, 79), (210, 121, 59), (208, 131, 56), (206, 141, 53), + (206, 146, 62), (206, 152, 71), (204, 164, 92), (203, 169, 101), + (181, 186, 132), (167, 195, 144), (153, 205, 156), (144, 200, 153), + (136, 195, 151), (125, 192, 131), (112, 178, 116), (108, 161, 93), + (102, 146, 75), (121, 158, 40), (135, 164, 36), (149, 170, 33), + (161, 181, 35), (173, 193, 38), (186, 216, 46), (202, 227, 57), + (221, 229, 84), (223, 221, 91), (226, 214, 98), (223, 209, 93), + (221, 205, 88), (224, 196, 78), (221, 177, 69), (213, 164, 65), + (200, 162, 53), (192, 158, 37), (191, 151, 35), (190, 144, 34), + (178, 138, 30), (163, 142, 34), (149, 150, 45), (143, 155, 57), + (130, 157, 84), (119, 171, 106), (108, 186, 129), (107, 191, 139), + (107, 196, 149), (101, 203, 165), (88, 206, 179), (67, 205, 185), + (53, 198, 182), (47, 180, 179), (47, 167, 182), (48, 155, 185), + (57, 124, 186), (60, 95, 179), (91, 82, 178), (115, 67, 188), + (133, 49, 181), (140, 62, 178), (148, 76, 175), (149, 81, 176), + (150, 87, 178), (122, 107, 168), (97, 121, 159), (77, 122, 163), + (66, 103, 182), (36, 108, 189), (33, 107, 189), (31, 107, 190), + (33, 86, 203), (40, 80, 222), (45, 100, 230), (53, 120, 233), + (56, 120, 227), (54, 127, 225), (53, 134, 223), (50, 155, 223), + (42, 171, 222), (46, 171, 212), (55, 164, 198), (75, 166, 197), + (88, 164, 191), (118, 114, 151), (123, 101, 146), (129, 88, 141), + (131, 70, 135), (129, 59, 128), (129, 57, 124), (123, 66, 136), + (135, 111, 176), (146, 124, 184), (157, 137, 193), (171, 168, 195), + (183, 189, 188), (196, 207, 174), (209, 207, 160), (224, 211, 128), + (224, 213, 96), (224, 220, 67), (223, 211, 48), (225, 193, 34), + (220, 174, 28), (210, 161, 36), (207, 151, 42), (205, 139, 53), + (178, 142, 103), (173, 147, 118), (168, 152, 133), (176, 161, 157), + (195, 177, 175), (199, 174, 182), (190, 167, 185), (183, 155, 174), + (190, 165, 163), (187, 155, 143), (170, 148, 126), (153, 151, 110), + (145, 177, 104), (140, 198, 106), (122, 211, 115), (107, 226, 135), + (95, 230, 147), (89, 226, 153), (79, 206, 149), (70, 182, 144), + (62, 151, 140), (56, 128, 140), (50, 107, 145), (40, 84, 144), + (48, 53, 152), (69, 40, 160), (87, 49, 182), (82, 72, 194), + (80, 94, 215), (97, 114, 227), (122, 138, 236), (132, 168, 235), + (134, 201, 237), (143, 221, 241), (159, 231, 243), (173, 238, 243), + (179, 241, 239), (183, 238, 230), (192, 235, 216), (203, 237, 201), + (194, 235, 175), (180, 221, 151), (165, 205, 123), (164, 195, 101), + (158, 193, 69), (154, 186, 50), (148, 177, 40), (149, 167, 47), + (151, 167, 50), (159, 176, 64), (162, 187, 80), (163, 198, 115), + (158, 204, 137), (155, 208, 166), (151, 211, 177), (146, 215, 192), + (135, 216, 200), (126, 208, 214), (115, 199, 216), (107, 190, 211), + (99, 189, 207), (101, 183, 215), (91, 178, 225), (78, 178, 230), + (72, 187, 227), (86, 187, 230), (97, 179, 226), (102, 167, 220), + (115, 161, 198), (134, 158, 169), (118, 154, 129), (101, 149, 106) + ), + +// 566 Foamy_Waves +((40, 46, 134), (48, 54, 142), (51, 57, 146), (55, 61, 151), + (58, 68, 156), (62, 75, 162), (62, 77, 164), (63, 80, 166), + (63, 86, 169), (61, 89, 169), (60, 93, 169), (58, 94, 169), + (56, 95, 169), (54, 95, 167), (52, 96, 166), (50, 95, 165), + (49, 95, 165), (44, 93, 162), (40, 88, 159), (36, 84, 156), + (31, 79, 149), (26, 75, 143), (23, 73, 140), (21, 71, 137), + (13, 64, 126), (11, 62, 122), (10, 61, 119), (10, 64, 119), + (11, 67, 119), (12, 70, 121), (14, 74, 123), (21, 81, 127), + (29, 92, 131), (59, 106, 132), (72, 113, 133), (86, 120, 135), + (100, 130, 138), (115, 140, 141), (122, 141, 138), (130, 142, 136), + (166, 168, 147), (169, 172, 159), (173, 177, 171), (180, 182, 176), + (187, 187, 181), (189, 188, 182), (191, 190, 184), (191, 184, 185), + (191, 184, 188), (185, 173, 180), (182, 163, 167), (179, 153, 154), + (170, 145, 154), (162, 138, 154), (155, 130, 152), (149, 123, 150), + (108, 98, 131), (91, 84, 127), (75, 70, 123), (57, 55, 119), + (40, 41, 115), (33, 37, 113), (26, 33, 111), (18, 27, 100), + (13, 23, 92), (7, 19, 79), (8, 24, 76), (9, 29, 73), + (9, 30, 71), (10, 31, 70), (13, 36, 70), (15, 39, 70), + (15, 45, 71), (14, 45, 69), (14, 46, 67), (13, 45, 64), + (13, 45, 62), (13, 45, 61), (13, 45, 60), (13, 43, 56), + (13, 43, 55), (14, 46, 55), (14, 49, 58), (15, 53, 62), + (16, 54, 63), (17, 55, 64), (18, 55, 67), (18, 56, 69), + (18, 54, 73), (18, 52, 72), (18, 50, 71), (18, 48, 70), + (18, 47, 69), (18, 43, 66), (17, 40, 64), (17, 39, 64), + (15, 36, 66), (14, 35, 74), (15, 37, 79), (17, 39, 85), + (17, 39, 87), (18, 40, 90), (21, 45, 97), (22, 48, 101), + (25, 50, 105), (28, 56, 106), (32, 62, 108), (34, 65, 108), + (36, 68, 108), (39, 72, 108), (40, 73, 107), (41, 78, 108), + (41, 80, 109), (48, 92, 116), (49, 94, 117), (51, 96, 119), + (52, 100, 123), (54, 103, 126), (54, 104, 127), (52, 104, 127), + (47, 104, 123), (43, 101, 119), (40, 98, 116), (38, 97, 113), + (36, 96, 111), (32, 93, 105), (29, 88, 100), (26, 82, 94), + (24, 78, 90), (18, 64, 82), (17, 60, 80), (17, 56, 79), + (14, 53, 77), (13, 46, 73), (11, 38, 70), (6, 32, 67), + (0, 23, 63), (0, 21, 61), (0, 20, 59), (0, 20, 58), + (0, 20, 58), (0, 18, 56), (0, 18, 55), (0, 17, 54), + (0, 17, 54), (0, 11, 52), (0, 10, 51), (0, 10, 51), + (0, 7, 49), (0, 7, 49), (0, 6, 48), (0, 6, 48), + (0, 8, 49), (0, 8, 49), (0, 8, 49), (0, 10, 51), + (0, 11, 52), (0, 13, 54), (0, 14, 56), (0, 15, 58), + (0, 16, 59), (0, 19, 62), (0, 19, 62), (0, 19, 62), + (0, 21, 63), (0, 24, 64), (0, 26, 66), (0, 26, 67), + (0, 34, 73), (0, 34, 74), (0, 35, 75), (0, 36, 78), + (0, 36, 81), (0, 38, 85), (0, 41, 88), (0, 39, 90), + (0, 38, 93), (0, 36, 94), (0, 35, 97), (0, 32, 98), + (0, 31, 100), (0, 27, 103), (0, 24, 105), (0, 23, 108), + (0, 15, 113), (0, 14, 115), (0, 13, 117), (0, 12, 123), + (0, 10, 128), (0, 8, 134), (1, 5, 139), (3, 5, 146), + (9, 7, 151), (17, 10, 157), (20, 13, 162), (24, 14, 168), + (28, 15, 172), (30, 17, 175), (28, 15, 177), (28, 15, 179), + (25, 14, 180), (22, 14, 181), (19, 14, 183), (16, 14, 184), + (14, 14, 184), (15, 17, 184), (15, 23, 183), (15, 26, 180), + (15, 28, 177), (15, 30, 173), (13, 31, 168), (10, 32, 162), + (6, 31, 157), (3, 30, 151), (1, 30, 147), (0, 31, 146), + (0, 31, 145), (0, 31, 145), (0, 31, 145), (0, 29, 146), + (0, 27, 147), (0, 27, 149), (0, 27, 150), (0, 24, 149), + (0, 24, 147), (0, 24, 145), (0, 26, 142), (0, 20, 139), + (0, 23, 138), (0, 22, 137), (0, 16, 137), (0, 16, 137), + (0, 13, 137), (0, 9, 137), (1, 7, 137), (3, 9, 135), + (5, 11, 134), (6, 12, 130), (7, 14, 126), (9, 16, 120), + (10, 16, 113), (10, 16, 109), (10, 16, 105), (11, 17, 104), + (13, 17, 103), (14, 17, 103), (17, 20, 105), (18, 18, 108), + (24, 21, 112), (25, 22, 116), (28, 25, 120), (32, 28, 123), + (33, 30, 124), (33, 32, 127), (35, 35, 128), (37, 40, 131) + ), + +// 567 For_Lenora +((169, 132, 163), (182, 138, 195), (176, 127, 195), (170, 117, 196), + (162, 104, 191), (154, 92, 187), (147, 81, 179), (141, 71, 171), + (111, 41, 143), (99, 39, 127), (88, 37, 112), (79, 39, 108), + (71, 42, 104), (69, 48, 107), (68, 54, 110), (69, 58, 117), + (70, 63, 125), (76, 91, 148), (88, 109, 163), (101, 128, 179), + (122, 143, 189), (144, 159, 199), (153, 167, 204), (163, 175, 210), + (171, 193, 224), (169, 190, 221), (167, 187, 219), (156, 179, 219), + (146, 171, 219), (134, 163, 214), (122, 155, 209), (105, 140, 189), + (93, 125, 166), (78, 117, 133), (64, 115, 108), (51, 113, 83), + (42, 116, 68), (33, 120, 53), (29, 119, 48), (26, 118, 44), + (33, 113, 45), (39, 101, 48), (46, 90, 52), (58, 78, 57), + (70, 67, 62), (75, 62, 63), (81, 58, 65), (80, 52, 71), + (76, 51, 78), (58, 38, 96), (59, 39, 102), (60, 40, 109), + (56, 34, 121), (53, 28, 134), (59, 23, 136), (65, 19, 139), + (91, 22, 134), (88, 19, 130), (86, 17, 127), (90, 15, 119), + (95, 14, 111), (91, 16, 109), (88, 18, 108), (84, 19, 109), + (85, 24, 107), (92, 23, 95), (86, 27, 93), (81, 31, 92), + (80, 33, 88), (80, 36, 85), (78, 34, 76), (68, 27, 65), + (44, 25, 53), (38, 20, 47), (32, 15, 41), (26, 18, 37), + (21, 22, 33), (20, 22, 39), (19, 23, 45), (20, 14, 51), + (20, 14, 53), (34, 19, 69), (49, 12, 83), (64, 5, 98), + (69, 9, 101), (75, 13, 104), (76, 27, 104), (72, 44, 97), + (73, 88, 91), (75, 107, 90), (77, 126, 90), (74, 126, 93), + (72, 126, 97), (72, 126, 97), (80, 110, 103), (94, 94, 114), + (107, 75, 131), (122, 51, 140), (125, 43, 140), (128, 36, 140), + (129, 37, 134), (131, 39, 129), (136, 45, 114), (140, 47, 102), + (131, 37, 94), (121, 29, 81), (112, 21, 69), (108, 22, 64), + (105, 23, 59), (94, 30, 60), (83, 31, 58), (71, 32, 55), + (66, 33, 50), (73, 40, 49), (75, 44, 52), (78, 48, 56), + (89, 56, 66), (113, 69, 79), (137, 77, 98), (159, 98, 115), + (187, 129, 139), (196, 142, 158), (206, 155, 177), (208, 160, 185), + (211, 165, 194), (215, 172, 196), (216, 169, 196), (209, 168, 195), + (192, 164, 194), (160, 146, 156), (153, 138, 144), (147, 130, 133), + (121, 114, 123), (97, 95, 107), (79, 79, 88), (73, 63, 73), + (69, 46, 73), (75, 46, 70), (82, 47, 68), (87, 51, 70), + (93, 55, 72), (102, 59, 86), (111, 68, 104), (118, 79, 123), + (130, 98, 139), (146, 119, 173), (144, 118, 181), (142, 117, 190), + (140, 114, 200), (137, 113, 199), (141, 106, 189), (136, 99, 169), + (114, 74, 130), (108, 71, 120), (103, 68, 111), (96, 71, 85), + (96, 79, 64), (89, 85, 47), (82, 91, 42), (77, 93, 44), + (81, 105, 61), (102, 139, 102), (103, 138, 110), (104, 138, 119), + (100, 128, 137), (93, 121, 147), (91, 126, 147), (91, 134, 143), + (106, 134, 137), (111, 135, 139), (117, 136, 141), (130, 149, 142), + (136, 155, 150), (149, 152, 146), (151, 132, 157), (148, 114, 159), + (131, 91, 162), (118, 71, 140), (98, 49, 121), (80, 37, 96), + (57, 31, 79), (46, 36, 58), (36, 44, 47), (30, 60, 36), + (21, 81, 19), (22, 82, 23), (23, 83, 28), (33, 84, 42), + (50, 88, 55), (71, 91, 57), (96, 90, 69), (121, 89, 84), + (142, 89, 104), (163, 102, 112), (186, 101, 120), (205, 99, 127), + (215, 95, 141), (218, 108, 150), (220, 116, 160), (216, 117, 169), + (210, 120, 182), (206, 130, 193), (205, 145, 202), (200, 154, 211), + (200, 165, 218), (204, 170, 220), (201, 169, 214), (191, 159, 205), + (183, 147, 196), (177, 135, 177), (160, 119, 157), (135, 105, 141), + (114, 92, 133), (106, 83, 124), (100, 75, 120), (100, 76, 125), + (108, 89, 138), (126, 107, 153), (140, 122, 170), (143, 133, 185), + (144, 142, 196), (148, 150, 201), (152, 147, 203), (149, 146, 197), + (143, 141, 195), (142, 140, 196), (146, 132, 199), (162, 134, 197), + (178, 142, 197), (194, 156, 206), (202, 167, 218), (215, 179, 226), + (225, 187, 227), (231, 193, 226), (226, 195, 227), (217, 193, 228), + (199, 189, 222), (182, 172, 205), (162, 154, 188), (145, 140, 167), + (123, 145, 143), (111, 146, 117), (106, 136, 99), (108, 120, 91), + (113, 114, 85), (118, 121, 88), (126, 121, 96), (127, 111, 108), + (133, 96, 118), (139, 85, 126), (144, 81, 130), (146, 80, 129), + (150, 90, 140), (159, 95, 144), (158, 106, 147), (164, 112, 142) + ), + +// 568 For_Stacy +((169, 133, 132), (195, 138, 160), (195, 127, 157), (196, 117, 155), + (191, 104, 147), (187, 92, 140), (179, 81, 128), (171, 71, 116), + (143, 41, 88), (127, 39, 80), (112, 37, 72), (108, 39, 78), + (104, 42, 84), (107, 48, 94), (110, 54, 104), (116, 58, 114), + (123, 63, 125), (122, 76, 148), (131, 88, 163), (140, 101, 179), + (158, 122, 189), (176, 144, 199), (183, 153, 204), (191, 163, 210), + (194, 171, 224), (193, 169, 221), (192, 167, 219), (187, 156, 219), + (183, 146, 219), (173, 134, 214), (163, 122, 209), (141, 105, 189), + (123, 93, 166), (85, 78, 133), (68, 84, 123), (51, 90, 113), + (42, 101, 116), (33, 113, 120), (29, 113, 119), (26, 113, 118), + (33, 113, 113), (39, 101, 101), (46, 90, 89), (56, 80, 75), + (66, 70, 62), (73, 70, 60), (81, 70, 58), (80, 56, 52), + (78, 51, 57), (96, 38, 84), (102, 39, 92), (109, 40, 100), + (121, 34, 112), (134, 28, 125), (136, 23, 118), (139, 19, 111), + (134, 22, 82), (130, 19, 78), (127, 17, 74), (119, 15, 59), + (111, 14, 44), (109, 16, 47), (108, 18, 51), (109, 19, 58), + (107, 24, 58), (95, 23, 37), (93, 27, 44), (92, 31, 51), + (88, 33, 49), (85, 36, 48), (78, 34, 38), (68, 27, 30), + (53, 25, 38), (47, 20, 33), (41, 15, 28), (35, 18, 30), + (30, 21, 33), (33, 20, 39), (37, 19, 45), (51, 14, 50), + (53, 14, 53), (69, 19, 61), (83, 12, 57), (98, 5, 53), + (101, 9, 54), (104, 13, 55), (104, 27, 67), (97, 44, 76), + (73, 73, 91), (75, 96, 108), (77, 120, 126), (74, 114, 126), + (72, 109, 126), (72, 109, 126), (80, 91, 110), (111, 94, 114), + (131, 75, 108), (140, 51, 82), (140, 43, 72), (140, 36, 63), + (135, 37, 57), (131, 39, 51), (136, 54, 45), (140, 72, 47), + (131, 60, 37), (121, 55, 29), (112, 50, 21), (108, 53, 22), + (105, 57, 23), (94, 54, 30), (83, 48, 31), (71, 42, 32), + (66, 44, 33), (73, 59, 40), (75, 62, 44), (78, 65, 48), + (89, 74, 56), (113, 96, 69), (137, 107, 77), (159, 133, 98), + (187, 169, 129), (196, 172, 142), (206, 176, 155), (208, 175, 160), + (211, 175, 165), (215, 185, 172), (216, 183, 169), (209, 176, 168), + (194, 164, 171), (160, 148, 146), (153, 144, 138), (147, 141, 130), + (123, 114, 117), (107, 95, 107), (86, 79, 88), (73, 63, 64), + (73, 46, 54), (77, 50, 50), (82, 55, 47), (87, 62, 51), + (93, 70, 55), (102, 68, 59), (111, 68, 68), (123, 79, 91), + (139, 98, 113), (173, 119, 154), (181, 118, 165), (190, 117, 176), + (200, 114, 187), (199, 113, 188), (189, 106, 167), (169, 99, 142), + (130, 74, 98), (120, 71, 90), (111, 68, 82), (96, 78, 71), + (86, 96, 64), (57, 89, 47), (42, 91, 43), (44, 93, 53), + (61, 105, 78), (102, 139, 133), (103, 133, 135), (104, 128, 138), + (104, 100, 137), (111, 93, 147), (104, 91, 147), (92, 91, 143), + (106, 107, 137), (112, 112, 139), (119, 117, 141), (130, 140, 149), + (136, 144, 155), (146, 152, 148), (157, 132, 142), (159, 114, 132), + (162, 91, 132), (140, 71, 103), (121, 49, 82), (96, 37, 61), + (79, 31, 60), (58, 36, 51), (37, 36, 47), (30, 58, 60), + (19, 81, 69), (21, 82, 74), (23, 83, 79), (33, 82, 84), + (50, 88, 87), (57, 91, 72), (79, 96, 69), (121, 120, 84), + (142, 119, 89), (163, 144, 102), (186, 155, 101), (205, 161, 99), + (215, 151, 95), (218, 159, 108), (220, 161, 116), (216, 148, 117), + (210, 135, 120), (206, 131, 130), (205, 145, 151), (211, 154, 174), + (218, 165, 191), (220, 170, 194), (214, 169, 189), (205, 159, 180), + (196, 147, 168), (177, 135, 141), (160, 119, 122), (141, 105, 116), + (133, 92, 117), (124, 83, 107), (120, 75, 102), (125, 76, 109), + (138, 89, 127), (153, 107, 141), (170, 122, 159), (185, 133, 183), + (190, 142, 196), (192, 148, 201), (200, 147, 203), (193, 146, 197), + (189, 141, 195), (190, 140, 196), (199, 132, 195), (197, 134, 178), + (197, 142, 170), (206, 156, 175), (218, 167, 191), (226, 179, 197), + (227, 187, 195), (231, 193, 194), (227, 195, 201), (228, 193, 210), + (222, 189, 217), (205, 172, 200), (188, 154, 185), (167, 140, 166), + (123, 128, 145), (111, 145, 146), (99, 136, 124), (91, 120, 99), + (88, 114, 85), (90, 121, 88), (105, 126, 96), (127, 127, 108), + (133, 105, 96), (139, 89, 85), (144, 85, 81), (146, 86, 80), + (150, 91, 90), (159, 100, 95), (158, 109, 106), (164, 126, 112) + ), + +// 569 Forest +((45, 71, 45), (42, 66, 42), (39, 61, 41), (36, 56, 41), + (32, 49, 35), (29, 42, 29), (32, 33, 27), (35, 25, 25), + (35, 25, 25), (35, 25, 25), (35, 25, 25), (35, 25, 25), + (35, 25, 25), (30, 30, 25), (25, 36, 25), (25, 36, 25), + (25, 37, 25), (33, 43, 28), (40, 48, 30), (47, 54, 32), + (54, 60, 33), (62, 67, 35), (65, 70, 35), (69, 74, 36), + (80, 84, 39), (84, 88, 41), (89, 93, 43), (92, 96, 44), + (96, 100, 45), (96, 100, 45), (97, 101, 45), (95, 101, 45), + (94, 100, 45), (88, 92, 41), (83, 87, 40), (78, 82, 39), + (72, 77, 37), (67, 72, 36), (63, 70, 36), (60, 68, 36), + (54, 64, 34), (51, 64, 34), (48, 64, 35), (50, 65, 36), + (52, 67, 38), (54, 68, 38), (56, 70, 39), (56, 73, 41), + (54, 75, 43), (57, 79, 44), (57, 79, 44), (58, 80, 44), + (57, 78, 43), (57, 77, 43), (55, 76, 43), (54, 75, 43), + (45, 67, 41), (40, 62, 38), (36, 58, 36), (33, 53, 35), + (31, 49, 35), (30, 47, 34), (29, 45, 34), (27, 41, 34), + (26, 38, 38), (35, 25, 25), (35, 25, 25), (35, 25, 25), + (35, 25, 25), (35, 25, 25), (35, 25, 25), (35, 25, 25), + (25, 37, 25), (26, 40, 29), (28, 43, 33), (31, 48, 36), + (35, 54, 39), (36, 57, 42), (38, 61, 45), (43, 70, 51), + (55, 82, 51), (88, 109, 62), (98, 118, 65), (109, 127, 69), + (113, 130, 70), (118, 133, 72), (119, 136, 71), (117, 136, 71), + (116, 133, 69), (117, 131, 67), (118, 130, 66), (116, 128, 64), + (115, 126, 62), (114, 121, 60), (111, 113, 56), (101, 105, 49), + (86, 91, 44), (65, 70, 34), (61, 64, 31), (57, 59, 28), + (56, 58, 27), (56, 58, 27), (58, 58, 28), (59, 61, 29), + (61, 61, 31), (58, 61, 31), (56, 61, 32), (56, 60, 31), + (56, 59, 31), (56, 59, 31), (58, 58, 30), (59, 59, 29), + (58, 58, 29), (55, 55, 28), (53, 53, 28), (51, 51, 28), + (47, 47, 27), (42, 42, 27), (38, 38, 26), (36, 26, 26), + (35, 25, 25), (35, 25, 25), (35, 25, 25), (35, 25, 25), + (35, 25, 25), (35, 25, 25), (35, 25, 25), (35, 25, 25), + (35, 25, 25), (35, 25, 25), (35, 25, 25), (35, 25, 25), + (35, 25, 25), (35, 25, 25), (25, 36, 25), (36, 36, 25), + (33, 38, 24), (33, 38, 24), (33, 38, 24), (35, 37, 24), + (37, 37, 24), (37, 37, 24), (37, 37, 25), (37, 37, 25), + (37, 37, 25), (30, 40, 25), (31, 40, 25), (33, 41, 25), + (31, 41, 26), (31, 41, 26), (27, 41, 27), (26, 41, 31), + (27, 42, 37), (27, 43, 35), (28, 44, 33), (29, 47, 34), + (31, 51, 39), (34, 56, 38), (37, 62, 37), (40, 67, 43), + (44, 71, 44), (54, 83, 50), (55, 87, 53), (56, 91, 56), + (67, 103, 63), (72, 116, 72), (81, 131, 85), (92, 147, 96), + (115, 178, 120), (120, 184, 122), (125, 191, 125), (129, 200, 143), + (132, 206, 146), (136, 209, 145), (134, 209, 151), (132, 209, 145), + (133, 208, 133), (139, 206, 130), (151, 205, 128), (156, 200, 123), + (155, 193, 117), (152, 184, 109), (137, 169, 101), (123, 153, 89), + (93, 119, 64), (88, 111, 59), (84, 104, 55), (79, 91, 46), + (74, 83, 40), (73, 77, 36), (66, 71, 34), (59, 66, 33), + (52, 62, 32), (49, 57, 31), (44, 54, 32), (42, 53, 32), + (41, 53, 33), (46, 56, 33), (50, 59, 34), (60, 63, 36), + (65, 68, 37), (72, 72, 38), (78, 78, 41), (80, 85, 46), + (89, 94, 50), (97, 107, 58), (108, 121, 66), (115, 134, 74), + (121, 143, 80), (129, 148, 82), (133, 151, 83), (134, 152, 83), + (131, 152, 82), (137, 154, 81), (142, 161, 82), (151, 172, 87), + (158, 184, 95), (163, 195, 103), (171, 205, 112), (184, 212, 114), + (188, 213, 114), (190, 210, 111), (184, 203, 105), (187, 198, 97), + (185, 196, 94), (184, 194, 92), (177, 194, 94), (179, 192, 95), + (174, 190, 98), (171, 186, 98), (157, 177, 95), (146, 164, 88), + (136, 148, 78), (120, 132, 67), (101, 115, 59), (88, 100, 51), + (73, 88, 47), (65, 79, 44), (58, 72, 41), (50, 66, 38), + (41, 60, 37), (35, 56, 39), (33, 52, 33), (32, 51, 32), + (33, 52, 33), (34, 55, 34), (41, 60, 37), (41, 66, 41), + (45, 72, 45), (45, 71, 45), (43, 70, 43), (42, 69, 46), + (42, 68, 45), (42, 67, 42), (44, 66, 40), (41, 66, 41) + ), + +// 570 Frivolous +((36, 180, 78), (49, 157, 77), (71, 156, 68), (93, 155, 59), + (123, 140, 55), (154, 125, 51), (165, 118, 52), (176, 112, 54), + (210, 76, 47), (202, 78, 49), (195, 80, 52), (179, 86, 47), + (163, 93, 43), (157, 103, 43), (152, 113, 44), (145, 121, 41), + (139, 129, 38), (137, 135, 28), (151, 133, 34), (165, 132, 41), + (170, 130, 43), (176, 128, 46), (183, 127, 45), (190, 127, 44), + (212, 131, 44), (221, 129, 44), (230, 128, 45), (225, 126, 38), + (221, 124, 32), (216, 121, 32), (211, 118, 33), (199, 110, 41), + (182, 115, 48), (168, 124, 68), (176, 138, 91), (184, 153, 114), + (194, 167, 136), (205, 182, 159), (215, 189, 170), (226, 196, 181), + (249, 219, 196), (251, 215, 189), (253, 212, 182), (252, 199, 153), + (251, 187, 124), (251, 179, 112), (251, 172, 101), (253, 156, 78), + (249, 139, 58), (242, 122, 24), (236, 120, 25), (230, 119, 27), + (224, 115, 30), (219, 111, 34), (216, 113, 36), (214, 115, 38), + (187, 118, 54), (176, 125, 68), (166, 132, 83), (168, 139, 93), + (170, 147, 104), (172, 154, 110), (174, 162, 117), (176, 183, 135), + (168, 193, 148), (170, 196, 143), (157, 192, 133), (145, 188, 124), + (137, 178, 116), (129, 169, 109), (124, 146, 86), (131, 127, 79), + (156, 86, 55), (172, 78, 50), (188, 71, 46), (208, 72, 46), + (229, 73, 46), (233, 76, 45), (238, 79, 45), (237, 90, 44), + (238, 96, 43), (248, 100, 45), (239, 105, 50), (230, 110, 56), + (224, 112, 57), (219, 115, 59), (207, 122, 63), (188, 134, 72), + (146, 153, 82), (133, 154, 80), (120, 156, 79), (115, 155, 81), + (110, 154, 83), (109, 151, 85), (113, 142, 84), (122, 130, 77), + (137, 116, 75), (176, 95, 72), (193, 95, 75), (210, 95, 79), + (217, 98, 84), (225, 101, 89), (236, 105, 101), (242, 110, 104), + (249, 143, 133), (249, 154, 146), (250, 165, 159), (247, 164, 157), + (245, 164, 156), (239, 159, 149), (234, 162, 145), (233, 160, 136), + (225, 150, 125), (197, 121, 95), (194, 120, 91), (192, 119, 87), + (187, 116, 84), (178, 110, 83), (160, 101, 79), (147, 99, 76), + (126, 92, 63), (119, 87, 62), (112, 82, 62), (108, 79, 63), + (104, 76, 65), (104, 71, 60), (108, 66, 62), (125, 76, 69), + (147, 87, 89), (183, 101, 107), (190, 108, 105), (197, 115, 104), + (214, 129, 102), (230, 135, 100), (243, 134, 99), (247, 137, 91), + (243, 139, 79), (244, 139, 84), (246, 139, 89), (243, 139, 92), + (241, 140, 96), (239, 138, 98), (240, 136, 99), (241, 130, 103), + (238, 118, 105), (219, 82, 97), (212, 73, 93), (206, 65, 90), + (205, 58, 83), (199, 55, 81), (203, 61, 86), (201, 70, 88), + (214, 106, 88), (220, 117, 93), (226, 129, 99), (233, 149, 111), + (231, 165, 112), (220, 173, 104), (208, 172, 96), (193, 169, 99), + (176, 159, 98), (147, 120, 68), (142, 112, 61), (137, 104, 54), + (129, 92, 46), (128, 86, 47), (137, 75, 48), (145, 74, 44), + (148, 100, 55), (157, 108, 63), (166, 117, 71), (183, 133, 77), + (197, 154, 68), (205, 172, 61), (215, 180, 57), (219, 175, 61), + (226, 175, 52), (236, 172, 37), (242, 163, 25), (243, 150, 33), + (236, 141, 46), (234, 134, 52), (236, 123, 50), (234, 114, 51), + (216, 112, 55), (212, 112, 53), (208, 112, 51), (201, 110, 46), + (201, 108, 55), (203, 115, 67), (208, 125, 85), (214, 140, 99), + (220, 155, 111), (222, 179, 124), (218, 187, 126), (202, 186, 130), + (184, 169, 122), (162, 161, 120), (146, 143, 101), (121, 122, 88), + (102, 91, 77), (96, 68, 77), (111, 48, 76), (135, 41, 72), + (151, 38, 68), (171, 45, 64), (190, 56, 66), (212, 69, 68), + (218, 81, 73), (216, 87, 82), (212, 98, 92), (212, 110, 100), + (214, 118, 106), (211, 112, 110), (213, 99, 108), (219, 92, 104), + (231, 89, 99), (240, 82, 90), (237, 70, 79), (227, 61, 71), + (215, 66, 70), (214, 75, 74), (211, 94, 80), (204, 108, 89), + (196, 123, 101), (200, 131, 114), (211, 143, 124), (222, 148, 128), + (226, 148, 132), (230, 134, 136), (235, 117, 138), (241, 106, 131), + (246, 108, 124), (244, 108, 116), (234, 100, 109), (219, 94, 100), + (205, 99, 94), (187, 111, 89), (166, 118, 85), (140, 115, 80), + (117, 108, 76), (102, 105, 74), (91, 112, 72), (85, 116, 74), + (81, 114, 77), (81, 112, 80), (80, 119, 77), (75, 127, 76), + (73, 129, 76), (70, 131, 82), (69, 139, 80), (62, 149, 78), + (52, 152, 74), (43, 145, 77), (38, 148, 79), (38, 166, 78) + ), + +// 571 Fun_Stuff +((41, 88, 87), (43, 107, 62), (54, 105, 64), (66, 103, 66), + (86, 105, 67), (107, 107, 69), (115, 112, 62), (124, 117, 56), + (139, 127, 28), (147, 127, 23), (156, 128, 18), (168, 129, 19), + (181, 130, 20), (183, 126, 18), (185, 123, 17), (182, 120, 19), + (179, 117, 22), (153, 112, 44), (148, 108, 54), (144, 104, 64), + (152, 91, 73), (160, 78, 83), (162, 74, 88), (165, 70, 93), + (161, 77, 108), (159, 81, 106), (157, 86, 105), (155, 87, 105), + (153, 89, 105), (149, 91, 104), (145, 94, 104), (133, 101, 98), + (119, 115, 88), (85, 134, 65), (72, 143, 64), (59, 152, 64), + (48, 151, 57), (38, 151, 51), (37, 150, 47), (37, 149, 43), + (35, 136, 37), (41, 137, 50), (47, 139, 63), (62, 134, 66), + (78, 129, 69), (81, 125, 69), (85, 122, 69), (97, 109, 69), + (106, 95, 79), (114, 77, 92), (125, 73, 86), (136, 69, 80), + (141, 62, 74), (147, 56, 69), (142, 53, 70), (137, 51, 71), + (115, 42, 76), (107, 39, 74), (99, 37, 73), (92, 40, 74), + (85, 43, 76), (81, 44, 78), (78, 45, 81), (72, 50, 88), + (72, 57, 93), (85, 75, 80), (96, 89, 67), (108, 104, 54), + (112, 110, 49), (116, 117, 45), (126, 125, 45), (135, 135, 39), + (155, 151, 27), (162, 154, 18), (170, 157, 10), (164, 151, 11), + (158, 146, 13), (151, 144, 13), (145, 143, 14), (133, 140, 15), + (125, 135, 15), (136, 112, 11), (136, 95, 14), (136, 78, 17), + (130, 74, 20), (125, 71, 23), (107, 70, 28), (98, 68, 33), + (94, 65, 39), (97, 57, 45), (101, 49, 51), (97, 47, 55), + (94, 46, 59), (88, 44, 66), (75, 47, 76), (59, 49, 82), + (53, 53, 86), (51, 57, 97), (54, 50, 100), (58, 43, 104), + (57, 38, 104), (56, 33, 105), (56, 27, 105), (56, 26, 107), + (58, 27, 102), (60, 24, 102), (62, 21, 102), (62, 18, 101), + (63, 15, 101), (65, 12, 102), (73, 16, 97), (82, 23, 89), + (97, 32, 81), (115, 45, 70), (113, 47, 70), (111, 50, 70), + (110, 55, 67), (107, 58, 63), (108, 61, 54), (108, 69, 41), + (103, 73, 26), (91, 72, 25), (79, 72, 24), (73, 69, 23), + (68, 67, 23), (53, 64, 18), (50, 57, 16), (50, 51, 12), + (48, 51, 11), (54, 45, 15), (54, 45, 18), (54, 46, 22), + (55, 42, 32), (59, 37, 42), (61, 35, 51), (63, 33, 59), + (78, 37, 76), (84, 43, 86), (90, 50, 97), (95, 53, 101), + (100, 57, 106), (110, 65, 112), (115, 71, 113), (127, 76, 115), + (135, 86, 114), (159, 111, 118), (165, 117, 116), (172, 124, 115), + (177, 139, 109), (185, 147, 104), (190, 150, 96), (193, 150, 97), + (201, 125, 101), (201, 125, 97), (201, 125, 94), (201, 128, 85), + (200, 130, 66), (193, 134, 51), (183, 130, 47), (172, 117, 43), + (156, 111, 36), (127, 122, 27), (117, 128, 22), (107, 134, 18), + (95, 147, 21), (83, 153, 26), (74, 151, 31), (75, 152, 39), + (67, 149, 51), (64, 149, 56), (62, 150, 62), (62, 150, 74), + (63, 145, 82), (79, 142, 82), (110, 131, 79), (129, 128, 70), + (141, 125, 61), (146, 121, 55), (140, 115, 52), (143, 108, 48), + (155, 93, 44), (162, 78, 44), (172, 70, 44), (182, 68, 42), + (181, 73, 37), (183, 73, 35), (185, 74, 34), (180, 66, 36), + (176, 52, 44), (180, 41, 49), (178, 38, 48), (173, 36, 43), + (171, 42, 34), (162, 46, 21), (145, 42, 17), (132, 31, 16), + (121, 23, 19), (114, 14, 21), (107, 10, 27), (101, 12, 27), + (90, 15, 29), (77, 13, 35), (66, 16, 45), (62, 17, 53), + (56, 17, 63), (58, 16, 71), (57, 16, 75), (56, 13, 76), + (56, 11, 79), (58, 10, 82), (57, 10, 82), (60, 8, 81), + (60, 6, 77), (59, 6, 73), (58, 13, 65), (60, 21, 62), + (64, 32, 53), (68, 41, 44), (73, 47, 37), (73, 46, 34), + (70, 47, 29), (62, 50, 32), (59, 54, 35), (55, 58, 37), + (56, 60, 38), (58, 54, 40), (60, 43, 42), (56, 33, 50), + (51, 26, 59), (46, 21, 68), (46, 17, 75), (47, 14, 82), + (51, 11, 88), (54, 8, 94), (61, 6, 100), (66, 10, 106), + (67, 16, 110), (66, 23, 113), (67, 27, 112), (63, 30, 114), + (66, 25, 114), (74, 23, 112), (78, 24, 113), (80, 25, 114), + (81, 26, 112), (73, 29, 114), (63, 27, 113), (60, 25, 110), + (57, 28, 105), (54, 36, 100), (53, 47, 91), (46, 49, 90), + (40, 49, 93), (37, 51, 97), (36, 57, 101), (38, 65, 99) + ), + +// 572 Getting_a_Tan +((129, 65, 31), (131, 65, 32), (128, 61, 30), (125, 58, 28), + (113, 45, 20), (102, 33, 13), (99, 32, 13), (97, 31, 13), + (91, 27, 10), (88, 26, 10), (85, 26, 10), (81, 27, 10), + (77, 28, 10), (76, 27, 10), (76, 27, 11), (79, 28, 11), + (82, 29, 12), (106, 43, 23), (116, 53, 25), (127, 63, 28), + (136, 70, 29), (145, 78, 31), (149, 79, 31), (154, 81, 32), + (167, 89, 34), (169, 91, 33), (172, 93, 33), (169, 89, 30), + (166, 86, 27), (161, 81, 25), (157, 76, 24), (145, 65, 18), + (134, 57, 15), (113, 43, 10), (102, 37, 11), (92, 32, 12), + (78, 24, 9), (64, 17, 7), (56, 14, 5), (49, 11, 4), + (24, 2, 0), (16, 1, 0), (9, 1, 0), (5, 1, 0), + (2, 1, 0), (1, 1, 0), (1, 1, 0), (2, 1, 0), + (3, 2, 2), (16, 8, 3), (28, 16, 8), (41, 24, 13), + (60, 40, 25), (79, 57, 37), (90, 67, 44), (101, 77, 52), + (144, 116, 78), (160, 126, 80), (176, 137, 82), (186, 143, 85), + (196, 149, 89), (197, 150, 89), (199, 152, 90), (198, 151, 92), + (190, 144, 86), (156, 106, 56), (134, 86, 42), (113, 66, 28), + (103, 58, 24), (94, 50, 21), (76, 39, 16), (60, 28, 11), + (34, 11, 2), (25, 6, 1), (17, 2, 0), (12, 1, 0), + (7, 1, 0), (6, 1, 0), (5, 1, 1), (4, 0, 1), + (3, 0, 1), (4, 0, 1), (4, 0, 1), (4, 0, 1), + (4, 0, 1), (4, 0, 1), (7, 1, 1), (10, 2, 2), + (25, 5, 1), (34, 8, 1), (43, 12, 1), (48, 13, 1), + (54, 15, 1), (63, 20, 2), (72, 25, 2), (84, 31, 5), + (97, 39, 8), (123, 55, 13), (131, 62, 13), (139, 70, 13), + (143, 73, 13), (147, 76, 14), (154, 83, 18), (164, 91, 23), + (186, 114, 46), (196, 130, 61), (206, 146, 76), (209, 154, 85), + (213, 163, 95), (220, 175, 115), (226, 185, 130), (232, 196, 151), + (239, 211, 167), (249, 236, 195), (250, 241, 199), (251, 246, 203), + (253, 251, 203), (251, 245, 195), (248, 237, 181), (246, 225, 167), + (246, 206, 139), (247, 205, 131), (249, 204, 124), (249, 202, 117), + (249, 201, 111), (244, 189, 99), (242, 167, 90), (236, 147, 76), + (232, 131, 69), (237, 117, 61), (233, 113, 58), (230, 109, 55), + (222, 97, 51), (203, 85, 43), (181, 67, 33), (163, 47, 23), + (137, 28, 11), (124, 26, 9), (111, 24, 8), (101, 24, 8), + (91, 24, 8), (72, 20, 7), (61, 17, 5), (54, 15, 5), + (51, 13, 4), (56, 12, 3), (59, 13, 3), (62, 14, 3), + (70, 16, 2), (74, 18, 1), (77, 20, 0), (76, 21, 0), + (78, 23, 2), (80, 25, 3), (83, 27, 5), (88, 31, 9), + (95, 36, 11), (98, 40, 14), (102, 47, 16), (107, 54, 20), + (116, 63, 24), (143, 97, 50), (151, 105, 59), (160, 114, 69), + (177, 135, 85), (193, 154, 98), (208, 167, 105), (214, 176, 110), + (222, 179, 111), (220, 176, 111), (218, 173, 111), (209, 166, 109), + (198, 154, 104), (181, 139, 95), (165, 121, 79), (147, 100, 63), + (129, 78, 48), (108, 57, 33), (88, 38, 20), (67, 25, 14), + (52, 17, 9), (42, 11, 6), (36, 8, 5), (32, 8, 4), + (27, 6, 2), (26, 6, 2), (25, 6, 2), (24, 6, 2), + (22, 4, 3), (20, 4, 4), (19, 4, 5), (18, 4, 6), + (16, 5, 7), (14, 6, 7), (12, 6, 7), (12, 6, 7), + (15, 7, 8), (21, 12, 11), (32, 21, 18), (47, 36, 25), + (67, 52, 36), (89, 71, 51), (111, 92, 68), (133, 112, 87), + (152, 132, 110), (171, 155, 130), (191, 174, 150), (210, 193, 167), + (227, 211, 179), (240, 222, 182), (247, 223, 180), (248, 220, 173), + (248, 211, 162), (248, 197, 149), (248, 186, 138), (246, 177, 125), + (240, 166, 106), (232, 153, 86), (219, 140, 71), (205, 122, 54), + (190, 105, 47), (174, 93, 45), (157, 83, 40), (143, 73, 35), + (126, 68, 33), (111, 61, 27), (98, 54, 24), (90, 50, 24), + (85, 47, 23), (87, 45, 19), (93, 47, 17), (101, 51, 14), + (111, 54, 12), (121, 62, 14), (131, 73, 19), (147, 83, 21), + (163, 97, 27), (180, 114, 37), (195, 134, 49), (207, 150, 61), + (215, 166, 75), (220, 173, 82), (226, 175, 83), (230, 172, 85), + (233, 174, 87), (233, 173, 88), (230, 175, 91), (220, 169, 93), + (211, 160, 88), (204, 145, 80), (201, 139, 78), (198, 128, 71), + (187, 114, 58), (172, 100, 51), (155, 87, 44), (138, 68, 31) + ), + +// 573 gipper +((190, 180, 144), (164, 160, 149), (146, 150, 148), (128, 141, 148), + (114, 129, 137), (101, 117, 126), (91, 110, 123), (82, 104, 121), + (66, 90, 114), (70, 91, 116), (75, 92, 118), (93, 97, 112), + (111, 103, 106), (122, 101, 102), (133, 100, 98), (141, 101, 94), + (149, 102, 91), (180, 104, 83), (185, 103, 77), (190, 103, 71), + (186, 97, 64), (183, 91, 57), (181, 89, 54), (179, 88, 51), + (175, 87, 48), (165, 85, 52), (156, 83, 57), (132, 77, 60), + (108, 71, 64), (99, 69, 65), (90, 67, 66), (72, 64, 67), + (65, 66, 70), (69, 70, 75), (58, 67, 78), (47, 64, 82), + (34, 55, 83), (21, 47, 85), (16, 45, 86), (12, 43, 88), + (29, 49, 88), (36, 53, 89), (43, 58, 90), (43, 58, 91), + (44, 59, 92), (44, 60, 93), (45, 61, 94), (28, 53, 93), + (33, 55, 94), (47, 58, 92), (47, 57, 91), (48, 57, 91), + (39, 53, 90), (30, 49, 90), (23, 46, 90), (16, 44, 90), + (14, 40, 85), (14, 40, 85), (14, 40, 86), (15, 41, 88), + (16, 43, 90), (16, 44, 91), (16, 45, 92), (16, 47, 94), + (16, 48, 95), (16, 50, 98), (16, 50, 98), (17, 50, 98), + (17, 49, 98), (17, 49, 98), (16, 48, 97), (15, 46, 95), + (14, 45, 93), (13, 45, 93), (13, 45, 93), (13, 45, 93), + (13, 45, 94), (13, 45, 94), (13, 45, 94), (14, 45, 95), + (13, 47, 97), (14, 51, 100), (15, 54, 103), (17, 57, 107), + (24, 58, 109), (31, 59, 111), (48, 63, 115), (65, 69, 116), + (100, 86, 123), (111, 97, 125), (122, 109, 127), (129, 110, 130), + (136, 112, 133), (152, 112, 142), (169, 110, 138), (186, 112, 134), + (201, 113, 132), (220, 131, 116), (217, 131, 117), (214, 132, 118), + (208, 127, 117), (203, 122, 116), (188, 112, 114), (170, 99, 115), + (142, 90, 107), (129, 92, 105), (117, 94, 104), (111, 92, 105), + (106, 90, 107), (90, 86, 112), (74, 80, 116), (60, 75, 120), + (46, 71, 123), (26, 70, 125), (25, 69, 124), (25, 69, 124), + (25, 68, 124), (24, 68, 123), (23, 67, 121), (23, 66, 121), + (21, 65, 120), (21, 64, 119), (21, 64, 119), (21, 64, 119), + (21, 64, 119), (22, 64, 118), (22, 63, 117), (21, 63, 115), + (21, 62, 114), (20, 60, 111), (20, 59, 111), (20, 59, 111), + (19, 58, 109), (18, 56, 106), (18, 54, 103), (17, 51, 98), + (15, 45, 87), (15, 41, 83), (15, 38, 79), (14, 36, 77), + (13, 35, 75), (11, 33, 74), (10, 31, 72), (8, 30, 71), + (7, 30, 71), (9, 30, 70), (9, 30, 70), (10, 31, 71), + (10, 32, 73), (11, 33, 76), (16, 32, 79), (29, 35, 81), + (67, 48, 82), (77, 52, 82), (88, 56, 82), (108, 68, 84), + (121, 82, 89), (133, 93, 96), (150, 103, 100), (167, 111, 102), + (184, 120, 101), (215, 134, 89), (211, 135, 90), (208, 137, 92), + (194, 139, 95), (178, 138, 100), (159, 132, 104), (140, 123, 105), + (118, 110, 93), (108, 104, 91), (98, 98, 89), (80, 88, 88), + (64, 82, 91), (58, 76, 95), (56, 69, 102), (57, 65, 110), + (58, 65, 111), (57, 66, 111), (57, 66, 111), (46, 66, 114), + (46, 68, 115), (48, 68, 116), (60, 71, 120), (61, 72, 123), + (60, 73, 124), (54, 72, 124), (48, 71, 125), (35, 68, 122), + (24, 64, 118), (32, 62, 110), (47, 63, 104), (63, 64, 96), + (77, 66, 87), (92, 67, 81), (101, 67, 77), (93, 67, 82), + (88, 65, 82), (89, 65, 83), (89, 63, 83), (89, 63, 79), + (93, 61, 75), (100, 60, 68), (88, 56, 70), (72, 53, 72), + (55, 50, 77), (40, 47, 85), (26, 47, 92), (18, 49, 97), + (19, 51, 101), (32, 50, 104), (47, 53, 110), (64, 60, 116), + (82, 72, 119), (101, 85, 119), (116, 97, 119), (119, 112, 119), + (136, 122, 115), (154, 132, 116), (171, 141, 120), (187, 154, 125), + (206, 165, 120), (223, 169, 113), (221, 176, 107), (217, 176, 97), + (202, 170, 93), (186, 160, 90), (168, 151, 96), (151, 145, 99), + (140, 134, 99), (125, 124, 99), (118, 114, 96), (100, 101, 97), + (83, 88, 96), (67, 78, 100), (50, 72, 105), (35, 65, 109), + (22, 60, 110), (21, 59, 109), (20, 58, 108), (20, 58, 108), + (20, 58, 109), (21, 60, 110), (28, 64, 109), (42, 72, 108), + (58, 82, 108), (74, 96, 109), (93, 109, 112), (112, 123, 118), + (126, 134, 129), (139, 146, 140), (156, 158, 146), (173, 167, 150), + (184, 179, 151), (197, 185, 144), (208, 189, 136), (202, 185, 137) + ), + +// 574 Glade +((71, 113, 64), (30, 66, 27), (16, 53, 21), (3, 40, 16), + (1, 39, 17), (0, 39, 19), (0, 39, 19), (0, 39, 20), + (0, 38, 22), (0, 37, 22), (0, 37, 23), (0, 38, 24), + (0, 39, 26), (0, 38, 25), (0, 38, 25), (0, 38, 25), + (1, 38, 26), (5, 43, 30), (9, 51, 32), (14, 60, 35), + (30, 83, 50), (46, 107, 66), (56, 119, 76), (66, 131, 86), + (102, 169, 102), (130, 185, 109), (158, 201, 116), (160, 195, 109), + (163, 190, 103), (161, 183, 91), (160, 176, 80), (150, 153, 59), + (129, 138, 47), (79, 99, 28), (58, 91, 27), (38, 84, 27), + (32, 85, 31), (26, 86, 35), (33, 91, 37), (40, 96, 40), + (77, 133, 53), (102, 146, 58), (127, 160, 64), (143, 166, 62), + (160, 172, 60), (163, 171, 61), (166, 170, 63), (171, 167, 70), + (171, 162, 67), (157, 144, 64), (147, 140, 64), (137, 136, 64), + (136, 135, 63), (136, 135, 63), (140, 133, 59), (144, 131, 56), + (138, 123, 35), (129, 120, 34), (121, 117, 33), (110, 109, 30), + (100, 102, 28), (92, 101, 27), (84, 101, 27), (77, 107, 27), + (73, 114, 34), (52, 116, 41), (64, 129, 43), (76, 142, 46), + (83, 148, 48), (90, 154, 50), (88, 168, 72), (82, 179, 96), + (109, 203, 121), (110, 201, 122), (112, 200, 124), (96, 185, 117), + (80, 170, 110), (75, 157, 98), (71, 144, 86), (58, 119, 67), + (42, 94, 43), (9, 59, 27), (6, 49, 24), (3, 39, 22), + (2, 37, 21), (2, 36, 20), (1, 35, 18), (0, 34, 16), + (0, 34, 16), (0, 34, 15), (0, 34, 14), (0, 34, 14), + (1, 35, 14), (2, 37, 14), (3, 38, 11), (3, 40, 9), + (4, 44, 9), (15, 67, 22), (31, 89, 37), (47, 112, 52), + (56, 125, 64), (65, 138, 77), (75, 156, 104), (90, 177, 112), + (136, 199, 116), (146, 191, 109), (157, 184, 103), (162, 178, 94), + (167, 173, 86), (179, 169, 68), (190, 163, 48), (198, 163, 47), + (201, 157, 48), (180, 156, 47), (171, 154, 48), (162, 153, 49), + (144, 139, 48), (120, 121, 42), (91, 104, 37), (65, 88, 34), + (35, 67, 30), (26, 63, 31), (17, 60, 32), (15, 58, 32), + (14, 57, 32), (11, 56, 32), (11, 57, 31), (9, 55, 32), + (7, 51, 30), (5, 42, 27), (5, 40, 27), (5, 39, 28), + (5, 38, 27), (4, 38, 26), (6, 39, 26), (7, 39, 26), + (8, 41, 23), (8, 40, 21), (9, 40, 19), (11, 40, 18), + (14, 41, 18), (28, 51, 17), (49, 64, 18), (67, 76, 18), + (81, 79, 19), (109, 94, 16), (110, 96, 14), (111, 99, 13), + (104, 91, 14), (89, 84, 13), (77, 73, 10), (59, 65, 4), + (26, 46, 1), (22, 43, 1), (19, 41, 2), (19, 40, 1), + (22, 41, 0), (27, 38, 0), (25, 36, 1), (25, 35, 2), + (25, 37, 4), (25, 33, 3), (22, 31, 3), (19, 30, 3), + (14, 31, 5), (10, 31, 7), (7, 32, 9), (6, 34, 11), + (16, 49, 21), (24, 55, 24), (33, 61, 28), (49, 75, 34), + (61, 92, 42), (71, 111, 47), (87, 120, 50), (95, 125, 50), + (95, 126, 52), (83, 124, 53), (69, 111, 48), (58, 98, 40), + (46, 83, 31), (36, 72, 28), (29, 62, 23), (30, 61, 21), + (40, 67, 13), (46, 71, 12), (52, 76, 12), (67, 88, 16), + (82, 101, 20), (90, 107, 23), (103, 117, 25), (121, 130, 34), + (144, 151, 43), (161, 166, 55), (176, 182, 66), (187, 192, 77), + (193, 203, 81), (192, 202, 78), (187, 198, 79), (177, 188, 79), + (157, 175, 72), (131, 156, 58), (105, 142, 50), (93, 138, 56), + (89, 149, 76), (85, 160, 95), (77, 174, 113), (80, 183, 119), + (93, 194, 124), (103, 197, 121), (102, 195, 116), (99, 180, 105), + (94, 154, 81), (84, 126, 54), (69, 104, 30), (55, 86, 22), + (42, 68, 20), (28, 51, 18), (16, 42, 17), (9, 35, 17), + (6, 33, 19), (4, 32, 20), (3, 33, 19), (3, 32, 20), + (2, 32, 21), (1, 32, 22), (0, 34, 21), (1, 36, 20), + (2, 37, 19), (2, 36, 16), (2, 36, 13), (3, 36, 12), + (3, 37, 13), (3, 36, 14), (4, 36, 13), (5, 35, 14), + (8, 36, 16), (11, 38, 18), (17, 44, 22), (28, 52, 26), + (39, 61, 28), (48, 65, 23), (50, 74, 23), (51, 80, 24), + (50, 87, 30), (57, 89, 27), (62, 94, 28), (68, 96, 25), + (71, 99, 33), (80, 105, 37), (94, 116, 50), (109, 137, 67), + (122, 149, 78), (110, 138, 69), (96, 115, 53), (74, 108, 57) + ), + +// 575 Glory +((143, 87, 62), (67, 69, 110), (68, 69, 103), (70, 69, 97), + (93, 82, 82), (116, 95, 67), (130, 101, 60), (145, 107, 54), + (160, 132, 42), (162, 138, 46), (165, 144, 50), (158, 149, 69), + (151, 155, 89), (166, 167, 106), (181, 180, 124), (187, 188, 124), + (194, 196, 125), (204, 187, 105), (211, 180, 92), (219, 174, 80), + (217, 154, 71), (215, 135, 63), (212, 133, 68), (210, 131, 74), + (208, 152, 95), (201, 170, 84), (194, 189, 74), (195, 187, 64), + (197, 186, 55), (195, 179, 53), (194, 173, 51), (197, 164, 43), + (198, 162, 46), (203, 170, 67), (206, 181, 60), (209, 193, 54), + (215, 189, 44), (222, 185, 35), (223, 183, 29), (225, 182, 24), + (222, 178, 8), (218, 181, 9), (214, 184, 10), (212, 174, 15), + (211, 165, 21), (210, 161, 20), (209, 157, 20), (204, 137, 20), + (207, 131, 32), (200, 117, 30), (190, 114, 35), (180, 111, 41), + (170, 97, 48), (160, 84, 55), (152, 78, 58), (145, 72, 61), + (135, 42, 55), (139, 45, 52), (144, 48, 50), (153, 62, 39), + (163, 77, 29), (169, 83, 29), (175, 90, 29), (180, 108, 26), + (184, 122, 22), (176, 143, 9), (177, 149, 11), (179, 155, 13), + (173, 155, 12), (168, 156, 12), (165, 142, 18), (170, 128, 37), + (151, 85, 72), (147, 80, 105), (144, 76, 138), (153, 74, 145), + (163, 73, 152), (165, 77, 150), (167, 81, 149), (187, 108, 129), + (189, 122, 98), (184, 146, 54), (183, 154, 51), (182, 162, 49), + (182, 157, 50), (183, 153, 51), (174, 142, 60), (162, 112, 63), + (123, 70, 73), (115, 48, 70), (107, 27, 68), (107, 28, 62), + (108, 29, 57), (118, 23, 55), (126, 14, 41), (135, 18, 27), + (134, 24, 29), (111, 21, 45), (96, 25, 57), (81, 30, 69), + (72, 34, 72), (64, 38, 75), (55, 42, 83), (49, 55, 91), + (40, 67, 107), (43, 63, 115), (46, 60, 123), (47, 56, 125), + (48, 52, 128), (60, 38, 124), (74, 25, 120), (75, 21, 109), + (89, 23, 97), (117, 51, 87), (123, 57, 82), (129, 63, 78), + (147, 80, 81), (139, 97, 81), (130, 105, 83), (115, 101, 91), + (73, 86, 114), (56, 69, 127), (39, 52, 140), (35, 51, 141), + (31, 50, 143), (25, 40, 138), (31, 33, 129), (36, 48, 117), + (29, 37, 107), (50, 34, 94), (53, 29, 91), (57, 25, 88), + (69, 16, 85), (74, 18, 66), (73, 25, 53), (79, 31, 49), + (61, 63, 47), (49, 67, 64), (38, 71, 81), (33, 77, 91), + (29, 83, 102), (15, 77, 116), (18, 66, 126), (34, 56, 152), + (50, 41, 165), (80, 18, 158), (91, 17, 157), (103, 16, 157), + (123, 15, 145), (128, 26, 134), (143, 49, 111), (167, 60, 96), + (178, 93, 69), (184, 97, 62), (190, 101, 55), (192, 90, 47), + (189, 81, 47), (180, 75, 60), (175, 62, 58), (171, 40, 57), + (153, 30, 78), (107, 19, 99), (100, 20, 103), (94, 22, 108), + (75, 30, 126), (72, 30, 131), (91, 39, 124), (105, 54, 114), + (159, 69, 89), (167, 76, 82), (175, 84, 76), (177, 99, 74), + (185, 115, 77), (198, 130, 75), (205, 142, 87), (207, 148, 85), + (218, 150, 65), (231, 152, 57), (226, 140, 46), (216, 134, 26), + (211, 126, 11), (195, 110, 11), (173, 95, 17), (156, 75, 19), + (111, 52, 40), (104, 45, 42), (97, 39, 44), (90, 33, 46), + (87, 34, 50), (91, 46, 43), (109, 55, 37), (132, 58, 33), + (140, 74, 21), (144, 92, 17), (136, 88, 16), (110, 76, 10), + (90, 67, 18), (62, 58, 32), (31, 44, 40), (18, 40, 46), + (18, 44, 56), (30, 50, 50), (46, 51, 35), (69, 45, 32), + (84, 40, 19), (96, 29, 13), (108, 15, 26), (107, 11, 35), + (97, 13, 52), (86, 17, 72), (82, 22, 84), (85, 28, 90), + (95, 42, 89), (106, 58, 77), (118, 53, 65), (130, 52, 50), + (142, 58, 29), (147, 50, 20), (146, 50, 21), (152, 56, 21), + (161, 60, 25), (173, 71, 36), (182, 84, 46), (183, 98, 57), + (181, 110, 79), (178, 124, 109), (168, 132, 111), (151, 124, 107), + (148, 117, 133), (131, 105, 137), (114, 83, 133), (119, 58, 146), + (106, 40, 153), (98, 31, 151), (103, 18, 149), (94, 13, 143), + (89, 11, 132), (88, 10, 122), (88, 17, 119), (90, 35, 122), + (95, 55, 117), (100, 62, 117), (98, 79, 116), (92, 97, 106), + (79, 94, 102), (72, 89, 103), (65, 77, 97), (60, 65, 91), + (66, 53, 88), (82, 34, 83), (103, 30, 71), (122, 39, 57), + (155, 55, 44), (178, 70, 32), (164, 71, 43), (152, 84, 61) + ), + +// 576 Gold_and_Blue +((161, 125, 84), (199, 134, 61), (210, 140, 61), (222, 146, 62), + (221, 143, 62), (221, 140, 63), (217, 137, 60), (214, 135, 58), + (201, 117, 55), (192, 106, 45), (183, 96, 36), (165, 82, 26), + (147, 69, 17), (134, 56, 14), (121, 43, 12), (118, 41, 10), + (115, 39, 9), (92, 48, 15), (87, 52, 20), (82, 56, 26), + (83, 53, 26), (85, 50, 26), (82, 50, 25), (80, 50, 25), + (68, 63, 37), (63, 63, 41), (59, 63, 45), (52, 65, 51), + (46, 68, 57), (44, 72, 64), (42, 76, 71), (34, 82, 82), + (31, 90, 97), (33, 110, 120), (41, 121, 129), (50, 132, 139), + (54, 140, 146), (59, 148, 153), (58, 148, 153), (58, 149, 154), + (64, 136, 141), (59, 130, 134), (55, 124, 127), (49, 114, 119), + (44, 105, 111), (43, 98, 105), (43, 91, 99), (43, 77, 87), + (40, 63, 76), (28, 42, 57), (25, 36, 49), (23, 31, 42), + (24, 28, 37), (26, 26, 32), (28, 26, 32), (30, 27, 32), + (50, 41, 32), (70, 53, 35), (90, 65, 38), (111, 79, 46), + (133, 94, 55), (141, 98, 57), (149, 102, 60), (165, 108, 59), + (176, 111, 54), (181, 109, 49), (173, 100, 45), (165, 92, 42), + (159, 88, 38), (154, 84, 35), (136, 71, 26), (117, 59, 19), + (81, 34, 11), (68, 29, 9), (55, 24, 8), (42, 18, 7), + (30, 13, 6), (24, 10, 6), (18, 8, 7), (12, 10, 12), + (7, 14, 18), (12, 30, 34), (21, 39, 46), (30, 49, 58), + (34, 54, 64), (39, 59, 71), (42, 65, 77), (45, 69, 82), + (45, 64, 78), (45, 60, 74), (46, 57, 70), (44, 54, 66), + (42, 52, 63), (40, 46, 53), (44, 40, 44), (51, 37, 34), + (63, 35, 25), (73, 35, 14), (81, 37, 13), (90, 39, 12), + (93, 38, 10), (96, 37, 9), (97, 31, 7), (85, 25, 3), + (57, 19, 5), (47, 15, 9), (37, 11, 13), (32, 9, 14), + (27, 8, 16), (18, 13, 18), (11, 18, 25), (3, 28, 35), + (2, 38, 48), (1, 56, 70), (2, 59, 74), (3, 63, 78), + (4, 70, 84), (6, 77, 91), (6, 78, 95), (4, 77, 97), + (4, 68, 86), (5, 61, 79), (6, 54, 72), (5, 49, 67), + (4, 45, 63), (2, 37, 52), (0, 31, 40), (0, 24, 32), + (0, 19, 26), (0, 9, 19), (0, 8, 16), (0, 8, 14), + (0, 9, 8), (0, 10, 4), (0, 12, 3), (2, 13, 4), + (14, 24, 15), (21, 32, 23), (28, 41, 32), (31, 43, 35), + (34, 46, 38), (41, 54, 39), (51, 61, 43), (64, 67, 49), + (85, 83, 62), (133, 127, 84), (142, 133, 87), (152, 140, 90), + (160, 142, 87), (166, 137, 85), (173, 134, 89), (177, 145, 97), + (169, 155, 116), (162, 150, 112), (155, 145, 109), (132, 123, 101), + (108, 111, 97), (95, 106, 102), (79, 110, 117), (77, 121, 125), + (75, 127, 133), (92, 138, 147), (97, 145, 155), (103, 153, 163), + (119, 167, 178), (130, 176, 188), (143, 183, 194), (152, 180, 192), + (153, 177, 178), (151, 171, 170), (149, 165, 162), (147, 152, 145), + (148, 136, 122), (147, 124, 103), (140, 115, 82), (134, 104, 62), + (133, 91, 43), (136, 83, 26), (151, 82, 20), (163, 86, 17), + (170, 91, 16), (173, 91, 18), (166, 85, 18), (163, 81, 21), + (166, 82, 26), (169, 85, 30), (173, 88, 34), (177, 91, 40), + (175, 92, 45), (171, 91, 43), (172, 95, 37), (182, 100, 40), + (201, 112, 48), (208, 124, 62), (206, 132, 79), (193, 136, 87), + (176, 135, 95), (165, 132, 99), (150, 123, 98), (127, 114, 103), + (104, 103, 104), (78, 93, 106), (59, 88, 101), (49, 82, 91), + (38, 74, 81), (31, 69, 72), (25, 66, 72), (20, 70, 74), + (23, 76, 79), (27, 80, 83), (33, 83, 86), (39, 81, 90), + (44, 80, 88), (52, 77, 83), (60, 73, 78), (70, 69, 72), + (76, 68, 75), (84, 72, 76), (102, 81, 81), (129, 97, 83), + (156, 119, 87), (174, 138, 101), (180, 156, 121), (182, 170, 142), + (189, 178, 156), (192, 185, 159), (191, 189, 155), (178, 189, 157), + (158, 182, 158), (136, 169, 161), (109, 150, 155), (83, 134, 142), + (58, 127, 137), (41, 123, 127), (35, 127, 129), (29, 123, 129), + (35, 115, 121), (43, 111, 119), (53, 107, 105), (70, 108, 97), + (83, 108, 92), (100, 104, 82), (116, 98, 74), (130, 92, 65), + (146, 95, 59), (150, 98, 62), (153, 109, 75), (149, 120, 88), + (141, 126, 101), (140, 135, 111), (134, 135, 113), (134, 133, 113), + (139, 137, 109), (142, 134, 104), (145, 133, 100), (152, 130, 94) + ), + +// 577 Golden +((148, 110, 66), (145, 114, 70), (137, 107, 64), (129, 101, 58), + (112, 85, 49), (96, 70, 41), (89, 65, 37), (82, 61, 34), + (61, 50, 34), (62, 51, 39), (63, 52, 44), (66, 56, 48), + (70, 61, 52), (71, 66, 61), (73, 72, 70), (77, 76, 75), + (81, 80, 81), (103, 101, 99), (112, 108, 101), (122, 115, 103), + (130, 118, 100), (139, 121, 97), (142, 122, 95), (145, 124, 94), + (149, 118, 80), (147, 113, 70), (146, 109, 60), (137, 102, 58), + (128, 96, 57), (122, 92, 56), (117, 89, 56), (107, 83, 55), + (101, 79, 52), (84, 72, 56), (78, 69, 59), (73, 67, 63), + (72, 68, 65), (72, 70, 68), (72, 70, 69), (73, 71, 71), + (74, 73, 74), (79, 75, 70), (85, 78, 66), (90, 80, 63), + (96, 83, 60), (95, 82, 58), (95, 81, 56), (92, 77, 47), + (90, 74, 35), (93, 71, 23), (97, 74, 24), (102, 77, 26), + (110, 85, 30), (119, 93, 35), (125, 97, 39), (132, 102, 44), + (165, 128, 64), (180, 145, 79), (196, 163, 95), (208, 177, 110), + (220, 191, 125), (224, 195, 127), (229, 199, 129), (230, 204, 131), + (232, 205, 128), (228, 201, 127), (221, 195, 124), (214, 189, 122), + (207, 182, 117), (201, 176, 113), (187, 161, 102), (172, 146, 94), + (146, 124, 91), (131, 113, 89), (116, 102, 87), (102, 91, 82), + (89, 81, 77), (85, 78, 74), (81, 75, 72), (74, 69, 69), + (69, 64, 64), (58, 55, 57), (54, 52, 53), (51, 49, 50), + (50, 48, 49), (49, 48, 48), (49, 48, 48), (48, 48, 49), + (47, 46, 47), (47, 46, 46), (48, 46, 46), (48, 46, 46), + (48, 47, 47), (49, 47, 47), (49, 46, 46), (51, 46, 41), + (52, 46, 36), (57, 49, 32), (57, 49, 34), (58, 49, 36), + (58, 49, 36), (59, 50, 37), (62, 54, 36), (67, 57, 41), + (70, 62, 54), (70, 63, 57), (71, 64, 60), (72, 65, 61), + (73, 66, 62), (76, 69, 65), (78, 72, 68), (83, 75, 71), + (85, 77, 72), (96, 80, 65), (98, 80, 63), (100, 81, 62), + (104, 83, 59), (105, 84, 60), (107, 83, 60), (107, 81, 57), + (96, 73, 47), (88, 68, 45), (81, 64, 44), (77, 61, 44), + (73, 59, 44), (65, 53, 43), (56, 48, 39), (52, 46, 35), + (50, 46, 35), (57, 51, 43), (60, 53, 44), (63, 56, 46), + (73, 63, 49), (83, 72, 58), (97, 85, 67), (114, 99, 80), + (154, 130, 92), (169, 143, 96), (185, 156, 100), (192, 162, 103), + (200, 168, 107), (212, 179, 113), (222, 187, 116), (224, 188, 113), + (216, 184, 113), (193, 162, 102), (187, 156, 100), (182, 151, 99), + (170, 139, 89), (156, 125, 83), (138, 111, 75), (119, 93, 62), + (92, 70, 47), (89, 67, 44), (86, 65, 42), (82, 63, 44), + (80, 64, 47), (78, 66, 54), (76, 69, 63), (77, 73, 70), + (80, 78, 77), (96, 89, 82), (100, 91, 81), (104, 93, 81), + (111, 95, 79), (116, 99, 82), (120, 101, 83), (126, 107, 87), + (136, 114, 87), (138, 116, 89), (140, 118, 92), (143, 121, 95), + (146, 127, 103), (153, 133, 108), (160, 140, 114), (167, 148, 122), + (173, 154, 129), (180, 164, 135), (191, 171, 135), (203, 179, 130), + (211, 185, 128), (214, 185, 123), (214, 185, 121), (213, 182, 120), + (201, 170, 106), (196, 163, 99), (192, 157, 92), (181, 143, 79), + (172, 131, 67), (163, 123, 62), (155, 115, 60), (150, 111, 57), + (148, 108, 55), (149, 108, 50), (155, 113, 49), (163, 120, 53), + (172, 129, 56), (183, 139, 62), (188, 145, 64), (193, 149, 65), + (195, 152, 67), (194, 151, 66), (191, 150, 70), (183, 147, 73), + (173, 141, 76), (163, 135, 78), (153, 127, 77), (144, 121, 80), + (137, 118, 84), (137, 117, 87), (141, 120, 90), (148, 126, 91), + (159, 134, 92), (166, 140, 100), (173, 147, 104), (179, 152, 108), + (181, 155, 110), (182, 155, 107), (179, 154, 111), (172, 150, 113), + (162, 143, 116), (149, 137, 119), (136, 128, 117), (128, 121, 112), + (122, 114, 105), (115, 105, 97), (107, 99, 91), (100, 92, 83), + (94, 86, 74), (91, 82, 67), (87, 76, 61), (82, 73, 58), + (76, 66, 54), (72, 62, 48), (68, 58, 45), (66, 57, 43), + (64, 57, 47), (63, 57, 51), (65, 58, 50), (67, 57, 47), + (70, 57, 43), (72, 58, 39), (73, 59, 36), (79, 61, 33), + (84, 64, 30), (89, 66, 28), (92, 66, 27), (93, 67, 26), + (98, 68, 26), (103, 72, 28), (112, 82, 40), (116, 86, 48), + (132, 101, 58), (144, 110, 64), (149, 110, 59), (160, 120, 67) + ), + +// 578 Golden_Green +((40, 49, 3), (42, 50, 3), (40, 47, 2), (38, 44, 2), + (31, 36, 1), (24, 29, 1), (20, 24, 0), (16, 19, 0), + (4, 6, 0), (2, 3, 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, 1, 0), (0, 1, 0), (0, 1, 0), (0, 2, 0), + (0, 2, 0), (0, 3, 0), (0, 3, 0), (1, 4, 0), + (1, 4, 0), (2, 5, 0), (3, 6, 0), (4, 8, 0), + (12, 17, 0), (18, 23, 0), (24, 29, 0), (28, 34, 0), + (33, 39, 0), (34, 41, 0), (35, 43, 0), (38, 46, 0), + (40, 49, 1), (45, 55, 1), (47, 57, 1), (49, 60, 1), + (48, 59, 1), (47, 59, 1), (45, 58, 1), (44, 57, 1), + (39, 53, 1), (38, 52, 1), (38, 51, 2), (38, 51, 1), + (39, 52, 1), (40, 53, 1), (41, 54, 1), (43, 57, 1), + (46, 59, 1), (54, 67, 3), (56, 69, 4), (59, 72, 5), + (60, 73, 5), (62, 74, 5), (65, 77, 5), (67, 78, 4), + (73, 84, 3), (74, 86, 4), (76, 89, 5), (77, 90, 5), + (79, 91, 5), (79, 91, 5), (80, 92, 5), (82, 93, 3), + (84, 94, 2), (90, 98, 0), (95, 102, 1), (100, 107, 3), + (105, 111, 5), (110, 116, 7), (122, 126, 12), (133, 134, 16), + (143, 141, 15), (140, 140, 13), (138, 139, 11), (138, 139, 11), + (138, 140, 11), (141, 142, 11), (147, 148, 15), (156, 155, 17), + (163, 160, 21), (165, 161, 21), (159, 156, 17), (153, 151, 13), + (149, 149, 11), (146, 147, 10), (147, 147, 9), (154, 150, 10), + (172, 165, 24), (181, 173, 29), (191, 181, 35), (190, 181, 36), + (189, 181, 37), (181, 175, 32), (172, 168, 26), (166, 163, 23), + (160, 159, 23), (158, 157, 24), (158, 158, 26), (158, 159, 28), + (151, 154, 26), (141, 145, 22), (130, 134, 17), (116, 121, 11), + (87, 92, 2), (77, 83, 1), (68, 74, 1), (64, 70, 1), + (60, 66, 1), (53, 60, 0), (47, 55, 1), (42, 49, 1), + (36, 43, 1), (25, 33, 1), (23, 30, 0), (21, 28, 0), + (19, 27, 0), (18, 28, 0), (20, 31, 0), (24, 36, 0), + (35, 47, 0), (39, 52, 0), (44, 57, 1), (47, 59, 1), + (50, 62, 1), (56, 68, 2), (62, 74, 2), (70, 82, 4), + (82, 92, 10), (105, 113, 18), (108, 116, 19), (112, 119, 20), + (115, 121, 22), (112, 120, 21), (106, 112, 17), (101, 105, 18), + (93, 97, 22), (91, 95, 22), (90, 93, 22), (87, 89, 23), + (80, 84, 20), (69, 75, 14), (55, 63, 9), (43, 51, 8), + (33, 41, 7), (21, 29, 6), (20, 28, 5), (20, 28, 4), + (20, 28, 3), (22, 30, 3), (24, 33, 2), (28, 36, 2), + (35, 43, 2), (36, 44, 2), (38, 46, 3), (41, 48, 2), + (43, 49, 1), (44, 52, 1), (46, 54, 0), (48, 57, 0), + (50, 61, 0), (52, 64, 1), (53, 65, 1), (54, 66, 1), + (54, 67, 1), (53, 66, 2), (54, 66, 4), (55, 68, 5), + (61, 73, 8), (63, 74, 8), (65, 75, 8), (67, 77, 7), + (69, 80, 5), (71, 81, 7), (70, 81, 6), (72, 82, 7), + (73, 83, 8), (73, 82, 8), (73, 81, 7), (73, 81, 4), + (72, 81, 4), (70, 80, 2), (69, 80, 1), (69, 81, 2), + (70, 82, 2), (71, 82, 1), (74, 84, 1), (78, 88, 2), + (82, 92, 2), (85, 95, 2), (86, 98, 2), (86, 99, 2), + (84, 97, 2), (82, 94, 2), (79, 89, 2), (76, 86, 2), + (74, 83, 2), (70, 79, 2), (67, 77, 1), (64, 76, 1), + (61, 73, 2), (58, 69, 2), (56, 66, 2), (55, 63, 2), + (55, 60, 2), (54, 58, 2), (54, 57, 1), (54, 57, 1), + (54, 58, 3), (55, 58, 5), (55, 59, 5), (54, 58, 6), + (53, 56, 6), (50, 52, 6), (46, 47, 5), (42, 43, 4), + (38, 38, 5), (33, 34, 5), (29, 32, 6), (25, 29, 5), + (23, 27, 6), (20, 24, 5), (17, 21, 2), (14, 17, 2), + (11, 13, 1), (8, 10, 1), (5, 7, 0), (3, 6, 0), + (2, 5, 1), (3, 6, 0), (5, 10, 1), (10, 16, 1), + (18, 24, 2), (25, 32, 2), (33, 42, 2), (39, 48, 2), + (42, 51, 2), (44, 52, 2), (41, 51, 2), (43, 52, 3) + ), + + +// 579 Goldenrod +((237, 184, 18), (252, 174, 18), (232, 168, 38), (212, 163, 59), + (196, 147, 89), (180, 131, 120), (166, 128, 136), (153, 126, 153), + (114, 116, 162), (93, 107, 136), (72, 99, 110), (52, 87, 82), + (33, 76, 55), (26, 57, 42), (20, 39, 29), (21, 36, 28), + (22, 34, 28), (27, 28, 25), (25, 29, 26), (24, 30, 28), + (17, 41, 34), (11, 52, 40), (10, 57, 45), (10, 62, 50), + (3, 100, 78), (5, 104, 81), (7, 108, 85), (7, 100, 78), + (8, 92, 71), (13, 84, 65), (19, 76, 59), (34, 72, 49), + (75, 75, 34), (152, 87, 24), (187, 101, 18), (223, 116, 13), + (201, 112, 15), (179, 109, 18), (158, 100, 22), (138, 91, 27), + (63, 84, 48), (48, 86, 64), (33, 88, 81), (53, 107, 106), + (74, 127, 132), (87, 133, 145), (101, 139, 159), (130, 144, 178), + (147, 141, 197), (143, 114, 209), (140, 95, 214), (138, 76, 220), + (129, 61, 214), (121, 46, 208), (115, 41, 199), (109, 37, 191), + (73, 34, 119), (51, 33, 97), (29, 33, 75), (16, 45, 62), + (3, 58, 49), (2, 65, 55), (1, 73, 61), (4, 86, 66), + (2, 93, 64), (5, 102, 62), (4, 87, 54), (3, 72, 47), + (5, 68, 43), (7, 65, 39), (10, 53, 31), (11, 35, 24), + (20, 23, 21), (23, 22, 21), (26, 22, 22), (83, 58, 18), + (140, 95, 14), (136, 93, 16), (132, 91, 19), (182, 119, 13), + (235, 140, 9), (159, 89, 16), (135, 69, 18), (111, 49, 20), + (90, 39, 21), (70, 30, 23), (51, 24, 30), (69, 30, 50), + (77, 50, 95), (86, 54, 127), (96, 58, 159), (92, 53, 167), + (88, 49, 175), (90, 33, 174), (84, 33, 181), (61, 41, 163), + (43, 58, 137), (32, 67, 129), (47, 72, 136), (63, 77, 144), + (78, 74, 156), (93, 72, 168), (118, 82, 190), (138, 99, 185), + (191, 143, 116), (203, 152, 87), (216, 162, 58), (225, 163, 42), + (235, 165, 26), (235, 155, 23), (217, 140, 19), (169, 119, 18), + (124, 86, 19), (59, 49, 16), (43, 37, 17), (28, 25, 19), + (24, 19, 20), (24, 16, 19), (23, 17, 20), (21, 17, 21), + (19, 24, 26), (27, 28, 39), (36, 32, 53), (42, 33, 68), + (49, 34, 83), (54, 38, 92), (46, 62, 105), (40, 90, 124), + (39, 109, 128), (2, 124, 94), (6, 122, 87), (11, 121, 81), + (26, 93, 58), (67, 81, 39), (119, 81, 30), (147, 81, 14), + (232, 126, 10), (242, 141, 11), (253, 156, 13), (252, 159, 14), + (251, 163, 15), (251, 168, 13), (254, 170, 18), (254, 167, 19), + (252, 163, 16), (220, 149, 38), (207, 147, 55), (195, 145, 72), + (190, 125, 106), (176, 114, 141), (153, 112, 184), (155, 98, 222), + (155, 70, 236), (151, 63, 235), (148, 57, 234), (133, 50, 221), + (119, 42, 209), (110, 33, 196), (98, 29, 176), (76, 25, 153), + (60, 21, 121), (44, 20, 81), (40, 18, 69), (37, 17, 57), + (48, 30, 39), (87, 48, 35), (126, 59, 34), (133, 81, 55), + (165, 85, 112), (163, 84, 126), (162, 83, 140), (128, 82, 174), + (119, 62, 188), (120, 39, 187), (96, 42, 168), (70, 55, 140), + (55, 53, 124), (39, 59, 113), (15, 82, 95), (2, 99, 90), + (6, 106, 94), (9, 112, 95), (25, 125, 100), (54, 126, 115), + (67, 88, 100), (73, 87, 98), (80, 87, 97), (82, 63, 83), + (57, 44, 67), (33, 48, 56), (24, 47, 42), (15, 46, 38), + (6, 46, 39), (3, 42, 37), (2, 38, 31), (1, 35, 27), + (2, 33, 24), (2, 32, 20), (1, 34, 23), (1, 42, 27), + (0, 49, 30), (0, 55, 37), (0, 59, 38), (1, 58, 36), + (5, 56, 34), (8, 50, 30), (9, 41, 22), (14, 34, 18), + (18, 28, 18), (19, 24, 17), (20, 22, 17), (21, 21, 16), + (21, 19, 16), (21, 19, 17), (21, 20, 16), (20, 20, 17), + (20, 19, 18), (20, 19, 20), (20, 20, 23), (17, 22, 25), + (13, 29, 28), (12, 35, 39), (8, 41, 47), (4, 53, 50), + (3, 61, 60), (4, 64, 67), (5, 64, 65), (7, 61, 61), + (7, 59, 56), (6, 52, 50), (11, 42, 39), (15, 38, 33), + (18, 42, 35), (31, 57, 46), (58, 73, 71), (81, 87, 93), + (76, 121, 107), (70, 149, 140), (69, 155, 149), (69, 152, 113), + (81, 149, 98), (102, 155, 81), (139, 148, 42), (185, 140, 24), + (224, 146, 15), (246, 156, 12), (251, 163, 16), (253, 166, 17), + (245, 169, 33), (228, 171, 78), (222, 178, 114), (208, 180, 124), + (194, 174, 124), (208, 183, 119), (217, 184, 110), (219, 178, 62) + ), + + +// 580 Grape +((83, 67, 90), (93, 75, 108), (98, 77, 115), (104, 79, 123), + (106, 80, 126), (109, 81, 130), (109, 81, 130), (109, 82, 131), + (110, 83, 129), (109, 81, 125), (108, 80, 122), (101, 82, 121), + (95, 84, 120), (90, 89, 124), (85, 94, 128), (83, 97, 133), + (82, 100, 138), (77, 116, 159), (74, 125, 168), (72, 135, 177), + (69, 138, 185), (66, 142, 193), (66, 141, 192), (66, 141, 192), + (70, 134, 171), (68, 125, 157), (67, 117, 143), (63, 103, 124), + (59, 90, 106), (56, 84, 96), (54, 79, 87), (51, 69, 67), + (47, 63, 54), (41, 54, 42), (39, 54, 41), (38, 54, 40), + (41, 66, 55), (45, 79, 70), (52, 87, 82), (59, 95, 94), + (110, 138, 138), (124, 155, 159), (139, 172, 180), (139, 181, 198), + (139, 190, 217), (139, 191, 221), (140, 193, 225), (150, 196, 224), + (143, 191, 224), (100, 163, 204), (87, 151, 192), (74, 140, 180), + (69, 135, 179), (64, 130, 179), (62, 128, 179), (60, 127, 179), + (60, 126, 171), (66, 125, 168), (72, 125, 166), (76, 123, 163), + (81, 122, 160), (81, 118, 158), (82, 114, 156), (83, 111, 146), + (88, 102, 134), (98, 88, 112), (97, 79, 109), (96, 70, 106), + (95, 67, 104), (94, 65, 103), (99, 63, 109), (103, 65, 112), + (103, 62, 119), (96, 59, 111), (89, 57, 104), (86, 56, 98), + (84, 55, 92), (81, 54, 90), (79, 53, 88), (67, 48, 74), + (57, 43, 64), (52, 39, 55), (56, 39, 59), (60, 40, 63), + (63, 41, 67), (67, 42, 72), (74, 46, 80), (80, 50, 89), + (94, 55, 104), (96, 56, 106), (98, 58, 109), (96, 59, 106), + (94, 60, 104), (87, 61, 97), (80, 59, 90), (73, 56, 82), + (64, 52, 73), (52, 53, 59), (51, 54, 57), (51, 55, 55), + (52, 56, 56), (54, 57, 57), (59, 58, 61), (68, 64, 70), + (87, 76, 94), (90, 89, 111), (93, 102, 128), (93, 108, 136), + (94, 115, 145), (95, 125, 162), (98, 131, 173), (96, 140, 185), + (92, 148, 197), (82, 165, 216), (82, 166, 218), (83, 167, 220), + (86, 170, 221), (90, 171, 222), (97, 175, 222), (115, 182, 223), + (143, 192, 200), (142, 179, 192), (141, 167, 185), (144, 161, 187), + (147, 155, 189), (154, 143, 172), (158, 138, 154), (156, 121, 140), + (140, 100, 128), (118, 66, 132), (117, 63, 131), (117, 61, 130), + (118, 59, 128), (119, 57, 128), (121, 53, 131), (116, 52, 131), + (105, 51, 124), (99, 49, 115), (94, 47, 106), (89, 45, 101), + (84, 43, 96), (71, 40, 82), (57, 36, 71), (46, 36, 58), + (39, 35, 45), (31, 32, 33), (30, 31, 32), (29, 30, 32), + (31, 27, 32), (36, 28, 34), (42, 27, 39), (48, 28, 45), + (66, 36, 67), (70, 39, 73), (75, 43, 80), (79, 57, 97), + (82, 72, 117), (85, 87, 138), (94, 94, 150), (110, 97, 157), + (115, 101, 162), (106, 110, 172), (102, 108, 168), (99, 107, 164), + (102, 102, 151), (105, 92, 135), (106, 85, 121), (99, 80, 113), + (83, 77, 95), (81, 77, 92), (80, 78, 89), (83, 82, 88), + (83, 86, 90), (84, 92, 94), (82, 95, 99), (82, 97, 105), + (86, 98, 110), (88, 100, 116), (91, 100, 119), (88, 96, 119), + (84, 92, 119), (83, 81, 117), (81, 70, 114), (79, 62, 113), + (67, 46, 96), (63, 41, 90), (60, 37, 84), (51, 25, 70), + (40, 19, 64), (36, 17, 58), (31, 21, 53), (34, 28, 51), + (38, 31, 48), (45, 33, 52), (54, 37, 62), (63, 44, 75), + (77, 52, 90), (90, 62, 103), (104, 67, 115), (117, 71, 127), + (124, 79, 138), (123, 89, 153), (117, 100, 165), (110, 109, 174), + (103, 114, 181), (101, 116, 180), (96, 123, 179), (92, 124, 177), + (91, 125, 175), (91, 122, 175), (96, 116, 175), (104, 118, 175), + (112, 125, 176), (118, 131, 177), (119, 131, 178), (114, 127, 173), + (110, 120, 168), (107, 121, 163), (105, 123, 155), (95, 123, 152), + (83, 120, 140), (72, 109, 123), (67, 96, 104), (66, 85, 85), + (63, 75, 72), (59, 66, 62), (52, 61, 53), (46, 56, 46), + (39, 51, 39), (33, 44, 31), (28, 36, 26), (23, 29, 21), + (22, 24, 22), (24, 22, 24), (26, 21, 27), (31, 20, 32), + (34, 19, 37), (42, 18, 44), (52, 22, 52), (59, 26, 62), + (66, 30, 69), (67, 31, 74), (69, 32, 74), (70, 34, 73), + (70, 38, 72), (72, 41, 73), (70, 42, 75), (69, 40, 74), + (67, 41, 70), (66, 43, 65), (67, 48, 63), (68, 52, 65), + (72, 54, 71), (74, 56, 76), (76, 58, 80), (80, 62, 86) + ), + +// 581 Lemon_Grass +((60, 101, 67), (33, 82, 77), (26, 80, 78), (19, 78, 80), + (13, 72, 75), (7, 66, 71), (8, 64, 67), (9, 62, 63), + (13, 51, 40), (21, 48, 34), (30, 45, 28), (38, 45, 21), + (47, 45, 14), (57, 47, 12), (68, 49, 10), (71, 48, 10), + (74, 48, 11), (81, 50, 11), (81, 45, 13), (81, 41, 16), + (82, 42, 22), (83, 44, 28), (84, 46, 32), (85, 48, 36), + (84, 63, 53), (83, 70, 55), (83, 78, 57), (83, 85, 56), + (84, 93, 56), (84, 95, 51), (84, 98, 47), (87, 103, 36), + (97, 107, 27), (126, 124, 15), (139, 134, 13), (152, 144, 12), + (163, 149, 19), (175, 155, 26), (178, 158, 28), (181, 162, 31), + (177, 163, 45), (173, 159, 50), (169, 156, 55), (161, 152, 52), + (154, 149, 50), (148, 145, 50), (143, 141, 51), (134, 129, 52), + (123, 117, 49), (94, 86, 45), (82, 72, 45), (70, 58, 46), + (55, 44, 41), (41, 30, 36), (36, 27, 34), (31, 24, 32), + (20, 24, 23), (15, 26, 18), (11, 29, 13), (18, 37, 11), + (26, 46, 9), (30, 51, 9), (35, 57, 10), (41, 67, 10), + (49, 74, 10), (65, 86, 18), (63, 88, 23), (61, 90, 28), + (58, 90, 32), (56, 91, 37), (53, 93, 51), (46, 90, 61), + (33, 80, 76), (33, 74, 82), (34, 69, 89), (36, 62, 89), + (39, 56, 89), (38, 51, 86), (37, 46, 84), (37, 36, 81), + (39, 35, 73), (36, 44, 64), (31, 46, 54), (27, 49, 45), + (30, 54, 40), (33, 60, 36), (47, 74, 29), (65, 93, 23), + (100, 115, 11), (122, 128, 10), (144, 141, 10), (151, 144, 11), + (159, 148, 12), (165, 149, 15), (164, 147, 19), (164, 148, 21), + (159, 147, 23), (144, 137, 33), (136, 135, 36), (129, 133, 39), + (124, 132, 39), (120, 131, 39), (109, 125, 42), (99, 119, 44), + (77, 105, 44), (69, 97, 44), (62, 90, 44), (62, 87, 44), + (62, 85, 45), (63, 81, 45), (66, 77, 46), (69, 74, 46), + (74, 74, 46), (81, 81, 44), (79, 82, 42), (78, 83, 40), + (72, 85, 35), (69, 88, 34), (70, 95, 36), (75, 104, 37), + (85, 117, 43), (96, 123, 52), (107, 130, 61), (112, 133, 64), + (118, 136, 68), (126, 139, 74), (127, 136, 77), (122, 128, 77), + (113, 118, 75), (97, 94, 64), (93, 87, 59), (89, 80, 55), + (84, 71, 46), (86, 70, 39), (94, 71, 32), (108, 76, 26), + (144, 103, 20), (159, 116, 17), (175, 130, 15), (179, 135, 13), + (184, 141, 12), (186, 147, 11), (181, 147, 9), (172, 144, 8), + (157, 137, 6), (117, 115, 7), (108, 110, 9), (100, 105, 12), + (85, 95, 18), (76, 87, 26), (68, 81, 34), (67, 80, 45), + (73, 82, 69), (75, 82, 73), (78, 82, 77), (83, 82, 81), + (86, 82, 82), (88, 81, 81), (89, 78, 76), (88, 73, 68), + (85, 65, 57), (74, 55, 36), (72, 54, 32), (70, 54, 29), + (66, 52, 23), (62, 51, 19), (59, 53, 19), (60, 59, 22), + (75, 80, 33), (81, 87, 37), (87, 94, 41), (103, 109, 51), + (120, 123, 59), (136, 136, 66), (147, 146, 70), (158, 153, 73), + (164, 157, 72), (165, 156, 68), (159, 148, 61), (150, 140, 54), + (142, 132, 45), (136, 125, 38), (131, 117, 34), (129, 113, 31), + (139, 121, 25), (143, 124, 25), (147, 127, 26), (156, 129, 32), + (166, 137, 38), (176, 145, 43), (180, 155, 47), (177, 155, 53), + (167, 150, 59), (155, 141, 66), (138, 135, 67), (121, 126, 65), + (101, 116, 64), (82, 101, 64), (64, 88, 63), (50, 75, 58), + (40, 67, 52), (34, 58, 48), (29, 52, 46), (26, 48, 44), + (25, 48, 39), (25, 48, 35), (26, 49, 33), (28, 51, 36), + (33, 56, 38), (39, 61, 41), (44, 61, 42), (48, 57, 42), + (52, 52, 43), (58, 49, 42), (65, 47, 39), (73, 43, 32), + (81, 40, 25), (90, 41, 20), (102, 49, 17), (112, 57, 14), + (124, 65, 10), (135, 74, 8), (147, 87, 8), (154, 97, 9), + (158, 102, 8), (160, 103, 6), (163, 107, 5), (164, 110, 6), + (159, 107, 7), (149, 98, 8), (139, 90, 9), (129, 88, 11), + (116, 86, 13), (97, 79, 14), (79, 72, 14), (68, 72, 15), + (61, 78, 14), (57, 85, 13), (58, 91, 11), (67, 99, 9), + (81, 109, 9), (96, 119, 10), (110, 125, 11), (124, 129, 12), + (136, 133, 12), (145, 137, 15), (152, 140, 18), (156, 144, 19), + (157, 147, 19), (155, 150, 20), (148, 149, 24), (140, 148, 28), + (127, 141, 33), (115, 136, 39), (99, 124, 49), (84, 116, 57) + ), + +// 582 Magenta_and_Teal +((171, 65, 180), (173, 49, 158), (176, 50, 150), (179, 51, 142), + (183, 53, 146), (187, 56, 150), (194, 57, 156), (201, 58, 163), + (212, 54, 173), (211, 59, 175), (210, 64, 177), (207, 76, 185), + (205, 89, 193), (199, 102, 202), (193, 115, 211), (188, 119, 214), + (183, 123, 217), (162, 141, 218), (150, 151, 223), (138, 162, 228), + (127, 179, 228), (117, 196, 229), (112, 202, 230), (108, 209, 232), + (109, 229, 218), (116, 228, 209), (124, 228, 201), (127, 219, 188), + (131, 210, 175), (130, 201, 171), (130, 192, 168), (122, 173, 162), + (128, 156, 154), (156, 129, 155), (169, 124, 156), (183, 119, 157), + (185, 111, 157), (188, 104, 158), (185, 99, 156), (182, 94, 155), + (177, 73, 149), (181, 78, 153), (186, 83, 157), (197, 97, 165), + (209, 111, 173), (211, 121, 178), (214, 131, 183), (223, 144, 185), + (226, 159, 179), (230, 175, 174), (229, 182, 179), (228, 189, 184), + (222, 200, 198), (217, 212, 212), (212, 217, 217), (208, 222, 223), + (178, 231, 238), (162, 231, 238), (147, 232, 239), (141, 231, 237), + (135, 231, 235), (134, 230, 234), (134, 230, 234), (134, 230, 234), + (131, 228, 233), (120, 227, 233), (117, 229, 232), (114, 231, 231), + (118, 232, 230), (122, 234, 230), (132, 237, 230), (147, 239, 232), + (178, 242, 231), (183, 244, 233), (188, 246, 235), (182, 246, 238), + (177, 247, 241), (170, 247, 243), (163, 248, 245), (152, 246, 248), + (143, 245, 250), (128, 236, 246), (125, 224, 239), (122, 213, 233), + (114, 208, 228), (107, 204, 223), (92, 192, 214), (85, 178, 204), + (70, 147, 180), (69, 126, 164), (69, 106, 148), (66, 96, 139), + (63, 87, 131), (59, 76, 119), (62, 73, 110), (74, 73, 114), + (93, 82, 113), (128, 104, 115), (137, 111, 104), (146, 119, 94), + (144, 122, 88), (143, 126, 82), (140, 127, 84), (141, 131, 86), + (136, 134, 100), (134, 132, 106), (133, 131, 112), (130, 130, 111), + (127, 129, 110), (121, 120, 110), (108, 119, 115), (100, 117, 120), + (93, 117, 130), (92, 120, 162), (95, 126, 169), (98, 133, 177), + (114, 141, 191), (126, 153, 208), (139, 164, 217), (153, 174, 228), + (182, 171, 237), (199, 163, 238), (216, 156, 240), (223, 149, 238), + (231, 142, 237), (239, 132, 224), (243, 123, 213), (242, 109, 209), + (244, 91, 208), (242, 53, 215), (242, 44, 218), (242, 35, 222), + (243, 26, 220), (243, 25, 213), (241, 24, 209), (238, 25, 204), + (222, 23, 203), (207, 18, 203), (193, 13, 203), (184, 13, 199), + (175, 14, 195), (161, 15, 188), (149, 18, 187), (145, 29, 185), + (140, 44, 183), (143, 74, 181), (143, 81, 178), (144, 89, 176), + (146, 109, 169), (147, 121, 171), (156, 137, 174), (165, 154, 177), + (193, 183, 200), (201, 186, 204), (210, 189, 208), (221, 196, 210), + (229, 198, 209), (237, 197, 206), (242, 196, 198), (240, 195, 196), + (237, 188, 191), (234, 160, 201), (232, 154, 204), (231, 148, 207), + (230, 138, 213), (231, 130, 213), (232, 126, 215), (233, 118, 209), + (235, 100, 210), (233, 93, 210), (231, 87, 211), (225, 77, 211), + (216, 68, 207), (207, 64, 202), (200, 61, 193), (192, 61, 190), + (186, 62, 191), (179, 65, 196), (168, 67, 198), (153, 73, 197), + (138, 79, 196), (126, 90, 193), (112, 102, 193), (108, 115, 198), + (113, 150, 221), (113, 156, 226), (114, 162, 231), (121, 168, 241), + (127, 172, 244), (133, 172, 246), (142, 172, 245), (152, 177, 246), + (164, 181, 246), (168, 186, 242), (173, 190, 241), (174, 192, 238), + (169, 191, 234), (164, 191, 230), (151, 193, 228), (140, 196, 230), + (129, 200, 229), (118, 206, 230), (109, 214, 232), (102, 224, 233), + (101, 230, 231), (102, 236, 229), (107, 240, 228), (115, 243, 225), + (127, 242, 221), (136, 236, 217), (150, 231, 210), (164, 225, 202), + (175, 221, 197), (180, 219, 197), (184, 221, 198), (187, 226, 201), + (184, 228, 205), (180, 228, 205), (171, 226, 202), (156, 220, 197), + (140, 211, 195), (124, 207, 196), (115, 209, 200), (113, 211, 209), + (117, 217, 220), (123, 225, 227), (124, 229, 231), (124, 227, 231), + (118, 226, 231), (111, 225, 228), (107, 220, 227), (111, 220, 228), + (123, 225, 229), (137, 232, 232), (153, 236, 235), (164, 241, 238), + (171, 246, 237), (171, 245, 236), (169, 243, 235), (171, 240, 227), + (173, 232, 221), (173, 219, 211), (173, 209, 205), (177, 205, 200), + (184, 198, 198), (185, 193, 202), (184, 186, 203), (182, 177, 205), + (177, 156, 198), (172, 136, 192), (151, 116, 176), (144, 99, 164), + (135, 88, 159), (137, 79, 163), (144, 78, 172), (150, 71, 173) + ), + +// 583 Mahogany +((49, 9, 15), (40, 6, 12), (30, 3, 9), (21, 0, 7), + (21, 0, 7), (21, 0, 8), (21, 0, 8), (21, 1, 8), + (22, 1, 9), (22, 1, 9), (22, 2, 10), (22, 2, 10), + (22, 2, 10), (22, 2, 10), (23, 2, 10), (23, 1, 10), + (24, 1, 11), (25, 2, 11), (28, 3, 12), (32, 5, 13), + (37, 6, 14), (43, 8, 16), (45, 8, 16), (47, 9, 17), + (52, 11, 17), (53, 11, 18), (55, 12, 19), (57, 12, 19), + (60, 12, 20), (61, 12, 19), (62, 12, 18), (65, 13, 19), + (70, 14, 19), (85, 19, 21), (97, 24, 23), (110, 29, 25), + (119, 35, 28), (128, 42, 31), (133, 46, 33), (138, 51, 36), + (164, 74, 49), (166, 76, 49), (168, 79, 49), (165, 76, 48), + (162, 74, 47), (162, 74, 48), (163, 75, 49), (162, 76, 50), + (158, 71, 47), (145, 57, 40), (141, 54, 39), (137, 52, 39), + (133, 48, 38), (129, 44, 37), (127, 42, 36), (126, 41, 35), + (116, 36, 32), (109, 32, 31), (103, 28, 30), (96, 24, 29), + (90, 21, 28), (86, 19, 27), (82, 18, 27), (74, 14, 23), + (68, 12, 21), (58, 9, 18), (53, 7, 16), (48, 6, 15), + (46, 5, 14), (44, 5, 14), (41, 3, 12), (40, 3, 12), + (40, 2, 10), (39, 2, 10), (38, 2, 10), (37, 2, 9), + (36, 2, 9), (35, 2, 9), (35, 2, 9), (33, 2, 9), + (31, 1, 8), (26, 1, 8), (25, 0, 7), (24, 0, 7), + (24, 0, 7), (25, 0, 7), (27, 0, 6), (30, 1, 8), + (39, 2, 8), (44, 3, 9), (49, 4, 10), (50, 4, 10), + (52, 5, 11), (53, 5, 11), (54, 6, 12), (56, 6, 13), + (57, 6, 12), (58, 8, 18), (57, 8, 19), (57, 9, 20), + (57, 9, 19), (58, 9, 18), (59, 10, 19), (61, 12, 21), + (70, 15, 24), (76, 16, 24), (82, 18, 25), (84, 19, 25), + (87, 20, 25), (92, 21, 23), (98, 23, 25), (103, 24, 26), + (106, 25, 29), (103, 23, 27), (100, 22, 26), (98, 22, 25), + (91, 20, 23), (82, 18, 23), (71, 16, 23), (60, 12, 18), + (41, 7, 14), (34, 5, 11), (28, 3, 9), (26, 2, 8), + (25, 2, 8), (23, 2, 9), (22, 1, 7), (21, 0, 6), + (21, 0, 6), (21, 0, 7), (21, 0, 7), (21, 0, 7), + (21, 0, 7), (22, 0, 7), (23, 0, 8), (24, 0, 8), + (26, 0, 10), (27, 0, 9), (29, 1, 9), (29, 0, 8), + (30, 0, 8), (31, 1, 10), (31, 1, 10), (31, 1, 10), + (31, 0, 8), (30, 1, 10), (29, 1, 9), (29, 1, 9), + (28, 1, 10), (28, 0, 8), (29, 0, 9), (31, 0, 7), + (40, 4, 10), (43, 5, 10), (47, 6, 11), (55, 9, 14), + (64, 11, 15), (71, 12, 14), (77, 14, 14), (81, 17, 16), + (83, 17, 17), (81, 16, 18), (79, 15, 17), (77, 15, 17), + (71, 13, 14), (63, 10, 11), (55, 9, 12), (48, 7, 13), + (38, 4, 10), (37, 3, 9), (37, 3, 9), (37, 3, 9), + (40, 4, 11), (44, 5, 12), (47, 7, 15), (49, 9, 18), + (49, 10, 19), (49, 10, 19), (49, 10, 20), (48, 9, 19), + (46, 9, 18), (42, 8, 17), (36, 7, 16), (31, 5, 14), + (26, 1, 10), (25, 0, 9), (25, 0, 9), (24, 0, 8), + (23, 0, 8), (23, 0, 8), (23, 0, 8), (23, 0, 8), + (24, 0, 8), (23, 0, 8), (23, 0, 6), (24, 1, 9), + (26, 1, 8), (29, 2, 9), (33, 4, 12), (40, 6, 15), + (46, 9, 18), (52, 12, 22), (58, 14, 24), (65, 15, 24), + (74, 17, 25), (83, 20, 29), (88, 22, 29), (91, 24, 33), + (91, 25, 32), (91, 25, 32), (92, 26, 36), (93, 25, 34), + (92, 25, 34), (89, 24, 31), (86, 23, 31), (83, 23, 33), + (80, 21, 31), (79, 19, 29), (78, 18, 28), (79, 16, 24), + (80, 16, 24), (81, 16, 23), (83, 16, 23), (85, 17, 23), + (88, 17, 24), (90, 17, 23), (92, 17, 23), (92, 18, 25), + (91, 17, 22), (91, 17, 22), (88, 15, 18), (83, 13, 17), + (77, 12, 18), (71, 10, 17), (68, 9, 16), (67, 9, 16), + (67, 9, 16), (67, 10, 17), (67, 10, 18), (68, 11, 19), + (69, 12, 20), (71, 13, 22), (71, 13, 22), (69, 13, 22), + (65, 12, 21), (59, 10, 18), (55, 9, 17), (51, 9, 17), + (48, 8, 17), (48, 9, 17), (50, 10, 19), (55, 12, 19), + (52, 11, 18), (48, 9, 15), (44, 8, 14), (41, 7, 14) + ), + +// 584 Marina +((19, 87, 122), (22, 88, 114), (18, 90, 112), (14, 92, 110), + (15, 103, 113), (17, 115, 116), (17, 119, 115), (18, 123, 115), + (13, 138, 116), (14, 139, 117), (16, 141, 118), (20, 135, 122), + (25, 130, 127), (30, 129, 135), (35, 128, 143), (36, 127, 148), + (38, 127, 153), (44, 119, 171), (47, 119, 175), (50, 119, 179), + (51, 120, 175), (52, 122, 172), (56, 123, 167), (61, 124, 163), + (103, 136, 137), (117, 146, 136), (132, 156, 135), (136, 160, 142), + (141, 164, 150), (141, 163, 148), (141, 163, 147), (149, 163, 145), + (139, 161, 147), (101, 149, 168), (84, 139, 166), (67, 129, 164), + (64, 125, 153), (62, 121, 142), (64, 121, 140), (67, 121, 138), + (65, 119, 128), (59, 112, 125), (53, 105, 122), (51, 102, 120), + (50, 100, 119), (46, 97, 117), (43, 94, 115), (29, 82, 114), + (14, 68, 111), (2, 55, 106), (1, 57, 105), (1, 59, 105), + (3, 65, 105), (6, 71, 106), (6, 77, 105), (6, 83, 105), + (5, 106, 109), (6, 114, 109), (7, 123, 110), (7, 130, 105), + (7, 138, 100), (6, 140, 99), (6, 142, 99), (5, 141, 97), + (6, 132, 93), (5, 114, 94), (8, 115, 102), (11, 117, 110), + (15, 119, 113), (20, 121, 116), (32, 129, 127), (47, 133, 132), + (67, 139, 146), (72, 146, 157), (77, 154, 168), (85, 157, 174), + (94, 160, 180), (97, 159, 181), (101, 159, 182), (101, 153, 184), + (97, 149, 192), (91, 144, 204), (95, 147, 206), (100, 151, 208), + (104, 155, 210), (109, 160, 212), (117, 164, 212), (132, 161, 194), + (150, 138, 142), (140, 129, 138), (130, 121, 134), (125, 114, 132), + (121, 108, 130), (114, 111, 118), (107, 93, 95), (98, 89, 89), + (71, 89, 96), (27, 94, 125), (20, 94, 128), (14, 95, 132), + (11, 96, 134), (9, 98, 137), (6, 102, 137), (4, 102, 138), + (4, 87, 136), (4, 84, 138), (5, 82, 140), (6, 83, 142), + (7, 84, 145), (10, 86, 148), (15, 89, 152), (20, 94, 156), + (26, 99, 159), (34, 103, 152), (36, 100, 144), (39, 97, 137), + (42, 91, 123), (42, 86, 111), (42, 81, 105), (35, 78, 97), + (27, 52, 57), (22, 41, 45), (18, 31, 33), (14, 31, 36), + (11, 32, 40), (6, 35, 53), (3, 36, 61), (0, 36, 64), + (1, 41, 72), (0, 60, 105), (0, 65, 114), (1, 71, 123), + (2, 79, 134), (3, 83, 142), (3, 87, 149), (3, 89, 156), + (5, 91, 162), (6, 90, 162), (7, 90, 163), (6, 90, 164), + (6, 90, 166), (7, 94, 173), (18, 102, 178), (35, 118, 188), + (57, 137, 199), (91, 169, 212), (94, 170, 211), (98, 172, 211), + (99, 182, 209), (94, 188, 208), (98, 193, 203), (99, 199, 202), + (97, 187, 190), (90, 182, 188), (83, 178, 187), (75, 170, 186), + (71, 169, 191), (76, 166, 196), (91, 167, 200), (102, 168, 206), + (112, 165, 210), (111, 160, 218), (108, 158, 216), (105, 156, 214), + (95, 149, 210), (86, 139, 205), (78, 133, 200), (72, 129, 197), + (63, 125, 190), (61, 122, 189), (59, 120, 189), (59, 122, 188), + (63, 124, 189), (71, 128, 188), (79, 133, 185), (86, 134, 180), + (88, 132, 176), (82, 128, 170), (78, 124, 163), (75, 123, 151), + (78, 129, 132), (86, 131, 118), (81, 132, 113), (71, 125, 115), + (45, 116, 123), (45, 117, 120), (46, 119, 118), (46, 122, 121), + (42, 119, 129), (35, 114, 144), (26, 107, 157), (23, 102, 163), + (25, 102, 167), (28, 104, 169), (34, 110, 171), (44, 117, 169), + (52, 121, 166), (57, 122, 165), (56, 118, 165), (51, 112, 158), + (50, 107, 146), (53, 102, 128), (60, 93, 111), (68, 78, 95), + (72, 60, 80), (80, 43, 64), (89, 33, 46), (97, 27, 32), + (111, 20, 19), (118, 15, 11), (121, 14, 9), (121, 20, 10), + (110, 32, 20), (107, 42, 34), (103, 54, 44), (98, 64, 54), + (96, 77, 59), (83, 92, 69), (73, 100, 80), (63, 110, 87), + (57, 111, 91), (56, 109, 90), (50, 104, 90), (42, 90, 84), + (26, 80, 73), (17, 71, 59), (10, 64, 53), (6, 57, 54), + (6, 49, 60), (2, 42, 65), (4, 38, 63), (5, 41, 64), + (5, 46, 73), (5, 52, 87), (2, 57, 104), (0, 61, 117), + (0, 65, 123), (0, 67, 128), (0, 68, 126), (1, 67, 125), + (1, 65, 122), (2, 63, 118), (2, 63, 117), (1, 62, 114), + (1, 62, 112), (1, 61, 112), (2, 62, 113), (3, 66, 119), + (4, 73, 126), (7, 80, 134), (10, 87, 138), (16, 95, 139), + (15, 87, 129), (13, 83, 121), (12, 77, 117), (10, 74, 114) + ), + +// 585 Meadow +((153, 129, 176), (154, 126, 170), (168, 135, 178), (183, 144, 187), + (195, 152, 198), (208, 160, 209), (212, 162, 213), (217, 165, 218), + (235, 179, 234), (228, 176, 228), (222, 173, 223), (203, 163, 206), + (185, 153, 190), (164, 147, 168), (143, 142, 146), (127, 140, 128), + (111, 138, 110), (105, 127, 91), (105, 124, 90), (105, 122, 89), + (108, 117, 88), (111, 112, 88), (111, 102, 93), (112, 92, 99), + (111, 76, 119), (103, 70, 111), (95, 64, 103), (84, 58, 94), + (74, 52, 85), (69, 50, 80), (65, 49, 75), (53, 45, 64), + (45, 41, 59), (38, 38, 50), (36, 38, 49), (35, 39, 48), + (34, 39, 45), (34, 39, 42), (34, 37, 41), (34, 36, 40), + (33, 35, 41), (34, 35, 43), (36, 36, 46), (44, 41, 52), + (52, 46, 59), (57, 48, 64), (62, 50, 70), (74, 57, 81), + (87, 64, 94), (110, 81, 117), (115, 86, 121), (120, 91, 126), + (114, 92, 121), (109, 93, 117), (103, 91, 111), (97, 89, 106), + (68, 93, 66), (55, 93, 51), (42, 93, 37), (36, 94, 30), + (31, 96, 24), (32, 96, 25), (34, 97, 27), (38, 97, 36), + (48, 101, 47), (72, 116, 101), (76, 130, 116), (81, 145, 132), + (79, 143, 123), (77, 141, 114), (68, 135, 90), (55, 142, 69), + (33, 138, 34), (39, 135, 23), (45, 133, 13), (43, 131, 7), + (42, 130, 2), (41, 131, 1), (40, 133, 1), (40, 133, 1), + (29, 126, 0), (37, 133, 2), (34, 128, 5), (31, 123, 9), + (34, 118, 15), (37, 113, 22), (45, 109, 35), (49, 99, 46), + (67, 83, 71), (71, 76, 78), (76, 70, 86), (80, 67, 90), + (84, 65, 94), (89, 62, 98), (94, 65, 102), (101, 70, 107), + (109, 78, 117), (130, 95, 135), (134, 98, 140), (139, 102, 145), + (139, 102, 145), (140, 102, 145), (134, 98, 139), (123, 92, 129), + (102, 78, 107), (95, 75, 100), (88, 72, 94), (85, 70, 91), + (82, 69, 89), (75, 67, 85), (77, 66, 88), (78, 67, 88), + (77, 66, 87), (64, 60, 80), (62, 58, 76), (60, 56, 73), + (57, 52, 68), (54, 52, 68), (57, 56, 72), (62, 58, 75), + (92, 70, 101), (106, 79, 114), (120, 89, 128), (128, 94, 136), + (137, 99, 144), (149, 106, 156), (161, 116, 166), (165, 121, 171), + (172, 126, 175), (175, 128, 178), (173, 127, 178), (172, 127, 178), + (172, 126, 177), (169, 126, 174), (162, 125, 167), (152, 124, 160), + (130, 140, 158), (118, 149, 158), (107, 159, 159), (99, 155, 145), + (92, 151, 132), (74, 144, 101), (52, 147, 74), (41, 137, 65), + (32, 134, 44), (34, 137, 14), (33, 128, 15), (32, 119, 17), + (33, 102, 23), (37, 88, 32), (44, 85, 36), (48, 72, 47), + (70, 61, 78), (79, 65, 86), (88, 70, 94), (101, 77, 108), + (99, 75, 106), (102, 79, 110), (101, 82, 109), (95, 83, 106), + (80, 76, 94), (56, 75, 69), (47, 73, 57), (39, 71, 45), + (27, 73, 26), (20, 69, 20), (26, 70, 18), (31, 70, 20), + (39, 69, 32), (45, 70, 37), (51, 72, 43), (57, 72, 54), + (69, 72, 70), (73, 76, 87), (80, 83, 98), (87, 95, 105), + (89, 97, 104), (87, 94, 100), (82, 84, 97), (77, 79, 92), + (71, 77, 85), (66, 71, 76), (62, 62, 71), (70, 61, 75), + (73, 72, 89), (79, 82, 95), (85, 93, 102), (95, 108, 115), + (99, 124, 127), (107, 125, 131), (105, 131, 132), (98, 129, 127), + (87, 124, 120), (85, 111, 111), (84, 93, 100), (79, 76, 91), + (82, 73, 92), (91, 75, 100), (104, 81, 112), (123, 90, 129), + (144, 103, 148), (165, 117, 166), (180, 128, 181), (189, 135, 189), + (192, 140, 192), (195, 142, 195), (196, 142, 196), (188, 138, 191), + (179, 132, 184), (174, 126, 179), (171, 123, 175), (162, 120, 168), + (151, 117, 159), (138, 108, 149), (124, 97, 135), (107, 87, 118), + (89, 79, 99), (72, 72, 82), (57, 66, 63), (40, 55, 41), + (29, 47, 29), (20, 42, 21), (17, 41, 15), (15, 39, 13), + (16, 38, 12), (12, 30, 12), (15, 25, 18), (21, 27, 29), + (24, 30, 31), (25, 28, 30), (25, 25, 34), (34, 32, 45), + (48, 47, 61), (64, 61, 75), (81, 71, 90), (106, 85, 114), + (129, 103, 135), (151, 124, 157), (173, 138, 177), (191, 148, 194), + (205, 154, 206), (208, 158, 212), (213, 160, 215), (208, 162, 211), + (203, 170, 199), (193, 176, 197), (199, 183, 205), (202, 186, 214), + (217, 197, 217), (210, 203, 216), (210, 204, 223), (202, 191, 230), + (199, 177, 222), (193, 164, 214), (180, 153, 202), (169, 140, 191) + ), + +// 586 Mermaid +((70, 122, 117), (80, 108, 100), (81, 102, 97), (82, 97, 94), + (76, 94, 104), (71, 92, 114), (67, 91, 120), (64, 90, 127), + (54, 86, 151), (60, 88, 156), (66, 91, 161), (76, 97, 166), + (87, 103, 172), (95, 110, 177), (103, 117, 183), (104, 121, 185), + (106, 125, 188), (101, 135, 205), (93, 139, 207), (86, 144, 210), + (84, 146, 210), (82, 148, 211), (81, 148, 211), (81, 149, 211), + (74, 129, 204), (73, 121, 202), (73, 114, 200), (66, 102, 198), + (59, 91, 196), (57, 89, 196), (56, 88, 196), (56, 91, 197), + (56, 93, 199), (51, 91, 203), (49, 92, 207), (48, 94, 211), + (41, 87, 213), (34, 80, 216), (31, 78, 217), (28, 76, 218), + (17, 71, 218), (15, 72, 216), (14, 73, 215), (15, 78, 212), + (17, 83, 210), (18, 88, 209), (20, 93, 209), (24, 102, 207), + (26, 108, 203), (34, 121, 193), (38, 126, 186), (43, 131, 179), + (44, 131, 166), (46, 131, 154), (46, 132, 149), (46, 134, 145), + (49, 138, 138), (44, 135, 139), (39, 132, 141), (36, 128, 148), + (34, 124, 156), (31, 119, 160), (29, 115, 165), (23, 103, 172), + (19, 91, 175), (16, 71, 178), (16, 66, 175), (16, 61, 173), + (19, 64, 172), (23, 68, 171), (32, 81, 168), (39, 89, 154), + (55, 116, 126), (63, 132, 118), (71, 148, 110), (78, 155, 113), + (85, 162, 116), (84, 161, 121), (84, 161, 127), (75, 151, 134), + (72, 139, 146), (70, 124, 179), (63, 114, 178), (57, 105, 178), + (56, 103, 174), (56, 101, 171), (57, 103, 161), (56, 106, 145), + (47, 113, 114), (43, 116, 104), (40, 119, 95), (36, 119, 91), + (32, 120, 88), (25, 120, 88), (23, 120, 90), (22, 119, 89), + (20, 118, 86), (28, 107, 77), (37, 101, 69), (47, 95, 61), + (51, 90, 56), (55, 86, 51), (66, 78, 44), (78, 77, 40), + (104, 89, 45), (104, 93, 42), (105, 98, 39), (102, 100, 37), + (99, 103, 35), (91, 106, 34), (82, 110, 37), (73, 114, 42), + (66, 118, 52), (59, 120, 79), (60, 119, 85), (61, 118, 92), + (67, 117, 102), (78, 118, 109), (88, 117, 110), (98, 114, 104), + (114, 108, 76), (119, 107, 63), (125, 107, 50), (126, 107, 46), + (128, 108, 43), (127, 107, 36), (124, 106, 30), (116, 106, 29), + (104, 102, 29), (73, 90, 25), (67, 88, 26), (61, 87, 27), + (53, 85, 33), (46, 83, 40), (39, 75, 42), (39, 67, 44), + (58, 60, 48), (70, 57, 45), (83, 54, 42), (90, 57, 39), + (98, 61, 37), (116, 80, 36), (124, 95, 30), (124, 105, 24), + (119, 117, 21), (103, 146, 26), (96, 148, 29), (90, 150, 33), + (78, 152, 47), (69, 157, 64), (61, 156, 83), (55, 152, 104), + (54, 161, 151), (56, 164, 159), (59, 168, 167), (60, 168, 175), + (54, 167, 175), (46, 164, 163), (42, 159, 141), (40, 150, 117), + (41, 143, 97), (54, 135, 61), (55, 131, 52), (57, 127, 44), + (55, 118, 35), (59, 117, 40), (71, 127, 58), (78, 140, 81), + (72, 142, 118), (71, 143, 127), (70, 144, 137), (74, 154, 162), + (77, 160, 182), (77, 158, 194), (72, 153, 202), (67, 152, 210), + (62, 148, 213), (53, 140, 213), (42, 133, 213), (34, 129, 209), + (29, 125, 199), (24, 118, 186), (22, 111, 170), (24, 106, 152), + (28, 100, 114), (30, 99, 109), (32, 98, 105), (36, 97, 99), + (37, 99, 100), (32, 97, 101), (30, 93, 107), (28, 87, 114), + (26, 84, 120), (22, 79, 119), (21, 71, 113), (24, 60, 101), + (27, 49, 84), (31, 41, 68), (35, 35, 54), (39, 34, 48), + (40, 35, 44), (39, 40, 46), (36, 48, 52), (31, 59, 61), + (26, 70, 68), (21, 79, 69), (17, 84, 66), (17, 88, 61), + (20, 93, 55), (24, 96, 51), (29, 96, 50), (35, 97, 54), + (40, 102, 64), (40, 106, 77), (39, 112, 94), (37, 116, 110), + (37, 122, 125), (33, 127, 138), (30, 132, 150), (29, 136, 158), + (33, 140, 163), (41, 143, 167), (54, 149, 171), (67, 153, 173), + (77, 152, 172), (86, 150, 165), (97, 150, 154), (105, 149, 140), + (106, 145, 123), (104, 145, 104), (103, 145, 85), (100, 145, 67), + (92, 143, 51), (84, 142, 37), (78, 141, 27), (73, 137, 21), + (71, 134, 20), (70, 130, 24), (71, 125, 31), (73, 120, 39), + (78, 116, 49), (86, 109, 59), (91, 104, 65), (94, 100, 68), + (96, 96, 71), (95, 92, 71), (86, 87, 65), (74, 87, 59), + (66, 92, 63), (63, 105, 80), (53, 113, 96), (44, 120, 106), + (40, 123, 113), (46, 130, 127), (51, 132, 135), (60, 130, 132) + ), + +// 587 Mesmerize +((20, 29, 51), (12, 59, 51), (12, 83, 57), (12, 107, 63), + (25, 120, 72), (39, 133, 82), (46, 145, 85), (53, 158, 89), + (77, 150, 120), (84, 151, 127), (91, 153, 135), (95, 148, 139), + (100, 143, 144), (112, 135, 146), (124, 128, 149), (132, 130, 154), + (140, 132, 159), (159, 138, 154), (171, 139, 156), (184, 141, 158), + (190, 145, 154), (197, 149, 151), (201, 146, 153), (206, 144, 156), + (224, 140, 154), (225, 118, 156), (226, 97, 159), (211, 85, 158), + (197, 74, 158), (188, 65, 155), (179, 56, 153), (140, 59, 152), + (100, 64, 147), (50, 65, 111), (40, 73, 101), (30, 81, 92), + (57, 81, 96), (85, 81, 101), (99, 86, 105), (113, 91, 109), + (179, 56, 135), (189, 47, 144), (199, 38, 154), (208, 29, 154), + (218, 21, 154), (216, 30, 155), (214, 39, 157), (228, 48, 159), + (196, 51, 149), (184, 88, 135), (172, 92, 124), (161, 96, 114), + (177, 99, 109), (193, 102, 104), (189, 105, 103), (186, 108, 102), + (161, 112, 115), (159, 124, 120), (157, 136, 125), (171, 133, 134), + (186, 130, 143), (200, 131, 144), (214, 133, 146), (233, 128, 147), + (240, 127, 143), (243, 133, 124), (245, 132, 122), (247, 132, 120), + (241, 134, 121), (236, 136, 122), (227, 127, 127), (218, 123, 133), + (182, 126, 149), (161, 120, 139), (141, 114, 130), (134, 114, 129), + (128, 114, 128), (123, 108, 128), (118, 103, 128), (110, 103, 130), + (122, 101, 137), (127, 85, 150), (129, 92, 150), (131, 100, 150), + (129, 108, 148), (127, 116, 147), (122, 123, 141), (118, 134, 139), + (140, 146, 134), (152, 129, 135), (165, 113, 136), (169, 108, 138), + (174, 104, 141), (177, 99, 154), (170, 92, 165), (161, 89, 166), + (164, 95, 170), (179, 118, 162), (192, 107, 143), (205, 97, 124), + (209, 95, 117), (214, 94, 111), (232, 76, 104), (236, 56, 101), + (245, 44, 107), (244, 45, 115), (244, 46, 124), (239, 48, 128), + (234, 51, 132), (225, 62, 135), (215, 72, 144), (202, 75, 157), + (191, 77, 158), (164, 70, 161), (153, 63, 164), (142, 56, 168), + (128, 41, 170), (116, 34, 167), (91, 44, 166), (81, 41, 163), + (105, 49, 153), (109, 58, 150), (113, 67, 148), (116, 71, 151), + (119, 76, 155), (131, 91, 160), (142, 110, 158), (148, 124, 157), + (167, 134, 150), (197, 133, 135), (198, 128, 131), (200, 123, 128), + (197, 108, 116), (194, 100, 110), (181, 101, 109), (163, 107, 115), + (132, 137, 128), (115, 142, 141), (99, 148, 155), (94, 147, 156), + (89, 146, 158), (111, 129, 163), (132, 125, 160), (148, 128, 146), + (179, 128, 135), (231, 139, 123), (235, 136, 118), (240, 134, 114), + (244, 130, 119), (249, 125, 126), (249, 117, 135), (250, 118, 144), + (246, 142, 154), (246, 144, 157), (246, 146, 160), (248, 149, 161), + (243, 139, 160), (247, 117, 160), (249, 96, 160), (247, 75, 160), + (251, 52, 161), (245, 39, 156), (242, 35, 153), (239, 31, 150), + (235, 38, 141), (224, 51, 134), (210, 52, 134), (202, 54, 132), + (181, 52, 132), (179, 51, 138), (178, 51, 144), (184, 37, 144), + (183, 35, 140), (187, 48, 144), (194, 54, 149), (210, 62, 147), + (223, 84, 138), (222, 109, 134), (229, 126, 133), (241, 134, 131), + (238, 142, 132), (237, 148, 136), (237, 143, 144), (221, 147, 152), + (195, 143, 160), (179, 143, 158), (164, 144, 156), (138, 143, 144), + (106, 120, 124), (73, 92, 103), (60, 71, 92), (71, 48, 96), + (87, 29, 97), (103, 14, 98), (154, 18, 120), (195, 29, 133), + (211, 33, 128), (234, 44, 124), (242, 61, 124), (241, 73, 125), + (246, 75, 120), (246, 82, 117), (244, 93, 110), (237, 107, 104), + (224, 117, 102), (217, 125, 89), (217, 142, 87), (218, 140, 89), + (220, 132, 85), (228, 128, 100), (241, 111, 113), (246, 91, 121), + (241, 74, 134), (234, 65, 149), (225, 54, 161), (208, 43, 167), + (191, 41, 164), (181, 42, 165), (172, 41, 173), (172, 41, 168), + (182, 54, 167), (198, 62, 175), (206, 61, 169), (210, 77, 166), + (216, 88, 168), (205, 83, 167), (192, 83, 164), (185, 84, 158), + (181, 78, 155), (181, 72, 153), (183, 74, 147), (192, 78, 148), + (204, 85, 150), (210, 95, 149), (213, 97, 153), (212, 101, 154), + (196, 104, 150), (178, 95, 147), (153, 96, 146), (109, 97, 136), + (85, 87, 118), (89, 92, 119), (79, 91, 124), (84, 77, 118), + (119, 75, 113), (151, 69, 119), (174, 56, 129), (193, 51, 119), + (205, 50, 104), (205, 48, 103), (168, 44, 96), (126, 42, 80), + (115, 31, 68), (72, 25, 61), (29, 33, 55), (26, 28, 49) + ), + +// 588 Midnight_Wave +((15, 35, 151), (16, 39, 153), (17, 39, 157), (18, 40, 161), + (19, 39, 165), (20, 39, 170), (20, 40, 171), (21, 42, 172), + (23, 47, 173), (22, 44, 171), (21, 41, 170), (20, 35, 167), + (20, 29, 164), (18, 27, 158), (17, 26, 153), (17, 26, 148), + (17, 26, 144), (12, 22, 126), (10, 18, 116), (9, 14, 106), + (7, 11, 94), (5, 8, 83), (4, 7, 77), (3, 6, 72), + (1, 3, 53), (0, 2, 45), (0, 2, 37), (0, 1, 32), + (0, 0, 27), (0, 0, 25), (0, 0, 24), (0, 0, 23), + (0, 0, 23), (0, 1, 25), (0, 1, 28), (0, 1, 31), + (0, 1, 34), (1, 2, 37), (2, 3, 38), (3, 5, 39), + (5, 8, 42), (5, 7, 42), (5, 7, 43), (4, 6, 41), + (4, 6, 39), (4, 6, 38), (5, 7, 37), (6, 9, 36), + (5, 8, 35), (3, 6, 34), (2, 4, 35), (1, 2, 36), + (1, 3, 40), (1, 4, 45), (1, 4, 49), (2, 5, 54), + (6, 16, 79), (13, 30, 94), (20, 44, 109), (41, 66, 126), + (62, 89, 143), (74, 99, 152), (87, 110, 162), (106, 129, 179), + (121, 148, 193), (139, 180, 217), (143, 186, 220), (148, 192, 224), + (148, 190, 224), (148, 188, 224), (144, 177, 221), (128, 158, 213), + (92, 124, 188), (72, 103, 173), (53, 82, 159), (36, 62, 143), + (20, 42, 127), (17, 36, 121), (15, 30, 116), (10, 21, 102), + (7, 15, 88), (3, 7, 66), (2, 5, 58), (1, 3, 50), + (0, 2, 47), (0, 2, 44), (0, 2, 39), (0, 2, 36), + (0, 2, 30), (0, 1, 29), (0, 1, 28), (0, 1, 28), + (0, 2, 28), (1, 2, 28), (1, 2, 28), (1, 2, 28), + (1, 2, 27), (1, 1, 27), (1, 1, 29), (1, 2, 32), + (1, 2, 34), (1, 3, 36), (2, 3, 42), (2, 4, 48), + (2, 5, 61), (3, 7, 71), (5, 10, 82), (6, 12, 87), + (8, 15, 92), (8, 15, 92), (8, 15, 94), (8, 15, 97), + (10, 16, 101), (16, 25, 129), (17, 27, 131), (19, 30, 134), + (21, 33, 137), (20, 34, 139), (20, 31, 137), (16, 25, 136), + (16, 25, 150), (16, 26, 150), (17, 27, 150), (16, 27, 148), + (16, 27, 147), (16, 24, 144), (14, 22, 143), (14, 25, 142), + (16, 34, 142), (26, 59, 148), (29, 65, 150), (32, 72, 152), + (38, 82, 160), (44, 95, 169), (49, 108, 178), (54, 114, 185), + (53, 113, 177), (49, 104, 166), (45, 95, 156), (43, 92, 151), + (42, 90, 146), (41, 83, 144), (37, 72, 142), (33, 65, 140), + (28, 59, 137), (22, 54, 130), (22, 55, 131), (23, 56, 132), + (22, 52, 134), (21, 49, 137), (20, 48, 137), (19, 47, 135), + (18, 49, 120), (17, 46, 114), (16, 44, 109), (13, 33, 97), + (9, 23, 84), (5, 12, 71), (3, 6, 58), (2, 4, 48), + (1, 3, 41), (0, 2, 34), (0, 2, 34), (0, 2, 34), + (0, 2, 35), (0, 1, 37), (0, 2, 40), (0, 2, 43), + (1, 3, 53), (1, 3, 56), (2, 4, 59), (2, 5, 66), + (3, 6, 77), (3, 6, 86), (4, 7, 92), (4, 7, 97), + (4, 7, 100), (4, 7, 100), (4, 8, 102), (4, 9, 105), + (4, 10, 105), (4, 10, 103), (4, 10, 102), (4, 10, 98), + (4, 10, 99), (4, 11, 101), (5, 12, 104), (7, 15, 110), + (9, 19, 118), (12, 22, 125), (15, 25, 132), (17, 27, 141), + (18, 28, 151), (19, 28, 160), (20, 28, 167), (20, 28, 169), + (20, 28, 165), (20, 27, 157), (18, 24, 147), (16, 21, 138), + (14, 17, 128), (11, 13, 117), (8, 10, 105), (6, 7, 91), + (4, 5, 78), (2, 5, 67), (2, 3, 58), (1, 3, 52), + (1, 3, 49), (1, 3, 48), (2, 3, 50), (2, 4, 54), + (3, 5, 56), (3, 5, 58), (3, 6, 60), (3, 6, 59), + (4, 5, 59), (4, 5, 60), (5, 6, 61), (4, 7, 63), + (5, 9, 68), (6, 11, 73), (7, 15, 82), (10, 20, 91), + (15, 29, 102), (18, 40, 112), (23, 50, 122), (28, 57, 135), + (30, 62, 148), (31, 67, 161), (34, 69, 172), (34, 72, 179), + (35, 74, 182), (36, 72, 181), (35, 67, 181), (31, 61, 178), + (27, 50, 172), (23, 43, 166), (19, 35, 160), (17, 29, 153), + (16, 25, 152), (16, 23, 152), (16, 24, 152), (18, 28, 154), + (18, 31, 156), (18, 33, 155), (18, 37, 157), (18, 38, 158), + (18, 38, 157), (19, 38, 157), (18, 38, 156), (17, 37, 155), + (16, 37, 156), (15, 36, 157), (14, 35, 155), (15, 34, 154) + ), + +// 589 Mint +((109, 152, 117), (117, 169, 136), (119, 172, 143), (121, 175, 150), + (121, 173, 147), (122, 172, 145), (121, 171, 144), (120, 171, 143), + (117, 160, 128), (110, 152, 123), (104, 144, 119), (94, 131, 116), + (84, 119, 113), (76, 108, 112), (69, 98, 111), (67, 93, 107), + (65, 89, 104), (69, 86, 104), (73, 91, 105), (78, 96, 107), + (86, 104, 115), (94, 113, 124), (97, 119, 127), (100, 125, 131), + (116, 140, 141), (120, 145, 143), (124, 151, 145), (129, 155, 149), + (135, 159, 154), (137, 162, 154), (139, 165, 155), (146, 175, 164), + (156, 180, 165), (157, 174, 155), (155, 170, 152), (153, 167, 150), + (145, 161, 150), (137, 155, 150), (136, 154, 150), (135, 154, 150), + (130, 148, 149), (123, 147, 140), (117, 146, 132), (111, 146, 126), + (105, 146, 120), (104, 147, 117), (103, 148, 115), (102, 149, 115), + (105, 155, 121), (123, 161, 133), (129, 165, 137), (136, 169, 142), + (139, 169, 142), (142, 169, 142), (142, 168, 141), (143, 167, 141), + (135, 165, 134), (130, 160, 131), (125, 155, 128), (117, 150, 124), + (110, 146, 121), (106, 142, 119), (102, 139, 118), (98, 134, 117), + (93, 131, 112), (93, 137, 110), (99, 140, 108), (105, 144, 106), + (110, 147, 106), (116, 150, 106), (125, 156, 110), (123, 156, 116), + (118, 148, 114), (108, 144, 111), (98, 140, 109), (90, 135, 99), + (82, 131, 90), (79, 129, 87), (77, 127, 85), (71, 123, 80), + (72, 123, 79), (70, 113, 83), (68, 109, 85), (67, 106, 88), + (66, 101, 88), (66, 96, 88), (60, 86, 83), (54, 79, 82), + (55, 68, 83), (56, 70, 86), (57, 72, 89), (58, 74, 90), + (59, 76, 91), (62, 84, 95), (69, 95, 99), (73, 104, 102), + (77, 110, 107), (84, 121, 108), (84, 116, 107), (84, 112, 107), + (84, 110, 106), (84, 109, 106), (88, 108, 105), (93, 113, 105), + (110, 129, 107), (111, 134, 108), (113, 140, 110), (112, 140, 109), + (111, 140, 108), (103, 127, 107), (96, 116, 102), (87, 111, 99), + (73, 97, 92), (57, 74, 74), (51, 71, 72), (45, 69, 70), + (34, 60, 59), (24, 45, 48), (20, 42, 44), (21, 44, 44), + (18, 43, 50), (29, 53, 59), (41, 63, 69), (44, 69, 73), + (47, 75, 78), (56, 85, 85), (70, 97, 95), (78, 105, 103), + (85, 110, 108), (97, 126, 121), (99, 129, 123), (102, 133, 125), + (109, 135, 130), (110, 139, 128), (110, 146, 127), (110, 148, 130), + (108, 148, 129), (105, 147, 130), (103, 146, 131), (103, 144, 133), + (103, 143, 136), (107, 145, 141), (113, 147, 140), (118, 150, 142), + (123, 156, 148), (128, 163, 138), (127, 163, 135), (126, 163, 133), + (123, 161, 123), (121, 158, 115), (119, 155, 108), (114, 150, 102), + (105, 148, 96), (101, 146, 95), (98, 144, 95), (89, 135, 90), + (80, 124, 87), (72, 109, 83), (62, 96, 75), (53, 84, 72), + (53, 76, 73), (56, 88, 85), (62, 95, 92), (68, 102, 100), + (78, 119, 108), (84, 130, 116), (91, 138, 124), (91, 143, 122), + (80, 132, 104), (74, 126, 99), (69, 121, 94), (59, 107, 80), + (50, 98, 67), (48, 92, 69), (48, 85, 71), (49, 86, 67), + (59, 93, 76), (65, 99, 88), (67, 102, 94), (71, 104, 93), + (70, 105, 92), (66, 103, 95), (63, 95, 94), (58, 90, 89), + (57, 95, 87), (59, 97, 86), (61, 99, 85), (70, 108, 88), + (81, 124, 89), (93, 135, 91), (107, 142, 98), (117, 151, 104), + (124, 160, 109), (130, 161, 117), (130, 159, 121), (126, 156, 122), + (124, 149, 127), (115, 141, 127), (104, 133, 124), (100, 126, 121), + (92, 119, 116), (83, 117, 109), (85, 121, 103), (89, 124, 99), + (94, 132, 98), (101, 141, 104), (112, 147, 111), (123, 151, 120), + (129, 152, 133), (130, 151, 143), (131, 148, 147), (132, 144, 149), + (127, 141, 148), (124, 137, 141), (119, 129, 137), (111, 124, 134), + (109, 123, 129), (105, 117, 128), (102, 118, 130), (105, 126, 131), + (106, 130, 133), (110, 137, 135), (115, 146, 136), (114, 150, 140), + (111, 155, 142), (114, 162, 139), (117, 165, 139), (114, 166, 141), + (111, 168, 140), (116, 167, 138), (115, 165, 135), (111, 160, 133), + (110, 150, 131), (105, 144, 128), (104, 136, 125), (102, 125, 121), + (95, 115, 118), (88, 105, 116), (86, 102, 117), (87, 101, 116), + (86, 98, 115), (85, 100, 116), (91, 107, 115), (94, 110, 116), + (93, 113, 119), (93, 116, 119), (91, 116, 120), (90, 116, 120), + (88, 112, 117), (84, 108, 115), (82, 104, 110), (81, 104, 104), + (83, 108, 98), (88, 111, 93), (93, 122, 98), (102, 142, 108) + ), + +// 590 Mistic +((29, 24, 66), (23, 20, 65), (19, 18, 64), (15, 17, 64), + (12, 14, 59), (10, 11, 54), (7, 9, 50), (5, 8, 46), + (7, 12, 36), (12, 19, 35), (18, 26, 34), (24, 32, 41), + (31, 39, 49), (38, 44, 56), (45, 49, 63), (48, 50, 66), + (52, 52, 69), (48, 47, 84), (43, 40, 85), (38, 34, 87), + (36, 33, 92), (35, 32, 98), (34, 32, 101), (34, 33, 105), + (43, 38, 108), (52, 47, 113), (61, 56, 119), (69, 64, 120), + (78, 72, 122), (79, 75, 121), (81, 78, 120), (83, 82, 115), + (82, 85, 111), (79, 85, 106), (77, 81, 101), (75, 77, 97), + (76, 76, 97), (77, 76, 97), (77, 75, 95), (78, 74, 94), + (90, 77, 93), (95, 80, 98), (101, 84, 104), (104, 86, 106), + (108, 88, 109), (109, 91, 113), (110, 94, 117), (115, 98, 127), + (119, 98, 136), (111, 98, 147), (100, 89, 143), (90, 81, 139), + (77, 70, 130), (65, 59, 122), (59, 53, 117), (53, 48, 112), + (38, 37, 87), (42, 40, 82), (46, 43, 78), (54, 50, 81), + (63, 57, 85), (66, 62, 88), (70, 68, 92), (78, 75, 101), + (83, 81, 114), (90, 92, 132), (92, 94, 134), (94, 97, 136), + (97, 99, 136), (100, 101, 137), (108, 105, 144), (117, 111, 149), + (132, 118, 155), (142, 125, 163), (153, 133, 172), (163, 143, 181), + (174, 154, 191), (177, 154, 188), (180, 155, 185), (176, 149, 181), + (175, 152, 186), (167, 142, 168), (148, 127, 151), (129, 112, 135), + (123, 107, 130), (117, 103, 126), (107, 93, 117), (99, 92, 112), + (91, 89, 110), (91, 89, 115), (91, 89, 121), (90, 88, 124), + (90, 87, 128), (87, 85, 130), (85, 83, 129), (80, 81, 124), + (77, 74, 120), (76, 67, 117), (82, 70, 119), (88, 74, 121), + (91, 77, 122), (95, 80, 123), (100, 84, 122), (100, 89, 126), + (92, 84, 120), (87, 82, 113), (83, 81, 106), (83, 79, 103), + (83, 77, 101), (86, 77, 102), (95, 80, 106), (100, 84, 110), + (103, 88, 111), (110, 94, 116), (109, 92, 117), (108, 91, 118), + (100, 85, 119), (90, 80, 120), (89, 79, 123), (91, 81, 125), + (97, 92, 139), (110, 103, 146), (124, 114, 153), (132, 119, 154), + (140, 125, 155), (153, 135, 157), (162, 142, 157), (167, 143, 156), + (168, 140, 156), (164, 139, 150), (159, 136, 146), (154, 134, 143), + (142, 123, 141), (129, 115, 139), (119, 109, 136), (108, 104, 129), + (90, 85, 122), (84, 79, 118), (78, 74, 114), (76, 73, 113), + (75, 73, 113), (75, 75, 115), (75, 76, 114), (76, 77, 113), + (79, 80, 111), (88, 90, 118), (87, 90, 118), (87, 91, 118), + (87, 91, 111), (85, 87, 104), (84, 89, 101), (84, 91, 103), + (88, 91, 104), (89, 92, 103), (90, 93, 103), (93, 98, 106), + (97, 104, 114), (99, 105, 119), (99, 104, 116), (97, 99, 110), + (94, 90, 102), (84, 76, 90), (80, 74, 89), (77, 72, 88), + (73, 63, 86), (72, 53, 84), (68, 49, 81), (62, 49, 84), + (49, 40, 81), (46, 36, 77), (43, 33, 74), (36, 26, 70), + (29, 22, 66), (24, 19, 59), (19, 17, 52), (16, 14, 45), + (14, 16, 46), (21, 26, 49), (32, 36, 54), (44, 47, 58), + (55, 57, 68), (72, 71, 85), (90, 86, 104), (108, 100, 118), + (145, 121, 141), (155, 125, 145), (165, 129, 149), (177, 134, 150), + (182, 138, 149), (182, 137, 148), (178, 135, 148), (171, 128, 146), + (155, 116, 144), (134, 104, 141), (112, 92, 139), (96, 82, 135), + (83, 71, 134), (68, 60, 127), (56, 51, 125), (47, 45, 117), + (43, 41, 112), (38, 36, 106), (35, 34, 104), (31, 34, 101), + (31, 39, 95), (33, 44, 90), (43, 54, 88), (54, 67, 95), + (72, 80, 106), (88, 94, 116), (104, 106, 125), (117, 122, 136), + (131, 132, 149), (145, 141, 161), (153, 144, 168), (160, 151, 170), + (168, 156, 170), (179, 158, 169), (189, 161, 166), (198, 160, 164), + (203, 160, 161), (208, 155, 160), (207, 152, 154), (200, 145, 149), + (189, 142, 144), (184, 137, 139), (175, 130, 132), (150, 112, 126), + (122, 95, 116), (107, 79, 103), (101, 70, 89), (83, 60, 82), + (62, 53, 77), (47, 42, 70), (42, 31, 65), (36, 29, 65), + (30, 31, 69), (27, 33, 72), (27, 26, 72), (27, 22, 69), + (24, 17, 67), (18, 13, 61), (16, 8, 51), (15, 6, 38), + (15, 7, 34), (9, 6, 31), (9, 4, 31), (6, 2, 27), + (7, 3, 30), (5, 5, 37), (9, 9, 47), (14, 11, 53), + (20, 12, 55), (21, 13, 56), (24, 19, 59), (25, 23, 65) + ), + +// 591 Mixed_Berry +((110, 35, 80), (140, 36, 80), (142, 30, 78), (144, 24, 76), + (149, 18, 80), (155, 13, 84), (149, 13, 82), (144, 14, 81), + (103, 12, 83), (80, 9, 80), (57, 7, 78), (48, 13, 71), + (40, 19, 64), (51, 25, 52), (63, 31, 40), (67, 29, 34), + (71, 27, 29), (97, 24, 22), (107, 24, 21), (118, 25, 21), + (125, 21, 22), (132, 18, 23), (137, 19, 25), (143, 20, 28), + (172, 25, 23), (176, 29, 22), (180, 33, 21), (172, 39, 31), + (165, 46, 42), (157, 52, 47), (149, 58, 53), (128, 64, 61), + (99, 58, 70), (59, 59, 89), (57, 51, 82), (56, 44, 75), + (65, 32, 67), (74, 21, 60), (77, 20, 54), (81, 20, 48), + (84, 21, 29), (77, 21, 31), (70, 21, 34), (61, 24, 44), + (53, 28, 54), (51, 26, 58), (49, 25, 62), (51, 20, 70), + (69, 16, 84), (118, 25, 93), (140, 25, 85), (162, 25, 78), + (181, 24, 71), (201, 23, 64), (203, 22, 58), (205, 22, 53), + (195, 18, 47), (185, 14, 49), (176, 11, 51), (162, 13, 58), + (149, 15, 66), (145, 14, 66), (141, 13, 67), (130, 10, 67), + (119, 11, 71), (103, 15, 78), (92, 12, 72), (81, 9, 67), + (76, 8, 70), (71, 8, 74), (61, 14, 78), (54, 21, 83), + (41, 42, 92), (43, 52, 96), (45, 63, 100), (44, 77, 95), + (44, 91, 90), (51, 95, 84), (58, 100, 78), (73, 100, 69), + (78, 92, 62), (94, 74, 47), (111, 64, 50), (129, 55, 53), + (133, 50, 53), (137, 45, 53), (137, 32, 59), (137, 28, 66), + (127, 38, 74), (113, 35, 75), (100, 33, 77), (93, 33, 75), + (87, 33, 73), (75, 40, 74), (63, 51, 80), (58, 50, 85), + (59, 53, 87), (60, 72, 90), (57, 68, 93), (54, 65, 96), + (52, 60, 98), (51, 56, 101), (48, 52, 106), (40, 40, 103), + (24, 19, 80), (19, 17, 74), (15, 16, 68), (12, 19, 61), + (10, 23, 54), (16, 30, 36), (30, 38, 27), (40, 44, 27), + (44, 49, 29), (72, 52, 25), (77, 53, 29), (83, 55, 34), + (82, 56, 46), (72, 59, 50), (67, 59, 45), (58, 67, 39), + (36, 91, 37), (46, 91, 30), (57, 92, 23), (65, 87, 19), + (73, 83, 16), (81, 85, 10), (99, 78, 17), (118, 65, 24), + (128, 50, 34), (124, 42, 44), (121, 39, 47), (118, 36, 50), + (115, 32, 59), (115, 29, 62), (119, 29, 62), (122, 28, 55), + (145, 17, 44), (155, 14, 39), (165, 12, 35), (168, 11, 35), + (171, 10, 36), (177, 13, 37), (184, 14, 36), (186, 18, 34), + (181, 19, 39), (158, 23, 51), (151, 22, 50), (145, 22, 49), + (123, 21, 53), (104, 14, 62), (81, 17, 74), (63, 17, 79), + (34, 27, 91), (31, 35, 93), (29, 44, 96), (26, 62, 93), + (22, 76, 91), (16, 95, 89), (15, 116, 85), (13, 133, 72), + (15, 136, 68), (28, 133, 63), (36, 127, 57), (44, 121, 52), + (67, 106, 48), (88, 87, 43), (116, 70, 45), (145, 51, 43), + (192, 30, 43), (200, 27, 49), (209, 24, 55), (218, 22, 69), + (222, 16, 72), (221, 18, 69), (225, 21, 67), (223, 28, 71), + (219, 23, 63), (212, 16, 49), (211, 12, 38), (213, 16, 36), + (215, 16, 34), (213, 11, 30), (208, 7, 30), (205, 7, 40), + (200, 8, 61), (194, 9, 62), (188, 11, 63), (167, 14, 69), + (150, 15, 82), (130, 22, 91), (110, 37, 90), (87, 56, 82), + (68, 68, 78), (52, 83, 73), (38, 101, 62), (29, 114, 47), + (22, 107, 40), (25, 97, 33), (29, 90, 30), (38, 84, 29), + (44, 69, 37), (56, 54, 43), (72, 49, 49), (86, 51, 56), + (90, 58, 69), (90, 69, 78), (94, 82, 87), (94, 94, 83), + (82, 105, 84), (69, 111, 87), (69, 111, 99), (81, 104, 97), + (92, 98, 88), (103, 87, 78), (125, 74, 75), (155, 57, 73), + (179, 48, 62), (198, 43, 48), (212, 41, 33), (219, 35, 28), + (218, 33, 20), (208, 33, 16), (194, 31, 10), (179, 29, 8), + (170, 27, 7), (166, 26, 9), (162, 20, 10), (157, 18, 10), + (163, 23, 10), (174, 31, 10), (181, 34, 11), (179, 32, 10), + (179, 30, 14), (179, 32, 20), (178, 29, 32), (166, 28, 43), + (156, 20, 57), (143, 20, 67), (129, 16, 81), (109, 21, 93), + (95, 21, 106), (92, 22, 111), (84, 19, 114), (74, 24, 112), + (60, 36, 111), (65, 50, 111), (70, 59, 112), (77, 65, 113), + (74, 67, 111), (78, 70, 107), (89, 68, 102), (98, 68, 99), + (99, 68, 98), (105, 58, 95), (108, 46, 82), (113, 34, 78) + ), + +// 592 More_Blue +((81, 103, 125), (61, 83, 110), (52, 73, 102), (43, 63, 94), + (41, 62, 91), (40, 62, 88), (39, 62, 88), (38, 62, 88), + (36, 63, 90), (35, 63, 95), (34, 63, 100), (30, 61, 103), + (26, 59, 106), (22, 59, 103), (19, 59, 100), (18, 58, 98), + (17, 57, 96), (15, 49, 84), (16, 49, 79), (17, 49, 74), + (19, 49, 75), (22, 50, 77), (22, 50, 76), (22, 51, 76), + (19, 45, 72), (18, 42, 71), (17, 39, 70), (17, 39, 68), + (18, 40, 66), (18, 40, 65), (19, 40, 65), (23, 45, 63), + (30, 50, 68), (46, 67, 82), (53, 76, 90), (60, 86, 98), + (65, 94, 109), (71, 103, 121), (73, 108, 128), (75, 113, 135), + (79, 124, 159), (79, 127, 160), (80, 130, 162), (85, 134, 165), + (91, 139, 168), (92, 140, 171), (94, 142, 174), (92, 142, 175), + (86, 140, 169), (83, 131, 153), (77, 122, 147), (71, 114, 141), + (58, 100, 130), (45, 86, 119), (40, 79, 112), (35, 72, 105), + (25, 50, 84), (19, 39, 74), (14, 28, 64), (11, 22, 52), + (8, 17, 41), (7, 16, 36), (7, 16, 32), (7, 17, 27), + (9, 17, 26), (17, 28, 36), (28, 40, 48), (39, 53, 60), + (47, 62, 68), (56, 72, 76), (73, 90, 94), (88, 110, 117), + (121, 147, 161), (140, 165, 174), (159, 184, 187), (157, 185, 191), + (155, 187, 196), (149, 183, 196), (144, 180, 196), (133, 174, 197), + (127, 164, 187), (100, 131, 153), (78, 110, 135), (56, 89, 118), + (48, 80, 111), (41, 72, 105), (30, 60, 92), (25, 50, 78), + (21, 39, 52), (19, 38, 48), (18, 38, 44), (18, 39, 45), + (18, 40, 47), (20, 44, 51), (26, 53, 58), (35, 60, 67), + (42, 68, 72), (44, 69, 83), (42, 67, 85), (41, 65, 88), + (41, 63, 86), (41, 62, 84), (39, 56, 79), (34, 49, 70), + (19, 29, 53), (15, 24, 45), (11, 20, 37), (10, 20, 34), + (10, 20, 31), (8, 19, 28), (9, 19, 27), (10, 21, 30), + (12, 23, 32), (17, 29, 35), (18, 30, 36), (20, 31, 37), + (21, 31, 40), (22, 31, 43), (21, 31, 45), (19, 29, 45), + (14, 23, 43), (11, 21, 42), (9, 19, 42), (8, 18, 43), + (7, 18, 44), (5, 16, 47), (4, 15, 51), (3, 17, 55), + (2, 18, 59), (2, 21, 63), (2, 20, 63), (3, 19, 63), + (3, 19, 61), (3, 18, 57), (1, 17, 51), (1, 16, 44), + (2, 13, 33), (1, 14, 32), (1, 15, 32), (1, 16, 34), + (1, 18, 36), (1, 23, 43), (3, 29, 53), (2, 35, 64), + (2, 37, 77), (1, 38, 94), (1, 38, 95), (2, 38, 97), + (2, 37, 97), (3, 36, 96), (4, 34, 97), (5, 33, 93), + (11, 36, 85), (13, 38, 83), (16, 40, 81), (18, 43, 78), + (19, 43, 76), (19, 43, 73), (18, 43, 74), (19, 43, 75), + (18, 42, 73), (15, 31, 64), (13, 28, 61), (12, 26, 59), + (10, 24, 57), (7, 27, 60), (8, 28, 64), (11, 32, 70), + (22, 46, 86), (23, 48, 86), (25, 51, 87), (27, 52, 89), + (28, 51, 85), (33, 54, 87), (34, 54, 91), (36, 53, 85), + (35, 50, 79), (32, 46, 69), (30, 45, 62), (25, 47, 65), + (20, 49, 71), (17, 54, 80), (19, 56, 88), (16, 56, 93), + (9, 50, 109), (6, 52, 117), (4, 55, 126), (9, 59, 142), + (15, 65, 149), (19, 71, 150), (26, 68, 146), (29, 72, 143), + (30, 75, 149), (36, 80, 151), (37, 86, 152), (37, 85, 151), + (38, 85, 144), (32, 77, 138), (28, 69, 130), (23, 61, 124), + (14, 49, 120), (9, 43, 117), (4, 38, 115), (1, 37, 112), + (2, 39, 108), (1, 38, 108), (1, 39, 109), (5, 44, 116), + (8, 53, 124), (16, 65, 132), (25, 77, 142), (30, 85, 148), + (37, 91, 156), (39, 99, 162), (40, 105, 168), (47, 111, 173), + (46, 109, 172), (44, 102, 167), (38, 93, 160), (28, 84, 151), + (23, 74, 141), (17, 64, 131), (12, 52, 118), (7, 39, 107), + (2, 29, 98), (1, 22, 95), (1, 21, 99), (2, 26, 105), + (2, 29, 113), (4, 38, 118), (8, 43, 121), (13, 45, 124), + (18, 53, 127), (22, 57, 127), (24, 62, 123), (27, 63, 113), + (30, 60, 99), (31, 56, 88), (32, 53, 78), (31, 51, 73), + (29, 50, 70), (29, 50, 70), (30, 49, 71), (29, 50, 73), + (31, 55, 77), (35, 60, 81), (42, 66, 88), (50, 74, 95), + (58, 80, 102), (69, 93, 110), (83, 105, 117), (91, 112, 127), + (92, 112, 132), (88, 108, 134), (83, 105, 133), (83, 104, 128) + ), + +// 593 Morning_Glories_at_Night +((43, 62, 147), (47, 68, 152), (44, 68, 146), (41, 68, 140), + (37, 69, 130), (34, 70, 120), (34, 72, 114), (34, 75, 109), + (33, 83, 88), (30, 83, 76), (27, 83, 65), (23, 78, 57), + (19, 74, 49), (15, 71, 45), (12, 68, 41), (11, 68, 39), + (10, 69, 37), (11, 67, 34), (11, 63, 36), (11, 60, 38), + (11, 57, 39), (11, 54, 40), (10, 53, 38), (10, 53, 37), + (7, 56, 28), (6, 60, 26), (6, 65, 25), (13, 71, 31), + (20, 77, 38), (22, 78, 45), (25, 80, 53), (28, 82, 64), + (31, 83, 72), (27, 84, 71), (29, 86, 71), (31, 89, 72), + (34, 88, 78), (38, 88, 85), (40, 86, 89), (42, 84, 94), + (42, 73, 103), (39, 70, 99), (37, 68, 96), (37, 67, 89), + (37, 67, 82), (37, 66, 80), (38, 65, 79), (38, 62, 80), + (40, 58, 82), (39, 50, 86), (39, 47, 87), (39, 44, 88), + (38, 40, 87), (38, 37, 86), (37, 36, 84), (36, 36, 83), + (31, 31, 79), (31, 28, 78), (32, 25, 77), (32, 22, 77), + (33, 19, 78), (33, 19, 78), (33, 19, 78), (32, 19, 78), + (30, 21, 77), (31, 24, 75), (30, 25, 73), (29, 26, 72), + (28, 26, 71), (28, 27, 71), (26, 25, 68), (22, 25, 65), + (16, 28, 57), (14, 31, 51), (12, 35, 45), (10, 39, 40), + (8, 44, 35), (7, 45, 32), (6, 46, 30), (6, 47, 30), + (8, 50, 32), (21, 62, 46), (31, 75, 60), (42, 88, 74), + (45, 93, 81), (49, 99, 88), (55, 104, 101), (58, 105, 114), + (60, 98, 138), (64, 98, 147), (68, 98, 156), (70, 99, 159), + (73, 100, 162), (74, 100, 163), (73, 98, 161), (70, 94, 155), + (64, 84, 150), (53, 66, 138), (51, 64, 136), (49, 62, 135), + (50, 64, 134), (52, 66, 134), (56, 71, 132), (62, 76, 130), + (73, 90, 131), (76, 94, 136), (79, 98, 142), (79, 99, 146), + (80, 100, 151), (79, 102, 160), (78, 102, 167), (78, 104, 171), + (79, 105, 171), (81, 106, 172), (80, 104, 173), (79, 103, 174), + (75, 99, 177), (70, 93, 177), (65, 86, 173), (61, 77, 168), + (55, 64, 152), (51, 59, 144), (48, 54, 136), (46, 52, 132), + (44, 51, 129), (39, 46, 119), (35, 41, 111), (30, 35, 101), + (30, 31, 93), (29, 27, 86), (29, 27, 87), (30, 28, 88), + (32, 31, 88), (33, 34, 88), (31, 35, 88), (31, 35, 87), + (30, 38, 85), (33, 40, 85), (36, 43, 85), (37, 44, 84), + (39, 46, 83), (40, 47, 81), (39, 47, 80), (36, 48, 79), + (33, 46, 78), (29, 43, 87), (29, 43, 89), (30, 44, 92), + (35, 47, 99), (40, 51, 106), (47, 59, 111), (52, 66, 117), + (61, 74, 125), (59, 74, 123), (58, 75, 121), (56, 74, 116), + (53, 73, 109), (51, 74, 99), (49, 75, 89), (47, 73, 83), + (48, 71, 79), (36, 61, 74), (32, 58, 73), (29, 55, 72), + (22, 51, 67), (17, 46, 60), (12, 41, 55), (12, 36, 54), + (13, 29, 59), (13, 28, 63), (13, 27, 67), (15, 28, 77), + (18, 27, 83), (21, 28, 87), (24, 29, 90), (24, 29, 90), + (24, 29, 91), (22, 29, 93), (21, 31, 99), (20, 31, 107), + (21, 31, 115), (23, 32, 125), (24, 33, 131), (24, 36, 138), + (25, 40, 144), (26, 43, 144), (27, 46, 145), (32, 53, 145), + (39, 62, 146), (47, 72, 145), (55, 83, 146), (61, 93, 144), + (64, 99, 147), (66, 102, 150), (67, 102, 152), (68, 102, 155), + (68, 103, 156), (69, 103, 157), (71, 103, 155), (69, 103, 155), + (64, 100, 157), (59, 92, 159), (52, 84, 162), (44, 75, 164), + (37, 67, 164), (32, 59, 160), (30, 56, 152), (30, 54, 145), + (30, 51, 138), (30, 50, 135), (31, 48, 134), (29, 47, 131), + (25, 44, 127), (23, 43, 121), (24, 42, 114), (25, 42, 106), + (28, 41, 102), (33, 44, 102), (41, 51, 103), (46, 56, 107), + (50, 65, 110), (55, 76, 112), (58, 85, 113), (61, 91, 115), + (65, 97, 123), (71, 105, 131), (77, 108, 141), (79, 110, 150), + (81, 114, 157), (80, 117, 159), (77, 114, 158), (73, 111, 156), + (71, 106, 154), (70, 101, 153), (69, 95, 152), (68, 92, 150), + (67, 89, 146), (64, 85, 140), (61, 81, 130), (58, 78, 120), + (57, 75, 112), (57, 73, 105), (58, 74, 99), (57, 75, 95), + (55, 74, 93), (55, 74, 93), (53, 74, 92), (49, 72, 96), + (47, 68, 101), (45, 64, 107), (41, 62, 113), (38, 58, 117), + (36, 55, 123), (36, 55, 128), (36, 56, 135), (39, 58, 141) + ), + +// 594 Moss +((139, 139, 109), (75, 80, 59), (56, 60, 45), (37, 40, 31), + (28, 31, 22), (19, 22, 14), (21, 22, 14), (23, 22, 15), + (52, 37, 25), (70, 52, 32), (88, 68, 39), (101, 82, 51), + (115, 97, 63), (117, 101, 63), (119, 106, 63), (115, 107, 65), + (112, 108, 67), (78, 85, 63), (60, 70, 53), (43, 55, 44), + (31, 40, 35), (19, 25, 26), (15, 20, 21), (12, 16, 16), + (12, 4, 4), (14, 2, 2), (17, 1, 0), (22, 2, 1), + (28, 3, 2), (29, 3, 2), (31, 4, 2), (30, 6, 0), + (29, 9, 2), (40, 23, 17), (46, 33, 24), (53, 44, 31), + (62, 57, 44), (71, 71, 57), (77, 76, 62), (84, 82, 68), + (103, 92, 79), (103, 96, 85), (104, 101, 91), (101, 96, 87), + (98, 92, 84), (90, 91, 79), (83, 90, 75), (64, 83, 67), + (49, 74, 56), (27, 53, 33), (18, 46, 27), (10, 39, 22), + (16, 37, 21), (22, 35, 20), (24, 36, 20), (27, 38, 20), + (30, 37, 27), (28, 35, 22), (26, 33, 18), (21, 25, 13), + (17, 18, 9), (15, 14, 7), (14, 11, 6), (15, 8, 3), + (25, 10, 3), (51, 29, 22), (68, 44, 31), (85, 60, 41), + (97, 68, 47), (109, 76, 54), (126, 93, 72), (136, 108, 91), + (149, 133, 105), (145, 132, 101), (142, 132, 98), (131, 121, 94), + (120, 111, 90), (111, 104, 82), (103, 97, 75), (87, 81, 58), + (72, 64, 48), (54, 43, 37), (53, 35, 33), (52, 28, 29), + (53, 30, 30), (54, 33, 32), (56, 43, 39), (66, 55, 47), + (82, 65, 60), (82, 69, 62), (82, 73, 65), (81, 71, 63), + (81, 70, 62), (79, 68, 54), (71, 60, 47), (65, 55, 39), + (60, 46, 34), (58, 43, 22), (62, 48, 29), (67, 54, 37), + (72, 58, 42), (78, 63, 47), (87, 72, 55), (96, 84, 67), + (127, 124, 109), (137, 140, 126), (147, 157, 144), (142, 163, 151), + (137, 170, 159), (135, 187, 170), (130, 192, 169), (136, 194, 174), + (132, 185, 170), (116, 166, 146), (114, 159, 139), (112, 152, 133), + (115, 139, 122), (114, 127, 116), (105, 113, 107), (84, 99, 97), + (50, 80, 75), (36, 66, 67), (22, 52, 60), (16, 45, 53), + (10, 39, 46), (2, 30, 30), (1, 19, 21), (2, 12, 16), + (4, 9, 13), (17, 21, 14), (22, 26, 18), (28, 31, 22), + (39, 42, 33), (46, 54, 43), (54, 64, 51), (57, 73, 59), + (56, 85, 65), (52, 97, 72), (49, 110, 79), (51, 109, 81), + (53, 109, 84), (55, 110, 86), (64, 112, 87), (68, 123, 94), + (81, 124, 99), (113, 120, 103), (118, 123, 105), (124, 126, 107), + (135, 135, 105), (141, 144, 108), (145, 157, 109), (150, 170, 124), + (165, 194, 146), (165, 197, 143), (165, 201, 140), (163, 198, 137), + (156, 199, 135), (153, 190, 140), (138, 185, 135), (124, 175, 132), + (118, 171, 124), (108, 147, 115), (98, 143, 116), (88, 140, 117), + (79, 142, 114), (90, 133, 112), (92, 120, 97), (85, 107, 86), + (62, 83, 61), (57, 74, 56), (52, 66, 51), (47, 56, 47), + (45, 48, 45), (46, 48, 42), (47, 51, 40), (56, 57, 42), + (65, 63, 45), (78, 62, 45), (86, 62, 43), (94, 58, 37), + (93, 57, 30), (92, 51, 22), (92, 43, 18), (94, 36, 18), + (84, 50, 29), (83, 55, 34), (82, 61, 39), (84, 69, 51), + (83, 79, 61), (81, 90, 71), (75, 97, 74), (67, 97, 72), + (57, 100, 64), (48, 100, 55), (42, 93, 50), (42, 84, 46), + (42, 80, 44), (40, 76, 40), (41, 71, 42), (48, 68, 45), + (57, 67, 48), (58, 62, 47), (56, 55, 43), (52, 50, 38), + (48, 44, 29), (41, 34, 20), (36, 26, 13), (28, 19, 8), + (23, 15, 7), (20, 12, 7), (25, 13, 9), (32, 20, 11), + (41, 32, 19), (53, 43, 28), (67, 51, 39), (79, 62, 44), + (88, 77, 53), (99, 88, 59), (108, 95, 65), (112, 100, 69), + (113, 104, 71), (112, 104, 71), (113, 105, 67), (109, 105, 66), + (104, 103, 64), (95, 95, 54), (82, 85, 40), (69, 71, 30), + (53, 60, 28), (40, 49, 20), (27, 38, 9), (17, 27, 0), + (8, 21, 0), (5, 23, 5), (9, 28, 13), (17, 37, 24), + (28, 46, 34), (39, 60, 46), (53, 74, 61), (74, 94, 71), + (100, 111, 82), (121, 124, 90), (137, 137, 105), (153, 154, 108), + (172, 172, 112), (185, 181, 113), (196, 193, 135), (205, 202, 152), + (219, 216, 166), (224, 222, 172), (232, 233, 186), (231, 228, 191), + (225, 220, 180), (208, 203, 171), (192, 192, 159), (170, 169, 146) + ), + +// 595 Moss2 +((82, 100, 57), (88, 105, 60), (85, 102, 60), (82, 100, 61), + (79, 95, 59), (76, 91, 58), (76, 90, 55), (76, 90, 52), + (74, 86, 45), (71, 82, 44), (69, 79, 44), (67, 76, 44), + (65, 73, 45), (63, 69, 41), (61, 66, 37), (58, 63, 34), + (56, 61, 32), (48, 49, 24), (43, 44, 22), (38, 39, 21), + (32, 33, 19), (27, 27, 18), (24, 24, 16), (22, 21, 15), + (14, 12, 8), (11, 10, 6), (9, 9, 4), (8, 10, 6), + (7, 11, 8), (7, 11, 8), (7, 12, 9), (8, 16, 9), + (11, 19, 9), (17, 30, 11), (20, 33, 11), (23, 37, 12), + (25, 36, 11), (27, 36, 11), (28, 37, 11), (30, 38, 12), + (38, 42, 15), (40, 44, 15), (43, 46, 15), (42, 43, 14), + (41, 41, 14), (40, 40, 14), (40, 39, 15), (40, 38, 17), + (43, 38, 18), (43, 40, 19), (40, 37, 18), (37, 34, 17), + (33, 30, 17), (29, 27, 17), (29, 26, 17), (29, 25, 18), + (30, 26, 24), (31, 29, 26), (33, 32, 28), (38, 38, 32), + (44, 44, 36), (47, 47, 38), (51, 51, 40), (61, 59, 46), + (70, 67, 49), (86, 87, 43), (95, 97, 41), (104, 108, 39), + (109, 113, 39), (114, 118, 40), (120, 122, 47), (125, 128, 53), + (126, 131, 55), (124, 132, 54), (123, 133, 53), (119, 129, 60), + (116, 126, 67), (114, 123, 71), (112, 121, 76), (106, 115, 85), + (100, 110, 93), (98, 109, 92), (96, 107, 90), (94, 106, 89), + (93, 104, 88), (92, 102, 88), (90, 98, 88), (89, 96, 85), + (88, 91, 74), (87, 89, 68), (87, 87, 63), (86, 86, 61), + (86, 86, 60), (87, 85, 58), (87, 85, 56), (85, 82, 53), + (83, 81, 52), (79, 81, 54), (82, 87, 58), (85, 94, 62), + (86, 97, 65), (87, 101, 68), (89, 105, 74), (87, 104, 77), + (79, 95, 77), (74, 90, 73), (70, 86, 69), (68, 84, 67), + (67, 82, 65), (62, 76, 60), (54, 68, 55), (47, 60, 48), + (41, 52, 40), (34, 39, 27), (33, 37, 24), (33, 36, 22), + (32, 34, 18), (31, 33, 16), (31, 34, 17), (32, 37, 18), + (39, 42, 25), (43, 44, 26), (47, 47, 28), (47, 49, 28), + (48, 51, 29), (52, 56, 29), (56, 60, 29), (60, 66, 30), + (67, 72, 33), (75, 85, 40), (77, 87, 41), (80, 90, 43), + (83, 94, 40), (87, 100, 40), (92, 105, 41), (99, 112, 46), + (109, 121, 65), (111, 124, 70), (114, 128, 76), (115, 128, 77), + (116, 129, 78), (117, 130, 77), (116, 130, 79), (116, 128, 83), + (112, 125, 83), (104, 111, 79), (102, 107, 76), (100, 103, 73), + (94, 95, 65), (87, 87, 58), (79, 78, 50), (71, 68, 42), + (55, 49, 30), (52, 45, 26), (50, 41, 23), (43, 36, 21), + (38, 33, 20), (35, 32, 21), (34, 35, 23), (33, 38, 26), + (34, 41, 27), (34, 49, 34), (33, 49, 35), (33, 50, 37), + (34, 52, 37), (32, 51, 38), (31, 48, 35), (31, 47, 36), + (28, 45, 40), (29, 46, 41), (31, 48, 43), (34, 52, 45), + (37, 55, 46), (42, 60, 49), (46, 66, 58), (52, 71, 65), + (61, 81, 73), (72, 92, 80), (80, 102, 82), (86, 109, 83), + (90, 117, 86), (89, 117, 85), (86, 114, 82), (84, 110, 77), + (72, 92, 56), (68, 87, 52), (65, 83, 48), (58, 75, 42), + (49, 66, 36), (42, 62, 30), (37, 57, 25), (32, 52, 21), + (31, 47, 18), (32, 43, 18), (32, 38, 20), (32, 38, 21), + (34, 40, 24), (37, 46, 28), (45, 54, 32), (55, 64, 35), + (67, 75, 38), (78, 84, 43), (89, 93, 51), (98, 104, 59), + (109, 113, 69), (116, 120, 76), (127, 132, 81), (136, 142, 84), + (144, 147, 89), (147, 151, 92), (148, 151, 97), (142, 145, 98), + (137, 139, 98), (131, 135, 93), (124, 127, 87), (115, 120, 80), + (107, 113, 75), (96, 103, 70), (82, 91, 69), (72, 83, 67), + (65, 75, 65), (58, 69, 62), (54, 65, 59), (50, 61, 58), + (43, 55, 59), (36, 50, 61), (34, 45, 61), (30, 39, 57), + (30, 36, 49), (31, 35, 45), (32, 34, 41), (29, 33, 38), + (27, 31, 36), (24, 29, 33), (25, 29, 29), (27, 30, 27), + (30, 33, 27), (34, 38, 30), (37, 43, 35), (39, 48, 40), + (43, 53, 46), (48, 60, 51), (53, 69, 54), (57, 74, 58), + (61, 78, 58), (62, 79, 59), (62, 79, 59), (61, 80, 59), + (64, 85, 58), (67, 90, 60), (73, 93, 58), (76, 96, 58), + (77, 95, 59), (76, 94, 58), (76, 93, 56), (77, 95, 56) + ), + +// 596 Motel_Decor +((236, 95, 36), (229, 55, 19), (232, 39, 48), (236, 24, 77), + (231, 34, 94), (227, 44, 111), (235, 47, 113), (244, 50, 116), + (210, 70, 82), (199, 65, 74), (189, 60, 66), (183, 43, 70), + (177, 27, 75), (168, 18, 83), (160, 10, 92), (156, 11, 89), + (152, 12, 86), (116, 28, 82), (100, 33, 75), (85, 39, 69), + (78, 55, 70), (71, 71, 71), (67, 81, 71), (64, 92, 71), + (69, 122, 79), (70, 130, 72), (71, 138, 66), (82, 122, 58), + (94, 107, 51), (95, 100, 43), (97, 94, 36), (95, 77, 25), + (84, 72, 17), (74, 48, 23), (61, 44, 29), (48, 41, 35), + (59, 37, 45), (70, 33, 56), (80, 39, 61), (90, 45, 67), + (160, 97, 116), (193, 146, 101), (227, 195, 87), (205, 218, 88), + (184, 241, 90), (178, 248, 69), (173, 255, 49), (153, 230, 48), + (128, 215, 40), (126, 165, 36), (128, 147, 33), (131, 129, 30), + (114, 104, 37), (97, 80, 45), (89, 73, 45), (81, 66, 45), + (54, 58, 48), (47, 82, 46), (41, 107, 44), (38, 108, 43), + (35, 110, 43), (34, 116, 44), (33, 123, 45), (20, 97, 46), + (14, 69, 38), (19, 44, 35), (21, 36, 27), (23, 29, 19), + (27, 25, 20), (32, 22, 22), (36, 24, 33), (35, 24, 32), + (60, 36, 55), (70, 50, 60), (81, 65, 66), (93, 70, 73), + (105, 76, 81), (100, 73, 80), (96, 71, 79), (95, 64, 82), + (91, 58, 80), (72, 66, 69), (76, 70, 61), (81, 74, 53), + (75, 77, 51), (70, 81, 50), (58, 77, 46), (54, 72, 44), + (40, 58, 45), (51, 46, 51), (63, 35, 58), (75, 37, 62), + (87, 39, 67), (113, 41, 79), (147, 46, 90), (168, 67, 98), + (175, 94, 103), (175, 111, 102), (156, 108, 93), (138, 105, 84), + (124, 93, 75), (111, 82, 67), (89, 70, 58), (72, 59, 41), + (66, 30, 24), (86, 26, 18), (106, 23, 13), (111, 20, 15), + (117, 17, 17), (127, 13, 20), (136, 13, 23), (129, 14, 32), + (132, 17, 49), (151, 29, 92), (164, 36, 104), (178, 43, 116), + (205, 59, 121), (226, 102, 105), (251, 154, 95), (255, 187, 92), + (255, 246, 36), (243, 221, 52), (232, 196, 69), (227, 185, 63), + (222, 174, 58), (199, 137, 67), (168, 102, 77), (151, 90, 80), + (144, 76, 82), (139, 58, 94), (130, 54, 95), (121, 51, 96), + (117, 45, 89), (107, 38, 86), (81, 43, 79), (64, 50, 70), + (46, 41, 71), (45, 35, 63), (44, 30, 55), (46, 22, 57), + (49, 14, 59), (50, 9, 54), (55, 10, 43), (63, 13, 43), + (74, 19, 40), (85, 40, 36), (91, 42, 40), (98, 44, 45), + (108, 40, 48), (116, 58, 43), (121, 67, 54), (125, 76, 70), + (106, 113, 56), (98, 119, 55), (90, 125, 54), (72, 122, 48), + (56, 112, 41), (39, 95, 34), (27, 75, 33), (27, 53, 32), + (25, 35, 34), (23, 35, 39), (23, 40, 36), (23, 46, 33), + (19, 58, 38), (19, 70, 36), (28, 77, 39), (36, 86, 44), + (76, 89, 63), (85, 89, 68), (95, 90, 74), (103, 98, 84), + (123, 100, 89), (147, 98, 92), (110, 74, 85), (90, 59, 67), + (138, 70, 67), (133, 49, 48), (132, 44, 30), (175, 74, 36), + (200, 89, 27), (213, 90, 18), (214, 92, 19), (205, 87, 13), + (177, 53, 10), (170, 51, 14), (164, 50, 18), (159, 58, 30), + (148, 72, 43), (146, 86, 44), (144, 116, 55), (143, 144, 65), + (149, 158, 50), (151, 183, 44), (160, 200, 50), (169, 201, 50), + (172, 219, 46), (200, 216, 33), (205, 178, 27), (182, 154, 30), + (182, 126, 24), (167, 80, 13), (136, 44, 13), (113, 22, 18), + (91, 4, 18), (79, 0, 20), (71, 0, 19), (60, 2, 18), + (49, 0, 24), (43, 1, 30), (40, 7, 35), (30, 7, 39), + (24, 4, 39), (25, 7, 39), (18, 3, 35), (15, 1, 35), + (24, 0, 36), (22, 0, 33), (15, 0, 34), (19, 0, 43), + (18, 4, 44), (8, 18, 39), (3, 32, 39), (8, 34, 40), + (12, 39, 35), (19, 44, 29), (33, 35, 28), (41, 23, 30), + (53, 14, 22), (66, 10, 19), (72, 3, 24), (74, 0, 23), + (71, 3, 28), (74, 9, 32), (79, 10, 33), (80, 15, 29), + (86, 22, 12), (105, 24, 9), (111, 43, 14), (100, 55, 5), + (101, 53, 9), (90, 64, 22), (71, 75, 34), (64, 70, 45), + (55, 60, 49), (55, 66, 53), (55, 69, 54), (51, 69, 51), + (61, 90, 33), (92, 103, 20), (111, 101, 23), (127, 125, 13), + (175, 139, 13), (213, 125, 33), (230, 118, 34), (236, 116, 29) + ), + +// 597 Muddy +((80, 63, 50), (89, 69, 51), (90, 69, 51), (92, 70, 52), + (92, 68, 50), (92, 67, 48), (89, 67, 48), (86, 67, 49), + (84, 69, 53), (86, 71, 54), (89, 74, 56), (90, 76, 59), + (91, 79, 62), (91, 80, 64), (91, 81, 66), (91, 81, 67), + (91, 82, 68), (87, 82, 69), (86, 81, 68), (86, 81, 67), + (86, 80, 65), (86, 80, 63), (86, 80, 63), (86, 80, 64), + (86, 81, 65), (85, 81, 65), (85, 81, 66), (83, 79, 64), + (81, 77, 63), (80, 76, 61), (80, 76, 59), (77, 72, 55), + (75, 68, 51), (69, 63, 45), (65, 61, 45), (62, 59, 45), + (59, 58, 47), (56, 58, 50), (55, 59, 51), (55, 60, 53), + (58, 65, 59), (62, 68, 60), (67, 71, 62), (72, 74, 63), + (78, 78, 64), (82, 80, 65), (86, 82, 67), (94, 86, 70), + (102, 91, 72), (111, 100, 79), (113, 102, 80), (115, 104, 82), + (114, 102, 80), (114, 101, 78), (112, 100, 77), (111, 99, 76), + (108, 95, 72), (106, 91, 68), (104, 88, 65), (99, 83, 63), + (95, 79, 61), (91, 76, 58), (88, 73, 56), (78, 66, 51), + (67, 58, 44), (46, 45, 34), (39, 39, 29), (32, 33, 24), + (29, 30, 22), (27, 28, 20), (23, 24, 16), (20, 20, 13), + (17, 14, 9), (16, 14, 9), (16, 15, 9), (19, 20, 14), + (22, 26, 20), (26, 30, 24), (30, 35, 28), (42, 46, 38), + (55, 58, 51), (82, 83, 77), (94, 93, 87), (106, 104, 97), + (110, 107, 100), (114, 111, 104), (118, 117, 109), (121, 120, 114), + (124, 125, 116), (125, 127, 118), (126, 129, 120), (126, 129, 118), + (127, 129, 117), (129, 129, 115), (129, 126, 111), (126, 121, 105), + (120, 113, 99), (101, 90, 75), (88, 78, 63), (75, 66, 52), + (69, 61, 47), (63, 56, 42), (53, 48, 33), (46, 40, 26), + (40, 31, 17), (40, 29, 15), (41, 27, 13), (41, 26, 12), + (41, 26, 11), (43, 26, 11), (44, 28, 13), (45, 32, 16), + (46, 36, 20), (53, 43, 26), (55, 43, 27), (57, 44, 28), + (62, 47, 30), (63, 48, 31), (66, 49, 31), (68, 49, 30), + (67, 52, 31), (66, 54, 32), (66, 57, 33), (66, 57, 33), + (67, 58, 34), (68, 59, 36), (67, 59, 38), (66, 59, 38), + (64, 56, 37), (57, 51, 34), (54, 49, 32), (51, 48, 31), + (46, 48, 30), (42, 47, 28), (42, 48, 28), (42, 49, 30), + (45, 53, 36), (48, 55, 39), (51, 58, 43), (52, 59, 44), + (53, 60, 46), (55, 61, 47), (55, 62, 48), (56, 64, 47), + (57, 64, 47), (60, 66, 48), (61, 66, 48), (62, 66, 49), + (66, 66, 50), (70, 66, 50), (74, 65, 51), (77, 63, 50), + (79, 63, 46), (79, 62, 45), (79, 62, 45), (78, 63, 44), + (77, 63, 45), (77, 62, 45), (78, 63, 45), (81, 63, 46), + (84, 65, 48), (89, 68, 53), (90, 69, 54), (91, 70, 55), + (92, 74, 58), (91, 77, 61), (90, 80, 65), (88, 82, 68), + (86, 85, 72), (84, 84, 72), (83, 84, 73), (81, 83, 74), + (78, 81, 73), (76, 79, 72), (74, 77, 69), (73, 74, 66), + (72, 71, 63), (69, 68, 59), (67, 65, 56), (64, 61, 51), + (60, 55, 46), (55, 50, 43), (50, 47, 40), (45, 43, 37), + (42, 39, 32), (43, 38, 31), (44, 38, 30), (46, 40, 30), + (50, 42, 31), (53, 45, 32), (58, 49, 36), (64, 55, 41), + (70, 64, 52), (78, 74, 62), (89, 86, 75), (102, 97, 88), + (113, 109, 100), (124, 120, 111), (133, 129, 120), (139, 136, 126), + (143, 140, 129), (149, 146, 134), (155, 151, 140), (162, 159, 146), + (169, 166, 153), (175, 172, 158), (179, 176, 161), (182, 177, 162), + (181, 175, 159), (174, 167, 151), (164, 157, 141), (153, 146, 129), + (144, 136, 118), (137, 128, 109), (132, 123, 102), (129, 120, 96), + (131, 119, 93), (136, 122, 92), (140, 124, 93), (141, 125, 94), + (138, 122, 93), (135, 120, 90), (131, 116, 88), (125, 112, 85), + (119, 108, 82), (112, 103, 80), (110, 100, 75), (108, 98, 74), + (109, 98, 73), (107, 94, 73), (104, 92, 72), (100, 89, 72), + (94, 86, 71), (87, 81, 68), (77, 75, 65), (67, 67, 57), + (57, 59, 49), (51, 52, 41), (46, 45, 35), (40, 40, 30), + (36, 35, 27), (32, 32, 25), (29, 30, 24), (28, 29, 26), + (29, 32, 27), (32, 34, 29), (38, 37, 29), (44, 40, 29), + (44, 41, 30), (45, 41, 31), (46, 41, 32), (49, 42, 33), + (52, 43, 36), (56, 47, 40), (58, 52, 45), (67, 56, 48) + ), + +// 598 Muddy_2 +((99, 79, 67), (82, 66, 53), (91, 76, 64), (100, 86, 75), + (109, 95, 84), (118, 104, 94), (119, 104, 95), (121, 105, 97), + (119, 108, 102), (112, 104, 99), (106, 100, 97), (96, 90, 87), + (87, 81, 78), (79, 73, 70), (72, 65, 62), (68, 60, 56), + (65, 56, 50), (61, 50, 42), (60, 48, 42), (60, 47, 42), + (62, 50, 45), (64, 53, 49), (64, 54, 50), (64, 55, 52), + (71, 55, 50), (75, 53, 44), (79, 51, 39), (77, 48, 36), + (76, 46, 33), (76, 45, 32), (76, 45, 32), (69, 45, 35), + (63, 45, 38), (56, 46, 43), (54, 45, 43), (52, 45, 43), + (52, 45, 41), (53, 45, 40), (53, 44, 39), (53, 43, 38), + (57, 40, 28), (58, 36, 25), (60, 32, 22), (59, 29, 19), + (58, 26, 16), (56, 25, 15), (54, 24, 15), (51, 23, 15), + (46, 21, 13), (37, 23, 15), (34, 22, 15), (32, 21, 16), + (32, 23, 17), (32, 25, 19), (33, 25, 19), (35, 25, 19), + (42, 32, 26), (46, 34, 29), (51, 37, 32), (51, 38, 34), + (52, 40, 37), (50, 39, 36), (49, 38, 35), (44, 35, 31), + (41, 31, 27), (30, 22, 18), (33, 23, 19), (36, 24, 20), + (39, 27, 22), (42, 30, 24), (53, 38, 32), (70, 46, 39), + (95, 62, 47), (111, 70, 50), (128, 78, 54), (140, 86, 55), + (152, 94, 57), (157, 97, 59), (162, 101, 61), (162, 101, 59), + (160, 103, 63), (134, 93, 68), (116, 85, 66), (99, 78, 65), + (93, 75, 64), (88, 72, 63), (79, 66, 58), (75, 60, 52), + (79, 57, 47), (85, 60, 49), (91, 64, 52), (91, 65, 53), + (92, 66, 54), (93, 67, 55), (91, 71, 58), (87, 69, 55), + (80, 61, 48), (70, 48, 34), (69, 43, 29), (69, 39, 24), + (69, 40, 25), (69, 41, 26), (73, 45, 35), (80, 53, 41), + (90, 74, 64), (95, 80, 71), (101, 86, 79), (100, 85, 80), + (99, 85, 81), (96, 82, 78), (90, 77, 73), (83, 68, 67), + (77, 62, 59), (69, 52, 45), (69, 51, 43), (70, 50, 41), + (73, 49, 34), (78, 46, 27), (84, 42, 22), (90, 40, 20), + (93, 43, 22), (94, 47, 31), (96, 52, 40), (96, 57, 45), + (97, 62, 50), (105, 73, 56), (114, 84, 72), (119, 96, 87), + (130, 111, 97), (132, 117, 108), (132, 118, 107), (132, 120, 107), + (126, 114, 100), (115, 98, 90), (104, 87, 79), (90, 77, 70), + (69, 60, 58), (57, 52, 51), (46, 45, 45), (43, 42, 41), + (40, 39, 37), (33, 34, 31), (27, 28, 25), (24, 23, 21), + (23, 21, 17), (18, 16, 11), (18, 15, 10), (19, 14, 10), + (25, 13, 7), (30, 14, 6), (34, 17, 8), (47, 22, 8), + (70, 35, 10), (74, 37, 14), (79, 40, 18), (89, 45, 23), + (100, 52, 23), (108, 53, 20), (110, 55, 26), (114, 57, 31), + (125, 55, 30), (124, 69, 40), (121, 64, 43), (119, 59, 47), + (116, 63, 46), (104, 67, 47), (94, 62, 49), (87, 58, 48), + (83, 61, 51), (82, 61, 51), (82, 61, 51), (82, 60, 50), + (85, 59, 49), (90, 60, 51), (93, 64, 52), (101, 69, 55), + (117, 73, 61), (122, 75, 66), (119, 80, 67), (118, 80, 67), + (112, 72, 62), (98, 65, 55), (83, 57, 47), (70, 48, 34), + (57, 36, 24), (56, 36, 22), (55, 36, 21), (56, 37, 25), + (60, 43, 34), (66, 51, 40), (73, 56, 46), (79, 60, 51), + (83, 63, 52), (84, 61, 52), (83, 60, 52), (80, 56, 49), + (73, 54, 46), (67, 50, 48), (64, 48, 49), (63, 50, 47), + (64, 51, 49), (69, 54, 52), (78, 62, 57), (86, 67, 61), + (93, 74, 64), (100, 77, 68), (99, 76, 70), (94, 76, 68), + (89, 73, 65), (78, 64, 59), (62, 54, 52), (53, 47, 44), + (47, 40, 37), (40, 34, 31), (37, 29, 24), (40, 26, 21), + (44, 26, 23), (48, 28, 24), (54, 30, 26), (56, 32, 29), + (58, 36, 31), (61, 38, 32), (63, 40, 33), (60, 40, 31), + (56, 38, 29), (52, 38, 27), (50, 36, 27), (48, 34, 27), + (47, 35, 27), (51, 38, 31), (56, 40, 36), (61, 45, 40), + (67, 50, 44), (69, 51, 46), (70, 52, 46), (71, 52, 45), + (71, 49, 40), (73, 44, 34), (72, 38, 30), (72, 35, 24), + (68, 30, 16), (61, 23, 12), (54, 19, 9), (43, 17, 7), + (35, 14, 7), (27, 11, 6), (26, 11, 8), (30, 14, 10), + (32, 18, 13), (41, 25, 19), (55, 35, 27), (66, 47, 38), + (85, 64, 55), (98, 75, 66), (87, 64, 55), (91, 68, 56) + ), + +// 599 Muted_Rainbow +((192, 123, 83), (209, 149, 116), (184, 129, 102), (160, 110, 88), + (137, 98, 81), (114, 86, 74), (103, 80, 67), (93, 74, 60), + (83, 79, 44), (80, 75, 36), (78, 72, 28), (75, 70, 32), + (73, 69, 36), (65, 61, 42), (58, 53, 48), (55, 54, 51), + (53, 55, 54), (53, 65, 53), (69, 78, 55), (85, 92, 57), + (94, 93, 48), (104, 95, 40), (105, 94, 39), (106, 93, 39), + (104, 74, 39), (104, 70, 45), (105, 66, 52), (105, 70, 55), + (105, 75, 59), (104, 78, 59), (104, 82, 59), (91, 77, 53), + (70, 74, 46), (46, 75, 50), (38, 76, 51), (31, 78, 52), + (29, 79, 53), (27, 81, 55), (26, 84, 55), (25, 87, 56), + (33, 93, 53), (41, 98, 53), (50, 103, 54), (68, 107, 51), + (87, 111, 49), (95, 105, 50), (104, 100, 51), (121, 97, 52), + (140, 97, 56), (165, 100, 48), (178, 115, 51), (191, 130, 55), + (207, 154, 70), (223, 178, 85), (227, 187, 101), (232, 197, 117), + (248, 226, 113), (232, 202, 110), (217, 179, 107), (185, 145, 85), + (154, 111, 64), (140, 89, 60), (127, 68, 56), (102, 43, 44), + (83, 30, 38), (76, 20, 35), (89, 32, 38), (102, 44, 41), + (108, 51, 40), (114, 58, 40), (129, 74, 43), (156, 101, 47), + (199, 157, 43), (212, 167, 47), (225, 177, 51), (209, 178, 54), + (194, 179, 57), (189, 172, 52), (184, 165, 48), (175, 152, 46), + (153, 136, 38), (150, 109, 21), (139, 93, 22), (129, 78, 23), + (119, 68, 23), (109, 59, 24), (87, 52, 23), (70, 46, 27), + (44, 31, 23), (41, 37, 25), (39, 44, 28), (37, 44, 29), + (35, 44, 30), (43, 47, 36), (53, 50, 46), (59, 53, 56), + (73, 47, 58), (94, 44, 59), (98, 42, 53), (102, 41, 48), + (102, 40, 44), (103, 39, 41), (110, 44, 37), (120, 55, 35), + (154, 69, 30), (167, 85, 27), (181, 102, 24), (189, 109, 25), + (198, 116, 27), (209, 120, 35), (218, 127, 39), (230, 131, 46), + (234, 123, 49), (247, 114, 48), (242, 112, 45), (238, 111, 42), + (233, 123, 32), (222, 122, 23), (199, 115, 21), (178, 114, 32), + (125, 85, 41), (96, 75, 48), (67, 66, 55), (57, 60, 52), + (47, 55, 50), (39, 51, 47), (40, 54, 41), (54, 61, 32), + (87, 60, 29), (149, 66, 28), (161, 62, 30), (173, 59, 32), + (188, 56, 35), (186, 55, 42), (182, 51, 47), (179, 60, 54), + (172, 82, 48), (181, 101, 45), (191, 120, 42), (194, 122, 41), + (198, 125, 40), (201, 136, 37), (197, 145, 30), (182, 140, 33), + (166, 129, 27), (112, 101, 27), (100, 89, 26), (89, 78, 25), + (76, 61, 19), (72, 44, 24), (78, 30, 29), (95, 27, 25), + (144, 46, 35), (161, 51, 36), (178, 57, 37), (207, 85, 39), + (219, 119, 47), (233, 132, 69), (245, 148, 95), (240, 167, 113), + (236, 162, 125), (227, 151, 119), (226, 150, 111), (226, 149, 103), + (214, 142, 75), (203, 135, 56), (198, 132, 40), (190, 126, 33), + (190, 105, 29), (194, 99, 28), (198, 94, 27), (214, 79, 42), + (218, 69, 44), (203, 69, 49), (181, 60, 75), (164, 55, 89), + (127, 65, 92), (84, 65, 93), (76, 60, 90), (68, 65, 80), + (57, 65, 64), (66, 57, 53), (82, 57, 47), (94, 63, 49), + (121, 61, 56), (128, 64, 57), (135, 67, 58), (141, 74, 69), + (143, 79, 72), (147, 84, 76), (164, 99, 85), (177, 113, 98), + (177, 111, 109), (180, 115, 121), (186, 118, 134), (187, 97, 150), + (163, 78, 153), (153, 82, 136), (166, 83, 143), (163, 85, 134), + (170, 100, 113), (177, 118, 113), (164, 130, 103), (158, 135, 87), + (143, 136, 78), (113, 138, 70), (103, 137, 54), (113, 134, 42), + (120, 133, 40), (128, 139, 44), (141, 146, 51), (148, 155, 50), + (139, 146, 56), (123, 131, 63), (101, 137, 56), (74, 125, 56), + (55, 103, 53), (41, 100, 44), (33, 100, 45), (28, 109, 47), + (35, 122, 56), (48, 124, 70), (57, 130, 85), (70, 142, 98), + (86, 148, 93), (82, 145, 81), (69, 139, 77), (64, 130, 69), + (58, 119, 55), (52, 107, 51), (51, 100, 57), (69, 95, 64), + (102, 99, 69), (118, 117, 69), (138, 125, 71), (164, 128, 77), + (170, 127, 80), (169, 118, 83), (173, 112, 84), (180, 95, 82), + (179, 87, 86), (182, 95, 85), (193, 87, 72), (204, 86, 62), + (217, 90, 55), (217, 81, 50), (206, 80, 47), (199, 76, 35), + (174, 62, 31), (143, 59, 40), (129, 64, 44), (119, 60, 39), + (120, 62, 40), (128, 64, 48), (158, 91, 81), (193, 131, 100) + ), + +// 600 Mystery +((80, 11, 0), (64, 6, 0), (58, 4, 0), (52, 3, 0), + (48, 2, 0), (44, 1, 0), (42, 0, 0), (41, 0, 0), + (36, 0, 0), (32, 0, 0), (29, 0, 0), (25, 0, 0), + (22, 0, 0), (20, 0, 0), (18, 0, 0), (18, 0, 0), + (18, 1, 1), (11, 3, 8), (13, 5, 12), (16, 8, 16), + (25, 9, 15), (34, 10, 14), (39, 11, 14), (45, 13, 15), + (74, 24, 19), (92, 29, 18), (111, 34, 17), (125, 42, 23), + (140, 51, 29), (143, 58, 37), (146, 66, 45), (150, 78, 61), + (136, 85, 77), (107, 110, 130), (102, 120, 145), (98, 130, 161), + (87, 122, 153), (77, 114, 145), (73, 109, 141), (70, 105, 137), + (80, 87, 108), (88, 73, 83), (97, 60, 58), (102, 46, 37), + (107, 32, 16), (110, 28, 10), (113, 24, 4), (116, 24, 4), + (118, 24, 3), (124, 24, 2), (126, 24, 1), (129, 24, 0), + (128, 24, 0), (128, 24, 0), (126, 24, 0), (125, 24, 0), + (109, 21, 1), (98, 18, 1), (88, 15, 1), (78, 12, 1), + (68, 10, 1), (62, 9, 1), (57, 8, 1), (46, 6, 1), + (37, 3, 1), (29, 2, 1), (34, 3, 0), (39, 5, 0), + (44, 6, 0), (50, 8, 1), (65, 14, 3), (87, 21, 4), + (115, 40, 20), (117, 49, 31), (120, 59, 42), (119, 59, 42), + (118, 59, 42), (111, 59, 45), (104, 60, 49), (87, 61, 57), + (67, 61, 65), (44, 48, 56), (40, 36, 45), (36, 25, 34), + (36, 22, 30), (36, 19, 27), (37, 18, 25), (44, 15, 20), + (60, 10, 7), (66, 8, 3), (72, 7, 0), (74, 7, 0), + (77, 8, 0), (83, 10, 0), (91, 13, 0), (101, 16, 0), + (113, 20, 0), (134, 28, 0), (144, 30, 0), (155, 33, 0), + (160, 34, 0), (165, 36, 0), (176, 41, 0), (186, 45, 0), + (200, 55, 7), (201, 60, 14), (203, 66, 21), (206, 67, 21), + (209, 69, 21), (216, 70, 19), (220, 69, 17), (213, 70, 21), + (203, 68, 23), (182, 56, 17), (177, 52, 13), (173, 48, 10), + (160, 40, 6), (143, 32, 3), (124, 25, 2), (108, 18, 0), + (82, 10, 1), (73, 7, 1), (64, 5, 1), (60, 4, 1), + (57, 3, 1), (50, 4, 3), (41, 6, 9), (34, 10, 17), + (28, 14, 27), (19, 34, 57), (17, 40, 67), (15, 47, 78), + (9, 53, 85), (5, 52, 88), (3, 48, 82), (3, 47, 79), + (15, 50, 78), (21, 42, 64), (28, 35, 50), (28, 31, 43), + (29, 28, 37), (27, 28, 38), (28, 32, 45), (40, 42, 52), + (55, 50, 59), (92, 66, 65), (95, 67, 65), (98, 68, 66), + (115, 75, 66), (127, 74, 62), (150, 78, 57), (168, 75, 45), + (182, 62, 22), (180, 58, 18), (178, 54, 14), (170, 53, 15), + (150, 49, 17), (130, 46, 19), (110, 41, 20), (90, 34, 19), + (75, 30, 19), (37, 23, 21), (29, 20, 20), (22, 17, 19), + (9, 10, 15), (5, 6, 9), (5, 2, 3), (8, 1, 2), + (24, 3, 2), (30, 4, 2), (36, 5, 2), (52, 10, 2), + (72, 14, 1), (95, 20, 0), (120, 27, 1), (145, 34, 2), + (169, 41, 2), (188, 48, 3), (206, 54, 2), (222, 59, 1), + (235, 63, 2), (246, 67, 3), (250, 69, 4), (250, 71, 5), + (246, 73, 7), (244, 73, 8), (242, 74, 10), (238, 71, 10), + (230, 69, 10), (224, 65, 8), (219, 63, 7), (215, 63, 9), + (215, 63, 9), (215, 62, 7), (217, 61, 5), (218, 58, 1), + (218, 58, 0), (220, 58, 0), (218, 58, 1), (215, 57, 1), + (209, 53, 1), (200, 50, 0), (191, 46, 0), (180, 43, 0), + (171, 39, 0), (163, 36, 0), (157, 33, 0), (153, 30, 0), + (150, 30, 0), (148, 31, 0), (146, 31, 0), (144, 31, 0), + (141, 30, 0), (134, 28, 0), (124, 25, 0), (112, 22, 0), + (102, 19, 0), (93, 16, 0), (85, 14, 1), (79, 12, 1), + (76, 11, 0), (77, 10, 1), (83, 12, 2), (92, 15, 3), + (102, 20, 4), (113, 23, 4), (122, 26, 3), (131, 28, 3), + (136, 30, 3), (137, 29, 4), (134, 27, 4), (127, 25, 2), + (119, 21, 1), (111, 18, 0), (101, 15, 0), (92, 11, 0), + (85, 9, 0), (80, 8, 0), (78, 9, 0), (78, 10, 0), + (79, 10, 0), (80, 8, 0), (83, 8, 0), (86, 8, 0), + (89, 8, 1), (92, 11, 1), (95, 12, 1), (99, 13, 1), + (102, 13, 0), (105, 13, 1), (105, 15, 1), (104, 16, 1), + (102, 17, 1), (99, 17, 0), (94, 15, 0), (87, 14, 0) + ), + +// 601 Neon +((21, 52, 121), (20, 40, 136), (19, 35, 145), (19, 31, 155), + (20, 28, 163), (21, 26, 172), (23, 25, 175), (25, 24, 178), + (37, 20, 187), (44, 18, 190), (52, 17, 193), (61, 15, 192), + (70, 14, 192), (80, 12, 189), (90, 11, 187), (95, 10, 185), + (101, 10, 183), (122, 7, 173), (131, 8, 166), (140, 9, 160), + (147, 11, 153), (155, 14, 147), (158, 15, 144), (162, 16, 142), + (176, 20, 134), (182, 21, 132), (188, 22, 131), (193, 22, 133), + (198, 23, 135), (200, 23, 137), (202, 23, 139), (205, 22, 145), + (208, 21, 151), (209, 18, 164), (208, 17, 170), (208, 16, 176), + (206, 16, 179), (204, 16, 183), (202, 16, 183), (201, 17, 184), + (193, 20, 178), (189, 22, 170), (186, 24, 163), (183, 27, 153), + (180, 30, 144), (179, 31, 139), (178, 33, 135), (176, 36, 129), + (173, 38, 123), (167, 44, 110), (164, 49, 103), (161, 55, 96), + (156, 63, 91), (152, 71, 86), (149, 74, 84), (146, 78, 83), + (136, 94, 78), (132, 100, 72), (128, 106, 67), (126, 112, 60), + (124, 118, 53), (123, 119, 50), (123, 121, 47), (123, 121, 42), + (123, 120, 37), (124, 107, 27), (128, 98, 26), (132, 90, 25), + (134, 85, 26), (136, 81, 28), (142, 71, 33), (147, 62, 39), + (153, 46, 56), (154, 41, 67), (155, 37, 79), (152, 36, 93), + (149, 36, 107), (146, 38, 114), (143, 40, 121), (136, 47, 134), + (128, 56, 146), (114, 81, 165), (108, 94, 169), (102, 108, 173), + (99, 114, 173), (97, 120, 173), (94, 132, 170), (95, 140, 164), + (106, 146, 148), (116, 143, 141), (127, 140, 134), (132, 136, 131), + (137, 133, 128), (146, 123, 123), (158, 114, 120), (170, 100, 117), + (181, 85, 116), (197, 55, 121), (196, 41, 128), (195, 27, 135), + (191, 22, 139), (188, 18, 143), (178, 11, 152), (166, 8, 160), + (135, 15, 174), (119, 25, 179), (103, 36, 185), (95, 42, 187), + (87, 49, 190), (73, 63, 194), (58, 78, 197), (45, 94, 199), + (34, 111, 201), (20, 145, 202), (19, 153, 201), (19, 161, 201), + (23, 175, 198), (32, 187, 191), (46, 195, 185), (63, 202, 176), + (97, 205, 158), (115, 200, 147), (134, 196, 137), (142, 193, 129), + (150, 190, 122), (168, 183, 109), (184, 179, 96), (198, 174, 85), + (209, 171, 75), (220, 166, 62), (218, 164, 60), (217, 163, 58), + (209, 158, 56), (197, 156, 56), (182, 154, 60), (165, 154, 66), + (129, 153, 83), (112, 148, 91), (96, 144, 100), (88, 140, 104), + (80, 137, 108), (64, 127, 116), (50, 118, 124), (37, 108, 132), + (26, 97, 139), (19, 75, 150), (20, 69, 151), (21, 64, 153), + (26, 54, 154), (33, 45, 155), (42, 37, 156), (50, 30, 157), + (66, 17, 161), (70, 14, 162), (75, 12, 164), (83, 8, 167), + (90, 5, 170), (95, 4, 175), (98, 4, 179), (97, 4, 185), + (94, 5, 191), (81, 10, 203), (77, 12, 206), (73, 14, 209), + (65, 20, 215), (56, 28, 221), (47, 36, 227), (38, 45, 231), + (20, 59, 238), (16, 61, 238), (13, 64, 239), (7, 69, 239), + (4, 74, 238), (1, 77, 234), (0, 79, 230), (0, 79, 224), + (1, 76, 216), (3, 71, 208), (5, 64, 199), (8, 58, 189), + (10, 52, 180), (14, 46, 170), (18, 41, 160), (24, 36, 150), + (38, 26, 131), (41, 25, 126), (45, 24, 122), (53, 22, 112), + (60, 22, 102), (67, 24, 92), (74, 26, 83), (81, 28, 74), + (89, 30, 66), (96, 33, 58), (103, 36, 52), (109, 38, 45), + (115, 42, 38), (120, 46, 31), (125, 50, 25), (130, 54, 19), + (136, 58, 15), (141, 61, 12), (147, 63, 10), (153, 66, 9), + (158, 70, 8), (162, 72, 10), (165, 73, 14), (167, 73, 20), + (169, 73, 29), (170, 72, 38), (169, 72, 49), (164, 72, 60), + (157, 75, 71), (148, 80, 82), (139, 84, 92), (129, 90, 105), + (119, 95, 115), (113, 100, 124), (105, 105, 131), (98, 110, 136), + (91, 116, 138), (85, 118, 140), (82, 118, 141), (82, 117, 141), + (85, 114, 140), (91, 108, 138), (97, 101, 136), (102, 95, 133), + (104, 87, 131), (107, 76, 130), (109, 66, 131), (109, 57, 134), + (107, 48, 136), (103, 41, 139), (99, 39, 140), (91, 40, 141), + (82, 43, 142), (73, 48, 143), (64, 55, 144), (54, 62, 144), + (45, 69, 144), (37, 77, 142), (30, 84, 139), (25, 91, 134), + (21, 96, 130), (19, 101, 126), (18, 104, 122), (18, 105, 118), + (19, 104, 113), (20, 100, 109), (21, 94, 106), (22, 87, 104), + (22, 80, 104), (22, 72, 106), (22, 65, 110), (22, 58, 114) + ), + +// 602 Neon_Purple +((192, 57, 254), (205, 58, 253), (198, 59, 246), (192, 60, 240), + (183, 62, 231), (175, 64, 223), (172, 65, 218), (170, 66, 214), + (164, 76, 196), (161, 87, 191), (158, 99, 187), (159, 114, 185), + (160, 130, 183), (160, 139, 184), (161, 149, 186), (161, 150, 184), + (162, 152, 183), (155, 143, 197), (143, 139, 202), (132, 135, 208), + (128, 134, 213), (124, 133, 218), (120, 129, 216), (117, 125, 214), + (106, 98, 213), (94, 85, 211), (83, 72, 209), (76, 62, 211), + (69, 53, 214), (68, 50, 212), (67, 48, 210), (65, 47, 207), + (75, 50, 201), (89, 58, 182), (86, 54, 173), (83, 51, 164), + (77, 45, 155), (71, 39, 147), (68, 36, 144), (65, 33, 141), + (47, 25, 126), (36, 21, 118), (25, 18, 110), (19, 18, 105), + (14, 19, 101), (14, 21, 103), (14, 23, 105), (12, 25, 116), + (13, 32, 128), (10, 38, 165), (12, 36, 177), (15, 35, 190), + (18, 29, 202), (21, 24, 214), (25, 24, 218), (30, 24, 223), + (51, 30, 241), (64, 32, 245), (77, 34, 250), (93, 36, 251), + (110, 39, 253), (118, 40, 253), (126, 41, 253), (138, 43, 253), + (142, 44, 253), (142, 44, 253), (136, 42, 248), (131, 40, 243), + (127, 39, 238), (123, 39, 234), (117, 37, 222), (111, 37, 209), + (99, 40, 188), (93, 41, 182), (88, 43, 177), (82, 41, 176), + (77, 39, 175), (75, 38, 174), (74, 38, 174), (72, 36, 173), + (73, 37, 174), (75, 42, 185), (78, 41, 195), (82, 41, 206), + (82, 40, 212), (82, 40, 219), (85, 37, 230), (89, 35, 239), + (104, 36, 251), (115, 38, 252), (126, 41, 253), (130, 42, 253), + (134, 43, 253), (142, 45, 253), (150, 46, 253), (153, 46, 253), + (153, 46, 252), (146, 45, 246), (137, 44, 240), (129, 43, 235), + (123, 42, 234), (118, 41, 233), (108, 42, 232), (101, 40, 232), + (86, 36, 235), (81, 35, 233), (77, 34, 232), (73, 32, 231), + (70, 30, 231), (65, 32, 231), (62, 32, 234), (62, 32, 236), + (63, 32, 242), (81, 35, 250), (84, 34, 251), (88, 34, 252), + (88, 34, 252), (90, 35, 254), (89, 35, 253), (89, 35, 252), + (90, 38, 245), (91, 40, 238), (93, 43, 232), (95, 46, 230), + (97, 49, 228), (103, 55, 224), (106, 60, 222), (110, 65, 225), + (114, 66, 226), (117, 64, 224), (115, 64, 223), (114, 64, 223), + (114, 64, 222), (111, 61, 218), (105, 63, 219), (100, 60, 220), + (96, 50, 223), (91, 45, 224), (87, 41, 225), (84, 38, 223), + (82, 35, 222), (68, 31, 219), (55, 27, 213), (43, 25, 207), + (33, 22, 200), (19, 19, 191), (20, 19, 188), (21, 19, 186), + (20, 20, 180), (21, 21, 173), (25, 29, 165), (28, 34, 157), + (32, 41, 146), (33, 42, 145), (34, 43, 144), (33, 36, 139), + (35, 32, 135), (42, 36, 132), (51, 41, 131), (63, 48, 130), + (76, 58, 132), (93, 71, 146), (97, 72, 150), (101, 73, 154), + (106, 76, 163), (110, 79, 172), (114, 81, 179), (122, 83, 189), + (142, 87, 209), (149, 87, 212), (156, 88, 215), (167, 89, 223), + (177, 90, 231), (180, 95, 232), (178, 97, 232), (176, 97, 232), + (171, 95, 228), (164, 93, 222), (161, 91, 214), (163, 88, 209), + (161, 89, 203), (155, 92, 197), (149, 96, 193), (141, 94, 185), + (114, 87, 177), (105, 83, 177), (96, 80, 177), (82, 71, 180), + (68, 62, 185), (57, 59, 195), (50, 55, 200), (45, 55, 206), + (38, 46, 212), (32, 47, 216), (26, 45, 221), (21, 48, 225), + (16, 48, 233), (8, 50, 240), (9, 52, 244), (19, 56, 245), + (32, 63, 243), (42, 69, 243), (51, 73, 240), (59, 71, 237), + (66, 74, 237), (74, 71, 238), (87, 82, 240), (107, 89, 241), + (124, 100, 243), (142, 110, 245), (161, 116, 244), (174, 117, 244), + (185, 113, 244), (191, 110, 245), (196, 103, 245), (196, 96, 246), + (192, 94, 249), (189, 89, 250), (184, 81, 252), (178, 73, 253), + (173, 67, 253), (166, 60, 253), (162, 52, 252), (157, 48, 252), + (149, 46, 252), (145, 45, 252), (141, 44, 252), (137, 42, 253), + (133, 41, 253), (124, 39, 252), (117, 37, 247), (114, 35, 240), + (108, 33, 230), (107, 33, 217), (101, 32, 204), (98, 31, 192), + (94, 29, 186), (87, 29, 181), (82, 28, 177), (69, 26, 169), + (55, 25, 166), (42, 22, 160), (32, 21, 156), (23, 19, 156), + (25, 21, 164), (35, 23, 176), (47, 26, 184), (60, 30, 197), + (73, 32, 208), (83, 35, 217), (88, 35, 222), (99, 38, 230), + (114, 41, 240), (132, 46, 245), (153, 51, 249), (173, 54, 252) + ), + +// 603 Night_Flower +((39, 60, 72), (63, 72, 122), (43, 81, 93), (23, 90, 64), + (15, 77, 51), (8, 64, 39), (6, 58, 31), (4, 53, 24), + (4, 49, 21), (9, 48, 24), (14, 47, 28), (29, 39, 54), + (44, 31, 81), (61, 28, 106), (78, 26, 132), (88, 21, 149), + (99, 16, 166), (117, 18, 196), (113, 16, 191), (110, 14, 187), + (99, 11, 178), (89, 8, 169), (85, 6, 161), (81, 4, 154), + (76, 2, 148), (78, 1, 147), (80, 0, 146), (81, 1, 149), + (83, 3, 153), (84, 2, 155), (85, 2, 157), (90, 1, 162), + (96, 4, 166), (115, 10, 185), (120, 16, 188), (126, 22, 191), + (121, 23, 192), (116, 25, 194), (112, 23, 186), (108, 22, 179), + (73, 12, 140), (59, 12, 108), (45, 12, 76), (39, 16, 51), + (33, 21, 26), (29, 23, 21), (26, 25, 16), (21, 28, 14), + (19, 40, 21), (21, 67, 49), (27, 73, 67), (33, 79, 85), + (49, 67, 107), (66, 56, 130), (72, 48, 138), (79, 41, 147), + (93, 6, 164), (86, 7, 145), (79, 8, 126), (61, 10, 99), + (44, 12, 72), (36, 14, 57), (28, 17, 43), (19, 27, 21), + (11, 31, 15), (3, 38, 12), (3, 36, 11), (3, 35, 10), + (3, 33, 9), (3, 32, 9), (3, 26, 8), (4, 22, 8), + (4, 15, 5), (6, 14, 11), (9, 13, 17), (20, 9, 41), + (31, 5, 65), (40, 9, 78), (50, 13, 92), (70, 18, 128), + (93, 16, 164), (129, 34, 207), (132, 33, 211), (136, 32, 215), + (133, 29, 213), (130, 27, 211), (115, 21, 192), (100, 17, 172), + (71, 11, 136), (58, 18, 106), (45, 26, 76), (39, 25, 68), + (34, 24, 61), (26, 31, 45), (19, 42, 25), (14, 42, 22), + (17, 39, 30), (3, 48, 25), (3, 48, 25), (3, 49, 25), + (2, 48, 21), (1, 47, 18), (1, 49, 11), (1, 48, 8), + (0, 43, 1), (0, 38, 1), (0, 34, 2), (0, 32, 2), + (0, 30, 2), (0, 27, 4), (0, 23, 6), (2, 21, 7), + (3, 24, 10), (6, 37, 19), (10, 40, 23), (14, 44, 27), + (25, 54, 34), (34, 62, 45), (35, 73, 57), (34, 82, 66), + (32, 89, 72), (25, 85, 66), (18, 82, 60), (16, 79, 52), + (15, 76, 44), (10, 67, 32), (12, 60, 22), (10, 54, 11), + (6, 49, 4), (3, 45, 4), (3, 44, 4), (3, 43, 5), + (2, 41, 6), (1, 38, 7), (1, 37, 10), (1, 38, 13), + (1, 40, 13), (1, 44, 10), (2, 48, 8), (1, 49, 8), + (1, 51, 8), (2, 52, 9), (4, 53, 15), (6, 61, 22), + (8, 69, 34), (21, 84, 61), (20, 86, 61), (19, 88, 61), + (24, 80, 61), (33, 69, 58), (28, 58, 44), (28, 45, 34), + (36, 20, 44), (38, 16, 55), (41, 12, 67), (56, 15, 84), + (71, 8, 110), (79, 0, 137), (83, 2, 146), (85, 14, 135), + (79, 27, 116), (48, 45, 68), (39, 49, 54), (30, 54, 40), + (23, 55, 28), (15, 53, 18), (8, 47, 13), (7, 40, 14), + (16, 28, 16), (18, 26, 16), (20, 25, 17), (27, 24, 19), + (36, 26, 22), (43, 31, 29), (46, 28, 50), (50, 20, 69), + (54, 23, 71), (54, 26, 73), (53, 23, 71), (47, 17, 64), + (42, 23, 49), (44, 26, 51), (47, 16, 69), (51, 12, 82), + (79, 3, 144), (87, 4, 153), (95, 6, 162), (105, 11, 178), + (116, 19, 192), (127, 27, 205), (132, 35, 214), (132, 41, 216), + (130, 42, 214), (122, 35, 203), (110, 26, 185), (95, 23, 170), + (80, 12, 151), (68, 3, 133), (58, 3, 128), (54, 2, 127), + (59, 1, 123), (54, 3, 122), (42, 8, 106), (46, 13, 82), + (46, 13, 71), (32, 18, 52), (32, 28, 32), (44, 34, 31), + (52, 41, 42), (60, 59, 55), (61, 75, 66), (55, 85, 73), + (54, 90, 76), (41, 89, 70), (25, 85, 57), (16, 72, 44), + (10, 56, 31), (8, 44, 21), (9, 36, 16), (13, 30, 16), + (16, 25, 17), (19, 22, 17), (25, 22, 18), (28, 22, 20), + (25, 23, 18), (26, 21, 16), (25, 18, 15), (19, 18, 12), + (15, 18, 10), (13, 16, 10), (9, 18, 10), (7, 20, 10), + (6, 20, 10), (6, 21, 10), (7, 21, 10), (6, 23, 9), + (7, 25, 10), (7, 25, 9), (6, 27, 9), (6, 31, 11), + (7, 32, 13), (6, 35, 13), (5, 39, 13), (5, 44, 10), + (8, 53, 7), (11, 56, 8), (18, 52, 12), (31, 56, 19), + (39, 58, 26), (48, 52, 41), (54, 49, 57), (49, 42, 58), + (41, 37, 51), (33, 41, 46), (49, 32, 85), (62, 31, 103) + ), + +// 604 Night_Reeds +((69, 72, 71), (44, 58, 44), (26, 43, 27), (9, 28, 10), + (15, 32, 10), (21, 37, 11), (27, 39, 13), (34, 42, 15), + (63, 59, 17), (77, 72, 16), (91, 85, 15), (106, 97, 25), + (122, 109, 35), (129, 111, 48), (137, 114, 61), (135, 114, 63), + (133, 114, 65), (113, 105, 62), (97, 92, 61), (82, 79, 60), + (68, 61, 53), (54, 44, 46), (47, 38, 40), (41, 32, 35), + (19, 20, 12), (14, 16, 8), (10, 12, 4), (8, 11, 3), + (7, 10, 3), (6, 10, 3), (6, 11, 4), (5, 13, 5), + (5, 14, 5), (5, 17, 4), (5, 21, 4), (5, 25, 4), + (7, 28, 4), (10, 32, 5), (12, 33, 5), (14, 35, 5), + (16, 42, 7), (18, 47, 8), (21, 52, 9), (24, 54, 10), + (28, 57, 12), (29, 57, 13), (30, 57, 14), (29, 55, 13), + (28, 54, 13), (26, 52, 14), (24, 51, 12), (22, 51, 11), + (20, 50, 10), (18, 50, 9), (18, 50, 9), (19, 50, 9), + (22, 56, 10), (25, 60, 10), (29, 65, 11), (33, 69, 13), + (37, 74, 16), (41, 76, 17), (45, 79, 18), (55, 84, 21), + (68, 87, 26), (81, 87, 49), (81, 86, 57), (82, 86, 65), + (81, 84, 62), (81, 82, 60), (77, 78, 57), (69, 72, 56), + (54, 63, 59), (43, 60, 47), (32, 57, 36), (27, 56, 25), + (22, 55, 15), (22, 55, 14), (22, 55, 14), (23, 55, 14), + (24, 55, 15), (26, 55, 15), (29, 57, 16), (33, 60, 18), + (35, 62, 20), (38, 65, 22), (48, 74, 25), (65, 85, 39), + (97, 110, 69), (101, 112, 72), (106, 115, 75), (107, 116, 74), + (109, 117, 74), (108, 121, 76), (107, 122, 78), (105, 117, 79), + (92, 104, 69), (59, 82, 37), (47, 75, 26), (36, 68, 15), + (33, 63, 14), (31, 59, 13), (26, 53, 11), (21, 47, 10), + (14, 35, 8), (12, 30, 8), (11, 26, 8), (10, 25, 8), + (9, 25, 9), (9, 26, 10), (11, 28, 10), (15, 33, 9), + (19, 35, 9), (26, 39, 8), (29, 38, 7), (33, 38, 7), + (41, 43, 6), (46, 46, 3), (45, 49, 4), (40, 46, 4), + (36, 30, 5), (32, 28, 4), (29, 26, 4), (24, 24, 3), + (20, 23, 3), (13, 17, 2), (7, 11, 2), (4, 6, 3), + (2, 3, 3), (0, 1, 2), (0, 1, 2), (0, 2, 3), + (0, 3, 4), (0, 4, 5), (0, 6, 6), (2, 6, 7), + (10, 12, 14), (16, 16, 21), (23, 21, 28), (26, 23, 31), + (29, 26, 34), (36, 33, 35), (40, 40, 35), (42, 46, 38), + (46, 51, 38), (52, 58, 41), (51, 59, 39), (50, 60, 37), + (45, 60, 33), (40, 59, 28), (34, 56, 25), (31, 51, 22), + (23, 38, 20), (21, 35, 20), (19, 32, 20), (14, 27, 19), + (11, 22, 18), (7, 18, 17), (5, 14, 16), (4, 12, 15), + (4, 11, 15), (7, 14, 13), (8, 15, 14), (9, 17, 15), + (14, 20, 17), (22, 24, 19), (27, 24, 20), (32, 24, 19), + (31, 23, 18), (31, 23, 18), (32, 24, 19), (30, 19, 19), + (29, 16, 19), (25, 13, 17), (18, 9, 14), (12, 7, 12), + (6, 5, 9), (3, 3, 8), (1, 3, 7), (1, 3, 5), + (0, 4, 4), (0, 5, 3), (0, 7, 2), (0, 9, 1), + (2, 15, 1), (3, 18, 1), (5, 21, 2), (6, 28, 2), + (8, 33, 3), (9, 38, 5), (12, 40, 6), (14, 42, 8), + (15, 45, 9), (16, 45, 9), (15, 44, 10), (13, 41, 10), + (12, 36, 11), (10, 31, 10), (9, 26, 8), (8, 21, 7), + (7, 16, 6), (8, 13, 6), (9, 11, 5), (10, 10, 5), + (11, 11, 5), (12, 11, 6), (15, 14, 8), (21, 18, 10), + (30, 20, 15), (36, 21, 18), (35, 22, 23), (34, 24, 24), + (34, 31, 25), (39, 38, 28), (48, 45, 29), (53, 51, 33), + (58, 59, 33), (60, 68, 31), (58, 76, 30), (60, 81, 27), + (58, 81, 25), (58, 79, 20), (60, 74, 16), (59, 71, 15), + (60, 70, 13), (64, 69, 13), (69, 67, 10), (78, 61, 7), + (85, 55, 6), (87, 53, 5), (91, 55, 12), (91, 60, 16), + (91, 65, 19), (90, 63, 19), (84, 64, 16), (78, 62, 19), + (66, 60, 22), (53, 62, 25), (41, 61, 24), (33, 64, 20), + (30, 63, 17), (28, 61, 15), (27, 58, 15), (25, 54, 14), + (23, 49, 14), (20, 44, 15), (19, 40, 17), (25, 41, 25), + (36, 43, 38), (48, 47, 52), (61, 56, 68), (73, 70, 78), + (68, 65, 71), (65, 63, 69), (61, 60, 64), (56, 54, 62) + ), + +// 605 No_Clue +((115, 83, 92), (119, 81, 103), (122, 82, 107), (125, 83, 112), + (125, 83, 111), (125, 83, 110), (127, 84, 108), (129, 86, 107), + (148, 97, 87), (158, 103, 77), (168, 110, 67), (173, 116, 62), + (179, 123, 57), (181, 132, 51), (183, 141, 45), (183, 144, 42), + (184, 148, 39), (179, 166, 30), (178, 168, 29), (177, 171, 28), + (173, 164, 35), (169, 157, 42), (166, 151, 46), (164, 146, 51), + (152, 122, 73), (144, 113, 81), (137, 105, 89), (132, 97, 97), + (127, 90, 105), (125, 85, 108), (123, 81, 112), (122, 72, 121), + (124, 60, 123), (124, 35, 130), (122, 32, 133), (120, 29, 136), + (117, 34, 134), (115, 40, 132), (115, 44, 130), (116, 49, 129), + (131, 66, 108), (140, 71, 95), (149, 77, 83), (153, 87, 76), + (158, 97, 70), (157, 102, 69), (157, 108, 68), (155, 120, 67), + (154, 131, 66), (156, 142, 66), (163, 141, 63), (170, 141, 61), + (176, 142, 57), (182, 143, 53), (183, 145, 52), (184, 147, 51), + (182, 153, 48), (179, 151, 50), (176, 150, 52), (173, 148, 53), + (170, 147, 54), (169, 146, 54), (169, 145, 54), (169, 144, 55), + (168, 143, 55), (167, 140, 57), (162, 131, 65), (157, 123, 73), + (153, 118, 77), (149, 114, 82), (142, 101, 91), (134, 91, 103), + (118, 77, 127), (110, 69, 136), (102, 61, 145), (96, 50, 155), + (90, 39, 166), (88, 34, 170), (86, 29, 175), (84, 19, 182), + (82, 14, 187), (82, 8, 190), (84, 9, 188), (86, 11, 187), + (87, 11, 187), (88, 11, 187), (91, 9, 188), (92, 8, 189), + (95, 5, 193), (97, 4, 192), (99, 4, 192), (101, 4, 190), + (103, 5, 189), (103, 5, 188), (103, 8, 185), (100, 10, 180), + (95, 13, 172), (83, 16, 156), (78, 21, 149), (74, 27, 142), + (75, 30, 139), (76, 33, 137), (80, 41, 132), (87, 48, 127), + (102, 53, 113), (109, 50, 95), (117, 48, 77), (118, 47, 72), + (120, 47, 68), (126, 45, 63), (131, 43, 63), (135, 44, 67), + (142, 45, 75), (151, 41, 97), (153, 37, 98), (156, 34, 99), + (157, 26, 105), (156, 19, 109), (154, 17, 111), (151, 21, 109), + (148, 40, 106), (147, 52, 103), (147, 64, 100), (148, 70, 97), + (150, 76, 95), (153, 85, 89), (153, 93, 86), (153, 102, 83), + (152, 111, 82), (154, 123, 72), (154, 125, 70), (155, 127, 69), + (158, 130, 68), (160, 126, 68), (161, 119, 70), (162, 111, 72), + (165, 88, 69), (163, 79, 67), (161, 70, 65), (157, 66, 65), + (154, 62, 65), (145, 57, 66), (133, 51, 67), (122, 46, 71), + (114, 41, 69), (106, 28, 68), (105, 28, 68), (105, 29, 69), + (103, 30, 70), (100, 35, 72), (93, 37, 80), (80, 42, 91), + (63, 50, 101), (63, 50, 103), (63, 50, 105), (68, 53, 112), + (75, 58, 115), (85, 62, 119), (92, 67, 124), (99, 76, 128), + (103, 83, 129), (123, 98, 116), (127, 102, 109), (131, 106, 102), + (139, 116, 94), (147, 125, 85), (154, 130, 78), (160, 135, 74), + (164, 140, 70), (165, 140, 68), (166, 141, 67), (167, 141, 65), + (167, 142, 64), (164, 141, 66), (158, 139, 68), (149, 136, 75), + (142, 128, 82), (136, 119, 90), (131, 108, 97), (126, 96, 111), + (119, 87, 123), (113, 79, 131), (106, 72, 137), (93, 64, 146), + (71, 47, 165), (67, 44, 168), (64, 42, 172), (60, 32, 178), + (55, 24, 178), (55, 19, 175), (56, 14, 169), (53, 14, 161), + (49, 13, 153), (47, 14, 144), (45, 18, 136), (45, 19, 131), + (45, 21, 123), (42, 21, 116), (45, 22, 114), (44, 26, 112), + (40, 31, 108), (39, 35, 104), (39, 45, 99), (40, 54, 99), + (41, 68, 97), (39, 79, 92), (42, 84, 95), (47, 86, 101), + (52, 86, 106), (58, 83, 110), (65, 81, 112), (69, 79, 112), + (72, 84, 108), (71, 89, 99), (71, 94, 83), (68, 91, 71), + (74, 86, 63), (75, 81, 62), (84, 64, 69), (88, 53, 80), + (93, 41, 89), (95, 34, 97), (92, 31, 103), (84, 31, 108), + (78, 32, 109), (68, 36, 111), (66, 36, 116), (64, 35, 118), + (64, 33, 119), (65, 32, 121), (65, 35, 124), (69, 36, 129), + (76, 36, 131), (78, 35, 130), (80, 37, 132), (85, 38, 130), + (90, 41, 125), (97, 44, 116), (106, 51, 104), (115, 59, 90), + (128, 62, 73), (137, 65, 62), (142, 69, 57), (145, 68, 59), + (146, 68, 62), (146, 68, 64), (144, 71, 64), (146, 86, 61), + (147, 94, 56), (146, 102, 55), (143, 108, 56), (137, 110, 60), + (131, 106, 65), (125, 98, 70), (114, 87, 79), (114, 85, 88) + ), + +// 606 Nonsense +((141, 166, 81), (171, 172, 77), (179, 186, 75), (188, 200, 74), + (195, 206, 75), (202, 213, 77), (198, 208, 80), (195, 203, 83), + (160, 167, 95), (145, 149, 113), (131, 131, 132), (115, 111, 146), + (100, 92, 160), (81, 75, 165), (63, 59, 170), (56, 52, 168), + (50, 46, 166), (41, 37, 151), (46, 32, 142), (51, 28, 133), + (61, 32, 130), (71, 37, 128), (78, 42, 131), (86, 48, 135), + (118, 78, 160), (134, 95, 173), (150, 113, 187), (163, 137, 191), + (176, 161, 196), (181, 171, 192), (186, 181, 188), (198, 191, 178), + (197, 191, 160), (174, 170, 122), (164, 159, 102), (155, 148, 83), + (141, 127, 73), (127, 107, 64), (114, 94, 62), (101, 82, 61), + (59, 45, 85), (49, 43, 103), (39, 41, 122), (37, 46, 134), + (36, 52, 147), (39, 54, 150), (43, 56, 154), (48, 54, 155), + (56, 55, 152), (66, 60, 145), (74, 56, 142), (83, 52, 140), + (79, 46, 135), (76, 41, 130), (72, 38, 131), (68, 36, 133), + (51, 34, 152), (44, 46, 160), (38, 59, 169), (46, 75, 164), + (54, 92, 160), (58, 98, 156), (63, 104, 153), (68, 117, 145), + (64, 119, 137), (74, 110, 130), (87, 104, 122), (101, 99, 115), + (105, 90, 111), (109, 81, 108), (104, 64, 98), (102, 49, 90), + (109, 34, 65), (107, 25, 58), (106, 16, 52), (96, 22, 55), + (86, 28, 59), (83, 33, 62), (80, 38, 66), (68, 44, 69), + (55, 40, 75), (23, 36, 81), (19, 42, 83), (15, 49, 85), + (14, 48, 82), (14, 48, 79), (14, 49, 65), (10, 38, 49), + (14, 29, 27), (17, 30, 23), (20, 31, 20), (19, 29, 20), + (18, 27, 20), (20, 24, 27), (19, 28, 29), (26, 31, 27), + (32, 32, 26), (38, 27, 38), (41, 27, 43), (44, 28, 48), + (49, 26, 48), (54, 25, 48), (64, 25, 50), (72, 25, 63), + (72, 34, 97), (71, 33, 105), (70, 33, 113), (67, 31, 120), + (65, 30, 128), (59, 33, 147), (45, 35, 172), (37, 46, 191), + (34, 59, 194), (37, 77, 203), (39, 80, 209), (42, 83, 216), + (54, 92, 234), (72, 112, 235), (80, 128, 233), (91, 143, 227), + (111, 171, 228), (124, 178, 223), (137, 186, 218), (137, 183, 214), + (137, 180, 210), (129, 170, 203), (109, 164, 207), (101, 164, 206), + (97, 162, 202), (103, 154, 185), (102, 151, 183), (102, 149, 181), + (95, 149, 167), (92, 146, 152), (84, 129, 136), (87, 121, 113), + (91, 110, 77), (82, 107, 61), (74, 105, 45), (69, 99, 39), + (64, 93, 33), (63, 81, 26), (65, 70, 24), (71, 66, 25), + (72, 68, 34), (73, 73, 62), (76, 71, 70), (79, 69, 79), + (81, 64, 84), (86, 57, 82), (84, 51, 80), (87, 53, 76), + (92, 54, 71), (97, 55, 65), (103, 56, 59), (111, 60, 45), + (120, 65, 35), (131, 67, 28), (133, 67, 31), (136, 58, 31), + (139, 51, 28), (137, 43, 36), (135, 42, 43), (133, 42, 50), + (126, 41, 62), (121, 42, 68), (116, 45, 72), (117, 56, 72), + (117, 76, 78), (112, 80, 78), (107, 85, 78), (94, 88, 74), + (88, 93, 65), (86, 95, 66), (100, 105, 64), (107, 118, 64), + (111, 128, 67), (115, 140, 65), (113, 148, 69), (127, 162, 82), + (142, 183, 96), (159, 198, 113), (173, 214, 133), (175, 224, 145), + (171, 222, 169), (170, 214, 166), (170, 206, 164), (173, 185, 158), + (183, 176, 154), (192, 172, 146), (197, 179, 142), (206, 181, 127), + (204, 173, 103), (210, 169, 83), (215, 176, 62), (216, 193, 52), + (224, 211, 46), (216, 220, 45), (205, 209, 49), (188, 198, 57), + (160, 186, 70), (146, 172, 85), (134, 169, 98), (127, 158, 110), + (129, 153, 119), (122, 154, 134), (129, 152, 158), (135, 156, 170), + (142, 154, 174), (152, 144, 166), (154, 143, 153), (155, 137, 151), + (149, 136, 145), (138, 132, 142), (120, 119, 130), (102, 115, 120), + (90, 114, 120), (82, 127, 120), (84, 146, 127), (89, 161, 130), + (100, 181, 142), (116, 197, 157), (128, 211, 167), (143, 221, 175), + (156, 224, 174), (174, 223, 174), (193, 217, 174), (206, 208, 164), + (215, 202, 150), (212, 195, 129), (215, 189, 107), (223, 183, 96), + (234, 171, 84), (245, 163, 73), (237, 155, 65), (228, 146, 54), + (211, 136, 46), (193, 123, 47), (182, 110, 50), (163, 101, 60), + (148, 99, 77), (128, 94, 86), (107, 90, 90), (89, 87, 90), + (72, 81, 85), (63, 88, 85), (59, 100, 91), (58, 111, 93), + (58, 122, 94), (56, 123, 85), (59, 118, 70), (67, 116, 61), + (76, 116, 57), (91, 122, 66), (104, 140, 73), (122, 156, 79) + ), + +// 607 Oak_Tree +((90, 69, 31), (105, 83, 43), (108, 86, 46), (112, 90, 50), + (111, 94, 55), (110, 98, 61), (109, 100, 62), (109, 102, 63), + (120, 108, 62), (126, 113, 64), (132, 118, 67), (141, 125, 77), + (151, 132, 87), (150, 133, 95), (150, 134, 103), (149, 134, 103), + (149, 134, 104), (133, 114, 104), (129, 115, 96), (126, 117, 88), + (126, 115, 82), (126, 114, 76), (127, 116, 70), (129, 119, 64), + (143, 100, 34), (143, 100, 22), (143, 101, 11), (141, 94, 13), + (139, 88, 16), (133, 88, 16), (127, 89, 16), (110, 83, 21), + (95, 66, 24), (60, 39, 19), (57, 33, 13), (54, 28, 8), + (67, 32, 5), (80, 36, 3), (87, 42, 9), (95, 49, 15), + (120, 70, 40), (116, 77, 56), (113, 84, 72), (116, 95, 79), + (119, 106, 86), (124, 111, 90), (129, 116, 95), (150, 135, 103), + (163, 151, 118), (202, 185, 153), (209, 194, 150), (216, 204, 147), + (222, 199, 129), (228, 194, 112), (224, 193, 102), (220, 192, 93), + (212, 178, 109), (207, 181, 118), (202, 185, 128), (195, 180, 127), + (188, 175, 126), (178, 165, 120), (168, 155, 114), (143, 131, 95), + (120, 110, 77), (81, 73, 59), (65, 60, 47), (50, 47, 36), + (45, 42, 32), (40, 38, 29), (32, 29, 22), (32, 28, 14), + (49, 41, 14), (60, 47, 15), (71, 53, 16), (84, 62, 23), + (97, 72, 30), (100, 73, 33), (104, 74, 36), (90, 67, 36), + (86, 71, 32), (83, 59, 31), (84, 57, 29), (86, 56, 27), + (90, 55, 29), (95, 55, 31), (104, 55, 31), (111, 61, 24), + (105, 65, 34), (99, 69, 34), (93, 73, 35), (89, 73, 39), + (85, 73, 43), (84, 73, 52), (87, 76, 58), (87, 76, 59), + (88, 73, 60), (88, 68, 59), (77, 59, 52), (66, 51, 46), + (60, 46, 41), (55, 42, 36), (42, 32, 30), (34, 25, 25), + (42, 28, 24), (54, 36, 27), (66, 44, 31), (72, 47, 31), + (78, 51, 31), (88, 59, 31), (89, 66, 33), (89, 71, 31), + (90, 73, 30), (79, 70, 35), (77, 69, 36), (75, 69, 38), + (69, 63, 39), (67, 58, 42), (67, 59, 43), (67, 60, 41), + (88, 66, 36), (102, 80, 39), (117, 94, 42), (128, 100, 41), + (140, 107, 41), (153, 118, 42), (157, 115, 46), (157, 120, 46), + (151, 118, 48), (116, 94, 66), (112, 95, 72), (109, 97, 78), + (108, 103, 96), (116, 117, 119), (132, 133, 134), (146, 139, 137), + (169, 159, 137), (172, 154, 121), (176, 149, 106), (175, 147, 102), + (174, 146, 98), (175, 142, 99), (181, 154, 99), (179, 156, 99), + (176, 151, 98), (160, 141, 75), (151, 131, 67), (142, 121, 59), + (128, 101, 39), (104, 79, 29), (85, 63, 26), (74, 55, 24), + (67, 49, 29), (70, 52, 33), (74, 55, 37), (88, 61, 46), + (106, 67, 50), (124, 78, 53), (136, 83, 57), (145, 89, 56), + (148, 98, 54), (139, 86, 56), (136, 83, 55), (134, 80, 54), + (128, 73, 55), (120, 62, 52), (112, 55, 50), (101, 53, 51), + (81, 60, 53), (76, 60, 53), (71, 61, 54), (67, 62, 54), + (66, 63, 55), (63, 63, 49), (60, 58, 41), (59, 52, 36), + (52, 46, 32), (47, 39, 26), (51, 38, 21), (56, 41, 27), + (61, 45, 34), (73, 57, 43), (96, 73, 57), (120, 92, 71), + (143, 120, 91), (148, 123, 91), (153, 127, 92), (149, 132, 90), + (141, 124, 89), (129, 115, 82), (117, 102, 73), (105, 88, 65), + (95, 79, 58), (91, 70, 51), (87, 62, 45), (91, 59, 38), + (105, 61, 27), (113, 65, 23), (118, 72, 25), (124, 75, 20), + (119, 77, 23), (107, 78, 31), (96, 75, 37), (91, 73, 48), + (91, 71, 56), (95, 74, 56), (103, 86, 57), (110, 91, 60), + (114, 91, 56), (114, 97, 54), (111, 99, 55), (106, 92, 53), + (101, 85, 53), (96, 84, 57), (90, 81, 58), (88, 76, 58), + (85, 77, 59), (83, 78, 59), (87, 80, 62), (94, 85, 66), + (96, 88, 69), (95, 92, 74), (95, 95, 75), (88, 91, 71), + (83, 86, 64), (80, 81, 56), (74, 71, 45), (74, 61, 36), + (79, 54, 35), (81, 51, 36), (85, 53, 36), (96, 57, 37), + (106, 66, 39), (115, 80, 44), (128, 93, 48), (145, 104, 54), + (154, 117, 65), (156, 124, 72), (157, 123, 76), (155, 122, 81), + (147, 118, 77), (134, 106, 72), (119, 95, 67), (104, 81, 56), + (87, 66, 46), (74, 57, 36), (66, 50, 26), (62, 48, 21), + (62, 47, 18), (66, 44, 13), (73, 48, 16), (77, 45, 22), + (77, 44, 20), (81, 49, 19), (83, 52, 26), (84, 58, 31) + ), + +// 608 Ocean_Mist +((117, 195, 196), (113, 177, 175), (105, 167, 161), (98, 157, 148), + (88, 144, 130), (79, 131, 113), (75, 124, 104), (72, 117, 96), + (54, 94, 67), (45, 88, 56), (37, 82, 45), (36, 73, 41), + (35, 65, 38), (30, 56, 36), (26, 47, 35), (22, 45, 32), + (18, 43, 29), (17, 32, 32), (17, 28, 37), (18, 24, 43), + (16, 21, 43), (15, 18, 44), (15, 17, 45), (16, 16, 46), + (19, 21, 59), (22, 27, 65), (26, 33, 71), (34, 44, 75), + (42, 56, 80), (47, 64, 80), (52, 72, 81), (59, 84, 84), + (64, 94, 88), (72, 112, 99), (79, 125, 104), (87, 138, 110), + (91, 148, 118), (96, 158, 126), (96, 159, 129), (97, 160, 132), + (93, 156, 135), (90, 160, 137), (88, 164, 140), (87, 160, 136), + (86, 157, 133), (83, 151, 127), (80, 146, 121), (71, 130, 114), + (62, 116, 103), (48, 94, 87), (46, 89, 83), (44, 85, 80), + (42, 81, 75), (41, 77, 71), (39, 75, 67), (38, 74, 64), + (42, 80, 61), (47, 86, 61), (53, 92, 62), (53, 93, 60), + (53, 94, 59), (52, 93, 60), (52, 93, 62), (54, 90, 66), + (56, 85, 73), (49, 70, 76), (45, 61, 76), (42, 52, 77), + (41, 47, 79), (40, 43, 81), (37, 37, 84), (37, 30, 83), + (34, 21, 73), (32, 24, 70), (30, 28, 68), (31, 38, 67), + (33, 48, 67), (35, 53, 67), (38, 59, 68), (45, 69, 68), + (51, 82, 70), (60, 107, 73), (64, 109, 74), (69, 112, 76), + (71, 110, 78), (73, 108, 81), (74, 104, 86), (68, 98, 86), + (50, 75, 77), (45, 62, 76), (40, 49, 75), (37, 43, 74), + (35, 38, 73), (29, 32, 71), (22, 26, 64), (19, 23, 57), + (18, 22, 53), (22, 33, 55), (24, 42, 59), (27, 51, 63), + (29, 54, 64), (31, 57, 66), (39, 61, 69), (48, 62, 73), + (57, 61, 88), (57, 58, 92), (57, 55, 96), (61, 53, 97), + (65, 52, 98), (71, 54, 110), (82, 63, 123), (90, 74, 134), + (98, 92, 148), (117, 120, 161), (120, 127, 159), (124, 134, 158), + (122, 141, 156), (119, 144, 151), (114, 144, 145), (109, 134, 140), + (91, 113, 108), (75, 101, 97), (59, 89, 87), (55, 86, 87), + (51, 84, 88), (54, 88, 86), (63, 92, 84), (71, 100, 85), + (76, 106, 86), (80, 120, 88), (79, 120, 85), (79, 120, 83), + (77, 119, 77), (74, 116, 73), (71, 110, 69), (69, 105, 65), + (52, 80, 57), (46, 72, 56), (40, 64, 55), (41, 65, 55), + (43, 66, 56), (53, 74, 60), (58, 82, 65), (65, 93, 75), + (71, 106, 91), (88, 140, 123), (90, 148, 129), (92, 157, 136), + (98, 170, 145), (101, 179, 155), (98, 182, 157), (96, 181, 159), + (90, 173, 145), (90, 171, 142), (90, 169, 140), (83, 161, 128), + (75, 152, 117), (68, 143, 106), (63, 134, 96), (63, 127, 90), + (62, 124, 86), (62, 116, 83), (62, 115, 84), (63, 115, 86), + (65, 113, 92), (71, 119, 99), (78, 128, 106), (91, 137, 116), + (115, 156, 146), (119, 160, 154), (123, 165, 162), (127, 172, 170), + (130, 177, 175), (126, 177, 175), (123, 169, 174), (118, 163, 171), + (112, 149, 162), (107, 140, 150), (93, 130, 135), (81, 119, 119), + (69, 115, 103), (62, 106, 90), (64, 104, 80), (64, 103, 75), + (59, 112, 73), (58, 113, 72), (57, 115, 71), (61, 120, 71), + (66, 122, 73), (73, 123, 76), (75, 126, 82), (75, 125, 89), + (77, 127, 95), (81, 127, 102), (88, 132, 112), (99, 137, 121), + (109, 141, 133), (121, 145, 145), (127, 144, 152), (127, 149, 156), + (125, 154, 153), (127, 158, 149), (137, 164, 146), (142, 163, 148), + (145, 163, 151), (138, 162, 150), (134, 164, 150), (138, 169, 149), + (144, 174, 156), (153, 186, 175), (161, 191, 189), (170, 198, 207), + (177, 203, 218), (181, 204, 219), (175, 210, 217), (166, 207, 203), + (155, 199, 187), (142, 188, 172), (130, 172, 159), (114, 160, 147), + (97, 148, 134), (82, 132, 122), (68, 116, 110), (56, 98, 104), + (49, 82, 99), (45, 71, 96), (44, 63, 98), (46, 58, 103), + (47, 53, 109), (49, 53, 112), (52, 52, 110), (56, 53, 105), + (61, 58, 104), (58, 58, 103), (56, 60, 104), (53, 59, 106), + (52, 55, 102), (55, 55, 100), (52, 52, 97), (48, 51, 97), + (45, 54, 101), (49, 61, 110), (63, 73, 122), (81, 92, 135), + (98, 110, 152), (112, 128, 165), (120, 149, 179), (126, 170, 191), + (132, 189, 200), (136, 202, 209), (142, 208, 213), (142, 212, 213), + (138, 214, 213), (133, 216, 213), (123, 214, 209), (120, 205, 206) + ), + +// 609 Paige +((91, 86, 67), (89, 83, 64), (92, 86, 64), (95, 90, 65), + (103, 95, 64), (111, 100, 64), (116, 102, 63), (121, 105, 63), + (133, 110, 61), (133, 111, 62), (133, 113, 63), (133, 118, 69), + (134, 123, 76), (141, 132, 83), (148, 141, 90), (154, 146, 94), + (160, 152, 99), (186, 178, 115), (196, 189, 121), (206, 201, 127), + (209, 207, 131), (213, 213, 136), (211, 213, 136), (210, 213, 137), + (196, 198, 133), (185, 187, 128), (174, 176, 123), (162, 165, 117), + (150, 155, 111), (145, 150, 108), (140, 146, 105), (132, 140, 102), + (128, 135, 100), (123, 129, 99), (120, 128, 100), (118, 127, 101), + (116, 128, 103), (115, 129, 105), (115, 130, 105), (115, 131, 106), + (116, 131, 105), (116, 128, 104), (116, 126, 103), (112, 122, 100), + (109, 118, 98), (107, 116, 96), (105, 114, 95), (101, 108, 90), + (96, 101, 83), (86, 85, 67), (80, 76, 62), (75, 68, 58), + (69, 62, 55), (63, 57, 53), (62, 55, 52), (61, 53, 52), + (62, 55, 53), (66, 56, 51), (70, 57, 49), (72, 60, 50), + (75, 63, 51), (75, 63, 51), (75, 64, 52), (73, 63, 50), + (70, 59, 49), (61, 52, 46), (54, 45, 41), (48, 39, 36), + (45, 36, 35), (43, 34, 34), (37, 30, 33), (31, 27, 32), + (21, 21, 31), (18, 18, 31), (16, 16, 32), (13, 14, 31), + (11, 12, 31), (10, 11, 32), (10, 11, 33), (10, 10, 33), + (10, 9, 32), (13, 12, 32), (16, 13, 32), (20, 15, 32), + (22, 17, 32), (24, 19, 32), (28, 24, 33), (35, 30, 34), + (51, 43, 36), (61, 51, 39), (72, 60, 43), (75, 61, 42), + (79, 63, 42), (84, 66, 41), (85, 69, 41), (86, 70, 42), + (85, 71, 43), (82, 72, 46), (83, 75, 50), (85, 78, 55), + (85, 78, 56), (86, 79, 57), (84, 79, 59), (81, 78, 59), + (71, 71, 56), (66, 67, 55), (61, 64, 54), (59, 63, 54), + (58, 62, 55), (56, 62, 57), (56, 62, 61), (56, 62, 63), + (58, 65, 66), (59, 69, 71), (60, 69, 72), (61, 70, 73), + (63, 72, 73), (63, 74, 73), (64, 74, 74), (66, 73, 75), + (68, 73, 73), (71, 76, 73), (75, 80, 73), (79, 83, 74), + (84, 86, 75), (93, 96, 76), (102, 105, 76), (111, 114, 75), + (119, 121, 76), (134, 130, 72), (137, 132, 71), (140, 135, 70), + (147, 139, 69), (155, 145, 72), (164, 153, 78), (172, 162, 84), + (186, 182, 105), (191, 189, 111), (196, 196, 118), (198, 198, 120), + (201, 201, 122), (204, 203, 124), (205, 205, 127), (206, 205, 128), + (206, 203, 128), (204, 201, 132), (203, 201, 132), (202, 201, 133), + (203, 202, 133), (204, 202, 130), (206, 202, 126), (206, 201, 121), + (208, 200, 115), (207, 199, 115), (207, 199, 115), (203, 196, 115), + (200, 196, 117), (199, 195, 118), (199, 195, 118), (198, 194, 115), + (198, 194, 112), (201, 194, 109), (200, 192, 108), (199, 191, 107), + (193, 183, 106), (183, 176, 105), (171, 165, 104), (157, 151, 98), + (128, 121, 85), (121, 115, 81), (115, 110, 78), (106, 100, 71), + (94, 86, 64), (82, 75, 60), (70, 64, 57), (57, 53, 53), + (45, 42, 53), (34, 33, 51), (25, 28, 51), (20, 27, 53), + (19, 28, 56), (22, 32, 58), (26, 37, 60), (31, 44, 62), + (48, 60, 70), (53, 65, 72), (58, 70, 74), (68, 81, 79), + (80, 91, 83), (91, 102, 87), (103, 111, 90), (110, 118, 91), + (115, 122, 93), (118, 123, 92), (120, 122, 91), (119, 120, 90), + (117, 115, 86), (112, 111, 83), (108, 105, 79), (104, 98, 76), + (97, 92, 73), (90, 85, 69), (86, 80, 67), (82, 77, 67), + (81, 75, 65), (81, 75, 65), (81, 77, 63), (85, 76, 60), + (85, 75, 57), (84, 73, 54), (85, 73, 51), (86, 73, 51), + (89, 73, 50), (93, 75, 50), (95, 80, 51), (98, 84, 53), + (97, 84, 53), (95, 81, 52), (90, 77, 49), (81, 71, 48), + (72, 62, 44), (64, 52, 41), (57, 47, 40), (52, 44, 40), + (48, 42, 41), (47, 40, 40), (46, 39, 39), (44, 40, 38), + (42, 40, 37), (41, 38, 34), (42, 37, 32), (43, 36, 32), + (43, 37, 34), (47, 41, 36), (53, 45, 40), (62, 52, 43), + (72, 62, 47), (81, 71, 49), (89, 79, 50), (96, 85, 54), + (95, 87, 59), (93, 89, 63), (90, 88, 69), (85, 86, 72), + (83, 85, 76), (81, 84, 77), (78, 84, 75), (80, 85, 74), + (80, 85, 74), (79, 84, 72), (84, 90, 75), (86, 92, 75), + (87, 92, 75), (89, 92, 73), (90, 90, 73), (91, 88, 68) + ), + +// 610 Paris +((176, 76, 65), (183, 75, 67), (187, 73, 69), (191, 72, 71), + (194, 71, 70), (198, 71, 69), (198, 71, 70), (199, 72, 72), + (196, 82, 72), (197, 94, 76), (199, 107, 81), (206, 118, 87), + (214, 129, 93), (219, 140, 96), (224, 151, 100), (224, 157, 102), + (225, 164, 105), (227, 181, 125), (223, 176, 131), (219, 171, 137), + (206, 169, 140), (194, 168, 144), (187, 170, 145), (181, 172, 147), + (158, 165, 152), (146, 155, 148), (134, 146, 144), (129, 139, 138), + (124, 133, 132), (124, 129, 130), (124, 126, 128), (126, 123, 123), + (131, 114, 118), (136, 100, 106), (125, 95, 100), (114, 90, 95), + (100, 88, 93), (87, 87, 92), (82, 88, 93), (77, 90, 95), + (57, 97, 99), (54, 91, 95), (52, 86, 91), (64, 81, 91), + (76, 77, 91), (80, 77, 91), (84, 77, 92), (93, 70, 84), + (103, 59, 72), (119, 26, 56), (114, 27, 53), (109, 28, 51), + (108, 31, 49), (108, 35, 47), (113, 33, 49), (119, 31, 52), + (127, 50, 68), (137, 62, 72), (147, 75, 76), (163, 78, 81), + (179, 82, 87), (180, 84, 90), (182, 86, 94), (179, 96, 102), + (175, 104, 104), (163, 121, 108), (159, 128, 118), (156, 136, 128), + (158, 143, 133), (161, 150, 138), (165, 167, 142), (167, 184, 147), + (177, 204, 162), (186, 212, 167), (196, 220, 173), (196, 220, 172), + (196, 221, 171), (194, 217, 170), (192, 213, 170), (191, 203, 165), + (195, 198, 161), (200, 189, 156), (199, 183, 153), (199, 178, 150), + (200, 178, 147), (201, 178, 145), (205, 179, 139), (209, 176, 134), + (206, 162, 130), (201, 156, 124), (196, 150, 119), (192, 146, 115), + (188, 143, 112), (182, 133, 105), (176, 123, 97), (173, 115, 95), + (166, 115, 90), (142, 115, 89), (131, 110, 86), (120, 105, 83), + (116, 103, 82), (113, 102, 81), (110, 99, 79), (105, 92, 79), + (103, 87, 72), (111, 87, 70), (120, 88, 68), (125, 86, 69), + (131, 84, 70), (142, 87, 71), (153, 91, 71), (165, 96, 71), + (176, 103, 73), (196, 113, 91), (199, 114, 93), (203, 116, 96), + (210, 116, 96), (214, 112, 95), (216, 107, 93), (218, 107, 97), + (224, 108, 99), (224, 106, 95), (224, 104, 92), (224, 103, 89), + (224, 102, 87), (222, 102, 84), (224, 104, 83), (226, 108, 85), + (227, 113, 86), (231, 120, 81), (231, 120, 80), (232, 121, 79), + (233, 126, 80), (233, 131, 84), (235, 134, 85), (238, 136, 86), + (238, 134, 87), (234, 136, 86), (230, 138, 86), (229, 137, 86), + (228, 137, 87), (225, 134, 90), (222, 131, 96), (220, 129, 98), + (214, 128, 98), (203, 125, 97), (199, 124, 99), (195, 123, 102), + (189, 120, 105), (183, 115, 104), (177, 106, 100), (175, 101, 93), + (174, 98, 88), (174, 98, 86), (174, 98, 85), (176, 95, 84), + (180, 95, 83), (185, 101, 85), (195, 111, 90), (206, 124, 93), + (214, 135, 99), (222, 159, 112), (222, 166, 116), (222, 173, 120), + (226, 184, 127), (230, 189, 132), (230, 192, 139), (228, 192, 142), + (206, 186, 144), (202, 183, 143), (199, 181, 142), (197, 173, 138), + (198, 163, 133), (194, 153, 125), (188, 142, 118), (177, 134, 113), + (171, 125, 106), (166, 119, 99), (159, 114, 95), (152, 109, 93), + (142, 106, 90), (136, 99, 89), (133, 93, 88), (132, 86, 90), + (128, 76, 91), (131, 71, 88), (134, 67, 86), (139, 64, 79), + (146, 57, 73), (149, 54, 69), (146, 52, 67), (145, 47, 60), + (142, 52, 54), (141, 60, 47), (139, 70, 45), (140, 79, 48), + (140, 87, 50), (139, 94, 55), (143, 102, 56), (147, 111, 62), + (156, 120, 71), (165, 133, 84), (170, 149, 97), (178, 159, 110), + (186, 164, 115), (194, 164, 115), (204, 164, 119), (210, 168, 118), + (212, 172, 121), (213, 170, 120), (211, 162, 114), (207, 147, 107), + (202, 134, 100), (193, 123, 97), (185, 114, 95), (175, 115, 98), + (170, 116, 103), (172, 118, 109), (175, 120, 112), (182, 120, 113), + (186, 126, 109), (191, 134, 108), (201, 141, 109), (210, 146, 108), + (219, 143, 105), (223, 141, 99), (223, 141, 97), (223, 141, 101), + (225, 146, 105), (228, 150, 110), (231, 157, 113), (232, 167, 122), + (231, 175, 133), (232, 185, 140), (232, 195, 144), (230, 204, 143), + (229, 210, 139), (219, 211, 136), (212, 205, 130), (208, 196, 123), + (200, 187, 116), (196, 182, 107), (189, 179, 106), (182, 176, 103), + (177, 167, 106), (173, 158, 111), (165, 149, 111), (158, 140, 111), + (153, 139, 108), (147, 129, 104), (146, 119, 103), (143, 106, 99), + (137, 91, 95), (143, 85, 88), (152, 78, 77), (163, 76, 72) + ), + +// 611 Parrot +((156, 101, 8), (97, 91, 9), (73, 88, 14), (50, 85, 20), + (40, 82, 23), (31, 79, 26), (27, 77, 24), (24, 76, 22), + (35, 58, 23), (44, 57, 16), (54, 56, 10), (53, 66, 11), + (52, 76, 12), (44, 89, 16), (36, 103, 20), (33, 109, 21), + (31, 115, 23), (43, 131, 28), (67, 137, 31), (92, 144, 35), + (106, 142, 52), (120, 141, 70), (112, 133, 75), (104, 125, 81), + (64, 111, 102), (48, 98, 92), (32, 86, 82), (53, 95, 66), + (75, 104, 50), (86, 106, 45), (97, 108, 41), (126, 122, 52), + (158, 129, 57), (176, 125, 78), (174, 103, 78), (172, 82, 79), + (154, 69, 70), (136, 56, 62), (135, 42, 60), (134, 29, 58), + (98, 14, 39), (81, 9, 36), (65, 5, 34), (59, 5, 26), + (54, 5, 18), (62, 7, 22), (70, 9, 27), (88, 18, 26), + (107, 34, 24), (146, 63, 18), (155, 87, 21), (165, 112, 25), + (179, 120, 29), (193, 129, 34), (198, 132, 39), (203, 136, 44), + (219, 104, 40), (226, 85, 33), (234, 66, 27), (233, 56, 22), + (232, 47, 18), (236, 52, 23), (240, 57, 29), (234, 74, 30), + (239, 98, 34), (242, 123, 33), (225, 127, 22), (209, 132, 12), + (192, 131, 11), (175, 131, 10), (140, 131, 16), (117, 122, 25), + (51, 130, 49), (51, 113, 60), (51, 96, 71), (52, 92, 67), + (54, 89, 64), (67, 88, 59), (81, 87, 54), (95, 86, 42), + (101, 94, 26), (108, 91, 10), (85, 79, 23), (63, 67, 36), + (56, 55, 38), (49, 43, 40), (39, 28, 57), (34, 22, 73), + (55, 5, 68), (81, 10, 62), (107, 16, 57), (115, 16, 55), + (123, 17, 53), (136, 16, 54), (157, 17, 59), (176, 18, 63), + (191, 13, 55), (206, 20, 55), (204, 21, 50), (202, 23, 45), + (189, 23, 49), (177, 23, 54), (152, 19, 67), (121, 15, 80), + (81, 12, 91), (66, 19, 78), (52, 26, 65), (54, 25, 58), + (57, 25, 52), (58, 29, 32), (48, 30, 13), (42, 22, 6), + (47, 19, 6), (60, 9, 11), (69, 9, 10), (78, 9, 9), + (103, 8, 6), (124, 4, 14), (145, 7, 20), (162, 11, 17), + (165, 18, 59), (160, 19, 69), (156, 20, 79), (145, 24, 79), + (134, 29, 79), (118, 34, 71), (103, 32, 64), (87, 35, 57), + (70, 34, 61), (68, 36, 81), (72, 34, 92), (76, 33, 103), + (81, 37, 123), (81, 62, 141), (84, 88, 149), (93, 108, 143), + (75, 142, 149), (76, 132, 131), (77, 123, 114), (77, 116, 106), + (78, 109, 98), (82, 96, 83), (103, 62, 71), (136, 47, 51), + (157, 48, 32), (177, 52, 22), (180, 60, 15), (184, 69, 9), + (178, 83, 15), (184, 99, 18), (193, 105, 12), (203, 95, 16), + (227, 69, 45), (224, 57, 50), (222, 45, 55), (216, 27, 73), + (204, 37, 91), (180, 30, 102), (146, 19, 105), (119, 39, 106), + (91, 44, 112), (63, 39, 110), (64, 38, 108), (66, 38, 106), + (64, 34, 98), (72, 44, 87), (88, 50, 79), (89, 47, 75), + (101, 62, 73), (100, 57, 74), (99, 53, 76), (94, 43, 79), + (98, 33, 74), (102, 24, 59), (102, 21, 51), (102, 20, 46), + (105, 19, 35), (111, 23, 23), (121, 37, 20), (124, 54, 20), + (125, 70, 15), (143, 82, 12), (164, 103, 12), (176, 119, 22), + (217, 120, 27), (224, 119, 34), (231, 118, 42), (229, 100, 52), + (229, 86, 51), (237, 75, 54), (227, 52, 66), (209, 38, 72), + (202, 39, 65), (194, 43, 64), (177, 52, 66), (161, 73, 72), + (148, 82, 78), (136, 77, 69), (134, 74, 71), (124, 71, 85), + (119, 57, 74), (117, 51, 58), (111, 57, 47), (111, 58, 29), + (103, 58, 24), (106, 56, 22), (114, 53, 23), (112, 62, 38), + (127, 70, 49), (150, 80, 51), (146, 98, 53), (143, 106, 56), + (146, 98, 42), (126, 84, 27), (103, 69, 25), (79, 46, 23), + (50, 27, 20), (38, 18, 24), (35, 13, 37), (33, 12, 50), + (41, 11, 52), (57, 17, 55), (82, 24, 60), (106, 31, 59), + (130, 43, 54), (153, 55, 53), (170, 62, 61), (192, 60, 70), + (197, 61, 81), (190, 69, 92), (192, 75, 92), (187, 75, 110), + (186, 75, 140), (177, 95, 141), (159, 100, 142), (154, 99, 165), + (138, 104, 164), (105, 85, 146), (79, 77, 134), (73, 82, 112), + (69, 69, 86), (57, 50, 63), (57, 52, 50), (59, 55, 52), + (52, 42, 54), (39, 32, 62), (30, 28, 79), (31, 23, 86), + (35, 16, 86), (44, 13, 79), (66, 23, 65), (87, 31, 57), + (117, 43, 42), (155, 65, 28), (151, 77, 26), (142, 89, 19) + ), + +// 612 Pastel_Lime +((29, 138, 35), (49, 165, 65), (56, 176, 79), (64, 188, 94), + (71, 197, 110), (78, 206, 126), (83, 210, 134), (88, 214, 143), + (113, 230, 174), (116, 228, 178), (120, 226, 182), (122, 218, 188), + (125, 210, 195), (131, 208, 197), (138, 206, 199), (141, 206, 197), + (144, 207, 196), (143, 203, 180), (141, 200, 180), (139, 197, 181), + (142, 202, 182), (145, 208, 183), (146, 211, 183), (148, 215, 184), + (136, 234, 181), (122, 236, 183), (109, 238, 185), (101, 234, 182), + (93, 231, 180), (89, 228, 177), (86, 225, 175), (82, 221, 173), + (77, 216, 175), (74, 216, 180), (86, 212, 179), (98, 209, 179), + (115, 204, 178), (133, 200, 178), (140, 196, 177), (148, 193, 177), + (181, 194, 176), (191, 195, 177), (202, 197, 178), (202, 199, 177), + (203, 202, 176), (202, 202, 175), (201, 203, 174), (202, 206, 169), + (201, 209, 162), (196, 207, 168), (188, 209, 177), (181, 212, 186), + (180, 217, 187), (180, 223, 189), (180, 225, 190), (181, 228, 191), + (190, 216, 199), (186, 205, 210), (182, 195, 221), (174, 191, 221), + (166, 188, 222), (160, 189, 219), (154, 190, 217), (154, 193, 214), + (149, 192, 218), (138, 191, 234), (129, 191, 234), (121, 192, 235), + (119, 195, 231), (117, 199, 228), (115, 204, 220), (110, 205, 211), + (99, 206, 203), (96, 200, 202), (93, 195, 202), (105, 187, 198), + (118, 180, 195), (124, 171, 192), (131, 162, 189), (141, 148, 183), + (152, 138, 178), (167, 109, 157), (182, 101, 146), (197, 94, 136), + (204, 92, 130), (211, 91, 125), (217, 94, 114), (216, 96, 105), + (195, 91, 89), (181, 90, 88), (168, 90, 88), (169, 97, 90), + (170, 105, 93), (164, 116, 94), (159, 133, 100), (161, 149, 110), + (161, 157, 119), (167, 173, 140), (174, 179, 141), (181, 186, 143), + (188, 193, 144), (195, 201, 145), (208, 213, 147), (205, 209, 146), + (209, 201, 140), (202, 192, 129), (196, 183, 118), (193, 181, 112), + (190, 180, 107), (180, 176, 97), (172, 166, 89), (161, 158, 79), + (144, 146, 67), (119, 131, 42), (114, 128, 37), (109, 126, 32), + (98, 124, 26), (93, 122, 24), (93, 114, 23), (97, 112, 25), + (120, 81, 23), (129, 77, 23), (139, 73, 23), (141, 72, 22), + (144, 71, 22), (148, 80, 27), (153, 83, 36), (158, 75, 42), + (161, 73, 55), (154, 76, 74), (146, 79, 77), (138, 82, 81), + (119, 94, 90), (104, 88, 92), (82, 86, 96), (72, 87, 95), + (62, 101, 91), (64, 110, 89), (66, 120, 88), (68, 124, 88), + (70, 128, 88), (70, 136, 86), (71, 150, 81), (73, 164, 77), + (76, 175, 72), (91, 186, 77), (94, 187, 80), (98, 189, 83), + (103, 194, 90), (107, 201, 98), (107, 204, 105), (102, 206, 114), + (97, 207, 125), (99, 206, 126), (101, 205, 128), (103, 202, 132), + (103, 199, 133), (102, 195, 140), (95, 192, 151), (79, 186, 161), + (69, 177, 157), (53, 156, 144), (52, 151, 140), (51, 146, 136), + (50, 144, 129), (43, 144, 142), (37, 150, 149), (35, 160, 159), + (42, 174, 170), (47, 179, 169), (53, 184, 168), (64, 194, 175), + (72, 202, 183), (75, 209, 194), (79, 215, 203), (81, 220, 216), + (87, 219, 225), (98, 216, 230), (112, 213, 230), (121, 206, 229), + (125, 203, 224), (128, 202, 220), (128, 200, 216), (132, 197, 213), + (156, 192, 202), (161, 189, 199), (166, 186, 197), (172, 185, 189), + (172, 186, 178), (168, 185, 162), (166, 188, 152), (164, 188, 144), + (159, 188, 146), (149, 193, 152), (138, 196, 162), (119, 194, 158), + (101, 196, 156), (87, 195, 142), (78, 194, 133), (73, 200, 125), + (73, 206, 126), (72, 202, 119), (75, 198, 115), (82, 195, 99), + (91, 184, 91), (106, 176, 86), (126, 175, 87), (144, 167, 92), + (158, 158, 103), (170, 157, 105), (174, 156, 111), (172, 158, 122), + (165, 168, 135), (164, 174, 153), (155, 178, 175), (144, 184, 193), + (132, 189, 201), (116, 199, 205), (94, 211, 204), (83, 221, 204), + (76, 229, 206), (72, 236, 208), (71, 238, 212), (72, 238, 213), + (71, 237, 211), (76, 234, 209), (88, 228, 208), (106, 221, 210), + (127, 208, 206), (143, 188, 196), (151, 175, 183), (153, 162, 172), + (154, 147, 161), (148, 142, 155), (149, 139, 148), (149, 127, 132), + (140, 126, 114), (123, 126, 96), (108, 122, 82), (85, 125, 73), + (71, 135, 75), (63, 136, 76), (56, 136, 69), (52, 139, 62), + (50, 135, 58), (43, 128, 54), (39, 124, 56), (40, 121, 58), + (35, 114, 56), (37, 112, 52), (39, 108, 45), (40, 104, 36), + (38, 104, 30), (38, 108, 24), (32, 114, 22), (27, 124, 26) + ), + +// 613 Peace +((59, 68, 101), (52, 53, 77), (38, 44, 65), (25, 35, 53), + (24, 35, 53), (24, 36, 54), (24, 36, 54), (24, 36, 55), + (26, 38, 58), (26, 39, 61), (26, 41, 65), (26, 42, 68), + (26, 43, 71), (27, 44, 73), (28, 46, 75), (28, 47, 76), + (29, 48, 78), (36, 54, 87), (45, 59, 92), (54, 64, 98), + (72, 71, 105), (91, 78, 113), (103, 84, 118), (116, 91, 124), + (143, 110, 147), (143, 112, 152), (144, 114, 158), (150, 118, 160), + (156, 123, 163), (160, 125, 164), (164, 127, 165), (171, 129, 167), + (170, 127, 166), (156, 118, 152), (151, 111, 145), (146, 104, 138), + (145, 99, 129), (144, 95, 121), (136, 90, 115), (128, 86, 109), + (82, 64, 88), (64, 56, 80), (47, 48, 72), (38, 44, 66), + (30, 40, 61), (28, 39, 60), (26, 39, 59), (25, 39, 59), + (24, 39, 60), (22, 39, 63), (22, 39, 63), (22, 40, 64), + (23, 39, 63), (24, 39, 62), (24, 39, 61), (24, 39, 61), + (24, 39, 61), (25, 39, 62), (26, 40, 63), (27, 42, 64), + (29, 44, 66), (30, 45, 68), (31, 46, 70), (33, 49, 75), + (37, 51, 81), (47, 58, 90), (54, 61, 95), (61, 65, 101), + (66, 67, 104), (72, 70, 107), (80, 74, 112), (86, 76, 116), + (85, 78, 120), (86, 80, 121), (87, 83, 123), (83, 84, 125), + (80, 86, 127), (76, 84, 127), (72, 82, 127), (65, 81, 123), + (61, 78, 120), (57, 78, 120), (61, 79, 121), (65, 80, 122), + (69, 80, 122), (74, 80, 122), (81, 80, 121), (87, 80, 121), + (94, 83, 123), (106, 85, 124), (119, 88, 125), (128, 90, 128), + (138, 93, 131), (156, 107, 141), (168, 117, 152), (180, 128, 160), + (190, 137, 167), (223, 155, 181), (234, 163, 190), (245, 172, 199), + (244, 173, 202), (244, 174, 205), (234, 176, 210), (219, 170, 207), + (186, 147, 190), (169, 137, 183), (153, 128, 176), (142, 124, 173), + (132, 121, 171), (111, 112, 163), (88, 101, 152), (75, 88, 137), + (63, 79, 125), (48, 69, 108), (44, 66, 105), (41, 64, 102), + (36, 60, 96), (33, 56, 91), (32, 53, 85), (31, 51, 80), + (29, 47, 74), (28, 46, 72), (28, 45, 71), (29, 45, 70), + (30, 45, 70), (31, 46, 70), (31, 46, 69), (30, 45, 68), + (29, 44, 68), (30, 46, 70), (30, 46, 71), (31, 47, 73), + (31, 48, 74), (32, 49, 77), (32, 50, 79), (32, 52, 82), + (35, 54, 86), (36, 56, 89), (38, 58, 92), (39, 59, 94), + (40, 61, 96), (43, 65, 103), (46, 69, 109), (48, 74, 116), + (50, 79, 122), (57, 92, 138), (59, 96, 144), (62, 101, 150), + (72, 115, 163), (88, 123, 174), (111, 131, 179), (130, 134, 180), + (138, 130, 172), (136, 127, 169), (134, 124, 166), (134, 119, 158), + (137, 112, 147), (129, 96, 128), (115, 83, 109), (91, 69, 92), + (69, 57, 77), (38, 41, 55), (34, 38, 50), (31, 35, 46), + (25, 30, 39), (22, 27, 36), (23, 27, 35), (22, 27, 35), + (22, 28, 37), (21, 28, 39), (21, 29, 41), (22, 31, 46), + (23, 34, 50), (25, 38, 56), (29, 42, 62), (33, 47, 69), + (41, 54, 81), (54, 62, 91), (76, 73, 105), (103, 92, 122), + (128, 116, 140), (151, 141, 163), (155, 155, 178), (157, 158, 186), + (153, 155, 184), (154, 156, 182), (155, 157, 181), (136, 151, 175), + (111, 137, 163), (84, 114, 146), (56, 90, 126), (44, 73, 109), + (37, 61, 95), (34, 54, 86), (32, 51, 80), (31, 49, 77), + (33, 50, 77), (37, 52, 77), (40, 53, 76), (42, 54, 76), + (42, 54, 76), (41, 53, 77), (42, 54, 78), (40, 54, 79), + (40, 54, 79), (39, 54, 80), (36, 53, 82), (35, 54, 85), + (35, 55, 88), (34, 55, 89), (34, 55, 90), (34, 55, 89), + (36, 55, 87), (37, 55, 84), (36, 53, 80), (35, 50, 75), + (34, 47, 70), (34, 46, 68), (34, 45, 66), (34, 45, 67), + (35, 47, 71), (35, 51, 76), (37, 56, 85), (40, 62, 94), + (43, 67, 103), (44, 71, 109), (46, 74, 113), (47, 75, 116), + (49, 76, 116), (50, 75, 114), (49, 72, 108), (46, 67, 98), + (42, 59, 89), (39, 54, 81), (37, 49, 74), (34, 45, 68), + (32, 42, 62), (29, 39, 57), (27, 37, 55), (25, 37, 56), + (24, 37, 57), (24, 38, 59), (25, 39, 61), (26, 41, 63), + (27, 43, 67), (28, 46, 72), (30, 50, 78), (33, 55, 86), + (36, 61, 96), (40, 67, 104), (57, 75, 114), (67, 80, 121), + (65, 77, 115), (63, 74, 112), (47, 69, 105), (52, 65, 99) + ), + +// 614 Persia +((236, 146, 111), (235, 132, 107), (225, 129, 101), (215, 127, 95), + (200, 122, 89), (185, 117, 84), (179, 113, 84), (174, 109, 84), + (157, 108, 88), (146, 110, 89), (135, 113, 91), (123, 109, 91), + (112, 105, 91), (107, 101, 87), (102, 97, 84), (102, 95, 81), + (103, 94, 78), (100, 82, 59), (104, 71, 49), (109, 60, 39), + (116, 51, 30), (124, 43, 22), (124, 41, 20), (125, 39, 19), + (140, 40, 29), (157, 42, 36), (174, 45, 44), (172, 46, 48), + (170, 48, 53), (162, 49, 55), (155, 51, 57), (146, 59, 63), + (141, 67, 70), (130, 66, 65), (111, 65, 57), (93, 65, 49), + (74, 65, 44), (56, 66, 39), (48, 62, 36), (41, 58, 33), + (34, 50, 22), (40, 46, 19), (47, 43, 17), (56, 35, 15), + (66, 28, 13), (71, 25, 13), (77, 23, 13), (85, 22, 18), + (95, 20, 21), (106, 19, 24), (102, 20, 24), (98, 21, 25), + (87, 25, 27), (76, 29, 29), (73, 34, 32), (70, 39, 35), + (79, 80, 63), (91, 96, 78), (103, 112, 93), (122, 126, 101), + (141, 140, 110), (151, 149, 115), (161, 159, 121), (180, 171, 134), + (197, 179, 143), (210, 173, 140), (203, 165, 134), (196, 157, 129), + (189, 148, 124), (183, 140, 120), (173, 117, 108), (159, 103, 96), + (131, 84, 72), (116, 72, 62), (102, 60, 53), (96, 55, 51), + (90, 50, 49), (91, 54, 51), (93, 58, 53), (96, 69, 58), + (96, 79, 64), (99, 96, 90), (107, 102, 99), (115, 109, 109), + (118, 111, 110), (122, 114, 112), (130, 121, 112), (139, 126, 113), + (159, 137, 116), (165, 142, 119), (171, 148, 122), (172, 150, 123), + (173, 153, 124), (172, 153, 122), (169, 150, 121), (163, 145, 119), + (152, 138, 118), (127, 123, 111), (117, 112, 103), (107, 101, 96), + (104, 97, 93), (101, 93, 91), (101, 91, 92), (103, 95, 97), + (116, 112, 114), (129, 120, 117), (143, 128, 120), (151, 131, 122), + (160, 135, 124), (175, 144, 126), (188, 149, 130), (193, 156, 128), + (192, 158, 123), (167, 143, 105), (158, 136, 100), (150, 130, 96), + (134, 117, 85), (122, 106, 78), (105, 96, 68), (85, 84, 64), + (53, 58, 52), (54, 50, 47), (55, 43, 43), (58, 42, 43), + (61, 42, 43), (67, 46, 48), (77, 54, 54), (89, 67, 61), + (107, 78, 66), (136, 85, 71), (141, 84, 69), (146, 84, 67), + (151, 86, 65), (158, 90, 59), (161, 80, 54), (154, 75, 51), + (118, 52, 37), (98, 46, 33), (79, 40, 29), (70, 39, 30), + (62, 38, 32), (49, 36, 37), (32, 37, 42), (21, 41, 45), + (14, 41, 48), (13, 44, 47), (15, 43, 46), (18, 42, 45), + (27, 45, 41), (37, 46, 38), (46, 48, 39), (52, 51, 40), + (62, 55, 46), (63, 55, 45), (65, 56, 44), (67, 54, 43), + (65, 53, 44), (56, 50, 46), (47, 48, 51), (38, 45, 50), + (28, 37, 42), (20, 20, 25), (22, 19, 24), (24, 19, 23), + (35, 23, 29), (47, 31, 37), (61, 42, 46), (74, 54, 53), + (103, 95, 80), (110, 105, 89), (118, 115, 98), (134, 135, 119), + (146, 145, 130), (151, 157, 141), (154, 164, 146), (156, 167, 146), + (156, 167, 145), (156, 155, 132), (155, 140, 114), (153, 125, 95), + (153, 107, 79), (153, 90, 63), (150, 75, 49), (137, 59, 33), + (104, 36, 12), (98, 31, 11), (92, 26, 10), (84, 19, 13), + (71, 14, 17), (51, 10, 20), (34, 10, 24), (17, 11, 27), + (10, 13, 28), (9, 19, 29), (10, 22, 28), (18, 27, 25), + (32, 31, 23), (51, 38, 23), (73, 50, 24), (93, 61, 30), + (105, 73, 34), (116, 81, 40), (121, 86, 47), (125, 89, 53), + (132, 99, 64), (131, 112, 76), (133, 120, 89), (134, 129, 103), + (134, 131, 112), (141, 134, 116), (147, 137, 119), (158, 132, 117), + (171, 125, 112), (181, 113, 105), (191, 100, 95), (192, 90, 88), + (183, 75, 77), (167, 60, 66), (143, 40, 51), (120, 26, 36), + (100, 17, 29), (79, 13, 26), (62, 17, 27), (42, 17, 27), + (27, 15, 23), (18, 13, 20), (21, 10, 18), (31, 14, 17), + (45, 15, 16), (63, 21, 15), (84, 26, 20), (107, 32, 27), + (130, 42, 36), (149, 50, 40), (161, 60, 38), (173, 67, 38), + (179, 67, 39), (186, 66, 43), (185, 64, 46), (175, 64, 46), + (165, 69, 40), (151, 71, 39), (147, 71, 44), (150, 75, 51), + (157, 80, 63), (166, 92, 71), (175, 107, 80), (183, 122, 91), + (192, 136, 103), (205, 146, 114), (219, 151, 119), (232, 154, 120), + (241, 156, 120), (243, 155, 120), (242, 156, 118), (238, 154, 115) + ), + +// 615 Persia_2 +((236, 205, 111), (235, 193, 107), (225, 188, 101), (215, 183, 95), + (200, 174, 89), (185, 165, 84), (179, 158, 84), (174, 152, 84), + (157, 140, 88), (146, 137, 89), (135, 134, 91), (122, 123, 91), + (109, 112, 91), (104, 107, 87), (99, 102, 84), (99, 102, 81), + (100, 103, 78), (99, 100, 59), (104, 96, 49), (109, 93, 39), + (116, 91, 30), (124, 90, 22), (124, 89, 20), (125, 88, 19), + (140, 92, 29), (157, 98, 36), (174, 105, 44), (172, 103, 46), + (170, 101, 48), (162, 97, 49), (155, 94, 51), (146, 95, 59), + (141, 99, 67), (130, 96, 65), (111, 91, 57), (93, 86, 49), + (68, 76, 44), (43, 66, 39), (38, 62, 37), (33, 58, 36), + (22, 50, 23), (29, 48, 20), (37, 47, 17), (51, 49, 15), + (66, 52, 13), (71, 52, 13), (77, 52, 13), (85, 53, 18), + (95, 53, 20), (106, 55, 19), (102, 54, 20), (98, 53, 21), + (87, 52, 25), (76, 51, 29), (73, 53, 32), (70, 55, 35), + (71, 80, 63), (82, 96, 78), (94, 112, 93), (111, 126, 101), + (128, 141, 110), (136, 151, 115), (144, 161, 121), (168, 180, 134), + (190, 197, 143), (210, 206, 140), (203, 197, 134), (196, 188, 129), + (189, 179, 124), (183, 170, 120), (173, 147, 108), (159, 133, 96), + (131, 111, 72), (116, 97, 62), (102, 83, 53), (96, 76, 51), + (90, 69, 49), (91, 72, 51), (93, 76, 53), (96, 86, 58), + (96, 94, 64), (98, 99, 90), (106, 105, 99), (115, 112, 109), + (118, 115, 110), (122, 119, 112), (130, 129, 112), (139, 138, 113), + (159, 157, 116), (165, 164, 119), (171, 171, 122), (170, 172, 123), + (170, 173, 124), (168, 172, 122), (166, 169, 121), (161, 163, 119), + (150, 152, 118), (124, 127, 111), (115, 116, 103), (107, 106, 96), + (104, 102, 93), (101, 98, 91), (101, 95, 91), (103, 97, 95), + (116, 112, 112), (129, 125, 116), (143, 139, 120), (151, 145, 122), + (160, 152, 124), (175, 167, 126), (188, 177, 130), (193, 187, 128), + (192, 190, 123), (162, 167, 105), (153, 158, 100), (145, 150, 96), + (128, 134, 85), (118, 122, 78), (97, 105, 68), (76, 85, 64), + (52, 58, 54), (53, 53, 48), (55, 48, 43), (58, 49, 42), + (61, 50, 42), (67, 53, 46), (77, 64, 54), (89, 80, 61), + (107, 97, 66), (136, 115, 71), (141, 118, 69), (146, 121, 67), + (151, 127, 65), (158, 137, 59), (161, 131, 54), (154, 123, 51), + (118, 90, 37), (98, 76, 33), (79, 63, 29), (70, 57, 30), + (62, 52, 32), (49, 41, 36), (32, 32, 42), (21, 29, 45), + (14, 25, 48), (13, 28, 47), (15, 28, 46), (18, 29, 45), + (27, 40, 45), (37, 46, 42), (42, 48, 39), (47, 52, 40), + (61, 62, 46), (62, 63, 45), (64, 65, 44), (67, 65, 43), + (65, 63, 44), (56, 54, 46), (48, 47, 51), (38, 39, 50), + (28, 30, 42), (22, 20, 25), (23, 19, 22), (24, 19, 20), + (35, 23, 23), (47, 32, 31), (61, 46, 42), (74, 64, 53), + (100, 103, 80), (106, 110, 89), (112, 118, 98), (126, 135, 119), + (140, 146, 130), (143, 157, 141), (146, 164, 146), (146, 167, 146), + (146, 167, 145), (146, 156, 132), (151, 155, 114), (153, 152, 95), + (153, 142, 79), (153, 132, 63), (150, 121, 49), (137, 107, 33), + (104, 79, 12), (98, 71, 11), (92, 64, 10), (84, 52, 13), + (71, 37, 14), (51, 18, 10), (34, 10, 12), (24, 11, 27), + (15, 10, 28), (9, 9, 29), (10, 13, 28), (18, 24, 27), + (28, 32, 23), (51, 51, 23), (73, 73, 24), (93, 91, 30), + (104, 105, 34), (116, 116, 40), (121, 121, 47), (125, 123, 53), + (132, 131, 64), (125, 131, 76), (126, 133, 89), (125, 134, 103), + (127, 134, 112), (136, 141, 116), (144, 147, 119), (158, 151, 117), + (171, 152, 112), (181, 148, 105), (191, 145, 95), (192, 138, 88), + (183, 124, 75), (167, 104, 60), (143, 78, 40), (120, 60, 26), + (100, 43, 17), (79, 30, 13), (62, 28, 17), (42, 18, 17), + (27, 15, 17), (20, 13, 18), (21, 10, 12), (31, 18, 14), + (45, 28, 15), (63, 43, 15), (84, 56, 20), (107, 69, 27), + (130, 86, 36), (149, 102, 40), (161, 118, 38), (173, 130, 38), + (179, 132, 39), (186, 134, 43), (185, 129, 46), (175, 123, 46), + (165, 127, 40), (151, 123, 39), (147, 120, 44), (150, 122, 51), + (157, 124, 63), (166, 136, 71), (175, 151, 80), (183, 165, 91), + (192, 177, 103), (205, 189, 114), (219, 198, 119), (232, 206, 120), + (241, 213, 120), (243, 213, 120), (242, 213, 118), (238, 212, 115) + ), + +// 616 Persia_3 +((175, 149, 236), (165, 145, 235), (159, 137, 225), (154, 129, 215), + (146, 121, 200), (138, 114, 185), (134, 113, 179), (130, 112, 174), + (126, 113, 157), (125, 113, 146), (124, 113, 135), (117, 111, 123), + (111, 109, 112), (106, 104, 107), (101, 100, 102), (100, 97, 102), + (100, 94, 103), (89, 75, 100), (81, 65, 104), (73, 56, 109), + (66, 49, 116), (59, 42, 124), (57, 40, 124), (56, 39, 125), + (62, 51, 140), (67, 61, 157), (73, 72, 174), (74, 74, 172), + (75, 77, 170), (75, 77, 162), (76, 78, 155), (82, 84, 146), + (89, 90, 141), (87, 86, 130), (81, 75, 111), (75, 64, 93), + (70, 56, 76), (66, 49, 59), (62, 45, 52), (58, 42, 46), + (50, 30, 38), (47, 27, 42), (44, 24, 47), (40, 23, 56), + (36, 23, 66), (34, 24, 71), (33, 25, 77), (35, 31, 85), + (35, 35, 95), (36, 37, 106), (36, 37, 102), (36, 38, 98), + (38, 39, 87), (41, 41, 76), (45, 43, 73), (49, 46, 70), + (80, 76, 79), (96, 93, 95), (112, 111, 111), (126, 122, 126), + (141, 133, 141), (151, 140, 151), (161, 147, 161), (177, 163, 180), + (190, 175, 197), (192, 174, 210), (184, 167, 203), (176, 160, 196), + (168, 154, 189), (161, 149, 183), (141, 136, 173), (126, 121, 159), + (101, 93, 131), (87, 81, 116), (74, 69, 102), (69, 66, 96), + (64, 63, 90), (67, 65, 91), (71, 68, 93), (80, 73, 96), + (87, 79, 96), (99, 99, 99), (107, 107, 107), (115, 115, 115), + (118, 118, 118), (122, 122, 122), (130, 130, 130), (137, 135, 139), + (151, 141, 159), (156, 145, 165), (161, 149, 171), (163, 150, 172), + (165, 152, 173), (164, 150, 172), (161, 148, 169), (156, 145, 163), + (148, 142, 152), (127, 127, 127), (117, 117, 117), (107, 107, 107), + (104, 104, 104), (101, 101, 101), (101, 101, 101), (103, 103, 103), + (116, 116, 116), (129, 129, 129), (143, 143, 143), (148, 146, 151), + (153, 150, 160), (162, 154, 175), (170, 160, 188), (174, 159, 193), + (174, 154, 192), (154, 132, 167), (146, 126, 158), (139, 120, 150), + (125, 106, 134), (114, 97, 122), (100, 85, 105), (84, 77, 85), + (58, 58, 58), (55, 55, 56), (52, 52, 55), (51, 51, 58), + (51, 51, 61), (56, 57, 67), (66, 66, 77), (78, 75, 89), + (91, 83, 107), (103, 93, 136), (103, 91, 141), (103, 90, 146), + (106, 89, 151), (109, 84, 158), (101, 80, 161), (95, 75, 154), + (68, 56, 118), (59, 48, 98), (50, 41, 79), (48, 41, 70), + (46, 42, 62), (44, 44, 49), (40, 42, 38), (41, 45, 28), + (41, 48, 21), (44, 47, 20), (43, 46, 22), (42, 45, 25), + (45, 42, 34), (46, 44, 44), (48, 46, 47), (51, 48, 52), + (59, 56, 62), (59, 55, 63), (60, 54, 65), (60, 53, 67), + (59, 54, 65), (55, 55, 56), (51, 51, 51), (48, 50, 46), + (39, 42, 34), (24, 25, 24), (23, 24, 24), (22, 23, 24), + (28, 31, 35), (38, 41, 47), (51, 53, 61), (65, 65, 74), + (101, 96, 103), (109, 106, 110), (118, 117, 118), (135, 135, 135), + (146, 146, 146), (157, 157, 157), (164, 164, 164), (167, 167, 167), + (167, 167, 167), (156, 156, 156), (150, 139, 155), (137, 119, 153), + (124, 103, 153), (108, 87, 153), (93, 73, 150), (76, 55, 137), + (50, 28, 104), (44, 26, 98), (38, 24, 92), (32, 26, 84), + (25, 26, 71), (18, 25, 51), (15, 25, 34), (15, 27, 19), + (16, 28, 14), (20, 29, 13), (22, 28, 14), (27, 26, 22), + (31, 28, 32), (41, 31, 51), (56, 35, 73), (69, 45, 93), + (81, 50, 105), (90, 58, 116), (97, 66, 121), (100, 73, 125), + (110, 85, 132), (120, 97, 131), (127, 110, 133), (132, 124, 134), + (134, 133, 134), (140, 139, 141), (146, 143, 147), (148, 142, 158), + (147, 139, 171), (140, 134, 181), (130, 126, 191), (121, 119, 192), + (104, 104, 183), (87, 89, 167), (63, 69, 143), (45, 50, 120), + (33, 42, 100), (25, 35, 79), (27, 34, 62), (23, 30, 42), + (19, 23, 27), (16, 20, 18), (13, 18, 21), (19, 20, 31), + (22, 22, 45), (29, 25, 63), (39, 33, 84), (49, 44, 107), + (63, 57, 130), (73, 64, 149), (83, 64, 161), (90, 65, 173), + (91, 67, 179), (93, 73, 186), (92, 75, 185), (89, 74, 175), + (91, 66, 165), (89, 63, 151), (90, 67, 147), (95, 75, 150), + (102, 88, 157), (113, 97, 166), (128, 108, 175), (142, 120, 183), + (156, 134, 192), (168, 147, 205), (176, 154, 219), (181, 157, 232), + (185, 159, 241), (184, 159, 243), (184, 157, 242), (182, 153, 238) + ), + +// 617 Pink +((182, 60, 110), (175, 52, 105), (171, 49, 103), (167, 47, 101), + (165, 46, 99), (163, 46, 98), (162, 46, 97), (162, 46, 96), + (155, 43, 92), (151, 40, 91), (148, 37, 91), (145, 36, 92), + (143, 35, 94), (145, 36, 96), (147, 38, 98), (150, 39, 100), + (154, 41, 102), (170, 47, 106), (176, 49, 106), (182, 51, 107), + (185, 52, 106), (188, 54, 106), (188, 54, 105), (188, 55, 104), + (181, 47, 97), (174, 43, 94), (167, 39, 92), (160, 36, 92), + (154, 33, 92), (151, 32, 92), (149, 31, 93), (145, 30, 94), + (142, 30, 94), (141, 29, 94), (142, 30, 94), (144, 31, 95), + (145, 31, 94), (146, 31, 93), (147, 30, 91), (148, 30, 90), + (151, 30, 85), (152, 31, 83), (154, 33, 81), (159, 35, 81), + (164, 38, 82), (168, 40, 84), (173, 43, 86), (182, 51, 90), + (190, 60, 97), (209, 81, 109), (220, 91, 118), (231, 102, 128), + (237, 112, 140), (243, 122, 152), (245, 126, 157), (247, 130, 163), + (239, 130, 170), (230, 121, 166), (222, 113, 162), (213, 105, 157), + (204, 98, 153), (199, 93, 150), (194, 89, 148), (184, 77, 140), + (173, 65, 129), (159, 55, 117), (157, 53, 117), (156, 52, 117), + (157, 52, 118), (158, 52, 120), (160, 52, 122), (162, 54, 124), + (173, 61, 125), (180, 65, 127), (188, 70, 129), (193, 73, 134), + (198, 76, 139), (201, 78, 141), (204, 81, 143), (208, 89, 150), + (214, 94, 153), (215, 96, 162), (217, 97, 162), (219, 99, 163), + (221, 102, 163), (224, 105, 164), (229, 113, 163), (231, 124, 168), + (239, 153, 180), (244, 165, 184), (249, 177, 189), (250, 178, 189), + (251, 180, 189), (254, 180, 190), (252, 176, 188), (247, 171, 189), + (241, 162, 180), (227, 128, 151), (221, 109, 136), (215, 90, 121), + (211, 83, 115), (208, 77, 110), (199, 69, 102), (191, 62, 95), + (185, 59, 91), (184, 57, 94), (183, 56, 98), (179, 54, 99), + (176, 52, 100), (171, 49, 102), (165, 49, 104), (163, 50, 105), + (161, 51, 108), (159, 49, 114), (159, 49, 115), (159, 49, 116), + (163, 51, 114), (166, 54, 112), (169, 56, 108), (171, 56, 106), + (173, 54, 107), (170, 52, 105), (168, 50, 103), (165, 48, 100), + (162, 46, 98), (155, 40, 95), (148, 36, 95), (141, 31, 97), + (138, 29, 96), (138, 27, 92), (140, 27, 91), (142, 28, 91), + (148, 31, 92), (157, 36, 92), (167, 45, 92), (176, 54, 93), + (190, 61, 94), (190, 59, 92), (191, 58, 91), (189, 58, 90), + (187, 58, 89), (182, 55, 88), (173, 53, 86), (162, 47, 86), + (155, 41, 85), (141, 33, 83), (138, 32, 82), (135, 31, 81), + (131, 29, 83), (129, 30, 86), (128, 32, 88), (126, 31, 90), + (116, 22, 83), (115, 20, 83), (114, 19, 83), (115, 16, 82), + (119, 18, 85), (114, 17, 80), (115, 15, 76), (119, 15, 74), + (128, 15, 74), (145, 21, 82), (147, 23, 82), (149, 25, 83), + (153, 26, 84), (156, 28, 85), (159, 31, 88), (161, 32, 91), + (166, 38, 95), (167, 38, 95), (169, 39, 95), (172, 44, 95), + (174, 47, 98), (174, 52, 100), (176, 56, 102), (177, 58, 100), + (176, 62, 101), (178, 63, 103), (175, 65, 108), (172, 64, 112), + (171, 62, 111), (168, 63, 110), (171, 63, 111), (177, 65, 113), + (191, 67, 120), (195, 68, 120), (199, 70, 121), (204, 72, 123), + (205, 74, 123), (205, 74, 126), (200, 72, 126), (197, 69, 125), + (193, 64, 124), (185, 60, 119), (177, 54, 116), (166, 49, 111), + (160, 42, 106), (158, 37, 102), (158, 34, 96), (158, 32, 90), + (159, 33, 84), (161, 34, 81), (163, 35, 80), (168, 37, 81), + (170, 38, 82), (171, 38, 81), (170, 41, 82), (167, 43, 83), + (167, 46, 87), (167, 47, 92), (167, 47, 95), (165, 50, 98), + (159, 51, 100), (154, 50, 102), (148, 47, 103), (144, 41, 101), + (140, 37, 98), (134, 35, 95), (129, 31, 94), (124, 27, 93), + (121, 22, 89), (123, 18, 85), (125, 17, 81), (128, 17, 78), + (132, 18, 80), (138, 21, 81), (146, 23, 81), (153, 27, 81), + (160, 30, 82), (165, 33, 85), (168, 37, 88), (171, 40, 92), + (173, 44, 98), (175, 49, 105), (177, 54, 113), (181, 60, 120), + (185, 65, 126), (187, 69, 133), (189, 74, 140), (188, 77, 142), + (190, 80, 142), (191, 78, 139), (192, 74, 135), (191, 71, 132), + (188, 67, 127), (187, 66, 122), (188, 65, 115), (190, 63, 110), + (194, 64, 108), (196, 64, 107), (198, 65, 109), (200, 67, 109), + (198, 65, 109), (194, 63, 109), (190, 63, 109), (185, 60, 110) + ), + +// 618 Pollen +((115, 114, 55), (143, 139, 47), (166, 158, 48), (189, 177, 49), + (198, 189, 46), (207, 202, 44), (209, 203, 42), (211, 204, 40), + (216, 200, 47), (205, 191, 43), (194, 182, 39), (173, 160, 38), + (153, 138, 37), (126, 112, 37), (99, 87, 37), (87, 77, 32), + (75, 67, 28), (40, 33, 9), (35, 30, 6), (30, 28, 4), + (37, 35, 10), (45, 43, 17), (52, 49, 22), (59, 55, 27), + (98, 92, 51), (118, 111, 67), (139, 130, 83), (156, 148, 104), + (174, 167, 125), (183, 176, 136), (193, 185, 148), (211, 201, 165), + (219, 210, 171), (217, 210, 159), (215, 204, 148), (214, 199, 137), + (198, 184, 118), (183, 169, 99), (170, 157, 86), (157, 146, 74), + (129, 105, 29), (129, 85, 17), (130, 65, 6), (122, 54, 8), + (115, 44, 10), (107, 41, 9), (100, 38, 9), (101, 32, 10), + (104, 26, 7), (102, 27, 11), (92, 34, 14), (82, 42, 18), + (78, 50, 20), (75, 58, 23), (77, 63, 25), (79, 68, 28), + (96, 91, 42), (111, 96, 48), (126, 101, 55), (142, 103, 57), + (159, 106, 59), (161, 108, 56), (163, 111, 53), (154, 115, 50), + (141, 108, 41), (140, 91, 33), (135, 96, 28), (130, 101, 23), + (121, 102, 22), (113, 104, 21), (104, 97, 19), (96, 89, 20), + (86, 79, 17), (78, 71, 17), (70, 63, 18), (60, 51, 17), + (51, 40, 16), (47, 36, 13), (43, 33, 11), (33, 28, 10), + (30, 27, 12), (38, 40, 22), (49, 51, 29), (61, 63, 37), + (68, 69, 41), (76, 76, 46), (90, 93, 56), (103, 107, 64), + (119, 121, 64), (125, 117, 57), (131, 113, 51), (137, 108, 50), + (144, 104, 50), (147, 97, 47), (142, 93, 41), (130, 90, 33), + (119, 84, 25), (119, 68, 28), (109, 65, 28), (100, 63, 29), + (91, 64, 29), (83, 65, 29), (70, 68, 29), (65, 70, 36), + (65, 66, 39), (66, 66, 43), (67, 66, 47), (67, 68, 51), + (68, 71, 55), (73, 79, 61), (81, 86, 67), (93, 94, 75), + (101, 101, 80), (111, 113, 84), (112, 115, 83), (113, 117, 83), + (118, 121, 81), (124, 128, 83), (131, 135, 89), (139, 142, 93), + (148, 151, 98), (153, 153, 101), (158, 155, 104), (161, 155, 107), + (165, 156, 111), (170, 159, 118), (176, 164, 124), (178, 171, 132), + (181, 174, 135), (176, 166, 136), (173, 163, 134), (171, 160, 132), + (164, 159, 130), (158, 160, 129), (150, 154, 124), (145, 151, 119), + (142, 147, 105), (145, 150, 104), (149, 154, 103), (152, 158, 102), + (155, 162, 101), (163, 170, 104), (179, 184, 105), (194, 197, 104), + (206, 202, 107), (209, 205, 113), (209, 206, 114), (209, 207, 116), + (208, 209, 111), (205, 203, 103), (197, 194, 100), (185, 180, 96), + (156, 149, 89), (150, 141, 82), (145, 134, 76), (131, 119, 64), + (118, 104, 53), (101, 88, 45), (84, 69, 35), (69, 50, 25), + (56, 36, 17), (32, 19, 4), (26, 16, 3), (20, 13, 2), + (11, 6, 1), (6, 3, 2), (5, 3, 4), (11, 9, 9), + (27, 28, 24), (30, 33, 27), (34, 38, 31), (42, 48, 35), + (53, 60, 40), (68, 72, 44), (83, 84, 54), (90, 93, 63), + (97, 98, 70), (98, 102, 73), (102, 106, 71), (108, 109, 69), + (107, 112, 70), (111, 112, 72), (114, 113, 78), (121, 120, 87), + (145, 147, 105), (151, 153, 110), (157, 160, 115), (171, 173, 128), + (186, 184, 140), (197, 196, 148), (208, 206, 157), (209, 208, 159), + (208, 209, 165), (204, 205, 166), (196, 199, 157), (187, 190, 149), + (177, 176, 133), (163, 163, 125), (149, 147, 120), (134, 132, 107), + (118, 120, 96), (108, 110, 77), (97, 100, 64), (87, 88, 55), + (77, 77, 46), (67, 68, 37), (60, 64, 27), (55, 62, 22), + (53, 60, 23), (48, 56, 26), (47, 51, 27), (44, 46, 28), + (42, 45, 27), (42, 45, 27), (39, 44, 30), (40, 46, 32), + (43, 43, 33), (45, 43, 31), (48, 45, 30), (49, 46, 30), + (48, 50, 31), (50, 49, 31), (51, 47, 30), (49, 46, 29), + (46, 42, 28), (38, 42, 25), (34, 41, 22), (35, 41, 19), + (37, 43, 18), (44, 45, 21), (51, 53, 24), (58, 62, 29), + (69, 73, 31), (80, 86, 37), (93, 96, 42), (103, 105, 45), + (107, 109, 45), (106, 107, 41), (100, 100, 39), (89, 90, 37), + (76, 78, 33), (64, 67, 27), (56, 57, 21), (51, 48, 20), + (48, 42, 21), (46, 38, 25), (44, 38, 29), (48, 41, 32), + (55, 49, 35), (63, 56, 37), (70, 64, 40), (75, 69, 40), + (90, 82, 46), (102, 95, 54), (113, 105, 59), (119, 116, 64) + ), + +// 619 Poppies +((174, 44, 42), (206, 26, 41), (178, 23, 48), (151, 21, 55), + (143, 18, 42), (136, 16, 30), (139, 24, 32), (143, 33, 35), + (107, 54, 29), (75, 57, 25), (44, 61, 21), (40, 53, 14), + (36, 45, 8), (60, 47, 5), (84, 49, 3), (100, 50, 8), + (116, 51, 13), (116, 97, 51), (95, 123, 86), (75, 149, 121), + (85, 151, 145), (96, 154, 169), (100, 162, 167), (104, 171, 165), + (175, 112, 143), (190, 83, 116), (205, 55, 90), (205, 48, 69), + (206, 42, 48), (194, 38, 44), (182, 35, 41), (164, 49, 43), + (151, 56, 41), (157, 57, 62), (166, 57, 63), (175, 58, 65), + (168, 74, 51), (161, 91, 38), (162, 105, 38), (163, 120, 39), + (146, 152, 79), (148, 157, 110), (151, 163, 141), (153, 164, 151), + (156, 166, 162), (157, 158, 154), (159, 151, 147), (150, 149, 139), + (138, 131, 124), (94, 119, 94), (67, 108, 74), (40, 97, 54), + (45, 95, 44), (51, 94, 34), (67, 103, 33), (83, 113, 32), + (182, 140, 40), (211, 125, 57), (241, 111, 75), (242, 100, 69), + (244, 89, 63), (241, 103, 57), (239, 118, 52), (219, 122, 23), + (194, 169, 17), (169, 151, 31), (179, 127, 40), (190, 104, 49), + (193, 109, 58), (196, 114, 67), (182, 129, 81), (178, 161, 123), + (145, 175, 125), (121, 170, 98), (97, 165, 72), (71, 160, 53), + (45, 156, 35), (37, 143, 32), (30, 130, 29), (27, 120, 19), + (25, 98, 22), (45, 86, 4), (64, 86, 11), (84, 86, 19), + (96, 81, 16), (109, 77, 14), (147, 65, 25), (175, 44, 21), + (224, 17, 10), (235, 23, 13), (246, 29, 17), (242, 31, 17), + (238, 34, 17), (225, 69, 37), (212, 73, 23), (190, 80, 22), + (172, 83, 8), (124, 92, 25), (95, 98, 42), (67, 105, 59), + (47, 109, 58), (28, 114, 57), (28, 129, 48), (12, 143, 41), + (14, 156, 25), (43, 148, 47), (73, 141, 70), (105, 135, 82), + (138, 130, 94), (179, 104, 120), (213, 105, 127), (225, 112, 137), + (224, 151, 152), (194, 174, 173), (195, 152, 175), (197, 130, 177), + (184, 136, 170), (185, 99, 161), (208, 89, 146), (194, 62, 127), + (192, 47, 84), (184, 46, 79), (177, 46, 74), (174, 52, 70), + (171, 59, 66), (148, 62, 77), (128, 53, 81), (116, 67, 89), + (120, 67, 108), (155, 56, 134), (171, 52, 131), (188, 49, 129), + (202, 37, 140), (222, 36, 154), (232, 41, 165), (243, 43, 167), + (245, 66, 138), (247, 70, 140), (250, 74, 143), (242, 75, 146), + (235, 77, 150), (238, 81, 173), (224, 64, 178), (216, 77, 168), + (217, 65, 161), (195, 42, 130), (188, 36, 124), (181, 31, 118), + (174, 34, 111), (170, 52, 118), (176, 71, 99), (181, 71, 112), + (220, 56, 105), (227, 44, 99), (235, 33, 94), (244, 26, 84), + (235, 9, 59), (221, 34, 42), (209, 41, 48), (188, 87, 42), + (176, 92, 71), (114, 103, 105), (101, 107, 116), (88, 112, 127), + (47, 127, 122), (45, 155, 105), (24, 162, 83), (28, 174, 47), + (43, 166, 23), (51, 168, 26), (59, 171, 29), (88, 161, 15), + (97, 168, 45), (127, 163, 28), (137, 163, 70), (169, 167, 68), + (181, 171, 85), (190, 169, 90), (201, 171, 102), (191, 164, 111), + (191, 156, 130), (185, 143, 123), (200, 140, 142), (201, 122, 131), + (234, 117, 142), (235, 114, 145), (236, 111, 149), (247, 98, 130), + (248, 90, 138), (247, 74, 116), (242, 63, 122), (236, 63, 115), + (239, 49, 124), (226, 34, 126), (219, 23, 125), (223, 17, 107), + (214, 26, 87), (225, 42, 75), (214, 66, 72), (189, 102, 85), + (149, 117, 91), (104, 134, 113), (83, 153, 103), (54, 158, 98), + (68, 173, 79), (63, 182, 61), (67, 169, 67), (54, 165, 69), + (30, 143, 76), (27, 153, 98), (22, 152, 100), (43, 158, 122), + (84, 160, 134), (100, 151, 138), (146, 136, 140), (146, 142, 136), + (167, 140, 132), (167, 145, 123), (188, 159, 118), (211, 152, 120), + (225, 151, 117), (248, 138, 121), (247, 107, 97), (252, 88, 82), + (246, 70, 58), (241, 52, 41), (235, 48, 45), (231, 38, 53), + (232, 24, 84), (236, 32, 105), (231, 38, 134), (237, 54, 137), + (226, 58, 142), (233, 52, 140), (212, 40, 159), (217, 18, 168), + (208, 12, 169), (213, 15, 162), (226, 25, 150), (232, 47, 135), + (233, 62, 130), (193, 77, 117), (154, 73, 90), (90, 71, 66), + (46, 61, 57), (22, 49, 44), (10, 59, 58), (27, 71, 60), + (50, 92, 67), (75, 107, 81), (107, 100, 94), (118, 90, 93), + (117, 49, 95), (122, 47, 78), (108, 35, 67), (78, 44, 58) + ), + +// 620 Produce_Department +((153, 25, 65), (184, 50, 53), (193, 61, 57), (202, 73, 62), + (201, 89, 83), (201, 106, 105), (199, 114, 105), (198, 123, 105), + (192, 136, 85), (183, 142, 98), (175, 149, 111), (154, 148, 112), + (133, 148, 114), (113, 135, 99), (93, 123, 85), (86, 118, 84), + (80, 114, 83), (41, 95, 78), (26, 80, 76), (12, 65, 75), + (14, 51, 63), (17, 38, 52), (21, 32, 45), (26, 27, 38), + (48, 13, 18), (64, 10, 17), (81, 8, 16), (92, 7, 15), + (103, 7, 14), (106, 8, 12), (110, 10, 11), (116, 12, 11), + (123, 14, 14), (118, 13, 25), (110, 13, 29), (103, 13, 34), + (103, 15, 31), (103, 17, 28), (103, 17, 27), (104, 18, 26), + (111, 16, 30), (118, 16, 27), (126, 17, 24), (130, 26, 20), + (134, 35, 17), (133, 39, 19), (133, 43, 21), (128, 52, 31), + (123, 58, 43), (104, 63, 56), (94, 66, 61), (84, 70, 67), + (81, 72, 76), (78, 74, 85), (77, 74, 88), (76, 75, 91), + (66, 71, 98), (63, 70, 109), (60, 70, 120), (63, 72, 124), + (66, 75, 129), (65, 79, 127), (65, 83, 125), (66, 84, 118), + (70, 87, 112), (86, 89, 98), (85, 96, 92), (84, 103, 86), + (84, 107, 82), (84, 111, 79), (84, 123, 68), (86, 123, 59), + (60, 126, 63), (45, 128, 62), (31, 131, 62), (28, 126, 54), + (25, 121, 47), (26, 118, 46), (28, 115, 45), (26, 115, 41), + (26, 119, 41), (24, 125, 43), (29, 129, 55), (34, 133, 67), + (37, 133, 77), (40, 134, 88), (46, 141, 112), (52, 145, 121), + (52, 154, 118), (51, 138, 121), (51, 123, 125), (56, 115, 125), + (62, 107, 126), (68, 104, 122), (74, 103, 106), (75, 103, 89), + (78, 95, 90), (92, 106, 127), (94, 109, 138), (97, 112, 150), + (96, 109, 152), (95, 106, 155), (85, 105, 167), (78, 112, 182), + (75, 107, 192), (73, 86, 175), (71, 66, 158), (71, 59, 146), + (71, 52, 135), (80, 42, 119), (93, 45, 99), (110, 52, 78), + (125, 57, 64), (137, 68, 46), (138, 75, 48), (139, 83, 50), + (143, 104, 50), (145, 126, 66), (157, 142, 86), (158, 156, 110), + (145, 179, 147), (134, 187, 159), (124, 196, 171), (124, 193, 179), + (124, 190, 188), (116, 181, 199), (113, 168, 201), (99, 154, 194), + (86, 141, 180), (74, 99, 164), (72, 89, 157), (71, 79, 150), + (68, 62, 136), (62, 53, 113), (69, 52, 94), (71, 52, 74), + (77, 55, 42), (81, 54, 31), (86, 54, 21), (91, 54, 17), + (97, 54, 13), (112, 55, 11), (125, 55, 9), (134, 51, 11), + (146, 40, 13), (162, 16, 14), (161, 14, 15), (161, 13, 16), + (155, 15, 19), (150, 19, 25), (144, 21, 26), (140, 16, 32), + (121, 16, 44), (115, 18, 47), (110, 21, 51), (98, 31, 55), + (90, 41, 61), (85, 57, 68), (83, 73, 65), (82, 84, 60), + (82, 87, 58), (88, 85, 61), (91, 87, 58), (95, 89, 56), + (97, 94, 43), (99, 92, 37), (99, 83, 33), (100, 67, 40), + (101, 44, 45), (99, 45, 45), (98, 47, 46), (91, 52, 49), + (86, 51, 56), (90, 44, 61), (93, 36, 63), (100, 35, 59), + (109, 45, 58), (116, 50, 58), (123, 45, 57), (129, 38, 57), + (129, 29, 55), (126, 33, 55), (127, 40, 58), (121, 42, 63), + (114, 35, 78), (110, 36, 82), (106, 37, 87), (105, 37, 97), + (100, 38, 103), (100, 39, 106), (97, 34, 108), (89, 37, 106), + (87, 35, 106), (80, 33, 101), (73, 33, 92), (67, 26, 82), + (52, 22, 72), (44, 19, 66), (35, 18, 62), (31, 26, 59), + (34, 37, 59), (34, 46, 61), (31, 52, 68), (28, 56, 76), + (26, 64, 81), (29, 78, 85), (36, 94, 87), (37, 101, 89), + (35, 102, 86), (35, 92, 78), (35, 82, 65), (40, 78, 52), + (43, 75, 42), (42, 76, 33), (42, 69, 25), (43, 55, 20), + (40, 41, 16), (36, 34, 18), (32, 36, 28), (29, 43, 35), + (30, 48, 45), (29, 50, 56), (24, 51, 63), (22, 48, 79), + (23, 48, 89), (33, 49, 96), (46, 56, 103), (44, 59, 92), + (39, 54, 83), (31, 47, 74), (26, 38, 63), (36, 39, 60), + (38, 38, 46), (34, 36, 34), (26, 35, 25), (13, 31, 19), + (9, 35, 20), (11, 42, 16), (14, 46, 17), (15, 52, 19), + (13, 59, 29), (10, 67, 39), (9, 75, 39), (9, 79, 38), + (11, 81, 33), (9, 84, 37), (7, 85, 47), (14, 82, 55), + (20, 79, 63), (32, 68, 65), (45, 58, 64), (57, 50, 67), + (78, 42, 65), (98, 37, 65), (121, 26, 66), (141, 21, 61) + ), + +// 621 Purple +((65, 56, 83), (69, 65, 87), (70, 68, 86), (71, 71, 86), + (73, 76, 86), (76, 82, 87), (72, 77, 84), (69, 73, 81), + (64, 71, 76), (67, 73, 79), (70, 75, 83), (80, 80, 86), + (90, 86, 90), (97, 87, 96), (104, 88, 103), (106, 87, 106), + (109, 87, 109), (113, 82, 119), (112, 79, 119), (112, 76, 119), + (110, 68, 118), (109, 60, 118), (107, 54, 118), (106, 48, 118), + (101, 32, 116), (97, 29, 117), (93, 27, 119), (86, 22, 118), + (80, 18, 118), (75, 17, 119), (71, 16, 120), (65, 14, 122), + (64, 10, 126), (66, 12, 134), (72, 12, 137), (78, 12, 140), + (82, 16, 142), (87, 21, 145), (90, 23, 145), (94, 26, 146), + (106, 48, 145), (116, 57, 149), (127, 66, 154), (131, 65, 155), + (136, 64, 156), (138, 60, 155), (140, 57, 154), (135, 51, 148), + (135, 47, 139), (123, 48, 129), (114, 44, 126), (105, 41, 123), + (95, 30, 116), (86, 19, 110), (78, 12, 101), (71, 6, 93), + (52, 0, 71), (46, 0, 65), (40, 0, 60), (39, 0, 59), + (38, 0, 59), (37, 0, 55), (36, 0, 52), (36, 0, 50), + (35, 0, 51), (37, 0, 57), (38, 0, 63), (40, 0, 69), + (41, 0, 70), (42, 0, 72), (42, 0, 75), (41, 3, 79), + (44, 6, 88), (50, 6, 95), (57, 6, 102), (63, 11, 108), + (70, 16, 114), (71, 20, 115), (72, 24, 117), (74, 26, 119), + (73, 31, 120), (78, 36, 120), (85, 37, 120), (92, 38, 120), + (95, 39, 119), (98, 41, 119), (103, 42, 116), (102, 46, 114), + (96, 43, 105), (94, 35, 100), (92, 28, 95), (91, 25, 91), + (90, 22, 88), (91, 17, 83), (91, 16, 76), (90, 17, 70), + (87, 19, 65), (83, 26, 58), (82, 31, 54), (81, 36, 51), + (80, 37, 49), (80, 39, 48), (78, 43, 44), (73, 49, 43), + (70, 56, 37), (70, 58, 36), (71, 60, 36), (71, 61, 38), + (72, 63, 40), (71, 64, 46), (62, 66, 52), (56, 62, 62), + (50, 53, 64), (46, 35, 65), (47, 32, 66), (49, 30, 68), + (56, 27, 72), (62, 25, 81), (70, 26, 100), (80, 22, 113), + (100, 17, 135), (109, 17, 140), (118, 18, 146), (121, 17, 146), + (125, 16, 147), (137, 19, 152), (145, 20, 158), (154, 16, 164), + (166, 16, 173), (170, 10, 181), (167, 8, 178), (164, 6, 175), + (159, 5, 164), (148, 4, 152), (138, 0, 140), (130, 0, 130), + (119, 0, 119), (115, 0, 116), (112, 0, 114), (110, 0, 111), + (108, 0, 108), (103, 0, 101), (100, 0, 96), (100, 0, 93), + (98, 3, 92), (101, 19, 91), (103, 23, 92), (106, 28, 93), + (109, 38, 95), (114, 47, 102), (117, 53, 104), (118, 58, 108), + (115, 64, 109), (115, 65, 108), (115, 66, 107), (114, 72, 107), + (118, 73, 107), (123, 71, 109), (126, 68, 112), (125, 62, 116), + (120, 54, 116), (109, 35, 112), (106, 31, 110), (103, 28, 109), + (101, 20, 109), (101, 14, 108), (101, 8, 110), (100, 8, 109), + (94, 12, 105), (90, 14, 104), (87, 17, 103), (80, 21, 101), + (76, 27, 97), (74, 31, 100), (75, 36, 100), (74, 42, 101), + (72, 49, 104), (73, 54, 105), (71, 57, 104), (69, 58, 102), + (69, 58, 101), (70, 54, 100), (71, 49, 97), (69, 44, 96), + (66, 32, 94), (64, 28, 92), (63, 25, 91), (60, 20, 86), + (59, 17, 81), (59, 14, 78), (62, 10, 74), (66, 9, 71), + (70, 9, 70), (71, 9, 69), (71, 14, 66), (72, 19, 65), + (71, 27, 68), (70, 35, 69), (71, 42, 68), (74, 49, 70), + (75, 51, 76), (76, 57, 80), (78, 64, 85), (81, 70, 91), + (82, 78, 96), (83, 86, 100), (87, 96, 103), (91, 103, 114), + (92, 107, 118), (94, 118, 122), (98, 125, 125), (107, 126, 135), + (117, 137, 144), (127, 141, 147), (137, 146, 157), (142, 139, 163), + (145, 137, 166), (144, 132, 161), (142, 118, 161), (141, 110, 156), + (139, 100, 149), (139, 91, 147), (132, 79, 145), (128, 66, 141), + (117, 58, 134), (104, 44, 123), (94, 35, 109), (84, 31, 96), + (78, 28, 85), (69, 27, 73), (64, 25, 60), (58, 26, 50), + (51, 27, 41), (47, 31, 38), (43, 34, 35), (43, 38, 32), + (41, 43, 30), (43, 44, 29), (44, 46, 29), (48, 46, 30), + (49, 43, 31), (48, 40, 36), (50, 37, 38), (50, 36, 46), + (51, 34, 52), (51, 35, 58), (53, 38, 62), (56, 43, 65), + (58, 48, 68), (58, 47, 70), (69, 59, 80), (76, 64, 88), + (80, 65, 91), (79, 66, 92), (79, 66, 93), (79, 69, 93) + ), + +// 622 Queen_Anne +((128, 126, 186), (127, 126, 170), (127, 121, 154), (128, 117, 139), + (119, 109, 117), (111, 102, 96), (105, 97, 86), (100, 92, 77), + (74, 73, 39), (62, 66, 24), (51, 59, 9), (44, 54, 7), + (37, 50, 5), (32, 47, 6), (28, 44, 8), (27, 42, 8), + (27, 40, 8), (24, 34, 10), (22, 30, 13), (20, 27, 17), + (22, 27, 22), (25, 27, 28), (29, 29, 28), (33, 32, 29), + (36, 37, 40), (43, 40, 54), (50, 44, 68), (55, 50, 78), + (61, 57, 89), (61, 57, 91), (61, 58, 94), (62, 59, 99), + (59, 57, 97), (54, 57, 81), (54, 57, 69), (54, 58, 58), + (60, 59, 55), (66, 61, 53), (71, 65, 59), (76, 69, 66), + (95, 93, 94), (99, 95, 101), (104, 97, 108), (96, 96, 101), + (89, 95, 95), (85, 94, 91), (81, 93, 87), (70, 84, 74), + (57, 69, 56), (40, 53, 32), (36, 49, 29), (33, 46, 27), + (31, 42, 28), (29, 39, 29), (31, 40, 30), (34, 41, 32), + (38, 41, 47), (42, 45, 50), (47, 50, 54), (51, 55, 64), + (56, 60, 74), (61, 64, 78), (67, 68, 82), (77, 78, 86), + (79, 86, 88), (83, 92, 89), (83, 92, 85), (83, 93, 81), + (81, 93, 74), (79, 93, 67), (79, 93, 65), (79, 91, 68), + (80, 86, 84), (89, 91, 97), (98, 96, 111), (105, 101, 131), + (113, 106, 151), (117, 107, 159), (122, 109, 167), (132, 117, 177), + (135, 124, 185), (148, 136, 204), (157, 144, 207), (167, 153, 210), + (166, 155, 212), (166, 157, 214), (169, 158, 221), (172, 156, 220), + (171, 155, 215), (169, 154, 212), (167, 154, 209), (164, 153, 201), + (162, 153, 194), (166, 151, 178), (171, 154, 167), (175, 156, 172), + (167, 157, 173), (152, 139, 156), (144, 133, 156), (136, 127, 156), + (132, 122, 158), (129, 118, 161), (124, 111, 156), (123, 109, 147), + (133, 128, 140), (134, 125, 130), (135, 123, 120), (129, 120, 113), + (123, 118, 107), (107, 114, 100), (98, 105, 87), (82, 88, 68), + (65, 71, 46), (35, 47, 27), (32, 45, 25), (30, 43, 24), + (28, 40, 21), (25, 37, 18), (23, 34, 16), (22, 31, 17), + (20, 31, 12), (26, 34, 17), (33, 38, 23), (39, 39, 27), + (46, 41, 32), (51, 46, 39), (45, 47, 28), (50, 54, 37), + (60, 58, 46), (58, 59, 58), (56, 60, 63), (55, 61, 68), + (60, 65, 80), (62, 68, 85), (63, 67, 86), (65, 68, 86), + (69, 71, 80), (62, 66, 65), (56, 61, 50), (52, 58, 42), + (48, 55, 35), (40, 50, 23), (34, 44, 17), (28, 40, 15), + (25, 37, 14), (21, 35, 12), (21, 36, 11), (21, 37, 11), + (22, 38, 11), (22, 38, 12), (22, 38, 11), (24, 39, 13), + (27, 42, 15), (26, 42, 15), (26, 43, 15), (25, 41, 16), + (26, 40, 17), (25, 37, 17), (23, 37, 17), (19, 34, 16), + (17, 32, 13), (18, 31, 8), (18, 32, 7), (18, 34, 6), + (20, 36, 6), (23, 40, 7), (27, 44, 11), (31, 51, 12), + (37, 52, 18), (36, 51, 19), (35, 51, 21), (33, 50, 21), + (31, 48, 21), (29, 42, 19), (24, 37, 16), (19, 33, 13), + (15, 29, 10), (12, 22, 9), (11, 18, 8), (12, 19, 11), + (17, 23, 13), (24, 26, 18), (31, 29, 23), (38, 39, 33), + (59, 64, 53), (62, 66, 55), (66, 68, 58), (67, 74, 56), + (67, 78, 56), (66, 81, 56), (64, 77, 56), (57, 72, 48), + (53, 67, 40), (49, 64, 34), (49, 61, 32), (49, 60, 33), + (52, 61, 37), (60, 65, 48), (70, 75, 64), (85, 89, 85), + (102, 106, 107), (123, 125, 136), (137, 136, 164), (143, 142, 186), + (144, 143, 198), (150, 149, 206), (148, 145, 202), (134, 132, 185), + (111, 113, 157), (94, 98, 126), (81, 89, 95), (74, 87, 71), + (71, 87, 51), (81, 93, 37), (96, 102, 29), (108, 108, 32), + (106, 110, 43), (106, 108, 57), (111, 111, 68), (115, 105, 81), + (101, 94, 92), (83, 79, 94), (64, 69, 88), (54, 60, 82), + (44, 51, 78), (43, 49, 70), (40, 47, 58), (39, 47, 46), + (35, 45, 42), (38, 48, 46), (44, 51, 58), (51, 58, 73), + (58, 62, 88), (65, 70, 101), (76, 75, 118), (87, 89, 140), + (101, 99, 158), (109, 106, 166), (115, 108, 167), (114, 112, 164), + (115, 114, 161), (111, 110, 153), (108, 101, 145), (100, 95, 132), + (95, 94, 129), (91, 92, 129), (93, 92, 137), (97, 91, 144), + (108, 98, 159), (117, 105, 176), (124, 116, 191), (124, 119, 200), + (126, 119, 206), (128, 118, 206), (132, 122, 201), (132, 126, 193) + ), + +// 623 Quiet +((89, 51, 90), (95, 51, 100), (96, 52, 108), (98, 54, 116), + (86, 49, 116), (75, 44, 116), (67, 43, 116), (60, 43, 117), + (44, 49, 121), (41, 48, 121), (39, 48, 121), (40, 48, 124), + (42, 49, 127), (45, 45, 124), (49, 41, 122), (51, 38, 121), + (53, 36, 120), (53, 32, 118), (51, 30, 109), (49, 28, 101), + (43, 24, 86), (37, 21, 71), (32, 18, 63), (28, 16, 56), + (18, 10, 29), (11, 6, 18), (5, 3, 7), (5, 3, 7), + (6, 3, 7), (10, 4, 11), (14, 6, 16), (22, 12, 29), + (25, 15, 41), (48, 29, 76), (53, 45, 92), (58, 61, 108), + (58, 64, 111), (59, 68, 115), (62, 67, 116), (66, 66, 117), + (75, 78, 118), (86, 70, 112), (98, 62, 106), (108, 58, 102), + (119, 54, 99), (122, 54, 99), (125, 55, 99), (128, 55, 96), + (129, 51, 94), (118, 47, 82), (112, 43, 79), (106, 40, 76), + (102, 38, 77), (98, 37, 78), (94, 35, 78), (91, 34, 79), + (77, 32, 86), (71, 32, 91), (66, 32, 96), (63, 32, 98), + (61, 32, 100), (61, 32, 100), (61, 32, 101), (62, 32, 100), + (64, 32, 97), (69, 32, 90), (66, 31, 88), (63, 30, 86), + (60, 29, 86), (58, 29, 87), (54, 28, 89), (53, 28, 88), + (51, 28, 88), (53, 28, 86), (56, 29, 85), (63, 29, 78), + (71, 30, 71), (73, 30, 69), (76, 31, 67), (81, 31, 64), + (84, 31, 63), (84, 33, 71), (79, 33, 79), (74, 33, 87), + (71, 32, 90), (69, 32, 94), (62, 31, 100), (54, 29, 102), + (46, 26, 91), (44, 24, 81), (43, 22, 72), (40, 21, 65), + (38, 21, 58), (30, 16, 43), (22, 13, 30), (21, 9, 24), + (17, 9, 17), (11, 7, 19), (16, 8, 25), (22, 10, 32), + (26, 12, 38), (30, 15, 45), (39, 19, 57), (50, 24, 69), + (63, 29, 83), (65, 30, 86), (68, 31, 89), (68, 31, 89), + (68, 32, 89), (69, 32, 90), (68, 32, 90), (68, 32, 90), + (69, 33, 90), (72, 33, 95), (72, 33, 98), (73, 33, 101), + (71, 35, 107), (68, 35, 111), (67, 33, 118), (67, 32, 123), + (60, 34, 125), (63, 33, 121), (67, 33, 117), (70, 33, 114), + (73, 34, 111), (81, 37, 106), (91, 39, 99), (102, 45, 94), + (107, 47, 89), (104, 49, 80), (102, 49, 79), (100, 49, 78), + (93, 43, 75), (80, 42, 73), (69, 37, 68), (59, 32, 65), + (50, 23, 62), (50, 23, 62), (50, 23, 63), (50, 23, 64), + (51, 23, 65), (53, 24, 67), (52, 24, 66), (52, 24, 64), + (50, 23, 63), (47, 21, 58), (43, 20, 53), (40, 20, 49), + (31, 16, 37), (23, 12, 27), (19, 9, 23), (16, 8, 17), + (18, 9, 15), (22, 10, 17), (26, 11, 20), (36, 13, 25), + (52, 19, 34), (66, 24, 48), (79, 29, 60), (86, 31, 68), + (91, 34, 75), (83, 44, 93), (79, 47, 96), (75, 51, 100), + (67, 56, 105), (58, 56, 105), (53, 55, 107), (51, 57, 106), + (53, 54, 101), (54, 49, 99), (56, 45, 97), (61, 38, 89), + (68, 33, 83), (73, 31, 78), (77, 33, 74), (78, 35, 71), + (79, 36, 72), (79, 34, 76), (81, 36, 78), (82, 38, 79), + (80, 40, 83), (76, 37, 89), (73, 35, 94), (73, 33, 93), + (68, 31, 88), (66, 30, 85), (64, 29, 83), (59, 27, 77), + (55, 25, 71), (51, 23, 65), (46, 21, 60), (43, 20, 55), + (41, 19, 52), (41, 18, 52), (43, 20, 55), (46, 22, 61), + (48, 24, 69), (48, 24, 76), (49, 25, 83), (50, 25, 85), + (52, 27, 86), (51, 27, 85), (49, 26, 83), (48, 25, 79), + (50, 26, 76), (54, 26, 74), (58, 27, 74), (58, 28, 75), + (61, 29, 79), (65, 31, 85), (69, 32, 90), (70, 33, 93), + (71, 33, 97), (69, 34, 102), (67, 33, 107), (62, 32, 109), + (62, 32, 112), (59, 32, 114), (60, 34, 115), (59, 33, 114), + (60, 33, 110), (61, 32, 107), (65, 34, 104), (69, 34, 100), + (72, 35, 96), (73, 34, 95), (73, 33, 95), (74, 33, 95), + (77, 34, 95), (85, 39, 97), (98, 46, 98), (112, 55, 99), + (129, 58, 95), (149, 68, 95), (165, 73, 95), (172, 83, 102), + (173, 81, 98), (179, 85, 95), (177, 80, 89), (166, 75, 94), + (144, 64, 96), (127, 58, 97), (114, 52, 92), (106, 46, 91), + (94, 39, 90), (85, 33, 87), (78, 30, 82), (73, 28, 77), + (65, 26, 73), (60, 25, 66), (58, 23, 60), (56, 21, 56), + (56, 24, 56), (52, 25, 56), (63, 34, 69), (71, 41, 78) + ), + +// 624 Rainbow_Sprinkles +((30, 20, 51), (12, 37, 59), (12, 65, 83), (12, 93, 107), + (25, 110, 120), (39, 127, 133), (46, 142, 144), (53, 158, 155), + (77, 135, 150), (84, 133, 151), (91, 132, 153), (95, 124, 148), + (100, 116, 144), (117, 120, 146), (135, 124, 149), (146, 128, 154), + (157, 132, 159), (159, 138, 141), (171, 144, 141), (184, 150, 141), + (190, 163, 145), (197, 176, 149), (201, 173, 146), (206, 170, 144), + (224, 178, 140), (225, 146, 118), (226, 114, 97), (211, 94, 89), + (197, 74, 82), (188, 65, 79), (179, 56, 76), (152, 59, 107), + (147, 64, 143), (72, 50, 111), (51, 46, 101), (30, 42, 92), + (63, 61, 96), (97, 81, 101), (105, 86, 98), (113, 91, 95), + (179, 56, 60), (189, 47, 57), (199, 38, 54), (208, 29, 44), + (218, 21, 34), (216, 30, 40), (214, 39, 47), (228, 48, 48), + (196, 51, 60), (184, 101, 88), (172, 109, 92), (161, 118, 96), + (177, 137, 99), (193, 157, 102), (189, 158, 102), (186, 160, 102), + (161, 139, 112), (159, 147, 118), (157, 156, 125), (171, 154, 127), + (186, 152, 130), (200, 161, 131), (214, 170, 133), (233, 174, 128), + (240, 182, 127), (243, 208, 124), (245, 209, 122), (247, 211, 120), + (241, 208, 121), (236, 206, 122), (227, 189, 127), (218, 172, 123), + (182, 137, 126), (161, 125, 120), (141, 114, 114), (134, 114, 116), + (128, 114, 119), (128, 108, 121), (128, 103, 123), (127, 103, 130), + (137, 101, 130), (150, 85, 133), (150, 92, 135), (150, 100, 138), + (148, 108, 142), (146, 116, 147), (133, 122, 141), (118, 121, 139), + (134, 146, 135), (149, 134, 124), (165, 122, 113), (169, 116, 108), + (174, 110, 104), (177, 99, 105), (170, 92, 117), (166, 89, 124), + (170, 95, 130), (179, 118, 124), (192, 127, 110), (205, 137, 97), + (209, 143, 95), (214, 150, 94), (232, 144, 76), (236, 122, 56), + (245, 104, 44), (244, 96, 45), (244, 89, 46), (239, 85, 48), + (234, 81, 51), (225, 89, 62), (215, 89, 72), (202, 75, 79), + (191, 77, 88), (164, 70, 103), (166, 63, 114), (168, 56, 125), + (170, 41, 133), (167, 34, 136), (166, 44, 166), (157, 41, 163), + (153, 49, 137), (150, 58, 135), (148, 67, 133), (151, 71, 137), + (155, 76, 142), (160, 91, 146), (158, 110, 144), (157, 124, 146), + (167, 138, 134), (197, 171, 133), (198, 168, 128), (200, 165, 123), + (197, 156, 108), (194, 149, 100), (181, 142, 101), (163, 133, 107), + (128, 137, 130), (113, 125, 142), (99, 114, 155), (94, 109, 156), + (89, 104, 158), (125, 111, 163), (154, 125, 160), (148, 128, 134), + (179, 153, 128), (231, 206, 123), (235, 209, 118), (240, 213, 114), + (244, 207, 119), (249, 202, 125), (249, 181, 117), (250, 173, 118), + (246, 194, 142), (246, 194, 144), (246, 195, 146), (248, 199, 149), + (243, 183, 139), (247, 154, 117), (249, 127, 96), (247, 95, 75), + (251, 65, 52), (245, 49, 39), (242, 45, 35), (239, 41, 31), + (235, 57, 38), (224, 74, 51), (210, 68, 52), (202, 66, 54), + (181, 52, 52), (179, 51, 59), (178, 51, 66), (184, 37, 54), + (183, 35, 49), (187, 48, 57), (194, 54, 63), (210, 69, 62), + (223, 116, 84), (222, 154, 109), (229, 183, 126), (241, 203, 131), + (238, 208, 132), (237, 210, 136), (237, 200, 143), (221, 188, 147), + (195, 158, 143), (179, 151, 143), (164, 144, 144), (138, 139, 144), + (106, 109, 124), (73, 73, 103), (68, 60, 92), (96, 48, 91), + (97, 29, 65), (103, 14, 43), (154, 18, 36), (195, 29, 31), + (211, 48, 33), (234, 82, 44), (242, 109, 61), (241, 123, 73), + (246, 135, 75), (246, 148, 82), (244, 169, 93), (237, 188, 104), + (224, 192, 102), (217, 205, 89), (213, 217, 87), (216, 218, 89), + (220, 216, 85), (228, 207, 100), (241, 189, 111), (246, 156, 91), + (241, 116, 74), (234, 85, 65), (225, 54, 57), (208, 43, 65), + (191, 41, 71), (181, 42, 79), (173, 41, 91), (172, 41, 87), + (182, 54, 88), (198, 62, 91), (206, 61, 80), (210, 77, 83), + (216, 88, 88), (205, 83, 91), (192, 83, 97), (185, 84, 96), + (181, 78, 92), (181, 72, 86), (183, 74, 79), (192, 78, 78), + (204, 93, 85), (210, 112, 95), (213, 112, 97), (212, 116, 101), + (196, 115, 104), (178, 95, 96), (153, 96, 111), (133, 97, 136), + (103, 85, 118), (104, 89, 119), (95, 79, 124), (109, 77, 118), + (119, 75, 86), (151, 69, 69), (174, 56, 56), (193, 70, 51), + (205, 91, 50), (205, 90, 48), (168, 69, 44), (126, 56, 42), + (115, 46, 31), (72, 25, 32), (41, 29, 55), (38, 26, 49) + ), + +// 625 Rainforest +((112, 86, 55), (141, 98, 52), (151, 104, 50), (162, 110, 49), + (158, 108, 59), (154, 106, 69), (148, 109, 73), (142, 112, 77), + (86, 125, 100), (67, 110, 109), (49, 95, 118), (37, 90, 107), + (25, 85, 97), (23, 85, 81), (21, 85, 66), (22, 82, 63), + (23, 80, 60), (26, 75, 33), (26, 71, 21), (27, 67, 9), + (30, 65, 8), (33, 63, 7), (33, 62, 7), (34, 62, 7), + (42, 61, 12), (57, 68, 11), (72, 75, 10), (88, 78, 9), + (104, 82, 8), (110, 84, 7), (117, 86, 7), (125, 85, 15), + (133, 86, 27), (121, 84, 50), (120, 77, 49), (120, 70, 49), + (125, 65, 55), (130, 61, 61), (125, 62, 65), (121, 63, 69), + (127, 76, 63), (128, 79, 73), (129, 82, 83), (112, 94, 94), + (96, 106, 105), (91, 114, 103), (86, 123, 102), (75, 112, 110), + (55, 110, 119), (12, 97, 121), (6, 93, 111), (1, 89, 102), + (0, 84, 96), (0, 80, 91), (1, 76, 88), (3, 73, 85), + (34, 56, 67), (54, 54, 61), (75, 52, 55), (89, 47, 51), + (104, 43, 48), (111, 39, 42), (119, 36, 36), (134, 20, 25), + (144, 15, 12), (135, 12, 1), (128, 12, 0), (121, 13, 0), + (115, 15, 0), (110, 17, 0), (93, 26, 0), (78, 32, 1), + (53, 46, 17), (45, 49, 20), (37, 53, 24), (28, 53, 23), + (19, 54, 23), (16, 52, 24), (13, 51, 26), (12, 48, 27), + (12, 44, 27), (14, 39, 15), (17, 35, 10), (21, 31, 6), + (25, 29, 4), (30, 27, 3), (41, 26, 1), (42, 25, 1), + (38, 21, 8), (39, 21, 7), (41, 21, 7), (43, 20, 6), + (45, 19, 6), (48, 19, 10), (51, 16, 20), (40, 26, 27), + (33, 40, 38), (22, 70, 63), (23, 79, 81), (24, 89, 99), + (21, 98, 107), (18, 107, 116), (10, 121, 132), (1, 136, 142), + (5, 135, 154), (8, 130, 151), (11, 125, 149), (10, 123, 146), + (10, 122, 144), (6, 117, 141), (7, 108, 135), (9, 98, 129), + (11, 91, 123), (5, 92, 118), (3, 93, 118), (1, 94, 118), + (1, 94, 118), (12, 87, 109), (25, 81, 96), (35, 79, 85), + (44, 75, 66), (53, 68, 52), (63, 61, 39), (66, 57, 33), + (70, 54, 27), (79, 41, 15), (76, 40, 11), (68, 43, 8), + (62, 39, 11), (45, 41, 29), (41, 43, 35), (37, 45, 41), + (32, 52, 46), (40, 54, 44), (47, 52, 44), (67, 51, 40), + (107, 47, 43), (132, 48, 37), (157, 50, 31), (167, 49, 26), + (177, 49, 22), (195, 43, 12), (199, 30, 10), (198, 31, 9), + (187, 30, 11), (146, 38, 16), (134, 38, 16), (122, 39, 17), + (97, 41, 18), (74, 41, 25), (53, 41, 36), (37, 42, 46), + (19, 60, 61), (18, 63, 64), (18, 66, 67), (26, 67, 67), + (34, 64, 68), (48, 63, 64), (58, 69, 57), (58, 79, 51), + (66, 83, 38), (81, 79, 17), (84, 77, 12), (88, 76, 7), + (82, 81, 4), (80, 82, 1), (78, 85, 0), (81, 80, 0), + (99, 71, 0), (103, 68, 0), (108, 65, 0), (113, 65, 4), + (117, 57, 11), (108, 58, 25), (100, 63, 39), (90, 64, 49), + (76, 70, 62), (69, 64, 69), (49, 61, 80), (29, 61, 86), + (14, 62, 87), (1, 63, 87), (0, 57, 82), (0, 52, 80), + (0, 55, 69), (0, 57, 66), (0, 60, 63), (0, 56, 58), + (0, 52, 57), (0, 48, 57), (0, 50, 58), (2, 56, 53), + (6, 51, 47), (11, 46, 40), (12, 35, 37), (10, 32, 38), + (9, 37, 32), (10, 39, 28), (19, 51, 17), (24, 54, 16), + (27, 65, 26), (25, 81, 35), (22, 90, 41), (22, 103, 45), + (21, 106, 49), (22, 108, 61), (20, 116, 79), (19, 119, 89), + (15, 120, 100), (9, 115, 108), (5, 110, 114), (0, 108, 124), + (0, 108, 125), (0, 109, 123), (2, 103, 119), (13, 95, 110), + (26, 87, 102), (38, 83, 91), (40, 85, 78), (41, 89, 67), + (52, 84, 50), (68, 75, 38), (95, 66, 27), (108, 64, 19), + (119, 75, 14), (133, 76, 8), (147, 76, 8), (167, 72, 11), + (181, 75, 15), (196, 82, 18), (207, 79, 19), (218, 73, 22), + (215, 66, 27), (205, 71, 31), (198, 73, 32), (186, 69, 27), + (181, 62, 22), (172, 48, 18), (154, 48, 16), (139, 46, 14), + (121, 43, 12), (109, 43, 8), (103, 39, 5), (95, 37, 7), + (90, 33, 12), (82, 28, 14), (76, 27, 18), (72, 31, 19), + (65, 38, 26), (59, 45, 41), (53, 50, 49), (51, 53, 61), + (61, 48, 59), (71, 51, 54), (86, 58, 54), (101, 71, 48) + ), + +// 626 Rainy_Day_in_Spring +((74, 101, 72), (82, 108, 82), (78, 97, 75), (75, 87, 68), + (75, 83, 66), (75, 80, 64), (75, 75, 63), (75, 71, 62), + (65, 46, 45), (60, 37, 36), (55, 28, 28), (50, 24, 24), + (46, 21, 20), (41, 22, 18), (36, 24, 17), (35, 27, 17), + (34, 30, 18), (29, 36, 18), (25, 39, 18), (22, 42, 19), + (20, 47, 21), (18, 52, 24), (18, 54, 25), (19, 57, 26), + (24, 63, 30), (24, 64, 31), (24, 65, 33), (26, 64, 33), + (28, 64, 34), (30, 63, 34), (32, 63, 34), (37, 61, 36), + (41, 61, 39), (49, 68, 46), (58, 76, 54), (67, 84, 63), + (76, 84, 68), (85, 84, 74), (85, 82, 74), (86, 81, 74), + (86, 83, 75), (91, 80, 76), (96, 78, 77), (96, 69, 74), + (96, 61, 71), (96, 59, 70), (96, 57, 70), (101, 55, 71), + (105, 55, 73), (102, 58, 76), (98, 61, 76), (95, 64, 77), + (85, 67, 71), (76, 70, 66), (69, 71, 63), (63, 72, 61), + (48, 77, 55), (42, 84, 53), (37, 91, 52), (33, 97, 51), + (30, 104, 51), (31, 103, 51), (33, 102, 52), (35, 101, 53), + (40, 99, 54), (42, 98, 55), (44, 89, 53), (47, 81, 51), + (50, 77, 50), (54, 73, 50), (61, 67, 53), (68, 66, 57), + (86, 68, 71), (94, 75, 80), (102, 82, 89), (109, 96, 98), + (117, 111, 108), (119, 116, 112), (121, 122, 116), (121, 134, 122), + (119, 141, 124), (106, 141, 115), (98, 129, 104), (91, 118, 94), + (85, 110, 88), (80, 103, 82), (66, 85, 67), (55, 67, 53), + (39, 38, 28), (39, 30, 26), (39, 23, 24), (43, 23, 27), + (48, 23, 31), (59, 36, 41), (76, 52, 57), (96, 70, 77), + (116, 91, 100), (158, 125, 140), (177, 138, 158), (196, 152, 177), + (202, 157, 183), (208, 162, 189), (214, 167, 197), (218, 167, 196), + (214, 156, 188), (208, 147, 181), (202, 139, 175), (200, 134, 170), + (199, 130, 165), (191, 130, 160), (188, 129, 157), (190, 127, 157), + (187, 125, 156), (181, 114, 145), (178, 112, 143), (175, 111, 141), + (172, 108, 138), (170, 106, 137), (167, 99, 132), (159, 92, 124), + (138, 77, 103), (129, 71, 94), (120, 65, 86), (115, 62, 82), + (111, 60, 79), (103, 58, 72), (97, 56, 67), (91, 51, 60), + (85, 46, 56), (72, 39, 46), (69, 40, 44), (67, 41, 43), + (62, 43, 39), (60, 44, 39), (60, 44, 39), (59, 44, 40), + (62, 46, 41), (65, 48, 44), (69, 50, 47), (72, 50, 49), + (76, 51, 51), (86, 52, 59), (96, 54, 66), (103, 57, 72), + (112, 61, 79), (134, 73, 97), (140, 77, 102), (146, 81, 107), + (155, 90, 121), (164, 100, 130), (173, 112, 142), (178, 124, 152), + (180, 142, 163), (178, 145, 163), (176, 148, 163), (173, 147, 162), + (175, 149, 165), (174, 153, 166), (173, 155, 167), (169, 167, 166), + (159, 167, 159), (161, 161, 157), (162, 155, 155), (164, 149, 154), + (165, 148, 153), (157, 143, 145), (144, 135, 132), (135, 128, 124), + (119, 93, 102), (117, 86, 98), (115, 80, 94), (110, 74, 87), + (109, 75, 86), (112, 79, 91), (119, 87, 99), (130, 99, 113), + (144, 114, 130), (160, 132, 146), (173, 151, 160), (181, 166, 172), + (184, 179, 179), (186, 189, 185), (183, 193, 186), (176, 197, 181), + (152, 190, 160), (147, 187, 156), (142, 184, 152), (134, 174, 144), + (123, 166, 134), (110, 156, 121), (96, 143, 105), (84, 131, 95), + (80, 119, 88), (77, 113, 85), (76, 107, 81), (75, 97, 74), + (75, 90, 71), (80, 83, 71), (87, 80, 75), (97, 80, 81), + (109, 77, 85), (118, 74, 88), (124, 70, 90), (125, 67, 90), + (122, 66, 88), (116, 62, 81), (107, 58, 73), (94, 54, 63), + (79, 51, 54), (67, 49, 46), (56, 49, 40), (51, 50, 37), + (51, 52, 37), (54, 56, 42), (65, 61, 51), (78, 68, 61), + (97, 77, 77), (117, 86, 94), (135, 99, 112), (156, 111, 131), + (172, 121, 145), (188, 133, 161), (204, 144, 177), (213, 157, 190), + (223, 166, 201), (229, 174, 208), (233, 180, 215), (239, 189, 223), + (238, 199, 227), (238, 206, 229), (234, 211, 226), (231, 213, 223), + (231, 216, 225), (223, 222, 222), (213, 223, 216), (196, 220, 201), + (173, 210, 181), (156, 191, 162), (138, 172, 142), (124, 151, 124), + (109, 129, 106), (89, 109, 88), (72, 87, 70), (59, 66, 54), + (51, 50, 41), (49, 38, 34), (47, 33, 30), (44, 33, 30), + (46, 35, 33), (47, 40, 35), (55, 51, 43), (59, 58, 46), + (59, 64, 49), (59, 73, 52), (58, 75, 51), (66, 90, 62) + ), + +// 627 Rainy_Forset +((118, 126, 87), (157, 130, 79), (169, 125, 69), (182, 121, 59), + (188, 119, 51), (194, 117, 43), (201, 115, 41), (209, 113, 40), + (215, 77, 32), (191, 67, 26), (168, 57, 21), (155, 56, 21), + (143, 55, 22), (133, 54, 23), (124, 53, 25), (115, 53, 25), + (106, 53, 25), (77, 52, 25), (71, 51, 25), (66, 50, 25), + (60, 46, 25), (55, 42, 25), (52, 39, 24), (50, 36, 23), + (49, 33, 19), (47, 34, 19), (46, 35, 19), (50, 40, 24), + (55, 45, 30), (58, 48, 35), (62, 52, 40), (69, 59, 57), + (74, 74, 76), (94, 94, 103), (99, 97, 106), (104, 101, 109), + (113, 111, 115), (123, 121, 121), (130, 124, 123), (137, 127, 126), + (137, 121, 118), (132, 117, 107), (128, 113, 97), (127, 103, 90), + (126, 94, 83), (122, 90, 81), (118, 86, 80), (109, 76, 76), + (94, 67, 69), (74, 43, 42), (70, 38, 33), (67, 33, 25), + (66, 30, 22), (65, 28, 19), (65, 27, 18), (66, 26, 18), + (72, 30, 18), (76, 35, 19), (80, 40, 21), (86, 45, 22), + (93, 50, 23), (96, 53, 23), (99, 56, 23), (103, 57, 25), + (103, 60, 26), (106, 62, 28), (105, 59, 26), (104, 56, 25), + (101, 54, 25), (99, 53, 25), (94, 55, 23), (90, 55, 23), + (82, 57, 23), (79, 59, 24), (76, 62, 26), (72, 64, 27), + (69, 66, 28), (68, 66, 28), (67, 67, 28), (65, 66, 28), + (63, 62, 28), (63, 52, 26), (61, 49, 27), (60, 47, 29), + (58, 48, 32), (57, 50, 36), (56, 56, 49), (62, 69, 70), + (82, 111, 133), (100, 132, 157), (118, 154, 181), (127, 158, 185), + (137, 162, 189), (137, 158, 175), (140, 158, 172), (128, 161, 189), + (138, 155, 174), (144, 114, 111), (125, 88, 82), (106, 63, 53), + (98, 56, 47), (90, 50, 42), (84, 43, 32), (84, 39, 26), + (77, 36, 19), (71, 37, 18), (65, 38, 18), (61, 38, 18), + (57, 38, 18), (52, 38, 18), (46, 33, 18), (42, 35, 19), + (36, 35, 19), (32, 35, 21), (31, 33, 21), (30, 32, 22), + (35, 32, 22), (39, 32, 23), (46, 35, 23), (52, 36, 22), + (66, 36, 22), (75, 39, 22), (84, 42, 22), (89, 45, 22), + (94, 49, 22), (104, 57, 26), (117, 59, 26), (127, 62, 26), + (134, 63, 25), (137, 70, 30), (137, 72, 31), (138, 74, 33), + (143, 79, 39), (147, 82, 43), (148, 83, 46), (144, 82, 53), + (124, 89, 65), (115, 93, 67), (107, 97, 69), (105, 96, 69), + (104, 96, 69), (96, 90, 63), (83, 83, 59), (67, 73, 55), + (52, 65, 47), (40, 55, 38), (41, 55, 38), (43, 56, 38), + (49, 63, 39), (59, 74, 40), (63, 92, 50), (74, 106, 62), + (109, 121, 76), (124, 126, 70), (140, 131, 65), (164, 150, 62), + (191, 170, 60), (216, 175, 70), (238, 175, 87), (255, 168, 90), + (255, 165, 94), (245, 164, 94), (240, 163, 100), (235, 162, 107), + (215, 147, 114), (195, 134, 118), (168, 121, 111), (130, 100, 101), + (83, 66, 76), (80, 59, 69), (77, 53, 63), (79, 45, 47), + (80, 40, 38), (84, 39, 29), (93, 42, 25), (106, 49, 26), + (121, 57, 32), (133, 72, 36), (144, 90, 39), (162, 103, 35), + (171, 114, 33), (181, 114, 33), (188, 111, 38), (192, 117, 40), + (235, 124, 36), (235, 124, 39), (235, 124, 42), (231, 114, 50), + (209, 109, 62), (207, 94, 62), (208, 92, 63), (194, 94, 72), + (177, 97, 80), (150, 106, 97), (121, 101, 101), (101, 92, 96), + (84, 80, 90), (74, 69, 77), (73, 66, 73), (69, 66, 69), + (65, 62, 63), (59, 56, 57), (55, 49, 47), (57, 46, 40), + (62, 50, 35), (66, 56, 33), (72, 62, 35), (74, 69, 38), + (79, 76, 40), (80, 83, 45), (80, 90, 45), (82, 92, 45), + (86, 92, 42), (89, 90, 42), (93, 87, 42), (90, 89, 42), + (86, 89, 42), (87, 92, 39), (86, 94, 39), (89, 96, 40), + (86, 97, 42), (80, 97, 45), (80, 99, 45), (77, 97, 45), + (79, 94, 43), (77, 89, 45), (73, 83, 47), (70, 79, 49), + (67, 74, 56), (70, 69, 56), (72, 62, 59), (73, 56, 60), + (70, 57, 60), (69, 57, 65), (67, 59, 66), (69, 57, 65), + (70, 53, 63), (72, 50, 60), (72, 52, 60), (70, 56, 60), + (70, 63, 60), (73, 69, 62), (77, 73, 60), (82, 74, 60), + (83, 76, 59), (82, 83, 59), (86, 92, 62), (90, 100, 63), + (96, 107, 69), (92, 101, 72), (89, 94, 74), (90, 93, 79), + (90, 94, 83), (101, 106, 86), (103, 111, 90), (107, 118, 89) + ), + +// 628 Red_Light +((46, 21, 37), (45, 26, 32), (42, 24, 31), (39, 22, 31), + (32, 17, 33), (26, 12, 35), (23, 11, 38), (21, 11, 41), + (18, 13, 56), (15, 11, 61), (13, 9, 67), (9, 7, 67), + (6, 5, 68), (3, 3, 66), (0, 2, 64), (0, 4, 62), + (1, 6, 60), (6, 16, 54), (7, 17, 49), (8, 18, 45), + (7, 16, 38), (6, 14, 32), (6, 14, 28), (6, 14, 25), + (6, 16, 16), (7, 17, 14), (8, 18, 12), (7, 15, 12), + (6, 12, 13), (5, 9, 13), (5, 7, 13), (2, 2, 12), + (0, 0, 11), (0, 0, 7), (0, 0, 6), (1, 0, 6), + (4, 2, 6), (7, 4, 7), (11, 6, 7), (15, 8, 8), + (40, 15, 8), (54, 16, 9), (69, 17, 11), (78, 22, 17), + (88, 28, 23), (90, 30, 28), (93, 33, 33), (93, 39, 42), + (92, 43, 49), (92, 36, 57), (88, 32, 58), (84, 29, 59), + (75, 27, 63), (67, 26, 68), (59, 27, 70), (51, 28, 73), + (24, 18, 72), (13, 11, 67), (3, 4, 62), (1, 2, 54), + (0, 0, 47), (0, 0, 44), (0, 0, 41), (0, 0, 35), + (0, 0, 30), (3, 2, 22), (6, 5, 20), (9, 9, 19), + (11, 11, 19), (13, 13, 20), (17, 16, 22), (19, 19, 25), + (25, 24, 27), (27, 26, 28), (29, 29, 29), (29, 29, 32), + (29, 30, 35), (28, 29, 37), (28, 29, 40), (25, 27, 43), + (23, 24, 45), (22, 20, 40), (24, 17, 35), (27, 15, 31), + (31, 13, 29), (36, 11, 28), (46, 7, 24), (59, 4, 22), + (93, 1, 19), (109, 7, 16), (126, 14, 13), (133, 15, 12), + (140, 16, 12), (154, 17, 16), (164, 17, 18), (173, 17, 22), + (181, 13, 21), (185, 15, 21), (178, 16, 19), (171, 17, 17), + (162, 16, 17), (154, 16, 18), (136, 16, 24), (116, 12, 26), + (83, 2, 30), (73, 4, 27), (64, 6, 25), (62, 8, 24), + (60, 10, 23), (58, 17, 23), (55, 24, 22), (53, 29, 22), + (49, 31, 24), (48, 33, 30), (49, 33, 32), (51, 34, 35), + (66, 36, 34), (84, 38, 33), (103, 40, 30), (120, 40, 26), + (149, 31, 24), (156, 25, 24), (164, 20, 25), (171, 18, 25), + (178, 17, 25), (192, 17, 24), (206, 18, 18), (218, 16, 18), + (228, 13, 16), (222, 9, 13), (217, 8, 12), (212, 7, 11), + (197, 9, 12), (182, 15, 11), (169, 22, 14), (159, 28, 17), + (139, 48, 21), (123, 46, 19), (108, 44, 17), (100, 42, 17), + (92, 41, 17), (80, 41, 16), (73, 34, 16), (79, 38, 20), + (87, 42, 20), (101, 41, 14), (105, 38, 14), (109, 35, 15), + (111, 29, 15), (105, 19, 16), (103, 12, 21), (102, 10, 26), + (98, 15, 33), (98, 17, 35), (98, 19, 38), (100, 20, 44), + (102, 25, 52), (101, 32, 55), (100, 37, 54), (100, 38, 53), + (100, 38, 49), (105, 34, 39), (110, 32, 38), (116, 30, 37), + (129, 29, 36), (140, 29, 30), (150, 28, 24), (160, 23, 18), + (159, 18, 8), (157, 17, 8), (155, 17, 8), (151, 18, 12), + (143, 20, 13), (133, 23, 15), (123, 23, 16), (112, 20, 14), + (95, 16, 15), (79, 16, 17), (66, 19, 22), (55, 23, 25), + (46, 29, 27), (39, 35, 31), (38, 38, 32), (35, 38, 31), + (30, 33, 35), (30, 33, 37), (30, 33, 39), (34, 35, 43), + (40, 39, 49), (51, 44, 54), (63, 48, 59), (71, 53, 63), + (70, 50, 67), (66, 46, 69), (61, 39, 69), (52, 33, 68), + (47, 29, 65), (47, 23, 63), (50, 23, 57), (52, 20, 54), + (53, 16, 49), (51, 11, 43), (43, 6, 37), (34, 4, 31), + (27, 0, 26), (24, 0, 19), (23, 0, 14), (23, 0, 10), + (25, 0, 7), (25, 0, 5), (26, 0, 4), (25, 0, 5), + (21, 0, 5), (16, 0, 6), (11, 0, 6), (7, 0, 6), + (3, 0, 5), (1, 0, 5), (0, 0, 5), (1, 0, 4), + (2, 0, 5), (4, 0, 5), (5, 0, 5), (5, 0, 6), + (6, 1, 6), (5, 1, 5), (5, 1, 4), (7, 0, 4), + (11, 0, 4), (18, 1, 3), (25, 0, 4), (33, 0, 4), + (41, 1, 5), (47, 1, 4), (53, 1, 4), (56, 0, 3), + (62, 1, 2), (67, 1, 3), (70, 2, 5), (74, 5, 8), + (78, 8, 11), (81, 11, 14), (79, 14, 17), (78, 16, 21), + (79, 15, 26), (72, 14, 32), (66, 14, 36), (61, 15, 41), + (59, 21, 44), (58, 26, 46), (56, 28, 46), (58, 27, 45), + (56, 25, 43), (53, 22, 41), (48, 17, 40), (47, 17, 38) + ), + +// 629 Riddle +((50, 16, 8), (51, 15, 11), (47, 14, 12), (44, 14, 14), + (39, 16, 17), (34, 19, 20), (31, 18, 22), (29, 17, 25), + (23, 15, 29), (26, 19, 26), (30, 23, 24), (42, 27, 26), + (55, 31, 29), (72, 40, 38), (89, 49, 48), (99, 56, 50), + (109, 63, 53), (146, 92, 62), (164, 110, 80), (182, 129, 98), + (184, 139, 108), (186, 149, 119), (182, 147, 118), (179, 145, 117), + (163, 132, 109), (148, 119, 107), (133, 106, 106), (126, 92, 110), + (120, 78, 115), (122, 72, 119), (125, 66, 123), (122, 52, 124), + (123, 41, 131), (122, 29, 138), (118, 28, 134), (115, 28, 130), + (109, 26, 119), (103, 25, 108), (94, 25, 99), (86, 25, 90), + (56, 25, 46), (49, 25, 37), (42, 26, 29), (51, 25, 41), + (60, 24, 53), (69, 25, 64), (78, 27, 75), (90, 35, 97), + (99, 43, 116), (103, 54, 136), (100, 56, 137), (97, 59, 139), + (86, 67, 132), (75, 75, 125), (70, 80, 120), (65, 85, 115), + (53, 111, 102), (56, 116, 100), (59, 122, 99), (66, 133, 104), + (74, 145, 110), (74, 152, 116), (75, 160, 122), (81, 169, 125), + (86, 171, 120), (81, 153, 89), (66, 145, 76), (52, 138, 63), + (49, 133, 55), (47, 128, 48), (47, 114, 34), (53, 99, 22), + (55, 68, 13), (62, 59, 14), (70, 50, 15), (82, 52, 19), + (95, 54, 24), (101, 57, 31), (107, 60, 38), (118, 63, 57), + (131, 64, 79), (152, 82, 116), (158, 103, 130), (165, 124, 144), + (166, 129, 148), (168, 135, 152), (168, 138, 161), (157, 139, 150), + (128, 139, 115), (113, 133, 97), (99, 127, 79), (91, 121, 70), + (83, 116, 62), (72, 102, 47), (62, 93, 36), (55, 84, 35), + (60, 77, 36), (75, 74, 44), (84, 83, 52), (94, 92, 61), + (101, 97, 67), (108, 102, 74), (116, 114, 85), (123, 127, 97), + (143, 146, 122), (146, 152, 132), (150, 158, 142), (147, 161, 142), + (145, 165, 143), (139, 166, 139), (136, 166, 132), (132, 164, 121), + (131, 158, 114), (136, 150, 102), (139, 148, 100), (142, 146, 99), + (141, 150, 97), (138, 153, 98), (143, 156, 103), (151, 161, 115), + (170, 159, 145), (165, 158, 148), (160, 158, 152), (155, 158, 146), + (150, 158, 141), (136, 151, 128), (124, 141, 113), (109, 129, 100), + (96, 115, 86), (66, 93, 51), (58, 91, 45), (50, 90, 40), + (33, 83, 38), (21, 77, 43), (17, 62, 44), (17, 49, 43), + (20, 40, 48), (21, 38, 55), (23, 37, 62), (25, 35, 60), + (27, 34, 59), (31, 35, 54), (37, 43, 53), (47, 57, 66), + (61, 70, 85), (86, 94, 120), (92, 100, 123), (98, 107, 127), + (107, 120, 132), (122, 131, 139), (134, 139, 145), (141, 139, 149), + (137, 132, 131), (134, 131, 123), (132, 131, 116), (129, 135, 100), + (124, 139, 89), (118, 146, 85), (111, 149, 82), (106, 148, 80), + (106, 151, 80), (103, 153, 79), (101, 153, 81), (100, 153, 83), + (91, 141, 83), (83, 123, 85), (81, 104, 88), (74, 90, 90), + (67, 86, 95), (65, 84, 96), (63, 82, 97), (64, 73, 94), + (62, 65, 93), (61, 66, 88), (62, 74, 81), (64, 84, 77), + (70, 92, 72), (73, 96, 81), (75, 101, 89), (82, 100, 103), + (91, 101, 119), (104, 97, 129), (116, 94, 146), (126, 97, 162), + (159, 98, 196), (166, 98, 203), (173, 98, 211), (183, 96, 217), + (179, 92, 220), (173, 90, 215), (166, 90, 197), (146, 82, 175), + (128, 80, 150), (105, 69, 133), (82, 60, 118), (71, 60, 102), + (50, 47, 74), (34, 38, 45), (19, 25, 25), (8, 17, 11), + (13, 18, 9), (22, 20, 8), (30, 26, 7), (34, 25, 12), + (39, 35, 19), (45, 39, 31), (56, 39, 43), (63, 40, 48), + (61, 33, 50), (57, 32, 47), (49, 32, 46), (47, 30, 52), + (43, 28, 55), (36, 22, 56), (26, 15, 52), (20, 14, 40), + (16, 13, 33), (15, 15, 29), (16, 16, 26), (15, 13, 27), + (19, 13, 26), (27, 9, 23), (38, 11, 20), (52, 17, 16), + (63, 19, 27), (71, 31, 38), (78, 46, 49), (83, 60, 58), + (88, 78, 52), (96, 90, 57), (98, 103, 66), (101, 127, 78), + (103, 144, 89), (101, 163, 89), (104, 173, 86), (104, 172, 90), + (110, 176, 98), (118, 181, 107), (125, 186, 115), (134, 187, 116), + (135, 183, 118), (137, 175, 123), (135, 163, 129), (133, 149, 130), + (126, 130, 118), (111, 114, 97), (100, 100, 79), (85, 86, 66), + (77, 68, 62), (67, 49, 54), (56, 34, 39), (50, 26, 25), + (41, 25, 11), (42, 23, 7), (43, 21, 6), (46, 17, 7) + ), + +// 630 Riverside +((82, 104, 100), (90, 97, 108), (93, 92, 113), (96, 88, 118), + (92, 82, 119), (88, 77, 121), (84, 75, 121), (81, 74, 121), + (67, 70, 115), (66, 68, 111), (65, 67, 107), (66, 66, 103), + (68, 66, 100), (70, 65, 94), (72, 65, 89), (71, 64, 84), + (70, 64, 79), (68, 60, 62), (69, 56, 62), (70, 52, 62), + (73, 50, 67), (76, 48, 73), (77, 47, 77), (79, 47, 81), + (82, 48, 84), (82, 51, 82), (82, 54, 80), (79, 58, 80), + (77, 63, 80), (75, 63, 81), (73, 64, 83), (72, 66, 87), + (72, 63, 92), (78, 65, 101), (86, 69, 102), (94, 74, 104), + (97, 77, 105), (101, 81, 106), (103, 79, 105), (106, 78, 105), + (115, 78, 107), (122, 78, 108), (130, 79, 109), (131, 78, 107), + (132, 78, 106), (130, 76, 103), (128, 75, 100), (123, 74, 94), + (118, 75, 93), (115, 87, 101), (111, 96, 106), (108, 106, 111), + (102, 112, 118), (97, 118, 125), (96, 121, 130), (95, 124, 136), + (97, 135, 164), (101, 143, 180), (105, 151, 197), (109, 158, 204), + (113, 166, 211), (114, 166, 212), (116, 166, 214), (120, 162, 216), + (129, 156, 213), (143, 139, 213), (142, 133, 205), (142, 128, 198), + (140, 124, 191), (139, 120, 185), (132, 109, 175), (133, 101, 164), + (133, 82, 138), (131, 79, 127), (130, 76, 117), (125, 73, 105), + (120, 71, 93), (118, 71, 90), (116, 72, 87), (113, 75, 82), + (118, 78, 80), (128, 92, 83), (135, 100, 85), (142, 109, 87), + (147, 114, 86), (152, 119, 85), (159, 128, 85), (171, 137, 88), + (189, 145, 98), (190, 148, 113), (192, 152, 128), (191, 152, 134), + (191, 152, 141), (187, 150, 153), (182, 147, 165), (180, 141, 163), + (174, 130, 160), (159, 115, 158), (147, 107, 156), (135, 99, 154), + (128, 95, 153), (121, 91, 153), (113, 85, 144), (106, 76, 127), + (99, 68, 96), (98, 65, 83), (97, 62, 70), (97, 61, 66), + (98, 60, 62), (101, 59, 57), (105, 61, 58), (109, 67, 60), + (115, 73, 59), (131, 83, 65), (133, 85, 68), (136, 88, 71), + (142, 91, 74), (145, 90, 80), (144, 91, 86), (140, 91, 85), + (138, 91, 80), (132, 91, 79), (126, 91, 79), (124, 88, 80), + (122, 86, 81), (114, 79, 85), (103, 73, 86), (98, 66, 84), + (93, 59, 78), (86, 56, 68), (85, 56, 67), (85, 56, 67), + (86, 57, 70), (87, 58, 74), (95, 59, 82), (102, 59, 84), + (111, 63, 76), (110, 63, 72), (110, 63, 68), (107, 61, 65), + (104, 60, 63), (101, 58, 66), (101, 56, 69), (102, 59, 74), + (104, 60, 79), (115, 69, 91), (116, 72, 92), (118, 75, 94), + (117, 76, 101), (116, 75, 109), (114, 77, 117), (112, 83, 129), + (120, 97, 154), (124, 103, 160), (128, 110, 167), (134, 123, 176), + (139, 130, 180), (142, 139, 176), (142, 150, 173), (142, 158, 170), + (142, 166, 166), (142, 184, 162), (141, 183, 160), (141, 182, 159), + (137, 180, 154), (135, 177, 147), (135, 175, 138), (134, 171, 129), + (131, 165, 122), (129, 160, 121), (127, 156, 121), (117, 148, 122), + (107, 138, 126), (101, 134, 130), (96, 130, 134), (91, 127, 139), + (89, 125, 143), (89, 121, 143), (88, 118, 143), (86, 114, 145), + (84, 113, 149), (86, 117, 155), (86, 125, 157), (89, 132, 157), + (85, 133, 152), (84, 130, 149), (84, 128, 146), (79, 122, 137), + (77, 114, 134), (75, 109, 136), (79, 109, 139), (81, 110, 143), + (83, 111, 150), (88, 110, 156), (88, 109, 156), (88, 107, 155), + (84, 102, 156), (82, 96, 153), (80, 90, 148), (78, 85, 146), + (80, 78, 150), (81, 74, 149), (82, 71, 143), (84, 71, 139), + (84, 70, 132), (82, 70, 121), (78, 71, 113), (76, 73, 110), + (75, 81, 108), (74, 91, 106), (77, 103, 111), (84, 113, 122), + (92, 125, 131), (98, 132, 142), (102, 138, 157), (105, 144, 168), + (107, 152, 179), (106, 161, 186), (106, 165, 194), (106, 170, 195), + (106, 165, 196), (104, 156, 196), (101, 141, 191), (96, 126, 182), + (90, 116, 170), (83, 105, 158), (79, 98, 144), (76, 90, 129), + (74, 84, 115), (73, 76, 104), (72, 67, 88), (71, 61, 74), + (68, 57, 63), (69, 54, 53), (71, 53, 45), (75, 54, 41), + (80, 56, 41), (87, 56, 41), (93, 60, 42), (95, 65, 44), + (98, 73, 48), (102, 84, 51), (104, 93, 56), (104, 99, 59), + (103, 100, 62), (100, 105, 67), (94, 107, 71), (92, 113, 76), + (93, 121, 81), (96, 132, 86), (100, 138, 86), (103, 138, 84), + (103, 134, 86), (97, 125, 87), (91, 117, 88), (85, 106, 93) + ), + +// 631 Rose_Bush +((162, 149, 111), (153, 149, 103), (150, 125, 97), (148, 101, 92), + (145, 86, 90), (142, 72, 89), (139, 65, 87), (137, 58, 85), + (127, 31, 69), (120, 33, 65), (114, 35, 62), (113, 36, 62), + (113, 38, 63), (113, 39, 64), (113, 40, 65), (113, 40, 66), + (113, 40, 68), (118, 33, 73), (113, 33, 70), (109, 33, 67), + (109, 31, 64), (109, 30, 61), (109, 29, 60), (109, 29, 59), + (113, 34, 59), (118, 34, 62), (124, 35, 65), (122, 40, 63), + (121, 45, 61), (121, 45, 60), (121, 46, 59), (122, 46, 60), + (122, 46, 61), (133, 43, 72), (144, 36, 79), (155, 30, 86), + (159, 28, 89), (163, 27, 92), (161, 29, 91), (159, 32, 91), + (145, 46, 89), (138, 54, 93), (131, 62, 98), (132, 68, 107), + (134, 74, 117), (137, 76, 124), (141, 78, 132), (154, 79, 142), + (166, 86, 152), (185, 101, 162), (187, 111, 168), (190, 121, 175), + (191, 128, 181), (192, 136, 187), (184, 136, 191), (177, 137, 196), + (195, 128, 206), (203, 123, 204), (211, 118, 202), (215, 111, 199), + (219, 105, 197), (219, 103, 194), (219, 102, 192), (220, 96, 184), + (220, 84, 173), (215, 60, 154), (212, 48, 143), (209, 36, 133), + (207, 30, 129), (206, 25, 125), (200, 21, 118), (192, 23, 111), + (182, 33, 100), (179, 39, 98), (177, 46, 97), (175, 54, 97), + (174, 62, 97), (176, 61, 96), (179, 60, 96), (178, 60, 98), + (177, 61, 99), (174, 62, 104), (175, 66, 108), (176, 70, 113), + (176, 72, 117), (177, 74, 122), (178, 83, 132), (186, 84, 138), + (198, 78, 153), (201, 69, 154), (205, 60, 155), (205, 54, 153), + (206, 49, 151), (207, 38, 145), (207, 28, 139), (207, 24, 131), + (206, 21, 125), (188, 28, 114), (180, 31, 110), (173, 34, 106), + (171, 35, 104), (169, 37, 102), (166, 42, 107), (165, 47, 112), + (174, 60, 122), (175, 68, 128), (176, 76, 135), (176, 79, 136), + (177, 82, 137), (177, 85, 138), (177, 89, 138), (175, 94, 146), + (173, 103, 158), (185, 124, 185), (190, 130, 190), (196, 136, 196), + (208, 144, 204), (217, 153, 201), (225, 158, 184), (228, 159, 174), + (219, 148, 148), (208, 148, 137), (197, 148, 127), (191, 151, 121), + (186, 155, 116), (176, 163, 109), (161, 168, 101), (146, 167, 90), + (135, 164, 82), (119, 148, 69), (114, 141, 65), (110, 135, 61), + (96, 123, 51), (84, 109, 44), (71, 96, 38), (60, 84, 30), + (45, 67, 19), (48, 61, 22), (51, 55, 25), (56, 48, 27), + (61, 42, 30), (69, 33, 37), (79, 30, 48), (89, 27, 55), + (99, 27, 64), (120, 23, 80), (122, 25, 83), (125, 27, 87), + (135, 24, 94), (142, 22, 100), (150, 19, 104), (155, 20, 106), + (161, 27, 109), (163, 29, 110), (165, 31, 112), (173, 31, 118), + (175, 36, 119), (172, 42, 118), (164, 46, 114), (159, 43, 110), + (151, 44, 102), (128, 45, 82), (119, 47, 75), (111, 49, 69), + (101, 50, 58), (96, 50, 54), (90, 59, 50), (83, 71, 49), + (77, 66, 47), (76, 64, 46), (75, 62, 45), (70, 60, 41), + (54, 63, 34), (40, 58, 26), (36, 52, 23), (29, 48, 23), + (27, 46, 22), (26, 44, 22), (26, 44, 22), (29, 45, 22), + (45, 39, 23), (53, 32, 22), (62, 24, 20), (68, 20, 18), + (69, 21, 17), (69, 20, 17), (69, 20, 17), (68, 21, 16), + (62, 30, 18), (62, 30, 17), (63, 31, 16), (65, 31, 16), + (70, 26, 15), (71, 26, 16), (72, 25, 15), (71, 23, 18), + (71, 24, 20), (70, 25, 24), (71, 28, 31), (73, 32, 39), + (77, 36, 47), (85, 38, 58), (93, 44, 72), (103, 50, 84), + (112, 57, 96), (117, 68, 105), (123, 73, 103), (128, 76, 103), + (130, 79, 107), (132, 78, 110), (136, 76, 109), (143, 73, 115), + (152, 70, 119), (161, 68, 125), (166, 70, 132), (171, 71, 132), + (174, 69, 126), (175, 66, 118), (173, 58, 110), (167, 51, 100), + (163, 40, 91), (160, 26, 84), (156, 14, 80), (150, 8, 79), + (147, 4, 80), (146, 2, 80), (146, 1, 76), (144, 0, 71), + (136, 1, 67), (128, 4, 63), (126, 1, 54), (127, 0, 52), + (127, 0, 53), (127, 0, 56), (127, 0, 62), (128, 6, 68), + (130, 12, 74), (132, 25, 83), (132, 42, 96), (135, 55, 105), + (144, 68, 109), (156, 75, 117), (169, 83, 125), (182, 92, 139), + (195, 99, 152), (208, 104, 160), (219, 113, 175), (225, 126, 192), + (229, 139, 209), (228, 140, 207), (220, 143, 204), (211, 143, 199), + (202, 145, 189), (193, 143, 155), (183, 161, 132), (175, 156, 122) + ), + +// 632 Rusted +((129, 170, 176), (126, 158, 170), (135, 161, 178), (144, 164, 187), + (152, 172, 198), (160, 180, 209), (162, 182, 213), (165, 185, 218), + (179, 199, 235), (176, 196, 229), (173, 193, 223), (163, 182, 206), + (153, 172, 190), (147, 159, 167), (142, 146, 145), (140, 136, 127), + (138, 127, 110), (127, 100, 91), (124, 97, 90), (122, 94, 89), + (117, 91, 92), (112, 88, 96), (105, 90, 104), (98, 92, 112), + (76, 100, 119), (70, 93, 111), (64, 86, 103), (58, 80, 94), + (52, 75, 85), (50, 71, 80), (49, 68, 75), (45, 63, 64), + (41, 59, 57), (38, 50, 46), (36, 49, 42), (35, 48, 39), + (34, 45, 36), (34, 42, 34), (34, 41, 34), (34, 40, 35), + (33, 41, 36), (34, 43, 39), (36, 46, 42), (41, 51, 50), + (46, 57, 59), (48, 61, 64), (50, 65, 70), (57, 73, 81), + (64, 82, 94), (81, 101, 117), (86, 105, 121), (91, 110, 126), + (92, 110, 121), (93, 110, 117), (91, 107, 111), (89, 104, 106), + (93, 81, 66), (93, 74, 51), (93, 67, 37), (94, 64, 30), + (96, 62, 24), (96, 63, 25), (97, 64, 27), (97, 73, 36), + (101, 79, 47), (103, 116, 72), (110, 130, 76), (117, 145, 81), + (122, 143, 79), (127, 141, 77), (135, 133, 68), (142, 124, 55), + (138, 101, 33), (135, 79, 23), (133, 58, 13), (131, 50, 7), + (130, 42, 2), (131, 43, 1), (133, 45, 1), (133, 46, 1), + (126, 50, 0), (133, 49, 2), (128, 54, 5), (123, 59, 9), + (118, 61, 15), (113, 64, 22), (109, 72, 35), (99, 76, 46), + (83, 81, 67), (76, 83, 76), (70, 86, 86), (67, 86, 90), + (65, 86, 94), (62, 84, 98), (65, 86, 102), (70, 90, 107), + (78, 100, 117), (95, 115, 135), (98, 119, 140), (102, 124, 145), + (102, 123, 145), (102, 123, 145), (98, 118, 139), (92, 111, 129), + (78, 94, 107), (75, 90, 100), (72, 86, 94), (70, 84, 91), + (69, 83, 89), (67, 83, 85), (66, 85, 88), (67, 85, 88), + (66, 84, 87), (60, 80, 77), (58, 76, 74), (56, 73, 71), + (52, 68, 67), (52, 68, 64), (56, 72, 67), (58, 75, 73), + (70, 90, 101), (79, 101, 114), (89, 112, 128), (94, 117, 136), + (99, 122, 144), (106, 131, 156), (116, 139, 166), (121, 145, 171), + (126, 147, 175), (128, 150, 178), (127, 151, 178), (127, 152, 178), + (126, 150, 177), (126, 148, 174), (125, 145, 167), (124, 145, 160), + (130, 158, 138), (128, 158, 122), (126, 159, 107), (129, 155, 99), + (132, 151, 92), (143, 144, 74), (147, 134, 52), (137, 126, 41), + (134, 108, 32), (137, 71, 14), (128, 68, 15), (119, 66, 17), + (102, 63, 23), (88, 62, 32), (85, 59, 36), (72, 62, 47), + (61, 75, 78), (65, 80, 86), (70, 85, 94), (77, 95, 108), + (75, 93, 106), (79, 98, 110), (82, 100, 109), (83, 102, 106), + (76, 94, 92), (69, 75, 56), (70, 70, 47), (71, 65, 39), + (73, 54, 26), (69, 51, 20), (70, 42, 18), (70, 40, 20), + (69, 48, 32), (70, 50, 37), (72, 53, 43), (72, 62, 54), + (72, 72, 69), (73, 87, 79), (80, 98, 88), (87, 105, 90), + (89, 104, 90), (87, 100, 88), (82, 97, 89), (77, 92, 84), + (71, 85, 74), (66, 76, 67), (62, 71, 68), (61, 71, 75), + (72, 89, 84), (78, 95, 86), (85, 102, 88), (95, 115, 95), + (106, 127, 99), (110, 131, 107), (114, 132, 105), (111, 129, 98), + (105, 124, 87), (94, 111, 85), (84, 100, 85), (76, 91, 89), + (73, 90, 92), (75, 93, 100), (81, 100, 112), (90, 110, 129), + (103, 123, 148), (117, 137, 166), (128, 148, 181), (135, 155, 189), + (140, 159, 192), (142, 161, 195), (142, 162, 196), (138, 161, 191), + (132, 156, 184), (126, 151, 179), (123, 146, 175), (120, 144, 168), + (117, 141, 159), (108, 134, 149), (97, 122, 135), (87, 109, 118), + (79, 96, 99), (72, 82, 78), (63, 66, 57), (55, 51, 40), + (47, 41, 29), (42, 35, 20), (41, 29, 15), (39, 27, 13), + (38, 24, 12), (30, 24, 12), (25, 25, 15), (22, 29, 21), + (26, 31, 24), (25, 30, 25), (25, 34, 30), (32, 45, 43), + (47, 61, 57), (61, 75, 73), (71, 87, 90), (85, 104, 114), + (103, 121, 135), (124, 142, 157), (138, 156, 177), (148, 168, 194), + (154, 174, 206), (158, 182, 212), (160, 183, 215), (162, 183, 211), + (170, 178, 203), (176, 188, 197), (183, 197, 205), (186, 209, 214), + (197, 204, 217), (203, 214, 216), (204, 223, 222), (191, 230, 227), + (177, 217, 222), (164, 204, 214), (153, 193, 202), (140, 181, 191) + ), + +// 633 Sachet +((73, 104, 39), (49, 73, 24), (32, 55, 17), (15, 37, 10), + (13, 36, 14), (12, 36, 18), (14, 36, 19), (16, 36, 21), + (29, 65, 32), (44, 83, 38), (59, 102, 45), (73, 117, 49), + (88, 133, 53), (94, 138, 54), (101, 143, 55), (97, 142, 51), + (94, 141, 48), (85, 132, 39), (73, 122, 37), (62, 112, 35), + (61, 110, 36), (60, 109, 37), (57, 106, 36), (54, 104, 36), + (70, 115, 40), (78, 118, 46), (86, 121, 52), (91, 123, 57), + (97, 125, 63), (100, 124, 62), (103, 123, 61), (97, 114, 60), + (85, 113, 57), (76, 105, 59), (66, 99, 63), (57, 93, 67), + (49, 85, 63), (41, 78, 60), (40, 77, 58), (39, 77, 57), + (37, 78, 50), (41, 83, 49), (46, 89, 49), (50, 88, 50), + (54, 87, 51), (51, 84, 49), (49, 81, 47), (48, 78, 42), + (46, 71, 44), (37, 62, 49), (47, 58, 71), (58, 54, 93), + (65, 58, 110), (73, 62, 128), (81, 61, 143), (90, 60, 159), + (110, 98, 158), (123, 115, 153), (136, 132, 148), (142, 142, 137), + (148, 153, 127), (150, 153, 137), (153, 153, 147), (160, 150, 157), + (155, 134, 162), (135, 117, 163), (130, 122, 143), (126, 127, 123), + (127, 129, 111), (128, 132, 99), (135, 143, 82), (139, 155, 74), + (132, 148, 56), (112, 132, 54), (93, 117, 52), (70, 94, 42), + (47, 71, 33), (37, 59, 30), (27, 48, 27), (13, 28, 19), + (7, 21, 15), (3, 20, 14), (8, 30, 17), (14, 40, 21), + (18, 48, 21), (22, 56, 22), (36, 75, 26), (58, 93, 26), + (85, 114, 32), (95, 113, 48), (106, 113, 64), (106, 107, 77), + (106, 102, 91), (101, 85, 104), (96, 78, 114), (91, 79, 125), + (83, 79, 118), (77, 86, 91), (74, 95, 87), (71, 104, 83), + (74, 106, 85), (78, 108, 87), (80, 108, 94), (79, 101, 96), + (89, 109, 97), (95, 114, 90), (102, 120, 84), (111, 127, 82), + (120, 134, 80), (133, 144, 83), (144, 156, 78), (150, 160, 73), + (148, 156, 77), (116, 135, 54), (105, 125, 51), (94, 116, 49), + (69, 98, 38), (50, 80, 27), (34, 62, 23), (24, 51, 22), + (40, 60, 31), (54, 73, 43), (69, 87, 55), (74, 94, 55), + (80, 102, 56), (82, 112, 59), (82, 113, 66), (85, 112, 71), + (86, 105, 75), (116, 114, 125), (127, 123, 137), (139, 132, 149), + (149, 143, 159), (165, 160, 159), (174, 174, 158), (169, 181, 140), + (143, 162, 99), (139, 156, 90), (135, 151, 81), (135, 152, 79), + (135, 153, 77), (133, 151, 74), (144, 159, 72), (156, 170, 69), + (162, 173, 68), (168, 182, 72), (168, 182, 73), (169, 182, 75), + (165, 176, 79), (163, 173, 79), (157, 167, 77), (145, 158, 76), + (125, 134, 69), (116, 129, 64), (108, 124, 60), (89, 111, 55), + (73, 99, 49), (58, 86, 37), (43, 72, 29), (30, 61, 21), + (20, 48, 12), (7, 28, 4), (6, 25, 2), (6, 22, 1), + (3, 16, 0), (0, 12, 0), (1, 14, 0), (3, 17, 1), + (4, 27, 1), (5, 31, 2), (7, 36, 4), (12, 44, 7), + (17, 50, 10), (23, 58, 13), (31, 66, 16), (36, 71, 21), + (39, 74, 26), (49, 80, 27), (58, 85, 26), (67, 89, 29), + (85, 106, 35), (104, 123, 40), (122, 135, 44), (139, 152, 51), + (154, 173, 67), (155, 172, 67), (156, 172, 67), (156, 169, 68), + (157, 173, 71), (157, 176, 73), (159, 173, 71), (167, 177, 74), + (172, 184, 78), (174, 186, 76), (176, 187, 75), (174, 184, 74), + (165, 178, 68), (153, 169, 66), (139, 158, 63), (116, 139, 57), + (100, 126, 62), (96, 127, 66), (100, 129, 77), (122, 150, 109), + (148, 172, 132), (167, 182, 140), (180, 197, 148), (185, 186, 162), + (178, 160, 166), (157, 143, 148), (143, 123, 140), (139, 113, 137), + (136, 124, 124), (145, 138, 114), (153, 155, 99), (157, 172, 88), + (166, 182, 86), (173, 186, 90), (178, 190, 92), (186, 200, 101), + (183, 202, 116), (178, 193, 109), (177, 194, 102), (159, 185, 105), + (132, 159, 86), (107, 131, 61), (82, 105, 49), (55, 80, 36), + (35, 54, 22), (25, 36, 18), (12, 29, 16), (9, 28, 17), + (18, 34, 19), (26, 49, 23), (35, 67, 33), (55, 85, 40), + (75, 101, 40), (89, 113, 43), (103, 120, 50), (112, 121, 48), + (122, 121, 50), (121, 121, 63), (113, 124, 71), (117, 125, 79), + (119, 124, 100), (110, 115, 129), (110, 106, 147), (119, 106, 154), + (116, 94, 165), (108, 87, 162), (111, 98, 144), (112, 108, 128), + (109, 122, 106), (115, 135, 82), (122, 142, 71), (95, 125, 58) + ), + +// 634 Sage +((63, 51, 34), (64, 46, 25), (66, 53, 29), (69, 60, 33), + (76, 73, 44), (83, 86, 55), (87, 93, 60), (91, 100, 66), + (111, 135, 90), (122, 151, 105), (134, 168, 121), (138, 178, 129), + (143, 189, 138), (141, 192, 139), (139, 196, 141), (139, 198, 140), + (139, 201, 140), (137, 198, 134), (130, 192, 124), (124, 186, 114), + (120, 181, 107), (117, 176, 100), (120, 176, 99), (123, 176, 98), + (135, 166, 88), (131, 150, 77), (127, 134, 66), (118, 121, 61), + (109, 109, 57), (105, 102, 53), (101, 96, 50), (94, 80, 36), + (84, 60, 24), (58, 30, 8), (49, 25, 6), (41, 21, 5), + (38, 20, 5), (36, 19, 5), (36, 19, 5), (36, 19, 5), + (41, 22, 6), (40, 22, 6), (40, 23, 6), (37, 24, 7), + (35, 25, 8), (36, 26, 9), (37, 28, 11), (40, 31, 13), + (44, 35, 19), (43, 61, 33), (48, 72, 40), (53, 84, 48), + (58, 87, 52), (63, 90, 57), (63, 92, 56), (64, 95, 56), + (62, 94, 47), (66, 86, 42), (71, 78, 38), (81, 75, 32), + (91, 73, 27), (94, 70, 23), (97, 68, 20), (98, 67, 20), + (96, 66, 21), (103, 81, 37), (107, 92, 46), (111, 104, 55), + (108, 109, 58), (105, 114, 62), (96, 123, 71), (91, 129, 76), + (93, 135, 86), (92, 134, 85), (91, 134, 84), (90, 124, 74), + (90, 114, 65), (88, 106, 60), (87, 98, 55), (81, 81, 45), + (72, 65, 37), (53, 41, 18), (46, 32, 12), (39, 24, 7), + (36, 21, 6), (34, 19, 5), (31, 16, 4), (27, 14, 3), + (28, 15, 3), (31, 19, 4), (35, 23, 5), (37, 25, 6), + (40, 28, 7), (44, 33, 12), (50, 41, 19), (58, 48, 28), + (67, 61, 37), (95, 95, 70), (104, 109, 84), (113, 123, 99), + (113, 126, 101), (114, 129, 103), (118, 130, 107), (116, 130, 106), + (107, 120, 97), (94, 108, 82), (82, 96, 67), (75, 87, 59), + (68, 79, 52), (57, 67, 42), (51, 59, 32), (48, 54, 24), + (50, 53, 19), (51, 56, 17), (53, 58, 18), (55, 61, 20), + (58, 65, 22), (62, 66, 23), (63, 63, 22), (61, 62, 23), + (60, 60, 24), (62, 57, 22), (64, 55, 20), (63, 52, 18), + (63, 50, 17), (65, 44, 13), (64, 40, 11), (65, 37, 9), + (66, 35, 6), (59, 28, 1), (56, 25, 0), (53, 22, 0), + (46, 17, 1), (39, 14, 0), (31, 13, 1), (27, 12, 2), + (22, 14, 4), (22, 17, 5), (23, 20, 6), (25, 21, 7), + (27, 22, 8), (31, 24, 10), (35, 27, 12), (38, 31, 15), + (40, 32, 16), (41, 33, 17), (40, 32, 16), (39, 31, 16), + (36, 30, 15), (34, 29, 14), (30, 27, 13), (26, 24, 10), + (20, 21, 5), (20, 22, 4), (21, 23, 4), (23, 24, 5), + (27, 27, 9), (34, 35, 15), (42, 44, 22), (51, 60, 28), + (60, 77, 35), (82, 109, 58), (87, 116, 66), (93, 124, 74), + (104, 143, 88), (113, 161, 99), (120, 169, 107), (125, 175, 110), + (128, 176, 114), (128, 176, 113), (129, 176, 113), (129, 170, 113), + (125, 159, 107), (119, 142, 96), (111, 125, 83), (103, 112, 70), + (96, 99, 63), (88, 87, 56), (78, 75, 51), (72, 64, 47), + (66, 55, 39), (58, 48, 33), (53, 43, 27), (48, 39, 23), + (51, 41, 25), (52, 43, 25), (53, 46, 26), (55, 50, 25), + (59, 53, 23), (64, 54, 24), (67, 55, 26), (72, 58, 30), + (73, 63, 31), (77, 70, 31), (81, 77, 36), (85, 86, 43), + (87, 96, 54), (87, 108, 65), (88, 119, 69), (88, 129, 75), + (91, 138, 82), (95, 143, 89), (98, 147, 98), (100, 148, 99), + (101, 146, 96), (110, 142, 90), (119, 133, 79), (127, 122, 70), + (129, 108, 59), (123, 95, 47), (120, 84, 37), (118, 75, 27), + (117, 68, 20), (113, 60, 14), (99, 53, 8), (84, 45, 4), + (69, 39, 2), (58, 35, 2), (52, 34, 1), (47, 34, 2), + (46, 35, 4), (46, 39, 7), (47, 41, 9), (49, 43, 9), + (51, 44, 8), (52, 43, 8), (56, 44, 10), (63, 45, 13), + (69, 46, 15), (77, 51, 17), (89, 60, 23), (97, 75, 35), + (109, 92, 53), (121, 110, 73), (130, 127, 91), (148, 144, 108), + (166, 166, 129), (182, 185, 150), (195, 206, 172), (204, 221, 193), + (210, 228, 205), (216, 234, 211), (216, 230, 209), (209, 227, 202), + (205, 223, 197), (198, 215, 187), (185, 205, 175), (170, 186, 160), + (148, 167, 141), (130, 150, 122), (117, 131, 103), (104, 111, 86), + (93, 92, 68), (81, 75, 54), (71, 64, 45), (66, 57, 38) + ), + +// 635 Saturday_Morning +((126, 171, 215), (115, 175, 207), (106, 179, 205), (98, 183, 204), + (101, 182, 200), (104, 182, 197), (110, 179, 194), (117, 177, 191), + (141, 156, 199), (151, 150, 199), (162, 145, 199), (163, 144, 204), + (165, 144, 210), (168, 143, 211), (171, 143, 212), (174, 140, 211), + (177, 138, 211), (181, 125, 189), (188, 125, 172), (196, 126, 155), + (199, 117, 139), (203, 108, 124), (206, 110, 112), (209, 112, 100), + (224, 117, 67), (220, 107, 66), (217, 98, 65), (217, 99, 71), + (217, 101, 77), (215, 100, 83), (213, 99, 90), (210, 103, 113), + (201, 105, 140), (200, 123, 175), (199, 128, 188), (198, 133, 201), + (198, 123, 199), (199, 114, 197), (202, 108, 191), (205, 103, 185), + (210, 91, 157), (210, 93, 146), (210, 96, 136), (212, 110, 138), + (215, 124, 140), (211, 131, 140), (208, 139, 140), (198, 159, 151), + (185, 171, 167), (175, 183, 190), (168, 182, 192), (161, 181, 195), + (149, 179, 199), (138, 178, 203), (131, 180, 203), (125, 182, 203), + (113, 175, 209), (109, 171, 211), (106, 167, 214), (118, 157, 208), + (130, 147, 203), (142, 141, 198), (155, 135, 194), (180, 128, 185), + (197, 123, 177), (228, 107, 158), (239, 103, 152), (251, 99, 147), + (252, 95, 145), (254, 91, 144), (253, 85, 135), (252, 76, 132), + (250, 54, 148), (244, 52, 157), (238, 50, 167), (235, 51, 176), + (233, 53, 186), (231, 59, 192), (229, 65, 199), (222, 80, 211), + (215, 93, 208), (224, 105, 167), (227, 106, 152), (231, 107, 138), + (232, 103, 134), (233, 100, 130), (238, 91, 112), (245, 86, 98), + (242, 78, 106), (241, 77, 114), (241, 76, 123), (240, 78, 130), + (239, 80, 138), (231, 93, 155), (220, 107, 166), (213, 123, 167), + (205, 140, 170), (191, 188, 165), (194, 203, 147), (197, 218, 130), + (196, 220, 123), (196, 222, 116), (192, 220, 117), (199, 218, 114), + (210, 197, 115), (207, 185, 130), (204, 173, 145), (205, 167, 145), + (207, 161, 146), (212, 150, 138), (217, 133, 132), (225, 121, 129), + (231, 108, 125), (244, 82, 99), (246, 78, 95), (249, 74, 92), + (249, 70, 89), (245, 67, 81), (245, 68, 75), (247, 70, 78), + (246, 70, 84), (245, 71, 90), (244, 72, 96), (243, 74, 104), + (242, 77, 112), (236, 79, 130), (224, 87, 145), (218, 94, 156), + (211, 103, 163), (179, 124, 180), (173, 128, 186), (168, 132, 192), + (160, 129, 198), (156, 125, 205), (147, 124, 201), (150, 124, 202), + (175, 104, 195), (189, 99, 188), (203, 94, 181), (209, 95, 177), + (215, 97, 174), (224, 98, 169), (227, 105, 170), (221, 116, 175), + (217, 128, 178), (195, 155, 191), (187, 163, 194), (180, 172, 198), + (172, 180, 200), (166, 184, 202), (162, 180, 204), (157, 181, 210), + (143, 181, 219), (138, 179, 220), (133, 177, 221), (127, 179, 220), + (129, 181, 218), (133, 185, 217), (133, 181, 215), (134, 176, 206), + (142, 166, 197), (163, 150, 166), (171, 145, 159), (180, 141, 153), + (198, 125, 148), (207, 114, 150), (209, 108, 151), (216, 113, 154), + (228, 117, 174), (224, 118, 182), (221, 119, 191), (209, 127, 209), + (192, 138, 218), (179, 149, 222), (171, 160, 223), (163, 164, 223), + (153, 169, 217), (142, 173, 210), (136, 183, 200), (138, 183, 194), + (139, 177, 193), (137, 169, 195), (131, 169, 199), (129, 171, 202), + (122, 163, 212), (122, 159, 218), (122, 156, 224), (121, 155, 236), + (108, 154, 235), (99, 153, 228), (106, 146, 229), (124, 137, 239), + (131, 128, 246), (130, 122, 240), (136, 121, 234), (152, 120, 233), + (171, 123, 234), (180, 125, 233), (179, 130, 227), (176, 132, 224), + (175, 134, 220), (181, 139, 219), (182, 141, 218), (185, 138, 214), + (187, 129, 202), (190, 118, 186), (188, 117, 178), (178, 113, 174), + (173, 110, 171), (165, 102, 166), (157, 107, 173), (142, 105, 186), + (138, 96, 201), (136, 91, 207), (141, 98, 215), (148, 108, 216), + (164, 104, 222), (171, 105, 220), (178, 110, 215), (180, 125, 201), + (184, 138, 196), (181, 148, 197), (182, 154, 202), (179, 156, 203), + (172, 156, 206), (163, 152, 211), (161, 148, 219), (161, 145, 224), + (156, 144, 224), (148, 143, 224), (141, 144, 227), (141, 146, 230), + (140, 149, 229), (141, 154, 229), (139, 160, 228), (139, 164, 228), + (137, 162, 227), (141, 160, 227), (148, 161, 224), (155, 161, 220), + (163, 157, 211), (170, 149, 201), (180, 144, 186), (182, 142, 174), + (184, 145, 171), (175, 144, 172), (168, 138, 175), (152, 124, 177), + (140, 116, 191), (124, 114, 204), (120, 123, 219), (124, 131, 224), + (126, 131, 231), (130, 121, 231), (129, 123, 232), (134, 143, 220) + ), + +// 636 Scattered_Petals +((68, 120, 123), (57, 97, 96), (51, 86, 84), (45, 75, 73), + (40, 63, 61), (36, 52, 50), (35, 48, 45), (34, 45, 40), + (33, 35, 27), (32, 32, 26), (31, 30, 25), (33, 31, 24), + (35, 33, 24), (37, 39, 23), (39, 45, 23), (39, 48, 24), + (40, 51, 26), (42, 55, 32), (43, 58, 35), (45, 62, 38), + (53, 72, 43), (61, 82, 48), (63, 86, 54), (66, 91, 60), + (74, 107, 81), (78, 111, 82), (82, 115, 83), (82, 112, 83), + (82, 110, 83), (80, 107, 83), (78, 104, 83), (69, 92, 77), + (63, 82, 68), (54, 60, 53), (56, 58, 52), (58, 56, 51), + (70, 62, 63), (83, 69, 75), (94, 71, 83), (106, 74, 91), + (150, 82, 117), (151, 86, 117), (153, 90, 117), (148, 85, 114), + (144, 80, 112), (141, 73, 108), (139, 67, 105), (123, 58, 89), + (95, 47, 69), (42, 34, 33), (30, 29, 26), (19, 25, 19), + (14, 22, 16), (10, 20, 13), (11, 21, 13), (12, 23, 14), + (21, 36, 19), (26, 46, 27), (31, 57, 35), (39, 65, 43), + (48, 73, 52), (55, 75, 58), (62, 78, 64), (88, 80, 83), + (114, 88, 103), (157, 104, 146), (166, 116, 157), (176, 129, 168), + (178, 133, 170), (180, 138, 172), (178, 144, 176), (169, 141, 174), + (142, 136, 153), (117, 131, 133), (92, 126, 113), (76, 108, 93), + (60, 91, 73), (57, 83, 67), (55, 76, 61), (51, 64, 51), + (46, 55, 46), (37, 41, 36), (37, 40, 33), (38, 40, 31), + (37, 39, 31), (36, 39, 32), (33, 39, 34), (30, 35, 36), + (30, 36, 35), (29, 41, 38), (29, 47, 42), (30, 50, 45), + (31, 53, 48), (33, 59, 50), (38, 63, 49), (42, 65, 48), + (42, 72, 53), (49, 88, 63), (53, 93, 63), (58, 99, 63), + (58, 103, 65), (58, 107, 68), (62, 117, 77), (69, 131, 91), + (78, 151, 111), (77, 154, 116), (77, 158, 121), (78, 158, 121), + (79, 158, 122), (79, 155, 114), (78, 146, 106), (74, 139, 93), + (69, 129, 81), (64, 109, 57), (61, 104, 52), (59, 99, 48), + (57, 94, 39), (57, 93, 36), (63, 97, 40), (73, 105, 47), + (79, 124, 74), (80, 132, 85), (81, 140, 96), (84, 141, 97), + (87, 142, 99), (87, 142, 101), (89, 142, 102), (87, 146, 100), + (84, 149, 97), (76, 135, 81), (74, 128, 76), (72, 122, 72), + (73, 113, 64), (74, 110, 59), (76, 111, 55), (74, 110, 52), + (67, 95, 46), (62, 85, 45), (58, 75, 44), (56, 72, 43), + (54, 69, 42), (49, 60, 38), (46, 55, 33), (41, 47, 30), + (38, 40, 29), (43, 32, 33), (50, 32, 36), (58, 33, 40), + (80, 34, 51), (102, 35, 59), (107, 37, 58), (105, 42, 56), + (112, 69, 61), (122, 77, 68), (132, 85, 75), (143, 94, 78), + (142, 102, 85), (139, 108, 94), (140, 116, 107), (153, 130, 133), + (175, 137, 152), (204, 137, 186), (212, 131, 190), (220, 126, 195), + (232, 119, 205), (237, 109, 201), (223, 102, 188), (201, 94, 170), + (155, 72, 121), (147, 65, 109), (139, 59, 98), (112, 50, 75), + (86, 43, 56), (59, 37, 37), (37, 33, 25), (39, 44, 24), + (42, 53, 23), (43, 57, 23), (49, 68, 26), (42, 60, 24), + (49, 71, 30), (57, 85, 38), (61, 94, 41), (66, 104, 45), + (52, 84, 41), (48, 79, 40), (45, 75, 40), (39, 65, 38), + (34, 59, 34), (31, 52, 32), (26, 48, 30), (24, 43, 28), + (23, 41, 31), (25, 43, 37), (30, 50, 47), (35, 62, 59), + (41, 76, 70), (51, 96, 84), (62, 115, 103), (72, 135, 124), + (81, 153, 142), (103, 156, 157), (127, 159, 169), (151, 157, 182), + (173, 155, 196), (179, 158, 203), (197, 149, 209), (217, 139, 209), + (235, 125, 210), (250, 115, 214), (247, 115, 213), (232, 118, 203), + (221, 123, 187), (209, 128, 169), (196, 128, 151), (184, 128, 140), + (160, 125, 122), (138, 121, 105), (120, 121, 88), (105, 119, 72), + (96, 114, 63), (86, 106, 53), (73, 93, 47), (62, 82, 44), + (52, 73, 44), (44, 65, 43), (39, 60, 39), (35, 55, 32), + (31, 50, 26), (27, 48, 23), (24, 44, 22), (22, 40, 22), + (23, 40, 19), (25, 40, 19), (29, 47, 18), (32, 54, 20), + (34, 58, 25), (36, 60, 27), (36, 59, 31), (36, 61, 32), + (39, 64, 34), (42, 67, 35), (46, 69, 37), (50, 68, 40), + (60, 67, 45), (78, 73, 61), (104, 80, 80), (124, 89, 98), + (125, 102, 112), (121, 107, 117), (118, 113, 126), (123, 119, 138), + (136, 121, 151), (130, 130, 158), (112, 132, 153), (89, 126, 138) + ), + +// 637 Sea_Mist +((66, 148, 132), (70, 145, 134), (64, 137, 127), (58, 129, 120), + (49, 112, 102), (41, 96, 85), (37, 89, 79), (34, 82, 74), + (34, 61, 57), (39, 62, 57), (44, 63, 57), (48, 66, 61), + (52, 70, 66), (61, 71, 69), (70, 73, 73), (75, 77, 76), + (81, 81, 80), (99, 103, 102), (101, 112, 111), (103, 122, 120), + (100, 130, 126), (97, 139, 132), (95, 142, 134), (94, 145, 137), + (80, 149, 136), (70, 147, 134), (60, 146, 132), (58, 137, 123), + (57, 128, 115), (56, 122, 110), (56, 117, 105), (55, 107, 96), + (52, 101, 92), (56, 84, 79), (59, 78, 74), (63, 73, 69), + (65, 72, 70), (68, 72, 71), (69, 72, 71), (71, 73, 71), + (74, 74, 73), (70, 79, 78), (66, 85, 83), (63, 90, 87), + (60, 96, 92), (58, 95, 91), (56, 95, 91), (47, 92, 89), + (35, 90, 89), (23, 93, 89), (24, 97, 93), (26, 102, 97), + (30, 110, 106), (35, 119, 115), (39, 125, 120), (44, 132, 126), + (64, 165, 155), (79, 180, 172), (95, 196, 190), (110, 208, 203), + (125, 220, 217), (127, 224, 221), (129, 229, 226), (131, 230, 230), + (128, 232, 232), (127, 228, 228), (124, 221, 221), (122, 214, 214), + (117, 207, 207), (113, 201, 200), (102, 187, 184), (94, 172, 167), + (91, 146, 139), (89, 131, 124), (87, 116, 110), (82, 102, 97), + (77, 89, 84), (74, 85, 80), (72, 81, 77), (69, 74, 70), + (64, 69, 65), (56, 58, 55), (52, 54, 52), (49, 51, 49), + (48, 50, 48), (48, 49, 48), (48, 49, 48), (49, 48, 48), + (46, 47, 46), (46, 47, 46), (46, 48, 46), (46, 48, 46), + (47, 48, 47), (47, 49, 47), (46, 49, 46), (41, 51, 48), + (36, 52, 50), (32, 57, 55), (34, 57, 54), (36, 58, 54), + (36, 58, 54), (37, 59, 55), (36, 62, 61), (41, 67, 64), + (54, 70, 66), (57, 70, 66), (60, 71, 67), (61, 72, 68), + (62, 73, 69), (65, 76, 72), (68, 78, 74), (71, 83, 78), + (72, 85, 80), (65, 96, 88), (63, 98, 89), (62, 100, 91), + (59, 104, 95), (60, 105, 96), (60, 107, 95), (57, 107, 94), + (47, 96, 86), (45, 88, 79), (44, 81, 73), (44, 77, 69), + (44, 73, 66), (43, 65, 58), (39, 56, 52), (35, 52, 50), + (35, 50, 50), (43, 57, 54), (44, 60, 57), (46, 63, 60), + (49, 73, 69), (58, 83, 79), (67, 97, 93), (80, 114, 108), + (92, 154, 147), (96, 169, 163), (100, 185, 180), (103, 192, 186), + (107, 200, 193), (113, 212, 206), (116, 222, 215), (113, 224, 219), + (113, 216, 211), (102, 193, 187), (100, 187, 180), (99, 182, 174), + (89, 170, 161), (83, 156, 145), (75, 138, 127), (62, 119, 108), + (47, 92, 82), (44, 89, 79), (42, 86, 76), (44, 82, 73), + (47, 80, 73), (54, 78, 72), (63, 76, 72), (70, 77, 75), + (77, 80, 79), (82, 96, 93), (81, 100, 96), (81, 104, 99), + (79, 111, 103), (82, 116, 108), (83, 120, 111), (87, 126, 118), + (87, 136, 127), (89, 138, 128), (92, 140, 130), (95, 143, 133), + (103, 146, 138), (108, 153, 145), (114, 160, 152), (122, 167, 160), + (129, 173, 166), (135, 180, 176), (135, 191, 187), (130, 203, 198), + (128, 211, 207), (123, 214, 210), (121, 214, 210), (120, 213, 207), + (106, 201, 195), (99, 196, 189), (92, 192, 184), (79, 181, 171), + (67, 172, 160), (62, 163, 150), (60, 155, 141), (57, 150, 136), + (55, 148, 133), (50, 149, 134), (49, 155, 141), (53, 163, 150), + (56, 172, 161), (62, 183, 171), (64, 188, 178), (65, 193, 183), + (67, 195, 187), (66, 194, 186), (70, 191, 183), (73, 183, 176), + (76, 173, 167), (78, 163, 157), (77, 153, 147), (80, 144, 138), + (84, 137, 132), (87, 137, 130), (90, 141, 133), (91, 148, 141), + (92, 159, 152), (100, 166, 157), (104, 173, 165), (108, 179, 171), + (110, 181, 174), (107, 182, 175), (111, 179, 172), (113, 172, 166), + (116, 162, 155), (119, 149, 145), (117, 136, 133), (112, 128, 125), + (105, 122, 119), (97, 115, 110), (91, 107, 103), (83, 100, 96), + (74, 94, 91), (67, 91, 88), (61, 87, 83), (58, 82, 79), + (54, 76, 72), (48, 72, 68), (45, 68, 64), (43, 66, 63), + (47, 64, 61), (51, 63, 60), (50, 65, 62), (47, 67, 62), + (43, 70, 64), (39, 72, 67), (36, 73, 68), (33, 79, 73), + (30, 84, 78), (28, 89, 82), (27, 92, 83), (26, 93, 85), + (26, 98, 87), (28, 103, 92), (40, 112, 101), (48, 116, 105), + (58, 132, 121), (64, 144, 132), (59, 149, 134), (67, 160, 145) + ), + +// 638 Secret +((82, 53, 109), (40, 21, 51), (40, 23, 53), (41, 26, 55), + (39, 23, 55), (38, 21, 55), (37, 22, 53), (36, 23, 51), + (31, 29, 53), (33, 25, 49), (35, 21, 46), (29, 19, 40), + (24, 17, 35), (22, 15, 32), (20, 13, 29), (19, 11, 28), + (19, 10, 27), (24, 10, 35), (25, 12, 33), (26, 15, 32), + (24, 16, 36), (23, 18, 41), (25, 20, 44), (28, 22, 48), + (33, 32, 66), (41, 36, 74), (49, 41, 82), (57, 38, 83), + (65, 36, 84), (63, 35, 79), (62, 34, 75), (55, 26, 80), + (53, 32, 75), (56, 36, 73), (56, 41, 75), (56, 47, 78), + (65, 53, 97), (74, 59, 116), (68, 60, 117), (63, 62, 119), + (43, 42, 84), (38, 35, 69), (34, 28, 54), (31, 26, 51), + (29, 25, 48), (28, 24, 44), (27, 24, 41), (23, 18, 38), + (20, 17, 34), (14, 14, 26), (12, 12, 25), (11, 10, 24), + (14, 10, 25), (18, 11, 27), (17, 10, 25), (16, 10, 24), + (8, 5, 12), (14, 7, 19), (20, 9, 26), (22, 10, 31), + (25, 11, 36), (25, 12, 35), (25, 13, 35), (24, 15, 36), + (21, 18, 35), (22, 19, 36), (22, 21, 39), (22, 23, 43), + (22, 23, 43), (23, 24, 44), (23, 21, 45), (25, 22, 49), + (29, 22, 55), (35, 29, 64), (41, 37, 74), (49, 41, 80), + (58, 46, 86), (70, 49, 98), (83, 52, 111), (99, 56, 135), + (147, 81, 179), (171, 69, 179), (135, 55, 148), (99, 41, 117), + (89, 46, 111), (79, 52, 105), (51, 44, 86), (43, 39, 72), + (26, 25, 56), (21, 21, 47), (17, 18, 38), (16, 17, 36), + (16, 17, 35), (17, 16, 32), (20, 13, 29), (21, 14, 32), + (26, 15, 32), (35, 17, 43), (47, 20, 54), (60, 23, 66), + (63, 27, 70), (67, 31, 75), (68, 30, 77), (73, 37, 85), + (83, 32, 101), (80, 35, 97), (77, 38, 93), (73, 38, 90), + (70, 38, 88), (57, 32, 72), (53, 28, 58), (44, 25, 55), + (41, 24, 56), (46, 22, 56), (49, 23, 61), (53, 25, 66), + (56, 23, 68), (53, 28, 67), (48, 30, 68), (44, 28, 65), + (43, 29, 64), (41, 33, 70), (40, 38, 77), (41, 35, 73), + (42, 32, 69), (33, 28, 60), (29, 26, 55), (26, 22, 47), + (25, 21, 38), (22, 18, 32), (21, 18, 31), (20, 18, 31), + (20, 20, 30), (20, 18, 31), (19, 17, 31), (18, 17, 31), + (15, 14, 28), (15, 13, 28), (16, 12, 29), (17, 13, 29), + (18, 14, 29), (19, 15, 32), (20, 17, 36), (19, 18, 36), + (17, 16, 34), (16, 15, 33), (17, 16, 33), (19, 18, 34), + (20, 17, 36), (20, 19, 37), (21, 19, 41), (18, 17, 48), + (31, 24, 66), (33, 27, 68), (36, 31, 71), (34, 31, 84), + (37, 29, 70), (32, 25, 66), (26, 18, 57), (19, 19, 45), + (17, 18, 36), (14, 14, 26), (12, 12, 24), (10, 10, 22), + (8, 6, 20), (12, 0, 21), (15, 3, 23), (24, 5, 35), + (29, 17, 41), (30, 19, 43), (32, 22, 46), (34, 22, 46), + (34, 22, 44), (29, 20, 39), (29, 17, 39), (31, 21, 45), + (29, 20, 49), (30, 25, 55), (33, 26, 60), (37, 26, 68), + (39, 28, 70), (41, 33, 72), (42, 35, 76), (48, 28, 77), + (36, 22, 58), (34, 20, 53), (32, 19, 49), (29, 16, 42), + (28, 14, 37), (27, 15, 35), (28, 16, 40), (32, 16, 43), + (31, 19, 43), (29, 21, 42), (23, 19, 42), (25, 21, 44), + (32, 19, 47), (34, 19, 52), (43, 19, 53), (48, 0, 68), + (55, 23, 62), (49, 25, 61), (43, 30, 58), (34, 30, 53), + (32, 28, 53), (31, 21, 45), (26, 17, 34), (23, 14, 31), + (22, 9, 27), (19, 13, 25), (17, 14, 25), (18, 14, 28), + (21, 17, 32), (26, 17, 38), (27, 25, 49), (36, 33, 62), + (44, 37, 78), (58, 43, 86), (80, 46, 106), (97, 56, 122), + (100, 66, 142), (92, 65, 132), (78, 65, 121), (88, 54, 114), + (83, 51, 116), (76, 41, 97), (68, 32, 76), (50, 30, 65), + (42, 27, 56), (31, 22, 49), (23, 21, 42), (20, 19, 37), + (20, 17, 36), (21, 18, 37), (22, 17, 40), (28, 22, 50), + (38, 28, 65), (44, 35, 82), (50, 42, 89), (64, 46, 106), + (74, 48, 113), (74, 57, 128), (82, 70, 136), (83, 75, 126), + (87, 78, 135), (98, 89, 134), (103, 82, 175), (129, 76, 182), + (173, 105, 188), (197, 126, 230), (220, 146, 255), (167, 108, 200), + (138, 88, 177), (105, 85, 156), (112, 74, 133), (97, 51, 124) + ), + +// 639 Serenity +((144, 133, 137), (142, 126, 129), (142, 125, 127), (142, 125, 126), + (139, 119, 119), (137, 113, 113), (133, 108, 108), (129, 103, 104), + (107, 80, 85), (97, 70, 77), (87, 60, 69), (81, 54, 63), + (76, 49, 57), (75, 50, 57), (74, 51, 57), (76, 53, 59), + (78, 56, 61), (88, 72, 77), (92, 78, 85), (96, 85, 93), + (100, 90, 97), (104, 96, 101), (105, 96, 102), (106, 97, 104), + (104, 95, 101), (103, 91, 98), (102, 87, 96), (100, 85, 94), + (99, 84, 92), (99, 84, 92), (100, 84, 92), (103, 87, 95), + (104, 92, 99), (113, 102, 107), (114, 104, 108), (116, 106, 110), + (117, 106, 111), (118, 106, 112), (117, 105, 112), (116, 105, 112), + (114, 102, 109), (114, 101, 108), (114, 100, 108), (117, 100, 108), + (121, 101, 108), (122, 101, 108), (124, 102, 109), (128, 103, 109), + (127, 103, 109), (119, 102, 107), (114, 99, 104), (109, 96, 102), + (102, 90, 97), (96, 85, 92), (94, 82, 89), (92, 79, 86), + (84, 65, 73), (83, 58, 66), (83, 52, 60), (83, 53, 61), + (84, 55, 62), (85, 57, 64), (87, 60, 67), (94, 70, 74), + (98, 78, 81), (107, 89, 91), (105, 87, 90), (103, 86, 90), + (101, 85, 89), (99, 84, 89), (94, 82, 86), (86, 75, 81), + (76, 63, 69), (74, 59, 66), (73, 56, 64), (76, 59, 66), + (79, 63, 69), (85, 68, 75), (91, 73, 81), (105, 86, 92), + (119, 103, 107), (150, 134, 138), (157, 144, 147), (165, 154, 157), + (166, 154, 157), (167, 155, 157), (168, 151, 152), (158, 141, 145), + (145, 125, 127), (138, 117, 120), (131, 109, 114), (129, 108, 113), + (127, 107, 112), (126, 107, 113), (124, 107, 113), (122, 107, 112), + (125, 110, 116), (133, 120, 125), (140, 124, 128), (148, 128, 132), + (151, 131, 134), (155, 134, 136), (163, 138, 141), (169, 145, 146), + (182, 163, 164), (186, 169, 170), (190, 176, 177), (188, 176, 177), + (186, 176, 178), (179, 170, 173), (174, 165, 169), (166, 157, 161), + (157, 147, 151), (148, 132, 137), (145, 128, 133), (143, 125, 130), + (137, 117, 122), (135, 109, 114), (129, 103, 108), (122, 99, 103), + (105, 80, 86), (93, 72, 78), (81, 64, 70), (77, 58, 65), + (73, 53, 60), (66, 44, 52), (60, 39, 48), (59, 37, 46), + (61, 38, 47), (76, 52, 60), (80, 56, 63), (84, 61, 67), + (95, 68, 75), (99, 76, 80), (100, 74, 78), (99, 69, 74), + (76, 55, 59), (67, 46, 52), (58, 38, 45), (53, 36, 43), + (48, 35, 41), (43, 30, 39), (42, 26, 36), (39, 25, 34), + (38, 25, 35), (44, 26, 36), (46, 28, 38), (48, 30, 40), + (51, 35, 44), (59, 40, 49), (68, 49, 57), (73, 57, 64), + (87, 72, 78), (89, 75, 81), (92, 79, 85), (97, 83, 89), + (102, 86, 93), (105, 89, 95), (109, 90, 96), (114, 92, 99), + (117, 96, 102), (122, 104, 112), (125, 108, 115), (128, 113, 119), + (133, 121, 126), (139, 128, 134), (146, 136, 142), (153, 144, 149), + (168, 159, 163), (171, 162, 166), (174, 165, 169), (178, 168, 172), + (182, 169, 171), (182, 168, 170), (177, 161, 164), (172, 152, 154), + (164, 144, 145), (154, 135, 134), (146, 123, 124), (136, 113, 115), + (129, 107, 108), (124, 101, 103), (119, 96, 101), (117, 97, 103), + (124, 109, 115), (127, 113, 119), (130, 117, 124), (138, 126, 132), + (149, 134, 139), (157, 142, 146), (159, 146, 151), (162, 148, 153), + (164, 150, 154), (160, 149, 154), (157, 148, 153), (157, 146, 150), + (155, 144, 148), (153, 143, 148), (155, 145, 149), (156, 146, 150), + (158, 149, 153), (164, 153, 157), (171, 155, 158), (173, 156, 159), + (173, 156, 158), (174, 153, 154), (170, 148, 150), (160, 142, 145), + (151, 135, 139), (145, 129, 131), (136, 123, 126), (128, 116, 122), + (125, 113, 118), (124, 113, 118), (126, 114, 118), (127, 115, 120), + (131, 120, 125), (136, 123, 128), (135, 124, 129), (134, 124, 129), + (134, 124, 129), (131, 121, 126), (129, 119, 125), (130, 119, 124), + (132, 122, 127), (138, 128, 133), (147, 137, 142), (159, 149, 153), + (171, 162, 165), (185, 173, 176), (200, 184, 184), (201, 188, 189), + (198, 185, 188), (195, 178, 179), (183, 169, 171), (170, 158, 162), + (160, 146, 151), (154, 138, 143), (151, 132, 136), (150, 127, 133), + (151, 124, 130), (150, 122, 127), (148, 120, 126), (145, 117, 123), + (141, 115, 120), (137, 114, 117), (132, 109, 113), (128, 105, 110), + (125, 103, 108), (123, 101, 107), (123, 104, 110), (125, 108, 115), + (132, 118, 124), (136, 125, 130), (134, 123, 128), (140, 128, 132) + ), + +// 640 Serpent +((36, 70, 44), (26, 82, 55), (26, 80, 55), (27, 79, 56), + (21, 70, 51), (16, 62, 46), (17, 56, 41), (18, 50, 37), + (11, 34, 23), (10, 35, 18), (10, 37, 14), (10, 45, 19), + (10, 54, 24), (10, 62, 31), (10, 70, 38), (9, 68, 38), + (9, 66, 39), (17, 51, 31), (19, 44, 22), (22, 37, 14), + (39, 43, 12), (57, 49, 10), (66, 57, 8), (76, 65, 7), + (107, 73, 5), (101, 69, 2), (96, 66, 0), (77, 49, 1), + (59, 32, 3), (49, 25, 1), (40, 18, 0), (31, 15, 2), + (31, 13, 3), (66, 26, 2), (79, 41, 7), (93, 56, 12), + (95, 66, 25), (98, 77, 38), (88, 81, 45), (78, 85, 52), + (48, 87, 73), (45, 81, 73), (42, 76, 74), (56, 77, 65), + (70, 79, 56), (79, 77, 53), (89, 75, 50), (97, 77, 45), + (92, 80, 45), (75, 91, 58), (55, 83, 57), (35, 76, 57), + (31, 66, 47), (27, 57, 37), (25, 52, 31), (24, 48, 25), + (25, 31, 7), (33, 35, 11), (41, 39, 15), (57, 59, 31), + (73, 80, 47), (86, 94, 54), (99, 108, 62), (125, 117, 62), + (140, 132, 71), (174, 149, 76), (174, 141, 68), (175, 134, 60), + (176, 133, 56), (177, 132, 53), (180, 127, 43), (185, 129, 35), + (196, 131, 20), (192, 131, 20), (189, 132, 20), (178, 125, 20), + (168, 118, 21), (159, 110, 20), (151, 103, 20), (132, 85, 24), + (110, 71, 16), (69, 42, 10), (63, 41, 6), (57, 41, 2), + (63, 43, 3), (70, 45, 4), (89, 53, 7), (104, 68, 11), + (153, 91, 12), (150, 96, 16), (147, 102, 21), (141, 98, 21), + (135, 94, 22), (111, 86, 26), (86, 74, 34), (62, 60, 40), + (41, 47, 41), (13, 32, 31), (9, 23, 26), (5, 15, 21), + (4, 15, 15), (4, 16, 10), (4, 15, 8), (5, 14, 9), + (7, 16, 8), (7, 15, 7), (7, 15, 6), (7, 14, 5), + (7, 13, 4), (5, 9, 2), (3, 6, 1), (3, 4, 2), + (3, 5, 3), (6, 12, 8), (8, 18, 11), (11, 25, 14), + (17, 39, 23), (20, 48, 30), (28, 58, 35), (39, 65, 37), + (49, 65, 34), (56, 61, 29), (64, 57, 25), (69, 55, 26), + (74, 53, 28), (85, 56, 30), (93, 65, 26), (107, 70, 26), + (118, 71, 25), (117, 77, 11), (109, 74, 12), (102, 71, 14), + (90, 61, 10), (70, 50, 7), (49, 43, 13), (36, 37, 13), + (19, 29, 11), (16, 27, 11), (13, 26, 11), (13, 25, 11), + (14, 24, 11), (18, 23, 10), (20, 20, 7), (25, 20, 4), + (38, 25, 3), (84, 44, 2), (92, 52, 3), (101, 60, 5), + (128, 76, 6), (152, 96, 12), (163, 114, 25), (172, 132, 35), + (201, 181, 68), (205, 184, 75), (210, 187, 82), (198, 183, 82), + (206, 194, 83), (209, 182, 78), (190, 154, 62), (183, 142, 49), + (178, 125, 44), (165, 102, 25), (160, 94, 30), (155, 87, 35), + (142, 70, 36), (118, 64, 27), (96, 59, 35), (81, 52, 44), + (43, 63, 46), (40, 66, 49), (38, 69, 53), (41, 73, 50), + (53, 78, 45), (71, 91, 47), (91, 100, 50), (115, 107, 52), + (139, 123, 56), (160, 142, 71), (179, 161, 97), (179, 171, 107), + (178, 173, 98), (192, 174, 99), (174, 165, 96), (156, 151, 70), + (152, 115, 35), (146, 107, 28), (141, 100, 22), (139, 89, 16), + (140, 82, 13), (131, 70, 10), (112, 58, 10), (98, 48, 9), + (87, 42, 10), (73, 40, 11), (68, 42, 13), (82, 55, 15), + (105, 75, 17), (121, 86, 25), (146, 105, 27), (168, 122, 28), + (150, 114, 36), (131, 106, 40), (114, 100, 45), (83, 92, 50), + (53, 78, 49), (40, 66, 51), (40, 62, 49), (37, 58, 43), + (37, 51, 35), (40, 43, 27), (39, 38, 24), (33, 33, 20), + (30, 27, 14), (23, 23, 11), (17, 18, 8), (14, 14, 5), + (8, 14, 4), (5, 14, 2), (5, 14, 0), (4, 17, 1), + (5, 17, 2), (7, 17, 4), (9, 20, 6), (9, 21, 7), + (9, 21, 8), (9, 20, 9), (10, 18, 7), (10, 14, 4), + (13, 10, 4), (16, 11, 5), (21, 18, 8), (25, 27, 15), + (27, 40, 26), (29, 54, 34), (30, 64, 40), (27, 68, 43), + (27, 62, 42), (30, 55, 35), (32, 51, 26), (36, 45, 25), + (38, 44, 24), (39, 45, 21), (37, 49, 25), (35, 49, 24), + (37, 42, 22), (40, 44, 24), (44, 43, 21), (48, 38, 20), + (53, 41, 18), (56, 43, 16), (52, 45, 18), (49, 49, 18), + (48, 49, 18), (44, 51, 22), (38, 59, 30), (36, 67, 36) + ), + +// 641 Sharp +((42, 214, 25), (29, 205, 17), (28, 201, 20), (27, 197, 23), + (27, 194, 34), (28, 192, 45), (26, 186, 52), (25, 181, 59), + (19, 151, 71), (14, 130, 67), (9, 109, 63), (6, 94, 57), + (3, 80, 52), (2, 66, 59), (2, 52, 66), (3, 47, 68), + (5, 42, 71), (19, 32, 71), (30, 45, 73), (42, 58, 75), + (48, 68, 84), (54, 79, 94), (53, 80, 101), (52, 81, 109), + (55, 92, 133), (61, 108, 142), (68, 125, 151), (71, 143, 155), + (74, 162, 160), (69, 166, 159), (65, 170, 158), (54, 166, 152), + (41, 162, 142), (26, 152, 107), (23, 159, 89), (21, 166, 71), + (17, 168, 57), (14, 171, 43), (15, 172, 40), (17, 174, 37), + (43, 179, 30), (62, 184, 29), (81, 190, 28), (99, 194, 31), + (117, 199, 35), (127, 203, 38), (138, 207, 41), (146, 211, 47), + (167, 212, 49), (196, 194, 44), (194, 178, 39), (193, 163, 34), + (179, 148, 32), (165, 133, 30), (156, 126, 30), (147, 119, 31), + (118, 83, 19), (100, 67, 12), (82, 51, 6), (61, 42, 5), + (41, 34, 5), (31, 31, 5), (22, 28, 5), (9, 25, 3), + (2, 22, 3), (0, 15, 1), (0, 26, 2), (0, 37, 3), + (0, 43, 3), (0, 50, 4), (0, 62, 5), (0, 73, 6), + (0, 82, 6), (0, 86, 6), (0, 90, 7), (0, 102, 9), + (0, 114, 12), (0, 118, 19), (0, 122, 26), (0, 128, 45), + (2, 131, 64), (3, 113, 95), (4, 105, 93), (5, 98, 92), + (5, 93, 90), (5, 89, 88), (4, 78, 87), (6, 67, 87), + (10, 42, 99), (14, 37, 95), (19, 32, 91), (19, 33, 82), + (20, 35, 74), (18, 42, 55), (17, 51, 36), (14, 57, 22), + (11, 64, 14), (15, 81, 17), (19, 85, 20), (24, 89, 23), + (24, 89, 23), (24, 89, 23), (22, 87, 22), (16, 84, 18), + (7, 78, 15), (9, 72, 16), (12, 66, 17), (12, 64, 17), + (13, 63, 17), (13, 60, 17), (13, 54, 16), (12, 44, 13), + (6, 38, 8), (1, 26, 4), (1, 25, 3), (1, 24, 2), + (1, 26, 2), (1, 30, 2), (1, 32, 3), (2, 34, 4), + (8, 30, 13), (14, 29, 18), (20, 29, 24), (21, 33, 25), + (23, 38, 27), (22, 50, 28), (21, 62, 27), (19, 74, 24), + (18, 85, 24), (21, 104, 27), (23, 109, 28), (25, 115, 30), + (25, 125, 30), (23, 132, 28), (21, 136, 22), (24, 138, 17), + (46, 122, 8), (65, 116, 8), (85, 110, 8), (94, 110, 7), + (104, 110, 7), (117, 110, 7), (134, 110, 8), (149, 101, 11), + (168, 90, 10), (184, 77, 20), (185, 76, 21), (187, 75, 23), + (182, 77, 25), (173, 83, 26), (158, 84, 30), (146, 76, 27), + (115, 59, 28), (105, 57, 29), (96, 55, 31), (76, 60, 32), + (58, 69, 32), (41, 80, 34), (27, 87, 30), (21, 90, 26), + (15, 90, 20), (7, 100, 15), (6, 104, 14), (5, 108, 13), + (4, 119, 12), (3, 130, 11), (3, 140, 10), (1, 140, 7), + (0, 122, 5), (1, 115, 4), (2, 109, 4), (7, 98, 3), + (15, 90, 3), (28, 84, 2), (46, 82, 1), (66, 85, 1), + (84, 87, 1), (102, 88, 2), (120, 87, 2), (136, 91, 3), + (152, 94, 2), (164, 93, 3), (174, 98, 7), (177, 110, 12), + (171, 130, 17), (164, 136, 18), (157, 142, 19), (145, 153, 19), + (130, 155, 16), (114, 151, 15), (92, 148, 17), (77, 147, 20), + (57, 143, 21), (37, 139, 21), (21, 135, 21), (12, 128, 16), + (7, 117, 11), (1, 104, 7), (0, 91, 6), (0, 80, 5), + (0, 72, 5), (0, 62, 4), (0, 50, 3), (0, 39, 2), + (0, 28, 1), (1, 21, 1), (1, 22, 0), (1, 29, 1), + (1, 41, 2), (1, 54, 3), (2, 67, 7), (3, 80, 12), + (10, 94, 18), (17, 109, 24), (21, 128, 39), (28, 148, 60), + (35, 165, 77), (35, 175, 93), (29, 182, 110), (32, 186, 123), + (36, 182, 130), (33, 175, 139), (31, 168, 156), (39, 157, 162), + (37, 143, 159), (27, 125, 158), (23, 110, 150), (20, 94, 135), + (13, 76, 114), (5, 61, 104), (7, 47, 92), (11, 36, 76), + (19, 31, 62), (32, 26, 47), (51, 28, 31), (72, 36, 14), + (90, 46, 7), (97, 52, 10), (100, 66, 18), (105, 83, 34), + (111, 97, 55), (123, 112, 76), (141, 132, 96), (166, 151, 100), + (170, 158, 98), (166, 172, 97), (152, 183, 93), (130, 186, 93), + (105, 186, 95), (88, 192, 110), (90, 196, 113), (86, 196, 106), + (87, 201, 97), (83, 210, 77), (74, 213, 57), (58, 213, 36) + ), + +// 642 Shy_Violets +((98, 90, 82), (65, 71, 48), (60, 64, 47), (55, 57, 47), + (60, 46, 53), (65, 36, 59), (69, 33, 64), (74, 30, 70), + (84, 26, 80), (80, 38, 75), (76, 51, 70), (74, 61, 63), + (73, 72, 56), (72, 75, 56), (72, 78, 57), (72, 80, 62), + (73, 82, 68), (87, 83, 105), (96, 76, 116), (105, 70, 128), + (103, 69, 131), (101, 69, 135), (97, 72, 135), (94, 75, 136), + (77, 97, 98), (60, 105, 80), (43, 113, 63), (37, 125, 50), + (32, 138, 38), (28, 147, 32), (24, 156, 26), (17, 161, 27), + (18, 170, 28), (44, 160, 19), (50, 150, 27), (57, 140, 36), + (72, 120, 46), (87, 100, 56), (92, 89, 61), (97, 78, 66), + (99, 51, 96), (96, 45, 111), (93, 39, 126), (86, 40, 126), + (79, 41, 126), (75, 42, 124), (72, 43, 123), (73, 41, 123), + (78, 44, 116), (72, 41, 96), (75, 37, 90), (79, 34, 85), + (76, 30, 81), (73, 27, 77), (67, 26, 77), (61, 26, 77), + (45, 27, 71), (37, 36, 63), (30, 45, 55), (23, 60, 49), + (16, 76, 43), (16, 86, 39), (16, 97, 35), (11, 108, 35), + (13, 109, 35), (15, 89, 52), (14, 74, 63), (14, 60, 75), + (16, 51, 80), (19, 42, 86), (28, 28, 93), (31, 20, 94), + (46, 22, 93), (52, 29, 89), (58, 37, 85), (58, 47, 72), + (58, 57, 60), (55, 64, 58), (53, 71, 56), (46, 83, 52), + (46, 90, 41), (44, 95, 35), (53, 92, 45), (63, 89, 55), + (73, 82, 60), (83, 76, 66), (102, 62, 80), (115, 49, 90), + (129, 32, 101), (129, 24, 102), (129, 17, 104), (123, 16, 105), + (117, 16, 106), (99, 12, 97), (76, 11, 90), (63, 23, 76), + (56, 44, 64), (51, 73, 46), (50, 80, 44), (49, 87, 42), + (56, 90, 43), (64, 93, 44), (69, 85, 54), (74, 75, 71), + (86, 63, 123), (105, 67, 140), (124, 72, 157), (128, 75, 158), + (132, 79, 159), (139, 86, 170), (143, 99, 155), (140, 111, 139), + (128, 120, 112), (100, 107, 77), (88, 103, 69), (77, 99, 61), + (60, 93, 49), (55, 80, 49), (58, 64, 53), (64, 49, 61), + (88, 19, 74), (100, 12, 76), (113, 5, 78), (116, 6, 78), + (119, 7, 78), (117, 12, 73), (123, 30, 68), (119, 53, 55), + (114, 71, 46), (99, 79, 43), (95, 81, 43), (91, 84, 44), + (84, 89, 45), (77, 82, 51), (66, 63, 66), (54, 42, 81), + (37, 18, 94), (26, 14, 94), (15, 10, 94), (11, 9, 92), + (7, 8, 91), (7, 5, 92), (14, 4, 92), (28, 6, 92), + (42, 10, 91), (69, 8, 102), (79, 8, 107), (90, 9, 113), + (109, 12, 123), (124, 13, 131), (127, 16, 138), (128, 20, 140), + (123, 27, 131), (122, 27, 126), (121, 28, 122), (119, 31, 109), + (109, 31, 94), (106, 27, 84), (107, 22, 81), (112, 21, 80), + (108, 18, 85), (102, 7, 104), (100, 7, 106), (99, 8, 108), + (91, 11, 112), (86, 11, 113), (84, 9, 113), (84, 10, 108), + (76, 8, 98), (77, 7, 96), (78, 6, 95), (82, 9, 94), + (84, 11, 97), (85, 13, 102), (90, 14, 107), (99, 20, 116), + (113, 32, 134), (129, 43, 153), (142, 57, 170), (156, 69, 181), + (171, 90, 195), (185, 108, 207), (198, 123, 217), (202, 130, 221), + (199, 141, 217), (199, 139, 215), (199, 137, 214), (195, 125, 214), + (189, 112, 213), (176, 101, 208), (164, 89, 198), (148, 75, 187), + (138, 60, 181), (129, 50, 171), (123, 43, 165), (115, 35, 157), + (113, 30, 155), (119, 28, 152), (127, 27, 158), (135, 28, 163), + (144, 30, 167), (156, 41, 173), (168, 50, 181), (177, 55, 180), + (183, 52, 171), (185, 48, 162), (188, 52, 160), (179, 51, 151), + (170, 47, 138), (159, 35, 121), (157, 36, 114), (154, 43, 115), + (148, 46, 119), (138, 45, 122), (124, 45, 123), (122, 52, 130), + (117, 51, 134), (109, 47, 137), (89, 39, 130), (76, 39, 122), + (63, 36, 110), (53, 36, 100), (46, 30, 89), (49, 37, 83), + (42, 38, 90), (32, 35, 96), (21, 25, 98), (26, 27, 94), + (22, 28, 104), (25, 22, 113), (25, 17, 115), (31, 27, 102), + (27, 46, 89), (27, 63, 75), (30, 79, 66), (38, 95, 58), + (47, 103, 56), (61, 106, 56), (80, 105, 70), (101, 110, 85), + (126, 105, 106), (153, 94, 125), (174, 85, 154), (191, 94, 175), + (200, 108, 196), (204, 116, 204), (200, 121, 209), (202, 127, 209), + (206, 136, 213), (207, 138, 211), (201, 138, 206), (198, 127, 194), + (187, 116, 178), (167, 106, 156), (139, 108, 131), (117, 101, 106) + ), + +// 643 Singe +((210, 164, 86), (236, 200, 106), (227, 187, 98), (219, 175, 91), + (190, 140, 75), (161, 106, 59), (148, 90, 50), (136, 74, 42), + (76, 21, 20), (66, 13, 11), (57, 6, 3), (54, 3, 1), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (67, 13, 13), (88, 33, 19), (110, 53, 26), + (145, 79, 44), (180, 106, 63), (191, 125, 72), (203, 144, 82), + (245, 180, 106), (249, 194, 122), (253, 209, 138), (254, 215, 140), + (255, 222, 142), (254, 221, 140), (254, 220, 139), (254, 222, 132), + (253, 217, 127), (227, 182, 104), (217, 170, 86), (208, 158, 69), + (199, 146, 63), (191, 134, 58), (193, 136, 56), (195, 139, 55), + (219, 168, 74), (216, 168, 78), (213, 169, 83), (208, 162, 78), + (204, 156, 74), (191, 142, 68), (178, 129, 62), (150, 98, 45), + (127, 68, 33), (84, 26, 7), (72, 13, 3), (60, 0, 0), + (56, 0, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 0, 0), (52, 0, 0), (54, 0, 0), (57, 0, 0), + (66, 1, 1), (69, 3, 1), (72, 6, 1), (72, 5, 1), + (72, 4, 1), (69, 5, 1), (67, 6, 1), (62, 3, 0), + (59, 0, 1), (52, 0, 0), (52, 0, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (51, 1, 0), (51, 1, 0), (49, 1, 0), + (48, 1, 0), (45, 0, 0), (44, 1, 0), (39, 2, 0), + (35, 1, 0), (35, 2, 0), (38, 1, 0), (41, 0, 0), + (42, 0, 0), (44, 0, 0), (47, 0, 0), (50, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (54, 1, 0), (56, 1, 0), (59, 6, 0), + (62, 11, 0), (75, 20, 0), (93, 29, 0), (112, 52, 8), + (149, 71, 20), (202, 111, 41), (215, 118, 47), (228, 125, 54), + (242, 139, 65), (234, 147, 75), (232, 152, 76), (216, 144, 69), + (176, 119, 57), (149, 86, 41), (123, 53, 26), (112, 46, 21), + (102, 40, 16), (77, 18, 8), (63, 1, 3), (57, 0, 1), + (53, 0, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (51, 1, 0), (49, 1, 2), (48, 1, 4), + (46, 1, 3), (42, 2, 3), (40, 0, 4), (42, 1, 2), + (44, 0, 0), (46, 0, 0), (48, 0, 0), (51, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (51, 0, 0), (51, 0, 0), (51, 0, 0), + (51, 0, 0), (51, 0, 0), (51, 0, 0), (51, 0, 0), + (51, 0, 0), (52, 1, 0), (52, 1, 0), (52, 3, 0), + (57, 5, 0), (63, 13, 1), (71, 23, 4), (92, 37, 12), + (111, 53, 18), (120, 66, 14), (137, 78, 14), (142, 77, 23), + (129, 66, 15), (118, 53, 2), (105, 41, 5), (84, 20, 5), + (71, 8, 1), (67, 5, 3), (63, 0, 2), (58, 1, 1), + (57, 1, 3), (57, 0, 2), (55, 0, 0), (52, 0, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 1, 0), + (52, 1, 0), (52, 1, 0), (52, 1, 0), (52, 0, 0), + (53, 0, 0), (55, 2, 0), (62, 7, 0), (74, 19, 2), + (95, 37, 12), (121, 65, 27), (151, 99, 43), (185, 131, 63) + ), + +// 644 Slate +((72, 72, 92), (81, 81, 100), (83, 83, 103), (85, 85, 106), + (83, 83, 103), (82, 81, 100), (80, 79, 97), (78, 78, 95), + (74, 71, 88), (72, 69, 86), (71, 67, 84), (70, 67, 83), + (70, 67, 82), (69, 67, 83), (68, 67, 84), (67, 67, 84), + (67, 68, 84), (70, 70, 85), (70, 72, 87), (71, 74, 89), + (71, 76, 93), (72, 78, 97), (73, 78, 98), (74, 79, 99), + (74, 82, 103), (74, 82, 103), (74, 82, 103), (73, 81, 103), + (72, 81, 103), (71, 79, 102), (71, 78, 101), (70, 77, 101), + (68, 75, 100), (61, 70, 100), (58, 67, 98), (56, 64, 96), + (52, 61, 92), (49, 59, 88), (47, 57, 87), (46, 56, 86), + (45, 53, 84), (44, 53, 84), (44, 53, 85), (44, 54, 85), + (44, 55, 86), (44, 55, 87), (44, 55, 89), (44, 56, 90), + (44, 56, 90), (41, 55, 92), (39, 53, 92), (38, 52, 92), + (37, 51, 91), (37, 50, 90), (37, 49, 89), (37, 49, 89), + (37, 48, 88), (37, 47, 86), (38, 46, 84), (38, 46, 82), + (39, 46, 81), (40, 45, 80), (41, 45, 79), (41, 45, 79), + (41, 45, 78), (41, 45, 77), (40, 44, 76), (39, 44, 75), + (38, 43, 75), (37, 42, 75), (35, 41, 74), (34, 39, 72), + (35, 38, 68), (35, 38, 67), (35, 38, 66), (36, 38, 64), + (38, 38, 63), (38, 38, 61), (39, 38, 60), (41, 37, 57), + (41, 37, 56), (44, 37, 53), (44, 36, 52), (45, 35, 52), + (45, 35, 52), (46, 35, 52), (48, 35, 52), (50, 37, 52), + (55, 41, 55), (58, 45, 59), (61, 49, 63), (64, 52, 65), + (67, 55, 67), (72, 60, 72), (79, 67, 77), (84, 71, 81), + (88, 75, 84), (96, 82, 84), (98, 84, 83), (100, 86, 82), + (100, 86, 81), (101, 86, 81), (103, 86, 81), (104, 86, 79), + (103, 84, 79), (102, 82, 78), (101, 81, 78), (100, 80, 78), + (100, 79, 78), (97, 78, 79), (97, 77, 81), (96, 75, 82), + (96, 77, 85), (99, 79, 92), (101, 82, 94), (103, 85, 96), + (106, 89, 101), (110, 93, 104), (117, 100, 108), (124, 108, 112), + (136, 119, 121), (137, 121, 123), (139, 124, 125), (139, 123, 125), + (139, 122, 126), (136, 121, 124), (133, 118, 121), (129, 114, 115), + (125, 108, 111), (115, 99, 101), (113, 97, 100), (111, 95, 99), + (106, 89, 96), (103, 86, 95), (99, 84, 95), (96, 79, 93), + (93, 79, 93), (94, 80, 93), (96, 82, 93), (96, 83, 93), + (97, 84, 93), (99, 85, 93), (100, 86, 95), (101, 86, 95), + (101, 86, 93), (100, 86, 93), (99, 85, 92), (99, 85, 92), + (99, 84, 90), (96, 82, 89), (93, 79, 88), (89, 77, 84), + (77, 66, 77), (73, 62, 74), (70, 59, 71), (61, 52, 67), + (56, 46, 61), (52, 42, 57), (48, 39, 55), (45, 38, 53), + (45, 37, 53), (42, 35, 55), (41, 34, 55), (41, 34, 55), + (39, 34, 56), (38, 32, 57), (38, 32, 57), (38, 32, 57), + (38, 32, 59), (38, 33, 59), (38, 34, 59), (38, 34, 60), + (38, 34, 60), (38, 34, 61), (39, 35, 61), (39, 35, 63), + (38, 35, 63), (38, 37, 64), (38, 37, 64), (39, 38, 64), + (39, 38, 66), (41, 39, 64), (42, 39, 66), (42, 39, 66), + (42, 38, 64), (41, 38, 63), (41, 38, 63), (42, 37, 61), + (42, 37, 60), (44, 37, 60), (44, 35, 59), (44, 35, 57), + (44, 35, 57), (44, 35, 56), (44, 34, 56), (44, 34, 55), + (44, 34, 55), (44, 32, 55), (44, 32, 53), (44, 32, 52), + (45, 32, 52), (44, 31, 50), (44, 31, 50), (44, 30, 50), + (42, 30, 49), (42, 28, 49), (44, 30, 48), (45, 30, 48), + (46, 31, 48), (48, 31, 48), (49, 32, 49), (49, 34, 50), + (49, 35, 52), (49, 35, 53), (48, 37, 55), (48, 37, 57), + (46, 38, 59), (46, 39, 60), (48, 41, 61), (48, 42, 63), + (48, 42, 64), (48, 44, 66), (49, 45, 67), (49, 45, 70), + (49, 48, 72), (50, 49, 74), (53, 52, 78), (57, 56, 82), + (60, 61, 88), (64, 66, 93), (66, 68, 97), (67, 71, 99), + (67, 72, 100), (68, 72, 101), (67, 72, 101), (67, 72, 103), + (68, 72, 103), (68, 74, 103), (67, 72, 103), (67, 72, 103), + (64, 71, 101), (63, 71, 100), (61, 68, 99), (60, 67, 96), + (57, 63, 93), (55, 61, 90), (55, 60, 89), (55, 60, 89), + (55, 60, 89), (56, 60, 89), (56, 61, 90), (57, 61, 90), + (59, 63, 89), (60, 63, 90), (64, 66, 89), (68, 68, 90) + ), + +// 645 Slightly_Messy +((81, 121, 23), (87, 118, 22), (89, 115, 22), (92, 113, 23), + (93, 110, 23), (95, 107, 23), (96, 105, 23), (97, 104, 24), + (102, 98, 25), (107, 96, 25), (113, 95, 25), (119, 95, 24), + (126, 96, 24), (133, 96, 22), (140, 97, 21), (142, 97, 20), + (145, 97, 19), (153, 100, 17), (154, 100, 14), (156, 101, 12), + (157, 100, 9), (158, 100, 7), (157, 99, 6), (157, 99, 5), + (152, 99, 3), (148, 100, 4), (145, 102, 5), (144, 103, 10), + (143, 104, 16), (142, 104, 19), (142, 104, 22), (141, 106, 29), + (139, 108, 38), (122, 118, 62), (112, 118, 74), (102, 119, 87), + (92, 115, 94), (83, 112, 101), (77, 111, 103), (71, 110, 106), + (43, 102, 111), (34, 94, 108), (25, 86, 106), (19, 78, 101), + (13, 70, 97), (11, 66, 95), (9, 62, 93), (6, 54, 90), + (3, 47, 88), (2, 36, 86), (6, 33, 88), (10, 31, 90), + (16, 32, 94), (23, 34, 98), (27, 35, 100), (32, 36, 102), + (59, 43, 110), (73, 51, 111), (88, 59, 113), (102, 72, 111), + (116, 85, 110), (122, 92, 109), (129, 100, 108), (142, 112, 107), + (154, 122, 101), (170, 141, 90), (173, 153, 87), (177, 165, 84), + (176, 169, 83), (176, 173, 82), (174, 174, 80), (170, 172, 78), + (160, 163, 74), (151, 158, 73), (143, 153, 72), (130, 144, 72), + (118, 136, 72), (111, 128, 73), (105, 121, 74), (93, 106, 75), + (81, 90, 77), (58, 63, 76), (47, 51, 75), (36, 40, 75), + (32, 35, 74), (28, 30, 73), (24, 21, 68), (21, 15, 62), + (19, 7, 53), (19, 6, 51), (19, 6, 50), (18, 6, 49), + (18, 7, 49), (19, 8, 49), (20, 11, 50), (22, 15, 52), + (25, 22, 53), (37, 39, 55), (47, 46, 56), (57, 54, 58), + (62, 58, 58), (67, 62, 59), (79, 72, 57), (92, 81, 53), + (117, 94, 45), (125, 95, 42), (133, 96, 40), (135, 95, 38), + (138, 94, 37), (141, 91, 35), (143, 86, 34), (142, 80, 36), + (139, 74, 42), (124, 60, 60), (118, 55, 65), (112, 51, 70), + (98, 44, 80), (85, 40, 90), (73, 38, 101), (62, 39, 111), + (43, 43, 128), (37, 47, 132), (32, 52, 137), (31, 56, 137), + (31, 60, 138), (32, 67, 136), (35, 75, 131), (38, 81, 124), + (41, 85, 115), (54, 89, 95), (56, 89, 90), (59, 90, 85), + (63, 89, 73), (64, 87, 60), (65, 85, 48), (66, 80, 39), + (68, 69, 29), (66, 63, 25), (65, 57, 21), (63, 54, 19), + (62, 52, 18), (58, 48, 17), (56, 45, 16), (55, 41, 16), + (55, 37, 17), (55, 29, 22), (54, 27, 23), (54, 26, 25), + (53, 25, 28), (52, 24, 30), (51, 21, 32), (49, 19, 34), + (46, 13, 40), (45, 12, 41), (44, 11, 42), (41, 9, 44), + (40, 9, 45), (39, 8, 46), (37, 7, 48), (36, 6, 50), + (34, 6, 54), (33, 11, 64), (34, 13, 66), (35, 16, 68), + (37, 23, 73), (39, 33, 77), (40, 43, 80), (40, 54, 85), + (41, 74, 97), (41, 79, 99), (42, 84, 102), (43, 94, 102), + (43, 101, 101), (43, 106, 97), (41, 106, 92), (38, 103, 88), + (35, 99, 84), (33, 94, 78), (31, 89, 71), (31, 83, 64), + (31, 76, 57), (34, 68, 50), (36, 60, 46), (40, 54, 43), + (44, 57, 43), (46, 59, 43), (48, 61, 44), (52, 67, 46), + (58, 71, 47), (64, 79, 48), (67, 87, 50), (68, 96, 52), + (66, 103, 53), (65, 107, 53), (64, 110, 53), (65, 110, 53), + (66, 108, 51), (68, 104, 49), (70, 97, 46), (70, 89, 42), + (69, 80, 37), (69, 72, 32), (70, 65, 28), (73, 56, 24), + (75, 46, 20), (77, 36, 16), (78, 27, 13), (79, 21, 10), + (82, 17, 7), (84, 16, 7), (87, 16, 7), (90, 18, 9), + (91, 20, 11), (93, 22, 15), (94, 23, 21), (94, 24, 29), + (94, 26, 38), (93, 30, 48), (91, 33, 57), (87, 36, 67), + (82, 38, 76), (76, 40, 84), (70, 43, 90), (64, 47, 93), + (59, 52, 95), (54, 57, 95), (48, 64, 91), (45, 71, 85), + (43, 77, 75), (43, 82, 65), (46, 86, 55), (48, 90, 45), + (52, 94, 36), (58, 99, 27), (65, 104, 19), (72, 107, 12), + (78, 109, 8), (81, 110, 7), (83, 109, 9), (83, 109, 11), + (82, 109, 14), (81, 109, 16), (80, 110, 18), (79, 110, 21), + (76, 109, 23), (72, 109, 25), (67, 110, 27), (61, 110, 27), + (58, 112, 28), (57, 113, 27), (59, 115, 27), (63, 116, 27), + (67, 117, 26), (70, 119, 26), (74, 120, 25), (77, 121, 24) + ), + +// 646 Smog +((47, 52, 45), (48, 51, 45), (48, 50, 45), (48, 50, 45), + (48, 49, 45), (48, 49, 45), (48, 48, 45), (48, 48, 46), + (48, 47, 45), (46, 46, 44), (45, 45, 44), (43, 43, 42), + (42, 42, 41), (40, 41, 39), (38, 40, 38), (37, 39, 37), + (36, 38, 37), (33, 36, 34), (33, 36, 34), (33, 37, 34), + (36, 39, 36), (39, 42, 39), (42, 45, 42), (46, 49, 45), + (65, 67, 60), (74, 75, 68), (83, 84, 77), (94, 93, 86), + (106, 102, 95), (113, 107, 100), (120, 113, 106), (132, 123, 116), + (140, 129, 123), (141, 127, 123), (139, 123, 121), (137, 119, 119), + (133, 115, 116), (130, 112, 113), (125, 108, 109), (121, 105, 105), + (95, 84, 84), (85, 77, 76), (76, 70, 69), (70, 66, 64), + (64, 62, 59), (61, 60, 56), (58, 58, 54), (53, 54, 50), + (49, 51, 47), (46, 48, 45), (46, 48, 45), (46, 48, 45), + (46, 47, 45), (46, 46, 45), (46, 45, 44), (46, 45, 44), + (44, 45, 43), (43, 44, 42), (42, 44, 41), (41, 43, 40), + (40, 42, 40), (40, 42, 39), (40, 42, 39), (40, 43, 40), + (41, 45, 41), (47, 52, 45), (52, 56, 50), (57, 61, 55), + (59, 64, 57), (62, 67, 60), (68, 73, 65), (72, 78, 69), + (80, 89, 78), (83, 92, 81), (86, 96, 84), (84, 95, 83), + (83, 94, 82), (81, 92, 80), (79, 91, 79), (75, 87, 75), + (71, 83, 72), (68, 78, 68), (67, 75, 66), (66, 73, 64), + (65, 72, 63), (65, 71, 63), (66, 70, 63), (68, 72, 64), + (74, 76, 68), (75, 76, 69), (76, 77, 70), (75, 76, 69), + (75, 75, 69), (72, 74, 68), (70, 73, 66), (67, 71, 64), + (65, 70, 63), (58, 64, 59), (55, 62, 57), (52, 61, 55), + (51, 61, 54), (51, 61, 54), (51, 61, 54), (52, 61, 54), + (54, 64, 56), (55, 65, 57), (57, 67, 58), (58, 67, 58), + (59, 67, 59), (60, 68, 60), (62, 67, 60), (62, 67, 60), + (62, 67, 60), (61, 65, 58), (60, 64, 57), (59, 63, 56), + (57, 60, 54), (55, 57, 52), (54, 56, 50), (52, 55, 49), + (49, 53, 47), (48, 52, 46), (47, 51, 45), (47, 51, 44), + (47, 51, 44), (47, 51, 44), (47, 52, 44), (47, 52, 45), + (47, 52, 45), (48, 51, 45), (48, 51, 45), (48, 51, 45), + (48, 50, 45), (48, 49, 45), (48, 49, 45), (48, 48, 46), + (48, 47, 45), (46, 46, 44), (45, 45, 44), (44, 44, 43), + (43, 44, 42), (42, 42, 41), (40, 41, 40), (38, 40, 38), + (36, 38, 37), (33, 36, 34), (33, 36, 34), (33, 36, 34), + (33, 37, 34), (35, 38, 36), (39, 42, 39), (46, 49, 45), + (65, 67, 60), (69, 71, 64), (74, 76, 69), (83, 84, 77), + (93, 92, 85), (106, 102, 95), (120, 113, 106), (132, 123, 116), + (140, 129, 123), (141, 127, 123), (139, 125, 122), (138, 123, 121), + (137, 119, 119), (135, 116, 117), (130, 112, 113), (121, 105, 105), + (95, 84, 84), (89, 80, 79), (84, 76, 75), (76, 70, 69), + (70, 66, 64), (64, 62, 59), (58, 58, 54), (53, 54, 50), + (49, 51, 47), (47, 49, 45), (46, 48, 45), (47, 48, 45), + (46, 48, 45), (46, 47, 45), (46, 46, 45), (46, 45, 44), + (44, 45, 43), (43, 45, 42), (43, 45, 42), (42, 44, 41), + (41, 44, 40), (40, 42, 40), (40, 42, 39), (40, 43, 40), + (41, 45, 41), (43, 48, 43), (47, 52, 45), (51, 56, 50), + (57, 61, 55), (62, 67, 60), (68, 73, 65), (72, 78, 69), + (76, 84, 74), (80, 89, 78), (83, 93, 82), (86, 96, 84), + (85, 96, 85), (83, 94, 82), (79, 91, 79), (75, 87, 75), + (71, 83, 72), (69, 81, 70), (68, 78, 68), (67, 76, 66), + (66, 73, 64), (65, 71, 63), (66, 70, 63), (68, 72, 64), + (71, 74, 65), (74, 76, 68), (76, 77, 69), (76, 77, 70), + (75, 75, 69), (72, 74, 68), (70, 73, 66), (67, 71, 64), + (65, 70, 63), (62, 67, 61), (58, 64, 59), (55, 62, 57), + (52, 61, 55), (51, 61, 54), (51, 61, 54), (52, 61, 54), + (52, 62, 55), (54, 64, 56), (55, 65, 57), (57, 67, 58), + (59, 67, 59), (60, 68, 60), (62, 67, 60), (62, 67, 60), + (62, 67, 60), (62, 67, 59), (61, 65, 58), (59, 63, 56), + (57, 60, 54), (55, 57, 52), (54, 56, 50), (52, 55, 49), + (50, 54, 47), (49, 53, 47), (48, 52, 46), (47, 51, 45), + (47, 51, 44), (47, 51, 44), (47, 52, 44), (47, 52, 45) + ), + +// 647 Sno_and_Shadows +((8, 19, 22), (11, 20, 32), (8, 16, 34), (6, 12, 36), + (5, 9, 38), (4, 7, 40), (2, 5, 40), (1, 4, 41), + (0, 4, 47), (6, 11, 59), (12, 18, 71), (23, 37, 90), + (34, 57, 109), (59, 78, 129), (85, 100, 149), (93, 111, 155), + (102, 122, 162), (133, 147, 172), (122, 135, 153), (112, 123, 135), + (95, 106, 120), (79, 89, 105), (71, 81, 100), (63, 74, 96), + (38, 51, 96), (37, 52, 98), (37, 54, 101), (29, 49, 98), + (22, 45, 96), (22, 43, 93), (22, 41, 91), (21, 39, 94), + (24, 43, 99), (36, 56, 109), (63, 81, 127), (90, 107, 146), + (118, 134, 169), (146, 161, 193), (165, 177, 202), (184, 194, 212), + (228, 234, 243), (238, 243, 248), (249, 252, 253), (251, 252, 253), + (254, 252, 253), (254, 252, 253), (254, 253, 253), (252, 253, 255), + (245, 247, 251), (225, 230, 238), (210, 214, 226), (195, 199, 214), + (185, 191, 213), (175, 184, 213), (178, 184, 211), (182, 185, 210), + (204, 209, 230), (218, 222, 234), (232, 235, 238), (227, 234, 239), + (223, 234, 241), (216, 227, 235), (209, 221, 230), (186, 202, 216), + (157, 176, 210), (129, 153, 191), (119, 144, 181), (110, 135, 172), + (108, 132, 166), (107, 130, 160), (92, 114, 147), (74, 91, 123), + (41, 53, 83), (31, 45, 69), (22, 38, 56), (21, 37, 53), + (21, 36, 50), (22, 37, 52), (23, 39, 55), (26, 43, 68), + (37, 54, 86), (59, 77, 137), (85, 104, 158), (111, 132, 179), + (122, 144, 191), (134, 157, 204), (163, 182, 215), (185, 198, 223), + (202, 214, 231), (197, 205, 221), (192, 196, 211), (188, 193, 205), + (185, 191, 199), (177, 182, 192), (172, 179, 191), (178, 187, 193), + (188, 194, 198), (216, 222, 225), (226, 231, 235), (236, 240, 245), + (237, 241, 246), (239, 243, 248), (233, 239, 247), (221, 227, 239), + (186, 192, 216), (171, 177, 209), (156, 163, 202), (152, 161, 202), + (148, 159, 203), (142, 155, 208), (151, 162, 213), (169, 179, 226), + (187, 198, 234), (223, 228, 244), (227, 234, 247), (232, 241, 251), + (232, 243, 250), (222, 233, 238), (202, 216, 228), (179, 195, 217), + (141, 154, 171), (128, 141, 164), (116, 128, 158), (115, 125, 154), + (115, 123, 151), (113, 120, 146), (95, 109, 154), (78, 94, 149), + (69, 82, 132), (27, 45, 97), (21, 36, 84), (15, 28, 71), + (9, 18, 54), (8, 15, 42), (8, 13, 34), (7, 12, 32), + (17, 22, 45), (21, 30, 58), (26, 38, 72), (35, 50, 83), + (44, 62, 94), (66, 86, 117), (87, 104, 139), (113, 131, 159), + (140, 154, 176), (189, 198, 201), (190, 199, 201), (192, 201, 202), + (201, 201, 198), (199, 202, 196), (180, 191, 185), (169, 174, 169), + (148, 153, 160), (145, 152, 160), (142, 151, 161), (146, 156, 157), + (147, 159, 160), (143, 156, 165), (137, 147, 151), (118, 127, 130), + (88, 104, 115), (52, 58, 81), (39, 47, 73), (27, 37, 66), + (20, 27, 54), (14, 20, 44), (10, 15, 37), (11, 13, 32), + (11, 18, 39), (14, 21, 46), (17, 25, 53), (23, 33, 70), + (29, 42, 86), (34, 49, 97), (39, 56, 113), (38, 57, 124), + (34, 54, 124), (37, 53, 129), (34, 47, 126), (29, 44, 119), + (34, 49, 126), (51, 59, 130), (74, 82, 137), (99, 111, 162), + (172, 179, 208), (186, 193, 218), (200, 208, 228), (213, 225, 231), + (216, 227, 226), (208, 219, 219), (183, 200, 198), (154, 168, 172), + (120, 134, 149), (89, 103, 134), (70, 82, 118), (50, 64, 103), + (36, 50, 97), (30, 45, 93), (25, 39, 87), (23, 34, 85), + (17, 34, 79), (13, 29, 65), (15, 26, 57), (16, 30, 53), + (15, 32, 44), (15, 31, 35), (16, 27, 30), (12, 22, 28), + (8, 21, 26), (6, 14, 20), (4, 10, 18), (4, 13, 19), + (5, 13, 18), (6, 12, 17), (5, 13, 18), (5, 13, 17), + (5, 11, 15), (5, 8, 15), (5, 8, 13), (4, 8, 12), + (4, 8, 14), (5, 9, 18), (4, 10, 24), (3, 12, 37), + (4, 16, 53), (6, 22, 69), (10, 30, 86), (15, 35, 98), + (18, 39, 104), (23, 43, 99), (25, 43, 93), (22, 41, 89), + (19, 35, 79), (16, 32, 66), (11, 30, 60), (11, 27, 56), + (13, 25, 48), (14, 26, 40), (13, 24, 32), (12, 25, 30), + (13, 28, 32), (15, 28, 30), (13, 26, 29), (10, 23, 30), + (11, 23, 28), (11, 17, 25), (7, 10, 21), (4, 6, 17), + (3, 5, 14), (1, 5, 12), (0, 6, 12), (1, 6, 12), + (3, 9, 13), (6, 18, 19), (8, 21, 22), (7, 16, 18) + ), + +// 648 Snowy_Field +((124, 176, 180), (121, 174, 176), (128, 178, 181), (135, 182, 186), + (133, 176, 179), (131, 170, 173), (131, 166, 169), (131, 162, 166), + (128, 153, 159), (127, 153, 160), (126, 153, 161), (124, 155, 163), + (122, 157, 166), (123, 154, 165), (124, 151, 165), (123, 149, 161), + (122, 147, 158), (122, 125, 135), (124, 113, 123), (127, 102, 111), + (124, 94, 103), (122, 86, 95), (121, 85, 94), (120, 85, 93), + (123, 95, 105), (124, 104, 113), (126, 114, 122), (130, 129, 136), + (134, 144, 151), (138, 150, 156), (142, 156, 161), (146, 169, 172), + (152, 179, 181), (161, 196, 198), (164, 197, 199), (167, 198, 201), + (165, 193, 196), (164, 188, 192), (163, 181, 186), (163, 175, 180), + (143, 145, 152), (129, 127, 134), (115, 109, 116), (101, 94, 102), + (88, 79, 88), (83, 71, 79), (78, 64, 71), (72, 53, 60), + (68, 47, 56), (76, 46, 60), (82, 54, 67), (88, 62, 74), + (95, 75, 86), (103, 88, 99), (107, 96, 106), (111, 104, 114), + (123, 139, 147), (128, 153, 159), (134, 168, 172), (139, 179, 182), + (145, 190, 193), (147, 193, 196), (149, 197, 200), (151, 200, 202), + (153, 203, 203), (151, 198, 199), (145, 187, 189), (139, 177, 180), + (133, 168, 171), (128, 160, 163), (114, 140, 144), (98, 118, 125), + (79, 86, 99), (77, 76, 89), (75, 67, 79), (83, 72, 87), + (91, 78, 95), (98, 85, 101), (105, 93, 108), (119, 107, 121), + (130, 125, 135), (141, 156, 162), (143, 161, 167), (145, 167, 172), + (144, 166, 171), (144, 165, 170), (136, 159, 161), (135, 149, 151), + (133, 118, 127), (129, 105, 113), (125, 92, 100), (121, 86, 94), + (117, 80, 88), (114, 70, 82), (111, 66, 79), (108, 66, 78), + (103, 66, 77), (95, 66, 82), (95, 72, 87), (95, 78, 92), + (95, 80, 93), (96, 83, 95), (97, 86, 97), (97, 91, 99), + (101, 94, 98), (100, 91, 95), (99, 88, 93), (96, 88, 92), + (94, 88, 91), (92, 84, 91), (88, 77, 85), (87, 65, 79), + (83, 62, 75), (92, 68, 81), (94, 68, 82), (96, 69, 83), + (99, 73, 85), (104, 82, 97), (116, 95, 109), (123, 107, 121), + (140, 134, 145), (156, 147, 157), (173, 160, 169), (180, 167, 173), + (187, 174, 178), (199, 185, 185), (213, 195, 191), (228, 204, 197), + (239, 208, 203), (240, 219, 206), (240, 221, 207), (240, 224, 208), + (240, 225, 212), (232, 223, 212), (219, 220, 210), (207, 220, 208), + (188, 210, 204), (184, 203, 197), (181, 197, 191), (181, 195, 190), + (181, 193, 190), (185, 192, 187), (195, 192, 186), (204, 195, 186), + (207, 199, 190), (192, 200, 194), (187, 197, 193), (182, 194, 193), + (170, 187, 189), (152, 177, 180), (133, 169, 173), (123, 157, 166), + (128, 145, 160), (129, 146, 159), (131, 148, 159), (141, 155, 165), + (156, 164, 170), (172, 173, 175), (179, 180, 179), (183, 182, 184), + (185, 185, 183), (181, 175, 165), (180, 170, 162), (180, 166, 159), + (177, 162, 159), (175, 155, 157), (168, 150, 151), (166, 147, 146), + (159, 142, 146), (155, 138, 142), (152, 135, 139), (143, 126, 129), + (135, 118, 123), (125, 109, 118), (119, 104, 114), (116, 102, 110), + (114, 102, 111), (113, 102, 114), (112, 108, 121), (112, 114, 126), + (109, 121, 130), (109, 123, 132), (110, 126, 132), (111, 125, 130), + (100, 113, 123), (98, 110, 119), (97, 107, 116), (97, 101, 110), + (97, 96, 105), (94, 90, 100), (91, 87, 98), (90, 88, 98), + (94, 91, 99), (96, 94, 100), (99, 97, 104), (101, 104, 110), + (108, 107, 117), (116, 111, 122), (123, 116, 129), (127, 125, 134), + (133, 133, 141), (147, 144, 150), (161, 158, 162), (174, 175, 173), + (185, 190, 184), (200, 205, 194), (214, 219, 206), (228, 232, 216), + (238, 239, 223), (245, 244, 226), (249, 245, 227), (250, 246, 225), + (249, 245, 222), (246, 245, 219), (242, 241, 216), (240, 236, 210), + (237, 230, 204), (232, 227, 202), (223, 224, 205), (211, 222, 206), + (200, 217, 205), (195, 215, 205), (186, 212, 209), (176, 211, 210), + (164, 209, 210), (159, 207, 207), (155, 203, 206), (154, 199, 201), + (152, 197, 198), (152, 189, 190), (150, 180, 183), (149, 169, 174), + (146, 162, 167), (146, 151, 156), (149, 139, 145), (154, 130, 138), + (163, 125, 134), (170, 122, 133), (171, 118, 131), (167, 120, 132), + (169, 119, 128), (174, 119, 126), (178, 114, 123), (167, 114, 124), + (155, 115, 122), (144, 116, 118), (144, 114, 116), (144, 114, 117), + (144, 118, 122), (135, 123, 129), (129, 131, 137), (124, 137, 143), + (120, 142, 147), (115, 138, 146), (119, 150, 155), (124, 160, 167) + ), + +// 649 Snuggle +((120, 26, 61), (118, 24, 56), (116, 24, 52), (114, 24, 49), + (121, 20, 46), (129, 17, 43), (134, 15, 41), (140, 14, 40), + (140, 16, 33), (133, 20, 29), (126, 25, 25), (119, 29, 30), + (112, 33, 35), (113, 39, 48), (114, 45, 62), (113, 44, 68), + (112, 44, 74), (107, 46, 92), (101, 43, 95), (95, 40, 98), + (92, 43, 106), (89, 46, 115), (87, 46, 121), (85, 47, 128), + (77, 51, 152), (76, 51, 153), (76, 51, 154), (83, 51, 146), + (90, 51, 138), (98, 53, 133), (107, 56, 128), (120, 62, 123), + (128, 70, 121), (136, 98, 125), (137, 110, 123), (138, 122, 122), + (142, 129, 116), (146, 137, 110), (150, 137, 108), (155, 137, 107), + (160, 145, 118), (161, 150, 128), (163, 156, 138), (155, 160, 145), + (147, 164, 153), (142, 160, 153), (137, 156, 153), (121, 147, 153), + (104, 139, 154), (81, 122, 138), (83, 113, 132), (85, 104, 126), + (91, 91, 115), (98, 79, 104), (100, 73, 100), (103, 67, 97), + (101, 51, 78), (99, 46, 79), (98, 41, 81), (102, 36, 88), + (107, 32, 96), (112, 29, 104), (118, 26, 112), (132, 25, 122), + (145, 24, 129), (158, 27, 132), (161, 30, 131), (164, 33, 130), + (165, 32, 131), (166, 31, 133), (168, 33, 132), (172, 33, 127), + (184, 38, 100), (192, 46, 84), (200, 54, 69), (203, 56, 58), + (207, 59, 48), (207, 58, 45), (207, 58, 42), (206, 57, 38), + (202, 55, 34), (195, 52, 37), (186, 50, 37), (178, 49, 38), + (172, 47, 38), (166, 46, 38), (154, 40, 36), (141, 35, 34), + (133, 18, 39), (129, 16, 39), (126, 14, 39), (123, 14, 40), + (121, 15, 41), (112, 15, 41), (101, 17, 40), (94, 19, 42), + (92, 19, 44), (95, 24, 47), (96, 33, 50), (97, 43, 54), + (94, 49, 53), (91, 56, 53), (81, 69, 55), (73, 80, 66), + (66, 86, 79), (71, 87, 87), (77, 89, 95), (81, 92, 96), + (85, 95, 98), (92, 100, 92), (99, 104, 95), (106, 104, 92), + (112, 101, 88), (119, 76, 90), (121, 71, 94), (123, 66, 98), + (125, 58, 94), (125, 49, 98), (124, 44, 98), (118, 39, 95), + (93, 29, 81), (82, 27, 78), (72, 25, 75), (69, 26, 79), + (66, 27, 83), (69, 38, 97), (76, 48, 112), (82, 66, 124), + (90, 76, 133), (100, 92, 140), (100, 90, 140), (101, 89, 140), + (103, 88, 148), (110, 88, 158), (114, 93, 167), (121, 95, 172), + (133, 99, 174), (133, 94, 172), (134, 89, 171), (136, 87, 171), + (138, 85, 172), (140, 81, 168), (144, 79, 160), (148, 74, 148), + (154, 66, 133), (165, 66, 123), (166, 71, 129), (167, 76, 136), + (165, 89, 150), (160, 108, 163), (151, 127, 171), (138, 137, 172), + (115, 143, 170), (111, 140, 172), (107, 137, 175), (99, 132, 183), + (87, 135, 199), (78, 141, 213), (68, 148, 220), (55, 150, 220), + (46, 150, 222), (45, 132, 213), (44, 124, 211), (44, 117, 209), + (44, 97, 208), (45, 85, 208), (40, 72, 207), (35, 63, 206), + (37, 55, 200), (40, 52, 194), (44, 49, 189), (53, 41, 176), + (65, 36, 164), (75, 33, 155), (86, 26, 146), (99, 21, 137), + (108, 20, 130), (121, 20, 127), (137, 27, 123), (150, 36, 116), + (160, 37, 101), (165, 36, 93), (168, 33, 91), (162, 34, 93), + (152, 38, 110), (151, 47, 120), (150, 56, 131), (156, 67, 138), + (159, 78, 149), (164, 91, 157), (162, 106, 160), (155, 114, 161), + (150, 110, 161), (140, 114, 166), (140, 117, 163), (143, 116, 159), + (152, 118, 153), (165, 117, 140), (174, 121, 125), (186, 114, 112), + (184, 103, 100), (175, 92, 88), (162, 75, 79), (148, 60, 79), + (138, 48, 82), (127, 46, 84), (127, 43, 90), (128, 41, 98), + (126, 35, 108), (120, 30, 113), (113, 24, 117), (103, 25, 121), + (95, 29, 120), (90, 30, 118), (87, 32, 112), (82, 33, 111), + (76, 41, 104), (82, 41, 93), (85, 41, 84), (92, 42, 72), + (101, 44, 65), (111, 44, 60), (118, 42, 64), (114, 49, 72), + (111, 50, 81), (105, 51, 87), (100, 50, 90), (102, 49, 92), + (107, 45, 92), (113, 35, 96), (113, 34, 102), (109, 29, 111), + (103, 26, 116), (94, 25, 114), (84, 24, 111), (73, 21, 104), + (63, 18, 94), (57, 23, 89), (53, 29, 92), (51, 31, 97), + (44, 35, 98), (36, 41, 97), (29, 44, 97), (24, 46, 91), + (20, 47, 86), (19, 52, 86), (26, 50, 87), (35, 49, 89), + (44, 51, 87), (53, 51, 86), (62, 51, 81), (71, 47, 73), + (78, 45, 66), (90, 40, 60), (102, 35, 61), (115, 31, 62) + ), + +// 650 Soap_Bubble +((112, 150, 197), (89, 188, 214), (87, 207, 218), (85, 226, 222), + (103, 230, 220), (122, 234, 219), (131, 230, 217), (141, 226, 216), + (169, 195, 209), (174, 174, 198), (180, 154, 187), (169, 135, 168), + (159, 116, 150), (145, 104, 134), (131, 92, 118), (126, 93, 115), + (121, 95, 112), (97, 114, 125), (86, 129, 130), (76, 144, 135), + (66, 165, 143), (57, 186, 152), (57, 194, 162), (58, 203, 173), + (68, 218, 187), (60, 213, 175), (52, 208, 163), (48, 195, 157), + (44, 182, 152), (42, 176, 156), (40, 171, 160), (37, 158, 159), + (38, 154, 157), (71, 135, 142), (77, 115, 148), (84, 95, 154), + (91, 92, 152), (99, 90, 150), (112, 91, 143), (126, 93, 136), + (152, 105, 135), (150, 106, 146), (149, 107, 158), (169, 107, 157), + (190, 108, 156), (197, 108, 152), (204, 108, 149), (210, 118, 135), + (205, 115, 132), (218, 116, 125), (224, 115, 111), (231, 115, 97), + (228, 110, 85), (226, 105, 74), (223, 103, 77), (220, 101, 81), + (209, 97, 119), (202, 91, 134), (196, 85, 149), (195, 81, 161), + (195, 77, 173), (198, 78, 175), (201, 79, 178), (197, 97, 181), + (189, 116, 177), (172, 156, 159), (168, 171, 151), (165, 186, 143), + (156, 194, 142), (147, 202, 141), (123, 204, 139), (99, 213, 138), + (75, 223, 140), (61, 220, 149), (48, 218, 158), (51, 206, 165), + (55, 195, 173), (66, 187, 170), (77, 179, 167), (101, 174, 171), + (124, 161, 174), (159, 126, 191), (180, 104, 197), (201, 83, 203), + (207, 77, 207), (213, 72, 211), (223, 69, 226), (216, 71, 237), + (207, 60, 241), (203, 60, 236), (200, 61, 232), (197, 65, 227), + (194, 70, 223), (193, 79, 206), (188, 91, 189), (175, 106, 168), + (156, 127, 149), (120, 158, 115), (108, 159, 93), (97, 161, 72), + (88, 161, 64), (79, 161, 56), (71, 170, 53), (76, 166, 62), + (107, 136, 74), (118, 115, 84), (129, 95, 94), (132, 92, 105), + (135, 89, 116), (138, 87, 129), (136, 87, 132), (125, 85, 122), + (123, 89, 118), (127, 127, 120), (128, 136, 119), (129, 146, 119), + (128, 159, 110), (138, 167, 110), (152, 179, 120), (170, 194, 129), + (198, 220, 147), (202, 221, 159), (207, 222, 171), (207, 220, 177), + (208, 218, 183), (212, 207, 198), (214, 199, 204), (206, 189, 201), + (202, 178, 206), (189, 175, 220), (191, 168, 223), (193, 161, 226), + (192, 143, 217), (194, 114, 205), (185, 93, 186), (178, 87, 172), + (184, 80, 149), (195, 64, 127), (206, 49, 106), (209, 43, 97), + (212, 38, 88), (220, 31, 87), (224, 32, 96), (223, 37, 101), + (217, 36, 112), (177, 35, 117), (169, 35, 123), (161, 36, 129), + (146, 41, 139), (129, 41, 154), (104, 40, 172), (73, 44, 178), + (42, 59, 186), (40, 63, 187), (39, 67, 188), (42, 71, 195), + (43, 73, 198), (48, 69, 194), (69, 66, 179), (97, 63, 155), + (123, 66, 130), (161, 75, 99), (168, 81, 96), (176, 88, 93), + (199, 103, 82), (219, 126, 72), (231, 146, 68), (237, 158, 73), + (233, 181, 113), (233, 185, 124), (233, 189, 136), (236, 190, 148), + (236, 178, 154), (239, 159, 160), (237, 138, 168), (228, 119, 184), + (217, 96, 192), (207, 80, 199), (192, 64, 203), (175, 51, 205), + (152, 42, 215), (124, 30, 222), (104, 32, 232), (83, 42, 237), + (59, 84, 244), (56, 89, 242), (54, 95, 241), (56, 108, 237), + (55, 123, 232), (46, 143, 225), (41, 173, 224), (42, 189, 222), + (61, 201, 220), (79, 200, 220), (92, 200, 211), (103, 209, 199), + (108, 216, 187), (121, 226, 174), (135, 229, 172), (146, 230, 163), + (147, 232, 145), (140, 235, 129), (127, 236, 110), (116, 235, 107), + (111, 229, 108), (96, 229, 105), (84, 229, 101), (71, 228, 102), + (67, 231, 109), (80, 227, 120), (98, 226, 130), (123, 228, 137), + (141, 230, 148), (159, 235, 163), (170, 234, 173), (174, 235, 185), + (177, 233, 195), (178, 228, 204), (169, 219, 217), (153, 197, 222), + (131, 177, 230), (102, 153, 234), (87, 131, 238), (67, 113, 242), + (50, 91, 241), (46, 72, 241), (44, 54, 239), (55, 43, 242), + (70, 35, 244), (81, 33, 244), (91, 42, 236), (98, 49, 223), + (102, 61, 204), (105, 61, 189), (112, 57, 176), (132, 64, 159), + (144, 71, 143), (155, 97, 122), (160, 117, 108), (160, 130, 101), + (175, 134, 102), (189, 135, 106), (202, 141, 114), (214, 146, 128), + (214, 154, 143), (214, 145, 161), (216, 129, 173), (214, 112, 178), + (214, 90, 180), (208, 80, 182), (195, 76, 189), (190, 65, 194), + (166, 77, 194), (149, 90, 194), (134, 108, 187), (109, 140, 192) + ), + +// 651 Sophia +((170, 128, 57), (151, 105, 51), (145, 99, 50), (139, 93, 49), + (129, 82, 45), (120, 71, 42), (117, 67, 40), (115, 63, 39), + (113, 55, 43), (116, 60, 46), (120, 66, 49), (126, 73, 48), + (133, 80, 48), (141, 85, 48), (149, 91, 49), (154, 95, 52), + (159, 100, 55), (175, 116, 67), (179, 118, 68), (184, 121, 69), + (181, 122, 72), (178, 124, 76), (175, 124, 78), (172, 125, 80), + (167, 123, 83), (164, 124, 85), (162, 125, 88), (158, 130, 86), + (155, 135, 85), (155, 136, 84), (155, 137, 84), (161, 136, 83), + (163, 131, 83), (160, 121, 75), (152, 110, 67), (145, 100, 59), + (135, 86, 55), (125, 73, 52), (118, 67, 52), (111, 61, 53), + (98, 53, 49), (94, 50, 45), (91, 47, 42), (85, 44, 44), + (80, 42, 47), (79, 42, 45), (78, 42, 43), (78, 43, 38), + (79, 41, 27), (73, 27, 17), (66, 21, 12), (59, 15, 8), + (56, 12, 5), (54, 10, 3), (56, 9, 3), (58, 8, 4), + (67, 6, 6), (72, 10, 6), (78, 14, 6), (77, 17, 8), + (77, 20, 10), (76, 20, 11), (75, 20, 13), (75, 21, 16), + (77, 24, 15), (65, 30, 11), (58, 28, 11), (52, 27, 11), + (52, 26, 12), (53, 25, 13), (61, 31, 16), (71, 41, 21), + (103, 76, 38), (119, 89, 48), (135, 102, 59), (144, 112, 72), + (154, 122, 86), (159, 130, 96), (165, 138, 106), (176, 156, 126), + (186, 174, 148), (197, 187, 157), (198, 186, 158), (199, 186, 159), + (200, 190, 162), (201, 194, 165), (209, 206, 163), (217, 220, 155), + (228, 217, 133), (224, 204, 122), (220, 191, 111), (216, 187, 105), + (213, 184, 100), (201, 167, 91), (190, 154, 82), (178, 130, 75), + (159, 107, 69), (133, 77, 68), (126, 76, 75), (120, 76, 83), + (120, 79, 91), (120, 82, 99), (124, 93, 116), (133, 106, 135), + (153, 133, 159), (166, 146, 161), (179, 159, 163), (184, 165, 160), + (190, 171, 157), (197, 171, 155), (198, 168, 143), (199, 158, 125), + (198, 145, 107), (186, 119, 76), (179, 110, 72), (173, 102, 69), + (157, 86, 64), (145, 73, 61), (137, 62, 60), (128, 56, 63), + (111, 50, 75), (107, 55, 81), (103, 61, 87), (102, 64, 89), + (102, 68, 92), (104, 76, 98), (105, 83, 103), (110, 88, 105), + (119, 97, 112), (133, 109, 131), (134, 111, 134), (136, 113, 137), + (138, 110, 135), (141, 109, 130), (138, 109, 126), (139, 102, 127), + (137, 93, 121), (133, 92, 113), (129, 92, 105), (127, 91, 103), + (126, 90, 101), (127, 91, 98), (133, 93, 96), (143, 98, 92), + (152, 110, 90), (164, 128, 92), (166, 130, 92), (168, 132, 93), + (169, 131, 89), (167, 129, 79), (160, 121, 71), (154, 110, 62), + (138, 88, 62), (133, 85, 61), (129, 82, 61), (116, 76, 60), + (105, 69, 55), (96, 59, 50), (89, 48, 47), (79, 39, 43), + (68, 34, 38), (42, 29, 25), (39, 26, 23), (36, 24, 21), + (30, 17, 17), (27, 10, 13), (25, 10, 8), (28, 14, 5), + (49, 31, 12), (55, 35, 13), (62, 39, 15), (73, 47, 17), + (86, 53, 18), (102, 62, 24), (114, 69, 29), (122, 77, 35), + (124, 82, 40), (125, 82, 46), (127, 82, 53), (129, 82, 60), + (130, 83, 63), (131, 83, 61), (130, 81, 62), (133, 78, 61), + (147, 75, 62), (149, 74, 58), (151, 73, 54), (153, 72, 50), + (154, 71, 43), (160, 72, 45), (166, 78, 50), (170, 82, 52), + (167, 88, 56), (162, 90, 53), (157, 92, 54), (152, 93, 55), + (145, 90, 53), (135, 85, 54), (124, 75, 48), (113, 66, 39), + (99, 54, 32), (83, 42, 21), (65, 31, 17), (52, 19, 13), + (50, 14, 10), (54, 11, 10), (61, 13, 9), (66, 17, 11), + (69, 20, 15), (78, 26, 21), (90, 31, 32), (103, 35, 43), + (114, 40, 50), (122, 43, 51), (130, 48, 51), (140, 52, 56), + (147, 59, 66), (146, 67, 78), (144, 78, 87), (147, 91, 89), + (157, 107, 89), (174, 124, 92), (186, 138, 98), (192, 152, 108), + (192, 162, 116), (189, 173, 122), (187, 182, 128), (187, 188, 133), + (192, 192, 147), (196, 196, 157), (196, 196, 172), (192, 199, 186), + (190, 204, 194), (192, 208, 199), (200, 220, 196), (207, 222, 192), + (209, 217, 188), (207, 212, 187), (201, 198, 181), (195, 191, 176), + (183, 182, 163), (176, 166, 150), (165, 151, 147), (158, 134, 143), + (156, 122, 146), (151, 121, 146), (157, 124, 140), (164, 129, 134), + (171, 133, 124), (180, 135, 112), (184, 136, 104), (184, 138, 92), + (189, 147, 88), (192, 154, 86), (190, 156, 78), (186, 149, 70) + ), + +// 652 Strawberries +((108, 0, 9), (116, 2, 9), (117, 3, 9), (119, 4, 10), + (118, 4, 10), (117, 5, 11), (116, 4, 11), (115, 4, 12), + (103, 5, 11), (97, 5, 12), (92, 6, 13), (89, 5, 13), + (87, 4, 14), (85, 3, 13), (84, 2, 12), (83, 1, 12), + (83, 1, 12), (83, 0, 12), (83, 0, 12), (83, 0, 12), + (81, 2, 14), (80, 5, 16), (78, 7, 18), (77, 10, 21), + (68, 20, 26), (61, 20, 25), (55, 21, 25), (51, 21, 25), + (48, 21, 25), (47, 21, 25), (47, 22, 26), (48, 23, 25), + (49, 23, 27), (50, 17, 17), (55, 11, 13), (61, 6, 9), + (67, 3, 7), (74, 1, 5), (76, 0, 5), (79, 0, 5), + (85, 0, 6), (90, 0, 7), (95, 0, 8), (98, 0, 8), + (101, 0, 9), (102, 0, 10), (103, 0, 11), (104, 1, 14), + (106, 3, 18), (106, 24, 35), (111, 41, 49), (116, 59, 63), + (129, 79, 84), (142, 99, 105), (148, 107, 112), (155, 115, 119), + (153, 143, 147), (146, 150, 150), (140, 158, 154), (142, 158, 152), + (145, 159, 151), (142, 155, 148), (140, 151, 145), (133, 139, 136), + (118, 123, 120), (83, 87, 79), (77, 72, 62), (71, 57, 45), + (71, 51, 40), (71, 46, 36), (70, 35, 31), (72, 27, 27), + (83, 18, 21), (92, 13, 19), (102, 8, 17), (112, 4, 16), + (122, 1, 15), (126, 0, 15), (130, 0, 15), (134, 1, 17), + (136, 2, 19), (134, 6, 20), (129, 5, 18), (125, 5, 17), + (121, 5, 16), (117, 6, 16), (107, 8, 16), (94, 12, 18), + (73, 16, 16), (68, 14, 14), (63, 13, 12), (61, 11, 11), + (60, 9, 10), (58, 10, 11), (55, 11, 10), (54, 11, 9), + (55, 10, 7), (57, 4, 5), (56, 3, 5), (55, 3, 6), + (54, 4, 6), (53, 6, 6), (54, 8, 8), (59, 10, 10), + (70, 9, 13), (76, 8, 13), (82, 8, 13), (84, 8, 13), + (86, 9, 14), (92, 10, 17), (101, 12, 19), (109, 11, 23), + (118, 9, 24), (130, 8, 21), (131, 8, 20), (133, 8, 19), + (137, 8, 19), (141, 9, 22), (143, 11, 27), (146, 22, 34), + (161, 54, 55), (170, 71, 64), (179, 88, 73), (185, 94, 80), + (191, 100, 87), (190, 115, 96), (192, 126, 107), (183, 133, 112), + (171, 134, 109), (149, 130, 101), (141, 127, 98), (134, 124, 95), + (127, 116, 87), (118, 101, 80), (110, 82, 67), (102, 59, 49), + (103, 27, 25), (112, 20, 21), (121, 13, 17), (126, 11, 16), + (132, 9, 16), (146, 6, 14), (160, 3, 13), (171, 1, 12), + (179, 0, 12), (182, 0, 12), (179, 0, 12), (176, 0, 12), + (168, 1, 12), (159, 1, 12), (149, 1, 12), (140, 1, 12), + (120, 0, 11), (115, 0, 11), (111, 0, 11), (102, 0, 10), + (93, 0, 10), (87, 0, 9), (82, 0, 10), (78, 0, 10), + (77, 0, 9), (77, 0, 7), (77, 0, 6), (77, 0, 5), + (78, 0, 5), (77, 0, 5), (76, 0, 5), (77, 0, 6), + (83, 1, 5), (86, 1, 5), (90, 1, 5), (97, 1, 7), + (103, 3, 8), (109, 4, 11), (110, 7, 16), (111, 16, 19), + (112, 28, 27), (123, 26, 29), (133, 26, 28), (146, 24, 27), + (154, 19, 26), (159, 16, 24), (156, 28, 29), (161, 27, 30), + (174, 22, 29), (178, 18, 28), (182, 15, 27), (188, 3, 23), + (186, 4, 23), (185, 3, 24), (181, 3, 23), (179, 3, 23), + (177, 4, 24), (174, 3, 25), (170, 3, 25), (168, 3, 25), + (166, 2, 23), (166, 2, 20), (167, 3, 20), (169, 4, 20), + (171, 5, 21), (170, 8, 23), (165, 15, 27), (166, 31, 36), + (168, 47, 47), (169, 65, 61), (170, 80, 73), (170, 89, 78), + (156, 89, 77), (145, 92, 79), (134, 93, 76), (127, 94, 78), + (122, 94, 79), (124, 90, 77), (119, 79, 68), (114, 64, 59), + (108, 47, 44), (105, 32, 34), (104, 19, 28), (105, 11, 23), + (108, 10, 22), (111, 21, 32), (114, 33, 43), (115, 44, 53), + (115, 48, 60), (117, 49, 61), (124, 40, 55), (129, 41, 54), + (137, 44, 59), (145, 49, 64), (147, 51, 67), (147, 49, 66), + (151, 37, 56), (152, 23, 42), (154, 12, 32), (158, 7, 27), + (157, 5, 25), (150, 4, 26), (141, 7, 26), (129, 10, 25), + (116, 13, 25), (102, 14, 25), (90, 14, 23), (81, 12, 23), + (73, 12, 23), (66, 13, 23), (62, 14, 24), (58, 15, 24), + (56, 15, 21), (58, 11, 19), (61, 7, 17), (68, 4, 16), + (75, 2, 13), (83, 2, 12), (92, 2, 12), (100, 1, 11) + ), + +// 653 Summer +((125, 67, 47), (88, 47, 13), (76, 44, 14), (64, 41, 15), + (51, 36, 16), (39, 31, 18), (39, 29, 14), (39, 27, 10), + (47, 22, 6), (63, 32, 4), (80, 43, 3), (96, 50, 9), + (113, 57, 15), (133, 70, 24), (153, 84, 33), (161, 88, 43), + (169, 92, 53), (190, 138, 79), (198, 152, 96), (207, 167, 114), + (204, 164, 115), (202, 161, 116), (185, 155, 118), (168, 150, 120), + (136, 109, 95), (122, 105, 85), (109, 102, 75), (116, 101, 64), + (123, 100, 53), (130, 103, 52), (137, 107, 52), (147, 119, 49), + (154, 134, 56), (188, 165, 84), (199, 186, 107), (210, 207, 131), + (216, 209, 151), (223, 212, 171), (226, 218, 172), (230, 224, 174), + (226, 213, 177), (213, 202, 163), (201, 191, 149), (186, 172, 126), + (171, 153, 104), (165, 145, 97), (159, 137, 91), (148, 118, 75), + (149, 113, 54), (171, 122, 35), (177, 130, 37), (184, 138, 40), + (182, 144, 55), (181, 150, 71), (173, 145, 76), (166, 141, 81), + (141, 118, 93), (130, 100, 81), (119, 82, 70), (116, 75, 55), + (114, 69, 40), (114, 68, 32), (115, 67, 25), (105, 64, 19), + (91, 66, 18), (59, 60, 18), (48, 56, 25), (37, 53, 32), + (35, 52, 32), (34, 51, 32), (41, 51, 36), (58, 56, 43), + (91, 73, 57), (99, 81, 66), (107, 90, 75), (100, 86, 74), + (93, 82, 73), (85, 76, 70), (77, 71, 67), (64, 63, 49), + (50, 44, 33), (25, 23, 15), (23, 24, 15), (21, 25, 15), + (22, 29, 17), (24, 34, 20), (38, 51, 30), (54, 62, 45), + (77, 75, 52), (87, 68, 51), (98, 62, 50), (97, 61, 53), + (97, 61, 56), (92, 66, 55), (87, 67, 58), (83, 78, 74), + (88, 95, 96), (103, 126, 112), (105, 130, 117), (108, 135, 123), + (109, 134, 120), (110, 134, 117), (102, 129, 109), (92, 122, 97), + (99, 121, 95), (118, 131, 105), (138, 142, 115), (145, 149, 120), + (152, 157, 126), (165, 176, 131), (174, 174, 136), (166, 166, 125), + (154, 166, 110), (126, 150, 103), (120, 146, 102), (114, 143, 101), + (105, 142, 99), (97, 144, 105), (87, 137, 102), (77, 118, 87), + (57, 83, 55), (61, 64, 41), (66, 46, 27), (69, 47, 24), + (73, 49, 22), (91, 50, 19), (107, 54, 27), (112, 67, 29), + (114, 79, 35), (106, 89, 50), (107, 96, 60), (108, 104, 71), + (114, 117, 89), (122, 131, 93), (142, 150, 104), (177, 165, 112), + (210, 199, 103), (224, 196, 98), (238, 194, 93), (232, 192, 92), + (227, 191, 91), (220, 181, 89), (215, 158, 85), (208, 146, 82), + (198, 141, 79), (187, 146, 80), (183, 147, 84), (179, 148, 89), + (180, 156, 100), (181, 174, 116), (177, 185, 135), (187, 195, 163), + (205, 227, 200), (204, 229, 205), (204, 231, 210), (215, 233, 210), + (213, 221, 199), (200, 193, 181), (185, 173, 156), (172, 155, 133), + (167, 127, 114), (159, 109, 66), (156, 105, 61), (153, 101, 57), + (151, 97, 49), (149, 93, 46), (132, 85, 49), (115, 79, 54), + (82, 66, 58), (76, 70, 61), (71, 74, 64), (69, 87, 77), + (73, 103, 91), (83, 124, 106), (86, 150, 132), (107, 175, 151), + (133, 182, 154), (136, 186, 165), (148, 189, 169), (161, 177, 156), + (163, 160, 134), (163, 141, 111), (158, 128, 99), (150, 115, 80), + (136, 96, 64), (134, 98, 66), (133, 100, 69), (140, 106, 67), + (149, 116, 61), (153, 123, 60), (158, 116, 47), (158, 118, 29), + (149, 117, 24), (133, 94, 23), (117, 70, 22), (99, 59, 23), + (85, 49, 28), (77, 41, 34), (71, 38, 37), (75, 43, 42), + (82, 55, 45), (86, 61, 46), (94, 66, 43), (95, 67, 42), + (86, 59, 43), (73, 51, 33), (64, 43, 29), (52, 36, 35), + (47, 37, 36), (51, 41, 38), (57, 46, 49), (66, 58, 55), + (72, 70, 57), (72, 82, 63), (78, 86, 68), (92, 96, 67), + (102, 114, 64), (113, 124, 73), (139, 138, 84), (163, 156, 93), + (182, 176, 110), (197, 190, 127), (202, 194, 139), (206, 197, 155), + (210, 198, 163), (203, 195, 159), (201, 187, 159), (208, 189, 155), + (213, 197, 141), (225, 198, 134), (233, 200, 132), (236, 204, 124), + (239, 204, 116), (231, 195, 117), (221, 183, 119), (210, 177, 116), + (202, 162, 119), (204, 153, 134), (209, 159, 149), (207, 161, 165), + (209, 175, 180), (215, 192, 196), (204, 201, 204), (193, 209, 202), + (181, 213, 201), (160, 202, 191), (156, 184, 177), (155, 175, 162), + (134, 162, 145), (127, 141, 124), (140, 126, 105), (141, 115, 92), + (133, 99, 84), (132, 91, 78), (134, 78, 53), (133, 64, 43) + ), + +// 654 Summer_Fire +((254, 222, 57), (253, 233, 58), (246, 226, 59), (240, 220, 60), + (231, 209, 62), (223, 198, 64), (218, 195, 65), (214, 192, 66), + (196, 181, 76), (191, 176, 87), (187, 171, 99), (185, 169, 114), + (183, 168, 130), (184, 167, 139), (186, 166, 149), (184, 166, 150), + (183, 167, 152), (197, 163, 143), (202, 152, 137), (208, 141, 132), + (213, 134, 128), (218, 128, 124), (216, 125, 120), (214, 123, 117), + (213, 122, 98), (211, 113, 85), (209, 105, 72), (211, 99, 62), + (214, 93, 53), (212, 91, 50), (210, 90, 48), (207, 90, 47), + (201, 97, 50), (182, 108, 58), (173, 104, 54), (164, 100, 51), + (155, 93, 45), (147, 87, 39), (144, 84, 36), (141, 81, 33), + (126, 62, 25), (118, 50, 21), (110, 39, 18), (105, 30, 16), + (101, 21, 14), (103, 20, 14), (105, 19, 14), (116, 14, 12), + (128, 13, 14), (165, 10, 15), (177, 15, 15), (190, 20, 15), + (202, 33, 18), (214, 47, 21), (218, 54, 22), (223, 61, 24), + (241, 82, 30), (245, 96, 32), (250, 110, 34), (251, 125, 36), + (253, 141, 39), (253, 148, 40), (253, 156, 41), (253, 169, 43), + (253, 173, 44), (253, 172, 44), (248, 166, 42), (243, 161, 40), + (238, 157, 39), (234, 153, 39), (222, 144, 37), (209, 136, 37), + (188, 122, 40), (182, 115, 41), (177, 108, 43), (176, 103, 41), + (175, 98, 39), (174, 96, 38), (174, 94, 38), (173, 93, 36), + (174, 94, 37), (185, 98, 42), (195, 102, 41), (206, 106, 41), + (212, 108, 40), (219, 110, 40), (230, 115, 37), (239, 121, 35), + (251, 137, 36), (252, 147, 38), (253, 157, 41), (253, 162, 42), + (253, 167, 43), (253, 175, 45), (253, 181, 46), (253, 184, 46), + (252, 183, 46), (246, 177, 45), (240, 168, 44), (235, 159, 43), + (234, 153, 42), (233, 148, 41), (232, 138, 42), (232, 129, 40), + (235, 114, 36), (233, 110, 35), (232, 106, 34), (231, 102, 32), + (231, 99, 30), (231, 94, 32), (234, 93, 32), (236, 92, 32), + (242, 96, 32), (250, 114, 35), (251, 117, 34), (252, 120, 34), + (252, 122, 34), (254, 123, 35), (253, 123, 35), (252, 121, 35), + (245, 122, 38), (238, 122, 40), (232, 122, 43), (230, 123, 46), + (228, 124, 49), (224, 128, 55), (222, 131, 60), (225, 133, 65), + (226, 138, 66), (224, 142, 64), (223, 140, 64), (223, 139, 64), + (222, 138, 64), (218, 134, 61), (219, 129, 63), (220, 125, 60), + (223, 122, 50), (224, 119, 45), (225, 116, 41), (223, 113, 38), + (222, 111, 35), (219, 98, 31), (213, 84, 27), (207, 71, 25), + (200, 61, 22), (191, 46, 19), (188, 46, 19), (186, 47, 19), + (180, 45, 20), (173, 44, 21), (165, 42, 25), (157, 41, 28), + (146, 40, 32), (145, 41, 33), (144, 42, 34), (139, 45, 33), + (135, 51, 32), (132, 57, 36), (131, 65, 41), (130, 75, 48), + (132, 88, 58), (146, 105, 71), (150, 109, 72), (154, 114, 73), + (163, 119, 76), (172, 124, 79), (179, 129, 81), (189, 137, 83), + (209, 160, 87), (212, 167, 87), (215, 175, 88), (223, 188, 89), + (231, 199, 90), (232, 201, 95), (232, 199, 97), (232, 195, 97), + (228, 190, 95), (222, 184, 93), (214, 180, 91), (209, 181, 88), + (203, 178, 89), (197, 171, 92), (193, 164, 96), (185, 155, 94), + (177, 128, 87), (177, 119, 83), (177, 111, 80), (180, 99, 71), + (185, 86, 62), (195, 76, 57), (200, 67, 50), (206, 58, 45), + (212, 56, 38), (216, 45, 32), (221, 35, 26), (225, 25, 21), + (233, 16, 17), (240, 8, 15), (244, 9, 16), (245, 19, 24), + (243, 32, 32), (243, 44, 42), (240, 58, 51), (237, 73, 59), + (237, 83, 66), (238, 98, 71), (240, 112, 82), (241, 129, 89), + (243, 145, 100), (245, 162, 110), (244, 181, 116), (244, 194, 117), + (244, 205, 113), (245, 212, 110), (245, 217, 103), (246, 219, 96), + (249, 216, 94), (250, 213, 89), (252, 208, 81), (253, 204, 73), + (253, 200, 67), (253, 196, 60), (252, 192, 52), (252, 186, 48), + (252, 181, 46), (252, 176, 45), (252, 172, 44), (253, 168, 42), + (253, 163, 41), (252, 157, 39), (247, 150, 37), (240, 145, 35), + (230, 138, 33), (217, 133, 33), (204, 128, 32), (192, 122, 31), + (186, 117, 29), (181, 111, 29), (177, 105, 28), (169, 91, 26), + (166, 77, 25), (160, 64, 22), (156, 52, 21), (156, 44, 19), + (164, 47, 21), (176, 59, 23), (184, 71, 26), (197, 85, 30), + (208, 100, 32), (217, 112, 35), (222, 117, 35), (230, 129, 38), + (240, 144, 41), (245, 163, 46), (249, 182, 51), (252, 202, 54) + ), + +// 655 Summer_Skies +((122, 101, 184), (121, 121, 183), (125, 131, 185), (130, 141, 188), + (132, 148, 193), (135, 156, 199), (136, 158, 200), (137, 160, 202), + (137, 153, 192), (127, 145, 183), (118, 137, 174), (108, 131, 166), + (99, 126, 159), (93, 120, 158), (87, 114, 158), (82, 110, 158), + (78, 106, 158), (61, 90, 164), (53, 85, 163), (46, 81, 163), + (43, 77, 163), (41, 74, 164), (42, 74, 163), (44, 75, 162), + (65, 84, 167), (78, 89, 173), (91, 94, 179), (101, 100, 187), + (112, 106, 196), (115, 110, 199), (118, 114, 202), (128, 123, 204), + (137, 132, 206), (156, 153, 209), (163, 165, 210), (171, 178, 211), + (174, 192, 216), (178, 206, 221), (177, 210, 223), (177, 215, 226), + (165, 224, 231), (156, 222, 227), (148, 221, 223), (142, 213, 220), + (136, 206, 218), (133, 203, 215), (131, 200, 212), (122, 189, 205), + (116, 182, 200), (94, 168, 190), (80, 157, 182), (67, 146, 174), + (56, 135, 163), (46, 124, 153), (42, 119, 148), (38, 115, 143), + (34, 92, 123), (34, 81, 115), (34, 70, 107), (32, 60, 102), + (30, 51, 97), (29, 48, 94), (28, 45, 92), (26, 42, 90), + (23, 41, 92), (13, 56, 97), (12, 66, 102), (12, 76, 108), + (13, 81, 113), (15, 87, 118), (18, 97, 129), (23, 107, 140), + (40, 125, 161), (48, 133, 173), (57, 141, 186), (60, 153, 196), + (63, 166, 206), (63, 172, 209), (64, 178, 213), (64, 190, 221), + (61, 206, 228), (53, 223, 238), (52, 226, 239), (52, 229, 241), + (53, 228, 241), (55, 227, 242), (58, 224, 242), (59, 225, 240), + (64, 218, 232), (66, 217, 221), (69, 217, 210), (67, 218, 204), + (65, 219, 199), (62, 222, 190), (60, 222, 187), (64, 221, 187), + (72, 220, 186), (90, 222, 189), (97, 216, 193), (105, 210, 198), + (111, 206, 194), (117, 203, 190), (120, 195, 185), (119, 185, 179), + (114, 165, 167), (111, 154, 161), (108, 144, 156), (106, 142, 153), + (105, 140, 151), (104, 130, 151), (105, 119, 158), (109, 108, 161), + (110, 100, 163), (108, 95, 161), (106, 93, 161), (105, 92, 161), + (95, 87, 159), (88, 86, 156), (79, 89, 153), (73, 94, 151), + (77, 105, 156), (79, 115, 159), (81, 125, 163), (82, 131, 164), + (84, 138, 165), (89, 148, 171), (90, 157, 181), (91, 169, 190), + (86, 180, 199), (72, 204, 211), (70, 209, 213), (68, 214, 216), + (64, 217, 222), (61, 222, 227), (61, 229, 229), (65, 230, 228), + (83, 235, 237), (90, 236, 239), (97, 238, 242), (98, 238, 242), + (99, 238, 242), (99, 239, 243), (95, 239, 243), (90, 237, 244), + (84, 238, 243), (77, 241, 241), (79, 241, 241), (82, 242, 242), + (90, 241, 243), (101, 241, 243), (115, 240, 244), (131, 242, 245), + (151, 245, 249), (153, 244, 249), (156, 243, 249), (153, 240, 247), + (147, 233, 244), (141, 226, 241), (138, 223, 238), (136, 219, 235), + (137, 214, 231), (148, 212, 228), (150, 212, 227), (153, 213, 227), + (157, 217, 228), (158, 219, 228), (159, 220, 229), (156, 219, 230), + (155, 220, 231), (155, 218, 230), (155, 217, 229), (155, 215, 228), + (155, 213, 229), (153, 210, 227), (151, 205, 226), (145, 199, 222), + (137, 191, 218), (126, 186, 215), (114, 181, 212), (106, 178, 209), + (102, 173, 206), (102, 175, 203), (105, 174, 204), (112, 177, 204), + (134, 174, 204), (136, 171, 202), (139, 169, 200), (141, 159, 195), + (133, 153, 191), (123, 149, 186), (112, 142, 182), (102, 141, 177), + (90, 144, 175), (80, 153, 173), (74, 162, 175), (74, 174, 177), + (75, 180, 177), (81, 183, 176), (88, 181, 173), (93, 181, 174), + (99, 174, 178), (108, 166, 180), (111, 159, 181), (109, 155, 179), + (105, 149, 178), (103, 139, 175), (96, 132, 170), (91, 129, 166), + (88, 122, 156), (89, 121, 146), (91, 109, 137), (102, 100, 137), + (117, 95, 140), (133, 95, 144), (144, 100, 152), (161, 104, 160), + (172, 107, 167), (180, 112, 176), (182, 118, 181), (185, 133, 183), + (183, 140, 178), (184, 146, 178), (189, 154, 180), (195, 161, 185), + (201, 174, 193), (207, 185, 203), (212, 192, 213), (220, 195, 221), + (221, 198, 231), (218, 208, 239), (210, 218, 242), (198, 223, 242), + (185, 223, 240), (172, 219, 235), (160, 210, 226), (148, 198, 219), + (135, 186, 213), (126, 172, 207), (122, 158, 207), (121, 145, 205), + (115, 132, 200), (105, 120, 193), (93, 107, 187), (80, 100, 181), + (68, 94, 173), (59, 96, 171), (47, 96, 166), (44, 97, 163), + (47, 93, 163), (61, 89, 167), (72, 83, 170), (83, 79, 172), + (93, 75, 176), (105, 80, 180), (113, 80, 179), (124, 93, 185) + ), + +// 656 Summer_Tulips +((179, 133, 66), (205, 125, 44), (204, 117, 30), (203, 110, 16), + (197, 106, 11), (192, 102, 7), (188, 99, 6), (185, 97, 5), + (178, 97, 5), (176, 98, 7), (175, 100, 9), (176, 105, 18), + (177, 110, 27), (176, 116, 37), (175, 123, 48), (177, 125, 50), + (180, 127, 53), (186, 126, 44), (186, 122, 35), (186, 118, 26), + (172, 114, 30), (159, 111, 35), (157, 112, 38), (155, 113, 42), + (113, 112, 70), (112, 115, 77), (111, 119, 84), (109, 120, 87), + (107, 122, 90), (110, 123, 91), (113, 125, 92), (121, 124, 87), + (133, 120, 72), (153, 108, 43), (162, 101, 27), (172, 94, 12), + (171, 86, 9), (170, 79, 6), (169, 74, 6), (168, 69, 7), + (169, 58, 7), (171, 56, 6), (173, 55, 6), (175, 65, 6), + (178, 75, 7), (179, 77, 7), (180, 80, 7), (186, 94, 17), + (187, 114, 29), (198, 136, 56), (207, 145, 64), (216, 154, 73), + (216, 154, 73), (217, 154, 74), (214, 153, 74), (212, 153, 75), + (185, 142, 76), (168, 140, 82), (152, 139, 89), (142, 137, 92), + (133, 136, 96), (130, 136, 97), (127, 137, 99), (133, 138, 97), + (144, 143, 102), (180, 146, 104), (200, 155, 108), (220, 164, 112), + (226, 164, 112), (233, 164, 112), (240, 163, 110), (239, 172, 97), + (222, 159, 68), (208, 149, 55), (195, 140, 43), (188, 135, 36), + (182, 130, 29), (181, 126, 31), (181, 122, 34), (182, 124, 33), + (185, 129, 34), (183, 129, 48), (174, 129, 55), (166, 129, 63), + (162, 128, 65), (159, 127, 67), (158, 121, 60), (161, 111, 46), + (168, 90, 24), (172, 79, 15), (176, 68, 6), (176, 70, 5), + (176, 72, 5), (178, 74, 6), (178, 70, 5), (175, 73, 5), + (175, 74, 7), (171, 57, 7), (167, 50, 8), (163, 44, 9), + (161, 41, 10), (160, 39, 11), (158, 37, 9), (157, 37, 9), + (146, 47, 9), (149, 55, 8), (152, 64, 7), (150, 66, 7), + (148, 68, 8), (152, 66, 8), (155, 65, 8), (154, 66, 10), + (159, 64, 8), (157, 71, 11), (157, 76, 11), (157, 81, 11), + (151, 93, 20), (148, 101, 37), (145, 112, 49), (137, 121, 63), + (142, 135, 92), (145, 139, 94), (149, 143, 97), (152, 142, 94), + (155, 141, 92), (159, 138, 83), (164, 132, 72), (167, 125, 57), + (175, 121, 40), (187, 122, 27), (186, 123, 29), (186, 124, 32), + (189, 132, 39), (188, 137, 52), (181, 141, 68), (176, 145, 80), + (173, 150, 91), (176, 152, 92), (179, 154, 94), (182, 154, 92), + (185, 155, 90), (186, 152, 84), (191, 145, 72), (199, 140, 54), + (196, 129, 40), (190, 108, 17), (182, 107, 19), (174, 107, 21), + (161, 102, 32), (150, 107, 47), (132, 115, 63), (121, 119, 77), + (118, 130, 96), (120, 132, 97), (123, 134, 99), (133, 138, 103), + (149, 145, 109), (176, 156, 119), (201, 166, 124), (216, 172, 125), + (224, 172, 132), (217, 171, 124), (207, 166, 122), (197, 162, 120), + (174, 153, 109), (166, 147, 104), (160, 144, 98), (154, 139, 90), + (157, 136, 84), (156, 135, 83), (156, 134, 82), (152, 132, 81), + (148, 135, 86), (144, 138, 93), (141, 139, 96), (137, 141, 101), + (134, 144, 107), (135, 145, 108), (133, 145, 107), (130, 144, 108), + (129, 143, 106), (126, 142, 105), (122, 139, 103), (118, 134, 99), + (112, 127, 94), (110, 125, 93), (108, 123, 92), (107, 122, 90), + (107, 121, 89), (108, 122, 89), (117, 124, 89), (129, 127, 84), + (141, 126, 75), (159, 125, 61), (175, 124, 46), (187, 121, 34), + (197, 119, 21), (200, 119, 16), (196, 119, 24), (190, 121, 32), + (177, 124, 45), (168, 128, 62), (168, 132, 70), (165, 135, 75), + (166, 138, 77), (177, 141, 71), (185, 143, 61), (191, 145, 55), + (201, 146, 49), (205, 142, 41), (203, 139, 39), (209, 140, 35), + (213, 134, 30), (208, 129, 30), (206, 131, 28), (211, 134, 28), + (213, 138, 33), (213, 144, 40), (224, 151, 52), (228, 157, 64), + (229, 160, 73), (230, 163, 79), (226, 164, 79), (221, 161, 77), + (214, 159, 74), (208, 158, 67), (208, 155, 64), (210, 150, 72), + (209, 142, 78), (210, 139, 81), (216, 141, 90), (214, 143, 95), + (214, 144, 94), (219, 150, 99), (222, 160, 97), (229, 162, 91), + (230, 164, 88), (225, 163, 81), (224, 158, 75), (215, 157, 71), + (205, 153, 66), (202, 147, 60), (202, 146, 55), (204, 148, 52), + (207, 148, 50), (215, 150, 49), (223, 155, 49), (225, 155, 58), + (223, 151, 71), (219, 154, 79), (215, 158, 84), (206, 150, 89), + (187, 145, 90), (177, 149, 90), (186, 144, 93), (182, 135, 81) + ), + +// 657 Sunbathing +((217, 135, 3), (250, 167, 1), (251, 164, 1), (252, 161, 2), + (251, 163, 2), (251, 166, 3), (250, 164, 3), (249, 163, 3), + (221, 132, 3), (193, 108, 2), (165, 84, 2), (141, 69, 5), + (117, 54, 9), (88, 40, 13), (59, 26, 18), (53, 25, 18), + (48, 25, 18), (84, 51, 20), (91, 63, 24), (99, 76, 29), + (98, 83, 42), (98, 90, 56), (99, 100, 71), (101, 110, 87), + (65, 126, 147), (69, 135, 167), (73, 145, 187), (105, 163, 176), + (137, 181, 165), (141, 180, 158), (145, 180, 152), (181, 193, 130), + (214, 190, 94), (226, 176, 50), (191, 172, 76), (157, 168, 102), + (139, 143, 100), (121, 119, 99), (115, 114, 98), (109, 109, 98), + (120, 123, 105), (140, 120, 76), (160, 118, 47), (192, 131, 27), + (225, 145, 7), (234, 150, 4), (243, 155, 2), (246, 162, 4), + (247, 163, 7), (251, 154, 11), (240, 134, 12), (230, 114, 13), + (199, 95, 18), (169, 76, 24), (158, 68, 23), (147, 61, 23), + (78, 21, 27), (51, 18, 32), (24, 15, 38), (14, 18, 33), + (5, 22, 28), (4, 21, 29), (3, 20, 30), (6, 20, 34), + (11, 24, 27), (36, 27, 25), (64, 41, 26), (93, 55, 28), + (110, 64, 29), (128, 73, 30), (154, 86, 34), (180, 104, 32), + (233, 144, 22), (242, 151, 21), (252, 159, 21), (251, 159, 15), + (250, 160, 10), (249, 160, 8), (249, 161, 6), (248, 161, 7), + (243, 162, 10), (195, 144, 17), (160, 130, 40), (126, 117, 63), + (116, 117, 77), (106, 117, 91), (76, 107, 111), (48, 86, 123), + (53, 87, 123), (74, 92, 110), (96, 98, 97), (99, 91, 84), + (102, 85, 71), (112, 74, 43), (118, 71, 16), (126, 78, 6), + (134, 81, 3), (156, 83, 10), (169, 92, 16), (183, 101, 22), + (195, 106, 21), (208, 112, 20), (211, 107, 21), (191, 95, 20), + (139, 63, 25), (104, 44, 25), (69, 25, 26), (52, 18, 25), + (35, 12, 25), (18, 6, 23), (8, 3, 26), (2, 1, 24), + (0, 2, 20), (0, 3, 11), (0, 3, 10), (0, 3, 9), + (0, 3, 9), (1, 4, 10), (5, 4, 9), (10, 4, 9), + (30, 6, 17), (58, 26, 14), (86, 47, 11), (99, 57, 10), + (113, 68, 9), (140, 79, 15), (172, 95, 16), (196, 111, 20), + (206, 119, 21), (172, 102, 31), (157, 97, 43), (142, 92, 55), + (120, 87, 86), (88, 91, 116), (56, 100, 139), (23, 107, 167), + (4, 120, 200), (2, 113, 182), (1, 106, 165), (1, 100, 147), + (1, 95, 130), (0, 80, 104), (0, 56, 70), (0, 32, 41), + (0, 21, 14), (8, 19, 2), (14, 19, 3), (20, 19, 5), + (45, 33, 4), (74, 57, 3), (109, 83, 2), (138, 100, 5), + (201, 142, 5), (214, 153, 4), (228, 165, 4), (245, 176, 6), + (252, 180, 12), (251, 177, 19), (243, 173, 31), (205, 171, 61), + (171, 167, 99), (124, 147, 136), (103, 139, 142), (83, 132, 148), + (53, 116, 151), (25, 104, 154), (21, 89, 132), (13, 69, 113), + (17, 31, 65), (16, 29, 58), (15, 27, 51), (10, 21, 52), + (8, 17, 55), (6, 19, 66), (4, 32, 86), (5, 48, 110), + (7, 67, 132), (5, 87, 151), (1, 112, 171), (2, 123, 188), + (6, 121, 189), (6, 108, 179), (4, 98, 155), (7, 84, 131), + (29, 43, 71), (40, 41, 56), (52, 39, 41), (83, 49, 22), + (116, 67, 9), (142, 81, 4), (167, 100, 1), (196, 120, 1), + (223, 136, 3), (227, 138, 3), (212, 124, 1), (184, 106, 0), + (159, 86, 1), (133, 74, 2), (103, 55, 3), (68, 36, 6), + (40, 18, 10), (21, 13, 14), (11, 11, 18), (6, 16, 27), + (3, 20, 43), (2, 29, 65), (0, 42, 95), (2, 65, 124), + (3, 90, 152), (3, 112, 176), (1, 129, 201), (1, 141, 216), + (5, 140, 215), (13, 132, 189), (33, 126, 157), (65, 131, 126), + (99, 127, 100), (128, 121, 68), (156, 119, 40), (189, 142, 25), + (221, 165, 17), (242, 182, 13), (251, 185, 9), (253, 189, 16), + (253, 193, 15), (253, 192, 13), (255, 180, 5), (250, 158, 6), + (234, 131, 7), (209, 106, 6), (187, 86, 4), (174, 65, 1), + (163, 49, 3), (155, 42, 3), (152, 46, 3), (157, 53, 0), + (160, 62, 0), (160, 66, 0), (155, 68, 0), (146, 62, 0), + (124, 58, 0), (97, 45, 0), (65, 28, 0), (40, 10, 0), + (20, 3, 2), (10, 1, 5), (3, 2, 6), (2, 2, 6), + (7, 2, 7), (16, 2, 8), (34, 8, 10), (59, 28, 10), + (98, 61, 7), (128, 80, 4), (157, 87, 4), (180, 98, 3) + ), + +// 658 Sunny_Field +((117, 176, 112), (110, 170, 116), (110, 170, 127), (111, 171, 138), + (110, 175, 144), (110, 179, 150), (110, 183, 151), (111, 187, 152), + (127, 195, 155), (135, 202, 153), (143, 209, 152), (148, 208, 154), + (153, 208, 157), (155, 209, 158), (157, 210, 159), (154, 210, 157), + (151, 210, 156), (153, 197, 144), (149, 193, 136), (145, 189, 128), + (141, 177, 113), (137, 166, 99), (130, 156, 91), (124, 147, 84), + (87, 107, 58), (69, 87, 46), (51, 68, 34), (42, 64, 32), + (34, 61, 31), (36, 64, 33), (39, 68, 36), (50, 77, 37), + (58, 87, 48), (74, 113, 77), (72, 114, 75), (71, 116, 73), + (59, 113, 72), (48, 110, 71), (44, 106, 66), (40, 102, 62), + (21, 81, 41), (16, 75, 32), (11, 69, 24), (11, 58, 19), + (12, 48, 15), (10, 45, 13), (8, 43, 12), (11, 40, 7), + (19, 44, 9), (41, 57, 16), (55, 68, 17), (70, 80, 18), + (83, 90, 28), (97, 101, 38), (103, 107, 42), (109, 113, 47), + (112, 128, 69), (107, 128, 78), (103, 129, 88), (91, 127, 89), + (79, 125, 91), (76, 121, 90), (74, 118, 90), (64, 110, 88), + (58, 109, 79), (44, 118, 65), (45, 117, 58), (46, 117, 51), + (46, 116, 48), (46, 115, 46), (42, 112, 41), (39, 107, 37), + (43, 92, 28), (41, 86, 28), (39, 81, 29), (44, 89, 35), + (49, 97, 41), (53, 101, 45), (58, 106, 50), (66, 111, 57), + (77, 119, 63), (86, 130, 86), (83, 132, 90), (81, 135, 94), + (79, 135, 90), (78, 136, 87), (75, 135, 81), (66, 132, 79), + (64, 140, 75), (75, 145, 71), (86, 150, 68), (89, 155, 72), + (93, 160, 77), (99, 167, 89), (109, 175, 95), (105, 180, 99), + (96, 182, 105), (76, 182, 103), (60, 176, 100), (45, 171, 97), + (38, 170, 97), (31, 169, 97), (27, 167, 98), (29, 169, 97), + (44, 162, 94), (50, 158, 91), (57, 155, 89), (58, 154, 89), + (60, 154, 90), (60, 153, 86), (61, 148, 82), (56, 148, 81), + (53, 148, 83), (41, 156, 94), (41, 156, 99), (42, 156, 104), + (50, 153, 111), (58, 155, 112), (65, 154, 111), (68, 148, 107), + (71, 132, 91), (69, 131, 79), (68, 130, 67), (64, 127, 60), + (61, 124, 53), (55, 121, 44), (47, 117, 41), (39, 111, 40), + (31, 103, 39), (25, 90, 35), (24, 87, 32), (24, 84, 30), + (26, 74, 30), (34, 74, 33), (41, 75, 39), (56, 87, 44), + (120, 109, 61), (144, 131, 75), (168, 153, 90), (179, 160, 101), + (190, 168, 113), (211, 172, 124), (220, 182, 133), (216, 192, 139), + (203, 200, 148), (166, 189, 160), (154, 185, 161), (142, 182, 163), + (115, 180, 158), (98, 175, 153), (83, 163, 142), (72, 151, 132), + (49, 134, 100), (46, 128, 90), (44, 122, 80), (42, 110, 66), + (39, 105, 49), (37, 104, 40), (39, 106, 32), (45, 105, 31), + (52, 110, 29), (86, 125, 41), (95, 130, 48), (104, 136, 56), + (122, 142, 72), (147, 157, 92), (178, 166, 102), (200, 182, 112), + (214, 201, 135), (214, 203, 139), (215, 206, 143), (208, 210, 145), + (197, 217, 142), (169, 219, 145), (142, 220, 149), (119, 216, 152), + (110, 214, 148), (101, 214, 148), (95, 213, 145), (91, 210, 143), + (93, 205, 131), (95, 200, 122), (94, 192, 111), (90, 180, 103), + (67, 152, 79), (60, 148, 73), (54, 144, 68), (48, 134, 63), + (42, 132, 60), (36, 129, 61), (28, 136, 63), (29, 137, 65), + (27, 129, 64), (26, 128, 65), (25, 134, 74), (34, 147, 90), + (36, 143, 98), (42, 139, 102), (48, 137, 107), (56, 146, 118), + (56, 162, 128), (53, 171, 129), (55, 170, 122), (57, 159, 110), + (60, 156, 103), (64, 159, 99), (69, 160, 96), (73, 155, 92), + (77, 155, 93), (87, 160, 98), (95, 168, 107), (100, 174, 119), + (104, 182, 127), (111, 191, 137), (117, 197, 140), (124, 202, 145), + (130, 210, 145), (139, 215, 145), (144, 217, 141), (147, 217, 134), + (147, 212, 125), (144, 201, 114), (147, 189, 103), (146, 178, 95), + (145, 164, 91), (137, 152, 87), (142, 147, 86), (143, 150, 87), + (144, 156, 96), (139, 166, 104), (145, 175, 110), (155, 185, 114), + (158, 194, 123), (162, 205, 135), (163, 208, 140), (173, 202, 143), + (181, 195, 145), (195, 199, 148), (205, 205, 146), (213, 208, 145), + (222, 204, 145), (227, 204, 147), (229, 208, 145), (223, 217, 143), + (220, 223, 144), (214, 229, 152), (205, 228, 156), (193, 228, 163), + (180, 230, 165), (171, 232, 169), (163, 227, 162), (157, 220, 154), + (145, 212, 141), (133, 204, 133), (124, 193, 121), (120, 184, 118) + ), + +// 659 Sunset +((189, 106, 106), (165, 81, 91), (155, 71, 87), (146, 62, 83), + (137, 51, 81), (129, 41, 80), (123, 36, 79), (117, 31, 78), + (89, 23, 63), (76, 19, 54), (63, 16, 45), (54, 14, 39), + (45, 13, 34), (44, 12, 33), (43, 12, 33), (43, 12, 32), + (44, 12, 32), (49, 12, 34), (53, 11, 34), (57, 10, 35), + (64, 9, 31), (72, 9, 27), (79, 9, 26), (87, 9, 26), + (115, 16, 22), (132, 24, 24), (149, 32, 26), (162, 41, 32), + (175, 50, 39), (181, 53, 40), (187, 57, 42), (200, 61, 44), + (213, 62, 41), (218, 72, 33), (220, 78, 31), (223, 84, 30), + (217, 87, 31), (212, 91, 32), (208, 89, 32), (204, 88, 33), + (184, 74, 31), (167, 66, 29), (151, 59, 27), (136, 53, 24), + (121, 47, 21), (112, 45, 19), (104, 44, 18), (90, 37, 15), + (81, 28, 13), (68, 19, 13), (67, 27, 22), (67, 35, 31), + (75, 50, 42), (83, 65, 54), (86, 72, 59), (90, 79, 65), + (112, 94, 82), (124, 100, 84), (136, 107, 87), (151, 116, 90), + (167, 125, 93), (177, 131, 94), (188, 137, 96), (203, 149, 99), + (213, 156, 102), (223, 142, 95), (218, 128, 84), (214, 114, 74), + (210, 106, 68), (207, 99, 63), (206, 88, 50), (205, 86, 39), + (205, 91, 33), (207, 93, 34), (209, 96, 35), (208, 100, 39), + (208, 105, 44), (208, 105, 43), (208, 105, 43), (207, 108, 42), + (205, 112, 45), (204, 124, 53), (206, 133, 58), (209, 142, 63), + (210, 146, 66), (212, 151, 70), (215, 157, 73), (218, 162, 74), + (213, 161, 75), (205, 152, 71), (198, 144, 68), (193, 138, 66), + (188, 132, 64), (175, 120, 60), (159, 109, 56), (146, 101, 51), + (132, 92, 46), (107, 79, 36), (95, 71, 32), (84, 63, 29), + (78, 58, 27), (73, 54, 25), (59, 43, 19), (46, 32, 15), + (31, 14, 7), (31, 11, 4), (31, 8, 2), (34, 7, 2), + (37, 7, 3), (51, 9, 4), (65, 10, 6), (77, 9, 6), + (88, 8, 7), (107, 7, 9), (110, 7, 8), (114, 8, 8), + (117, 6, 7), (121, 7, 7), (120, 8, 8), (117, 8, 7), + (108, 6, 7), (100, 4, 7), (92, 3, 7), (86, 2, 6), + (80, 2, 5), (69, 0, 3), (55, 0, 3), (45, 0, 4), + (39, 1, 5), (38, 8, 6), (41, 11, 7), (44, 14, 8), + (52, 21, 10), (65, 31, 12), (75, 41, 14), (89, 51, 19), + (117, 69, 35), (132, 76, 43), (147, 84, 52), (154, 84, 54), + (161, 85, 57), (175, 86, 59), (186, 85, 59), (196, 85, 59), + (204, 86, 62), (211, 84, 76), (213, 84, 79), (215, 84, 82), + (220, 86, 88), (223, 89, 93), (226, 92, 99), (228, 93, 102), + (232, 98, 109), (232, 102, 110), (233, 106, 112), (233, 113, 115), + (236, 127, 119), (238, 141, 125), (241, 158, 133), (243, 175, 142), + (242, 186, 154), (248, 208, 164), (246, 208, 164), (245, 209, 164), + (241, 206, 160), (238, 197, 153), (232, 186, 143), (228, 178, 135), + (210, 150, 123), (207, 143, 119), (205, 136, 116), (197, 122, 108), + (187, 108, 98), (180, 95, 85), (172, 81, 71), (167, 69, 63), + (161, 59, 53), (156, 50, 50), (153, 49, 49), (150, 49, 49), + (149, 54, 49), (153, 61, 49), (156, 70, 48), (159, 76, 54), + (168, 89, 56), (169, 92, 55), (171, 96, 55), (169, 99, 56), + (165, 100, 55), (161, 100, 56), (150, 98, 53), (140, 94, 53), + (132, 88, 48), (130, 80, 43), (130, 72, 37), (129, 64, 30), + (126, 53, 24), (127, 45, 20), (124, 34, 18), (119, 28, 21), + (116, 22, 26), (117, 18, 31), (122, 15, 32), (131, 14, 33), + (143, 12, 32), (156, 14, 32), (171, 13, 28), (181, 18, 29), + (186, 23, 32), (190, 31, 39), (193, 41, 42), (192, 49, 46), + (194, 54, 48), (192, 60, 48), (187, 61, 43), (181, 65, 36), + (174, 64, 31), (167, 65, 31), (161, 67, 29), (151, 69, 29), + (144, 68, 29), (141, 66, 27), (135, 61, 26), (126, 58, 24), + (117, 51, 21), (104, 44, 19), (93, 37, 16), (80, 32, 13), + (70, 26, 11), (65, 18, 8), (65, 11, 6), (66, 8, 6), + (70, 5, 4), (70, 4, 3), (71, 4, 3), (72, 6, 3), + (73, 9, 7), (74, 15, 11), (82, 24, 17), (94, 39, 27), + (111, 55, 38), (128, 69, 47), (145, 83, 57), (162, 96, 63), + (178, 107, 72), (185, 115, 80), (194, 120, 85), (202, 132, 92), + (211, 144, 99), (217, 148, 105), (221, 148, 113), (222, 149, 117), + (225, 148, 119), (219, 140, 121), (211, 125, 116), (199, 113, 112) + ), + +// 660 Surfer +((21, 75, 192), (8, 98, 234), (5, 102, 240), (2, 106, 247), + (3, 108, 246), (4, 111, 246), (4, 112, 246), (5, 113, 247), + (3, 119, 252), (5, 119, 249), (8, 119, 246), (12, 112, 234), + (17, 105, 222), (20, 92, 204), (24, 80, 186), (26, 75, 178), + (29, 70, 171), (27, 58, 163), (25, 57, 165), (23, 57, 168), + (21, 63, 174), (20, 70, 180), (17, 75, 187), (14, 80, 195), + (2, 105, 233), (2, 113, 242), (2, 121, 252), (2, 121, 252), + (2, 122, 253), (2, 121, 253), (3, 121, 254), (5, 120, 254), + (8, 120, 253), (21, 99, 224), (31, 84, 197), (41, 69, 170), + (53, 62, 149), (65, 55, 128), (69, 49, 116), (74, 43, 105), + (93, 13, 50), (96, 7, 37), (99, 2, 25), (93, 4, 35), + (88, 7, 45), (84, 11, 55), (80, 16, 65), (67, 31, 94), + (60, 44, 116), (35, 64, 162), (24, 77, 187), (14, 90, 212), + (10, 102, 228), (7, 115, 244), (5, 118, 248), (4, 122, 252), + (0, 125, 254), (0, 128, 254), (0, 131, 254), (0, 132, 254), + (1, 134, 255), (1, 134, 254), (1, 134, 254), (2, 134, 254), + (2, 130, 254), (5, 116, 244), (9, 104, 226), (13, 93, 209), + (18, 86, 197), (23, 80, 185), (38, 66, 159), (53, 52, 135), + (83, 27, 85), (99, 18, 61), (116, 10, 37), (130, 6, 22), + (144, 2, 8), (147, 1, 5), (151, 1, 3), (155, 1, 1), + (159, 1, 1), (165, 1, 1), (168, 1, 1), (172, 1, 1), + (174, 2, 0), (177, 3, 0), (184, 4, 0), (188, 4, 0), + (191, 2, 1), (191, 3, 1), (191, 4, 1), (189, 4, 0), + (188, 4, 0), (177, 4, 1), (165, 2, 2), (153, 1, 4), + (143, 1, 6), (132, 1, 7), (125, 0, 8), (119, 0, 9), + (117, 0, 9), (115, 0, 9), (118, 0, 8), (124, 0, 7), + (137, 0, 6), (137, 1, 6), (137, 2, 7), (135, 2, 9), + (133, 3, 11), (126, 5, 22), (117, 9, 38), (105, 16, 59), + (90, 25, 82), (59, 37, 122), (52, 37, 126), (46, 38, 130), + (39, 37, 134), (39, 37, 133), (45, 37, 127), (58, 35, 117), + (90, 23, 79), (106, 15, 56), (123, 8, 34), (130, 5, 26), + (138, 3, 18), (151, 1, 8), (165, 1, 4), (176, 1, 2), + (184, 1, 2), (190, 0, 1), (189, 0, 1), (189, 1, 2), + (189, 1, 2), (193, 1, 2), (202, 7, 1), (211, 13, 0), + (218, 60, 1), (220, 84, 2), (223, 109, 4), (228, 111, 5), + (233, 114, 6), (244, 119, 10), (231, 119, 26), (207, 135, 52), + (178, 146, 83), (137, 143, 131), (125, 130, 140), (113, 117, 149), + (88, 102, 170), (60, 87, 189), (35, 83, 197), (34, 79, 187), + (50, 57, 141), (54, 51, 131), (59, 45, 122), (68, 31, 97), + (79, 19, 70), (89, 10, 46), (99, 4, 25), (106, 2, 16), + (111, 1, 13), (112, 0, 10), (110, 0, 11), (109, 0, 13), + (101, 2, 23), (93, 4, 34), (83, 9, 50), (74, 14, 64), + (59, 19, 84), (57, 18, 83), (56, 18, 83), (55, 17, 86), + (56, 18, 84), (61, 18, 82), (71, 17, 75), (84, 14, 59), + (98, 8, 43), (112, 4, 26), (117, 1, 17), (122, 0, 12), + (130, 0, 7), (135, 0, 4), (142, 0, 2), (142, 0, 1), + (139, 0, 3), (139, 0, 3), (139, 0, 3), (146, 0, 2), + (153, 0, 0), (158, 0, 0), (165, 0, 0), (172, 0, 0), + (185, 6, 0), (197, 12, 0), (207, 18, 0), (219, 25, 0), + (225, 25, 1), (235, 31, 3), (244, 37, 6), (250, 43, 7), + (254, 49, 6), (254, 50, 6), (254, 48, 5), (249, 43, 7), + (239, 37, 8), (229, 30, 7), (218, 26, 6), (214, 24, 3), + (208, 18, 2), (198, 12, 2), (188, 6, 1), (178, 0, 2), + (178, 0, 1), (182, 0, 1), (192, 6, 1), (202, 12, 1), + (208, 17, 1), (213, 17, 1), (214, 10, 2), (217, 11, 1), + (216, 12, 3), (210, 18, 7), (192, 20, 17), (165, 19, 35), + (137, 22, 59), (113, 25, 85), (94, 36, 109), (73, 44, 130), + (52, 53, 151), (30, 60, 170), (17, 63, 184), (15, 63, 186), + (17, 61, 182), (25, 58, 175), (23, 56, 166), (21, 52, 159), + (24, 43, 140), (29, 33, 122), (42, 23, 105), (50, 18, 90), + (56, 18, 86), (66, 17, 77), (77, 15, 65), (91, 11, 52), + (103, 7, 37), (114, 5, 29), (122, 4, 22), (125, 3, 19), + (125, 3, 19), (114, 5, 29), (102, 14, 49), (90, 26, 76), + (73, 39, 106), (61, 50, 128), (44, 57, 150), (30, 65, 171) + ), + +// 661 Tequila +((197, 113, 40), (197, 107, 47), (196, 104, 48), (195, 102, 49), + (195, 100, 47), (196, 98, 46), (198, 97, 46), (200, 97, 46), + (205, 96, 43), (205, 92, 43), (205, 88, 44), (203, 83, 42), + (201, 79, 41), (197, 72, 38), (194, 65, 36), (193, 62, 34), + (193, 59, 33), (192, 59, 37), (191, 62, 47), (190, 66, 57), + (192, 76, 69), (194, 86, 81), (194, 91, 86), (194, 96, 92), + (191, 107, 111), (191, 115, 119), (191, 124, 128), (191, 131, 135), + (191, 139, 142), (192, 142, 144), (193, 146, 147), (195, 152, 152), + (197, 158, 154), (201, 162, 158), (202, 158, 158), (204, 155, 158), + (205, 151, 153), (207, 147, 149), (207, 144, 144), (207, 142, 140), + (206, 130, 117), (207, 123, 103), (209, 117, 90), (206, 107, 81), + (204, 98, 72), (201, 93, 70), (199, 89, 69), (195, 82, 68), + (193, 78, 66), (190, 69, 61), (190, 69, 57), (190, 69, 53), + (188, 72, 54), (186, 76, 56), (184, 79, 59), (183, 82, 63), + (175, 93, 87), (174, 95, 99), (173, 97, 111), (176, 100, 115), + (180, 104, 120), (183, 105, 122), (187, 107, 124), (192, 112, 127), + (197, 117, 128), (203, 128, 132), (203, 126, 134), (203, 125, 136), + (202, 122, 133), (201, 120, 131), (196, 113, 125), (192, 103, 116), + (185, 84, 95), (180, 78, 82), (175, 73, 69), (174, 68, 60), + (174, 63, 51), (174, 62, 47), (175, 61, 43), (175, 60, 40), + (174, 59, 42), (176, 58, 58), (175, 60, 66), (175, 63, 75), + (176, 63, 80), (177, 63, 85), (181, 62, 95), (186, 62, 97), + (192, 62, 95), (193, 62, 94), (195, 63, 94), (195, 63, 94), + (195, 64, 95), (195, 66, 94), (197, 66, 92), (199, 64, 97), + (203, 61, 94), (203, 51, 79), (201, 46, 67), (200, 41, 56), + (197, 39, 51), (195, 38, 46), (190, 36, 36), (188, 35, 25), + (194, 39, 16), (199, 43, 15), (204, 48, 14), (206, 50, 13), + (209, 53, 13), (212, 58, 13), (214, 62, 14), (213, 63, 14), + (214, 63, 14), (213, 67, 14), (213, 70, 15), (214, 73, 17), + (214, 82, 23), (214, 92, 31), (214, 102, 42), (214, 112, 54), + (216, 125, 76), (217, 127, 85), (218, 129, 94), (219, 129, 98), + (221, 130, 103), (223, 131, 111), (225, 134, 120), (224, 138, 132), + (221, 143, 145), (214, 154, 172), (213, 153, 178), (212, 153, 184), + (210, 147, 192), (211, 138, 199), (212, 133, 202), (214, 131, 202), + (213, 131, 206), (208, 134, 205), (204, 137, 205), (202, 139, 202), + (200, 141, 200), (198, 139, 190), (196, 129, 181), (193, 121, 170), + (190, 113, 157), (182, 99, 134), (181, 94, 129), (180, 90, 125), + (176, 88, 117), (172, 89, 107), (172, 92, 96), (173, 89, 86), + (179, 76, 63), (180, 72, 56), (182, 68, 50), (184, 60, 39), + (186, 51, 30), (187, 44, 25), (186, 39, 22), (186, 38, 19), + (189, 38, 20), (196, 45, 26), (198, 48, 29), (201, 52, 33), + (208, 58, 42), (213, 66, 52), (218, 74, 64), (220, 82, 76), + (222, 94, 97), (222, 96, 100), (223, 98, 104), (221, 104, 109), + (219, 113, 117), (217, 119, 124), (219, 127, 130), (220, 135, 140), + (220, 144, 151), (219, 151, 164), (218, 156, 177), (218, 161, 187), + (218, 162, 193), (218, 164, 198), (216, 164, 201), (217, 164, 200), + (220, 166, 197), (221, 167, 197), (222, 168, 197), (223, 168, 197), + (223, 171, 201), (224, 172, 203), (225, 171, 207), (225, 170, 211), + (226, 168, 211), (227, 164, 208), (229, 159, 203), (228, 154, 195), + (227, 145, 183), (223, 136, 171), (217, 128, 159), (211, 121, 148), + (205, 113, 138), (202, 109, 128), (201, 107, 118), (199, 103, 110), + (194, 100, 102), (186, 97, 91), (176, 91, 81), (166, 82, 71), + (155, 74, 61), (143, 65, 51), (132, 57, 45), (124, 54, 37), + (121, 53, 35), (118, 50, 34), (116, 54, 33), (116, 56, 37), + (118, 62, 43), (121, 68, 52), (123, 73, 60), (123, 75, 71), + (124, 77, 81), (129, 81, 92), (139, 83, 103), (147, 89, 108), + (155, 91, 114), (162, 95, 116), (170, 97, 117), (175, 99, 115), + (178, 98, 116), (179, 98, 116), (181, 98, 115), (186, 98, 114), + (190, 99, 110), (192, 95, 105), (193, 92, 101), (198, 88, 93), + (200, 85, 81), (201, 82, 70), (199, 79, 60), (196, 77, 51), + (192, 75, 42), (191, 76, 33), (191, 75, 26), (191, 76, 24), + (195, 77, 23), (197, 76, 21), (198, 75, 19), (197, 75, 19), + (198, 76, 22), (197, 79, 25), (197, 88, 27), (196, 94, 28), + (195, 100, 30), (197, 107, 32), (199, 111, 37), (200, 114, 39) + ), + +// 662 Thistle +((153, 156, 146), (160, 169, 153), (167, 172, 161), (174, 176, 170), + (167, 173, 162), (161, 170, 154), (160, 168, 154), (159, 166, 155), + (175, 163, 168), (183, 153, 181), (191, 144, 194), (192, 142, 188), + (194, 140, 182), (183, 138, 161), (173, 136, 140), (158, 132, 132), + (144, 129, 124), (109, 117, 75), (101, 107, 72), (94, 98, 70), + (100, 87, 88), (107, 76, 107), (119, 75, 120), (131, 75, 134), + (167, 100, 177), (179, 119, 188), (192, 139, 200), (192, 153, 198), + (193, 168, 197), (186, 172, 186), (179, 176, 175), (158, 173, 150), + (135, 155, 133), (94, 117, 87), (78, 103, 69), (62, 90, 51), + (60, 88, 46), (58, 87, 41), (61, 90, 39), (64, 93, 37), + (75, 111, 25), (76, 115, 26), (77, 120, 27), (75, 117, 23), + (73, 114, 20), (67, 111, 19), (61, 108, 19), (53, 101, 20), + (49, 96, 21), (49, 92, 29), (53, 93, 36), (57, 95, 43), + (66, 101, 50), (76, 108, 58), (78, 109, 62), (81, 110, 67), + (85, 108, 75), (85, 108, 74), (85, 109, 74), (82, 102, 72), + (79, 95, 71), (76, 91, 68), (73, 88, 65), (65, 82, 60), + (57, 77, 60), (51, 56, 58), (42, 51, 52), (34, 47, 46), + (30, 46, 45), (27, 46, 44), (26, 44, 44), (31, 47, 41), + (40, 58, 50), (46, 59, 57), (53, 61, 65), (63, 58, 74), + (73, 56, 84), (73, 56, 88), (74, 56, 93), (71, 58, 92), + (69, 55, 88), (65, 48, 83), (70, 55, 89), (76, 63, 96), + (79, 71, 99), (83, 79, 103), (92, 96, 102), (101, 101, 112), + (127, 117, 143), (137, 114, 151), (148, 111, 159), (151, 101, 164), + (154, 92, 170), (161, 82, 181), (167, 84, 188), (176, 80, 197), + (179, 63, 203), (171, 52, 195), (165, 65, 186), (159, 78, 177), + (153, 80, 172), (148, 82, 167), (143, 88, 155), (142, 104, 142), + (155, 143, 153), (160, 159, 152), (165, 176, 151), (166, 180, 149), + (168, 184, 148), (166, 182, 146), (160, 181, 137), (152, 176, 123), + (142, 174, 103), (120, 157, 66), (114, 150, 60), (109, 144, 54), + (98, 140, 46), (85, 128, 39), (79, 121, 40), (76, 109, 44), + (77, 97, 62), (79, 98, 71), (82, 100, 80), (83, 100, 81), + (84, 101, 82), (92, 105, 83), (97, 105, 86), (98, 112, 84), + (94, 119, 76), (94, 121, 61), (96, 122, 60), (98, 123, 59), + (106, 135, 60), (117, 151, 67), (132, 166, 78), (147, 176, 102), + (179, 198, 149), (189, 208, 160), (199, 218, 172), (201, 218, 171), + (204, 218, 171), (204, 212, 172), (207, 212, 178), (204, 213, 188), + (201, 210, 183), (187, 175, 163), (183, 165, 167), (179, 155, 172), + (173, 138, 183), (169, 119, 183), (156, 98, 173), (138, 76, 151), + (104, 48, 112), (98, 45, 106), (92, 42, 101), (77, 40, 79), + (56, 33, 56), (38, 33, 35), (28, 33, 24), (25, 37, 17), + (20, 35, 12), (18, 34, 11), (20, 37, 11), (22, 40, 12), + (27, 47, 11), (26, 48, 11), (27, 43, 14), (24, 38, 15), + (22, 43, 16), (22, 44, 22), (23, 45, 28), (26, 44, 47), + (35, 46, 65), (48, 48, 81), (64, 54, 95), (77, 64, 110), + (84, 72, 116), (88, 76, 117), (91, 80, 110), (96, 83, 104), + (90, 85, 90), (80, 81, 75), (67, 75, 61), (62, 67, 60), + (61, 56, 62), (61, 52, 64), (61, 48, 67), (64, 39, 78), + (70, 35, 88), (79, 38, 96), (89, 37, 106), (97, 37, 120), + (109, 29, 137), (115, 30, 142), (115, 26, 140), (107, 30, 135), + (102, 26, 133), (96, 27, 121), (83, 22, 102), (65, 24, 82), + (46, 25, 66), (32, 24, 51), (26, 25, 37), (26, 29, 31), + (29, 40, 33), (35, 45, 41), (55, 55, 56), (77, 74, 70), + (102, 97, 91), (118, 123, 109), (140, 139, 131), (155, 161, 143), + (166, 174, 151), (163, 185, 148), (159, 185, 146), (150, 181, 141), + (142, 173, 132), (129, 160, 119), (118, 145, 111), (106, 126, 109), + (98, 111, 114), (96, 96, 120), (99, 87, 127), (100, 78, 130), + (102, 70, 134), (105, 61, 137), (113, 62, 135), (120, 71, 126), + (122, 83, 118), (122, 91, 115), (120, 97, 115), (119, 105, 118), + (113, 105, 120), (112, 99, 128), (114, 91, 136), (117, 91, 147), + (115, 93, 152), (121, 93, 158), (130, 92, 157), (138, 100, 155), + (145, 121, 155), (161, 147, 162), (177, 164, 173), (189, 181, 180), + (199, 195, 188), (215, 211, 200), (227, 219, 216), (233, 228, 229), + (234, 229, 234), (229, 228, 230), (212, 217, 215), (191, 203, 192), + (166, 182, 162), (160, 174, 159), (159, 172, 163), (163, 167, 169) + ), + +// 663 Tribal +((106, 84, 41), (99, 83, 51), (98, 85, 56), (98, 88, 61), + (97, 87, 65), (96, 87, 69), (97, 88, 69), (98, 90, 70), + (120, 100, 69), (125, 103, 66), (131, 106, 63), (132, 105, 57), + (134, 105, 52), (119, 93, 46), (105, 81, 40), (98, 75, 36), + (91, 70, 33), (81, 54, 22), (89, 57, 18), (98, 60, 15), + (113, 71, 13), (128, 83, 11), (129, 84, 11), (130, 86, 11), + (123, 85, 12), (122, 84, 10), (121, 84, 9), (125, 87, 10), + (130, 90, 12), (136, 94, 12), (143, 99, 13), (156, 108, 15), + (168, 117, 20), (172, 128, 34), (172, 132, 41), (172, 136, 49), + (170, 138, 58), (168, 141, 67), (165, 140, 71), (163, 140, 75), + (151, 140, 99), (146, 141, 113), (142, 143, 128), (140, 146, 144), + (138, 150, 161), (139, 151, 164), (141, 152, 168), (133, 148, 176), + (128, 146, 180), (98, 126, 183), (86, 119, 182), (75, 112, 181), + (69, 108, 179), (64, 105, 178), (62, 100, 174), (60, 96, 171), + (52, 80, 147), (42, 68, 132), (33, 57, 117), (21, 48, 109), + (10, 40, 101), (7, 38, 99), (4, 37, 98), (1, 34, 97), + (1, 34, 97), (1, 36, 100), (2, 37, 103), (3, 39, 106), + (3, 37, 101), (3, 36, 97), (3, 35, 92), (3, 33, 89), + (3, 32, 87), (7, 33, 85), (12, 34, 83), (23, 42, 84), + (35, 50, 85), (42, 54, 81), (49, 58, 77), (63, 65, 68), + (78, 72, 57), (98, 80, 28), (111, 87, 23), (124, 95, 18), + (130, 99, 19), (137, 104, 20), (152, 116, 22), (167, 129, 28), + (201, 162, 41), (210, 174, 50), (219, 186, 60), (221, 190, 65), + (224, 195, 70), (227, 200, 77), (221, 195, 80), (204, 186, 87), + (189, 176, 92), (159, 152, 91), (144, 141, 91), (129, 131, 92), + (126, 128, 91), (123, 125, 91), (116, 115, 85), (99, 101, 80), + (63, 70, 66), (45, 52, 54), (27, 34, 42), (18, 26, 38), + (9, 18, 34), (1, 9, 26), (1, 5, 17), (1, 2, 11), + (1, 1, 7), (1, 1, 5), (1, 1, 5), (1, 1, 5), + (1, 1, 5), (1, 1, 5), (2, 1, 5), (2, 1, 5), + (11, 5, 5), (21, 11, 4), (31, 18, 4), (36, 22, 4), + (42, 26, 4), (53, 33, 4), (64, 40, 4), (73, 45, 4), + (66, 41, 4), (63, 38, 4), (63, 38, 3), (63, 38, 3), + (63, 38, 3), (63, 38, 2), (65, 39, 2), (73, 45, 2), + (55, 35, 2), (44, 27, 2), (33, 20, 3), (27, 16, 2), + (22, 13, 2), (11, 6, 2), (3, 0, 3), (3, 0, 3), + (3, 0, 3), (3, 0, 4), (3, 0, 4), (4, 0, 5), + (3, 0, 5), (3, 0, 5), (3, 0, 6), (3, 0, 6), + (3, 0, 5), (3, 0, 5), (3, 0, 5), (3, 0, 5), + (3, 0, 6), (3, 1, 7), (9, 6, 7), (18, 13, 8), + (29, 20, 8), (51, 35, 11), (54, 38, 12), (58, 41, 14), + (67, 48, 16), (70, 50, 19), (77, 57, 22), (87, 64, 27), + (111, 82, 31), (118, 86, 31), (126, 91, 31), (139, 100, 32), + (153, 110, 35), (162, 118, 37), (170, 127, 39), (176, 134, 44), + (179, 138, 45), (182, 144, 47), (187, 148, 50), (191, 150, 50), + (194, 152, 51), (197, 154, 50), (201, 158, 49), (204, 163, 50), + (204, 164, 53), (202, 163, 54), (200, 162, 56), (188, 153, 57), + (171, 142, 60), (153, 129, 62), (137, 117, 63), (122, 107, 65), + (110, 99, 67), (98, 90, 67), (89, 83, 66), (78, 73, 63), + (63, 62, 60), (49, 50, 58), (36, 40, 54), (24, 29, 50), + (14, 22, 46), (6, 16, 43), (2, 13, 40), (10, 15, 36), + (20, 19, 31), (28, 20, 25), (28, 18, 20), (28, 17, 15), + (29, 17, 11), (38, 22, 8), (42, 26, 7), (55, 34, 6), + (72, 48, 7), (95, 65, 7), (112, 81, 9), (127, 92, 8), + (134, 100, 12), (144, 110, 13), (147, 115, 14), (149, 116, 13), + (152, 118, 14), (160, 122, 13), (170, 129, 13), (170, 129, 11), + (162, 123, 12), (151, 116, 13), (138, 108, 12), (124, 97, 12), + (109, 86, 12), (93, 72, 11), (86, 65, 12), (71, 54, 15), + (64, 48, 17), (60, 44, 17), (60, 43, 17), (60, 43, 17), + (64, 46, 17), (70, 51, 15), (83, 62, 14), (91, 68, 16), + (101, 77, 18), (111, 84, 18), (122, 92, 18), (132, 98, 18), + (140, 102, 17), (143, 101, 13), (143, 100, 9), (138, 94, 6), + (129, 89, 6), (118, 82, 7), (109, 77, 10), (104, 76, 14), + (106, 78, 18), (105, 77, 23), (105, 78, 28), (105, 82, 34) + ), + +// 664 Trippy +((0, 86, 253), (0, 120, 253), (0, 129, 253), (0, 138, 253), + (0, 144, 251), (0, 151, 249), (0, 155, 242), (0, 160, 235), + (3, 174, 171), (22, 175, 146), (41, 177, 122), (71, 174, 112), + (101, 172, 102), (115, 157, 74), (129, 143, 47), (128, 133, 33), + (127, 124, 19), (126, 115, 57), (118, 99, 77), (110, 83, 97), + (82, 75, 84), (54, 67, 71), (39, 66, 72), (25, 66, 73), + (4, 53, 110), (14, 45, 125), (24, 38, 141), (26, 31, 140), + (28, 25, 140), (25, 21, 137), (22, 18, 134), (25, 11, 130), + (26, 7, 127), (29, 2, 114), (19, 2, 90), (9, 2, 67), + (6, 4, 44), (3, 6, 22), (6, 5, 15), (10, 5, 9), + (17, 4, 12), (13, 6, 23), (10, 9, 34), (11, 13, 37), + (13, 18, 40), (15, 18, 41), (17, 18, 42), (14, 27, 71), + (7, 34, 104), (0, 46, 142), (0, 42, 134), (0, 39, 127), + (0, 44, 144), (0, 50, 161), (0, 52, 169), (0, 55, 177), + (0, 65, 126), (0, 72, 104), (0, 80, 82), (3, 82, 73), + (7, 84, 65), (13, 90, 57), (19, 97, 49), (33, 114, 30), + (55, 125, 13), (95, 96, 8), (116, 87, 26), (137, 78, 44), + (139, 77, 49), (142, 76, 55), (147, 70, 54), (134, 52, 45), + (124, 27, 52), (101, 19, 53), (79, 11, 54), (54, 6, 36), + (29, 1, 18), (24, 1, 12), (20, 1, 7), (12, 1, 0), + (7, 0, 0), (1, 1, 0), (0, 1, 0), (0, 1, 0), + (0, 1, 0), (0, 1, 1), (0, 1, 3), (0, 1, 11), + (0, 8, 42), (0, 19, 66), (0, 30, 90), (0, 37, 100), + (0, 44, 111), (0, 54, 133), (0, 64, 139), (1, 71, 130), + (4, 85, 125), (22, 115, 108), (28, 123, 87), (34, 131, 66), + (32, 134, 52), (30, 137, 39), (27, 142, 27), (29, 142, 40), + (33, 142, 103), (24, 141, 117), (15, 141, 132), (11, 133, 135), + (7, 126, 138), (0, 107, 144), (0, 86, 147), (0, 70, 139), + (0, 61, 126), (0, 34, 75), (0, 27, 61), (0, 20, 48), + (0, 8, 33), (5, 3, 34), (11, 2, 48), (16, 3, 66), + (12, 4, 110), (12, 4, 135), (12, 5, 161), (15, 5, 173), + (19, 6, 185), (27, 8, 206), (32, 9, 224), (37, 8, 222), + (33, 7, 212), (25, 5, 162), (23, 5, 153), (22, 5, 144), + (32, 5, 122), (31, 4, 97), (24, 2, 68), (15, 1, 38), + (0, 1, 6), (0, 2, 3), (0, 3, 1), (0, 3, 1), + (0, 3, 1), (0, 5, 5), (0, 8, 11), (0, 11, 27), + (0, 17, 46), (0, 35, 97), (0, 43, 107), (0, 51, 118), + (0, 69, 145), (0, 90, 170), (0, 103, 191), (0, 120, 217), + (0, 162, 241), (0, 172, 242), (0, 183, 243), (0, 194, 237), + (0, 187, 229), (0, 181, 216), (4, 177, 186), (11, 177, 156), + (22, 182, 128), (28, 148, 90), (27, 134, 76), (27, 120, 62), + (23, 97, 37), (25, 87, 16), (33, 76, 1), (28, 66, 1), + (12, 32, 1), (7, 25, 1), (3, 19, 2), (4, 16, 2), + (11, 24, 2), (23, 37, 1), (40, 52, 1), (58, 67, 1), + (73, 81, 1), (90, 97, 1), (97, 115, 0), (102, 133, 0), + (107, 152, 0), (111, 164, 0), (120, 174, 0), (121, 187, 8), + (90, 203, 43), (79, 202, 57), (69, 202, 71), (55, 187, 85), + (47, 172, 96), (52, 160, 93), (41, 143, 96), (29, 126, 103), + (14, 100, 104), (0, 69, 98), (0, 47, 78), (0, 28, 57), + (0, 16, 40), (0, 10, 35), (0, 5, 38), (0, 2, 45), + (0, 2, 53), (0, 2, 59), (0, 6, 58), (4, 10, 55), + (12, 17, 55), (23, 24, 54), (35, 23, 50), (47, 23, 43), + (60, 20, 27), (77, 27, 14), (98, 31, 5), (116, 31, 0), + (129, 27, 0), (134, 13, 2), (134, 11, 3), (133, 10, 3), + (130, 10, 3), (124, 10, 2), (117, 3, 2), (100, 4, 3), + (80, 6, 3), (61, 6, 3), (46, 6, 2), (42, 4, 1), + (42, 4, 7), (42, 6, 15), (45, 6, 25), (50, 5, 31), + (65, 3, 26), (88, 3, 23), (110, 9, 22), (131, 21, 25), + (145, 39, 31), (163, 56, 25), (181, 81, 18), (197, 105, 8), + (210, 129, 2), (199, 144, 2), (185, 140, 1), (169, 132, 9), + (152, 121, 19), (137, 121, 32), (116, 115, 45), (89, 102, 61), + (65, 77, 89), (44, 48, 118), (26, 32, 148), (16, 21, 170), + (6, 23, 186), (0, 26, 208), (0, 34, 228), (0, 41, 245), + (0, 48, 253), (0, 56, 253), (0, 60, 253), (0, 71, 254) + ), + +// 665 Tropic +((111, 42, 86), (103, 43, 110), (97, 43, 117), (91, 43, 125), + (85, 42, 130), (79, 42, 135), (76, 41, 135), (74, 41, 135), + (71, 38, 133), (71, 37, 131), (71, 36, 129), (71, 33, 128), + (72, 31, 127), (70, 28, 125), (69, 26, 123), (67, 25, 122), + (66, 24, 121), (65, 23, 110), (67, 26, 100), (69, 29, 90), + (75, 33, 79), (82, 38, 68), (86, 41, 63), (91, 45, 59), + (114, 65, 49), (126, 76, 40), (139, 88, 31), (152, 100, 21), + (166, 112, 12), (172, 118, 8), (179, 124, 4), (191, 137, 1), + (202, 145, 0), (222, 163, 0), (229, 170, 0), (236, 177, 0), + (241, 181, 0), (247, 185, 0), (248, 188, 0), (250, 192, 0), + (254, 199, 0), (254, 201, 0), (255, 204, 0), (255, 204, 0), + (255, 204, 0), (255, 204, 0), (255, 204, 0), (255, 204, 0), + (255, 204, 0), (255, 200, 0), (255, 193, 0), (255, 187, 0), + (255, 183, 0), (255, 179, 0), (255, 174, 0), (255, 170, 0), + (255, 168, 5), (255, 163, 8), (255, 158, 11), (255, 153, 14), + (255, 148, 17), (255, 146, 18), (255, 145, 19), (255, 139, 22), + (255, 136, 25), (255, 133, 33), (255, 134, 38), (255, 135, 43), + (255, 136, 44), (255, 137, 46), (255, 139, 50), (255, 139, 51), + (251, 143, 54), (247, 144, 54), (243, 145, 54), (238, 145, 54), + (234, 145, 55), (231, 143, 56), (229, 141, 58), (224, 137, 66), + (215, 132, 77), (192, 114, 100), (177, 99, 109), (162, 84, 118), + (155, 77, 121), (148, 70, 125), (139, 58, 135), (135, 47, 150), + (120, 29, 173), (111, 23, 184), (103, 17, 195), (99, 14, 197), + (96, 12, 200), (91, 7, 201), (93, 4, 201), (91, 2, 199), + (95, 2, 195), (109, 6, 183), (117, 9, 172), (125, 13, 162), + (129, 16, 155), (134, 19, 149), (137, 27, 132), (144, 35, 117), + (161, 55, 96), (170, 65, 84), (180, 75, 72), (185, 81, 66), + (191, 88, 60), (201, 100, 46), (210, 109, 32), (217, 119, 22), + (222, 129, 16), (231, 146, 9), (232, 148, 7), (234, 150, 6), + (236, 151, 4), (239, 152, 2), (240, 156, 0), (240, 156, 0), + (237, 162, 0), (233, 163, 0), (230, 165, 0), (228, 164, 0), + (227, 163, 0), (222, 159, 0), (216, 155, 1), (210, 151, 2), + (203, 146, 3), (189, 140, 4), (186, 138, 4), (184, 136, 5), + (179, 130, 5), (174, 126, 6), (170, 118, 6), (166, 110, 7), + (158, 96, 9), (154, 86, 9), (151, 77, 9), (150, 73, 9), + (149, 70, 10), (148, 64, 12), (146, 56, 15), (143, 47, 21), + (140, 41, 28), (131, 20, 38), (128, 17, 43), (125, 14, 49), + (119, 9, 60), (113, 4, 73), (106, 1, 87), (106, 0, 108), + (94, 0, 138), (92, 0, 145), (91, 0, 152), (88, 0, 166), + (86, 0, 179), (85, 0, 190), (86, 0, 199), (87, 1, 208), + (94, 3, 214), (109, 10, 223), (116, 12, 224), (123, 15, 225), + (136, 20, 224), (148, 25, 219), (161, 30, 212), (168, 36, 201), + (174, 49, 164), (179, 53, 157), (184, 58, 150), (192, 65, 137), + (200, 72, 123), (206, 79, 111), (209, 83, 98), (210, 92, 88), + (208, 98, 81), (201, 99, 81), (193, 98, 83), (183, 94, 88), + (173, 85, 91), (164, 81, 100), (156, 80, 110), (153, 76, 111), + (150, 71, 116), (150, 70, 116), (150, 69, 116), (149, 67, 116), + (149, 65, 115), (148, 67, 114), (151, 69, 107), (159, 74, 101), + (168, 77, 89), (179, 82, 79), (190, 91, 71), (199, 93, 58), + (207, 99, 45), (211, 105, 35), (215, 114, 31), (216, 118, 27), + (217, 120, 24), (218, 123, 22), (219, 126, 19), (220, 124, 15), + (221, 123, 11), (223, 123, 8), (225, 126, 4), (226, 125, 2), + (226, 125, 2), (226, 122, 4), (225, 116, 7), (225, 107, 11), + (224, 99, 16), (224, 93, 22), (224, 87, 29), (225, 77, 36), + (227, 70, 43), (230, 63, 48), (233, 49, 46), (234, 42, 48), + (235, 39, 55), (235, 37, 63), (236, 37, 67), (236, 38, 74), + (239, 39, 75), (242, 40, 80), (246, 40, 78), (250, 43, 70), + (253, 47, 67), (254, 53, 59), (255, 66, 60), (255, 78, 59), + (255, 87, 54), (255, 96, 48), (255, 104, 40), (255, 111, 33), + (255, 113, 25), (255, 116, 17), (255, 113, 12), (254, 115, 9), + (251, 114, 9), (248, 113, 9), (244, 111, 9), (240, 106, 11), + (235, 101, 12), (230, 96, 13), (225, 85, 15), (219, 75, 19), + (211, 67, 24), (202, 60, 32), (190, 57, 42), (174, 44, 44), + (158, 43, 52), (143, 42, 62), (130, 41, 70), (119, 41, 79) + ), + +// 666 True_Blue +((0, 19, 94), (0, 18, 93), (0, 17, 92), (0, 16, 92), + (0, 19, 93), (1, 22, 94), (2, 24, 95), (3, 26, 97), + (5, 28, 95), (8, 28, 86), (11, 29, 77), (13, 28, 71), + (16, 27, 65), (14, 23, 61), (12, 20, 58), (11, 18, 57), + (11, 16, 56), (12, 14, 53), (8, 12, 60), (4, 11, 68), + (2, 12, 76), (1, 14, 85), (1, 16, 88), (2, 18, 91), + (5, 26, 104), (6, 29, 113), (8, 33, 122), (8, 35, 126), + (8, 38, 130), (8, 38, 131), (8, 39, 133), (8, 37, 131), + (8, 33, 132), (6, 27, 129), (4, 27, 125), (2, 27, 121), + (2, 27, 120), (2, 27, 120), (4, 28, 121), (7, 30, 122), + (19, 48, 137), (19, 52, 138), (19, 56, 140), (19, 54, 138), + (19, 53, 137), (20, 52, 135), (21, 52, 134), (21, 49, 124), + (18, 42, 110), (5, 23, 79), (2, 16, 70), (0, 10, 62), + (0, 6, 58), (0, 3, 54), (0, 2, 53), (0, 1, 52), + (0, 0, 55), (0, 0, 59), (0, 1, 63), (0, 1, 67), + (0, 2, 72), (0, 2, 73), (0, 3, 74), (0, 4, 75), + (0, 4, 76), (1, 6, 82), (3, 9, 89), (6, 12, 97), + (7, 14, 104), (8, 17, 111), (12, 25, 122), (16, 36, 133), + (20, 56, 147), (19, 64, 158), (19, 72, 170), (19, 82, 176), + (19, 93, 183), (20, 100, 184), (21, 107, 186), (21, 110, 194), + (20, 107, 201), (16, 86, 203), (14, 82, 202), (12, 79, 201), + (12, 77, 201), (12, 75, 202), (17, 70, 199), (16, 58, 195), + (14, 41, 176), (10, 38, 167), (6, 35, 158), (6, 33, 154), + (7, 31, 150), (8, 30, 141), (10, 26, 134), (9, 19, 127), + (5, 14, 120), (2, 10, 110), (3, 12, 106), (4, 14, 102), + (4, 14, 100), (5, 14, 98), (4, 17, 95), (4, 19, 93), + (7, 22, 83), (9, 22, 74), (12, 22, 66), (12, 22, 63), + (12, 22, 61), (10, 22, 59), (8, 20, 57), (7, 17, 56), + (8, 16, 53), (9, 14, 56), (8, 13, 57), (7, 12, 58), + (3, 10, 62), (1, 10, 64), (2, 11, 66), (4, 15, 69), + (19, 34, 87), (25, 42, 98), (31, 50, 109), (30, 51, 109), + (30, 53, 109), (33, 54, 104), (36, 55, 105), (40, 57, 105), + (41, 56, 105), (28, 42, 81), (24, 35, 73), (21, 28, 65), + (16, 19, 52), (13, 12, 45), (10, 9, 41), (7, 7, 40), + (2, 2, 44), (1, 2, 45), (0, 2, 47), (0, 2, 46), + (0, 2, 45), (0, 2, 43), (0, 1, 40), (0, 1, 36), + (0, 2, 32), (0, 3, 25), (0, 2, 24), (0, 2, 24), + (0, 0, 25), (0, 1, 31), (0, 2, 38), (0, 3, 47), + (0, 4, 64), (0, 4, 68), (1, 4, 73), (1, 4, 79), + (1, 4, 83), (2, 4, 85), (1, 4, 86), (1, 4, 86), + (0, 6, 86), (1, 13, 89), (2, 16, 92), (3, 20, 96), + (6, 30, 106), (13, 44, 118), (24, 60, 134), (36, 79, 151), + (77, 124, 189), (87, 135, 196), (98, 147, 204), (112, 158, 215), + (118, 166, 224), (106, 170, 230), (107, 178, 237), (113, 193, 243), + (118, 195, 245), (120, 193, 245), (100, 181, 241), (77, 168, 235), + (62, 165, 232), (58, 161, 228), (58, 155, 227), (58, 141, 224), + (42, 106, 198), (37, 98, 186), (32, 91, 175), (23, 75, 154), + (18, 57, 135), (11, 43, 116), (7, 30, 99), (5, 23, 81), + (2, 19, 68), (1, 16, 61), (0, 19, 61), (0, 23, 64), + (2, 29, 71), (6, 34, 82), (7, 39, 96), (8, 43, 110), + (7, 47, 121), (6, 48, 128), (7, 48, 136), (8, 42, 139), + (8, 39, 139), (7, 36, 138), (4, 32, 133), (2, 30, 131), + (1, 25, 130), (2, 23, 127), (5, 24, 122), (12, 30, 117), + (21, 39, 117), (27, 51, 123), (32, 60, 132), (32, 62, 136), + (32, 62, 134), (35, 60, 129), (35, 59, 127), (33, 61, 130), + (28, 57, 135), (20, 48, 138), (14, 37, 136), (8, 27, 138), + (5, 20, 142), (2, 19, 144), (1, 19, 147), (1, 20, 146), + (0, 21, 145), (1, 19, 147), (2, 19, 143), (2, 19, 137), + (1, 19, 124), (1, 18, 106), (0, 14, 90), (1, 9, 74), + (2, 6, 62), (2, 4, 50), (4, 4, 41), (5, 4, 34), + (5, 4, 30), (6, 4, 32), (5, 5, 36), (5, 6, 42), + (6, 8, 48), (5, 9, 56), (6, 9, 68), (5, 10, 81), + (3, 11, 91), (3, 14, 97), (1, 18, 100), (0, 21, 103), + (2, 19, 104), (2, 17, 103), (2, 16, 100), (1, 16, 96) + ), + +// 667 Tryst +((165, 198, 195), (171, 198, 186), (185, 202, 186), (200, 207, 187), + (209, 204, 183), (219, 202, 179), (219, 197, 173), (219, 192, 167), + (197, 157, 133), (181, 140, 116), (166, 124, 99), (158, 113, 89), + (150, 103, 80), (150, 98, 78), (150, 94, 76), (151, 93, 76), + (153, 93, 76), (155, 97, 77), (157, 105, 82), (160, 113, 88), + (164, 121, 95), (169, 130, 103), (174, 133, 106), (179, 137, 110), + (190, 142, 115), (190, 135, 110), (191, 129, 105), (179, 119, 95), + (168, 109, 86), (160, 102, 81), (152, 96, 76), (137, 84, 66), + (126, 76, 60), (113, 55, 45), (114, 48, 40), (115, 41, 36), + (115, 35, 30), (115, 30, 25), (116, 32, 24), (117, 35, 24), + (119, 48, 27), (125, 52, 28), (131, 57, 30), (136, 51, 28), + (141, 46, 26), (141, 44, 22), (142, 42, 19), (141, 41, 17), + (139, 44, 14), (144, 59, 10), (142, 60, 15), (141, 61, 21), + (139, 62, 30), (137, 64, 40), (135, 68, 45), (134, 72, 50), + (131, 90, 67), (133, 95, 67), (136, 101, 68), (129, 97, 71), + (122, 93, 74), (118, 92, 75), (115, 91, 77), (104, 85, 85), + (93, 83, 93), (93, 85, 86), (89, 79, 81), (86, 74, 76), + (84, 70, 72), (82, 67, 69), (78, 59, 63), (72, 52, 63), + (60, 45, 60), (57, 48, 60), (54, 51, 61), (58, 56, 60), + (62, 62, 60), (65, 63, 61), (68, 65, 63), (75, 69, 67), + (80, 69, 68), (83, 71, 67), (85, 72, 67), (87, 73, 67), + (87, 71, 67), (88, 69, 67), (92, 69, 67), (98, 67, 65), + (115, 67, 64), (121, 72, 65), (127, 77, 67), (128, 77, 68), + (130, 77, 70), (133, 81, 74), (134, 81, 75), (135, 83, 76), + (137, 84, 75), (146, 96, 77), (153, 99, 81), (160, 103, 86), + (163, 104, 88), (166, 106, 90), (172, 111, 93), (178, 114, 92), + (186, 122, 92), (184, 124, 94), (183, 126, 96), (183, 128, 99), + (183, 130, 102), (188, 137, 108), (194, 146, 116), (201, 156, 122), + (210, 169, 133), (220, 192, 154), (220, 196, 159), (221, 200, 165), + (223, 206, 172), (225, 212, 179), (227, 216, 182), (230, 219, 187), + (228, 224, 195), (224, 221, 195), (220, 219, 195), (218, 215, 192), + (216, 212, 190), (212, 203, 180), (208, 193, 168), (200, 179, 157), + (189, 171, 149), (174, 155, 130), (173, 152, 124), (172, 150, 119), + (171, 145, 108), (173, 138, 94), (173, 125, 80), (166, 113, 68), + (140, 85, 49), (131, 78, 42), (122, 71, 36), (119, 70, 34), + (116, 69, 32), (114, 66, 29), (111, 66, 31), (102, 63, 37), + (89, 64, 45), (73, 66, 56), (72, 68, 58), (71, 70, 61), + (76, 76, 65), (88, 84, 72), (100, 92, 79), (109, 103, 90), + (126, 123, 106), (129, 126, 108), (133, 130, 111), (141, 131, 112), + (149, 127, 109), (156, 117, 104), (157, 108, 103), (157, 103, 103), + (157, 100, 102), (147, 101, 103), (144, 100, 101), (142, 99, 99), + (136, 93, 93), (126, 86, 89), (114, 79, 87), (104, 73, 82), + (82, 68, 77), (77, 68, 75), (73, 69, 73), (69, 66, 65), + (69, 64, 59), (71, 60, 54), (78, 60, 50), (86, 62, 44), + (97, 64, 42), (104, 69, 40), (113, 72, 36), (124, 77, 33), + (138, 82, 34), (155, 92, 37), (171, 104, 39), (189, 114, 44), + (211, 129, 53), (211, 127, 52), (211, 126, 51), (203, 120, 50), + (194, 115, 48), (181, 110, 45), (173, 104, 45), (165, 102, 49), + (159, 101, 51), (152, 93, 47), (146, 84, 44), (146, 75, 40), + (141, 69, 37), (140, 69, 35), (143, 77, 37), (152, 93, 46), + (161, 109, 52), (172, 125, 60), (186, 139, 65), (196, 149, 72), + (204, 156, 77), (211, 163, 80), (216, 172, 86), (214, 176, 90), + (205, 179, 92), (191, 178, 87), (176, 174, 84), (161, 164, 80), + (146, 153, 77), (134, 150, 72), (128, 142, 75), (123, 136, 75), + (119, 130, 76), (116, 127, 77), (115, 124, 76), (116, 116, 78), + (119, 119, 75), (129, 123, 78), (141, 129, 81), (153, 131, 87), + (164, 136, 90), (171, 138, 92), (174, 133, 93), (172, 124, 89), + (165, 117, 83), (155, 113, 76), (147, 101, 74), (142, 94, 70), + (135, 86, 65), (132, 81, 62), (133, 73, 57), (135, 67, 50), + (133, 68, 43), (134, 72, 45), (139, 77, 51), (147, 88, 55), + (157, 101, 63), (173, 114, 75), (189, 128, 85), (203, 140, 90), + (210, 153, 99), (209, 161, 114), (202, 168, 122), (188, 174, 127), + (176, 177, 134), (167, 179, 147), (164, 182, 154), (165, 186, 164), + (171, 193, 179), (175, 195, 191), (173, 197, 197), (168, 199, 195) + ), + +// 668 Tumbleweed +((85, 75, 65), (84, 76, 61), (88, 78, 62), (93, 81, 64), + (111, 93, 71), (129, 106, 78), (134, 111, 82), (140, 116, 86), + (146, 122, 90), (147, 119, 84), (148, 117, 78), (138, 111, 77), + (129, 105, 76), (115, 94, 71), (101, 83, 67), (97, 80, 64), + (93, 77, 62), (91, 81, 69), (95, 87, 76), (100, 94, 83), + (105, 99, 88), (110, 105, 93), (111, 106, 94), (113, 107, 95), + (116, 111, 98), (111, 106, 93), (106, 102, 89), (97, 90, 79), + (89, 79, 69), (85, 74, 63), (82, 69, 57), (76, 63, 47), + (70, 60, 41), (64, 56, 35), (63, 53, 31), (63, 51, 27), + (61, 52, 30), (59, 53, 33), (59, 53, 36), (59, 54, 39), + (59, 54, 47), (57, 53, 50), (55, 52, 53), (54, 52, 54), + (54, 52, 56), (55, 52, 56), (56, 53, 56), (57, 55, 54), + (61, 58, 53), (73, 63, 51), (78, 66, 51), (84, 70, 51), + (87, 74, 52), (90, 78, 53), (90, 77, 53), (91, 77, 54), + (88, 74, 59), (81, 71, 59), (75, 68, 59), (64, 60, 54), + (54, 53, 50), (50, 48, 47), (46, 44, 45), (39, 36, 38), + (32, 29, 31), (21, 19, 20), (20, 18, 19), (19, 17, 18), + (20, 17, 17), (21, 18, 17), (25, 22, 18), (28, 25, 19), + (34, 30, 21), (35, 31, 19), (37, 32, 17), (36, 31, 15), + (35, 30, 14), (34, 28, 13), (33, 26, 13), (32, 23, 12), + (30, 21, 11), (28, 21, 17), (31, 23, 20), (34, 25, 24), + (36, 26, 25), (38, 28, 27), (43, 33, 30), (47, 38, 32), + (52, 40, 26), (49, 37, 22), (47, 34, 18), (43, 32, 17), + (40, 31, 17), (36, 29, 14), (31, 24, 10), (27, 22, 6), + (21, 17, 3), (14, 11, 8), (15, 12, 12), (16, 13, 16), + (17, 14, 17), (18, 16, 18), (20, 18, 18), (22, 19, 19), + (25, 21, 25), (27, 23, 25), (29, 26, 26), (29, 27, 26), + (30, 28, 27), (31, 30, 28), (32, 32, 31), (35, 34, 33), + (37, 36, 34), (41, 36, 32), (41, 35, 31), (41, 35, 30), + (40, 32, 28), (38, 31, 28), (36, 30, 29), (37, 30, 29), + (37, 29, 31), (35, 29, 33), (34, 30, 35), (34, 32, 37), + (35, 35, 40), (39, 40, 45), (43, 44, 48), (46, 45, 50), + (48, 45, 50), (51, 52, 54), (53, 54, 55), (56, 56, 57), + (61, 60, 62), (68, 64, 65), (71, 66, 70), (72, 70, 73), + (73, 72, 76), (73, 70, 74), (73, 68, 73), (71, 67, 71), + (70, 66, 69), (67, 61, 64), (61, 57, 58), (56, 51, 51), + (51, 46, 47), (48, 41, 41), (47, 41, 40), (47, 41, 40), + (47, 42, 40), (47, 43, 42), (48, 45, 45), (52, 48, 51), + (60, 58, 64), (62, 60, 65), (64, 63, 67), (69, 69, 70), + (73, 72, 70), (79, 75, 68), (87, 76, 66), (92, 75, 60), + (95, 74, 56), (85, 65, 40), (82, 62, 38), (79, 59, 36), + (75, 54, 30), (71, 49, 30), (67, 46, 30), (59, 43, 31), + (47, 41, 40), (47, 43, 43), (47, 45, 47), (53, 51, 53), + (60, 56, 60), (67, 62, 67), (74, 69, 74), (84, 77, 76), + (94, 85, 78), (101, 89, 75), (105, 89, 70), (103, 84, 66), + (98, 78, 57), (93, 72, 49), (84, 63, 40), (74, 53, 28), + (54, 37, 14), (53, 35, 12), (52, 33, 11), (52, 37, 17), + (59, 44, 26), (72, 58, 44), (88, 80, 63), (114, 103, 82), + (133, 125, 100), (150, 142, 112), (162, 152, 123), (162, 157, 128), + (169, 161, 129), (166, 160, 130), (159, 154, 124), (149, 144, 117), + (134, 130, 106), (125, 123, 95), (122, 118, 89), (123, 118, 92), + (126, 122, 101), (133, 128, 110), (139, 135, 120), (145, 141, 122), + (148, 145, 126), (149, 147, 128), (148, 147, 131), (147, 144, 133), + (142, 140, 131), (136, 132, 126), (128, 125, 115), (119, 117, 106), + (112, 110, 98), (107, 105, 91), (103, 98, 87), (99, 95, 81), + (94, 91, 75), (88, 87, 70), (82, 81, 63), (76, 74, 55), + (70, 66, 51), (63, 60, 48), (55, 54, 44), (48, 47, 41), + (42, 40, 34), (38, 32, 28), (34, 26, 24), (29, 22, 20), + (24, 17, 16), (20, 15, 11), (19, 12, 8), (18, 12, 5), + (19, 14, 7), (21, 16, 11), (24, 21, 16), (29, 27, 21), + (33, 34, 25), (40, 41, 32), (46, 47, 40), (52, 52, 47), + (59, 57, 54), (65, 62, 58), (70, 66, 61), (74, 70, 66), + (78, 74, 70), (83, 77, 72), (90, 82, 74), (93, 84, 75), + (88, 79, 70), (84, 74, 66), (77, 69, 64), (78, 69, 62) + ), + +// 669 Type_AB_Positive +((116, 19, 18), (115, 19, 18), (105, 22, 19), (95, 26, 20), + (82, 25, 19), (70, 24, 18), (64, 23, 17), (58, 23, 17), + (40, 27, 18), (37, 27, 19), (35, 28, 20), (39, 28, 20), + (43, 28, 20), (52, 28, 21), (62, 28, 22), (67, 26, 22), + (73, 25, 23), (105, 27, 26), (116, 28, 27), (127, 29, 28), + (131, 33, 34), (136, 38, 40), (139, 38, 40), (143, 38, 40), + (155, 34, 34), (153, 34, 34), (151, 34, 35), (148, 35, 35), + (146, 36, 36), (148, 34, 34), (151, 33, 32), (160, 27, 25), + (166, 26, 23), (169, 29, 27), (171, 30, 28), (174, 32, 29), + (180, 32, 28), (187, 33, 28), (189, 35, 28), (191, 37, 29), + (195, 37, 29), (195, 37, 29), (195, 37, 29), (188, 37, 30), + (182, 37, 32), (175, 37, 33), (168, 38, 34), (153, 37, 34), + (137, 37, 34), (105, 35, 31), (89, 33, 31), (74, 32, 32), + (65, 30, 29), (56, 29, 27), (54, 28, 26), (53, 28, 25), + (49, 30, 25), (48, 29, 25), (47, 28, 25), (46, 25, 24), + (45, 23, 23), (44, 25, 23), (44, 27, 24), (40, 29, 25), + (37, 29, 23), (31, 24, 20), (30, 24, 19), (30, 24, 19), + (30, 25, 19), (31, 26, 20), (34, 27, 20), (39, 29, 20), + (53, 28, 18), (64, 25, 17), (76, 23, 17), (88, 23, 18), + (100, 24, 19), (102, 22, 18), (105, 20, 17), (107, 20, 13), + (107, 20, 13), (102, 21, 16), (92, 19, 16), (82, 18, 16), + (76, 17, 15), (70, 17, 15), (61, 18, 14), (56, 21, 16), + (55, 26, 23), (59, 26, 25), (63, 27, 28), (63, 27, 28), + (64, 27, 28), (65, 27, 25), (66, 29, 24), (67, 33, 26), + (68, 38, 29), (71, 44, 34), (73, 52, 38), (76, 61, 43), + (77, 63, 44), (78, 66, 45), (79, 66, 48), (76, 47, 47), + (73, 54, 51), (69, 55, 48), (66, 57, 45), (62, 47, 41), + (58, 37, 37), (53, 31, 31), (45, 27, 27), (41, 26, 25), + (41, 28, 25), (49, 30, 25), (50, 29, 25), (52, 29, 25), + (56, 31, 25), (60, 33, 25), (63, 33, 26), (64, 31, 26), + (60, 32, 23), (58, 31, 21), (57, 31, 19), (58, 31, 18), + (59, 32, 18), (60, 30, 16), (66, 29, 16), (75, 27, 18), + (89, 25, 17), (123, 30, 19), (131, 30, 19), (139, 30, 19), + (155, 32, 21), (171, 31, 22), (186, 35, 25), (197, 37, 26), + (204, 37, 26), (203, 37, 26), (202, 38, 26), (201, 38, 26), + (200, 38, 27), (195, 35, 26), (185, 34, 26), (174, 28, 23), + (158, 27, 21), (128, 29, 23), (119, 30, 24), (111, 31, 25), + (95, 26, 24), (79, 24, 21), (65, 23, 21), (53, 22, 20), + (42, 32, 26), (42, 32, 27), (43, 32, 29), (51, 37, 35), + (63, 41, 43), (83, 58, 60), (102, 57, 61), (119, 54, 59), + (134, 55, 54), (158, 61, 58), (162, 60, 56), (167, 59, 55), + (169, 47, 47), (160, 42, 38), (142, 30, 20), (128, 28, 18), + (99, 27, 18), (91, 25, 17), (83, 23, 16), (71, 24, 15), + (65, 25, 14), (63, 27, 14), (67, 28, 15), (75, 25, 17), + (87, 25, 19), (102, 27, 18), (115, 26, 18), (122, 26, 17), + (125, 24, 17), (125, 23, 18), (122, 24, 18), (118, 26, 19), + (95, 25, 16), (87, 25, 17), (80, 26, 18), (65, 25, 18), + (54, 27, 17), (45, 31, 18), (38, 29, 18), (34, 32, 20), + (27, 31, 19), (22, 29, 20), (25, 29, 22), (31, 31, 23), + (35, 30, 25), (41, 36, 28), (47, 35, 30), (53, 36, 33), + (59, 37, 33), (64, 38, 32), (70, 42, 31), (75, 43, 30), + (77, 42, 30), (77, 40, 29), (72, 34, 25), (66, 31, 22), + (62, 28, 20), (59, 27, 18), (57, 25, 17), (57, 25, 17), + (56, 23, 16), (59, 20, 15), (64, 18, 14), (69, 17, 13), + (77, 20, 12), (82, 21, 11), (85, 25, 11), (89, 28, 11), + (86, 27, 11), (82, 27, 12), (75, 24, 12), (67, 27, 13), + (61, 30, 15), (54, 31, 16), (47, 31, 18), (40, 28, 18), + (34, 25, 19), (31, 25, 19), (27, 30, 20), (23, 29, 21), + (24, 28, 21), (27, 27, 21), (27, 21, 27), (27, 21, 27), + (24, 21, 28), (24, 21, 28), (28, 21, 28), (28, 20, 22), + (29, 20, 24), (28, 20, 22), (28, 20, 20), (27, 20, 20), + (28, 25, 20), (28, 25, 20), (28, 22, 20), (30, 22, 19), + (33, 19, 19), (41, 22, 19), (52, 21, 19), (67, 22, 18), + (81, 21, 19), (94, 20, 20), (102, 25, 21), (110, 23, 21) + ), + +// 670 Underwater_Day +((29, 150, 138), (65, 164, 138), (81, 173, 150), (98, 183, 163), + (115, 186, 168), (133, 190, 173), (133, 186, 175), (133, 182, 178), + (123, 169, 157), (104, 159, 154), (86, 149, 151), (69, 142, 154), + (53, 136, 157), (58, 135, 169), (64, 134, 181), (66, 130, 186), + (69, 127, 192), (60, 144, 186), (46, 138, 182), (32, 132, 179), + (18, 120, 174), (5, 109, 170), (12, 103, 166), (19, 98, 162), + (58, 72, 150), (82, 71, 148), (107, 70, 146), (114, 74, 147), + (121, 79, 148), (115, 84, 147), (110, 89, 147), (94, 98, 145), + (73, 108, 147), (34, 120, 138), (33, 126, 140), (33, 133, 143), + (37, 131, 140), (41, 129, 137), (45, 127, 133), (49, 126, 129), + (39, 101, 118), (40, 93, 108), (42, 86, 98), (42, 85, 98), + (43, 84, 98), (42, 88, 98), (41, 93, 98), (39, 97, 97), + (36, 104, 104), (43, 113, 115), (57, 105, 113), (72, 98, 112), + (95, 96, 111), (119, 95, 111), (128, 96, 108), (138, 98, 105), + (144, 97, 132), (137, 109, 148), (130, 121, 165), (116, 121, 168), + (102, 121, 172), (92, 121, 168), (83, 122, 165), (66, 116, 148), + (57, 109, 115), (48, 84, 71), (48, 66, 48), (49, 48, 26), + (48, 42, 22), (47, 36, 18), (33, 35, 11), (25, 41, 7), + (12, 47, 41), (10, 60, 58), (8, 73, 76), (22, 76, 103), + (36, 79, 131), (46, 83, 133), (56, 88, 136), (77, 85, 139), + (90, 81, 138), (87, 58, 118), (73, 45, 102), (60, 32, 86), + (49, 26, 76), (39, 20, 67), (32, 18, 49), (29, 12, 33), + (39, 16, 16), (60, 27, 42), (81, 38, 68), (97, 46, 79), + (114, 54, 90), (140, 86, 117), (159, 97, 151), (181, 95, 165), + (177, 109, 163), (160, 104, 152), (131, 110, 143), (102, 116, 135), + (96, 121, 136), (91, 127, 138), (79, 143, 156), (74, 159, 155), + (92, 165, 176), (105, 158, 176), (118, 151, 177), (117, 144, 177), + (116, 138, 177), (118, 129, 168), (116, 118, 150), (106, 100, 140), + (93, 83, 112), (57, 53, 75), (52, 47, 70), (47, 41, 66), + (39, 44, 67), (31, 55, 83), (35, 54, 90), (43, 54, 102), + (51, 86, 143), (61, 86, 146), (71, 87, 150), (71, 95, 150), + (71, 103, 151), (82, 119, 148), (91, 123, 142), (87, 119, 131), + (83, 120, 132), (110, 103, 141), (112, 101, 145), (115, 100, 150), + (140, 119, 158), (160, 122, 164), (154, 119, 165), (153, 137, 168), + (126, 144, 148), (111, 139, 147), (97, 135, 147), (90, 134, 143), + (83, 134, 140), (75, 135, 142), (62, 140, 149), (53, 134, 152), + (56, 124, 152), (86, 128, 168), (100, 126, 171), (115, 125, 175), + (139, 131, 185), (165, 144, 191), (176, 150, 194), (172, 162, 198), + (149, 153, 184), (139, 150, 182), (130, 147, 180), (117, 147, 176), + (119, 137, 172), (118, 125, 174), (119, 117, 169), (134, 112, 154), + (143, 111, 147), (137, 106, 135), (136, 110, 131), (135, 115, 127), + (123, 117, 127), (111, 114, 127), (110, 120, 124), (115, 122, 112), + (109, 121, 110), (109, 122, 107), (109, 124, 105), (97, 126, 113), + (74, 127, 118), (55, 116, 115), (40, 102, 117), (28, 87, 108), + (12, 61, 83), (10, 39, 67), (12, 24, 51), (5, 11, 31), + (3, 9, 21), (4, 11, 13), (7, 11, 8), (9, 13, 9), + (12, 8, 4), (15, 8, 4), (19, 9, 5), (18, 9, 2), + (20, 8, 4), (23, 9, 8), (21, 14, 9), (21, 20, 22), + (29, 26, 40), (39, 32, 53), (50, 45, 72), (64, 59, 98), + (85, 63, 126), (97, 78, 151), (101, 101, 165), (110, 109, 180), + (114, 120, 207), (124, 162, 218), (143, 183, 210), (159, 175, 217), + (178, 191, 233), (193, 196, 229), (200, 190, 212), (202, 177, 202), + (189, 155, 183), (173, 163, 146), (159, 164, 112), (141, 134, 90), + (125, 137, 81), (97, 150, 81), (78, 141, 84), (62, 140, 100), + (33, 139, 111), (20, 137, 105), (11, 123, 93), (5, 101, 78), + (12, 86, 71), (29, 75, 67), (50, 77, 66), (67, 83, 74), + (89, 86, 77), (113, 96, 83), (110, 101, 90), (100, 94, 73), + (94, 88, 48), (68, 81, 52), (49, 74, 50), (39, 68, 32), + (28, 64, 44), (36, 62, 65), (52, 55, 61), (65, 46, 58), + (87, 38, 64), (111, 33, 57), (115, 27, 38), (124, 21, 39), + (133, 34, 56), (126, 53, 72), (125, 65, 105), (134, 93, 146), + (147, 119, 177), (144, 137, 205), (129, 155, 231), (134, 159, 229), + (130, 157, 213), (97, 152, 205), (70, 148, 184), (59, 150, 165), + (43, 141, 155), (26, 133, 146), (14, 136, 142), (16, 143, 139) + ), + +// 671 Venice +((79, 14, 7), (81, 38, 30), (94, 53, 45), (107, 69, 61), + (129, 91, 72), (152, 114, 84), (161, 122, 92), (170, 131, 100), + (199, 156, 129), (191, 161, 137), (184, 166, 145), (160, 173, 152), + (137, 181, 160), (119, 180, 165), (101, 179, 171), (95, 173, 170), + (90, 168, 169), (73, 158, 167), (75, 161, 170), (78, 164, 173), + (83, 157, 167), (89, 150, 161), (92, 145, 156), (95, 140, 151), + (100, 130, 139), (94, 120, 129), (88, 110, 119), (84, 96, 106), + (81, 82, 93), (82, 75, 86), (84, 68, 80), (80, 66, 75), + (78, 63, 69), (69, 70, 79), (80, 68, 75), (91, 67, 72), + (96, 74, 79), (102, 81, 86), (96, 92, 98), (90, 103, 111), + (120, 119, 108), (140, 120, 98), (161, 121, 88), (166, 125, 91), + (172, 130, 94), (175, 132, 90), (178, 134, 87), (181, 138, 89), + (177, 143, 91), (156, 141, 106), (158, 141, 104), (161, 142, 103), + (164, 145, 107), (167, 148, 111), (167, 151, 116), (167, 154, 122), + (190, 170, 126), (199, 170, 115), (208, 171, 105), (207, 168, 99), + (206, 165, 93), (203, 158, 90), (201, 151, 88), (191, 129, 77), + (179, 107, 64), (141, 73, 35), (117, 53, 25), (94, 34, 16), + (85, 27, 13), (76, 21, 11), (62, 8, 10), (50, 11, 14), + (21, 18, 21), (19, 21, 21), (18, 24, 22), (28, 33, 26), + (39, 43, 31), (43, 43, 33), (47, 43, 35), (58, 41, 30), + (71, 32, 26), (94, 34, 25), (95, 35, 40), (96, 36, 55), + (98, 36, 60), (101, 37, 66), (113, 43, 72), (124, 56, 63), + (121, 70, 79), (117, 71, 95), (113, 72, 112), (115, 73, 111), + (118, 75, 111), (123, 80, 96), (121, 74, 84), (109, 60, 80), + (100, 44, 74), (101, 25, 62), (103, 20, 49), (106, 15, 36), + (104, 13, 30), (102, 11, 24), (95, 8, 15), (85, 14, 18), + (72, 33, 35), (64, 43, 48), (57, 54, 61), (52, 58, 68), + (48, 62, 76), (40, 69, 89), (37, 82, 102), (38, 96, 116), + (40, 107, 123), (49, 105, 125), (50, 101, 119), (52, 97, 114), + (55, 85, 102), (52, 75, 91), (49, 69, 76), (45, 60, 66), + (49, 39, 38), (50, 36, 39), (52, 33, 40), (50, 37, 45), + (48, 41, 51), (44, 52, 59), (46, 61, 66), (46, 70, 79), + (47, 81, 91), (29, 97, 109), (26, 97, 108), (24, 98, 108), + (25, 100, 110), (30, 96, 110), (38, 93, 116), (45, 89, 123), + (57, 88, 138), (68, 94, 149), (80, 100, 160), (86, 104, 165), + (92, 109, 170), (97, 113, 176), (99, 117, 178), (102, 130, 182), + (102, 132, 183), (91, 142, 171), (83, 145, 168), (75, 148, 166), + (62, 158, 169), (52, 168, 180), (43, 176, 187), (37, 177, 187), + (21, 174, 181), (18, 174, 181), (16, 174, 182), (14, 173, 182), + (19, 169, 180), (20, 164, 173), (25, 151, 161), (31, 140, 151), + (36, 130, 141), (41, 124, 135), (41, 124, 134), (41, 124, 134), + (41, 124, 134), (36, 125, 133), (31, 128, 135), (26, 132, 138), + (20, 141, 149), (18, 141, 149), (16, 142, 150), (16, 141, 148), + (16, 141, 147), (17, 142, 147), (21, 143, 150), (22, 143, 150), + (26, 137, 145), (29, 131, 138), (29, 125, 129), (27, 121, 123), + (24, 117, 119), (19, 111, 114), (17, 108, 110), (12, 103, 108), + (7, 105, 108), (8, 104, 108), (9, 104, 108), (14, 106, 110), + (20, 107, 115), (24, 112, 120), (30, 118, 126), (36, 123, 132), + (41, 127, 136), (46, 130, 139), (48, 131, 140), (49, 131, 141), + (50, 130, 140), (50, 129, 137), (55, 122, 132), (60, 112, 129), + (66, 101, 127), (71, 94, 121), (74, 92, 110), (78, 88, 97), + (79, 86, 94), (80, 82, 94), (80, 80, 100), (75, 85, 99), + (71, 89, 95), (64, 98, 96), (57, 104, 100), (52, 109, 111), + (46, 115, 119), (44, 117, 123), (43, 121, 127), (42, 123, 130), + (43, 125, 132), (44, 126, 134), (44, 127, 136), (45, 127, 136), + (45, 127, 137), (45, 127, 137), (45, 127, 138), (46, 127, 139), + (47, 129, 139), (50, 129, 140), (53, 128, 140), (59, 125, 144), + (65, 122, 150), (71, 122, 159), (79, 121, 166), (82, 120, 167), + (86, 117, 168), (88, 115, 167), (93, 114, 168), (107, 118, 171), + (122, 124, 166), (136, 129, 163), (150, 140, 154), (157, 148, 145), + (170, 154, 139), (183, 160, 126), (193, 159, 116), (200, 159, 105), + (197, 143, 89), (195, 126, 78), (187, 107, 64), (178, 85, 50), + (168, 75, 40), (153, 53, 25), (142, 33, 14), (126, 17, 10), + (111, 2, 5), (98, 2, 5), (88, 2, 5), (81, 3, 3) + ), + +// 672 Victoria +((103, 95, 129), (114, 85, 111), (123, 80, 103), (132, 75, 96), + (140, 73, 89), (148, 71, 83), (151, 72, 80), (154, 74, 77), + (174, 79, 64), (180, 75, 59), (187, 72, 54), (189, 71, 53), + (191, 70, 53), (187, 73, 55), (183, 76, 57), (178, 77, 57), + (174, 78, 58), (152, 66, 61), (140, 60, 60), (129, 55, 60), + (117, 52, 60), (106, 50, 60), (100, 49, 60), (94, 48, 60), + (72, 43, 60), (66, 42, 59), (60, 42, 58), (63, 42, 55), + (67, 42, 53), (71, 42, 53), (76, 43, 53), (87, 41, 54), + (100, 41, 53), (113, 41, 53), (114, 41, 53), (116, 42, 53), + (119, 41, 56), (122, 40, 59), (123, 40, 62), (124, 40, 65), + (118, 44, 75), (108, 49, 80), (99, 55, 86), (91, 59, 92), + (84, 64, 99), (82, 64, 101), (81, 65, 104), (78, 66, 104), + (75, 66, 104), (73, 67, 99), (72, 67, 99), (72, 67, 99), + (70, 66, 98), (69, 66, 97), (68, 65, 96), (68, 65, 96), + (68, 63, 92), (69, 60, 93), (70, 57, 95), (67, 56, 97), + (64, 55, 100), (62, 55, 101), (61, 55, 102), (59, 58, 104), + (60, 57, 104), (63, 58, 105), (66, 62, 108), (70, 66, 111), + (74, 70, 114), (78, 75, 117), (90, 88, 124), (100, 100, 130), + (116, 114, 135), (117, 116, 136), (118, 118, 138), (122, 122, 140), + (127, 127, 143), (130, 128, 140), (134, 130, 137), (133, 130, 137), + (128, 125, 134), (111, 107, 128), (107, 103, 128), (103, 100, 128), + (102, 100, 128), (102, 100, 128), (102, 100, 127), (101, 98, 128), + (88, 90, 125), (82, 84, 121), (77, 78, 117), (75, 75, 116), + (73, 72, 115), (72, 67, 112), (72, 64, 110), (71, 60, 105), + (70, 57, 98), (64, 48, 88), (65, 47, 88), (66, 47, 89), + (68, 48, 91), (70, 50, 94), (75, 56, 96), (81, 66, 98), + (97, 89, 104), (107, 102, 113), (118, 115, 122), (123, 121, 127), + (128, 127, 133), (134, 136, 140), (135, 137, 146), (136, 140, 145), + (134, 140, 143), (125, 128, 140), (121, 124, 139), (118, 120, 138), + (107, 106, 137), (99, 97, 132), (91, 90, 126), (82, 81, 121), + (73, 72, 115), (71, 70, 114), (70, 69, 113), (71, 69, 111), + (72, 69, 110), (75, 70, 107), (81, 73, 102), (88, 73, 97), + (94, 71, 93), (108, 66, 84), (108, 63, 81), (109, 61, 78), + (108, 58, 70), (105, 53, 64), (100, 49, 59), (98, 48, 57), + (96, 45, 57), (93, 45, 57), (91, 45, 57), (88, 44, 57), + (85, 44, 57), (81, 44, 57), (82, 44, 56), (87, 46, 56), + (94, 51, 54), (105, 58, 54), (105, 60, 56), (106, 62, 58), + (108, 64, 64), (108, 65, 70), (112, 66, 74), (112, 65, 75), + (102, 63, 80), (97, 62, 82), (93, 61, 84), (80, 59, 88), + (73, 57, 91), (72, 53, 90), (73, 50, 84), (78, 46, 79), + (88, 42, 76), (106, 48, 70), (111, 50, 69), (117, 53, 68), + (128, 61, 65), (141, 65, 61), (156, 71, 59), (170, 73, 58), + (191, 80, 57), (192, 83, 57), (194, 87, 58), (194, 89, 59), + (194, 92, 58), (186, 91, 57), (178, 86, 52), (165, 81, 49), + (151, 77, 48), (135, 72, 49), (124, 67, 51), (112, 65, 54), + (101, 60, 53), (89, 55, 53), (80, 50, 54), (70, 47, 58), + (67, 53, 74), (68, 56, 78), (70, 60, 83), (74, 67, 91), + (78, 73, 99), (82, 75, 104), (84, 79, 109), (86, 82, 116), + (88, 85, 119), (88, 88, 121), (88, 89, 120), (86, 85, 117), + (83, 81, 110), (77, 76, 103), (73, 73, 97), (69, 70, 93), + (68, 68, 91), (69, 67, 91), (71, 66, 91), (71, 65, 90), + (74, 69, 91), (82, 74, 88), (93, 82, 85), (107, 92, 83), + (123, 102, 83), (137, 110, 82), (147, 115, 81), (154, 116, 75), + (156, 111, 69), (154, 107, 65), (151, 103, 63), (144, 97, 63), + (136, 94, 66), (127, 89, 69), (118, 79, 71), (105, 67, 72), + (93, 56, 75), (79, 46, 79), (69, 40, 85), (63, 38, 91), + (63, 38, 96), (65, 37, 99), (69, 38, 99), (74, 39, 100), + (76, 43, 103), (79, 47, 104), (82, 53, 108), (83, 58, 112), + (84, 59, 110), (85, 58, 106), (83, 58, 102), (81, 57, 97), + (78, 59, 94), (77, 64, 94), (79, 69, 91), (88, 72, 89), + (100, 76, 84), (109, 81, 79), (113, 85, 81), (115, 91, 87), + (112, 96, 97), (114, 102, 107), (119, 105, 115), (128, 112, 117), + (133, 116, 121), (133, 118, 124), (127, 118, 131), (116, 116, 136), + (107, 112, 142), (104, 108, 143), (101, 103, 140), (100, 100, 135) + ), + +// 673 Violet +((50, 27, 100), (48, 28, 96), (50, 28, 96), (53, 28, 97), + (56, 30, 100), (59, 33, 104), (59, 34, 104), (60, 36, 105), + (59, 34, 105), (59, 34, 106), (59, 34, 108), (58, 33, 106), + (58, 33, 105), (58, 32, 101), (58, 31, 98), (58, 31, 97), + (58, 32, 97), (61, 39, 96), (63, 41, 94), (65, 44, 93), + (69, 48, 95), (73, 52, 97), (76, 54, 98), (80, 57, 100), + (89, 62, 107), (93, 66, 114), (98, 70, 122), (105, 80, 134), + (113, 90, 146), (117, 96, 152), (122, 103, 159), (134, 114, 171), + (140, 124, 181), (146, 138, 196), (148, 143, 198), (151, 148, 201), + (152, 148, 201), (153, 148, 202), (152, 148, 202), (152, 148, 203), + (150, 149, 206), (151, 150, 208), (153, 152, 211), (156, 154, 214), + (160, 157, 217), (160, 159, 216), (160, 161, 216), (158, 160, 214), + (154, 155, 205), (146, 136, 190), (141, 131, 189), (136, 127, 188), + (132, 125, 186), (129, 124, 185), (129, 123, 184), (129, 122, 184), + (130, 124, 198), (136, 133, 206), (143, 143, 215), (151, 151, 218), + (159, 160, 221), (162, 163, 222), (165, 166, 224), (173, 172, 226), + (181, 178, 230), (187, 182, 228), (179, 173, 217), (172, 165, 207), + (168, 158, 202), (165, 152, 197), (159, 138, 189), (154, 125, 183), + (130, 102, 168), (122, 95, 163), (115, 89, 158), (120, 93, 163), + (126, 98, 169), (129, 104, 173), (132, 110, 177), (137, 122, 187), + (144, 137, 197), (165, 161, 212), (171, 168, 218), (178, 176, 225), + (178, 177, 226), (178, 178, 228), (176, 175, 228), (172, 169, 225), + (160, 147, 209), (150, 132, 197), (140, 117, 186), (134, 110, 179), + (129, 104, 172), (118, 90, 161), (108, 78, 150), (101, 69, 139), + (96, 63, 132), (93, 64, 124), (96, 72, 128), (99, 80, 132), + (103, 86, 136), (107, 92, 141), (114, 105, 152), (121, 117, 163), + (134, 135, 181), (134, 135, 183), (134, 135, 185), (132, 132, 183), + (130, 130, 182), (124, 121, 175), (117, 109, 165), (105, 94, 150), + (93, 78, 136), (79, 54, 112), (78, 51, 108), (78, 49, 105), + (77, 47, 98), (76, 48, 94), (77, 51, 93), (78, 54, 97), + (85, 65, 109), (87, 69, 112), (90, 73, 116), (90, 72, 117), + (91, 72, 118), (94, 70, 121), (94, 69, 125), (97, 69, 129), + (99, 69, 132), (103, 68, 134), (104, 69, 135), (105, 71, 137), + (110, 79, 143), (118, 90, 152), (126, 104, 163), (133, 117, 172), + (143, 140, 191), (153, 154, 202), (164, 168, 214), (169, 173, 220), + (175, 179, 227), (183, 188, 235), (187, 194, 240), (192, 197, 241), + (197, 200, 242), (208, 205, 248), (209, 206, 248), (211, 207, 249), + (214, 210, 250), (217, 216, 248), (218, 220, 249), (220, 223, 251), + (218, 223, 251), (217, 222, 251), (217, 222, 251), (213, 220, 251), + (210, 219, 252), (206, 215, 252), (203, 210, 249), (201, 207, 247), + (201, 204, 245), (199, 200, 244), (200, 199, 243), (201, 198, 243), + (202, 197, 241), (203, 195, 239), (199, 191, 233), (188, 180, 225), + (175, 157, 206), (171, 152, 201), (168, 148, 197), (159, 140, 187), + (147, 132, 177), (125, 106, 154), (116, 96, 147), (108, 85, 137), + (105, 79, 131), (103, 77, 128), (94, 63, 116), (88, 55, 112), + (83, 49, 109), (80, 45, 109), (74, 43, 108), (69, 38, 107), + (61, 35, 107), (61, 36, 109), (62, 38, 112), (62, 42, 117), + (64, 42, 119), (67, 41, 121), (69, 39, 119), (73, 42, 120), + (77, 48, 122), (81, 52, 123), (86, 53, 126), (91, 57, 127), + (96, 61, 130), (101, 71, 136), (107, 83, 142), (114, 94, 152), + (122, 108, 165), (131, 121, 178), (142, 134, 192), (153, 149, 204), + (166, 163, 214), (178, 176, 225), (187, 187, 234), (193, 194, 240), + (197, 198, 244), (200, 200, 245), (201, 199, 245), (199, 197, 242), + (194, 190, 234), (187, 179, 225), (178, 170, 215), (170, 160, 208), + (162, 154, 202), (158, 153, 199), (156, 151, 197), (156, 153, 196), + (158, 155, 200), (159, 154, 200), (162, 158, 202), (164, 160, 205), + (165, 162, 208), (165, 163, 210), (161, 157, 207), (155, 148, 201), + (148, 139, 193), (143, 133, 189), (141, 130, 187), (140, 128, 186), + (141, 128, 187), (141, 126, 186), (144, 130, 190), (150, 135, 195), + (156, 142, 198), (163, 148, 201), (169, 149, 203), (171, 151, 205), + (170, 150, 207), (163, 149, 207), (154, 144, 202), (146, 135, 196), + (137, 125, 188), (126, 113, 182), (114, 103, 176), (97, 92, 168), + (83, 79, 159), (71, 67, 147), (62, 54, 137), (55, 46, 128), + (49, 40, 121), (46, 35, 114), (47, 31, 107), (49, 28, 102) + ), + +// 674 Violet_Fog +((135, 103, 140), (117, 84, 121), (113, 73, 114), (109, 63, 108), + (103, 60, 103), (97, 58, 99), (92, 56, 95), (88, 55, 91), + (76, 47, 79), (66, 44, 71), (57, 41, 64), (46, 39, 56), + (35, 38, 49), (32, 37, 46), (29, 36, 43), (28, 36, 42), + (28, 36, 42), (24, 37, 40), (23, 37, 39), (22, 37, 38), + (21, 36, 37), (21, 35, 37), (21, 34, 36), (21, 34, 36), + (25, 31, 37), (29, 31, 40), (33, 32, 43), (44, 35, 51), + (55, 39, 59), (60, 41, 64), (66, 43, 69), (74, 46, 77), + (80, 49, 84), (102, 65, 108), (110, 72, 118), (118, 80, 128), + (116, 82, 130), (115, 84, 132), (115, 83, 132), (116, 83, 132), + (118, 84, 129), (111, 80, 121), (104, 76, 114), (94, 68, 103), + (84, 60, 93), (81, 57, 89), (79, 54, 85), (76, 48, 78), + (68, 48, 72), (55, 49, 65), (60, 53, 71), (65, 57, 78), + (72, 66, 89), (79, 76, 100), (83, 83, 107), (87, 90, 115), + (112, 117, 140), (125, 124, 153), (138, 131, 167), (143, 135, 174), + (148, 140, 182), (148, 142, 182), (149, 144, 183), (151, 140, 179), + (149, 131, 171), (126, 102, 144), (111, 92, 129), (96, 83, 114), + (91, 77, 106), (87, 72, 99), (73, 62, 84), (60, 52, 68), + (38, 45, 51), (37, 42, 50), (37, 40, 49), (39, 40, 52), + (41, 41, 56), (45, 43, 59), (50, 45, 63), (59, 49, 72), + (69, 51, 78), (82, 52, 88), (84, 52, 89), (86, 53, 90), + (87, 54, 91), (88, 56, 92), (95, 57, 96), (101, 62, 105), + (110, 70, 121), (110, 75, 123), (110, 81, 125), (112, 85, 128), + (114, 90, 131), (121, 94, 139), (129, 95, 145), (128, 93, 145), + (122, 87, 135), (99, 76, 110), (90, 69, 101), (82, 63, 93), + (79, 60, 90), (76, 58, 87), (72, 57, 86), (69, 60, 87), + (67, 66, 89), (65, 69, 88), (64, 72, 87), (63, 73, 87), + (62, 74, 87), (64, 75, 87), (65, 77, 89), (66, 80, 91), + (68, 84, 91), (71, 88, 94), (71, 88, 95), (72, 89, 97), + (75, 90, 105), (77, 91, 106), (76, 92, 105), (76, 88, 101), + (67, 69, 89), (58, 59, 78), (50, 49, 67), (46, 45, 61), + (42, 41, 55), (36, 33, 44), (34, 27, 41), (33, 25, 40), + (32, 22, 40), (31, 21, 38), (30, 21, 38), (30, 21, 38), + (30, 22, 37), (29, 21, 39), (27, 21, 38), (27, 20, 37), + (26, 21, 34), (26, 22, 34), (26, 23, 34), (26, 23, 34), + (26, 24, 34), (27, 25, 35), (27, 25, 34), (27, 25, 35), + (27, 26, 35), (27, 29, 36), (27, 29, 36), (27, 29, 36), + (27, 30, 36), (26, 29, 36), (25, 29, 36), (26, 30, 37), + (27, 34, 40), (27, 34, 40), (27, 35, 40), (27, 36, 41), + (27, 37, 41), (28, 37, 42), (29, 37, 43), (30, 37, 44), + (30, 37, 44), (31, 35, 44), (31, 34, 44), (32, 34, 44), + (35, 32, 44), (37, 31, 45), (41, 30, 47), (50, 33, 54), + (68, 41, 69), (72, 43, 72), (77, 45, 76), (74, 44, 73), + (74, 46, 75), (74, 48, 76), (74, 50, 78), (81, 57, 86), + (81, 61, 89), (79, 67, 91), (78, 72, 92), (78, 77, 94), + (82, 84, 101), (89, 91, 112), (96, 100, 123), (104, 107, 134), + (117, 115, 148), (117, 116, 150), (118, 117, 153), (115, 118, 154), + (111, 117, 152), (110, 113, 150), (108, 109, 147), (104, 104, 141), + (93, 99, 131), (82, 92, 117), (72, 84, 105), (65, 78, 95), + (60, 71, 88), (54, 64, 79), (49, 58, 69), (43, 51, 60), + (39, 46, 54), (37, 43, 52), (37, 41, 50), (38, 39, 49), + (38, 37, 47), (38, 36, 46), (36, 35, 45), (34, 36, 44), + (33, 36, 45), (32, 36, 45), (33, 37, 45), (34, 37, 46), + (33, 37, 46), (33, 37, 46), (33, 37, 46), (33, 36, 46), + (34, 34, 45), (34, 33, 44), (34, 32, 43), (35, 30, 41), + (35, 29, 40), (35, 29, 40), (36, 29, 41), (38, 33, 43), + (47, 36, 49), (58, 39, 57), (67, 43, 66), (76, 46, 75), + (80, 52, 82), (88, 56, 91), (97, 59, 99), (99, 60, 102), + (98, 58, 100), (92, 57, 97), (84, 56, 94), (80, 56, 93), + (75, 57, 89), (72, 57, 87), (74, 60, 88), (76, 65, 92), + (83, 72, 100), (91, 79, 106), (103, 86, 117), (118, 92, 132), + (135, 101, 149), (155, 114, 170), (172, 125, 183), (182, 129, 189), + (186, 131, 194), (184, 130, 191), (182, 135, 193), (184, 141, 195), + (175, 135, 185), (167, 128, 176), (155, 113, 160), (139, 106, 145) + ), + +// 675 Watermelon +((92, 42, 30), (108, 66, 42), (106, 72, 54), (105, 79, 66), + (111, 83, 75), (117, 88, 85), (119, 94, 83), (122, 101, 82), + (106, 119, 84), (95, 118, 85), (85, 117, 87), (75, 108, 74), + (65, 100, 61), (52, 88, 48), (40, 76, 35), (36, 70, 34), + (33, 64, 33), (39, 48, 31), (46, 46, 30), (53, 45, 29), + (51, 48, 29), (49, 51, 29), (49, 52, 29), (50, 53, 30), + (54, 53, 28), (50, 57, 29), (46, 61, 30), (44, 71, 31), + (42, 82, 33), (44, 84, 32), (47, 87, 31), (51, 92, 32), + (54, 93, 32), (59, 101, 34), (60, 101, 33), (62, 101, 33), + (61, 96, 32), (61, 91, 32), (63, 87, 31), (65, 83, 31), + (79, 64, 30), (88, 54, 31), (97, 45, 33), (109, 37, 31), + (121, 30, 29), (128, 28, 29), (135, 26, 29), (145, 25, 29), + (146, 26, 30), (140, 31, 30), (134, 42, 29), (129, 54, 29), + (122, 70, 28), (115, 87, 28), (113, 91, 29), (111, 95, 31), + (89, 108, 33), (79, 106, 31), (70, 104, 30), (64, 94, 29), + (58, 84, 29), (53, 78, 28), (48, 72, 28), (38, 61, 26), + (29, 48, 25), (22, 29, 24), (21, 26, 23), (21, 23, 23), + (20, 23, 22), (20, 23, 22), (21, 23, 23), (25, 23, 23), + (42, 22, 24), (53, 20, 24), (64, 19, 25), (77, 17, 25), + (90, 15, 25), (96, 15, 25), (102, 15, 26), (112, 13, 27), + (115, 14, 27), (104, 15, 26), (95, 16, 25), (86, 17, 25), + (81, 17, 24), (76, 17, 24), (70, 18, 24), (66, 20, 23), + (81, 21, 23), (96, 19, 23), (112, 18, 23), (120, 20, 24), + (129, 23, 25), (146, 24, 28), (162, 27, 31), (175, 25, 32), + (180, 20, 32), (168, 24, 31), (157, 25, 32), (146, 27, 33), + (141, 24, 33), (136, 22, 33), (123, 20, 28), (113, 18, 26), + (106, 22, 25), (115, 25, 25), (125, 28, 25), (130, 28, 25), + (135, 29, 25), (145, 27, 25), (157, 27, 26), (175, 29, 31), + (189, 33, 31), (208, 36, 29), (208, 34, 28), (209, 33, 28), + (209, 28, 31), (201, 24, 32), (195, 22, 32), (184, 21, 30), + (159, 18, 25), (145, 14, 24), (131, 10, 24), (123, 9, 23), + (116, 9, 23), (99, 9, 22), (83, 13, 22), (69, 14, 20), + (59, 15, 20), (45, 19, 21), (41, 21, 22), (38, 23, 23), + (36, 28, 26), (40, 34, 29), (52, 40, 34), (68, 50, 35), + (84, 73, 40), (88, 83, 43), (93, 94, 47), (95, 95, 45), + (98, 97, 44), (94, 98, 45), (84, 96, 42), (74, 97, 37), + (61, 95, 37), (39, 77, 31), (33, 71, 30), (27, 66, 29), + (19, 55, 26), (16, 49, 25), (16, 43, 23), (17, 39, 22), + (16, 32, 20), (16, 30, 20), (16, 29, 20), (17, 26, 20), + (18, 26, 19), (19, 28, 20), (19, 30, 20), (20, 33, 22), + (22, 36, 24), (39, 39, 26), (46, 39, 25), (53, 39, 25), + (68, 38, 25), (84, 39, 26), (102, 33, 29), (117, 30, 29), + (141, 16, 26), (144, 16, 26), (148, 16, 26), (151, 13, 27), + (151, 13, 27), (146, 12, 29), (139, 9, 28), (130, 10, 27), + (121, 12, 27), (112, 14, 27), (102, 17, 27), (93, 19, 27), + (84, 19, 26), (75, 20, 24), (65, 21, 23), (55, 21, 22), + (39, 22, 22), (36, 22, 22), (33, 22, 22), (28, 24, 21), + (24, 26, 21), (23, 29, 23), (24, 32, 24), (30, 32, 26), + (39, 31, 26), (48, 29, 27), (56, 29, 28), (58, 32, 29), + (57, 32, 29), (56, 32, 29), (55, 27, 27), (55, 23, 25), + (53, 21, 24), (46, 21, 23), (38, 23, 22), (30, 24, 22), + (28, 25, 21), (32, 24, 21), (38, 23, 21), (46, 23, 21), + (52, 24, 23), (58, 31, 24), (63, 41, 26), (68, 53, 28), + (76, 65, 30), (83, 74, 34), (88, 84, 41), (90, 95, 49), + (87, 104, 54), (82, 109, 58), (78, 109, 57), (73, 102, 56), + (69, 95, 61), (63, 85, 58), (55, 72, 58), (46, 60, 49), + (38, 47, 39), (30, 37, 35), (26, 30, 29), (23, 25, 26), + (22, 24, 24), (25, 23, 22), (29, 24, 21), (32, 26, 23), + (38, 34, 27), (48, 50, 40), (65, 66, 53), (84, 84, 67), + (100, 97, 80), (114, 112, 97), (132, 139, 126), (148, 158, 147), + (163, 173, 157), (174, 164, 148), (181, 149, 137), (188, 141, 132), + (192, 130, 132), (184, 124, 125), (174, 98, 102), (161, 71, 76), + (154, 48, 52), (151, 34, 41), (144, 36, 40), (133, 47, 37), + (125, 53, 36), (109, 49, 33), (97, 46, 28), (95, 37, 31) + ), + +// 676 Whisp +((179, 160, 155), (199, 173, 168), (210, 184, 179), (222, 195, 190), + (214, 185, 180), (207, 175, 171), (203, 171, 167), (200, 167, 163), + (180, 156, 152), (170, 145, 140), (160, 134, 129), (150, 125, 120), + (141, 117, 111), (129, 103, 97), (117, 90, 83), (114, 81, 77), + (112, 73, 71), (103, 56, 55), (98, 55, 54), (93, 54, 54), + (95, 56, 56), (97, 59, 58), (97, 64, 62), (97, 69, 66), + (100, 90, 85), (106, 100, 93), (113, 111, 101), (122, 117, 109), + (132, 123, 118), (135, 127, 121), (138, 132, 125), (142, 137, 130), + (140, 135, 128), (133, 126, 120), (127, 121, 115), (121, 116, 110), + (119, 113, 105), (117, 110, 100), (117, 110, 100), (117, 110, 101), + (127, 117, 108), (132, 120, 112), (138, 123, 116), (140, 125, 118), + (143, 127, 121), (143, 128, 121), (143, 129, 121), (142, 128, 123), + (141, 125, 123), (137, 120, 119), (136, 118, 117), (136, 117, 115), + (141, 116, 115), (147, 115, 116), (149, 115, 116), (152, 116, 116), + (150, 114, 112), (149, 116, 113), (149, 118, 114), (141, 114, 112), + (134, 111, 111), (129, 109, 108), (125, 107, 106), (116, 106, 104), + (111, 104, 104), (105, 98, 100), (102, 94, 97), (99, 91, 94), + (97, 89, 91), (95, 88, 89), (91, 81, 81), (85, 74, 73), + (67, 53, 52), (56, 42, 40), (46, 31, 29), (43, 29, 28), + (40, 28, 28), (41, 30, 31), (43, 33, 34), (51, 42, 43), + (67, 55, 58), (115, 103, 101), (141, 127, 124), (168, 152, 148), + (179, 162, 157), (191, 172, 166), (209, 189, 184), (222, 204, 198), + (234, 213, 206), (232, 208, 203), (231, 203, 200), (227, 199, 196), + (224, 195, 192), (217, 187, 183), (210, 181, 179), (214, 182, 179), + (217, 186, 181), (223, 192, 189), (226, 199, 195), (229, 207, 201), + (230, 207, 202), (231, 208, 203), (230, 205, 202), (223, 197, 193), + (191, 175, 168), (175, 160, 154), (159, 145, 141), (152, 137, 134), + (145, 130, 127), (129, 116, 111), (117, 107, 100), (109, 96, 91), + (110, 88, 84), (110, 82, 77), (110, 82, 78), (111, 83, 80), + (119, 84, 81), (125, 88, 83), (132, 94, 87), (136, 101, 96), + (150, 115, 110), (152, 121, 117), (155, 128, 124), (158, 129, 126), + (161, 131, 129), (161, 133, 131), (161, 133, 131), (153, 130, 130), + (147, 125, 123), (131, 110, 106), (126, 105, 102), (121, 101, 98), + (109, 90, 87), (95, 80, 78), (81, 69, 66), (70, 59, 58), + (54, 43, 42), (50, 39, 37), (47, 36, 33), (50, 38, 35), + (54, 41, 38), (64, 49, 45), (78, 61, 56), (93, 72, 68), + (113, 88, 85), (152, 122, 118), (157, 127, 124), (163, 132, 130), + (170, 138, 136), (172, 137, 137), (166, 132, 132), (153, 125, 124), + (117, 98, 95), (106, 90, 86), (96, 82, 78), (75, 67, 64), + (60, 55, 52), (49, 45, 43), (43, 39, 36), (41, 35, 36), + (48, 37, 40), (63, 49, 50), (67, 51, 51), (71, 53, 53), + (82, 60, 59), (93, 69, 66), (97, 75, 72), (97, 75, 69), + (90, 67, 59), (86, 64, 57), (83, 62, 56), (77, 59, 53), + (71, 57, 50), (70, 56, 50), (69, 55, 50), (68, 54, 51), + (65, 54, 52), (65, 55, 54), (67, 54, 55), (65, 51, 53), + (58, 45, 48), (51, 41, 44), (46, 35, 38), (45, 33, 35), + (45, 35, 35), (47, 38, 37), (50, 41, 40), (57, 48, 47), + (62, 54, 52), (64, 58, 56), (67, 61, 59), (69, 63, 61), + (70, 65, 62), (69, 65, 61), (70, 66, 60), (71, 64, 61), + (73, 66, 64), (79, 69, 68), (89, 77, 73), (96, 82, 79), + (100, 86, 84), (104, 90, 87), (106, 91, 86), (107, 89, 84), + (102, 82, 78), (94, 76, 71), (82, 66, 60), (70, 56, 53), + (59, 43, 44), (52, 35, 38), (46, 31, 31), (44, 32, 31), + (46, 33, 34), (55, 41, 41), (65, 51, 48), (78, 65, 59), + (92, 73, 67), (105, 82, 75), (117, 84, 80), (126, 87, 84), + (131, 90, 88), (131, 95, 91), (129, 96, 93), (129, 96, 94), + (129, 99, 97), (128, 107, 104), (127, 115, 112), (130, 123, 119), + (136, 129, 129), (147, 139, 139), (161, 150, 150), (177, 162, 160), + (188, 171, 172), (198, 180, 182), (207, 188, 189), (216, 193, 192), + (216, 193, 191), (210, 186, 186), (202, 177, 176), (191, 166, 165), + (181, 155, 153), (165, 142, 140), (151, 132, 129), (139, 123, 120), + (130, 118, 115), (120, 111, 108), (113, 109, 105), (109, 105, 103), + (107, 104, 102), (105, 101, 99), (106, 100, 97), (109, 98, 95), + (115, 102, 100), (119, 103, 101), (138, 122, 120), (157, 139, 133) + ), + +// 677 Whisper +((32, 70, 66), (16, 29, 31), (13, 28, 30), (10, 27, 30), + (10, 33, 35), (10, 39, 41), (12, 42, 44), (14, 46, 48), + (13, 50, 52), (13, 48, 50), (14, 47, 48), (12, 38, 41), + (10, 30, 34), (9, 25, 28), (9, 21, 22), (9, 20, 21), + (9, 19, 20), (13, 18, 16), (16, 19, 15), (19, 20, 15), + (25, 22, 14), (32, 25, 14), (33, 27, 16), (34, 29, 18), + (42, 35, 23), (42, 37, 25), (42, 39, 28), (39, 38, 27), + (37, 38, 27), (34, 36, 25), (32, 34, 24), (28, 31, 22), + (25, 27, 18), (18, 20, 13), (15, 18, 13), (13, 17, 13), + (12, 17, 15), (11, 18, 17), (11, 19, 19), (11, 21, 22), + (14, 33, 33), (18, 49, 48), (23, 65, 64), (32, 81, 78), + (42, 97, 92), (42, 105, 99), (42, 114, 106), (37, 120, 118), + (38, 119, 113), (24, 86, 85), (19, 71, 68), (14, 56, 52), + (14, 44, 41), (14, 33, 30), (13, 31, 27), (13, 30, 25), + (12, 22, 22), (18, 24, 21), (24, 26, 21), (32, 30, 22), + (40, 34, 23), (44, 35, 23), (48, 37, 24), (52, 40, 26), + (54, 44, 28), (44, 39, 27), (40, 37, 25), (36, 35, 23), + (35, 33, 21), (34, 31, 19), (39, 31, 16), (47, 36, 18), + (66, 54, 26), (76, 62, 34), (86, 71, 42), (97, 80, 49), + (109, 89, 56), (114, 95, 61), (120, 101, 67), (144, 115, 75), + (151, 128, 88), (151, 139, 88), (131, 134, 86), (111, 130, 84), + (100, 116, 71), (90, 102, 59), (62, 84, 49), (43, 66, 42), + (21, 35, 24), (17, 29, 23), (14, 24, 23), (13, 23, 23), + (12, 22, 24), (12, 22, 24), (16, 24, 26), (18, 27, 29), + (16, 30, 32), (22, 39, 42), (23, 41, 43), (24, 43, 45), + (27, 46, 48), (31, 50, 51), (44, 54, 51), (49, 61, 46), + (65, 93, 67), (62, 99, 73), (60, 105, 79), (57, 103, 80), + (55, 102, 81), (50, 96, 82), (40, 78, 72), (32, 60, 55), + (32, 50, 45), (30, 36, 28), (30, 35, 27), (31, 34, 27), + (32, 35, 26), (31, 33, 24), (28, 31, 23), (27, 30, 23), + (24, 28, 21), (21, 26, 20), (19, 24, 19), (17, 22, 18), + (15, 21, 17), (10, 19, 15), (8, 16, 13), (6, 14, 13), + (5, 13, 13), (6, 14, 14), (6, 15, 15), (7, 16, 16), + (8, 18, 19), (6, 20, 22), (6, 21, 23), (7, 21, 23), + (5, 18, 21), (4, 15, 17), (3, 12, 14), (2, 10, 12), + (2, 9, 10), (0, 7, 8), (0, 7, 8), (2, 7, 6), + (3, 7, 6), (4, 11, 11), (5, 11, 11), (6, 11, 11), + (6, 13, 14), (5, 15, 16), (6, 15, 16), (6, 16, 16), + (8, 17, 19), (9, 19, 19), (10, 21, 20), (15, 25, 22), + (18, 32, 29), (22, 42, 38), (28, 51, 44), (37, 55, 49), + (44, 61, 53), (50, 59, 53), (50, 56, 50), (50, 54, 47), + (46, 51, 43), (43, 45, 39), (36, 43, 38), (31, 44, 40), + (30, 51, 44), (33, 55, 44), (36, 59, 44), (36, 58, 40), + (34, 58, 44), (38, 60, 42), (39, 56, 34), (33, 48, 35), + (35, 51, 38), (39, 56, 43), (42, 60, 46), (50, 71, 52), + (55, 83, 63), (52, 92, 69), (51, 95, 68), (51, 99, 74), + (41, 93, 73), (40, 91, 72), (40, 89, 72), (37, 85, 80), + (37, 85, 79), (39, 88, 81), (47, 97, 87), (63, 104, 88), + (69, 102, 82), (71, 97, 78), (78, 94, 78), (71, 87, 69), + (52, 77, 64), (42, 76, 73), (37, 90, 86), (30, 107, 105), + (32, 117, 114), (48, 129, 119), (54, 139, 131), (49, 131, 123), + (55, 113, 104), (52, 99, 91), (40, 80, 75), (41, 62, 60), + (45, 55, 52), (45, 54, 44), (60, 57, 42), (79, 66, 49), + (93, 81, 53), (115, 103, 66), (151, 145, 113), (149, 174, 149), + (127, 166, 140), (150, 176, 152), (149, 184, 163), (117, 155, 131), + (107, 123, 103), (105, 100, 78), (100, 87, 59), (87, 77, 54), + (69, 61, 45), (52, 49, 36), (39, 42, 31), (30, 35, 26), + (24, 29, 23), (20, 25, 20), (18, 24, 19), (21, 25, 21), + (25, 27, 21), (28, 30, 21), (28, 32, 23), (28, 32, 25), + (27, 34, 24), (25, 31, 24), (22, 30, 25), (22, 31, 26), + (23, 30, 27), (22, 32, 31), (19, 34, 36), (19, 36, 39), + (21, 39, 40), (23, 41, 41), (28, 43, 40), (38, 43, 37), + (47, 45, 33), (52, 52, 33), (56, 60, 40), (58, 64, 45), + (55, 79, 64), (53, 94, 78), (43, 74, 64), (36, 66, 63) + ), + +// 678 Wintergrass +((161, 147, 99), (150, 137, 77), (153, 144, 92), (156, 151, 108), + (167, 158, 121), (179, 166, 134), (182, 168, 137), (185, 171, 141), + (190, 172, 141), (175, 161, 126), (160, 150, 112), (147, 142, 94), + (135, 134, 77), (127, 124, 57), (120, 115, 38), (123, 114, 34), + (126, 114, 30), (134, 115, 20), (138, 115, 21), (143, 116, 23), + (142, 114, 25), (142, 112, 28), (139, 111, 28), (136, 110, 29), + (119, 105, 47), (115, 106, 53), (112, 108, 60), (119, 115, 73), + (126, 123, 87), (134, 128, 94), (142, 133, 102), (155, 143, 113), + (164, 147, 117), (150, 142, 118), (137, 131, 104), (124, 120, 91), + (111, 110, 73), (98, 101, 56), (101, 100, 50), (105, 100, 44), + (119, 101, 25), (128, 107, 23), (138, 113, 21), (142, 118, 24), + (146, 123, 27), (144, 124, 31), (143, 126, 35), (141, 128, 43), + (136, 125, 51), (133, 124, 48), (134, 123, 42), (136, 122, 36), + (140, 122, 26), (144, 122, 17), (143, 120, 14), (142, 119, 11), + (129, 112, 7), (121, 105, 7), (114, 98, 8), (108, 96, 9), + (103, 95, 10), (101, 94, 11), (99, 93, 13), (101, 92, 12), + (104, 92, 16), (95, 89, 21), (92, 88, 26), (89, 87, 31), + (87, 88, 33), (86, 89, 35), (85, 92, 40), (90, 95, 40), + (104, 111, 37), (106, 111, 33), (108, 111, 30), (105, 107, 33), + (103, 104, 36), (99, 102, 36), (96, 100, 37), (89, 93, 42), + (86, 90, 47), (83, 86, 50), (80, 83, 46), (78, 81, 42), + (77, 81, 40), (77, 81, 38), (78, 82, 37), (76, 83, 39), + (87, 94, 49), (101, 104, 65), (116, 115, 81), (126, 122, 89), + (137, 129, 97), (157, 143, 112), (174, 156, 124), (186, 167, 128), + (186, 170, 121), (190, 162, 79), (184, 152, 57), (178, 142, 35), + (177, 137, 27), (176, 133, 19), (169, 127, 16), (160, 122, 16), + (139, 109, 21), (125, 108, 26), (112, 107, 32), (110, 105, 33), + (109, 104, 34), (100, 101, 36), (92, 98, 38), (93, 97, 35), + (95, 94, 31), (92, 90, 34), (91, 89, 32), (90, 89, 31), + (88, 87, 30), (86, 85, 31), (84, 84, 29), (87, 84, 28), + (100, 90, 22), (113, 96, 20), (127, 102, 18), (131, 106, 16), + (135, 110, 14), (152, 119, 12), (167, 127, 15), (168, 133, 24), + (172, 141, 45), (183, 153, 87), (183, 155, 98), (184, 158, 109), + (184, 161, 130), (186, 164, 136), (179, 158, 130), (163, 148, 116), + (126, 123, 93), (109, 109, 76), (92, 96, 60), (86, 92, 55), + (81, 88, 50), (68, 78, 40), (60, 73, 33), (59, 69, 23), + (53, 66, 19), (44, 64, 28), (45, 65, 29), (47, 66, 30), + (50, 75, 38), (54, 78, 42), (58, 82, 47), (63, 88, 51), + (70, 96, 57), (70, 96, 60), (71, 97, 63), (77, 99, 66), + (83, 105, 65), (86, 107, 65), (96, 110, 58), (106, 113, 48), + (107, 111, 42), (109, 104, 31), (108, 101, 32), (108, 99, 34), + (109, 99, 36), (110, 101, 42), (112, 105, 49), (120, 112, 49), + (133, 125, 51), (137, 125, 47), (141, 126, 43), (147, 126, 40), + (153, 131, 39), (162, 131, 35), (164, 131, 44), (166, 138, 63), + (171, 146, 79), (163, 148, 88), (149, 143, 101), (137, 139, 108), + (124, 131, 96), (105, 116, 84), (86, 104, 79), (75, 96, 68), + (73, 91, 60), (73, 91, 60), (73, 91, 60), (77, 94, 58), + (88, 98, 54), (100, 102, 49), (109, 107, 46), (116, 109, 43), + (126, 111, 37), (133, 115, 32), (135, 119, 28), (141, 121, 26), + (144, 120, 24), (146, 122, 23), (150, 123, 24), (152, 121, 26), + (153, 122, 30), (152, 123, 34), (148, 122, 40), (145, 123, 47), + (142, 125, 54), (142, 129, 69), (147, 136, 85), (156, 142, 98), + (163, 148, 111), (165, 150, 115), (173, 152, 103), (179, 153, 85), + (170, 148, 72), (157, 142, 55), (152, 135, 37), (143, 132, 34), + (127, 128, 41), (113, 122, 45), (105, 116, 47), (99, 112, 50), + (93, 106, 51), (88, 101, 50), (86, 98, 49), (84, 93, 46), + (78, 89, 44), (71, 81, 42), (61, 70, 39), (49, 63, 35), + (44, 57, 30), (50, 57, 37), (51, 59, 37), (56, 64, 32), + (70, 75, 37), (82, 86, 41), (93, 95, 38), (104, 100, 35), + (112, 107, 36), (122, 116, 40), (132, 124, 45), (140, 130, 59), + (149, 139, 81), (162, 149, 96), (172, 154, 114), (183, 163, 132), + (197, 172, 143), (205, 178, 147), (210, 184, 154), (212, 186, 159), + (212, 187, 157), (211, 188, 157), (209, 187, 159), (206, 181, 155), + (197, 173, 145), (193, 170, 141), (187, 162, 121), (169, 148, 95) + ), + + +// 679 Wooden +((92, 74, 63), (75, 57, 57), (70, 54, 54), (66, 51, 51), + (62, 49, 48), (59, 48, 45), (57, 48, 43), (56, 49, 42), + (54, 48, 42), (51, 55, 48), (49, 63, 54), (55, 74, 67), + (62, 86, 81), (69, 94, 81), (77, 102, 81), (90, 104, 79), + (104, 107, 78), (129, 101, 72), (132, 97, 64), (136, 94, 56), + (132, 87, 50), (129, 80, 45), (125, 79, 42), (122, 78, 39), + (104, 75, 39), (91, 69, 40), (78, 63, 42), (71, 59, 41), + (64, 56, 40), (61, 57, 40), (58, 58, 41), (55, 55, 41), + (53, 47, 42), (39, 51, 47), (44, 48, 42), (50, 46, 38), + (49, 48, 35), (48, 50, 33), (48, 49, 32), (48, 48, 31), + (46, 38, 25), (42, 36, 24), (39, 35, 23), (35, 29, 23), + (32, 23, 23), (30, 22, 22), (28, 21, 21), (24, 18, 24), + (17, 22, 22), (12, 20, 20), (12, 19, 18), (13, 19, 16), + (15, 22, 18), (17, 26, 21), (19, 27, 25), (22, 29, 29), + (27, 30, 37), (29, 34, 39), (31, 38, 42), (31, 34, 40), + (31, 31, 39), (30, 32, 38), (29, 33, 38), (27, 30, 37), + (27, 31, 35), (31, 35, 27), (36, 35, 28), (41, 35, 30), + (42, 35, 30), (44, 36, 31), (48, 42, 31), (51, 47, 32), + (55, 43, 30), (54, 44, 29), (53, 45, 28), (49, 42, 25), + (45, 40, 23), (43, 39, 22), (42, 38, 22), (38, 36, 21), + (33, 29, 19), (20, 24, 15), (20, 21, 13), (21, 19, 12), + (20, 15, 10), (19, 12, 9), (17, 11, 8), (15, 10, 7), + (16, 9, 6), (15, 10, 7), (15, 11, 8), (16, 13, 9), + (18, 16, 10), (21, 23, 14), (29, 23, 17), (34, 29, 19), + (39, 34, 21), (50, 38, 27), (54, 39, 27), (58, 40, 27), + (59, 41, 26), (60, 42, 26), (61, 40, 27), (61, 42, 28), + (64, 45, 29), (65, 48, 31), (66, 52, 34), (67, 53, 34), + (68, 54, 35), (69, 56, 39), (72, 59, 43), (75, 65, 49), + (78, 71, 52), (80, 75, 56), (82, 75, 56), (85, 76, 57), + (92, 80, 59), (97, 82, 60), (104, 88, 61), (113, 93, 65), + (131, 110, 79), (142, 115, 80), (154, 121, 81), (156, 124, 82), + (158, 128, 84), (149, 127, 86), (145, 117, 82), (140, 107, 75), + (135, 100, 67), (104, 84, 54), (97, 77, 52), (90, 71, 51), + (80, 64, 49), (72, 61, 49), (67, 64, 47), (65, 62, 47), + (56, 60, 45), (57, 56, 45), (58, 53, 45), (58, 52, 44), + (59, 51, 43), (57, 48, 39), (57, 43, 34), (57, 39, 30), + (58, 40, 27), (63, 40, 21), (65, 41, 19), (68, 43, 18), + (74, 44, 18), (77, 48, 20), (80, 51, 24), (85, 57, 27), + (97, 61, 31), (97, 62, 33), (98, 64, 35), (99, 66, 41), + (99, 70, 43), (100, 71, 46), (97, 73, 47), (94, 72, 50), + (86, 69, 53), (57, 76, 63), (54, 77, 65), (52, 79, 67), + (49, 78, 66), (48, 76, 68), (46, 71, 65), (45, 69, 61), + (51, 61, 45), (53, 57, 42), (56, 53, 40), (54, 45, 36), + (50, 47, 34), (43, 51, 36), (36, 54, 39), (35, 55, 39), + (30, 54, 40), (30, 54, 39), (30, 52, 40), (30, 49, 34), + (31, 43, 27), (38, 36, 22), (36, 29, 18), (34, 24, 18), + (31, 21, 13), (30, 19, 13), (29, 18, 13), (26, 15, 15), + (24, 14, 16), (22, 15, 15), (24, 18, 15), (28, 16, 17), + (32, 20, 22), (38, 26, 31), (48, 37, 43), (66, 50, 50), + (86, 72, 67), (103, 98, 80), (108, 113, 89), (118, 106, 88), + (123, 115, 88), (126, 119, 88), (119, 116, 86), (104, 94, 73), + (89, 79, 59), (76, 74, 51), (65, 70, 49), (52, 65, 49), + (51, 62, 47), (52, 62, 46), (62, 65, 46), (75, 63, 42), + (89, 62, 37), (95, 57, 30), (92, 55, 27), (87, 50, 22), + (87, 50, 18), (82, 42, 13), (70, 37, 11), (53, 34, 11), + (45, 34, 13), (42, 31, 14), (44, 29, 11), (44, 31, 10), + (47, 32, 13), (54, 35, 16), (61, 36, 17), (65, 40, 18), + (69, 42, 23), (71, 47, 29), (73, 47, 32), (72, 50, 32), + (74, 46, 32), (73, 50, 32), (73, 48, 32), (70, 46, 32), + (68, 42, 30), (64, 40, 30), (62, 39, 29), (58, 36, 30), + (54, 33, 28), (49, 32, 27), (44, 35, 26), (42, 34, 26), + (40, 35, 27), (36, 40, 30), (31, 44, 34), (35, 50, 38), + (40, 57, 40), (53, 63, 44), (62, 68, 49), (80, 77, 56), + (90, 82, 59), (90, 82, 58), (83, 72, 57), (86, 74, 60) + ), + +// 680 Wooden_2 +((59, 44, 27), (70, 50, 29), (75, 53, 30), (80, 57, 32), + (83, 59, 33), (87, 62, 34), (87, 63, 34), (88, 64, 35), + (88, 66, 35), (87, 64, 34), (86, 63, 34), (83, 61, 33), + (80, 59, 32), (76, 56, 30), (73, 54, 29), (70, 52, 28), + (68, 51, 28), (58, 45, 25), (52, 41, 23), (47, 37, 22), + (41, 33, 20), (36, 29, 19), (33, 27, 18), (31, 26, 18), + (24, 21, 16), (21, 19, 15), (19, 18, 15), (18, 17, 15), + (18, 17, 15), (17, 16, 15), (17, 16, 15), (17, 16, 15), + (17, 16, 15), (17, 16, 16), (17, 16, 16), (18, 17, 16), + (20, 17, 16), (22, 18, 17), (23, 19, 17), (24, 20, 17), + (31, 24, 19), (36, 26, 20), (41, 29, 22), (47, 32, 23), + (54, 36, 25), (57, 37, 25), (60, 39, 25), (64, 41, 26), + (67, 42, 27), (72, 47, 28), (75, 49, 28), (79, 52, 29), + (86, 56, 31), (93, 61, 33), (97, 63, 33), (101, 66, 34), + (117, 78, 38), (124, 85, 39), (132, 92, 41), (140, 105, 49), + (149, 118, 57), (154, 124, 62), (159, 131, 68), (171, 144, 74), + (181, 151, 79), (195, 164, 85), (199, 165, 83), (204, 167, 82), + (205, 168, 82), (206, 169, 83), (206, 170, 89), (207, 176, 93), + (205, 175, 95), (201, 170, 92), (197, 166, 90), (192, 157, 81), + (187, 149, 72), (184, 144, 68), (182, 139, 65), (180, 137, 63), + (181, 137, 61), (180, 135, 59), (176, 132, 56), (172, 130, 54), + (169, 127, 52), (166, 125, 51), (158, 117, 48), (148, 110, 44), + (134, 100, 39), (128, 95, 37), (122, 91, 36), (118, 88, 35), + (115, 86, 34), (107, 80, 32), (98, 73, 31), (86, 64, 29), + (74, 56, 27), (58, 45, 24), (55, 43, 24), (52, 41, 24), + (52, 41, 24), (53, 41, 24), (55, 42, 25), (57, 43, 26), + (59, 45, 27), (57, 44, 27), (56, 43, 27), (54, 42, 26), + (53, 42, 26), (51, 40, 26), (50, 39, 26), (49, 39, 25), + (49, 39, 25), (53, 41, 26), (54, 42, 26), (55, 43, 27), + (58, 44, 27), (60, 46, 28), (64, 49, 29), (69, 52, 30), + (80, 60, 32), (85, 63, 33), (91, 67, 35), (93, 68, 35), + (96, 70, 36), (99, 72, 36), (101, 74, 37), (103, 76, 37), + (105, 77, 38), (107, 79, 38), (106, 79, 38), (106, 79, 39), + (106, 79, 40), (105, 79, 39), (103, 78, 38), (102, 77, 38), + (105, 80, 37), (109, 81, 38), (113, 82, 40), (114, 82, 41), + (116, 83, 42), (117, 83, 43), (116, 82, 43), (113, 80, 42), + (110, 79, 41), (102, 75, 37), (100, 73, 36), (99, 72, 36), + (95, 69, 35), (91, 64, 34), (83, 59, 33), (75, 52, 31), + (56, 41, 26), (51, 38, 24), (47, 36, 23), (41, 33, 22), + (38, 32, 21), (38, 31, 21), (39, 32, 22), (43, 35, 23), + (48, 38, 24), (59, 45, 26), (62, 48, 27), (66, 51, 28), + (74, 57, 30), (83, 63, 32), (94, 69, 34), (104, 74, 36), + (101, 73, 35), (99, 71, 34), (98, 70, 34), (94, 67, 33), + (89, 64, 32), (82, 61, 30), (77, 58, 29), (82, 60, 29), + (76, 55, 28), (69, 51, 26), (61, 45, 24), (53, 39, 22), + (43, 32, 20), (32, 25, 18), (21, 19, 16), (21, 19, 16), + (20, 19, 16), (19, 18, 16), (19, 18, 16), (19, 18, 16), + (18, 17, 16), (18, 17, 15), (18, 17, 16), (18, 17, 16), + (19, 18, 16), (20, 19, 16), (22, 20, 16), (24, 22, 17), + (27, 23, 18), (29, 25, 18), (31, 27, 19), (32, 28, 20), + (33, 29, 20), (35, 30, 20), (36, 31, 21), (38, 33, 21), + (42, 35, 22), (46, 38, 23), (50, 41, 25), (56, 45, 26), + (61, 49, 27), (66, 52, 28), (72, 56, 29), (76, 59, 30), + (80, 62, 31), (84, 64, 31), (87, 67, 32), (91, 69, 34), + (95, 72, 36), (100, 76, 37), (106, 80, 38), (111, 84, 41), + (116, 87, 42), (118, 88, 43), (118, 89, 43), (115, 88, 44), + (111, 85, 44), (105, 80, 43), (99, 76, 40), (94, 73, 39), + (89, 69, 38), (84, 66, 37), (79, 62, 36), (74, 59, 34), + (69, 55, 33), (63, 50, 31), (56, 45, 29), (51, 41, 26), + (46, 37, 24), (42, 34, 22), (38, 32, 20), (35, 29, 19), + (33, 28, 19), (32, 27, 19), (30, 26, 19), (30, 26, 19), + (30, 26, 19), (31, 27, 19), (33, 28, 19), (35, 28, 19), + (38, 29, 19), (40, 31, 20), (42, 32, 21), (44, 33, 22), + (46, 34, 22), (48, 36, 23), (51, 38, 24), (54, 41, 26) + ), + +// 681 Wooden_3 +((95, 69, 38), (68, 47, 22), (53, 33, 11), (38, 20, 1), + (33, 17, 0), (28, 15, 0), (25, 14, 0), (23, 13, 1), + (15, 9, 1), (13, 7, 0), (12, 5, 0), (12, 5, 0), + (12, 5, 0), (14, 6, 0), (17, 7, 0), (19, 7, 0), + (21, 8, 0), (29, 12, 0), (31, 13, 0), (34, 15, 0), + (34, 15, 0), (35, 16, 0), (35, 15, 0), (35, 15, 0), + (32, 14, 1), (31, 14, 2), (30, 14, 3), (33, 18, 7), + (36, 23, 12), (40, 28, 18), (44, 33, 24), (57, 47, 38), + (74, 65, 57), (103, 96, 86), (117, 112, 102), (132, 128, 119), + (146, 144, 136), (161, 160, 154), (165, 164, 158), (169, 169, 163), + (168, 166, 160), (162, 158, 149), (156, 150, 138), (144, 135, 122), + (132, 120, 107), (123, 110, 97), (115, 101, 88), (99, 84, 68), + (87, 70, 52), (63, 41, 21), (53, 31, 12), (43, 21, 3), + (41, 20, 2), (39, 19, 1), (39, 19, 0), (40, 19, 0), + (43, 21, 0), (46, 24, 3), (50, 27, 6), (61, 36, 12), + (72, 45, 18), (78, 51, 21), (85, 57, 24), (96, 64, 25), + (105, 70, 27), (115, 79, 32), (114, 78, 30), (113, 78, 29), + (111, 74, 26), (109, 71, 23), (103, 65, 18), (95, 59, 15), + (81, 51, 17), (83, 54, 22), (85, 57, 28), (94, 66, 36), + (104, 75, 44), (108, 80, 47), (113, 86, 51), (122, 94, 60), + (130, 103, 67), (139, 108, 71), (138, 106, 69), (137, 105, 67), + (135, 104, 66), (133, 103, 65), (129, 100, 63), (127, 99, 63), + (124, 96, 63), (117, 91, 60), (110, 86, 57), (106, 82, 53), + (102, 79, 50), (92, 73, 46), (85, 66, 43), (78, 59, 39), + (67, 49, 32), (47, 29, 13), (43, 24, 10), (39, 19, 7), + (38, 18, 6), (38, 18, 6), (38, 17, 4), (38, 18, 3), + (39, 18, 3), (38, 17, 3), (38, 16, 3), (36, 15, 2), + (35, 15, 2), (34, 14, 1), (32, 13, 0), (31, 12, 0), + (31, 11, 0), (32, 13, 1), (33, 14, 2), (34, 15, 3), + (39, 22, 10), (48, 33, 21), (61, 45, 31), (77, 59, 41), + (107, 83, 51), (125, 102, 69), (144, 121, 87), (154, 132, 100), + (164, 143, 113), (183, 164, 136), (191, 174, 145), (200, 184, 151), + (205, 187, 155), (211, 194, 165), (208, 191, 163), (205, 189, 162), + (193, 178, 153), (178, 160, 136), (162, 139, 108), (145, 120, 86), + (114, 85, 48), (99, 70, 37), (84, 56, 26), (77, 49, 20), + (70, 43, 15), (61, 35, 8), (55, 29, 3), (52, 26, 3), + (55, 27, 4), (66, 38, 13), (70, 42, 17), (75, 46, 21), + (83, 54, 27), (93, 62, 34), (100, 70, 41), (107, 78, 50), + (120, 93, 65), (123, 94, 66), (126, 96, 67), (125, 96, 64), + (118, 89, 58), (110, 81, 52), (100, 73, 44), (92, 63, 39), + (87, 59, 32), (69, 40, 15), (65, 36, 11), (62, 33, 7), + (55, 26, 3), (52, 25, 3), (49, 23, 3), (46, 21, 2), + (42, 18, 0), (40, 17, 0), (39, 17, 0), (36, 17, 1), + (35, 16, 1), (35, 16, 1), (36, 17, 2), (40, 19, 3), + (45, 26, 8), (55, 37, 15), (68, 48, 23), (80, 59, 32), + (94, 67, 38), (102, 75, 48), (114, 87, 58), (125, 102, 73), + (149, 131, 105), (152, 135, 111), (155, 139, 117), (162, 143, 120), + (168, 148, 121), (171, 153, 122), (174, 154, 120), (174, 153, 119), + (174, 149, 115), (174, 145, 107), (173, 141, 98), (169, 134, 89), + (161, 126, 79), (152, 116, 74), (142, 106, 69), (130, 94, 60), + (117, 85, 53), (104, 75, 45), (94, 66, 37), (86, 59, 34), + (75, 49, 25), (66, 40, 18), (59, 34, 13), (57, 34, 12), + (63, 40, 18), (69, 46, 23), (74, 49, 26), (80, 51, 27), + (86, 59, 31), (98, 69, 37), (111, 81, 46), (120, 91, 55), + (128, 97, 62), (132, 105, 73), (141, 118, 86), (152, 131, 101), + (162, 144, 115), (171, 153, 126), (176, 159, 135), (179, 166, 145), + (184, 171, 152), (186, 173, 156), (186, 173, 152), (184, 167, 143), + (180, 161, 134), (177, 155, 126), (173, 148, 119), (166, 143, 111), + (157, 134, 101), (143, 122, 92), (130, 108, 79), (116, 93, 67), + (104, 83, 57), (96, 74, 48), (90, 70, 46), (87, 66, 44), + (89, 66, 44), (94, 71, 45), (102, 77, 47), (113, 87, 55), + (124, 98, 65), (136, 108, 72), (150, 119, 77), (158, 126, 79), + (161, 128, 79), (161, 128, 83), (158, 127, 83), (155, 124, 81), + (143, 112, 67), (129, 97, 53), (114, 83, 44), (101, 71, 35) + ), + +// 682 Woodland +((67, 42, 19), (78, 38, 13), (86, 38, 10), (94, 39, 7), + (105, 43, 6), (116, 47, 5), (119, 48, 4), (122, 49, 3), + (117, 44, 3), (108, 39, 2), (100, 34, 1), (90, 31, 3), + (81, 29, 6), (76, 26, 7), (72, 24, 8), (72, 24, 9), + (72, 25, 10), (70, 27, 8), (72, 28, 9), (74, 30, 10), + (72, 32, 10), (71, 34, 10), (70, 34, 10), (70, 34, 11), + (62, 36, 11), (60, 38, 14), (59, 41, 18), (64, 49, 24), + (69, 57, 30), (70, 61, 35), (72, 66, 41), (75, 72, 45), + (73, 72, 46), (62, 66, 40), (57, 55, 31), (53, 45, 22), + (54, 40, 16), (56, 36, 11), (59, 35, 11), (62, 34, 11), + (68, 30, 11), (72, 31, 11), (76, 32, 11), (79, 34, 12), + (82, 36, 13), (84, 36, 12), (86, 37, 12), (83, 38, 12), + (82, 40, 14), (75, 44, 18), (72, 43, 18), (69, 43, 18), + (65, 45, 18), (62, 48, 18), (63, 48, 17), (64, 49, 16), + (62, 58, 19), (68, 66, 21), (74, 74, 24), (78, 76, 25), + (83, 78, 27), (87, 77, 27), (92, 76, 28), (91, 80, 28), + (87, 76, 29), (78, 75, 36), (70, 77, 42), (62, 79, 48), + (59, 77, 47), (57, 75, 47), (53, 77, 47), (48, 71, 41), + (41, 55, 27), (37, 54, 24), (34, 54, 21), (34, 57, 22), + (34, 61, 23), (35, 65, 28), (37, 69, 34), (45, 80, 47), + (54, 93, 54), (69, 113, 95), (67, 127, 105), (65, 142, 115), + (72, 145, 130), (79, 149, 145), (74, 153, 146), (72, 150, 113), + (79, 137, 113), (69, 120, 80), (60, 103, 48), (52, 94, 45), + (45, 86, 42), (33, 71, 33), (33, 56, 23), (37, 48, 19), + (40, 42, 15), (52, 31, 11), (51, 31, 12), (51, 32, 14), + (50, 32, 14), (50, 33, 15), (46, 36, 16), (43, 39, 16), + (37, 47, 19), (37, 51, 20), (37, 56, 21), (41, 58, 23), + (45, 60, 26), (60, 66, 31), (74, 76, 34), (93, 77, 32), + (114, 73, 28), (133, 70, 21), (132, 65, 17), (132, 61, 14), + (125, 56, 9), (114, 50, 9), (99, 47, 10), (85, 45, 9), + (65, 45, 17), (62, 51, 27), (60, 58, 37), (63, 61, 42), + (67, 65, 48), (73, 77, 53), (80, 86, 58), (92, 93, 67), + (101, 105, 63), (106, 112, 49), (108, 113, 46), (110, 115, 44), + (107, 116, 36), (99, 104, 33), (88, 90, 28), (71, 82, 26), + (49, 63, 25), (43, 58, 22), (38, 54, 20), (41, 54, 19), + (44, 54, 19), (50, 55, 18), (57, 53, 13), (69, 49, 11), + (81, 51, 9), (96, 49, 9), (98, 49, 8), (101, 50, 8), + (101, 49, 7), (100, 51, 9), (96, 53, 13), (92, 52, 15), + (95, 56, 16), (97, 56, 15), (100, 56, 15), (107, 56, 14), + (113, 57, 12), (116, 58, 12), (117, 60, 14), (113, 60, 16), + (107, 60, 20), (100, 75, 29), (100, 78, 30), (100, 81, 32), + (96, 87, 30), (100, 93, 30), (101, 92, 28), (95, 85, 24), + (91, 69, 16), (87, 65, 15), (84, 62, 14), (82, 58, 11), + (80, 55, 11), (76, 49, 13), (74, 44, 10), (71, 35, 8), + (69, 24, 9), (68, 17, 8), (69, 15, 10), (72, 21, 13), + (77, 26, 14), (88, 36, 15), (99, 56, 27), (108, 75, 41), + (134, 124, 44), (139, 134, 51), (145, 144, 59), (145, 139, 59), + (145, 135, 51), (145, 140, 48), (138, 118, 46), (132, 92, 39), + (125, 85, 33), (120, 80, 29), (124, 77, 23), (129, 70, 18), + (131, 63, 11), (133, 64, 7), (130, 63, 8), (123, 65, 6), + (112, 64, 10), (95, 61, 17), (78, 64, 18), (64, 63, 22), + (53, 55, 25), (49, 52, 21), (46, 45, 19), (45, 37, 16), + (50, 30, 11), (55, 23, 10), (58, 18, 9), (61, 15, 8), + (63, 13, 7), (66, 14, 9), (66, 18, 10), (65, 23, 11), + (66, 26, 12), (63, 32, 14), (58, 37, 12), (55, 41, 13), + (54, 49, 18), (56, 61, 23), (60, 68, 28), (68, 76, 31), + (81, 87, 36), (87, 94, 43), (88, 101, 46), (87, 105, 42), + (83, 97, 36), (77, 87, 36), (73, 81, 32), (69, 68, 21), + (69, 53, 20), (72, 46, 20), (74, 49, 22), (74, 51, 23), + (77, 53, 21), (80, 59, 23), (81, 59, 22), (83, 58, 18), + (82, 56, 15), (83, 52, 14), (85, 50, 13), (84, 49, 11), + (84, 50, 9), (85, 54, 12), (87, 62, 15), (86, 70, 17), + (86, 74, 15), (84, 75, 13), (78, 76, 16), (72, 70, 16), + (67, 60, 12), (72, 59, 18), (72, 57, 25), (57, 44, 20) + ), + +// 683 Yellow_Silk +((222, 187, 42), (223, 201, 66), (215, 201, 67), (208, 202, 69), + (188, 192, 71), (168, 182, 74), (166, 176, 69), (164, 170, 65), + (167, 157, 52), (164, 157, 51), (162, 158, 51), (164, 158, 45), + (166, 159, 39), (164, 156, 36), (163, 154, 33), (163, 150, 30), + (163, 147, 28), (168, 138, 28), (166, 137, 32), (165, 136, 37), + (163, 136, 38), (162, 136, 39), (158, 139, 38), (155, 142, 38), + (161, 145, 28), (159, 140, 24), (158, 136, 21), (167, 121, 17), + (177, 106, 14), (175, 98, 18), (174, 90, 23), (183, 68, 25), + (189, 47, 25), (184, 37, 19), (181, 42, 20), (179, 47, 21), + (161, 40, 18), (144, 33, 16), (136, 35, 16), (129, 38, 17), + (90, 12, 29), (72, 11, 36), (54, 11, 43), (63, 20, 56), + (73, 29, 69), (79, 39, 79), (86, 49, 90), (113, 64, 94), + (128, 65, 89), (157, 86, 79), (171, 94, 63), (186, 102, 47), + (198, 117, 44), (211, 133, 41), (219, 148, 41), (227, 164, 41), + (236, 194, 45), (238, 200, 46), (240, 206, 48), (211, 186, 51), + (182, 167, 54), (169, 148, 53), (157, 130, 53), (150, 119, 69), + (104, 101, 82), (75, 74, 84), (60, 65, 82), (45, 57, 80), + (44, 62, 70), (44, 68, 61), (53, 57, 43), (65, 67, 45), + (117, 112, 45), (127, 122, 48), (138, 133, 52), (143, 137, 51), + (149, 141, 50), (154, 138, 49), (159, 135, 48), (167, 134, 43), + (175, 131, 38), (189, 122, 31), (191, 126, 29), (193, 130, 27), + (193, 130, 31), (194, 131, 35), (190, 140, 44), (182, 152, 51), + (172, 162, 82), (158, 147, 77), (144, 133, 72), (134, 120, 77), + (125, 107, 82), (94, 79, 76), (81, 53, 46), (78, 33, 37), + (76, 30, 29), (117, 45, 27), (144, 67, 31), (171, 90, 35), + (178, 101, 48), (186, 112, 61), (197, 115, 76), (199, 139, 90), + (207, 172, 141), (200, 174, 136), (193, 176, 132), (193, 169, 126), + (193, 163, 120), (181, 142, 86), (146, 124, 52), (120, 105, 30), + (116, 107, 23), (109, 100, 7), (111, 108, 12), (114, 117, 17), + (133, 133, 26), (152, 140, 26), (164, 147, 31), (173, 148, 39), + (210, 149, 55), (221, 137, 63), (233, 125, 72), (236, 125, 78), + (240, 126, 85), (233, 126, 95), (214, 118, 93), (193, 122, 92), + (173, 126, 85), (142, 133, 68), (139, 131, 64), (137, 130, 60), + (136, 128, 46), (140, 135, 43), (147, 137, 42), (153, 133, 37), + (190, 137, 59), (204, 146, 76), (218, 155, 93), (219, 161, 98), + (221, 167, 103), (217, 182, 107), (188, 188, 104), (170, 173, 100), + (177, 153, 87), (144, 128, 101), (148, 120, 101), (152, 113, 102), + (161, 115, 104), (155, 149, 126), (158, 178, 123), (168, 199, 117), + (216, 231, 119), (222, 236, 120), (229, 241, 121), (243, 239, 120), + (250, 235, 115), (251, 235, 117), (251, 232, 111), (250, 232, 102), + (252, 233, 104), (253, 231, 115), (252, 231, 124), (252, 232, 134), + (241, 230, 151), (229, 230, 163), (210, 229, 180), (178, 212, 185), + (139, 179, 188), (126, 176, 180), (113, 173, 172), (115, 158, 160), + (134, 167, 163), (160, 180, 155), (184, 180, 138), (207, 195, 122), + (233, 202, 113), (239, 196, 102), (224, 190, 87), (206, 182, 74), + (186, 180, 65), (172, 177, 66), (171, 178, 77), (185, 185, 74), + (215, 203, 72), (226, 208, 70), (238, 214, 69), (252, 220, 60), + (252, 221, 58), (244, 211, 55), (232, 195, 48), (216, 180, 40), + (190, 156, 31), (161, 128, 22), (135, 105, 12), (111, 76, 4), + (82, 48, 0), (72, 51, 0), (77, 53, 0), (84, 38, 5), + (103, 57, 13), (119, 76, 18), (142, 74, 26), (162, 86, 37), + (169, 104, 44), (182, 120, 61), (197, 141, 75), (210, 165, 71), + (220, 188, 74), (235, 203, 82), (247, 213, 74), (249, 219, 66), + (249, 222, 68), (252, 225, 71), (253, 223, 78), (251, 221, 89), + (240, 210, 90), (227, 195, 82), (227, 174, 73), (215, 149, 59), + (191, 132, 40), (182, 114, 21), (176, 97, 11), (168, 95, 6), + (157, 102, 8), (147, 103, 15), (147, 107, 20), (148, 114, 30), + (144, 110, 35), (137, 104, 31), (135, 86, 25), (135, 58, 20), + (137, 46, 13), (140, 32, 4), (129, 15, 0), (129, 24, 0), + (143, 45, 4), (147, 60, 8), (143, 75, 17), (151, 92, 33), + (162, 113, 42), (163, 126, 56), (154, 126, 69), (152, 136, 65), + (161, 145, 62), (159, 148, 59), (163, 150, 46), (181, 147, 37), + (191, 143, 35), (190, 144, 36), (190, 144, 40), (193, 144, 40), + (190, 143, 38), (188, 148, 41), (197, 156, 45), (210, 171, 43) + ), + +// 684 Zinfandel +((131, 89, 66), (114, 86, 62), (107, 88, 64), (101, 91, 66), + (91, 89, 64), (81, 87, 63), (77, 85, 61), (73, 83, 60), + (55, 66, 46), (56, 67, 47), (58, 69, 49), (71, 75, 53), + (85, 82, 57), (98, 88, 61), (112, 94, 65), (115, 95, 66), + (119, 97, 68), (129, 100, 71), (129, 100, 71), (130, 101, 71), + (134, 100, 71), (138, 99, 72), (139, 98, 71), (140, 97, 71), + (138, 88, 65), (125, 81, 60), (113, 75, 55), (104, 71, 54), + (96, 68, 53), (96, 69, 55), (96, 70, 58), (101, 76, 64), + (113, 85, 72), (136, 105, 84), (144, 110, 87), (152, 115, 91), + (161, 122, 97), (170, 129, 103), (175, 132, 105), (180, 136, 108), + (203, 155, 119), (211, 159, 121), (219, 164, 124), (225, 166, 126), + (231, 169, 129), (232, 171, 131), (233, 174, 134), (234, 179, 142), + (234, 185, 150), (236, 198, 169), (237, 203, 177), (239, 209, 186), + (240, 214, 194), (241, 220, 203), (241, 222, 207), (241, 225, 212), + (240, 236, 228), (240, 237, 232), (241, 239, 237), (241, 239, 237), + (241, 239, 237), (241, 239, 236), (241, 239, 236), (241, 240, 236), + (241, 240, 236), (241, 239, 235), (240, 236, 228), (239, 234, 221), + (238, 231, 216), (238, 228, 212), (236, 222, 201), (234, 214, 189), + (226, 192, 170), (218, 179, 157), (211, 166, 145), (203, 153, 133), + (195, 141, 121), (193, 137, 115), (192, 133, 109), (191, 127, 97), + (191, 122, 93), (183, 114, 89), (177, 109, 87), (171, 105, 85), + (170, 103, 83), (169, 102, 82), (171, 103, 83), (179, 107, 85), + (190, 120, 93), (191, 126, 96), (193, 132, 100), (192, 134, 100), + (192, 136, 100), (191, 139, 103), (196, 141, 105), (203, 142, 108), + (207, 146, 111), (209, 156, 121), (203, 157, 120), (197, 158, 119), + (194, 156, 118), (191, 154, 117), (185, 147, 114), (179, 138, 110), + (172, 126, 104), (168, 125, 102), (164, 124, 101), (164, 124, 101), + (164, 124, 101), (164, 125, 103), (165, 126, 103), (167, 126, 104), + (171, 127, 107), (179, 132, 111), (181, 133, 111), (184, 134, 111), + (184, 135, 113), (181, 134, 111), (174, 133, 108), (164, 132, 105), + (143, 125, 93), (132, 115, 85), (121, 106, 77), (114, 100, 72), + (108, 94, 68), (95, 82, 59), (82, 72, 53), (70, 68, 47), + (64, 67, 44), (69, 74, 46), (74, 77, 49), (79, 80, 52), + (93, 86, 59), (107, 90, 66), (120, 97, 74), (133, 104, 80), + (161, 122, 96), (174, 135, 109), (188, 148, 123), (195, 156, 131), + (202, 164, 140), (213, 179, 156), (224, 191, 170), (233, 203, 182), + (239, 209, 191), (244, 223, 208), (244, 227, 212), (245, 231, 217), + (245, 238, 226), (246, 243, 233), (245, 249, 239), (239, 250, 237), + (231, 240, 220), (228, 236, 215), (225, 232, 210), (217, 222, 199), + (210, 212, 187), (204, 199, 178), (193, 187, 165), (181, 172, 150), + (173, 159, 134), (159, 138, 111), (156, 135, 106), (153, 132, 101), + (153, 127, 97), (153, 125, 97), (154, 124, 98), (157, 127, 100), + (171, 142, 121), (174, 147, 126), (177, 153, 131), (185, 167, 144), + (194, 180, 158), (201, 192, 170), (208, 200, 178), (217, 211, 190), + (225, 219, 202), (232, 225, 208), (236, 228, 211), (239, 230, 212), + (238, 233, 216), (238, 233, 216), (238, 233, 216), (237, 236, 222), + (237, 237, 222), (237, 236, 219), (238, 235, 217), (235, 236, 214), + (233, 236, 212), (230, 232, 205), (227, 229, 203), (224, 226, 200), + (223, 223, 198), (224, 216, 191), (223, 209, 181), (222, 204, 174), + (220, 193, 162), (217, 183, 149), (214, 171, 136), (212, 157, 124), + (210, 146, 114), (207, 136, 104), (204, 129, 97), (196, 119, 91), + (183, 111, 84), (169, 104, 76), (158, 95, 70), (151, 92, 69), + (146, 94, 71), (147, 100, 75), (150, 109, 84), (151, 122, 97), + (152, 134, 110), (151, 143, 120), (154, 154, 132), (156, 165, 142), + (165, 171, 147), (178, 179, 151), (193, 189, 158), (208, 197, 165), + (217, 202, 170), (226, 205, 175), (228, 208, 181), (229, 203, 178), + (225, 196, 170), (219, 189, 159), (214, 182, 149), (208, 174, 138), + (205, 168, 130), (200, 165, 128), (196, 163, 127), (190, 161, 129), + (183, 160, 127), (177, 159, 126), (171, 157, 125), (168, 157, 124), + (169, 159, 123), (170, 159, 123), (173, 159, 125), (173, 159, 124), + (172, 158, 123), (169, 155, 122), (165, 150, 117), (163, 148, 112), + (162, 140, 105), (163, 131, 99), (163, 124, 92), (163, 116, 86), + (164, 110, 82), (162, 103, 78), (158, 102, 75), (157, 108, 77), + (155, 107, 78), (153, 106, 77), (144, 100, 72), (137, 94, 68) + ), + +// 685 040412 +((0, 110, 219), (0, 110, 222), (8, 107, 223), (16, 105, 225), + (19, 103, 225), (23, 102, 226), (24, 100, 225), (26, 99, 225), + (42, 89, 224), (39, 90, 220), (37, 91, 217), (36, 86, 212), + (36, 82, 208), (39, 83, 195), (43, 85, 183), (46, 88, 179), + (50, 91, 175), (68, 106, 162), (73, 117, 156), (78, 128, 151), + (88, 136, 144), (98, 145, 138), (104, 149, 134), (110, 154, 131), + (119, 169, 117), (118, 168, 120), (117, 168, 124), (120, 168, 120), + (123, 169, 117), (127, 167, 113), (131, 166, 109), (138, 158, 102), + (140, 149, 89), (130, 151, 60), (132, 154, 46), (135, 158, 33), + (147, 163, 19), (159, 168, 5), (164, 168, 4), (170, 169, 4), + (180, 165, 5), (175, 160, 8), (170, 156, 11), (166, 143, 16), + (163, 130, 21), (157, 121, 21), (152, 113, 21), (142, 99, 21), + (133, 86, 22), (113, 72, 16), (111, 71, 8), (109, 70, 0), + (107, 66, 0), (106, 63, 0), (102, 62, 0), (99, 61, 0), + (84, 64, 0), (79, 61, 0), (75, 58, 0), (65, 57, 5), + (56, 56, 11), (49, 53, 18), (42, 51, 26), (28, 54, 40), + (14, 58, 54), (2, 70, 82), (3, 78, 94), (5, 86, 107), + (5, 89, 113), (5, 93, 120), (5, 102, 133), (5, 110, 145), + (1, 126, 170), (0, 132, 183), (0, 138, 196), (0, 146, 210), + (0, 155, 224), (0, 160, 231), (0, 165, 238), (0, 179, 243), + (0, 194, 246), (0, 218, 236), (0, 224, 227), (0, 231, 219), + (0, 232, 214), (0, 233, 210), (0, 232, 198), (7, 228, 184), + (15, 212, 156), (18, 200, 145), (21, 189, 134), (21, 183, 130), + (21, 177, 126), (25, 169, 124), (30, 158, 117), (33, 148, 109), + (33, 138, 100), (33, 127, 82), (34, 127, 67), (36, 127, 53), + (38, 127, 46), (40, 127, 39), (39, 128, 25), (40, 121, 16), + (32, 103, 12), (26, 98, 16), (21, 93, 21), (18, 91, 21), + (16, 89, 21), (9, 82, 21), (2, 71, 22), (0, 58, 29), + (0, 53, 29), (0, 58, 29), (0, 64, 25), (0, 71, 22), + (0, 81, 19), (0, 92, 12), (0, 100, 7), (0, 109, 7), + (0, 131, 0), (0, 141, 0), (0, 152, 0), (0, 153, 0), + (0, 155, 0), (2, 152, 0), (5, 152, 0), (7, 152, 0), + (8, 155, 0), (8, 148, 0), (8, 144, 0), (8, 141, 0), + (7, 133, 0), (5, 124, 0), (5, 116, 0), (4, 114, 0), + (5, 116, 0), (4, 114, 0), (4, 112, 0), (3, 110, 0), + (2, 109, 0), (1, 116, 0), (0, 116, 0), (0, 119, 0), + (0, 120, 0), (0, 119, 9), (0, 117, 14), (0, 116, 19), + (0, 112, 26), (0, 103, 35), (0, 96, 42), (0, 88, 49), + (0, 68, 71), (0, 66, 76), (0, 65, 81), (0, 64, 88), + (0, 65, 96), (0, 65, 100), (0, 70, 105), (8, 70, 107), + (21, 72, 110), (47, 84, 106), (53, 86, 102), (60, 89, 99), + (72, 98, 91), (79, 103, 84), (91, 105, 81), (96, 107, 82), + (109, 106, 79), (114, 105, 79), (120, 105, 79), (131, 103, 84), + (142, 99, 85), (156, 102, 84), (170, 106, 88), (186, 112, 86), + (200, 117, 85), (214, 130, 81), (224, 141, 78), (232, 154, 70), + (235, 168, 61), (232, 182, 54), (225, 194, 44), (215, 211, 40), + (190, 226, 57), (183, 228, 61), (177, 231, 65), (165, 235, 82), + (152, 235, 96), (140, 232, 110), (127, 231, 121), (117, 228, 135), + (113, 224, 149), (106, 218, 161), (99, 212, 172), (100, 205, 176), + (96, 200, 173), (89, 196, 170), (81, 183, 169), (72, 169, 166), + (70, 159, 166), (65, 148, 162), (63, 140, 159), (58, 133, 155), + (54, 126, 154), (57, 123, 151), (61, 119, 148), (61, 117, 142), + (71, 113, 135), (82, 109, 133), (93, 105, 131), (103, 98, 128), + (107, 89, 130), (116, 79, 130), (124, 70, 130), (135, 60, 130), + (144, 50, 128), (149, 42, 127), (148, 39, 123), (148, 39, 119), + (141, 44, 116), (135, 51, 109), (127, 61, 110), (123, 74, 117), + (117, 82, 124), (106, 89, 137), (95, 95, 149), (84, 96, 162), + (75, 96, 172), (68, 93, 182), (64, 91, 193), (53, 86, 203), + (42, 85, 214), (30, 86, 226), (21, 89, 232), (8, 92, 235), + (0, 100, 238), (0, 109, 240), (0, 117, 245), (0, 126, 252), + (0, 135, 255), (0, 144, 255), (0, 149, 255), (0, 154, 255), + (0, 156, 255), (0, 156, 255), (0, 155, 255), (0, 149, 255), + (0, 144, 252), (0, 138, 242), (0, 131, 233), (0, 126, 225), + (0, 121, 219), (0, 120, 218), (0, 120, 218), (0, 114, 218) + ), + +// 686 040412-000 +((171, 102, 133), (150, 79, 120), (137, 65, 111), (125, 51, 103), + (128, 47, 103), (132, 44, 104), (132, 43, 104), (133, 43, 105), + (132, 51, 106), (135, 59, 109), (138, 67, 112), (142, 75, 115), + (147, 84, 119), (151, 94, 123), (156, 105, 128), (159, 110, 130), + (163, 115, 133), (180, 127, 143), (186, 129, 146), (193, 132, 149), + (197, 134, 151), (202, 136, 153), (204, 136, 154), (206, 137, 155), + (212, 140, 158), (216, 140, 160), (220, 141, 163), (223, 141, 165), + (227, 142, 167), (228, 142, 167), (229, 142, 167), (230, 141, 168), + (232, 141, 169), (235, 141, 171), (235, 142, 171), (236, 143, 171), + (236, 144, 171), (237, 146, 171), (238, 146, 171), (239, 147, 172), + (241, 150, 173), (241, 150, 173), (241, 151, 173), (239, 150, 172), + (237, 150, 171), (234, 149, 170), (232, 148, 169), (225, 145, 165), + (216, 142, 161), (193, 132, 149), (178, 126, 141), (163, 120, 134), + (147, 113, 126), (131, 106, 118), (124, 103, 114), (117, 100, 111), + (92, 89, 99), (83, 85, 94), (74, 81, 90), (69, 79, 87), + (65, 77, 85), (64, 76, 84), (63, 75, 84), (62, 74, 83), + (62, 74, 83), (64, 74, 84), (66, 74, 85), (69, 75, 86), + (70, 75, 86), (71, 75, 87), (72, 76, 88), (74, 78, 89), + (78, 80, 91), (80, 80, 92), (82, 81, 93), (84, 81, 94), + (86, 82, 95), (87, 82, 95), (88, 82, 95), (90, 81, 96), + (93, 79, 97), (100, 73, 98), (103, 70, 99), (106, 68, 100), + (107, 67, 100), (108, 66, 100), (110, 65, 100), (111, 64, 100), + (110, 65, 100), (107, 66, 99), (105, 68, 99), (103, 69, 98), + (101, 70, 98), (98, 71, 97), (94, 73, 96), (92, 77, 96), + (92, 80, 97), (98, 88, 101), (105, 91, 104), (112, 95, 108), + (116, 97, 110), (121, 100, 113), (130, 105, 117), (139, 109, 122), + (152, 115, 128), (153, 115, 129), (154, 116, 130), (152, 115, 129), + (151, 115, 128), (146, 112, 126), (138, 109, 122), (131, 106, 118), + (124, 103, 114), (115, 100, 110), (114, 99, 110), (114, 99, 110), + (116, 100, 111), (120, 102, 112), (126, 104, 116), (134, 108, 120), + (153, 115, 129), (160, 118, 132), (167, 122, 136), (169, 122, 137), + (172, 123, 138), (173, 124, 139), (173, 124, 139), (172, 123, 138), + (168, 122, 137), (158, 117, 132), (153, 115, 129), (149, 114, 127), + (140, 110, 123), (131, 106, 118), (123, 103, 114), (116, 100, 111), + (100, 94, 103), (92, 90, 99), (85, 87, 95), (83, 86, 94), + (81, 85, 93), (78, 83, 91), (77, 81, 91), (76, 80, 90), + (75, 79, 90), (78, 78, 90), (79, 77, 90), (81, 77, 91), + (84, 77, 93), (87, 77, 94), (90, 76, 95), (93, 75, 96), + (99, 72, 98), (101, 71, 98), (103, 70, 99), (108, 66, 100), + (112, 62, 101), (116, 59, 102), (120, 55, 102), (125, 51, 103), + (128, 48, 104), (132, 44, 104), (132, 44, 104), (132, 44, 104), + (133, 43, 104), (133, 43, 104), (132, 44, 104), (130, 46, 104), + (126, 49, 103), (125, 50, 103), (124, 52, 103), (121, 55, 102), + (119, 61, 103), (121, 68, 106), (127, 76, 109), (135, 84, 115), + (143, 91, 120), (152, 101, 126), (163, 112, 132), (176, 121, 140), + (190, 129, 148), (203, 134, 154), (214, 138, 160), (222, 141, 164), + (232, 141, 169), (232, 140, 169), (233, 140, 170), (234, 139, 170), + (233, 137, 170), (232, 136, 169), (231, 135, 169), (231, 135, 169), + (231, 135, 169), (232, 136, 169), (233, 138, 170), (235, 140, 170), + (236, 142, 171), (237, 144, 172), (239, 146, 172), (240, 148, 173), + (241, 149, 173), (241, 150, 173), (242, 150, 173), (241, 150, 173), + (241, 149, 173), (241, 149, 173), (241, 149, 173), (241, 149, 173), + (240, 148, 173), (240, 148, 172), (238, 148, 172), (236, 148, 171), + (234, 147, 169), (229, 146, 167), (224, 144, 164), (216, 141, 161), + (207, 138, 156), (196, 133, 150), (184, 128, 144), (170, 122, 137), + (155, 116, 130), (140, 110, 123), (125, 104, 115), (112, 98, 109), + (99, 93, 102), (87, 88, 96), (77, 84, 91), (68, 80, 87), + (62, 78, 84), (58, 76, 82), (54, 74, 80), (52, 73, 79), + (50, 73, 78), (50, 72, 77), (49, 72, 77), (49, 72, 77), + (49, 72, 77), (50, 72, 78), (51, 72, 78), (53, 73, 79), + (55, 74, 80), (58, 75, 82), (62, 77, 84), (68, 79, 86), + (74, 82, 90), (84, 86, 94), (94, 91, 100), (108, 97, 107), + (124, 103, 114), (140, 110, 123), (159, 118, 132), (174, 124, 139), + (171, 121, 138), (168, 116, 135), (163, 109, 132), (161, 102, 129) + ), + +// 687 040412-001 +((100, 88, 103), (127, 94, 112), (138, 92, 116), (150, 91, 120), + (156, 90, 121), (162, 89, 123), (162, 86, 120), (163, 83, 118), + (154, 62, 107), (145, 52, 101), (136, 43, 95), (127, 38, 90), + (118, 34, 85), (111, 33, 82), (104, 32, 80), (101, 32, 79), + (99, 33, 78), (87, 38, 76), (81, 40, 74), (75, 43, 73), + (70, 44, 71), (66, 45, 70), (64, 45, 69), (62, 46, 68), + (59, 45, 66), (59, 45, 66), (59, 45, 66), (59, 45, 66), + (60, 45, 66), (60, 45, 66), (60, 45, 66), (58, 46, 65), + (56, 47, 65), (51, 49, 63), (49, 51, 63), (47, 54, 64), + (46, 56, 65), (46, 59, 67), (47, 59, 68), (48, 59, 69), + (55, 59, 72), (57, 58, 72), (59, 58, 73), (59, 56, 72), + (59, 54, 71), (59, 53, 71), (59, 53, 71), (58, 51, 69), + (57, 50, 67), (56, 47, 65), (57, 47, 66), (59, 48, 68), + (62, 48, 70), (66, 49, 72), (66, 48, 71), (67, 47, 71), + (67, 47, 71), (65, 48, 71), (63, 50, 71), (58, 50, 68), + (53, 51, 66), (50, 51, 64), (48, 52, 63), (44, 52, 61), + (42, 55, 62), (44, 61, 64), (45, 62, 65), (46, 63, 66), + (47, 63, 67), (49, 64, 68), (53, 64, 71), (57, 64, 74), + (66, 62, 77), (70, 62, 79), (74, 62, 82), (78, 62, 84), + (83, 63, 86), (84, 60, 85), (85, 58, 85), (88, 55, 85), + (91, 53, 86), (96, 53, 88), (95, 49, 86), (95, 46, 84), + (95, 45, 84), (95, 45, 84), (95, 46, 84), (96, 48, 86), + (105, 48, 88), (116, 54, 94), (127, 60, 100), (133, 65, 104), + (140, 71, 109), (150, 81, 116), (161, 86, 122), (174, 91, 128), + (188, 98, 134), (209, 116, 148), (212, 121, 151), (215, 127, 155), + (214, 128, 154), (213, 130, 154), (209, 130, 153), (206, 129, 155), + (203, 131, 163), (201, 131, 164), (199, 131, 166), (198, 129, 165), + (197, 127, 164), (196, 124, 162), (194, 117, 160), (191, 110, 156), + (186, 102, 151), (173, 83, 131), (168, 77, 125), (164, 72, 120), + (153, 61, 108), (139, 53, 100), (126, 45, 92), (115, 40, 86), + (97, 36, 77), (90, 36, 75), (84, 36, 73), (83, 36, 73), + (82, 37, 73), (83, 39, 75), (91, 41, 78), (100, 46, 83), + (112, 52, 89), (141, 69, 107), (148, 73, 111), (155, 78, 116), + (169, 89, 124), (178, 97, 129), (183, 104, 137), (184, 108, 142), + (173, 112, 142), (161, 108, 135), (150, 104, 129), (143, 98, 125), + (136, 93, 121), (125, 84, 115), (112, 75, 107), (100, 66, 97), + (92, 61, 90), (83, 48, 79), (83, 45, 78), (83, 43, 77), + (83, 38, 75), (85, 36, 75), (88, 34, 75), (92, 32, 76), + (101, 29, 79), (103, 28, 79), (105, 27, 80), (108, 26, 81), + (111, 25, 82), (111, 25, 82), (109, 26, 81), (107, 27, 80), + (102, 29, 79), (91, 33, 76), (88, 35, 76), (86, 38, 76), + (80, 42, 75), (74, 46, 75), (70, 50, 75), (68, 50, 74), + (69, 52, 76), (70, 52, 76), (72, 52, 77), (76, 51, 79), + (81, 48, 80), (86, 44, 80), (91, 41, 81), (94, 39, 81), + (96, 38, 81), (95, 38, 81), (93, 40, 81), (89, 44, 80), + (86, 48, 80), (85, 54, 81), (85, 57, 82), (86, 57, 84), + (95, 55, 84), (97, 54, 85), (100, 54, 86), (107, 53, 89), + (111, 48, 90), (117, 41, 91), (120, 35, 88), (123, 29, 86), + (127, 27, 86), (126, 26, 86), (125, 26, 86), (125, 28, 85), + (128, 31, 86), (134, 37, 90), (141, 45, 95), (147, 56, 101), + (151, 66, 107), (151, 75, 110), (149, 81, 112), (147, 85, 112), + (142, 90, 113), (135, 91, 111), (126, 89, 107), (115, 85, 102), + (106, 76, 96), (101, 69, 91), (96, 59, 86), (93, 51, 83), + (92, 44, 81), (91, 38, 79), (92, 36, 78), (94, 34, 78), + (96, 32, 77), (99, 29, 78), (101, 29, 78), (105, 30, 80), + (110, 34, 83), (119, 42, 89), (132, 52, 98), (147, 63, 109), + (163, 75, 119), (178, 87, 128), (190, 98, 140), (201, 110, 153), + (210, 120, 166), (217, 129, 176), (222, 136, 180), (221, 139, 184), + (217, 138, 185), (211, 135, 186), (201, 131, 185), (198, 126, 177), + (194, 119, 169), (183, 114, 161), (170, 108, 151), (154, 106, 145), + (147, 105, 140), (148, 101, 137), (151, 101, 138), (148, 100, 136), + (138, 99, 132), (129, 100, 130), (123, 98, 127), (120, 98, 125), + (116, 96, 123), (108, 93, 117), (100, 89, 110), (93, 85, 105), + (83, 80, 97), (78, 76, 92), (78, 76, 93), (85, 79, 94) + ), + +// 688 040412-002 +((42, 85, 77), (18, 49, 50), (17, 49, 50), (16, 50, 50), + (15, 49, 49), (14, 49, 49), (13, 48, 48), (12, 47, 48), + (11, 46, 46), (10, 45, 45), (10, 44, 45), (10, 44, 45), + (10, 44, 45), (11, 44, 45), (13, 44, 46), (14, 44, 46), + (15, 44, 46), (17, 39, 42), (17, 35, 38), (17, 31, 34), + (16, 29, 31), (15, 27, 29), (15, 27, 29), (15, 28, 30), + (21, 40, 41), (29, 50, 49), (37, 61, 57), (43, 74, 67), + (50, 87, 77), (54, 93, 81), (59, 99, 86), (64, 110, 97), + (68, 120, 112), (79, 145, 143), (85, 157, 162), (91, 170, 181), + (97, 182, 193), (103, 194, 206), (104, 198, 210), (106, 202, 214), + (103, 195, 207), (101, 192, 204), (100, 189, 201), (100, 190, 202), + (101, 191, 203), (101, 190, 202), (101, 189, 201), (99, 185, 197), + (96, 179, 191), (85, 155, 167), (77, 145, 154), (70, 135, 141), + (65, 128, 132), (61, 122, 124), (58, 118, 118), (55, 114, 113), + (55, 100, 94), (56, 98, 90), (57, 96, 86), (59, 101, 91), + (61, 107, 97), (61, 110, 102), (61, 114, 107), (64, 120, 110), + (64, 119, 109), (58, 106, 97), (51, 92, 84), (45, 78, 71), + (41, 71, 66), (38, 65, 61), (30, 54, 52), (23, 45, 45), + (19, 36, 38), (19, 36, 38), (20, 37, 39), (21, 39, 42), + (23, 42, 45), (24, 44, 47), (25, 46, 49), (28, 53, 53), + (34, 60, 58), (42, 72, 66), (47, 77, 69), (53, 83, 72), + (53, 84, 73), (54, 85, 74), (53, 83, 73), (50, 80, 71), + (40, 72, 68), (36, 68, 66), (33, 65, 65), (32, 64, 65), + (31, 64, 66), (30, 66, 68), (30, 70, 72), (33, 76, 77), + (34, 81, 82), (37, 90, 90), (37, 90, 90), (38, 90, 90), + (37, 89, 89), (36, 88, 88), (34, 83, 84), (30, 78, 79), + (25, 68, 69), (24, 67, 68), (24, 67, 68), (25, 69, 70), + (27, 72, 72), (31, 77, 78), (37, 84, 84), (41, 92, 92), + (45, 98, 98), (50, 104, 105), (48, 104, 105), (47, 104, 105), + (49, 107, 108), (50, 110, 110), (51, 112, 112), (54, 117, 118), + (69, 136, 142), (75, 144, 152), (81, 153, 162), (83, 155, 165), + (86, 158, 169), (86, 157, 169), (81, 147, 158), (75, 135, 145), + (66, 119, 128), (48, 86, 91), (44, 80, 84), (40, 74, 77), + (34, 63, 66), (30, 57, 58), (26, 53, 54), (23, 51, 53), + (22, 51, 52), (22, 53, 52), (23, 55, 53), (23, 55, 54), + (24, 56, 55), (26, 57, 58), (30, 62, 61), (33, 68, 67), + (37, 74, 73), (45, 90, 87), (48, 94, 89), (51, 98, 92), + (53, 102, 97), (54, 105, 99), (55, 106, 97), (54, 103, 95), + (50, 96, 94), (48, 95, 93), (47, 94, 92), (47, 93, 94), + (46, 95, 98), (46, 99, 100), (46, 101, 102), (44, 101, 101), + (44, 101, 101), (44, 95, 94), (43, 92, 91), (42, 90, 89), + (41, 87, 87), (41, 83, 82), (39, 78, 78), (37, 75, 75), + (33, 67, 68), (32, 65, 67), (31, 64, 66), (30, 60, 63), + (29, 58, 62), (28, 59, 62), (32, 61, 65), (35, 64, 70), + (35, 69, 72), (37, 73, 74), (41, 74, 75), (39, 73, 72), + (35, 69, 70), (34, 65, 64), (31, 61, 61), (27, 58, 61), + (26, 63, 65), (26, 65, 67), (26, 68, 69), (28, 74, 75), + (33, 83, 84), (38, 92, 92), (44, 100, 100), (48, 107, 108), + (52, 114, 114), (57, 117, 119), (58, 117, 120), (55, 115, 116), + (52, 106, 109), (47, 96, 99), (41, 85, 85), (33, 71, 73), + (26, 59, 63), (26, 54, 58), (25, 54, 57), (28, 57, 63), + (36, 68, 76), (46, 86, 92), (57, 104, 112), (70, 126, 135), + (81, 147, 158), (91, 170, 181), (101, 190, 202), (105, 199, 212), + (105, 198, 211), (102, 192, 204), (95, 178, 189), (85, 156, 167), + (73, 132, 143), (63, 113, 122), (55, 99, 106), (48, 89, 94), + (45, 84, 87), (43, 84, 86), (41, 87, 87), (42, 91, 90), + (46, 97, 97), (48, 102, 103), (49, 105, 106), (53, 109, 107), + (56, 112, 107), (58, 111, 106), (61, 112, 103), (63, 115, 104), + (64, 117, 105), (67, 121, 107), (68, 125, 111), (66, 127, 116), + (64, 128, 121), (66, 131, 124), (64, 131, 127), (62, 129, 130), + (62, 129, 130), (61, 129, 129), (60, 126, 126), (58, 123, 123), + (59, 120, 117), (57, 116, 111), (54, 111, 109), (52, 106, 103), + (51, 101, 96), (48, 95, 93), (49, 92, 89), (52, 92, 87), + (53, 97, 90), (59, 104, 93), (52, 89, 81), (40, 76, 72) + ), + +// 689 040412-005 +((48, 130, 119), (77, 132, 126), (88, 143, 127), (99, 154, 128), + (111, 176, 108), (123, 198, 88), (128, 204, 81), (134, 211, 75), + (146, 207, 66), (148, 199, 66), (150, 192, 67), (146, 184, 66), + (143, 176, 66), (128, 159, 70), (113, 143, 75), (105, 138, 77), + (98, 134, 79), (77, 105, 98), (70, 93, 114), (64, 81, 130), + (49, 68, 145), (34, 55, 160), (31, 52, 165), (28, 49, 170), + (44, 42, 161), (56, 44, 145), (68, 46, 129), (61, 43, 131), + (55, 41, 133), (55, 39, 137), (56, 37, 141), (61, 32, 156), + (72, 21, 155), (106, 20, 113), (103, 19, 101), (101, 18, 90), + (84, 17, 112), (68, 17, 134), (69, 17, 142), (71, 17, 151), + (70, 31, 161), (71, 38, 162), (73, 45, 163), (57, 49, 180), + (42, 54, 198), (34, 55, 208), (26, 57, 219), (12, 60, 232), + (7, 62, 235), (5, 67, 237), (4, 66, 237), (3, 66, 237), + (3, 67, 237), (3, 68, 237), (4, 69, 237), (5, 70, 237), + (5, 76, 236), (5, 79, 238), (6, 83, 240), (21, 91, 238), + (37, 99, 236), (46, 104, 233), (55, 109, 230), (71, 118, 222), + (82, 126, 212), (93, 127, 198), (94, 125, 191), (96, 124, 184), + (96, 123, 180), (97, 123, 176), (93, 124, 166), (84, 122, 160), + (59, 106, 163), (45, 93, 169), (31, 81, 175), (28, 71, 179), + (25, 61, 184), (33, 61, 183), (41, 62, 182), (60, 68, 180), + (79, 74, 179), (106, 89, 181), (120, 86, 185), (135, 84, 190), + (141, 85, 190), (148, 86, 190), (151, 84, 187), (146, 82, 183), + (118, 81, 172), (104, 68, 173), (91, 55, 174), (82, 48, 174), + (74, 41, 174), (55, 28, 176), (37, 23, 173), (21, 23, 169), + (5, 23, 163), (0, 28, 151), (0, 27, 149), (0, 27, 147), + (0, 26, 147), (0, 25, 147), (0, 25, 148), (2, 26, 149), + (26, 30, 154), (42, 29, 157), (59, 28, 160), (68, 27, 161), + (77, 27, 163), (90, 26, 163), (99, 28, 169), (115, 31, 173), + (134, 37, 177), (166, 65, 174), (170, 75, 167), (175, 85, 161), + (174, 106, 143), (171, 122, 126), (170, 131, 112), (170, 129, 97), + (172, 115, 97), (169, 113, 96), (167, 112, 96), (160, 114, 98), + (153, 116, 100), (136, 105, 98), (121, 84, 104), (108, 61, 115), + (92, 42, 128), (88, 26, 140), (88, 27, 137), (88, 29, 135), + (85, 29, 122), (83, 28, 106), (83, 23, 92), (82, 22, 94), + (116, 29, 93), (135, 42, 90), (155, 56, 88), (162, 62, 84), + (170, 68, 81), (169, 85, 81), (168, 103, 81), (166, 115, 84), + (167, 135, 84), (171, 171, 78), (170, 180, 72), (169, 190, 67), + (165, 208, 51), (157, 216, 36), (148, 224, 23), (141, 229, 9), + (124, 222, 15), (117, 216, 24), (111, 211, 34), (98, 199, 53), + (94, 193, 73), (93, 192, 89), (93, 191, 96), (98, 197, 105), + (99, 198, 114), (95, 192, 119), (97, 194, 120), (100, 196, 121), + (111, 199, 115), (124, 207, 117), (137, 212, 120), (140, 213, 120), + (127, 183, 124), (120, 178, 123), (114, 174, 122), (100, 164, 135), + (84, 154, 150), (72, 148, 165), (77, 148, 174), (76, 140, 182), + (78, 142, 172), (78, 146, 161), (76, 154, 144), (63, 159, 128), + (64, 174, 119), (60, 174, 126), (62, 176, 130), (63, 176, 137), + (60, 171, 142), (57, 170, 143), (54, 170, 145), (39, 159, 163), + (26, 145, 185), (14, 132, 209), (4, 119, 233), (0, 103, 242), + (0, 95, 243), (0, 89, 241), (1, 81, 237), (2, 73, 233), + (7, 68, 228), (20, 65, 223), (33, 68, 212), (46, 80, 188), + (61, 92, 164), (74, 105, 141), (79, 118, 119), (93, 129, 102), + (104, 140, 95), (111, 158, 74), (120, 175, 53), (124, 191, 36), + (112, 193, 32), (101, 187, 33), (96, 174, 53), (98, 158, 73), + (103, 143, 89), (115, 144, 90), (122, 135, 101), (119, 136, 96), + (117, 138, 97), (121, 139, 98), (129, 136, 101), (143, 152, 93), + (157, 155, 102), (162, 163, 99), (155, 167, 100), (137, 170, 99), + (123, 176, 92), (109, 189, 75), (94, 192, 72), (85, 198, 68), + (85, 194, 71), (74, 184, 78), (71, 178, 81), (69, 179, 70), + (61, 183, 54), (53, 193, 41), (50, 193, 41), (46, 186, 50), + (44, 178, 69), (43, 171, 90), (42, 165, 104), (39, 166, 117), + (30, 158, 139), (19, 148, 158), (10, 140, 178), (3, 131, 196), + (0, 122, 204), (0, 119, 201), (0, 115, 196), (0, 110, 190), + (0, 104, 184), (0, 97, 178), (0, 92, 173), (0, 83, 167), + (0, 79, 159), (6, 88, 148), (19, 100, 131), (34, 114, 118) + ), + +// 690 040412-006 +((42, 112, 82), (71, 97, 64), (77, 84, 59), (83, 72, 55), + (92, 65, 50), (101, 58, 46), (106, 54, 44), (112, 51, 43), + (129, 66, 44), (136, 69, 39), (144, 72, 35), (134, 66, 39), + (125, 61, 43), (114, 56, 48), (104, 52, 53), (97, 51, 58), + (91, 50, 63), (77, 46, 73), (76, 49, 69), (76, 52, 65), + (74, 52, 63), (72, 52, 62), (72, 50, 62), (73, 48, 62), + (74, 35, 74), (81, 26, 80), (89, 18, 86), (104, 13, 83), + (120, 9, 81), (128, 6, 79), (136, 4, 78), (152, 1, 72), + (166, 0, 67), (191, 0, 65), (192, 0, 70), (194, 0, 76), + (188, 3, 79), (183, 7, 82), (177, 11, 82), (171, 15, 83), + (145, 31, 83), (133, 40, 85), (121, 49, 88), (109, 54, 95), + (98, 60, 102), (90, 63, 106), (82, 66, 111), (67, 74, 119), + (50, 83, 126), (25, 101, 121), (20, 112, 113), (16, 123, 105), + (23, 127, 96), (31, 132, 88), (34, 133, 83), (38, 135, 79), + (47, 138, 67), (47, 138, 60), (48, 139, 54), (48, 139, 54), + (48, 140, 54), (48, 140, 55), (48, 141, 56), (48, 142, 59), + (49, 144, 64), (45, 144, 82), (38, 141, 92), (31, 138, 103), + (27, 137, 108), (23, 136, 113), (16, 134, 121), (9, 130, 129), + (11, 130, 129), (21, 130, 121), (31, 130, 113), (40, 123, 104), + (50, 116, 96), (51, 112, 92), (53, 108, 88), (48, 98, 87), + (46, 93, 79), (46, 95, 59), (55, 101, 46), (64, 107, 34), + (70, 108, 29), (77, 109, 24), (87, 111, 15), (91, 109, 15), + (86, 103, 19), (80, 108, 19), (74, 114, 19), (72, 120, 18), + (71, 126, 17), (69, 133, 21), (69, 141, 26), (69, 146, 30), + (69, 149, 34), (64, 147, 42), (65, 148, 38), (67, 149, 35), + (67, 149, 34), (67, 149, 33), (66, 148, 33), (64, 149, 33), + (55, 146, 42), (48, 137, 45), (41, 129, 48), (41, 125, 46), + (41, 122, 44), (43, 114, 37), (51, 104, 30), (64, 100, 21), + (78, 97, 13), (96, 99, 10), (98, 98, 10), (101, 97, 10), + (106, 94, 11), (103, 90, 12), (106, 79, 14), (116, 67, 18), + (137, 48, 32), (148, 48, 38), (160, 49, 44), (159, 52, 46), + (159, 56, 49), (148, 66, 56), (134, 75, 61), (125, 78, 66), + (124, 78, 71), (125, 61, 85), (132, 55, 87), (139, 50, 89), + (141, 42, 88), (140, 40, 88), (135, 47, 84), (124, 57, 77), + (121, 84, 59), (127, 87, 54), (133, 90, 49), (139, 87, 45), + (145, 85, 41), (147, 78, 37), (146, 72, 32), (136, 69, 30), + (124, 69, 28), (108, 94, 18), (104, 100, 18), (100, 106, 19), + (104, 116, 14), (97, 120, 14), (85, 120, 21), (72, 117, 31), + (41, 109, 55), (40, 107, 59), (40, 106, 64), (42, 99, 72), + (56, 95, 77), (72, 94, 73), (84, 89, 75), (96, 84, 77), + (105, 73, 85), (113, 59, 93), (117, 53, 93), (122, 47, 94), + (133, 36, 94), (149, 28, 86), (163, 20, 78), (177, 13, 68), + (191, 7, 55), (191, 10, 51), (192, 13, 48), (191, 19, 40), + (190, 28, 31), (191, 38, 23), (190, 48, 15), (189, 55, 7), + (185, 65, 3), (180, 75, 1), (175, 85, 0), (167, 94, 0), + (160, 105, 0), (153, 116, 0), (146, 127, 0), (141, 135, 0), + (133, 150, 0), (131, 152, 0), (130, 154, 0), (126, 157, 0), + (122, 158, 0), (118, 159, 0), (115, 160, 0), (113, 160, 0), + (112, 161, 0), (113, 160, 0), (116, 155, 0), (117, 144, 4), + (120, 132, 11), (125, 121, 20), (130, 108, 30), (134, 96, 38), + (137, 85, 46), (137, 77, 51), (135, 72, 52), (128, 61, 54), + (119, 53, 58), (110, 47, 64), (102, 42, 73), (94, 39, 83), + (87, 38, 97), (81, 39, 109), (72, 49, 117), (64, 55, 123), + (52, 63, 126), (39, 71, 127), (26, 78, 128), (15, 85, 128), + (15, 89, 133), (20, 89, 138), (26, 90, 144), (36, 87, 149), + (47, 83, 152), (56, 78, 155), (56, 77, 154), (48, 77, 149), + (47, 76, 144), (47, 68, 138), (49, 59, 130), (58, 50, 122), + (73, 40, 109), (96, 30, 101), (109, 26, 91), (110, 28, 84), + (101, 35, 79), (89, 42, 78), (73, 50, 76), (57, 58, 80), + (48, 62, 78), (50, 62, 78), (52, 60, 73), (62, 62, 71), + (62, 65, 69), (59, 69, 71), (50, 76, 76), (36, 85, 86), + (22, 92, 97), (9, 98, 109), (0, 102, 117), (0, 105, 122), + (0, 107, 123), (3, 97, 118), (3, 91, 114), (3, 87, 110), + (7, 91, 102), (14, 96, 96), (23, 101, 90), (34, 103, 84) + ), + +// 691 040412-007 +((108, 129, 87), (98, 136, 98), (113, 138, 101), (128, 140, 105), + (134, 123, 114), (140, 106, 123), (122, 105, 130), (105, 105, 138), + (105, 105, 140), (122, 103, 133), (139, 101, 126), (141, 95, 117), + (144, 90, 108), (146, 81, 99), (148, 73, 91), (148, 68, 87), + (148, 64, 84), (148, 46, 70), (148, 40, 64), (148, 34, 58), + (148, 31, 58), (148, 28, 58), (148, 27, 58), (149, 27, 58), + (147, 27, 59), (143, 27, 59), (139, 27, 59), (132, 27, 59), + (126, 28, 59), (123, 27, 59), (120, 27, 60), (115, 26, 62), + (112, 25, 63), (108, 22, 67), (107, 20, 69), (107, 18, 71), + (107, 18, 71), (107, 18, 71), (107, 19, 70), (107, 21, 70), + (109, 32, 76), (109, 39, 82), (110, 47, 88), (110, 57, 97), + (111, 68, 106), (108, 72, 111), (105, 77, 117), (90, 86, 123), + (86, 114, 128), (87, 145, 138), (87, 155, 141), (87, 165, 144), + (84, 175, 147), (82, 185, 151), (80, 189, 153), (79, 193, 155), + (76, 202, 154), (76, 202, 149), (76, 203, 144), (77, 197, 137), + (79, 192, 131), (79, 187, 127), (79, 183, 123), (77, 176, 113), + (75, 168, 104), (73, 151, 88), (72, 143, 78), (71, 135, 68), + (73, 132, 65), (76, 129, 63), (82, 120, 58), (84, 111, 53), + (81, 94, 44), (78, 86, 43), (75, 79, 42), (71, 73, 41), + (67, 67, 40), (64, 66, 41), (62, 65, 42), (64, 57, 43), + (64, 44, 44), (64, 41, 55), (64, 40, 56), (65, 39, 58), + (65, 39, 58), (65, 39, 58), (65, 39, 58), (65, 39, 58), + (67, 40, 52), (70, 39, 53), (74, 39, 54), (76, 38, 54), + (78, 37, 55), (83, 36, 56), (88, 36, 56), (92, 41, 56), + (97, 45, 54), (104, 65, 52), (110, 74, 53), (116, 84, 54), + (119, 87, 55), (122, 90, 57), (129, 94, 59), (135, 94, 64), + (143, 102, 75), (144, 109, 78), (146, 116, 82), (147, 120, 82), + (148, 125, 83), (147, 128, 81), (144, 136, 80), (140, 140, 77), + (134, 138, 72), (119, 131, 68), (116, 129, 68), (113, 127, 69), + (104, 124, 65), (100, 122, 65), (102, 120, 64), (104, 118, 64), + (108, 117, 58), (110, 115, 56), (113, 113, 54), (113, 111, 54), + (114, 109, 54), (113, 107, 56), (115, 104, 57), (118, 99, 59), + (123, 90, 60), (132, 80, 63), (133, 77, 63), (134, 75, 63), + (137, 69, 65), (138, 64, 68), (136, 63, 72), (134, 60, 75), + (125, 49, 78), (120, 44, 77), (116, 40, 76), (113, 38, 74), + (110, 37, 73), (104, 36, 68), (98, 34, 65), (92, 33, 62), + (88, 32, 61), (79, 31, 62), (78, 31, 62), (78, 31, 63), + (77, 31, 62), (78, 31, 63), (79, 30, 63), (81, 31, 62), + (89, 32, 61), (91, 34, 61), (93, 36, 61), (97, 40, 60), + (104, 44, 60), (112, 47, 60), (120, 49, 59), (129, 50, 56), + (137, 51, 54), (155, 53, 51), (158, 55, 50), (162, 58, 50), + (165, 66, 51), (170, 74, 52), (173, 85, 55), (174, 97, 59), + (174, 124, 69), (173, 129, 71), (173, 135, 73), (173, 141, 76), + (175, 143, 77), (176, 141, 75), (177, 139, 74), (178, 137, 73), + (177, 131, 74), (176, 126, 74), (173, 121, 75), (167, 120, 77), + (159, 119, 78), (151, 118, 78), (144, 118, 77), (137, 115, 73), + (136, 107, 64), (138, 105, 63), (140, 103, 62), (143, 100, 60), + (144, 100, 62), (143, 104, 66), (139, 110, 72), (134, 123, 77), + (120, 133, 82), (103, 135, 83), (96, 137, 83), (100, 137, 83), + (113, 136, 85), (129, 135, 87), (140, 124, 89), (147, 112, 90), + (153, 107, 91), (156, 100, 93), (153, 94, 96), (149, 89, 100), + (145, 81, 101), (142, 72, 99), (139, 63, 92), (136, 54, 84), + (132, 46, 77), (131, 41, 68), (130, 36, 62), (130, 37, 59), + (130, 39, 61), (128, 44, 64), (126, 50, 69), (124, 54, 75), + (123, 57, 77), (122, 60, 80), (123, 60, 79), (125, 59, 75), + (129, 58, 72), (136, 57, 69), (143, 58, 69), (150, 62, 69), + (157, 68, 68), (161, 74, 71), (165, 79, 74), (170, 84, 76), + (173, 85, 75), (176, 85, 70), (181, 80, 64), (185, 71, 59), + (190, 70, 52), (196, 70, 47), (196, 66, 45), (192, 67, 45), + (186, 71, 45), (179, 76, 45), (171, 82, 44), (163, 86, 42), + (154, 85, 41), (146, 83, 39), (144, 85, 36), (143, 78, 34), + (142, 72, 32), (141, 67, 32), (141, 60, 34), (140, 56, 35), + (133, 50, 38), (129, 49, 41), (123, 51, 47), (119, 63, 52), + (114, 76, 59), (112, 91, 66), (112, 109, 72), (104, 120, 79) + ), + +// 692 040412-008 +((58, 76, 155), (56, 80, 157), (54, 82, 159), (53, 85, 161), + (50, 89, 164), (47, 94, 167), (44, 97, 169), (42, 100, 171), + (35, 110, 180), (33, 113, 182), (31, 117, 185), (30, 118, 186), + (30, 120, 187), (29, 122, 188), (29, 125, 190), (29, 126, 190), + (29, 127, 190), (29, 125, 190), (30, 123, 188), (31, 121, 187), + (34, 117, 185), (38, 114, 183), (39, 111, 181), (41, 108, 179), + (46, 96, 167), (50, 88, 160), (54, 80, 153), (59, 70, 147), + (65, 61, 141), (69, 59, 139), (73, 57, 137), (80, 53, 133), + (86, 50, 131), (97, 46, 127), (100, 44, 124), (104, 43, 121), + (104, 42, 118), (105, 42, 116), (106, 41, 115), (108, 41, 114), + (109, 34, 112), (109, 32, 109), (110, 30, 106), (111, 28, 107), + (113, 27, 108), (114, 26, 107), (116, 26, 106), (116, 26, 106), + (117, 25, 106), (116, 25, 100), (118, 25, 96), (120, 25, 93), + (121, 25, 89), (123, 25, 86), (123, 25, 85), (124, 25, 84), + (127, 25, 82), (127, 25, 81), (127, 25, 80), (124, 25, 80), + (121, 25, 80), (120, 25, 80), (119, 25, 80), (114, 25, 82), + (110, 25, 84), (104, 25, 84), (104, 28, 90), (104, 31, 96), + (103, 34, 100), (102, 38, 105), (102, 45, 110), (100, 51, 117), + (92, 61, 129), (86, 65, 133), (80, 69, 137), (74, 73, 140), + (68, 77, 143), (66, 79, 144), (64, 82, 145), (58, 90, 149), + (53, 98, 156), (43, 116, 169), (40, 125, 176), (38, 135, 184), + (38, 139, 188), (38, 144, 192), (41, 152, 200), (41, 163, 207), + (41, 169, 212), (42, 166, 210), (43, 164, 208), (44, 160, 207), + (46, 157, 206), (46, 152, 200), (49, 144, 196), (47, 136, 192), + (49, 129, 190), (56, 117, 184), (58, 112, 181), (61, 108, 179), + (63, 104, 177), (66, 101, 176), (70, 94, 173), (74, 89, 171), + (84, 82, 168), (88, 79, 166), (92, 76, 164), (93, 74, 162), + (94, 73, 160), (98, 68, 157), (104, 64, 153), (106, 58, 151), + (109, 57, 147), (104, 51, 140), (102, 51, 139), (101, 51, 139), + (93, 53, 137), (86, 54, 137), (77, 57, 139), (68, 60, 139), + (56, 65, 139), (52, 67, 139), (49, 70, 139), (47, 69, 137), + (46, 68, 136), (45, 68, 136), (46, 69, 136), (46, 73, 137), + (43, 77, 140), (43, 84, 144), (42, 84, 143), (41, 84, 143), + (38, 82, 140), (35, 81, 139), (31, 80, 139), (29, 78, 136), + (25, 70, 133), (25, 70, 133), (25, 70, 133), (25, 71, 134), + (25, 72, 135), (25, 77, 137), (25, 80, 140), (25, 80, 140), + (26, 78, 140), (31, 76, 136), (32, 72, 132), (33, 68, 129), + (35, 56, 123), (38, 43, 114), (41, 35, 106), (45, 30, 100), + (49, 26, 97), (51, 26, 96), (53, 26, 96), (57, 26, 96), + (65, 27, 94), (73, 27, 93), (82, 26, 92), (92, 25, 89), + (97, 25, 85), (110, 25, 76), (113, 25, 74), (116, 25, 73), + (120, 25, 70), (123, 25, 70), (125, 25, 68), (125, 25, 70), + (127, 25, 72), (127, 25, 72), (128, 25, 72), (128, 25, 73), + (131, 25, 73), (132, 25, 73), (135, 25, 73), (136, 25, 73), + (137, 25, 74), (137, 25, 74), (137, 25, 76), (136, 25, 80), + (135, 25, 82), (132, 25, 88), (129, 25, 93), (125, 25, 101), + (114, 25, 120), (109, 27, 123), (104, 29, 127), (96, 34, 135), + (85, 42, 140), (73, 50, 147), (60, 58, 153), (54, 69, 160), + (47, 84, 165), (42, 93, 172), (35, 102, 177), (31, 112, 183), + (26, 120, 188), (25, 128, 194), (25, 135, 196), (25, 137, 199), + (25, 137, 199), (25, 136, 199), (25, 135, 196), (25, 129, 194), + (26, 125, 190), (27, 120, 184), (30, 116, 179), (31, 109, 173), + (31, 104, 168), (30, 96, 164), (30, 90, 159), (30, 84, 152), + (30, 74, 147), (29, 68, 140), (30, 58, 135), (33, 47, 129), + (37, 41, 123), (41, 35, 120), (43, 35, 117), (45, 35, 119), + (42, 39, 120), (38, 46, 123), (34, 53, 127), (31, 60, 129), + (27, 62, 132), (26, 64, 135), (25, 64, 136), (26, 60, 136), + (29, 58, 136), (33, 57, 136), (38, 54, 139), (41, 54, 140), + (43, 58, 143), (46, 65, 147), (46, 70, 152), (46, 78, 157), + (45, 86, 164), (42, 94, 169), (41, 98, 173), (39, 101, 175), + (39, 101, 175), (41, 98, 173), (42, 94, 171), (46, 90, 167), + (49, 85, 163), (53, 80, 159), (51, 84, 160), (50, 85, 161), + (50, 88, 161), (49, 88, 161), (50, 88, 161), (50, 88, 161), + (50, 85, 161), (51, 85, 161), (53, 85, 161), (54, 85, 160) + ), + +// 693 040412-010 +((105, 129, 103), (109, 131, 103), (110, 132, 103), (112, 133, 103), + (114, 134, 103), (116, 135, 103), (116, 135, 103), (117, 136, 103), + (120, 137, 102), (121, 137, 101), (123, 138, 101), (124, 138, 100), + (126, 138, 100), (127, 138, 99), (128, 138, 98), (128, 138, 97), + (129, 138, 97), (131, 138, 95), (131, 138, 94), (132, 138, 93), + (133, 138, 92), (134, 138, 92), (134, 138, 91), (134, 138, 91), + (135, 137, 90), (135, 137, 89), (136, 137, 88), (135, 135, 86), + (134, 133, 84), (132, 132, 82), (131, 131, 81), (128, 128, 77), + (126, 126, 74), (120, 121, 68), (117, 118, 65), (115, 116, 63), + (112, 114, 60), (109, 112, 57), (108, 110, 56), (107, 109, 55), + (102, 105, 51), (99, 103, 49), (97, 101, 47), (94, 99, 45), + (92, 97, 43), (90, 96, 42), (89, 95, 42), (87, 93, 40), + (84, 91, 39), (79, 87, 36), (77, 85, 35), (75, 84, 34), + (72, 82, 33), (70, 81, 33), (69, 80, 32), (68, 79, 32), + (63, 76, 31), (61, 74, 31), (59, 73, 31), (57, 72, 31), + (55, 71, 31), (54, 70, 31), (53, 70, 31), (52, 69, 31), + (50, 68, 32), (47, 66, 33), (45, 65, 33), (44, 65, 34), + (43, 64, 34), (42, 64, 35), (41, 64, 36), (40, 64, 36), + (38, 63, 38), (37, 63, 39), (36, 63, 40), (35, 62, 41), + (34, 62, 42), (33, 62, 42), (33, 62, 43), (32, 62, 44), + (31, 62, 45), (30, 62, 46), (29, 62, 47), (29, 62, 48), + (28, 62, 48), (28, 63, 48), (28, 63, 49), (27, 63, 50), + (26, 63, 51), (26, 63, 51), (26, 64, 52), (25, 64, 52), + (25, 64, 53), (25, 65, 53), (25, 65, 54), (25, 66, 54), + (25, 66, 55), (25, 68, 56), (26, 69, 57), (28, 71, 59), + (30, 72, 60), (32, 74, 62), (35, 77, 65), (38, 80, 68), + (45, 85, 74), (48, 87, 76), (51, 90, 79), (52, 91, 80), + (54, 93, 81), (58, 95, 83), (61, 98, 86), (64, 100, 88), + (67, 103, 89), (73, 107, 93), (74, 108, 93), (76, 109, 94), + (79, 112, 96), (82, 114, 97), (84, 116, 98), (87, 118, 100), + (92, 121, 102), (94, 122, 102), (97, 124, 103), (98, 125, 103), + (99, 126, 104), (102, 127, 105), (104, 129, 105), (106, 130, 105), + (105, 129, 103), (109, 131, 103), (110, 131, 103), (111, 132, 103), + (112, 133, 103), (114, 134, 103), (116, 135, 103), (117, 136, 103), + (120, 137, 102), (121, 137, 101), (123, 138, 101), (123, 138, 100), + (124, 138, 100), (126, 138, 100), (127, 138, 99), (128, 138, 98), + (129, 138, 97), (131, 138, 95), (131, 138, 94), (131, 138, 94), + (132, 138, 93), (133, 138, 92), (134, 138, 92), (134, 138, 91), + (135, 137, 90), (135, 137, 89), (136, 137, 89), (136, 137, 88), + (137, 136, 88), (134, 133, 84), (131, 131, 81), (128, 128, 77), + (126, 126, 74), (120, 121, 68), (118, 120, 66), (117, 119, 65), + (115, 116, 63), (112, 114, 60), (109, 112, 57), (107, 109, 55), + (102, 105, 51), (100, 104, 50), (99, 103, 49), (97, 101, 47), + (94, 99, 45), (92, 97, 43), (89, 95, 42), (87, 93, 40), + (84, 91, 39), (82, 89, 37), (79, 87, 36), (77, 86, 35), + (75, 84, 34), (72, 82, 33), (70, 81, 33), (68, 79, 32), + (63, 76, 31), (62, 75, 31), (61, 75, 31), (59, 73, 31), + (57, 72, 31), (55, 71, 31), (53, 70, 31), (52, 69, 31), + (50, 68, 32), (48, 67, 32), (47, 66, 33), (45, 66, 33), + (44, 65, 34), (42, 64, 35), (41, 64, 36), (40, 64, 36), + (39, 63, 37), (38, 63, 38), (37, 63, 39), (36, 63, 40), + (35, 62, 41), (34, 62, 42), (33, 62, 43), (32, 62, 44), + (31, 62, 45), (31, 62, 46), (30, 62, 46), (29, 62, 47), + (29, 62, 48), (28, 63, 48), (28, 63, 49), (27, 63, 50), + (27, 63, 50), (26, 63, 51), (26, 64, 52), (26, 64, 52), + (25, 64, 53), (25, 65, 53), (25, 65, 54), (25, 66, 54), + (25, 66, 55), (25, 67, 55), (25, 68, 56), (25, 68, 56), + (28, 71, 59), (32, 74, 62), (35, 77, 65), (38, 80, 68), + (42, 82, 71), (45, 85, 74), (48, 88, 76), (51, 90, 79), + (54, 93, 81), (58, 95, 83), (61, 98, 86), (64, 100, 88), + (67, 103, 89), (70, 105, 91), (73, 107, 93), (76, 109, 94), + (79, 112, 96), (82, 114, 97), (84, 116, 98), (87, 118, 100), + (90, 119, 101), (92, 121, 102), (95, 123, 102), (97, 124, 103), + (99, 126, 104), (102, 127, 105), (104, 129, 105), (106, 130, 105) + ), + +// 694 040412-011 +((126, 48, 55), (118, 44, 69), (114, 43, 73), (110, 42, 78), + (106, 41, 80), (103, 40, 83), (101, 39, 84), (99, 38, 86), + (92, 38, 92), (87, 36, 89), (83, 34, 87), (77, 33, 85), + (72, 33, 83), (70, 32, 80), (69, 31, 78), (68, 30, 77), + (67, 30, 76), (63, 30, 71), (63, 30, 69), (63, 30, 67), + (63, 30, 63), (63, 30, 59), (62, 30, 57), (62, 30, 55), + (66, 29, 54), (67, 28, 56), (69, 28, 58), (71, 27, 59), + (73, 27, 60), (74, 26, 60), (75, 26, 61), (77, 26, 62), + (79, 25, 64), (83, 24, 67), (85, 23, 68), (88, 23, 70), + (90, 22, 71), (93, 21, 73), (94, 21, 73), (96, 21, 74), + (101, 19, 78), (104, 18, 80), (107, 18, 82), (110, 17, 83), + (113, 16, 85), (114, 15, 85), (116, 15, 85), (119, 14, 87), + (122, 14, 89), (129, 12, 88), (132, 11, 88), (136, 10, 88), + (139, 9, 88), (143, 8, 88), (145, 7, 86), (147, 7, 85), + (154, 5, 83), (157, 4, 81), (161, 3, 79), (165, 2, 75), + (169, 1, 71), (170, 0, 70), (172, 0, 69), (176, 2, 66), + (180, 4, 61), (187, 6, 52), (190, 8, 46), (194, 10, 41), + (195, 11, 39), (197, 12, 38), (201, 15, 29), (204, 17, 22), + (211, 33, 16), (214, 40, 14), (218, 48, 12), (220, 56, 10), + (223, 65, 9), (224, 69, 8), (226, 74, 8), (228, 81, 6), + (231, 87, 4), (234, 100, 2), (236, 107, 1), (238, 115, 0), + (238, 118, 0), (239, 122, 0), (240, 126, 0), (241, 131, 0), + (242, 144, 0), (242, 147, 0), (243, 150, 0), (243, 153, 0), + (243, 156, 0), (243, 160, 0), (243, 161, 0), (243, 162, 1), + (242, 165, 2), (241, 168, 5), (240, 169, 6), (239, 170, 8), + (238, 169, 9), (238, 168, 10), (237, 166, 12), (235, 165, 15), + (229, 163, 19), (225, 161, 19), (221, 159, 19), (219, 158, 19), + (217, 157, 20), (212, 156, 21), (208, 152, 21), (204, 149, 24), + (199, 147, 24), (190, 139, 26), (187, 137, 27), (185, 135, 29), + (180, 129, 31), (176, 125, 31), (171, 118, 33), (166, 113, 35), + (156, 98, 39), (151, 92, 40), (146, 86, 41), (144, 83, 41), + (142, 80, 42), (137, 72, 44), (133, 63, 45), (128, 58, 46), + (126, 48, 55), (118, 44, 69), (116, 43, 71), (114, 43, 73), + (110, 42, 78), (106, 41, 81), (103, 40, 83), (99, 38, 86), + (92, 38, 92), (87, 36, 89), (83, 34, 87), (80, 34, 86), + (78, 34, 85), (72, 33, 83), (69, 32, 80), (69, 31, 78), + (67, 30, 76), (63, 30, 71), (62, 29, 70), (61, 29, 69), + (63, 30, 67), (65, 30, 65), (63, 30, 59), (62, 30, 55), + (66, 29, 54), (66, 29, 56), (67, 29, 59), (69, 28, 58), + (71, 27, 58), (73, 27, 60), (75, 26, 61), (77, 26, 62), + (79, 25, 64), (83, 24, 67), (84, 24, 68), (85, 24, 69), + (88, 23, 70), (90, 22, 71), (93, 21, 73), (96, 21, 74), + (101, 19, 78), (102, 18, 79), (104, 18, 80), (107, 18, 82), + (110, 17, 83), (113, 16, 85), (116, 15, 85), (119, 14, 87), + (122, 14, 89), (126, 13, 87), (129, 12, 88), (132, 11, 88), + (136, 10, 88), (139, 9, 88), (143, 8, 88), (147, 7, 85), + (154, 5, 83), (156, 4, 82), (158, 4, 82), (161, 3, 79), + (165, 2, 75), (169, 1, 71), (172, 0, 69), (176, 2, 66), + (180, 4, 61), (183, 5, 58), (187, 6, 52), (190, 8, 49), + (194, 10, 41), (197, 12, 38), (201, 15, 29), (204, 17, 22), + (208, 23, 17), (211, 33, 16), (215, 42, 14), (218, 48, 12), + (221, 57, 10), (223, 65, 9), (226, 74, 8), (228, 81, 6), + (231, 87, 4), (233, 95, 3), (234, 100, 2), (236, 108, 1), + (238, 115, 0), (239, 122, 0), (240, 126, 0), (241, 131, 0), + (242, 137, 0), (242, 144, 0), (243, 147, 0), (243, 150, 0), + (243, 156, 0), (243, 160, 0), (243, 161, 0), (243, 162, 1), + (242, 165, 2), (242, 165, 3), (241, 168, 5), (240, 168, 7), + (239, 170, 8), (238, 168, 10), (237, 166, 12), (235, 165, 15), + (233, 164, 17), (229, 163, 19), (225, 161, 19), (221, 159, 19), + (217, 157, 20), (212, 156, 21), (208, 152, 21), (204, 149, 24), + (199, 147, 24), (195, 143, 26), (190, 139, 26), (185, 135, 29), + (180, 129, 31), (176, 125, 31), (171, 118, 33), (166, 113, 35), + (161, 106, 36), (156, 98, 39), (151, 94, 40), (146, 86, 41), + (142, 80, 42), (137, 72, 44), (133, 63, 45), (128, 58, 46) + ), + +// 695 040412-012 +((185, 134, 154), (177, 127, 143), (172, 123, 137), (168, 120, 132), + (164, 116, 126), (160, 113, 121), (158, 111, 118), (156, 110, 115), + (147, 102, 104), (143, 98, 98), (139, 95, 93), (134, 91, 87), + (130, 88, 81), (123, 83, 74), (116, 78, 67), (112, 76, 64), + (109, 74, 61), (95, 65, 49), (89, 61, 44), (83, 58, 39), + (78, 54, 35), (73, 51, 31), (70, 49, 29), (67, 48, 27), + (57, 42, 21), (52, 39, 18), (47, 37, 16), (43, 35, 15), + (40, 34, 14), (39, 33, 14), (39, 33, 15), (38, 33, 15), + (37, 32, 16), (35, 31, 17), (34, 30, 18), (33, 30, 19), + (32, 30, 19), (31, 30, 20), (30, 29, 20), (30, 29, 21), + (28, 28, 22), (27, 27, 23), (26, 27, 24), (25, 26, 24), + (24, 26, 25), (23, 26, 25), (23, 26, 26), (23, 26, 27), + (22, 26, 28), (21, 27, 30), (21, 27, 31), (21, 28, 33), + (21, 29, 34), (21, 31, 36), (21, 32, 37), (21, 33, 38), + (22, 37, 42), (22, 39, 44), (23, 41, 47), (24, 44, 49), + (26, 47, 52), (26, 48, 53), (27, 50, 55), (28, 53, 57), + (29, 57, 60), (31, 63, 65), (32, 66, 67), (33, 69, 70), + (34, 70, 71), (35, 72, 73), (36, 75, 76), (37, 78, 78), + (39, 84, 84), (40, 87, 86), (41, 91, 89), (42, 94, 91), + (44, 97, 94), (44, 98, 95), (45, 100, 97), (46, 103, 100), + (48, 106, 102), (52, 111, 108), (55, 113, 111), (58, 116, 114), + (59, 117, 115), (61, 119, 116), (65, 121, 119), (69, 123, 122), + (77, 127, 128), (82, 129, 131), (87, 131, 134), (89, 132, 135), + (92, 133, 137), (97, 135, 141), (103, 136, 144), (108, 138, 147), + (114, 139, 150), (125, 143, 156), (130, 144, 159), (136, 146, 162), + (139, 147, 164), (142, 148, 166), (148, 149, 169), (153, 151, 172), + (164, 154, 178), (170, 155, 181), (176, 157, 184), (178, 158, 185), + (181, 159, 187), (187, 161, 191), (192, 162, 193), (197, 163, 196), + (201, 164, 198), (207, 165, 200), (208, 165, 200), (210, 165, 200), + (211, 164, 199), (212, 163, 198), (212, 162, 197), (212, 161, 195), + (210, 157, 189), (207, 154, 185), (205, 152, 181), (203, 150, 178), + (202, 149, 176), (198, 145, 171), (194, 142, 165), (189, 138, 160), + (185, 134, 154), (177, 127, 143), (174, 125, 140), (172, 124, 137), + (168, 120, 132), (164, 117, 126), (160, 113, 121), (156, 110, 115), + (147, 102, 104), (143, 98, 98), (139, 95, 93), (136, 93, 90), + (134, 92, 87), (130, 88, 81), (123, 83, 74), (116, 78, 67), + (109, 74, 61), (95, 65, 49), (92, 63, 46), (89, 61, 44), + (83, 58, 39), (79, 55, 35), (73, 51, 31), (67, 48, 27), + (57, 42, 21), (54, 41, 19), (52, 40, 18), (47, 37, 16), + (42, 35, 14), (40, 34, 14), (39, 33, 15), (38, 33, 15), + (37, 32, 16), (35, 31, 17), (34, 31, 17), (34, 31, 18), + (33, 30, 19), (32, 30, 20), (31, 30, 20), (30, 29, 21), + (28, 28, 22), (27, 28, 22), (27, 28, 23), (26, 27, 24), + (25, 27, 24), (24, 26, 25), (23, 26, 26), (23, 26, 27), + (22, 26, 28), (21, 26, 29), (21, 27, 30), (21, 27, 31), + (21, 28, 33), (21, 30, 35), (21, 31, 36), (21, 33, 38), + (22, 37, 42), (22, 38, 43), (23, 39, 44), (23, 41, 47), + (24, 44, 49), (26, 47, 52), (27, 50, 55), (28, 53, 57), + (29, 57, 60), (30, 60, 62), (31, 63, 65), (32, 66, 68), + (33, 69, 70), (35, 72, 73), (36, 75, 76), (37, 78, 78), + (38, 81, 81), (39, 84, 84), (40, 87, 86), (41, 91, 89), + (42, 94, 92), (44, 97, 94), (45, 100, 97), (46, 103, 100), + (48, 106, 102), (50, 108, 105), (52, 111, 108), (55, 114, 111), + (58, 116, 114), (61, 119, 116), (65, 121, 119), (69, 123, 122), + (73, 125, 125), (77, 127, 128), (82, 129, 131), (87, 131, 134), + (92, 133, 137), (97, 135, 141), (103, 136, 144), (108, 138, 147), + (114, 139, 150), (120, 141, 153), (125, 143, 156), (131, 144, 159), + (136, 146, 162), (142, 148, 166), (148, 149, 169), (153, 151, 172), + (159, 152, 175), (164, 154, 178), (170, 156, 181), (176, 157, 184), + (181, 159, 187), (187, 161, 191), (192, 162, 193), (197, 163, 196), + (201, 164, 198), (205, 165, 199), (207, 165, 200), (210, 165, 200), + (211, 164, 199), (212, 163, 198), (212, 162, 197), (212, 161, 195), + (212, 159, 192), (210, 157, 189), (208, 154, 185), (205, 152, 181), + (202, 149, 176), (198, 145, 171), (194, 142, 165), (189, 138, 160) + ), + +// 696 040412-013 +((64, 11, 92), (58, 10, 86), (55, 9, 82), (52, 9, 79), + (49, 8, 76), (46, 8, 73), (45, 8, 72), (44, 9, 71), + (39, 9, 65), (37, 9, 62), (35, 10, 60), (33, 10, 58), + (31, 11, 56), (28, 12, 54), (26, 13, 52), (25, 13, 51), + (25, 14, 50), (29, 14, 56), (30, 14, 59), (32, 14, 62), + (34, 13, 65), (37, 13, 69), (38, 13, 70), (39, 14, 72), + (42, 14, 78), (44, 14, 81), (46, 14, 84), (47, 14, 87), + (49, 15, 90), (50, 14, 91), (52, 14, 93), (54, 14, 97), + (55, 15, 100), (59, 14, 106), (60, 14, 109), (62, 15, 112), + (64, 15, 115), (67, 15, 118), (68, 15, 119), (69, 15, 121), + (72, 17, 126), (74, 17, 128), (76, 18, 131), (77, 19, 133), + (78, 20, 135), (79, 20, 136), (80, 20, 138), (82, 22, 140), + (84, 22, 142), (87, 24, 146), (88, 26, 147), (90, 28, 149), + (92, 29, 150), (94, 31, 152), (94, 32, 153), (94, 33, 154), + (98, 36, 157), (99, 38, 158), (101, 40, 159), (102, 42, 160), + (103, 44, 161), (103, 45, 161), (104, 46, 162), (106, 48, 163), + (107, 51, 164), (110, 55, 165), (111, 58, 166), (112, 61, 167), + (113, 62, 167), (114, 63, 167), (115, 66, 167), (115, 69, 168), + (118, 74, 169), (119, 76, 169), (121, 79, 170), (122, 81, 170), + (123, 84, 171), (123, 85, 171), (124, 87, 171), (124, 90, 172), + (126, 93, 172), (128, 98, 173), (128, 101, 173), (128, 104, 174), + (128, 105, 174), (129, 106, 175), (130, 108, 175), (132, 111, 175), + (132, 115, 176), (132, 117, 176), (132, 119, 176), (132, 119, 176), + (133, 120, 176), (129, 122, 176), (131, 123, 176), (131, 123, 175), + (133, 124, 175), (131, 126, 174), (136, 125, 173), (141, 125, 172), + (142, 125, 171), (143, 125, 171), (142, 125, 170), (146, 124, 169), + (156, 122, 167), (158, 121, 166), (160, 120, 165), (161, 119, 164), + (163, 119, 163), (162, 117, 162), (162, 114, 154), (161, 113, 154), + (160, 110, 150), (157, 104, 145), (156, 103, 143), (156, 102, 142), + (155, 99, 140), (153, 95, 139), (152, 91, 134), (150, 88, 133), + (146, 81, 128), (144, 76, 125), (143, 72, 123), (142, 70, 122), + (141, 69, 122), (140, 65, 118), (138, 61, 116), (136, 58, 115), + (135, 53, 111), (131, 46, 108), (130, 44, 106), (130, 42, 105), + (128, 38, 103), (126, 35, 100), (125, 30, 98), (123, 27, 96), + (119, 19, 92), (117, 15, 89), (116, 12, 87), (115, 10, 86), + (115, 9, 85), (114, 6, 84), (113, 4, 82), (112, 2, 80), + (111, 0, 79), (109, 0, 77), (109, 0, 76), (109, 0, 76), + (108, 0, 77), (108, 0, 76), (108, 0, 75), (108, 0, 75), + (108, 0, 74), (108, 0, 74), (108, 0, 74), (108, 0, 74), + (108, 0, 74), (109, 0, 74), (109, 0, 74), (110, 0, 74), + (111, 0, 74), (112, 0, 74), (112, 1, 74), (113, 2, 74), + (115, 3, 76), (116, 6, 77), (117, 9, 77), (119, 11, 79), + (122, 19, 83), (123, 20, 83), (124, 22, 84), (126, 26, 86), + (128, 29, 87), (130, 34, 88), (132, 38, 90), (133, 41, 92), + (135, 45, 93), (137, 49, 94), (139, 52, 96), (141, 57, 96), + (143, 60, 98), (145, 64, 99), (147, 67, 100), (148, 71, 101), + (152, 79, 102), (153, 81, 102), (154, 83, 102), (156, 87, 102), + (158, 90, 102), (159, 94, 103), (161, 97, 102), (163, 100, 102), + (164, 103, 103), (165, 109, 104), (167, 113, 105), (168, 115, 107), + (169, 121, 108), (170, 123, 110), (171, 126, 110), (171, 128, 111), + (172, 128, 112), (173, 132, 113), (173, 131, 114), (173, 132, 115), + (174, 130, 116), (174, 132, 117), (174, 130, 118), (174, 128, 119), + (174, 127, 120), (174, 123, 120), (173, 120, 123), (173, 119, 129), + (172, 118, 132), (172, 116, 135), (171, 115, 140), (170, 114, 143), + (169, 111, 147), (168, 109, 149), (167, 106, 152), (166, 103, 154), + (165, 101, 156), (163, 98, 159), (162, 94, 160), (159, 91, 161), + (157, 88, 161), (154, 84, 161), (153, 82, 160), (151, 78, 160), + (148, 75, 160), (147, 72, 160), (144, 68, 160), (143, 65, 160), + (140, 62, 160), (139, 58, 160), (138, 55, 159), (135, 51, 159), + (134, 48, 159), (132, 45, 159), (131, 41, 159), (128, 38, 159), + (123, 35, 154), (118, 33, 149), (115, 31, 144), (110, 29, 139), + (105, 27, 135), (101, 25, 130), (97, 23, 126), (92, 22, 121), + (88, 20, 117), (84, 19, 113), (80, 18, 109), (78, 16, 105), + (74, 15, 101), (69, 14, 98), (67, 14, 94), (64, 13, 91) + ), + +// 697 040412-014 +((50, 131, 83), (52, 132, 87), (52, 133, 87), (52, 134, 87), + (52, 134, 87), (53, 134, 88), (54, 134, 88), (55, 134, 88), + (56, 132, 89), (56, 131, 89), (57, 131, 89), (57, 129, 88), + (57, 128, 88), (57, 127, 86), (57, 126, 84), (57, 124, 84), + (57, 123, 84), (56, 119, 80), (56, 117, 78), (57, 115, 76), + (57, 113, 75), (57, 111, 75), (57, 110, 73), (57, 110, 72), + (57, 106, 70), (56, 104, 68), (55, 102, 67), (55, 100, 65), + (56, 98, 63), (55, 97, 62), (55, 97, 61), (56, 94, 58), + (55, 93, 57), (54, 89, 54), (54, 87, 53), (55, 85, 53), + (56, 82, 51), (58, 79, 50), (57, 78, 49), (57, 78, 49), + (55, 73, 47), (54, 71, 45), (54, 69, 44), (54, 67, 42), + (55, 65, 40), (54, 63, 40), (53, 62, 40), (51, 60, 38), + (49, 58, 37), (46, 53, 35), (44, 50, 33), (43, 48, 32), + (41, 46, 30), (39, 44, 28), (38, 42, 27), (38, 41, 27), + (36, 36, 24), (34, 32, 23), (32, 29, 22), (30, 27, 20), + (28, 25, 19), (26, 22, 19), (25, 20, 20), (25, 20, 20), + (25, 20, 20), (25, 20, 20), (25, 20, 20), (25, 20, 20), + (25, 20, 20), (25, 20, 20), (25, 20, 20), (25, 20, 20), + (25, 20, 20), (25, 20, 20), (25, 20, 20), (25, 20, 20), + (25, 20, 20), (25, 20, 20), (25, 20, 20), (19, 19, 27), + (19, 19, 31), (20, 17, 41), (22, 18, 47), (24, 19, 53), + (25, 20, 56), (27, 21, 60), (31, 25, 66), (36, 28, 74), + (42, 37, 90), (46, 41, 98), (51, 45, 106), (52, 46, 110), + (54, 48, 114), (57, 54, 122), (62, 57, 130), (65, 60, 139), + (68, 65, 147), (76, 73, 163), (79, 77, 170), (83, 81, 178), + (85, 82, 182), (88, 84, 186), (91, 89, 194), (93, 93, 202), + (97, 97, 207), (96, 96, 201), (95, 95, 196), (94, 95, 192), + (94, 96, 188), (93, 94, 180), (93, 95, 172), (92, 93, 164), + (89, 95, 155), (89, 95, 141), (89, 95, 138), (89, 96, 136), + (89, 99, 130), (88, 97, 124), (86, 105, 114), (96, 108, 83), + (96, 102, 63), (92, 98, 53), (89, 95, 44), (87, 93, 39), + (85, 91, 34), (85, 89, 27), (84, 90, 22), (88, 93, 22), + (89, 95, 26), (96, 102, 30), (98, 103, 32), (101, 104, 34), + (103, 107, 37), (107, 110, 40), (110, 114, 43), (114, 116, 47), + (121, 123, 51), (124, 125, 54), (128, 128, 57), (130, 130, 59), + (132, 132, 61), (135, 135, 64), (139, 136, 66), (141, 139, 70), + (145, 143, 71), (151, 146, 77), (152, 148, 78), (153, 150, 79), + (155, 152, 82), (157, 154, 85), (159, 156, 86), (160, 158, 88), + (163, 160, 93), (163, 161, 94), (164, 162, 95), (165, 161, 97), + (165, 163, 99), (167, 161, 99), (167, 163, 100), (167, 163, 102), + (167, 163, 103), (165, 163, 106), (165, 163, 107), (165, 163, 108), + (164, 162, 108), (163, 163, 109), (161, 161, 109), (159, 161, 110), + (157, 160, 113), (155, 159, 113), (153, 159, 113), (150, 159, 114), + (151, 157, 114), (145, 156, 115), (145, 156, 115), (141, 155, 118), + (136, 155, 118), (126, 153, 119), (119, 153, 119), (119, 152, 127), + (118, 151, 135), (116, 151, 139), (116, 149, 149), (115, 143, 149), + (111, 144, 148), (110, 140, 148), (109, 137, 148), (107, 137, 147), + (106, 138, 145), (104, 132, 144), (101, 135, 141), (100, 131, 140), + (97, 131, 139), (96, 133, 136), (93, 129, 134), (91, 131, 131), + (90, 128, 128), (87, 127, 124), (84, 124, 122), (80, 123, 114), + (79, 120, 109), (75, 118, 105), (73, 116, 99), (71, 114, 94), + (68, 111, 91), (65, 108, 89), (61, 107, 83), (59, 104, 79), + (57, 102, 73), (54, 101, 70), (51, 98, 66), (48, 95, 62), + (46, 94, 57), (42, 91, 56), (40, 89, 52), (37, 86, 48), + (33, 85, 44), (32, 83, 41), (30, 81, 39), (29, 79, 36), + (26, 79, 35), (25, 78, 32), (23, 77, 31), (22, 77, 29), + (21, 77, 29), (21, 77, 28), (20, 77, 28), (20, 77, 28), + (20, 77, 28), (20, 78, 28), (20, 79, 28), (20, 79, 29), + (20, 81, 31), (21, 83, 32), (21, 85, 35), (23, 86, 35), + (24, 89, 39), (26, 91, 40), (27, 94, 43), (28, 95, 47), + (30, 98, 47), (30, 101, 50), (32, 102, 52), (34, 104, 55), + (35, 107, 56), (36, 108, 60), (39, 111, 63), (39, 114, 64), + (40, 115, 67), (42, 118, 68), (43, 120, 71), (44, 123, 74), + (45, 124, 77), (47, 127, 78), (48, 128, 80), (49, 130, 82) + ), + +// 698 040412-015 +((130, 49, 119), (131, 50, 117), (131, 51, 117), (132, 53, 117), + (133, 53, 119), (134, 53, 122), (134, 53, 121), (134, 53, 120), + (134, 55, 122), (133, 56, 121), (132, 57, 121), (131, 57, 120), + (130, 57, 119), (128, 57, 117), (127, 57, 115), (126, 57, 116), + (126, 57, 118), (122, 58, 114), (120, 57, 113), (118, 56, 113), + (116, 56, 111), (114, 56, 110), (112, 56, 108), (111, 57, 107), + (108, 56, 107), (105, 56, 105), (102, 57, 104), (100, 56, 102), + (99, 56, 101), (96, 56, 99), (94, 56, 98), (92, 55, 97), + (86, 56, 94), (81, 56, 90), (78, 54, 88), (75, 53, 86), + (72, 52, 84), (70, 52, 82), (66, 51, 80), (63, 50, 79), + (58, 47, 75), (54, 45, 73), (51, 44, 71), (49, 43, 68), + (48, 43, 66), (45, 41, 65), (43, 40, 65), (43, 40, 62), + (41, 38, 60), (35, 35, 56), (33, 34, 53), (32, 33, 50), + (30, 31, 47), (29, 30, 45), (28, 29, 44), (28, 28, 44), + (25, 28, 38), (23, 29, 36), (22, 30, 35), (20, 25, 32), + (19, 21, 29), (19, 22, 28), (19, 24, 28), (20, 25, 23), + (20, 25, 23), (20, 25, 23), (20, 25, 23), (20, 25, 23), + (20, 25, 23), (20, 25, 23), (20, 25, 23), (20, 25, 23), + (20, 25, 23), (20, 25, 23), (20, 25, 23), (20, 25, 23), + (20, 25, 23), (20, 25, 23), (20, 25, 23), (20, 25, 23), + (27, 24, 19), (36, 31, 18), (41, 37, 17), (46, 44, 16), + (49, 46, 17), (53, 49, 19), (60, 55, 21), (66, 61, 25), + (82, 74, 33), (90, 81, 37), (98, 88, 41), (102, 92, 43), + (106, 96, 45), (114, 102, 48), (122, 107, 54), (130, 115, 57), + (139, 123, 60), (155, 136, 68), (162, 141, 73), (170, 147, 78), + (174, 150, 79), (178, 154, 81), (186, 162, 84), (194, 168, 89), + (207, 178, 96), (205, 176, 96), (203, 175, 96), (199, 172, 95), + (196, 169, 95), (188, 161, 94), (180, 155, 93), (172, 148, 93), + (164, 144, 92), (147, 125, 88), (144, 123, 88), (141, 121, 89), + (136, 116, 89), (130, 109, 89), (124, 105, 88), (114, 87, 86), + (76, 74, 106), (65, 67, 102), (54, 60, 98), (49, 55, 96), + (44, 51, 95), (34, 43, 91), (27, 39, 89), (22, 34, 90), + (22, 36, 93), (29, 44, 98), (29, 43, 100), (30, 43, 102), + (34, 49, 104), (37, 52, 107), (40, 55, 110), (43, 58, 114), + (48, 67, 119), (51, 70, 122), (55, 74, 126), (56, 75, 127), + (57, 76, 128), (61, 80, 132), (64, 83, 135), (66, 88, 139), + (70, 91, 141), (75, 97, 148), (76, 99, 149), (77, 102, 151), + (79, 101, 153), (82, 104, 155), (85, 107, 157), (86, 108, 159), + (91, 112, 161), (92, 113, 162), (93, 115, 163), (95, 116, 164), + (97, 120, 165), (99, 119, 165), (99, 123, 167), (100, 122, 167), + (102, 124, 167), (104, 125, 167), (105, 124, 166), (106, 124, 165), + (108, 125, 165), (108, 125, 164), (109, 123, 163), (109, 123, 161), + (111, 122, 160), (112, 122, 160), (113, 122, 160), (113, 119, 159), + (114, 117, 159), (114, 120, 157), (115, 115, 156), (115, 115, 156), + (122, 118, 155), (127, 118, 155), (137, 119, 153), (144, 119, 153), + (152, 119, 152), (151, 118, 143), (151, 116, 138), (149, 116, 125), + (149, 112, 114), (148, 111, 115), (148, 111, 117), (148, 110, 109), + (147, 107, 108), (145, 106, 109), (144, 105, 104), (141, 101, 106), + (140, 100, 101), (139, 97, 100), (136, 96, 104), (134, 93, 99), + (131, 91, 102), (128, 90, 100), (127, 87, 100), (124, 84, 97), + (123, 80, 101), (120, 79, 101), (118, 75, 99), (116, 73, 102), + (114, 71, 102), (111, 68, 99), (108, 65, 96), (107, 61, 97), + (104, 59, 96), (102, 57, 98), (101, 54, 98), (98, 51, 96), + (95, 48, 93), (92, 46, 94), (91, 42, 90), (88, 40, 89), + (83, 37, 86), (82, 33, 85), (79, 32, 83), (77, 30, 81), + (72, 29, 79), (73, 26, 79), (71, 25, 78), (70, 23, 77), + (69, 22, 77), (70, 21, 77), (69, 21, 77), (69, 20, 77), + (69, 20, 77), (69, 20, 77), (70, 20, 78), (71, 20, 79), + (72, 20, 79), (76, 20, 81), (78, 21, 83), (82, 21, 85), + (81, 23, 86), (87, 24, 89), (88, 26, 91), (92, 27, 94), + (95, 28, 94), (97, 30, 98), (101, 30, 100), (102, 32, 101), + (104, 34, 102), (107, 35, 105), (108, 36, 103), (111, 39, 106), + (114, 39, 109), (115, 40, 107), (118, 42, 112), (120, 43, 112), + (123, 44, 114), (124, 45, 113), (127, 47, 118), (128, 48, 117) + ), + +// 699 040412-016 +((81, 115, 124), (85, 126, 131), (86, 132, 134), (87, 138, 138), + (86, 141, 138), (85, 144, 139), (84, 145, 139), (84, 147, 140), + (81, 152, 140), (79, 153, 140), (78, 155, 140), (76, 155, 138), + (75, 156, 137), (73, 156, 136), (72, 157, 136), (71, 156, 135), + (70, 156, 135), (66, 154, 131), (64, 152, 127), (62, 151, 124), + (60, 148, 122), (58, 146, 120), (57, 145, 119), (56, 144, 118), + (51, 137, 111), (48, 133, 107), (46, 129, 104), (43, 124, 99), + (41, 119, 94), (39, 116, 91), (38, 113, 89), (35, 108, 85), + (33, 102, 81), (28, 91, 72), (26, 86, 68), (25, 81, 65), + (24, 76, 62), (24, 72, 59), (23, 70, 58), (23, 68, 57), + (23, 60, 53), (23, 56, 51), (24, 53, 50), (24, 48, 48), + (24, 43, 46), (23, 40, 44), (23, 38, 43), (22, 32, 40), + (21, 26, 37), (22, 20, 35), (26, 19, 38), (31, 19, 41), + (37, 19, 44), (43, 20, 48), (45, 20, 50), (48, 20, 52), + (60, 22, 58), (63, 21, 60), (67, 20, 62), (70, 19, 63), + (73, 19, 65), (74, 19, 65), (75, 19, 65), (78, 18, 67), + (80, 18, 67), (83, 18, 69), (84, 18, 69), (85, 19, 69), + (85, 19, 68), (85, 19, 67), (86, 19, 68), (86, 20, 67), + (86, 21, 65), (85, 22, 64), (85, 23, 64), (83, 24, 62), + (82, 26, 61), (81, 26, 59), (80, 27, 58), (79, 29, 58), + (76, 30, 54), (72, 33, 50), (71, 34, 48), (70, 35, 46), + (69, 35, 45), (69, 36, 44), (70, 36, 44), (70, 39, 42), + (75, 50, 44), (79, 56, 46), (84, 62, 49), (86, 64, 50), + (88, 67, 51), (92, 72, 54), (97, 79, 57), (101, 83, 59), + (105, 88, 62), (114, 97, 67), (117, 98, 68), (120, 99, 69), + (122, 101, 70), (125, 103, 72), (129, 105, 74), (133, 107, 76), + (142, 110, 80), (146, 112, 82), (151, 115, 85), (153, 115, 86), + (155, 116, 87), (159, 119, 90), (163, 121, 93), (167, 125, 97), + (169, 123, 97), (172, 120, 100), (172, 119, 100), (173, 119, 101), + (174, 118, 102), (175, 117, 104), (175, 117, 105), (176, 116, 107), + (177, 119, 111), (177, 119, 113), (177, 119, 115), (176, 119, 116), + (176, 119, 117), (177, 121, 120), (177, 123, 122), (177, 125, 125), + (177, 127, 127), (176, 133, 134), (175, 134, 135), (174, 136, 137), + (173, 139, 141), (171, 142, 143), (169, 146, 147), (167, 149, 151), + (161, 156, 156), (158, 159, 158), (155, 162, 160), (153, 163, 161), + (152, 165, 163), (148, 166, 163), (145, 168, 165), (142, 169, 165), + (138, 169, 164), (131, 168, 163), (129, 167, 161), (127, 167, 160), + (124, 166, 160), (120, 164, 158), (116, 162, 154), (112, 159, 150), + (104, 153, 144), (102, 151, 142), (100, 149, 140), (96, 145, 136), + (92, 140, 130), (88, 135, 126), (84, 129, 119), (80, 123, 114), + (75, 116, 106), (66, 102, 92), (64, 98, 88), (62, 95, 85), + (58, 88, 78), (55, 82, 72), (51, 77, 65), (48, 72, 60), + (43, 64, 50), (42, 62, 48), (41, 61, 47), (39, 58, 43), + (37, 56, 39), (36, 55, 37), (35, 54, 35), (35, 55, 34), + (34, 55, 33), (34, 56, 32), (35, 58, 32), (36, 60, 32), + (37, 62, 33), (37, 65, 33), (38, 68, 34), (40, 72, 35), + (42, 80, 39), (43, 82, 40), (44, 85, 41), (45, 90, 43), + (47, 95, 45), (48, 99, 47), (50, 103, 49), (51, 106, 51), + (52, 109, 53), (53, 112, 53), (54, 114, 55), (55, 115, 57), + (55, 116, 57), (55, 117, 57), (55, 117, 57), (55, 117, 57), + (55, 117, 58), (55, 117, 58), (54, 116, 58), (53, 114, 56), + (52, 112, 55), (51, 110, 55), (50, 107, 54), (48, 103, 50), + (47, 99, 49), (44, 95, 47), (42, 90, 45), (40, 84, 42), + (37, 79, 40), (35, 73, 37), (33, 68, 35), (31, 63, 33), + (29, 59, 32), (28, 55, 30), (27, 52, 30), (26, 48, 28), + (26, 46, 29), (25, 43, 27), (26, 42, 30), (26, 40, 30), + (26, 39, 30), (27, 38, 32), (28, 37, 33), (29, 37, 35), + (30, 36, 37), (30, 35, 38), (30, 34, 39), (30, 33, 40), + (31, 34, 42), (32, 34, 44), (34, 35, 46), (36, 37, 49), + (38, 39, 53), (40, 41, 56), (43, 44, 60), (45, 47, 64), + (48, 51, 68), (50, 53, 71), (52, 56, 75), (55, 60, 79), + (57, 63, 82), (59, 67, 86), (61, 70, 89), (63, 74, 93), + (66, 79, 96), (68, 83, 100), (70, 87, 103), (72, 92, 107), + (74, 95, 110), (76, 101, 114), (78, 106, 117), (80, 111, 121) + ), + +// 700 040412-017 +((0, 68, 38), (0, 57, 27), (0, 53, 23), (0, 50, 20), + (0, 48, 19), (0, 46, 18), (0, 45, 18), (0, 45, 18), + (1, 44, 21), (1, 44, 23), (1, 45, 25), (2, 46, 28), + (3, 48, 31), (3, 49, 34), (4, 51, 37), (4, 51, 39), + (4, 52, 41), (6, 55, 47), (6, 56, 49), (7, 58, 52), + (8, 58, 53), (9, 59, 55), (9, 59, 55), (10, 59, 56), + (11, 58, 55), (11, 57, 53), (11, 57, 52), (11, 55, 50), + (12, 54, 48), (12, 53, 46), (12, 52, 45), (12, 51, 42), + (12, 49, 39), (12, 46, 32), (12, 45, 28), (13, 44, 25), + (14, 43, 23), (16, 43, 21), (17, 43, 20), (18, 43, 19), + (24, 45, 16), (28, 48, 15), (33, 51, 15), (39, 55, 16), + (45, 59, 17), (48, 62, 18), (52, 65, 19), (60, 71, 22), + (68, 78, 25), (87, 93, 33), (97, 101, 37), (107, 110, 42), + (117, 118, 47), (128, 127, 52), (133, 131, 54), (138, 136, 57), + (156, 153, 66), (163, 160, 70), (171, 167, 74), (176, 172, 77), + (182, 178, 80), (183, 179, 81), (185, 181, 82), (186, 183, 84), + (186, 184, 85), (179, 182, 85), (172, 179, 83), (166, 176, 82), + (162, 173, 80), (158, 171, 79), (148, 166, 76), (138, 160, 73), + (119, 149, 67), (108, 142, 65), (97, 136, 63), (86, 129, 61), + (75, 123, 59), (69, 120, 58), (64, 117, 58), (54, 112, 57), + (44, 107, 56), (28, 101, 57), (23, 100, 59), (18, 100, 62), + (16, 100, 64), (14, 100, 66), (11, 102, 71), (9, 104, 76), + (5, 110, 87), (3, 113, 93), (1, 117, 99), (0, 119, 102), + (0, 122, 106), (0, 128, 113), (0, 134, 121), (0, 142, 129), + (0, 149, 137), (2, 162, 153), (3, 168, 160), (4, 175, 168), + (4, 178, 171), (5, 181, 174), (6, 186, 180), (7, 191, 185), + (9, 199, 194), (10, 201, 196), (11, 204, 198), (11, 204, 198), + (12, 204, 199), (12, 204, 198), (13, 202, 196), (13, 199, 192), + (14, 195, 187), (13, 184, 173), (12, 180, 168), (12, 177, 164), + (11, 169, 155), (11, 161, 145), (10, 152, 134), (9, 143, 124), + (6, 124, 102), (5, 115, 91), (4, 106, 81), (3, 101, 76), + (3, 97, 71), (2, 89, 61), (2, 81, 53), (1, 74, 45), + (0, 68, 38), (0, 57, 27), (0, 55, 25), (0, 53, 23), + (0, 50, 20), (0, 47, 19), (0, 46, 18), (0, 45, 18), + (1, 44, 21), (1, 44, 23), (1, 45, 25), (1, 45, 26), + (2, 46, 28), (3, 48, 31), (3, 49, 34), (4, 51, 37), + (4, 52, 41), (6, 55, 47), (6, 56, 48), (7, 57, 50), + (7, 58, 52), (8, 58, 54), (9, 59, 55), (10, 59, 56), + (11, 58, 55), (11, 58, 54), (11, 58, 54), (11, 57, 52), + (12, 55, 50), (12, 54, 48), (12, 52, 45), (12, 51, 42), + (12, 49, 39), (12, 46, 32), (12, 45, 30), (12, 45, 29), + (13, 44, 25), (14, 43, 23), (16, 43, 21), (18, 43, 19), + (24, 45, 16), (26, 46, 15), (28, 48, 15), (33, 51, 15), + (38, 55, 16), (45, 59, 17), (52, 65, 19), (60, 71, 22), + (68, 78, 25), (78, 85, 29), (87, 93, 33), (97, 101, 38), + (107, 110, 42), (118, 118, 47), (128, 127, 52), (138, 136, 57), + (156, 153, 66), (160, 156, 68), (164, 160, 70), (171, 167, 74), + (177, 173, 77), (182, 178, 80), (185, 181, 82), (186, 183, 84), + (186, 184, 85), (183, 183, 85), (179, 182, 85), (174, 179, 84), + (166, 176, 82), (158, 171, 79), (148, 166, 76), (138, 160, 73), + (128, 155, 70), (119, 149, 67), (108, 142, 65), (97, 136, 63), + (86, 129, 61), (75, 123, 59), (64, 117, 58), (54, 112, 57), + (44, 107, 56), (35, 103, 56), (28, 101, 57), (23, 100, 59), + (18, 100, 62), (14, 100, 66), (11, 102, 71), (9, 104, 76), + (7, 106, 82), (5, 110, 87), (3, 113, 93), (1, 117, 99), + (0, 122, 106), (0, 128, 113), (0, 134, 121), (0, 142, 129), + (0, 149, 137), (1, 156, 145), (2, 162, 153), (3, 169, 161), + (4, 175, 168), (5, 181, 174), (6, 186, 180), (7, 191, 185), + (8, 196, 190), (9, 199, 194), (10, 202, 197), (11, 204, 198), + (12, 204, 199), (12, 204, 198), (13, 202, 196), (13, 199, 192), + (14, 195, 187), (13, 189, 180), (13, 184, 173), (12, 177, 164), + (11, 169, 155), (11, 161, 145), (10, 152, 134), (9, 143, 124), + (7, 134, 113), (6, 124, 102), (5, 115, 91), (4, 106, 81), + (3, 97, 71), (2, 89, 61), (2, 81, 53), (1, 74, 45) + ) + +); + +const CMapNames: array[0..700] of string = +( + '000_south-sea-bather', + '001_sky-flesh', + '002_blue-bather', + '003_no-name', + '004_pillows', + '005_mauve-splat', + '006_facial-treescape 6', + '007_fasion-bug', + '008_leafy-face', + '009_mouldy-sun', + '010_sunny-harvest', + '011_peach-tree', + '012_fire-dragon', + '013_ice-dragon', + '014_german-landscape', + '015_no-name', + '016_living-mud-bomb', + '017_cars', + '018_unhealthy-tan', + '019_daffodil', + '020_rose', + '021_healthy-skin', + '022_orange', + '023_white-ivy', + '024_summer-makeup', + '025_glow-buzz', + '026_deep-water', + '027_afternoon-beach', + '028_dim-beach', + '029_cloudy-brick', + '030_burning-wood', + '031_aquatic-garden', + '032_no-name', + '033_fall-quilt', + '034_night-blue-sky', + '035_shadow-iris', + '036_solid-sky', + '037_misty-field', + '038_wooden-highlight', + '039_jet-tundra', + '040_pastel-lime', + '041_hell', + '042_indian-coast', + '043_dentist-decor', + '044_greenland', + '045_purple-dress', + '046_no-name', + '047_spring-flora', + '048_andi', + '049_gig-o835', + '050_rie02', + '051_rie05', + '052_rie11', + '053_etretat.ppm', + '054_the-hollow-needle-at-etretat.ppm', + '055_rouen-cathedral-sunset.ppm', + '056_the-houses-of-parliament.ppm', + '057_starry-night.ppm', + '058_water-lilies-sunset.ppm', + '059_gogh.chambre-arles.ppm', + '060_gogh.entrance.ppm', + '061_gogh.the-night-cafe.ppm', + '062_gogh.vegetable-montmartre.ppm', + '063_matisse.bonheur-vivre.ppm', + '064_matisse.flowers.ppm', + '065_matisse.lecon-musique.ppm', + '066_modigliani.nude-caryatid.ppm', + '067_braque.instruments.ppm', + '068_calcoast09.ppm', + '069_dodge102.ppm', + '070_ernst.anti-pope.ppm', + '071_ernst.ubu-imperator.ppm', + '072_fighting-forms.ppm', + '073_fog25.ppm', + '074_geyser27.ppm', + '075_gris.josette.ppm', + '076_gris.landscape-ceret.ppm', + '077_kandinsky.comp-9.ppm', + '078_kandinsky.yellow-red-blue.ppm', + '079_klee.insula-dulcamara.ppm', + '080_nile.ppm', + '081_picasso.jfille-chevre.ppm', + '082_pollock.lavender-mist.ppm', + '083_yngpaint.ppm', + '084_cl-gold-orange-green from classlady1.ugr', + '085_cl-gold-rose', + '086_cl-lavender-purple-blues-black', + '087_cl-yellow_mixed-brown-gold', + '088_cl-dark_reds-white-grays', + '089_cl-gold-dark_reds-browns-blues', + '090_cl-golds-browns', + '091_cl-purples-browns-blues-tans', + '092_cl-oranges-browns-whites', + '093_cl-blues-greens-whites', + '094_cl-tans-yellows-browns', + '095_cl-golds-browns2', + '096_cl-pastels', + '097_multi_color_1 from ron1.ugr (classylady & ron)', + '098_oranges', + '099_multi_color_2', + '100_rw-yellow-orange', + '101_rw-multi-color-2', + '102_rw-blue-with-red', + '103_rw-blue-with-red-2', + '104_rw-blues-3', + '105_rw-reds-pinks-blues', + '106_rw-browns-greens-reds-bule', + '107_rw-browns-pinks-reds-blues', + '108_rw-reds-greens-blues-pinks-yellows-browns', + '109_rw-greens-light-to-dark', + '110_rw-blues-reds-purples', + '111_rw-multi-5', + '112_rw-blues-black-purple', + '113_rw-multi-colors-6', + '114_rw-multi-reds-oranges', + '115_rw-yellows-browns-goldish', + '116_rw-multi-blues-with-gray', + '117_rw-greens-multi', + '118_rw-browns-orange-yellow-with-blues', + '119_rw-reds-blues-greens-pinks', + '120_rw-reds-browns-golds-tans', + '121_dg009', + '122_dg016', + '123_dg031', + '124_dg085', + '125_dg086', + '126_dg089', + '127_Apophysis-040426-1crabgrass from pat phillips patrx.deviantart.com', + '128_Apophysis-040426-12bs1fl', + '129_Apophysis-040426-1cometnuc', + '130_Apophysis-040426-1passionscross', + '131_Apophysis-040426-1butterflyflower', + '132_Apophysis-040426-1Watcher', + '133_Apophysis-040426-1knotted', + '134_Apophysis-040426-1artdeco', + '135_Apophysis-040426-1expl_orange2a', + '136_Apophysis-040426-1heartFlowers', + '137_Apophysis-040426-1H-bird1g', + '138_Apophysis-040426-1Emergence2', + '139_Apophysis-040426-1Egg', + '140_Apophysis-040426-1PenEgg', + '141_Apophysis-040426-1kaosGothic', + '142_Apophysis-040426-1KQNova', + '143_Apophysis-040426-1kaosframe', + '144_Apophysis-040426-147KaosRing', + '145_Apophysis-040426-147Fighting_Fish', + '146_Apophysis-040426-147ReachingMoon', + '147_Apophysis-040426-163KaosScepter', + '148_Apophysis-040426-163KSphere', + '149_Apophysis-040426-163KInterseed', + '150_Apophysis-040426-163XmasFlwers', + '151_Apophysis-040426-163Shield', + '152_Apophysis-040426-163AlienFlwers', + '153_Apophysis-040426-163AlienFlwers4', + '154_Apophysis-040426-163butterflyflwer1', + '155_Apophysis-040426-163ButterflySherbert', + '156_Apophysis-040426-163BFlyGate4', + '157_Apophysis-040426-163BFlyGate4Inv', + '158_Apophysis-040426-163CeltCross', + '159_Apophysis-040426-163Egg4d', + '160_Apophysis-040426-163FlowerFerns', + '161_Apophysis-040426-163FlowerFernsInv', + '162_Apophysis-040426-163FlwrFernsInv', + '163_Apophysis-040426-163FloralCascade2', + '164_Apophysis-040426-163FlowerBurst', + '165_Apophysis-040426-163MaltesePurple', + '166_Apophysis-040426-163Mycelialg', + '167_Apophysis-040426-163MyceliaInv', + '168_Apophysis-040426-163MrryGRnd', + '169_Apophysis-040426-163SprngFlwrs', + '170_Apophysis-040426-163SprngFlwersInv', + '171_Apophysis-040426-163DemMask', + '172_Apophysis-040426-163ResurectTree', + '173_Apophysis-040426-163GldBlue', + '174_Apophysis-040426-163WrldBndr', + '175_Apophysis-040426-163GrnPrpl', + '176_Apophysis-040426-163SphPart2', + '177_Apophysis-040426-163StAmF', + '178_Apophysis-040426-163StCosOwl', + '179_Apophysis-040426-163StGenie', + '180_Apophysis-040426-163St', + '181_Apophysis-040426-163StSatAngel', + '182_Apophysis-040427-1knotted', + '183_Apophysis-040427-4AlngSpder', + '184_Apophysis-040427-4AlienFlwerBwl', + '185_Apophysis-040427-4AlienFlwrBwl_inv', + '186_Apophysis-040427-4AmusePrk', + '187_Apophysis-040427-4AmusePrkInv', + '188_Apophysis-040427-4AmythIceInv', + '189_Apophysis-040427-4AmythIce', + '190_Apophysis-040427-4AngOrchid', + '191_Apophysis-040427-4Leaves', + '192_Apophysis-040427-4Bdlnds', + '193_Apophysis-040427-4BnnySurp', + '194_Apophysis-040427-4BorgEY', + '195_Apophysis-040427-4BB4', + '196_Apophysis-040427-4BflyWindw2', + '197_Apophysis-040427-4BflyWndw3', + '198_Apophysis-040427-4ChalLghtDrknss', + '199_Apophysis-040427-4ChalicDrknsIce', + '200_Apophysis-040427-4CactusFlwer', + '201_Apophysis-040427-4ChrryBlssmT', + '202_Apophysis-040427-4ChrryBlssm2', + '203_Apophysis-040427-4CircAmbr', + '204_Apophysis-040427-4CsmcOwl', + '205_Apophysis-040427-4DblBeetle', + '206_Apophysis-040427-4DrkMantis', + '207_Apophysis-040427-4HolidyBull', + '208_Apophysis-040427-4DrkFlorCnpy', + '209_Apophysis-040427-4DethstrDemis', + '210_Apophysis-040427-4DethstrDems', + '211_Apophysis-040427-4DeerDemMsk', + '212_Apophysis-040427-4CrouchDragn', + '213_Apophysis-040427-4CopprMapleleaf', + '214_Apophysis-040427-4Circulations', + '215_Apophysis-040427-4DmnContaind', + '216_Apophysis-040427-4DmnCntndWP', + '217_Apophysis-040427-4DmnDimensn', + '218_Apophysis-040427-4SatnFlorlSwag', + '219_Apophysis-040427-4DDragHeart', + '220_Apophysis-040427-4DimesPathsE', + '221_Apophysis-040427-4DimensPathsE2', + '222_Apophysis-040427-4DimensPathE2', + '223_Apophysis-040427-4Doodles', + '224_Apophysis-040427-4Doodles2', + '225_Apophysis-040427-4doodles3', + '226_Apophysis-040427-4Doodle3inv', + '227_Apophysis-040427-6DoublEagles2', + '228_Apophysis-040427-6Equinox', + '229_Apophysis-040427-6Equinox2', + '230_Apophysis-040427-6BluBrd', + '231_Apophysis-040427-6BluBrdInv', + '232_Apophysis-040427-6FaerieKng', + '233_Apophysis-040427-6FireDemnOrch', + '234_Apophysis-040427-6CsmcLottoWhl', + '235_Apophysis-040427-6DreamFaeriRlm', + '236_Apophysis-040427-6EyeUniv', + '237_Apophysis-040427-6FaeriRob', + '238_Apophysis-040427-6FaeriRob2', + '239_Apophysis-040427-6FaeriRobDet', + '240_Apophysis-040427-6FlakWhorls', + '241_Apophysis-040427-11FlarCelebrat', + '242_Apophysis-040427-11SpacTrees', + '243_Apophysis-040427-11FloralQult', + '244_Apophysis-040427-20FlwrFrnsBFly', + '245_Apophysis-040427-24FracrameE', + '246_Apophysis-040427-24FNouveau', + '247_Apophysis-040427-24GuardFaeriR', + '248_Apophysis-040427-24GoldenRays', + '249_Apophysis-040427-24HunterSunset', + '250_Apophysis-040427-25IntoWeave', + '251_Apophysis-040427-26AlienMind', + '252_Apophysis-040427-26ISpher4', + '253_Apophysis-040427-26ISph2', + '254_Apophysis-040427-26ISph11', + '255_Apophysis-040427-43HeartFlwr', + '256_Apophysis-040427-43JunglThron', + '257_Apophysis-040427-44jawa', + '258_Apophysis-040427-51KaosGrn', + '259_Apophysis-040427-51KaosFish', + '260_Apophysis-040427-51KKlown', + '261_Apophysis-040427-51KaosEgg', + '262_Apophysis-040427-51LavLace', + '263_Apophysis-040427-51mudding', + '264_Apophysis-040427-51pane;', + '265_Apophysis-040427-51RiftAO', + '266_Apophysis-040427-51ylwAlien', + '267_Apophysis-040427-51elecforest', + '268_Apophysis-040427-51ReachMoon', + '269_Apophysis-040427-51satPhlox', + '270_Apophysis-040427-51SnikRchg', + '271_Apophysis-040427-51SmwhrDream', + '272_Apophysis-040427-51eyepuzzl', + '273_Apophysis-040427-51SpherInBlm', + '274_Apophysis-040427-51SunrisSpacTim', + '275_Apophysis-040427-51synaps', + '276_Apophysis-040427-51StPeacocl', + '277_Apophysis-040427-51TmplWatrs2', + '278_Apophysis-040427-51TeddyScare', + '279_Apophysis-040427-51kaosGardenr', + '280_Apophysis-040427-51Thatway4', + '281_Apophysis-040427-51ThatwayGrn', + '282_Apophysis-040427-51TreeLife1', + '283_Apophysis-040427-51TreeLife', + '284_Apophysis-040427-51triflwr', + '285_Apophysis-040427-51mitosis', + '286_Apophysis-040427-51triflwer', + '287_Apophysis-040427-51yggF', + '288_Apophysis-040427-51Gwrap', + '289_Apophysis-040428-1Gradient1', + '290_Apophysis-040428-3Gradient2', + '291_Apophysis-040602-1', + '292_Apophysis-040531-100figurine_2abcd', + '293_Apo-040627-1_chickadee_pix', + '294_2u0026t.jpg from bTomchek', + '295_2u0007t.jpg', + '296_2u0010t.jpg', + '297_2u0015t.jpg', + '298_2u0017pp1t.jpg', + '299_2u0017t.jpg', + '300_2u0018t.jpg', + '301_2u0020pp1t.jpg', + '302_2u0020t.jpg', + '303_2u0024t.jpg', + '304_gradient0000.jpg', + '305_0t0507.jpg', + '306_0t0524.jpg', + '307_0t0533.jpg', + '308_0u0075.jpg', + '309_0u0298.jpg', + '310_0u0298pp1.jpg', + '311_0u0303.jpg', + '312_0u0333.jpg', + '313_0u0752.jpg', + '314_0u0768.jpg', + '315_0u0795.jpg', + '316_1u0214.jpg', + '317_1u0215.jpg', + '318_1u0216.jpg', + '319_1u0216pp1.jpg', + '320_3m0001.jpg', + '321_3m0004.jpg', + '322_3m0005.jpg', + '323_3m0006.jpg', + '324_3m0007.jpg', + '325_3m0008.jpg', + '326_3m0009.jpg', + '327_3m0010.jpg', + '328_3m0011.jpg', + '329_3m0012.jpg', + '330_3m0013.jpg', + '331_3m0014.jpg', + '332_3m0015.jpg', + '333_3m0016.jpg', + '334_3m0018.jpg', + '335_4u0002.jpg', + '336_4u0003.jpg', + '337_4u0004.jpg', + '338_4u0005.jpg', + '339_4u0006.jpg', + '340_4u0007.jpg', + '341_4u0008.jpg', + '342_4u0009.jpg', + '343_4u0009b.jpg', + '344_4u0010.jpg', + '345_4u0011.jpg', + '346_4u0012.jpg', + '347_4u0013.jpg', + '348_4u0019.jpg', + '349_4u0022.jpg', + '350_k2u0217.jpg', + '351_ku0213.jpg', + '352_ku0215.jpg', + '353_s00026.jpg', + '354_s00043.jpg', + '355_s00118.jpg', + '356_s00138.jpg', + '357_s00149.jpg', + '358_vchira_0001.jpg', + '359_vchira_0003.jpg', + '360_vchira_0012.jpg', + '361_vchira_0013.jpg', + '362_vchira_0014.jpg', + '363_vchira_0015.jpg', + '364_vchira_17.jpg', + '365_vchira_18pp1.jpg', + '366_vchira_19.jpg', + '367_vchira_28.jpg', + '368_vchira_2pp1.jpg', + '369_00017', + '370_040208-115', + '371_040221-00', + '372_040221-11', + '373_040221-12', + '374_040221-13', + '375_040221-14', + '376_040221-19', + '377_040221-2', + '378_040221-21', + '379_040221-22', + '380_040221-23', + '381_040221-24', + '382_040221-25', + '383_040221-26', + '384_040221-27', + '385_040221-28', + '386_040221-29', + '387_040221-30', + '388_040221-31', + '389_040221-32', + '390_040221-33', + '391_040221-34', + '392_040221-35', + '393_040221-36', + '394_040221-37', + '395_040221-38', + '396_040221-39', + '397_040221-40', + '398_040221-41', + '399_040221-42', + '400_040221-43', + '401_040221-44', + '402_040221-45', + '403_040221-46', + '404_040221-47', + '405_040221-48', + '406_040221-49', + '407_040221-50', + '408_040221-51', + '409_040221-52', + '410_040221-53', + '411_040221-54', + '412_040221-55', + '413_040221-56', + '414_040221-57', + '415_040221-58', + '416_040221-59', + '417_040221-60', + '418_040221-61', + '419_040221-62', + '420_040221-63', + '421_040221-64', + '422_040221-71', + '423_040221-74', + '424_040221-78', + '425_040221-80', + '426_040221-81', + '427_040221-84', + '428_040221-85', + '429_040221-86', + '430_040221-88', + '431_040221-89', + '432_040221-90', + '433_040221-91', + '434_040221-92', + '435_040221-93', + '436_040221-94', + '437_040221-95', + '438_040221-96', + '439_040221-97', + '440_040221-98', + '441_040221-99', + '442_040222', + '443_040222-00', + '444_040222-01', + '445_040222-02', + '446_040222-03', + '447_040222-05', + '448_040222-06', + '449_040222-07', + '450_040222-08', + '451_040222-09', + '452_040222-10', + '453_040222-11', + '454_040222-12', + '455_040222-13', + '456_040222-15', + '457_040222-16', + '458_040222-17', + '459_040222-18', + '460_040222-19', + '461_040222-20', + '462_040222-21', + '463_040222-22', + '464_040222-23', + '465_040222-24', + '466_040222-25', + '467_040222-26', + '468_040222-27', + '469_040222-28', + '470_040222-29', + '471_040223', + '472_040224', + '473_040225', + '474_040226', + '475_040227', + '476_040228', + '477_10000', + '478_Apophysis-040208-115d', + '479_Apophysis-040208-115e', + '480_Apophysis-040208-115g', + '481_Apophysis-040208-115h', + '482_Apophysis-040208-115i', + '483_Apophysis-040208-115j', + '484_Apophysis-040208-115k', + '485_A_Bit_Confused', + '486_Afternoon_Shadows', + '487_Air', + '488_Angora', + '489_Antique', + '490_Arizona', + '491_Autumn_Garden', + '492_Autumn_Leaves', + '493_Autumn_Mountains', + '494_Awakening', + '495_Baby', + '496_Banana', + '497_Beach', + '498_Beautiful', + '499_Before_Dawn', + '500_Beginning_to_Thaw', + '501_Beige', + '502_Berry_Bush', + '503_Biology_Class', + '504_Birthday_Party', + '505_Bistro', + '506_Blossoms', + '507_Blue_Velvet', + '508_Bluebells', + '509_Blush', + '510_Bluster', + '511_Boquet_of_Roses', + '512_Brushed_Silver', + '513_Bubblegum', + '514_California', + '515_Canyon', + '516_Carnations', + '517_Carnival', + '518_Carpenter', + '519_Cellist', + '520_Cherry', + '521_Circus', + '522_City_Street', + '523_Clash', + '524_Clouds', + '525_Copper', + '526_Coral', + '527_Cotton_Flower', + '528_Country_Garden', + '529_Creamsicle', + '530_Cricket_Music', + '531_Dark_Rainbow', + '532_Dark_Rose', + '533_Dark_Turquoise', + '534_Dark_Waters', + '535_Darkness', + '536_Davinci', + '537_Daylight_Fading', + '538_Dinosaurs', + '539_Dragon', + '540_Dust_Bunny', + '541_Dynasty', + '542_Easter', + '543_Easter_2', + '544_Easter_3', + '545_Egg_Hunt', + '546_Elements', + '547_Embers', + '548_Etomchek-040328-005', + '549_Etomchek-040328-006', + '550_Etomchek-040328-007', + '551_Etomchek-040328-008', + '552_Etomchek-040328-009', + '553_Etomchek-040328-010', + '554_Etomchek-040328-011', + '555_Evening_Sunshine', + '556_Evensong', + '557_Exceding_Expectations', + '558_Explosion', + '559_Faded_Denim', + '560_Fading_Away', + '561_Fiery_Sky', + '562_Fiesta', + '563_First_Love', + '564_Flame', + '565_Flying_a_Kite', + '566_Foamy_Waves', + '567_For_Lenora', + '568_For_Stacy', + '569_Forest', + '570_Frivolous', + '571_Fun_Stuff', + '572_Getting_a_Tan', + '573_gipper', + '574_Glade', + '575_Glory', + '576_Gold_and_Blue', + '577_Golden', + '578_Golden_Green', + '579_Goldenrod', + '580_Grape', + '581_Lemon_Grass', + '582_Magenta_and_Teal', + '583_Mahogany', + '584_Marina', + '585_Meadow', + '586_Mermaid', + '587_Mesmerize', + '588_Midnight_Wave', + '589_Mint', + '590_Mistic', + '591_Mixed_Berry', + '592_More_Blue', + '593_Morning_Glories_at_Night', + '594_Moss', + '595_Moss2', + '596_Motel_Decor', + '597_Muddy', + '598_Muddy_2', + '599_Muted_Rainbow', + '600_Mystery', + '601_Neon', + '602_Neon_Purple', + '603_Night_Flower', + '604_Night_Reeds', + '605_No_Clue', + '606_Nonsense', + '607_Oak_Tree', + '608_Ocean_Mist', + '609_Paige', + '610_Paris', + '611_Parrot', + '612_Pastel_Lime', + '613_Peace', + '614_Persia', + '615_Persia_2', + '616_Persia_3', + '617_Pink', + '618_Pollen', + '619_Poppies', + '620_Produce_Department', + '621_Purple', + '622_Queen_Anne', + '623_Quiet', + '624_Rainbow_Sprinkles', + '625_Rainforest', + '626_Rainy_Day_in_Spring', + '627_Rainy_Forset', + '628_Red_Light', + '629_Riddle', + '630_Riverside', + '631_Rose_Bush', + '632_Rusted', + '633_Sachet', + '634_Sage', + '635_Saturday_Morning', + '636_Scattered_Petals', + '637_Sea_Mist', + '638_Secret', + '639_Serenity', + '640_Serpent', + '641_Sharp', + '642_Shy_Violets', + '643_Singe', + '644_Slate', + '645_Slightly_Messy', + '646_Smog', + '647_Sno_and_Shadows', + '648_Snowy_Field', + '649_Snuggle', + '650_Soap_Bubble', + '651_Sophia', + '652_Strawberries', + '653_Summer', + '654_Summer_Fire', + '655_Summer_Skies', + '656_Summer_Tulips', + '657_Sunbathing', + '658_Sunny_Field', + '659_Sunset', + '660_Surfer', + '661_Tequila', + '662_Thistle', + '663_Tribal', + '664_Trippy', + '665_Tropic', + '666_True_Blue', + '667_Tryst', + '668_Tumbleweed', + '669_Type_AB_Positive', + '670_Underwater_Day', + '671_Venice', + '672_Victoria', + '673_Violet', + '674_Violet_Fog', + '675_Watermelon', + '676_Whisp', + '677_Whisper', + '678_Wintergrass', + '679_Wooden', + '680_Wooden_2', + '681_Wooden_3', + '682_Woodland', + '683_Yellow_Silk', + '684_Zinfandel', + '685_040412', + '686_040412-000', + '687_040412-001', + '688_040412-002', + '689_040412-005', + '690_040412-006', + '691_040412-007', + '692_040412-008', + '693_040412-010', + '694_040412-011', + '695_040412-012', + '696_040412-013', + '697_040412-014', + '698_040412-015', + '699_040412-016', + '700_040412-017' +); + +implementation + +end. + + diff --git a/Core/BaseVariation.pas b/Core/BaseVariation.pas new file mode 100644 index 0000000..f755ae0 --- /dev/null +++ b/Core/BaseVariation.pas @@ -0,0 +1,210 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit BaseVariation; + +interface + +type + TCalcFunction = procedure of object; + +type + TBaseVariation = class + + protected + procedure CalcFunction; virtual; abstract; + + public + vvar: double; + FTx, FTy: ^double; + FPx, FPy: ^double; + FTz, FPz: ^double; + + // more params :) + color : ^double; + a, b, c, d, e, f : double; + + class function GetName: string; virtual; abstract; + class function GetInstance: TBaseVariation; virtual; abstract; + + function GetNrVariables: integer; virtual; + function GetVariableNameAt(const Index: integer): string; virtual; + + function GetVariable(const Name: string; var Value: double): boolean; virtual; + function SetVariable(const Name: string; var Value: double): boolean; virtual; + function ResetVariable(const Name: string): boolean; virtual; + + function GetVariableStr(const Name: string): string; virtual; + function SetVariableStr(const Name: string; var strValue: string): boolean; virtual; + + procedure Prepare; virtual; + + procedure GetCalcFunction(var Delphi_Suxx: TCalcFunction); virtual; + end; + + TBaseVariationClass = class of TBaseVariation; + +type + TVariationLoader = class + public + Supports3D, SupportsDC : boolean; + + function GetName: string; virtual; abstract; + function GetInstance: TBaseVariation; virtual; abstract; + function GetNrVariables: integer; virtual; abstract; + function GetVariableNameAt(const Index: integer): string; virtual; abstract; + end; + +type + TVariationClassLoader = class (TVariationLoader) + public + constructor Create(varClass : TBaseVariationClass); + function GetName: string; override; + function GetInstance: TBaseVariation; override; + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + private + VariationClass : TBaseVariationClass; + end; + +function fmod(x, y: double) : double; + +implementation + +uses SysUtils; + +function fmod(x, y: double) : double; +begin + Result := frac(x / y) * y; +end; + +{ TBaseVariation } + +/////////////////////////////////////////////////////////////////////////////// +function TBaseVariation.GetNrVariables: integer; +begin + Result := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TBaseVariation.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +function TBaseVariation.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +function TBaseVariation.ResetVariable(const Name: string): boolean; +var + zero: double; +begin + zero := 0; + Result := SetVariable(Name, zero); +end; + +/////////////////////////////////////////////////////////////////////////////// +function TBaseVariation.GetVariableStr(const Name: string): string; +var + value: double; +begin + if GetVariable(Name, value) then + Result := Format('%.6g', [value]) + else + Result := ''; +end; + +function TBaseVariation.SetVariableStr(const Name: string; var strValue: string): boolean; +var + v, oldv: double; +begin + if GetVariable(Name, oldv) then begin + try + v := StrToFloat(strValue); + SetVariable(Name, v); + except + v := oldv; + end; + strValue := Format('%.6g', [v]); + Result := true; + end + else Result := false; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TBaseVariation.GetVariableNameAt(const Index: integer): string; +begin + Result := '' +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseVariation.Prepare; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseVariation.GetCalcFunction(var Delphi_Suxx: TCalcFunction); +begin + Delphi_Suxx := CalcFunction; // -X- lol +end; + +/////////////////////////////////////////////////////////////////////////////// +{ TVariationClassLoader } + +constructor TVariationClassLoader.Create(varClass : TBaseVariationClass); +begin + VariationClass := varClass; +end; + +function TVariationClassLoader.GetName: string; +begin + Result := VariationClass.GetName(); +end; + +function TVariationClassLoader.GetInstance: TBaseVariation; +begin + Result := VariationClass.GetInstance(); +end; + +function TVariationClassLoader.GetNrVariables: integer; +var + hack : TBaseVariation; +begin + hack := GetInstance(); + Result := hack.GetNrVariables(); + hack.Free(); +end; + +function TVariationClassLoader.GetVariableNameAt(const Index: integer): string; +var + hack : TBaseVariation; +begin + hack := GetInstance(); + Result := hack.GetVariableNameAt(Index); + hack.Free(); +end; + +end. diff --git a/Core/Bezier.pas b/Core/Bezier.pas new file mode 100644 index 0000000..c6adfb1 --- /dev/null +++ b/Core/Bezier.pas @@ -0,0 +1,94 @@ +unit Bezier; + +interface + +uses Math; + + +type + BezierPoint = record + x, y: double; + end; + BezierRect = record + x0, y0, x1, y1: double; + end; + + BezierPoints = array [0..3] of BezierPoint; + BezierWeights = array [0..3] of double; + +procedure BezierCopy(src: BezierPoints; var tgt: BezierPoints); +procedure BezierSetRect(var points: BezierPoints; flip: boolean; rect: BezierRect); +procedure BezierUnsetRect(var points: BezierPoints; flip: boolean; rect: BezierRect); + +procedure BezierSolve(t: double; src: BezierPoints; w: BezierWeights; var solution: BezierPoint); +function BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double; + +implementation + procedure BezierCopy(src: BezierPoints; var tgt: BezierPoints); + var + i, n: integer; + begin + n := Length(src); + for i := 0 to n - 1 do + tgt[i] := src[i]; + end; + procedure BezierSetRect(var points: BezierPoints; flip: boolean; rect: BezierRect); + var + i, n: integer; + f: double; + begin + n := Length(points); + for i := 0 to n - 1 do + begin + if (flip) then f := 1 - points[i].y + else f := points[i].y; + + points[i].x := points[i].x * (rect.x1 - rect.x0) + rect.x0; + points[i].y := f * (rect.y1 - rect.y0) + rect.y0; + end; + end; + procedure BezierUnsetRect(var points: BezierPoints; flip: boolean; rect: BezierRect); + var + i, n: integer; + f: double; + begin + if ((rect.x1 - rect.x0) = 0) or ((rect.y1 - rect.y0) = 0) then Exit; + + n := Length(points); + for i := 0 to n - 1 do + begin + points[i].x := (points[i].x - rect.x0) / (rect.x1 - rect.x0); + points[i].y := (points[i].y - rect.y0) / (rect.y1 - rect.y0); + + if (flip) then points[i].y := 1 - points[i].y; + end; + end; + + procedure BezierSolve(t: double; src: BezierPoints; w: BezierWeights; var solution: BezierPoint); + var + s, s2, s3, t2, t3, nom_x, nom_y, denom: double; + begin + s := 1 - t; + s2 := s * s; s3 := s * s * s; + t2 := t * t; t3 := t * t * t; + + nom_x := w[0] * s3 * src[0].x + w[1] * s2 * 3 * t * src[1].x + + w[2] * s * 3 * t2 * src[2].x + w[3] * t3 * src[3].x; + nom_y := w[0] * s3 * src[0].y + w[1] * s2 * 3 * t * src[1].y + + w[2] * s * 3 * t2 * src[2].y + w[3] * t3 * src[3].y; + denom := w[0] * s3 + w[1] * s2 * 3 * t + w[2] * s * 3 * t2 + w[3] * t3; + + if (IsNaN(nom_x)) or (IsNaN(nom_y)) or (IsNaN(denom)) then Exit; + if denom = 0 then Exit; + + solution.x := nom_x / denom; + solution.y := nom_y / denom; + end; + function BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double; + var + p: BezierPoint; + begin + BezierSolve(t, src, w, p); + Result := p.y; + end; +end. diff --git a/Core/Chaotica.pas b/Core/Chaotica.pas new file mode 100644 index 0000000..8576dd8 --- /dev/null +++ b/Core/Chaotica.pas @@ -0,0 +1,268 @@ +unit Chaotica; + +interface + +uses Global, RegularExpressionsCore, RegexHelper, Classes, SysUtils, XFormMan, Windows, + ShellAPI, Forms, ControlPoint, Translation; + +function C_GetPathOf(filename: string; usex64: boolean): string; +function C_SupportsDllPlugins(usex64: boolean): boolean; +function C_IsDllPluginBlacklisted(filename: string; usex64: boolean): boolean; +function C_IsVariationNative(name: string; usex64: boolean): boolean; +function C_IsDllPluginInstalled(filename: string): boolean; + +procedure C_SyncDllPlugins; +procedure C_InstallVariation(name: string); +procedure C_ExecuteChaotica(flamexml: string; plugins: TStringList; usex64: boolean); + +implementation + +uses Main; + +function CheckX64: Boolean; +var + SEInfo: TShellExecuteInfo; + ExitCode: DWORD; + ExecuteFile, ParamString, StartInString: string; +begin + {$ifdef Apo7X64} + Result := true; + exit; + {$endif} + + ExecuteFile:=ExtractFilePath(Application.ExeName)+'chk64.exe'; + FillChar(SEInfo, SizeOf(SEInfo), 0); + SEInfo.cbSize := SizeOf(TShellExecuteInfo); + + with SEInfo do begin + fMask := SEE_MASK_NOCLOSEPROCESS; + Wnd := Application.Handle; + lpFile := PChar(ExecuteFile) ; + nShow := SW_SHOWNORMAL; + end; + + if ShellExecuteEx(@SEInfo) then + begin + repeat + Application.ProcessMessages; + GetExitCodeProcess(SEInfo.hProcess, ExitCode); + until (ExitCode <> STILL_ACTIVE) or Application.Terminated; + Result := (ExitCode = 0); + end else begin + Result := false; + end; +end; + +function C_GetPathOf(filename: string; usex64: boolean): string; +var + subf: string; +begin + if usex64 then subf := '64bit' + else subf := '32bit'; + Result := ChaoticaPath + '\' + subf + '\' + filename; +end; + +function C_SupportsDllPlugins(usex64: boolean): boolean; +const + re_root : string = '.*?'; + re_attrib : string = 'supports_dll_plugins="(.*?)"'; +var + xml_file : TStringList; + xml_text, attrib, value : string; +begin + if usex64 then begin + Result := false; + Exit; + end; + + xml_file := TStringList.Create; + xml_file.LoadFromFile(C_GetPathOf('variation_compatibility.xml', false)); + xml_text := xml_file.Text; + xml_file.Destroy; + + attrib := GetStringPart(xml_text, re_root, 1, 'supports_dll_plugins="false"'); + value := GetStringPart(attrib, re_attrib, 1, 'false'); + + Result := (value = 'true'); +end; + +function C_IsDllPluginBlacklisted(filename: string; usex64: boolean): boolean; +var + i: integer; + blacklist: TStringList; +begin + blacklist := TStringList.Create; + blacklist.LoadFromFile(C_GetPathOf('plugin_dll_blacklist.txt', usex64)); + + for i := 0 to blacklist.Count - 1 do begin + if LowerCase(filename) = LowerCase(blacklist.Strings[i]) then begin + Result := true; + blacklist.Destroy; + Exit; + end; + end; + + blacklist.Destroy; + Result := false; +end; + +function C_IsVariationNative(name: string; usex64: boolean): boolean; +const + re_root : string = '(.*?)'; + re_var : string = ''; +var + xml, var_name : string; + xml_file : TStringList; + find_var : TPerlRegEx; + found_var : boolean; +begin + + xml_file := TStringList.Create; + xml_file.LoadFromFile(C_GetPathOf('variation_compatibility.xml', false)); + xml := xml_file.Text; + xml_file.Destroy; + + find_var := TPerlRegEx.Create; + find_var.RegEx := Utf8String(re_var); + find_var.Options := [preSingleLine, preCaseless]; + find_var.Subject := Utf8String(GetStringPart(xml, re_root, 1, '')); + found_var := find_var.Match; + + while found_var do begin + var_name := String(find_var.Groups[1]); + found_var := find_var.MatchAgain; + + if LowerCase(name) = var_name then begin + find_var.Destroy; + Result := true; + Exit; + end; + end; + + find_var.Destroy; + Result := false; +end; + +function C_IsDllPluginInstalled(filename: string): boolean; +var + path : string; +begin + path := C_GetPathOf('plugins\' + filename, false); + Result := FileExists(path); +end; + +//////////////////////////////////////////////////////////////////// + +procedure C_InstallVariation(name: string); +var + filename: string; +begin + filename := GetFileNameOfVariation(name); + + if (filename = '') then Exit; + if C_IsDllPluginInstalled(filename) then Exit; + + CopyFile(PCHAR(filename), PCHAR(C_GetPathOf('plugins\' + + ExtractFileName(filename), false)), false); +end; + +procedure C_SyncDllPlugins; +var + src_dir: string; + tgt_dir: string; + + searchResult: TSearchRec; +begin + src_dir := PluginPath; + tgt_dir := C_GetPathOf('Plugins', false); + + if (not DirectoryExists(src_dir)) then Exit; + if (not DirectoryExists(tgt_dir)) then Exit; + + // First clear all plugins on Chaotica side + if FindFirst(tgt_dir + '\*.dll', faAnyFile, searchResult) = 0 then + begin + repeat + DeleteFile(PCHAR(tgt_dir + '\' + searchResult.Name)) ; + until (FindNext(searchResult) <> 0); + SysUtils.FindClose(searchResult); + end; + + // Then copy all plugins from Apophysis to Chaotica + if FindFirst(src_dir + '*.dll', faAnyFile, searchResult) = 0 then + begin + repeat + if not C_IsDllPluginBlacklisted(searchResult.Name, false) + then CopyFile( + PCHAR(src_dir + '\' + searchResult.Name), + PCHAR(tgt_dir + '\' + searchResult.Name), + false); + until (FindNext(searchResult) <> 0); + SysUtils.FindClose(searchResult); + end; +end; + +procedure C_ExecuteChaotica(flamexml: string; plugins: TStringList; usex64: boolean); +var + i: integer; + name, fname: string; + fails: TStringList; + txt: TStringList; + fin_usex64: boolean; +begin + fails := TStringList.Create; + + {$ifdef Apo7X64} + fin_usex64 := true; + {$else} + fin_usex64 := usex64 and CheckX64; + for i := 0 to plugins.Count - 1 do begin + name := GetFileNameOfVariation(plugins.Strings[i]); + if (name = '') then name := plugins.Strings[i]; + fin_usex64 := fin_usex64 and C_IsVariationNative(name, usex64); + end; + + for i := 0 to plugins.Count - 1 do begin + name := GetFileNameOfVariation(plugins.Strings[i]); + if (name = '') then name := plugins.Strings[i]; // assume built-in + + if not C_IsVariationNative(name, fin_usex64) then begin // not native -> try install + if C_SupportsDllPlugins(fin_usex64) then // dll unsupported -> fail + fails.Add(plugins.Strings[i]) + else if C_IsDllPluginBlacklisted(name, fin_usex64) then // dll supported and blacklisted -> fail + fails.Add(plugins.Strings[i]) + ;//else C_InstallVariation(plugins.Strings[i]); // dll supported and not blacklisted -> install + // ^^^ this is done on Apophysis startup now! + end; + end; + {$endif} + + name := C_GetPathOf('chaotica.exe', fin_usex64); + if (not FileExists(name)) then begin + messagebox(0, PCHAR(TextByKey('main-status-nochaotica')), + PCHAR('Apophysis 7X'), MB_ICONHAND); + Exit; + end; + + if (fails.Count > 0) then begin + messagebox(0, PCHAR(TextByKey('main-status-oldchaotica')), + PCHAR('Apophysis 7X'), MB_ICONHAND or MB_OK); + end; + + fname := GetEnvironmentVariable('TEMP') + '\chaotica_export.flame'; + txt := TStringList.Create; + + txt.Text := flamexml; + txt.SaveToFile(fname); + + txt.Destroy; + fails.Destroy; + + //if fin_usex64 then MessageBox(0, PCHAR('DBG:x64'), PCHAR(''), MB_OK) + //else MessageBox(0, PCHAR('DBG:x86'), PCHAR(''), MB_OK) ; + + ShellExecute(application.handle, PChar('open'), pchar(name), + PChar('"' + fname + '"'), PChar(ExtractFilePath(name)), SW_SHOWNORMAL); +end; + +end. diff --git a/Core/Global.pas b/Core/Global.pas new file mode 100644 index 0000000..260ae0f --- /dev/null +++ b/Core/Global.pas @@ -0,0 +1,689 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit Global; + +interface + +uses + Windows, SysUtils, Classes, SyncObjs, Controls, Graphics, Math, + cmap, ControlPoint, Xform, CommDlg; + +type + EFormatInvalid = class(Exception); + +{ Weight manipulation } +{ Triangle transformations } +function triangle_area(t: TTriangle): double; +function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean; +function line_dist(x, y, x1, y1, x2, y2: double): double; +function dist(x1, y1, x2, y2: double): double; +{ Parsing functions } +function GetVal(token: string): string; +function ReplaceTabs(str: string): string; +{ Palette and gradient functions } +//function GetGradient(FileName, Entry: string): string; +{ Misc } +function det(a, b, c, d: double): double; +function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double; + var a, b, e: double): double; +function OpenSaveFileDialog(Parent: TWinControl; + const DefExt, + Filter, + InitialDir, + Title: string; + var FileName: string; + MustExist, + OverwritePrompt, + NoChangeDir, + DoOpen: Boolean): Boolean; +procedure LoadThumbnailPlaceholder(ThumbnailSize : integer); +function GetEnvVarValue(const VarName: string): string; + + +const + APP_NAME: string = 'Apophysis 7x'; + {$ifdef Apo7X64} + APP_BUILD: string = '64 bit'; + {$else} + APP_BUILD: string = '32 bit'; + {$endif} + MAX_TRANSFORMS: integer = 100; + prefilter_white: integer = 1024; + eps: double = 1E-10; + White_level = 200; + clyellow1 = TColor($17FCFF); + clplum2 = TColor($ECA9E6); + clSlateGray = TColor($837365); + FT_BMP = 1; FT_PNG = 2; FT_JPG = 3; + +const + crEditArrow = 20; + crEditMove = 21; + crEditRotate = 22; + crEditScale = 23; + +const + SingleBuffer : boolean = + {$ifdef Apo7X64} + false + {$else} + true + {$endif}; + +var + MainSeed: integer; + MainTriangles: TTriangles; + Transforms: integer; // Count of Tranforms + EnableFinalXform: boolean; + AppPath: string; // Path of applicatio file + OpenFile: string; // Name of currently open file + CanDrawOnResize: boolean; + PreserveWeights: boolean; + AlwaysCreateBlankFlame : boolean; + StartupCheckForUpdates : boolean; + TBWidth1 : integer; + TBWidth2 : integer; + TBWidth3 : integer; + TBWidth4 : integer; + TBWidth5 : integer; + ThumbnailPlaceholder : TBitmap; + WarnOnMissingPlugin : boolean; + EmbedThumbnails : boolean; + LanguageFile : string; + AvailableLanguages : TStringList; + PluginPath : string; + + { UPR Options } + + UPRSampleDensity: integer; + UPRFilterRadius: double; + UPROversample: integer; + UPRAdjustDensity: boolean; + UPRColoringIdent: string; + UPRColoringFile: string; + UPRFormulaIdent: string; + UPRFormulaFile: string; + UPRWidth: Integer; + UPRHeight: Integer; + ImageFolder: string; + UPRPath: string; // Name and folder of last UPR file + cmap_index: integer; // Index to current gradient + Variation: TVariation; // Current variation + NumTries, TryLength: integer; // Settings for smooth palette + SmoothPaletteFile: string; + + { Editor } + + UseFlameBackground, UseTransformColors: boolean; + HelpersEnabled: boolean; + EditorBkgColor, ReferenceTriangleColor: integer; + GridColor1, GridColor2, HelpersColor: integer; + ExtEditEnabled, TransformAxisLock, RebuildXaosLinks: boolean; + ShowAllXforms: boolean; + EditorPreviewTransparency: integer; + EnableEditorPreview: boolean; + + { Display } + + defSampleDensity, defPreviewDensity: Double; + defGamma, defBrightness, defVibrancy, + defFilterRadius, defGammaThreshold: Double; + defOversample: integer; + + { Render } + + renderDensity, renderFilterRadius: double; + renderOversample, renderWidth, renderHeight: integer; + renderBitsPerSample: integer; + renderPath: string; + JPEGQuality: integer; + renderFileFormat: integer; + InternalBitsPerSample: integer; + + NrTreads: Integer; + UseNrThreads: integer; + + PNGTransparency: integer; + ShowTransparency: boolean; + + MainPreviewScale: double; + ExtendMainPreview: boolean; + + StoreEXIF : boolean; + StoreParamsEXIF : boolean; + ExifAuthor : string; + + { Defaults } + + LastOpenFile: string; + LastOpenFileEntry: integer; + RememberLastOpenFile: boolean; + UseSmallThumbnails: boolean; + ClassicListMode: boolean; + ConfirmDelete: boolean; // Flag confirmation of entry deletion + OldPaletteFormat: boolean; + ConfirmExit: boolean; + ConfirmStopRender: boolean; + SavePath, SmoothPalettePath: string; + RandomPrefix, RandomDate: string; + RandomIndex: integer; + FlameFile, GradientFile, GradientEntry, FlameEntry: string; + ParamFolder: string; + prevLowQuality, prevMediumQuality, prevHighQuality: double; + defSmoothPaletteFile: string; + BrowserPath: string; // Stored path of browser open dialog + EditPrevQual, MutatePrevQual, AdjustPrevQual: Integer; + randMinTransforms, randMaxTransforms: integer; + mutantMinTransforms, mutantMaxTransforms: integer; + KeepBackground: boolean; + randGradient: Integer; + randGradientFile: string; + defFlameFile: string; + + PlaySoundOnRenderComplete: boolean; + RenderCompleteSoundFile: string; + + SaveIncompleteRenders: boolean; + ShowRenderStats: boolean; + LowerRenderPriority: boolean; + + SymmetryType: integer; + SymmetryOrder: integer; + SymmetryNVars: integer; + Variations: array of boolean; + //VariationOptions: int64; + + MainForm_RotationMode: integer; + PreserveQuality: boolean; + + { For random gradients } + + MinNodes, MaxNodes, MinHue, MaxHue, MinSat, MaxSat, MinLum, MaxLum: integer; + //ReferenceMode: integer; + BatchSize: Integer; + Compatibility: integer; //0 = original, 1 = Drave's + Favorites: TStringList; + Script: string; + ScriptPath: string; + SheepServer, SheepNick, SheepURL, SheepPW, flam3Path, helpPath: string; + ExportBatches, ExportOversample, ExportWidth, ExportHeight, ExportFileFormat: Integer; + ExportFilter, ExportDensity: Double; + ExportEstimator, ExportEstimatorMin, ExportEstimatorCurve: double; + ExportJitters: integer; + ExportGammaTreshold: double; + OpenFileType: TFileType; +// ResizeOnLoad: Boolean; + ShowProgress: Boolean; + defLibrary: string; + LimitVibrancy: Boolean; + DefaultPalette: TColorMap; + + AutoOpenLog: Boolean; + AutoSaveEnabled: Boolean; + AutoSaveFreq: integer; + AutoSavePath: string; + + LineCenterColor : integer; + LineThirdsColor : integer; + LineGRColor : integer; + EnableGuides : boolean; + +function Round6(x: double): double; + +implementation + +function GetEnvVarValue(const VarName: string): string; +var + BufSize: Integer; // buffer size required for value +begin + // Get required buffer size (inc. terminal #0) + BufSize := GetEnvironmentVariable( + PChar(VarName), nil, 0); + if BufSize > 0 then + begin + // Read env var value into result string + SetLength(Result, BufSize - 1); + GetEnvironmentVariable(PChar(VarName), + PChar(Result), BufSize); + end + else + // No such environment variable + Result := ''; +end; + +procedure LoadThumbnailPlaceholder(ThumbnailSize : integer); +var + placeholder: TBitmap; + placeholderIcon: TBitmap; +const + pi_width = 48; + pi_height = 48; +begin + placeholder := TBitmap.Create; + placeholderIcon := TBitmap.Create; + + placeholderIcon.Handle := LoadBitmap(hInstance, 'THUMB_PLACEHOLDER'); + placeholder.PixelFormat := pf32bit; + placeholder.HandleType := bmDIB; + placeholder.Width := ThumbnailSize; + placeholder.Height := ThumbnailSize; + + with placeholder.Canvas do begin + Brush.Color := $000000; + FillRect(Rect(0, 0, placeholder.Width, placeholder.Height)); + Draw(round(ThumbnailSize / 2 - pi_width / 2), round(ThumbnailSize / 2 - pi_height / 2), placeholderIcon); + end; + + placeholderIcon.Free; + ThumbnailPlaceholder := placeholder; +end; + +{ IFS } + +function det(a, b, c, d: double): double; +begin + Result := (a * d - b * c); +end; + + +function Round6(x: double): double; +// Really ugly, but it works +begin + // --Z-- this is ridiculous: + // Result := StrToFloat(Format('%.6f', [x])); + // and yes, this is REALLY ugly :-\ + Result := RoundTo(x, -6); +end; + +function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double; + var a, b, e: double): double; +var + det1: double; +begin + det1 := x1 * det(y2, 1.0, z2, 1.0) - x2 * det(y1, 1.0, z1, 1.0) + + 1 * det(y1, y2, z1, z2); + if (det1 = 0.0) then + begin + Result := det1; + EXIT; + end + else + begin + a := (x1h * det(y2, 1.0, z2, 1.0) - x2 * det(y1h, 1.0, z1h, 1.0) + + 1 * det(y1h, y2, z1h, z2)) / det1; + b := (x1 * det(y1h, 1.0, z1h, 1.0) - x1h * det(y1, 1.0, z1, 1.0) + + 1 * det(y1, y1h, z1, z1h)) / det1; + e := (x1 * det(y2, y1h, z2, z1h) - x2 * det(y1, y1h, z1, z1h) + + x1h * det(y1, y2, z1, z2)) / det1; + a := Round6(a); + b := Round6(b); + e := Round6(e); + Result := det1; + end; +end; + +function dist(x1, y1, x2, y2: double): double; +//var +// d2: double; +begin +(* + { From FDesign source + { float pt_pt_distance(float x1, float y1, float x2, float y2) } + d2 := (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); + if (d2 = 0.0) then + begin + Result := 0.0; + exit; + end + else + Result := sqrt(d2); +*) + + // --Z-- This is just amazing... :-\ + // Someone needed an 'FDesign source' - to compute distance between two points??!? + + Result := Hypot(x2-x1, y2-y1); +end; + +function line_dist(x, y, x1, y1, x2, y2: double): double; +var + a, b, e, c: double; +begin + if ((x = x1) and (y = y1)) then + a := 0.0 + else + a := sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1)); + if ((x = x2) and (y = y2)) then + b := 0.0 + else + b := sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2)); + if ((x1 = x2) and (y1 = y2)) then + e := 0.0 + else + e := sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); + if ((a * a + e * e) < (b * b)) then + Result := a + else if ((b * b + e * e) < (a * a)) then + Result := b + else if (e <> 0.0) then + begin + c := (b * b - a * a - e * e) / (-2 * e); + if ((a * a - c * c) < 0.0) then + Result := 0.0 + else + Result := sqrt(a * a - c * c); + end + else + Result := a; +end; + +function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean; +var + ra, rb, rc, a, b, c: double; +begin + Result := True; + ra := dist(Triangles[-1].y[0], Triangles[-1].x[0], + Triangles[-1].y[1], Triangles[-1].x[1]); + rb := dist(Triangles[-1].y[1], Triangles[-1].x[1], + Triangles[-1].y[2], Triangles[-1].x[2]); + rc := dist(Triangles[-1].y[2], Triangles[-1].x[2], + Triangles[-1].y[0], Triangles[-1].x[0]); + a := dist(t.y[0], t.x[0], t.y[1], t.x[1]); + b := dist(t.y[1], t.x[1], t.y[2], t.x[2]); + c := dist(t.y[2], t.x[2], t.y[0], t.x[0]); + if (a > ra) then + Result := False + else if (b > rb) then + Result := False + else if (c > rc) then + Result := False + else if ((a = ra) and (b = rb) and (c = rc)) then + Result := False; +end; + +function triangle_area(t: TTriangle): double; +var + base, height: double; +begin + try + base := dist(t.x[0], t.y[0], t.x[1], t.y[1]); + height := line_dist(t.x[2], t.y[2], t.x[1], t.y[1], + t.x[0], t.y[0]); + if (base < 1.0) then + Result := height + else if (height < 1.0) then + Result := base + else + Result := 0.5 * base * height; + except on E: EMathError do + Result := 0; + end; +end; + +{ Parse } + +function GetVal(token: string): string; +var + p: integer; +begin + p := Pos('=', token); + Delete(Token, 1, p); + Result := Token; +end; + +function ReplaceTabs(str: string): string; +{Changes tab characters in a string to spaces} +var + i: integer; +begin + for i := 1 to Length(str) do + begin + if str[i] = #9 then + begin + Delete(str, i, 1); + Insert(#32, str, i); + end; + end; + Result := str; +end; + +(* +{ Palette and gradient functions } + +function RGBToColor(Pal: TMapPalette; index: integer): Tcolor; +begin + { Converts the RGB values from a palette index to the TColor type ... + could maybe change it to SHLs } + Result := (Pal.Blue[index] * 65536) + (Pal.Green[index] * 256) + + Pal.Red[index]; +end; + +procedure rgb2hsv(const rgb: array of double; out hsv: array of double); +var + maxval, minval: double; + del: double; +begin + Maxval := Max(rgb[0], Max(rgb[1], rgb[2])); + Minval := Min(rgb[0], Min(rgb[1], rgb[2])); + + hsv[2] := maxval; // v + + if (Maxval > 0) and (maxval <> minval) then begin + del := maxval - minval; + hsv[1] := del / Maxval; //s + + hsv[0] := 0; + if (rgb[0] > rgb[1]) and (rgb[0] > rgb[2]) then begin + hsv[0] := (rgb[1] - rgb[2]) / del; + end else if (rgb[1] > rgb[2]) then begin + hsv[0] := 2 + (rgb[2] - rgb[0]) / del; + end else begin + hsv[0] := 4 + (rgb[0] - rgb[1]) / del; + end; + + if hsv[0] < 0 then + hsv[0] := hsv[0] + 6; + + end else begin + hsv[0] := 0; + hsv[1] := 0; + end; +end; + +procedure hsv2rgb(const hsv: array of double; out rgb: array of double); +var + j: integer; + f, p, q, t, v: double; +begin + j := floor(hsv[0]); + f := hsv[0] - j; + v := hsv[2]; + p := hsv[2] * (1 - hsv[1]); + q := hsv[2] * (1 - hsv[1] * f); + t := hsv[2] * (1 - hsv[1] * (1 - f)); + + case j of + 0: begin rgb[0] := v; rgb[1] := t; rgb[2] := p; end; + 1: begin rgb[0] := q; rgb[1] := v; rgb[2] := p; end; + 2: begin rgb[0] := p; rgb[1] := v; rgb[2] := t; end; + 3: begin rgb[0] := p; rgb[1] := q; rgb[2] := v; end; + 4: begin rgb[0] := t; rgb[1] := p; rgb[2] := v; end; + 5: begin rgb[0] := v; rgb[1] := p; rgb[2] := t; end; + end; +end; + +function GetGradient(FileName, Entry: string): string; +var + FileStrings: TStringList; + GradStrings: TStringList; + i: integer; +begin + FileStrings := TStringList.Create; + GradStrings := TStringList.Create; + try + try + FileStrings.LoadFromFile(FileName); + for i := 0 to FileStrings.count - 1 do + if Pos(Entry + ' ', Trim(FileStrings[i])) = 1 then break; + GradStrings.Add(FileStrings[i]); + repeat + inc(i); + GradStrings.Add(FileStrings[i]); + until Pos('}', FileStrings[i]) <> 0; + GetGradient := GradStrings.Text; + except on exception do + Result := ''; + end; + finally + GradStrings.Free; + FileStrings.Free; + end; +end; +*) + +function ReplaceStr(Str, SearchStr, ReplaceStr: string): string; +begin + while Pos(SearchStr, Str) <> 0 do + begin + Insert(ReplaceStr, Str, Pos(SearchStr, Str)); + system.Delete(Str, Pos(SearchStr, Str), Length(SearchStr)); + end; + Result := Str; +end; + +function SplitFilter(const fText: String; const fSep: Char; fTrim: Boolean=false; fQuotes: Boolean=false):TStringList; +var vI: Integer; + vBuffer: String; + vOn: Boolean; +begin + Result:=TStringList.Create; + vBuffer:=''; + vOn:=true; + for vI:=1 to Length(fText) do + begin + if (fQuotes and(fText[vI]=fSep)and vOn)or(Not(fQuotes) and (fText[vI]=fSep)) then + begin + if fTrim then vBuffer:=Trim(vBuffer); + if vBuffer='' then vBuffer:=fSep; // !!! e.g. split(',**',',')... + if vBuffer[1]=fSep then + vBuffer:=Copy(vBuffer,2,Length(vBuffer)); + Result.Add(vBuffer); + vBuffer:=''; + end; + if fQuotes then + begin + if fText[vI]='"' then + begin + vOn:=Not(vOn); + Continue; + end; + if (fText[vI]<>fSep)or((fText[vI]=fSep)and(vOn=false)) then + vBuffer:=vBuffer+fText[vI]; + end else + if fText[vI]<>fSep then + vBuffer:=vBuffer+fText[vI]; + end; + if vBuffer<>'' then + begin + if fTrim then vBuffer:=Trim(vBuffer); + Result.Add(vBuffer); + end; +end; + +function OpenSaveFileDialog(Parent: TWinControl; + const DefExt, + Filter, + InitialDir, + Title: string; + var FileName: string; + MustExist, + OverwritePrompt, + NoChangeDir, + DoOpen: Boolean): Boolean; +// uses commdlg +var + ofn: TOpenFileName; + szFile: array[0..260] of Char; + fa, fa2: TStringList; + h,i,j,k,c : integer; + cs, s : string; +begin + Result := False; + FillChar(ofn, SizeOf(TOpenFileName), 0); + with ofn do + begin + lStructSize := SizeOf(TOpenFileName); + hwndOwner := Parent.Handle; + lpstrFile := szFile; + nMaxFile := SizeOf(szFile); + if (Title <> '') then + lpstrTitle := PChar(Title); + if (InitialDir <> '') then + lpstrInitialDir := PChar(InitialDir); + StrPCopy(lpstrFile, FileName); + lpstrFilter := PChar(ReplaceStr(Filter, '|', #0)+#0#0); + fa := splitFilter(Filter, '|'); + + k := 0; + c := (fa.Count div 2); + for i := 0 to c - 1 do begin + j := 2 * i + 1; + cs := LowerCase(fa.Strings[j]); + fa2 := splitFilter(cs, ';'); + for h := 0 to fa2.Count - 1 do begin + cs := fa2.Strings[h]; + s := '*.' + LowerCase(DefExt); + if (cs = s) then k := i; + end; + end; + + nFilterIndex := k + 1; + if DefExt <> '' then + lpstrDefExt := PChar(DefExt); + end; + + if MustExist then ofn.Flags := ofn.Flags or OFN_FILEMUSTEXIST; + if OverwritePrompt then ofn.Flags := ofn.Flags or OFN_OVERWRITEPROMPT; + if NoChangeDir then ofn.Flags := ofn.Flags or OFN_NOCHANGEDIR; + + if DoOpen then + begin + if GetOpenFileName(ofn) then + begin + Result := True; + FileName := StrPas(szFile); + end; + end + else + begin + if GetSaveFileName(ofn) then + begin + Result := True; + FileName := StrPas(szFile); + end; + end +end; // function OpenSaveFileDialog + +end. + diff --git a/Core/Translation.pas b/Core/Translation.pas new file mode 100644 index 0000000..da3fe93 --- /dev/null +++ b/Core/Translation.pas @@ -0,0 +1,754 @@ +unit Translation; + +interface + +uses Global, Classes, Forms, LibXmlParser, LibXmlComps, SysUtils, RegexHelper; + +procedure ListLanguages; +procedure LanguageInfo(path: string; var name, localName: string); +function LanguageAuthor(path: string): string; +procedure Add(key, value: string); +procedure LoadLanguage(path:string); +procedure LoadEnglish(); +function TextByKey(key:string):string; + +type + TParser = class + public + constructor Create; + + procedure ListXmlScannerStartTag(Sender: TObject; TagName: string; Attributes: TAttrList); + procedure ListXmlScannerEndTag(Sender: TObject; TagName: string); + procedure ListXmlScannerEmptyTag(Sender: TObject; TagName: string; Attributes: TAttrList); + procedure ListXmlScannerContent(Sender: TObject; Content: string); + private + currentTagname: string; + parentTagnames: TStringList; + end; + + TKeyValuePair = class + public + key: string; + value: string; + end; + + TDictionary = array of TKeyValuePair; +var + language: TDictionary; + defaultlanguage: TDictionary; + tokenCount: integer; + ListXmlScanner: TEasyXmlScanner; + parser: TParser; + +implementation + +procedure ListLanguages; +var + searchResult: TSearchRec; +begin + if FindFirst(ExtractFilePath(Application.ExeName) + 'Languages\*.xml', faAnyFile, searchResult) = 0 then + begin + repeat + AvailableLanguages.Add(ExtractFilePath(Application.ExeName) + 'Languages\' + searchResult.Name); + until (FindNext(searchResult) <> 0); + SysUtils.FindClose(searchResult); + end; +end; + +procedure LanguageInfo(path: string; var name, localName: string); +const + exp1 = '\stitle="([^"]*)"'; + exp2 = '\slocalized-title="([^"]*)"'; +var + langxml : string; + sl: TStringList; +begin + sl := TStringList.Create; + sl.LoadFromFile(path); + langxml := sl.Text; + sl.Destroy; + + name := GetStringPart(langxml, exp1, 1, ''); + localname := GetStringPart(langxml, exp2, 1, ''); +end; +function LanguageAuthor(path: string): string; +const + exp = '\sauthor="([^"]*)"'; +var + langxml : string; + sl: TStringList; +begin + sl := TStringList.Create; + sl.LoadFromFile(path); + langxml := sl.Text; + sl.Destroy; + + Result := GetStringPart(langxml, exp, 1, ''); +end; + +procedure LoadEnglish(); +begin + //TODO: + //render-status-renderhibernated + + Add('common-ok', 'OK'); + Add('common-cancel', 'Cancel'); + Add('common-apply', 'Apply'); + Add('common-yes', 'Yes'); + Add('common-no', 'No'); + Add('common-lowquality', 'Low Quality'); + Add('common-mediumquality', 'Medium Quality'); + Add('common-highquality', 'High Quality'); + Add('common-copy', 'Copy'); + Add('common-paste', 'Paste'); + Add('common-delete', 'Delete'); + Add('common-rename', 'Rename'); + Add('common-undo', 'Undo'); + Add('common-redo', 'Redo'); + Add('common-width', 'Width'); + Add('common-height', 'Height'); + Add('common-size', 'Size'); + Add('common-pixels', 'Pixels'); + Add('common-keepaspect', 'Maintain aspect ratio'); + Add('common-destination', 'Destination'); + Add('common-filename', 'File name'); + Add('common-browse', 'Browse...'); + Add('common-quality', 'Quality'); + Add('common-filterradius', 'Filter Radius'); + Add('common-density', 'Density'); + Add('common-oversample', 'Oversample'); + Add('common-gamma', 'Gamma'); + Add('common-brightness', 'Brightness'); + Add('common-contrast', 'Contrast'); + Add('common-vibrancy', 'Vibrancy'); + Add('common-background', 'Background'); + Add('common-gammathreshold', 'Gamma Threshold'); + Add('common-start', 'Start'); + Add('common-pause', 'Pause'); + Add('common-resume', 'Resume'); + Add('common-close', 'Close'); + Add('common-clear', 'Clear'); + Add('common-enabled', 'Enabled'); + Add('common-disabled', 'Disabled'); + Add('common-minimum', 'Minimum'); + Add('common-maximum', 'Maximum'); + Add('common-resetlocation', 'Reset location'); + Add('common-genericopenfailure', 'Unable to open "%s".'); + Add('common-genericsavefailure', 'Unable to save "%s".'); + Add('common-invalidformat', 'Invalid format.'); + Add('common-confirmexit', 'Do you really want to exit? All unsaved data will be lost!'); + Add('common-confirmdelete', 'Are you sure you want to permanently delete "%s"?'); + Add('common-dragpanelhint', 'Click and drag to change value'); + Add('common-trace-pausing', 'Pausing render'); + Add('common-trace-resuming', 'Resuming render'); + Add('common-trace-terminating', 'Terminating render'); + Add('common-trace-stopping', 'Stopping render'); + Add('common-trace-saving', 'Saving image...'); + Add('common-trace-creating-simple', 'Creating image...'); + Add('common-trace-creating-detailed', 'Creating image with quality: %f...'); + Add('common-trace-rendering-oneslice', 'Rendering...'); + Add('common-trace-rendering-multipleslices', 'Rendering slice %d of %d...'); + Add('common-trace-allocating', 'Allocating %n Mb of memory...'); + Add('common-trace-notenoughmemory', 'ERROR: Not enough memory for this render!'); + Add('common-statistics-title-oneslice', 'Render Statistics:'); + Add('common-statistics-title-multipleslices', 'Render Statistics for the last slice:'); + Add('common-statistics-maxpossiblebits', 'Max possible bits: %2.3f'); + Add('common-statistics-maxred', 'Max Red: %2.3f bits'); + Add('common-statistics-maxgreen', 'Max Green: %2.3f bits'); + Add('common-statistics-maxblue', 'Max Blue: %2.3f bits'); + Add('common-statistics-maxcounter', 'Max Count: %2.3f bits'); + Add('common-statistics-pointhitratio', 'Point hit ratio: %2.2f%%'); + Add('common-statistics-averagespeed', 'Average speed: %n iterations per second'); + Add('common-statistics-purerenderingtime', 'Pure rendering time:'); + Add('common-seconds', 'second(s)'); + Add('common-minutes', 'minute(s)'); + Add('common-hours', 'hour(s)'); + Add('common-days', 'day(s)'); + Add('common-suspendtodisk', 'Suspend to disk'); + Add('common-resumefromdisk', 'Resume from disk'); + Add('common-filter-flamefiles', 'Apophysis Flame Library (*.flame;*.xml)'); + Add('common-filter-gradientfiles', 'Gradient files (*.gradient;*.ugr)'); + Add('common-filter-fractintfiles', 'Fractint maps (*.map)'); + Add('common-filter-uprfiles', 'UltraFractal parameters (*.upr)'); + Add('common-filter-script', 'Apophysis Script (*.aposcript;*.asc)'); + Add('common-filter-allimages', 'All images (*.bmp;*.dib;*.jpg;*.jpeg)'); + Add('common-filter-bitmap', 'Windows Bitmap (*.bmp;*.dib)'); + Add('common-filter-jpeg', 'JPEG (*.jpg;*.jpeg)'); + Add('common-filter-png', 'Portable Network Graphics (*.png)'); + Add('common-filter-allfiles', 'All files (*.*)'); + Add('splash-loadingui', 'Loading user interface...'); + Add('splash-loadingsettings', 'Loading settings...'); + Add('splash-loadingplugins', 'Loading plugins...'); + Add('splash-initrenderer', 'Initializing renderer...'); + Add('splash-initcolormap', 'Initializing gradients...'); + Add('splash-initbatch', 'Creating random batch...'); + Add('splash-execstartupscript', 'Executing "autoexec.asc"...'); + Add('adjustment-title', 'Adjustment'); + Add('adjustment-common-depthblur', 'Depth Blur'); + Add('adjustment-common-pitch', 'Pitch'); + Add('adjustment-common-yaw', 'Yaw'); + Add('adjustment-common-height', 'Height'); + Add('adjustment-common-perspective', 'Perspective'); + Add('adjustment-common-scale', 'Scale'); + Add('adjustment-tab-camera-title', 'Camera'); + Add('adjustment-tab-camera-zoom', 'Zoom'); + Add('adjustment-tab-camera-xpos', 'X-Position'); + Add('adjustment-tab-camera-ypos', 'Y-Position'); + Add('adjustment-tab-camera-rotation', 'Rotation'); + Add('adjustment-tab-rendering-title', 'Rendering'); + Add('adjustment-tab-rendering-istransparent', 'Transparent'); + Add('adjustment-tab-gradient-title', 'Gradient'); + Add('adjustment-tab-gradient-moderotate', 'Rotate'); + Add('adjustment-tab-gradient-modehue', 'Hue'); + Add('adjustment-tab-gradient-modesaturation', 'Saturation'); + Add('adjustment-tab-gradient-modebrightness', 'Brightness'); + Add('adjustment-tab-gradient-modecontrast', 'Contrast'); + Add('adjustment-tab-gradient-modeblur', 'Blur'); + Add('adjustment-tab-gradient-modefrequency', 'Frequency'); + Add('adjustment-tab-gradient-preset', 'Preset'); + Add('adjustment-tab-gradient-reset', 'Reset'); + Add('adjustment-tab-gradient-modehint', 'Click for menu'); + Add('adjustment-tab-gradient-presethint', 'Click to choose random preset'); + Add('adjustment-tab-size-title', 'Image size'); + Add('adjustment-tab-size-preset', 'Empty preset'); + Add('adjustment-tab-size-resizemain', 'Resize main window'); + Add('adjustment-tab-curves-title', 'Curves'); + Add('adjustment-tab-curves-reset', 'Reset'); + Add('adjustment-tab-curves-selected', 'Selected curve:'); + Add('adjustment-tab-curves-overall', 'Overall'); + Add('adjustment-tab-curves-red', 'Red'); + Add('adjustment-tab-curves-green', 'Green'); + Add('adjustment-tab-curves-blue', 'Blue'); + Add('adjustment-popup-quality-instantpreview', 'Instant preview'); + Add('adjustment-popup-gradient-randomize', 'Randomize'); + Add('adjustment-popup-gradient-invert', 'Invert'); + Add('adjustment-popup-gradient-reverse', 'Reverse'); + Add('adjustment-popup-gradient-smooth', 'Smooth Palette...'); + Add('adjustment-popup-gradient-browser', 'Gradient Browser...'); + Add('adjustment-popup-gradient-saveasugr', 'Save Gradient...'); + Add('adjustment-popup-gradient-saveasmap', 'Save as Map File...'); + Add('adjustment-popup-gradient-saveasdefault', 'Save as default'); + Add('editor-title', 'Editor'); + Add('editor-common-transform', 'Transform:'); + Add('editor-common-name', 'Name:'); + Add('editor-common-weight', 'Weight:'); + Add('editor-common-finalxformlistitem', 'Final'); + Add('editor-common-fromprefix', 'from %d'); + Add('editor-common-toprefix', 'to %d'); + Add('editor-tab-variations-title', 'Variations'); + Add('editor-tab-variations-name', 'Name'); + Add('editor-tab-variations-value', 'Value'); + Add('editor-tab-variations-togglehideunused', 'Hide unused variations'); + Add('editor-tab-variables-title', 'Variables'); + Add('editor-tab-variables-name', 'Name'); + Add('editor-tab-variables-value', 'Value'); + Add('editor-tab-variables-toggleshowall', 'Show all variables'); + Add('editor-tab-chaos-title', 'Xaos'); + Add('editor-tab-chaos-path', 'Path'); + Add('editor-tab-chaos-modifier', 'Weight modifier'); + Add('editor-tab-chaos-viewasto', 'View as "to"'); + Add('editor-tab-chaos-viewasfrom', 'View as "from"'); + Add('editor-tab-triangle-title', 'Triangle'); + Add('editor-tab-triangle-pivot', 'Pivot'); + Add('editor-tab-triangle-modelocal', 'Local'); + Add('editor-tab-triangle-modeworld', 'World'); + Add('editor-tab-triangle-resetpivot', 'Reset pivot point'); + Add('editor-tab-triangle-pickpivot', 'Pick pivot point'); + Add('editor-tab-triangle-rotateleft', 'Rotate triangle counter-clockwise'); + Add('editor-tab-triangle-rotateright', 'Rotate triangle clockwise'); + Add('editor-tab-triangle-moveup', 'Move triangle up'); + Add('editor-tab-triangle-movedown', 'Move triangle down'); + Add('editor-tab-triangle-moveleft', 'Move triangle left'); + Add('editor-tab-triangle-moveright', 'Move triangle right'); + Add('editor-tab-triangle-scaledown', 'Scale triangle down'); + Add('editor-tab-triangle-scaleup', 'Scale triangle up'); + Add('editor-tab-triangle-autoweight', 'Auto-balance weights'); + Add('editor-tab-transform-title', 'Transform'); + Add('editor-tab-transform-reset', 'Reset transform'); + Add('editor-tab-transform-resethint', 'Reset all vectors to default position'); + Add('editor-tab-transform-rectangular', 'Rectangular'); + Add('editor-tab-transform-rectangularhint', 'Show vectors in rectangular (cartesian) corrdinates'); + Add('editor-tab-transform-polar', 'Polar (deg)'); + Add('editor-tab-transform-polarhint', 'Show vector in polar coordinates'); + Add('editor-tab-transform-resetpost', 'Reset post transform'); + Add('editor-tab-transform-resetposthint', 'Reset all post-transform vectors to default position'); + Add('editor-tab-transform-autozscale', 'Auto-calculate pre_zscale'); + Add('editor-tab-transform-resetxhint', 'Reset vector X'); + Add('editor-tab-transform-resetyhint', 'Reset vector Y'); + Add('editor-tab-transform-resetohint', 'Reset vector O'); + Add('editor-tab-color-title', 'Colors'); + Add('editor-tab-color-transformcolor', 'Transform color'); + Add('editor-tab-color-colorspeed', 'Color speed'); + Add('editor-tab-color-opacity', 'Opacity'); + Add('editor-tab-color-directcolor', 'Direct color'); + Add('editor-tab-color-togglesolo', 'Solo'); + Add('editor-tab-color-togglesoloformat', 'Solo transform #%d'); + Add('editor-tab-color-varpreview', 'Variation preview'); + Add('editor-tab-color-previewrange', 'Range'); + Add('editor-tab-color-previewdepth', 'Depth'); + Add('editor-tab-color-previewdensity', 'Density'); + Add('editor-tab-color-preview', 'Preview'); + Add('editor-toolbar-newflame', 'New flame'); + Add('editor-toolbar-newtransform', 'New transform'); + Add('editor-toolbar-addlinkedtransform', 'Add linked transform'); + Add('editor-toolbar-duplicatetransform', 'Duplicate transform'); + Add('editor-toolbar-removetransform', 'Remove transform'); + Add('editor-toolbar-modeselect', 'Selection mode'); + Add('editor-toolbar-modemove', 'Movement mode'); + Add('editor-toolbar-moderotate', 'Rotation mode'); + Add('editor-toolbar-modescale', 'Scale mode'); + Add('editor-toolbar-toggleworldpivot', 'Toggle world pivot'); + Add('editor-toolbar-rotate90ccw', 'Rotate 90° counter-clockwise'); + Add('editor-toolbar-rotate90cw', 'Rotate 90° clockwise'); + Add('editor-toolbar-fliph', 'Flip horizontal'); + Add('editor-toolbar-flipv', 'Flip vertical'); + Add('editor-toolbar-togglevarpreview', 'Show variation preview'); + Add('editor-toolbar-toggleposttransform', 'Enable/edit post-transform'); + Add('editor-toolbar-togglefinaltransform', 'Enable final transform'); + Add('editor-popup-panel-autozoom', 'Zoom automatically'); + Add('editor-popup-panel-toggleextendededit', 'Toggle extended edit mode'); + Add('editor-popup-panel-locktransformaxes', 'Lock transform axes'); + Add('editor-popup-panel-allfliph', 'Flip all horizontally'); + Add('editor-popup-panel-allflipv', 'Flip all vertically'); + Add('editor-popup-quality-autoreset', 'Auto-reset location'); + Add('editor-popup-transform-resetposition', 'Reset position'); + Add('editor-popup-transform-resetrotation', 'Reset rotation'); + Add('editor-popup-transform-resetscale', 'Reset scale'); + Add('editor-popup-transform-copycoords', 'Copy triangle coordinates'); + Add('editor-popup-transform-pastecoords', 'Paste triangle coordinates'); + Add('editor-popup-transform-resetentiretriangle', 'Reset triangle'); + Add('editor-popup-chaos-rebuildlinks', 'Rebuild links'); + Add('editor-popup-chaos-clearall', 'Clear all'); + Add('editor-popup-chaos-setall', 'Set all'); + Add('editor-status-zoomformat', 'Zoom: %f'); + Add('editor-status-xformat', 'X: %f'); + Add('editor-status-yformat', 'Y: %f'); + Add('editor-status-rotateformat', 'Rotate: %3.2f° Inner angle: %3.2f°'); + Add('editor-status-rotateformat2', 'Rotate: %3.2f° Local axis: %3.2f°'); + Add('editor-status-rotateformat3', 'Rotate: %3.2f°'); + Add('editor-status-scaleformat', 'Distance: %3.3f Scale: %3.2f%%'); + Add('editor-status-scaleformat2', 'Scale: %3.2f%%'); + Add('editor-status-moveformat', 'Move: %3.3f ; %3.3f'); + Add('editor-status-moveformat2', 'Move: %3.3f ; %3.3f'); + Add('editor-status-transformformat', 'Transform #%d'); + Add('editor-status-zoomformat', 'Zoom: %f'); + Add('editor-status-selecton', 'Select ON'); + Add('editor-status-selectoff', 'Select OFF'); + Add('export-title', 'Export to flam3'); + Add('export-paramoptions-title', 'Parameter options'); + Add('export-paramoptions-bufferdepth', 'Buffer depth'); + Add('export-paramoptions-strips', 'Strips'); + Add('export-paramoptions-estimatorradius', 'DE radius'); + Add('export-paramoptions-estimatorcurve', 'DE curve'); + Add('export-paramoptions-estimatormin', 'DE minimum'); + Add('export-paramoptions-dorender', 'Render'); + Add('export-paramoptions-warningtitle', 'WARNING'); + Add('export-paramoptions-warningtext', 'Fractals created with this version of Apophysis are not supported by flam3! To render 2D-only fractals, download the latest version of flam3 from http://www.flam3.com'); + Add('favscripts-title', 'Favorite scripts'); + Add('favscripts-add', 'Add'); + Add('favscripts-remove', 'Remove'); + Add('favscripts-moveup', 'Move up'); + Add('favscripts-movedown', 'Move down'); + Add('fullscreen-popup-rendermore', 'Render more'); + Add('fullscreen-popup-stoprender', 'Stop render'); + Add('gradientbrowser-title', 'Gradient Browser'); + Add('postprocess-title', 'Post-process render'); + Add('postprocess-save', 'Save'); + Add('postprocess-fittowindow', 'Fit to window'); + Add('render-title', 'Render flame'); + Add('render-common-gotofolder', 'Open target folder...'); + Add('render-tab-settings-title', 'Settings'); + Add('render-tab-output-title', 'Output'); + Add('render-resourceusage-title', 'Resource usage'); + Add('render-resourceusage-infotext', 'The render process will use %u MB of %u MB available physical memory'); + Add('render-resourceusage-infotext2', 'Apophysis will try to use %u processor cores (%u available) - change this in the options'); + Add('render-resourceusage-limit', 'Memory limit'); + Add('render-resourceusage-nolimit', 'No limit'); + Add('render-resourceusage-bufferdepth', 'Buffer depth'); + Add('render-output-title', 'Output options'); + Add('render-output-saveparams', 'Save parameters'); + Add('render-completion-title', 'Completion options'); + Add('render-completion-postprocess', 'Post-process after rendering'); + Add('render-completion-shutdown', 'Shut down after rendering'); + Add('render-completion-saveincomplete', 'Save incomplete renders'); + Add('render-status-rendererror-log', 'Rendering failed!'); + Add('render-status-rendererror-message', 'Error while rendering!'); + Add('render-status-saveerror-log', 'Error saving image!'); + Add('render-status-saveerror-message1', 'An error occured while saving the image:'); + Add('render-status-saveerror-message2', 'Check your free disk space and try again.'); + Add('render-status-totaltime', 'Total time:'); + Add('render-status-renderterminated', 'Rendering terminated!'); + Add('render-status-renderhibernated', 'Rendering paused and progress saved!'); + Add('render-status-elapsed', 'Elapsed'); + Add('render-status-remaining', 'Remaining'); + Add('render-status-slicestatus', 'Slice %d of %d'); + Add('render-status-notenoughmemory1', 'You do not have enough memory for this render. Do you want to continue anyway?'); + Add('render-status-notenoughmemory2', 'You do not have enough memory for this render. Please use a lower Maximum memory setting. Do you want to ignore this problem and continue?'); + Add('render-status-nofilename', 'Please enter a file name.'); + Add('render-status-fileexists-message1', '"%s" already exists'); + Add('render-status-fileexists-message2', 'Do you want to replace it?'); + Add('render-status-pathdoesnotexist', 'The directory does not exist.'); + Add('render-status-invaliddensity', 'Invalid Sample Density value'); + Add('render-status-invalidfilterradius', 'Invalid Filter Radius value'); + Add('render-status-invalidoversample', 'Invalid Oversample value'); + Add('render-status-invalidwidth', 'Invalid image width'); + Add('render-status-invalidheight', 'Invalid image height'); + Add('render-status-maxmemorytoosmall', 'Maximum memory value is too small. Do you want to continue anyway?'); + Add('render-status-shuttingdownrender', 'Shutting down previous render...'); + Add('render-status-log-title', 'Rendering "%s"'); + Add('render-status-log-size', 'Size: %dx%d'); + Add('render-status-log-quality', 'Quality: %g'); + Add('render-status-log-oversampling', 'Oversample: %d, Filter: %g'); + Add('render-status-log-bufferdepth', 'Buffer depth: %s'); + Add('render-status-log-memorylimit', 'Memory limit: %d MB'); + Add('render-status-log-largepng-message1', '*** WARNING *** You have selected PNG format and an image size which exceeds 20 megapixels'); + Add('render-status-log-largepng-message2', 'PNG format with extreme high-resolution images is not recommended!'); + Add('render-status-log-largepng-message3', 'To avoid slowdown (and possible memory problems) use BMP file format instead.'); + Add('render-status-confirmstop', 'Do you want to stop the current render?'); + Add('imagecoloring-title', 'Image coloring'); + Add('imagecoloring-enable', 'Enable'); + Add('imagecoloring-firstpalette', 'First palette'); + Add('imagecoloring-secondpalette', 'Second palette'); + Add('imagecoloring-preset', 'Preset'); + Add('imagecoloring-image', 'Image'); + Add('messages-title', 'Messages'); + Add('messages-openautomatically', 'Automatically open this window'); + Add('mutation-title', 'Mutation'); + Add('mutation-directions', 'Directions'); + Add('mutation-speed', 'Speed'); + Add('mutation-trend', 'Trend'); + Add('mutation-keepnumberoftransforms', 'Keep transform count'); + Add('mutation-randomtrend', 'Random'); + Add('mutation-maintainsymmetry', 'Maintain symmetry'); + Add('mutation-previous', 'Previous'); + Add('options-title', 'Settings '); + Add('options-restartnotice', 'You must restart Apophysis 7x to make your changes have effect'); + Add('options-tab-general-title', 'General '); + Add('options-tab-general-language', 'Language file'); + Add('options-tab-general-multithreading', 'Multithreading '); + Add('options-tab-general-multithreading-off', 'Off '); + Add('options-tab-general-bufferdepth', 'Buffer depth '); + Add('options-tab-general-jpegquality', 'JPEG quality '); + Add('options-tab-general-pngtransparency', 'PNG transparency '); + Add('options-tab-general-showextendedstatistics', 'Show extended render statistics '); + Add('options-tab-general-confirmdelete', 'Confirm delete '); + Add('options-tab-general-confirmexit', 'Confirm exit '); + Add('options-tab-general-confirmrenderstop', 'Confirm stop rendering '); + Add('options-tab-general-oldgradientformat', 'Use old gradient format '); + Add('options-tab-general-alwaysblankflame', 'Disable templates '); + Add('options-tab-general-enablemissingpluginswarning', 'Warn on missing plugins '); + Add('options-tab-general-enablethumbnailembedding', 'Enable thumbnail embedding '); + Add('options-tab-general-rotatemode', 'Rotate mode '); + Add('options-tab-general-rotateimage', 'Rotate image '); + Add('options-tab-general-rotateframe', 'Rotate frame '); + Add('options-tab-general-zoommode', 'Zoom mode '); + Add('options-tab-general-preservequality', 'Preserve quality '); + Add('options-tab-general-preservespeed', 'Preserve speed '); + Add('options-tab-general-guides', 'Guidelines '); + Add('options-tab-general-enableguides', 'Enable guides '); + Add('options-tab-general-guidecentercolor', 'Center '); + Add('options-tab-general-guidethirdscolor', 'Thirds '); + Add('options-tab-general-guidegoldenratiocolor', 'Golden ratio '); + Add('options-tab-general-singleprecision', 'Use single-precision buffers '); + Add('options-tab-general-pluginpath', 'Plugin folder '); + Add('options-tab-editor-title', 'Editor '); + Add('options-tab-editor-editorgraph', 'Graph '); + Add('options-tab-editor-editordefaults', 'Defaults '); + Add('options-tab-editor-referencetriangle', 'Reference triangle '); + Add('options-tab-editor-usetransformcolor', 'Use transform color '); + Add('options-tab-editor-helperlines', 'Show helper lines '); + Add('options-tab-editor-alwaysshowbothtransformtypes', 'Always show both transform types '); + Add('options-tab-editor-backgroundcolor', 'Background '); + Add('options-tab-editor-gridcolors', 'Grid '); + Add('options-tab-editor-referencecolor', 'Reference '); + Add('options-tab-editor-helpercolors', 'Helpers '); + Add('options-tab-editor-extendededit', 'Extended edit mode '); + Add('options-tab-editor-locktransformaxes', 'Lock transform axes '); + Add('options-tab-editor-rebuildxaoslinks', 'Rebuild links '); + Add('options-tab-editor-normalreference', 'Normal '); + Add('options-tab-editor-proportionalreference', 'Proportional '); + Add('options-tab-editor-wanderingreference', 'Wandering (old style) '); + Add('options-tab-editor-enablepreview', 'Enable editor preview'); + Add('options-tab-editor-previewtransparency', 'Transparency'); + Add('options-tab-display-title', 'Display '); + Add('options-tab-display-rendering', 'Rendering '); + Add('options-tab-display-previewdensity', 'Preview density '); + Add('options-tab-display-mainpreview', 'Main window preview '); + Add('options-tab-display-extendpreviewbuffer', 'Extend preview buffer '); + Add('options-tab-display-extenspreviewbufferlabel', 'Buffer extension '); + Add('options-tab-display-showtransparency', 'Show transparency '); + Add('options-tab-display-usesmallthumbs', 'Use small thumbnails (like Apophysis 2.09) '); + Add('options-tab-random-title', 'Random '); + Add('options-tab-random-numberoftransforms', 'Number of transforms '); + Add('options-tab-random-mutationtransforms', 'Mutation transforms '); + Add('options-tab-random-randombatch', 'Random batch '); + Add('options-tab-random-forcedsymmetry', 'Forced symmetry '); + Add('options-tab-random-batchsize', 'Batch size '); + Add('options-tab-random-titleprefix', 'Title prefix '); + Add('options-tab-random-keepbackground', 'Keep background color '); + Add('options-tab-random-symtype', 'Type '); + Add('options-tab-random-symorder', 'Order '); + Add('options-tab-random-symlimit', 'Limit '); + Add('options-tab-random-type-none', 'None '); + Add('options-tab-random-type-bilateral', 'Bilateral '); + Add('options-tab-random-type-rotational', 'Rotational '); + Add('options-tab-random-type-dihedral', 'Dihedral '); + Add('options-tab-random-onrandom', 'On random flame use... '); + Add('options-tab-random-userandom', 'Random preset '); + Add('options-tab-random-usedefault', 'Default gradient '); + Add('options-tab-random-usecurrent', 'Current gradient '); + Add('options-tab-random-randomcalculated', 'Random gradient '); + Add('options-tab-random-randomfromfile', 'Random from file '); + Add('options-tab-random-filetouse', 'Random file to use '); + Add('options-tab-variations-title', 'Variations '); + Add('options-tab-variations-setall', 'Set all '); + Add('options-tab-variations-clearall', 'Clear all '); + Add('options-tab-gradient-title', 'Gradient '); + Add('options-tab-gradient-numberofnodes', 'Number of nodes '); + Add('options-tab-gradient-smoothpalette', 'Smooth palette '); + Add('options-tab-gradient-huebetween', 'Hue range '); + Add('options-tab-gradient-satbetween', 'Saturation range '); + Add('options-tab-gradient-lumbetween', 'Luminance range '); + Add('options-tab-gradient-numtries', 'Number of tries '); + Add('options-tab-gradient-trylength', 'Try length '); + Add('options-tab-upr-title', 'UltraFractal '); + Add('options-tab-upr-paramdefaults', 'Parameter defaults '); + Add('options-tab-upr-coloralgorithm', 'Coloring algorithm '); + Add('options-tab-upr-uprsize', 'Image size '); + Add('options-tab-upr-formula', 'Formula '); + Add('options-tab-upr-identifier', 'Identifier '); + Add('options-tab-upr-adjustdensity', 'Adjust sample density '); + Add('options-tab-environment-title', 'Environment'); + Add('options-tab-environment-defaultparams', 'Default parameters '); + Add('options-tab-environment-smoothpalette', 'Smooth palette '); + Add('options-tab-environment-functionlib', 'Scripting function library '); + Add('options-tab-environment-exportrenderer', 'Export renderer '); + Add('options-tab-environment-helpfile', 'Help file '); + Add('options-tab-environment-rememberlastopen', 'Remember last open parameters '); + Add('options-tab-environment-autosave', 'Enable autosave '); + Add('options-tab-environment-savefrequency', 'Save frequency '); + Add('preview-title', 'Preview'); + Add('save-title', 'Save'); + Add('save-name', 'Name'); + Add('save-oldformat', 'Use old format'); + Add('save-newformat', 'Use new format'); + Add('save-type-parameters', 'Save Parameters'); + Add('save-type-allparameters', 'Save All Parameters'); + Add('save-type-gradient', 'Save Gradient'); + Add('save-type-exportupr', 'Export UPR'); + Add('save-status-notitle', 'No item name given.'); + Add('save-status-invalidfilename', 'Invalid file name.'); + Add('save-status-alreadyexists', '"%s" in "%s" already exists. Do you want to replace it?'); + Add('save-status-alreadyexists2', '"%s" already exists. Do you want to replace it?'); + Add('savepreset-title', 'Save preset'); + Add('savepreset-name', 'Name'); + Add('savepreset-notitle', 'No preset name given.'); + Add('script-title', 'Script'); + Add('script-rendering', 'Rendering...'); + Add('script-break', 'Break'); + Add('script-new', 'New'); + Add('script-open', 'Open'); + Add('script-save', 'Save'); + Add('script-run', 'Run'); + Add('script-stop', 'Stop'); + Add('splash-loadingtext', 'Loading'); + Add('template-title', 'Templates'); + Add('main-common-title-lite', 'Lite Version'); + Add('main-common-title-t500', 'High-Memory Version'); + Add('main-common-randombatch', 'Random Batch'); + Add('main-menu-file-title', 'File'); + Add('main-menu-file-new', 'New'); + Add('main-menu-file-open', 'Open...'); + Add('main-menu-file-restoreautosave', 'Restore last autosave'); + Add('main-menu-file-saveparams', 'Save parameters...'); + Add('main-menu-file-saveallparams', 'Save all parameters...'); + Add('main-menu-file-smoothpalette', 'Smooth palette...'); + Add('main-menu-file-gradientbrowser', 'Gradient browser...'); + Add('main-menu-file-exportupr', 'Export UPR...'); + Add('main-menu-file-exportflame', 'Export to flam3...'); + Add('main-menu-file-importgimp', 'Import GIMP parameters...'); + Add('main-menu-file-submitsheep', 'Submit sheep'); + Add('main-menu-file-randombatch', 'Random batch'); + Add('main-menu-file-exit', 'Exit'); + Add('main-menu-edit-title', 'Edit'); + Add('main-menu-edit-saveundo', 'Save undo stack...'); + Add('main-menu-edit-copyasupr', 'Copy as UPR'); + Add('main-menu-view-title', 'View'); + Add('main-menu-view-fullscreen', 'Full screen'); + Add('main-menu-view-editor', 'Editor'); + Add('main-menu-view-adjustment', 'Adjustment'); + Add('main-menu-view-gradient', 'Gradient'); + Add('main-menu-view-mutation', 'Mutation'); + Add('main-menu-view-imagesize', 'Image size'); + Add('main-menu-view-messages', 'Messages'); + Add('main-menu-view-curves', 'Curves'); + Add('main-menu-flame-title', 'Flame'); + Add('main-menu-flame-reset', 'Reset location'); + Add('main-menu-flame-randomize', 'Randomize'); + Add('main-menu-flame-randomweights', 'Randomize weights'); + Add('main-menu-flame-equalweights', 'Equalize weights'); + Add('main-menu-flame-computeweights', 'Normalize weights'); + Add('main-menu-flame-calculatecolors', 'Calculate colors'); + Add('main-menu-flame-randomizecolors', 'Randomize colors'); + Add('main-menu-flame-rendertodisk', 'Render flame...'); + Add('main-menu-flame-renderallflames', 'Render all flames...'); + Add('main-menu-flame-resumeunfinished', 'Resume unfinished render process...'); + Add('main-menu-flame-generatereport', 'Summarize flame...'); + Add('main-menu-variation-title', 'Variation'); + Add('main-menu-variation-random', 'Random'); + Add('main-menu-variation-builtin', 'Built-in'); + Add('main-menu-variation-plugins', 'Plugins'); + Add('main-menu-script-title', 'Script'); + Add('main-menu-script-run', 'Run script'); + Add('main-menu-script-run2', 'Run "%s"'); + Add('main-menu-script-directory', 'Directory'); + Add('main-menu-script-more', 'More'); + Add('main-menu-script-stop', 'Stop script'); + Add('main-menu-script-open', 'Open...'); + Add('main-menu-script-edit', 'Edit script'); + Add('main-menu-script-managefaves', 'Manage favorites...'); + Add('main-menu-script-flametoscript', 'Generate script from flame'); + Add('main-menu-options-title', 'Tools'); + Add('main-menu-options-togglemaintoolbar', 'Show toolbar'); + Add('main-menu-options-togglestatusbar', 'Show status bar'); + Add('main-menu-options-togglefilelist', 'Show parameter list'); + Add('main-menu-options-resetfilelistwidth', 'Reset layout'); + Add('main-menu-options-showoptions', 'Settings...'); + Add('main-menu-help-title', '?'); + Add('main-menu-help-contents', 'Contents'); + Add('main-menu-help-aboutalgorithm', 'About fractal flames...'); + Add('main-menu-help-aboutapophysis', 'About Apophysis 7x...'); + Add('main-toolbar-listviewmode-classic', 'Classic view'); + Add('main-toolbar-listviewmode-icons', 'Thumbnail view'); + Add('main-toolbar-togglealpha', 'Show transparency'); + Add('main-toolbar-toggleguides', 'Show guidelines'); + Add('main-toolbar-modemove', 'Pan camera'); + Add('main-toolbar-moderotate', 'Rotate camera'); + Add('main-toolbar-modezoomin', 'Zoom in'); + Add('main-toolbar-modezoomout', 'Zoom out'); + Add('main-status-batchgenerate', 'Generating %d of %s...'); + Add('main-status-batcherror', 'Error creating batch.'); + Add('main-status-calculatingpalette', 'Calculating palette (%d%)...'); + Add('main-status-noflam3', 'Unable to find flam3 executable. Please verify your settings.'); + Add('main-status-nohelpfile', 'Please specify a help file path in the options dialog first.'); + Add('main-status-variationsorvariables', 'variations or variables'); + Add('main-status-plugins', 'plugins'); + Add('main-status-pluginpath-ioerror', 'Failed to write the setting for the plugin directory. Apophysis will use the default setting.'); + Add('main-status-noloadingerrors', 'Flame loaded without errors'); + Add('main-status-loadingerrorcount', '%d errors in flame'); + Add('main-status-morepluginsneeded', 'The flame "%s" requires the following additional %s:'); + Add('main-status-noautosave', 'No autosave present.'); + Add('main-report-transformcount', 'Transform count: %d'); + Add('main-report-finaltransform', 'Has final transform: %s'); + Add('main-report-usedplugins', 'Used plugins:'); + Add('main-report-noplugins', '(none)'); +end; + +procedure Add(key, value: string); +var entry : TKeyValuePair; +begin + Inc(tokenCount); + SetLength(language, tokenCount); + SetLength(defaultlanguage, tokenCount); + entry := TKeyValuePair.Create; + entry.key := key; + entry.value := value; + language[tokenCount - 1] := entry; + defaultlanguage[tokenCount - 1] := entry; +end; +procedure AddNoDefault(key, value: string); +var entry : TKeyValuePair; +begin + Inc(tokenCount); + SetLength(language, tokenCount); + entry := TKeyValuePair.Create; + entry.key := key; + entry.value := value; + language[tokenCount - 1] := entry; +end; + +procedure LoadLanguage(path:string); +begin + if (path = '') or (not FileExists(path)) then LoadEnglish() + else begin + tokenCount := 0; + if true then begin + parser := TParser.Create; + ListXmlScanner := TEasyXmlScanner.Create(nil); + + ListXmlScanner.OnStartTag := parser.ListXmlScannerStartTag; + ListXmlScanner.OnEndTag := parser.ListXmlScannerEndTag; + ListXmlScanner.OnEmptyTag := parser.ListXmlScannerEmptyTag; + ListXmlScanner.OnContent := parser.ListXmlScannerContent; + + ListXmlScanner.Filename := path; + ListXmlScanner.Execute; + + ListXmlScanner.Destroy; + parser.Destroy; + end; + end; +end; + +function TextByKey(key:string):string; +var i: integer; +begin + + Result := '#ERR_NO_TEXT#'; + for i:=0 to tokenCount - 1 do begin + if LowerCase(language[i].key) = LowerCase(key) then begin + Result := language[i].value; + exit; + end; + end; + + // maybe try default language? + for i:=0 to tokenCount - 1 do begin + if LowerCase(defaultlanguage[i].key) = LowerCase(key) then begin + Result := defaultlanguage[i].value; + exit; + end; + end; + +end; + +constructor TParser.Create; +begin + self.parentTagnames := TStringList.Create; +end; + +procedure TParser.ListXmlScannerStartTag(Sender: TObject; TagName: string; Attributes: TAttrList); +begin + self.parentTagnames.Add(self.currentTagname); + self.currentTagname := TagName; +end; +procedure TParser.ListXmlScannerEndTag(Sender: TObject; TagName: string); +var lastIndex : integer; +begin + lastIndex := self.parentTagnames.Count - 1; + self.currentTagname := self.parentTagnames.Strings[lastIndex]; + self.parentTagnames.Delete(lastIndex); +end; +procedure TParser.ListXmlScannerEmptyTag(Sender: TObject; TagName: string; Attributes: TAttrList); +var lastIndex : integer; +begin + self.parentTagnames.Add(self.currentTagname); + self.currentTagname := TagName; + self.ListXmlScannerContent(Sender, ''); + lastIndex := self.parentTagnames.Count - 1; + self.currentTagname := self.parentTagnames.Strings[lastIndex]; + self.parentTagnames.Delete(lastIndex); +end; +procedure TParser.ListXmlScannerContent(Sender: TObject; Content: string); +const root: string = 'stringtable'; +var key, tn: string; i: integer; +begin + for i:=0 to self.parentTagnames.Count - 1 do begin + tn := self.parentTagnames.Strings[i]; + if not (tn = '') and not (tn = root) then key := key + tn + '-'; + end; + key := key + self.currentTagname; + Add(key, Content); +end; + +end. diff --git a/Core/XFormMan.pas b/Core/XFormMan.pas new file mode 100644 index 0000000..b194b1f --- /dev/null +++ b/Core/XFormMan.pas @@ -0,0 +1,340 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit XFormMan; + +interface + +uses + BaseVariation, SysUtils, Forms, Windows; + +const + NRLOCVAR = 29; +var + NumBuiltinVars: integer; + +type + TFNToVN = record + FileName: string; + VarName: string; + end; + +function NrVar: integer; +function Varnames(const index: integer): String; +procedure RegisterVariation(Variation: TVariationLoader; supports3D, supportsDC : boolean); +function GetNrRegisteredVariations: integer; +function GetRegisteredVariation(const Index: integer): TVariationLoader; +function GetNrVariableNames: integer; +function GetVariableNameAt(const Index: integer): string; +function GetVariationIndex(const str: string): integer; +function GetVariationIndexFromVariableNameIndex(const Index: integer): integer; +procedure VarSupports(index : integer; var supports3D : boolean; var supportsDC : boolean); +procedure InitializeXFormMan; +procedure DestroyXFormMan; +procedure RegisterVariationFile(filename, name: string); +function GetFileNameOfVariation(name: string): string; + +implementation + +uses + Classes; + +var + VariationList: TList; + VariableNames: TStringlist; + loaderNum : integer; + Variable2VariationIndex : array of integer; + FNToVNList : array of TFNToVN; + FNToVNCount: integer; + +procedure InitializeXFormMan; +begin + VariationList := TList.Create; + VariableNames := TStringlist.create; + SetLength(Variable2VariationIndex,0); + SetLength(FNToVNList, 0); + FNToVNCount := 0; +end; + +procedure VarSupports(index : integer; var supports3D : boolean; var supportsDC : boolean); +const + supports3D_arr: array[0..NRLOCVAR-1] of boolean = ( + true, //'linear', + true, //'flatten', + true, //'sinusoidal', + true, //'spherical', + true, //'swirl', + true, //'horseshoe', + true, //'polar', + true, //'disc', + true, //'spiral', + true, //'hyperbolic', + true, //'diamond', + true, //'eyefish', + true, //'bubble', + true, //'cylinder', + true, //'noise', + true, //'blur', + true, //'gaussian_blur', + true, //'zblur', + true, //'blur3D', + true, //'pre_blur', + true, //'pre_zscale', + true, //'pre_ztranslate', + true, //'pre_rotate_x', + true, //'pre_rotate_y', + true, //'zscale', + true, //'ztranslate', + true, //'zcone', + true, //'post_rotate_x', + true //'post_rotate_y', + ); + supportsDC_arr: array[0..NRLOCVAR-1] of boolean = ( + false, //'linear3D', + false, //'linear', + false, //'sinusoidal', + false, //'spherical', + false, //'swirl', + false, //'horseshoe', + false, //'polar', +// false, // 'handkerchief', +// false, // 'heart', + false, //'disc', + false, //'spiral', + false, //'hyperbolic', + false, //'diamond', +// false, // 'ex', +// false, // 'julia', +// false, // 'bent', +// false, // 'waves', +// false, // 'fisheye', +// false, // 'popcorn', +// false, // 'exponential', +// false, // 'power', +// false, // 'cosine', +// false, // 'rings', +// false, // 'fan', + false, //'eyefish', + false, //'bubble', + false, //'cylinder', + false, //'noise', + false, //'blur', + false, //'gaussian_blur', + false, //'zblur', + false, //'blur3D', + + false, //'pre_blur', + false, //'pre_zscale', + false, //'pre_ztranslate', + false, //'pre_rotate_x', + false, //'pre_rotate_y', + + false, //'zscale', + false, //'ztranslate', + false, //'zcone', + + false, //'post_rotate_x', + false //'post_rotate_y' + ); +var + varl : TVariationLoader; +begin + + if (index >= NRLOCVAR) then begin + supports3D := TVariationLoader(VariationList.Items[index - NRLOCVAR]).supports3D; + supportsDC := TVariationLoader(VariationList.Items[index - NRLOCVAR]).supportsDC; + end else begin + supports3D := supports3D_arr[index]; + supportsDC := supportsDC_arr[index]; + end; +end; + + +procedure DestroyXFormMan; +var i: integer; +begin + VariableNames.Free; + + // The registered variation loaders are owned here, so we must free them. + for i := 0 to VariationList.Count-1 do + TVariationLoader(VariationList[i]).Free; + VariationList.Free; + + Finalize(Variable2VariationIndex); + Finalize(FNToVNList); +end; + +/////////////////////////////////////////////////////////////////////////////// +function NrVar: integer; +begin + Result := NRLOCVAR + VariationList.Count; +end; + +/////////////////////////////////////////////////////////////////////////////// + +function GetVariationIndexFromVariableNameIndex(const Index: integer): integer; +begin + if (Index<0) or (Index > High(Variable2VariationIndex)) then + Result := -1 + else + Result := Variable2VariationIndex[Index]; +end; + +function Varnames(const index: integer): String; +const + cvarnames: array[0..NRLOCVAR-1] of string = ( + 'linear', + 'flatten', + 'sinusoidal', + 'spherical', + 'swirl', + 'horseshoe', + 'polar', +// 'handkerchief', +// 'heart', + 'disc', + 'spiral', + 'hyperbolic', + 'diamond', +// 'ex', +// 'julia', +// 'bent', +// 'waves', +// 'fisheye', +// 'popcorn', +// 'exponential', +// 'power', +// 'cosine', +// 'rings', +// 'fan', + 'eyefish', + 'bubble', + 'cylinder', + 'noise', + 'blur', + 'gaussian_blur', + 'zblur', + 'blur3D', + + 'pre_blur', + 'pre_zscale', + 'pre_ztranslate', + 'pre_rotate_x', + 'pre_rotate_y', + + 'zscale', + 'ztranslate', + 'zcone', + + 'post_rotate_x', + 'post_rotate_y' + ); +begin + if Index < NRLOCVAR then + Result := cvarnames[Index] + else + Result := TVariationLoader(VariationList[Index - NRLOCVAR]).GetName; +end; + +/////////////////////////////////////////////////////////////////////////////// +function GetVariationIndex(const str: string): integer; +var + i: integer; +begin + i := NRVAR-1; + while (i >= 0) and (Varnames(i) <> str) do Dec(i); + Result := i; +end; + +/////////////////////////////////////////////////////////////////////////////// + +procedure RegisterVariationFile(filename, name: string); +begin + FNToVNCount := FNToVNCount + 1; + SetLength(FNToVNList, FNToVNCount); + FNToVNList[FNToVNCount - 1].FileName := filename; + FNToVNList[FNToVNCount - 1].VarName := name; +end; +function GetFileNameOfVariation(name: string): string; +var i: integer; +begin + for i := 0 to FNToVNCount - 1 do begin + if FNToVNList[i].VarName = name then begin + Result := FNToVNList[i].FileName; + Exit; + end; + end; + Result := ''; +end; + +procedure RegisterVariation(Variation: TVariationLoader; supports3D, supportsDC : boolean); +var + i: integer; + prevNumVariables:integer; +begin + OutputDebugString(PChar(Variation.GetName)); + + VariationList.Add(Variation); + Variation.Supports3D := supports3D; + Variation.SupportsDC := supportsDC; + + prevNumVariables := GetNrVariableNames; + setLength(Variable2VariationIndex, prevNumVariables + Variation.GetNrVariables); + for i := 0 to Variation.GetNrVariables - 1 do begin + VariableNames.Add(Variation.GetVariableNameAt(i)); + Variable2VariationIndex[prevNumVariables + i] := NrVar-1; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function GetNrRegisteredVariations: integer; +begin + Result := VariationList.count; +end; + +/////////////////////////////////////////////////////////////////////////////// +function GetRegisteredVariation(const Index: integer): TVariationLoader; +begin + Result := TVariationLoader(VariationList[Index]); +end; + +/////////////////////////////////////////////////////////////////////////////// +function GetNrVariableNames: integer; +begin + Result := VariableNames.Count; +end; + +/////////////////////////////////////////////////////////////////////////////// +function GetVariableNameAt(const Index: integer): string; +begin + Result := VariableNames[Index]; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + InitializeXFormMan; + +finalization + DestroyXFormMan; + +end. diff --git a/Flame/ControlPoint.pas b/Flame/ControlPoint.pas new file mode 100644 index 0000000..46980d9 --- /dev/null +++ b/Flame/ControlPoint.pas @@ -0,0 +1,2833 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit ControlPoint; + +interface + +//{$define VAR_STR} + +uses + Classes, Windows, Cmap, XForm, XFormMan, Binary, + SysUtils, math, ZLib, Bezier; + +const + SUB_BATCH_SIZE = 10000; + PROP_TABLE_SIZE = 1024; + PREFILTER_WHITE = (1 shl 26); + FILTER_CUTOFF = 1.8; + BRIGHT_ADJUST = 2.3; + FUSE = 15; + +type + TCoefsArray= array[0..2, 0..1] of double; + pCoefsArray= ^TCoefsArray; + TTriangle = record + x: array[0..2] of double; + y: array[0..2] of double; + end; + TTriangles = array[-1..NXFORMS] of TTriangle; + TSPoint = record + x: double; + y: double; + end; + TSRect = record + Left, Top, Right, Bottom: double; + end; + TMapPalette = record + Red: array[0..255] of byte; + Green: array[0..255] of byte; + Blue: array[0..255] of byte; + end; + TColorMaps = record + Identifier: string; + UGRFile: string; + end; + pPixArray = ^TPixArray; + TPixArray = array[0..1279, 0..1023, 0..3] of integer; + pPreviewPixArray = ^TPreviewPixArray; + TPreviewPixArray = array[0..159, 0..119, 0..3] of integer; + TFileType = (ftIfs, ftFla, ftXML); + +type //? + PLongintArray = ^TLongintArray; + TLongintArray = array[0..8192] of Longint; + +type + TVariation = (vLinear, vSinusoidal, vSpherical, vSwirl, vHorseshoe, vPolar, + vHandkerchief, vHeart, vDisc, vSpiral, vHyperbolic, vSquare, vEx, vJulia, + vBent, vWaves, vFisheye, vPopcorn, vExponential, vPower, vCosine, + vRings, vFan, vRandom); + +type + TPointsArray = array of TCPpoint; + TPointsXYArray = array of TXYpoint; + + P2Cpoint = ^T2Cpoint; + T2CPointsArray = array of T2Cpoint; + + TControlPoint = class + public + finalXform: TXForm; + finalXformEnabled: boolean; + useFinalXform: boolean; + soloXform: integer; + curvePoints: array [0..3] of BezierPoints; + curveWeights: array [0..3] of BezierWeights; + + Transparency: boolean; + + cameraPitch, cameraYaw, cameraPersp, cameraDOF: double; + cameraZpos: double; + ProjectionFunc: procedure(pPoint: PCPPoint) of object; + + xform: array[0..NXFORMS] of TXForm; + + noLinearFix: boolean; + variation: TVariation; + cmap: TColorMap; + cmapindex: integer; + time: double; + Fbrightness: double; // 1.0 = normal + contrast: double; // 1.0 = normal + gamma: double; + Width: integer; + Height: integer; + spatial_oversample: integer; + name, nick, url: string; + center: array[0..1] of double; // camera center + vibrancy: double; // blend between color algs (0=old,1=new) + hue_rotation: double; // applies to cmap, 0-1 + background: array[0..3] of Integer; // Changed to integers so no conversion needed - mt + zoom: double; // effects ppu and sample density + pixels_per_unit: double; // and scale + spatial_filter_radius: double; // variance of gaussian + sample_density: extended; // samples per pixel (not bucket) + (* in order to motion blur more accurately we compute the logs of the + sample density many times and average the results. we interplate + only this many times. *) + actual_density: extended; // for incomplete renders + nbatches: integer; // this much color resolution. but making it too high induces clipping + white_level: integer; + cmap_inter: integer; // if this is true, then color map interpolates one entry + // at a time with a bright edge + symmetry: integer; + pulse: array[0..1, 0..1] of double; // [i][0]=magnitute [i][1]=frequency */ + wiggle: array[0..1, 0..1] of double; // frequency is /minute, assuming 30 frames/s */ + + estimator, estimator_min, estimator_curve: double; // density estimator. + jitters: integer; + gamma_threshold: double; + enable_de : boolean; + used_plugins : TStringList; + +// PropTable: array of TXForm; + FAngle: Double; + FTwoColorDimensions: Boolean; + + procedure FillUsedPlugins; + + private + invalidXform: TXForm; + + CameraMatrix: array[0..2, 0..2] of double; + DofCoef: double; + gauss_rnd: array [0..3] of double; + gauss_N: integer; + + procedure ProjectNone(pPoint: PCPPoint); + procedure ProjectPitch(pPoint: PCPPoint); + procedure ProjectPitchYaw(pPoint: PCPPoint); + procedure ProjectPitchDOF(pPoint: PCPPoint); + procedure ProjectPitchYawDOF(pPoint: PCPPoint); + + function getppux: double; + function getppuy: double; + + function GetBrightness: double; + procedure SetBrightness(br: double); + function GetRelativeGammaThreshold: double; + procedure SetRelativeGammaThreshold(gtr: double); + + public + xdata : string; + + procedure SaveToStringlist(sl: TStringlist); + procedure SaveToFile(Filename: string); + procedure SaveToBinary(const handle: File); + + procedure ParseString(aString: string); + procedure ParseStringList(sl: TStringlist); + procedure RandomCP(min: integer = 2; max: integer = NXFORMS; calc: boolean = true); + procedure RandomCP1; + procedure CalcBoundbox; + function BlowsUp(NrPoints: integer): boolean; + + procedure SetVariation(vari: TVariation); + procedure Clear; + +// class function interpolate(cp1, cp2: TControlPoint; Time: double): TControlPoint; /// just for now + procedure InterpolateX(cp1, cp2: TControlPoint; Tm: double); +// procedure Iterate_Old(NrPoints: integer; var Points: TPointsArray); + procedure IterateXY(NrPoints: integer; var Points: TPointsXYArray); + procedure IterateXYC(NrPoints: integer; var Points: TPointsArray); +// procedure IterateXYCC(NrPoints: integer; var Points: T2CPointsArray); + + procedure Prepare; +// procedure Testiterate(NrPoints: integer; var Points: TPointsArray); + + function Clone: TControlPoint; + procedure Copy(cp1: TControlPoint; KeepSizes: boolean = false); + +// function HasNewVariants: boolean; + function HasFinalXForm: boolean; + + // CP-specific functions moved from unit Main + function NumXForms: integer; + function TrianglesFromCP(var Triangles: TTriangles): integer; + procedure GetFromTriangles(const Triangles: TTriangles; const t: integer); + + procedure GetTriangle(var Triangle: TTriangle; const n: integer); + procedure GetPostTriangle(var Triangle: TTriangle; const n: integer); + + procedure EqualizeWeights; + procedure NormalizeWeights; + procedure RandomizeWeights; + procedure ComputeWeights(Triangles: TTriangles; t: integer); + procedure AdjustScale(w, h: integer); + + constructor Create; + destructor Destroy; override; + + procedure ZoomtoRect(R: TSRect); + procedure ZoomOuttoRect(R: TSRect); + procedure MoveRect(R: TSRect); + procedure ZoomIn(Factor: double); + procedure Rotate(Angle: double); + + property ppux: double read getppux; + property ppuy: double read getppuy; + + property brightness: double + read GetBrightness + write SetBrightness; + property gammaThreshRelative: double + read GetRelativeGammaThreshold + write SetRelativeGammaThreshold; + end; + +function add_symmetry_to_control_point(var cp: TControlPoint; sym: integer): integer; +function CalcUPRMagn(const cp: TControlPoint): double; +procedure FillVarDisturb; +function CalcBinaryFlameSize(cp: TControlPoint): integer; + +implementation + +uses global; + +var + var_distrib: array of integer; + mixed_var_distrib: array of integer; + +{ TControlPoint } + +function sign(n: double): double; +begin + if n < 0 then Result := -1 + else if n > 0 then Result := 1 + else Result := 0; +end; + +procedure TControlPoint.FillUsedPlugins; +var + i, j, k, f : integer; + v : double; + s : String; +begin + used_plugins.Clear; + + f := -1; if self.finalXformEnabled then f := 0; + //MessageBox(0, PCHAR(IntToStr(NumXForms + f)), PCHAR(''), 0); + + for i := 0 to Min(NumXForms+f, NXFORMS) do + with xform[i] do begin + for j := 0 to NRVAR - 1 do begin + v := self.xform[i].GetVariation(j); + if (v <> 0) and // uses variation + (used_plugins.IndexOf(Varnames(j)) < 0) // not listed yet + then begin + used_plugins.Add(Varnames(j)); + s := s + Varnames(j) + ' on TX #' + IntToStr(i + 1) + #13#10; + end; + end; + end; + + //MessageBox(0, PCHAR(s), PCHAR(''), MB_OK); + + // Faulty... + (* + for i := 0 to NumXforms-1 do begin + for j := NumBuiltinVars to xform[i].NumVariations-1 do begin + v := self.xform[i].GetVariation(j); + if (v = 0) then continue; + s := Varnames(j); + k := used_plugins.IndexOf(s); + if (k < 0) or (k >= used_plugins.Count) then + used_plugins.Add(s); + end; + end; + if finalXformEnabled then begin + for j := NumBuiltinVars to self.finalXform.NumVariations-1 do begin + v := self.finalXform.GetVariation(j); + s := Varnames(j); + if (v = 0) then continue; + k := used_plugins.IndexOf(s); + if (k < 0) or (k >= used_plugins.Count) then + used_plugins.Add(s); + end; + end; + *) +end; + +constructor TControlPoint.Create; +var + i: Integer; +begin + for i := 0 to NXFORMS do begin + xform[i] := TXForm.Create; + end; + invalidXform := TXForm.Create; + soloXform := -1; + + pulse[0][0] := 0; + pulse[0][1] := 60; + pulse[1][0] := 0; + pulse[1][1] := 60; + + wiggle[0][0] := 0; + wiggle[0][1] := 60; + wiggle[1][0] := 0; + wiggle[1][1] := 60; + + background[0] := 0; + background[1] := 0; + background[2] := 0; + + for i := 0 to 3 do + begin + curvePoints[i][0].x := 0.00; curvePoints[i][0].y := 0.00; curveWeights[i][0] := 1; + curvePoints[i][1].x := 0.00; curvePoints[i][1].y := 0.00; curveWeights[i][1] := 1; + curvePoints[i][2].x := 1.00; curvePoints[i][2].y := 1.00; curveWeights[i][2] := 1; + curvePoints[i][3].x := 1.00; curvePoints[i][3].y := 1.00; curveWeights[i][3] := 1; + end; + + center[0] := 0; + center[1] := 0; + + pixels_per_unit := 50; + + width := 100; + Height := 100; + + spatial_oversample := 1; + spatial_filter_radius := 0.5; + + FAngle := 0; + gamma := 1; + vibrancy := 1; + contrast := 1; + Fbrightness := 1; + + sample_density := 50; + zoom := 0; + nbatches := 1; + + white_level := 200; + + estimator := 9.0; + estimator_min := 0.0; + estimator_curve := 0.4; + enable_de := false; + jitters := 1; + gamma_threshold := 0.01; + + FTwoColorDimensions := False; + + finalXformEnabled := false; + Transparency := false; + + cameraPitch := 0; + cameraYaw := 0; + cameraPersp := 0; + cameraZpos := 0; + cameraDOF := 0; + + used_plugins := TStringList.Create; + xdata := ''; +end; + +destructor TControlPoint.Destroy; +var + i: Integer; +begin + for i := 0 to NXFORMS do + xform[i].Free; + invalidXform.Free; + + //used_plugins.Free; <<< -X- commenting out = hack - fixme! + inherited; +end; + +procedure TControlPoint.Prepare; +var + i, n: Integer; + propsum: double; + LoopValue: double; + j: integer; + TotValue: double; + + k: integer; + tp: array[0..NXFORMS] of double; +begin +// SetLength(PropTable, PROP_TABLE_SIZE); + + //totValue := 0; + n := NumXforms; + assert(n > 0); + + finalXform := xform[n]; + finalXform.Prepare; + useFinalXform := FinalXformEnabled and HasFinalXform; + for i := 0 to n - 1 do begin + xform[i].Prepare; + //totValue := totValue + xform[i].density; + end; + invalidXform.PrepareInvalidXForm; + + if soloXform >= 0 then begin + for i := 0 to n - 1 do begin + xform[i].transOpacity := 0; + end; + xform[soloXform].transOpacity := 1; + end; + + for k := 0 to n - 1 do begin + totValue := 0; + SetLength(xform[k].PropTable, PROP_TABLE_SIZE); + + for i := 0 to n - 1 do begin + tp[i] := xform[i].density * xform[k].modWeights[i]; + totValue := totValue + tp[i]; + end; + + if totValue > 0 then begin + LoopValue := 0; + for i := 0 to PROP_TABLE_SIZE-1 do begin + propsum := 0; + j := -1; + repeat + inc(j); + propsum := propsum + tp[j];//xform[j].density; + until (propsum > LoopValue) or (j = n - 1); + + //assert(tp[j]<>0); + + xform[k].PropTable[i] := xform[j]; + LoopValue := LoopValue + TotValue / PROP_TABLE_SIZE; + end; + end + else begin + for i := 0 to PROP_TABLE_SIZE-1 do + xform[k].PropTable[i] := invalidXform; + end; + end; + + // 3D camera precalc + + CameraMatrix[0, 0] := cos(-CameraYaw); + CameraMatrix[1, 0] := -sin(-CameraYaw); + CameraMatrix[2, 0] := 0; + CameraMatrix[0, 1] := cos(CameraPitch) * sin(-CameraYaw); + CameraMatrix[1, 1] := cos(CameraPitch) * cos(-CameraYaw); + CameraMatrix[2, 1] := -sin(CameraPitch); + CameraMatrix[0, 2] := sin(CameraPitch) * sin(-CameraYaw); + CameraMatrix[1, 2] := sin(CameraPitch) * cos(-CameraYaw); + CameraMatrix[2, 2] := cos(CameraPitch); + DofCoef := 0.1 * CameraDOF; + gauss_rnd[0] := random; + gauss_rnd[1] := random; + gauss_rnd[2] := random; + gauss_rnd[3] := random; + gauss_N := 0; + + if (CameraDOF <> 0) then begin + if (CameraYaw <> 0) then + ProjectionFunc := ProjectPitchYawDOF + else + ProjectionFunc := ProjectPitchDOF; + end + else if (CameraPitch <> 0) or (CameraYaw <> 0) then begin + if (CameraYaw <> 0) then + ProjectionFunc := ProjectPitchYaw + else + ProjectionFunc := ProjectPitch; + end + else ProjectionFunc := ProjectNone; +end; + +procedure TControlPoint.IterateXY(NrPoints: integer; var Points: TPointsXYArray); +var + i: Integer; + px, py: double; + pPoint: PXYPoint; + + xf: TXform; +begin + px := 2 * random - 1; + py := 2 * random - 1; + + try + xf := xform[0];//random(NumXForms)]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPointXY(px,py); + end; + + pPoint := @Points[0]; + + if UseFinalXform then + for i := 0 to NrPoints - 1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPointXY(px,py); + if (xf.transOpacity = 0) then + pPoint^.x := MaxDouble // hack + else begin + pPoint^.X := px; + pPoint^.Y := py; + end; + finalXform.NextPointXY(pPoint^.X, pPoint^.y); + Inc(pPoint); + end + else + for i := 0 to NrPoints - 1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPointXY(px,py); + if (xf.transOpacity = 0) then + pPoint^.x := MaxDouble // hack + else begin + pPoint.X := px; + pPoint.Y := py; + end; + Inc(pPoint); + end; + except + on EMathError do begin + exit; + end; + end; +end; + +procedure TControlPoint.IterateXYC(NrPoints: integer; var Points: TPointsArray); +var + i: Integer; + p: TCPPoint; + pPoint: PCPPoint; + depth: double; + + xf: TXform; +begin + p.x := 2 * random - 1; + p.y := 2 * random - 1; + p.c := random; + + try + xf := xform[0];//random(NumXForms)]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + end; + + pPoint := @Points[0]; + + if UseFinalXform then + for i := 0 to NrPoints - 1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + + //if random >= xf.transOpacity then continue; + finalXform.NextPointTo(p, pPoint^); + + ProjectionFunc(pPoint); + pPoint^.o := xf.transOpacity; + Inc(pPoint); + end + else + for i := 0 to NrPoints - 1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + + //if random >= xf.transOpacity then continue; + pPoint^ := p; + ProjectionFunc(pPoint); + pPoint^.o := xf.transOpacity; + Inc(pPoint); + end; + except + on EMathError do begin + exit; + end; + end; +end; + +procedure TControlPoint.ProjectNone(pPoint: PCPPoint); +var + zr: double; +begin + zr := 1 - cameraPersp * (pPoint^.z - CameraZpos); + + pPoint^.x := pPoint^.x / zr; + pPoint^.y := pPoint^.y / zr; + pPoint^.z := pPoint^.z - CameraZpos; +end; + +procedure TControlPoint.ProjectPitch(pPoint: PCPPoint); +var + y, z, zr: double; +begin + z := pPoint^.z - CameraZpos; + y := CameraMatrix[1,1]*pPoint^.y + CameraMatrix[2,1]*z; + zr := 1 - cameraPersp * + (CameraMatrix[1,2]*pPoint^.y + CameraMatrix[2,2]*z); + + pPoint^.x := pPoint^.x / zr; + pPoint^.y := y / zr; + pPoint^.z := pPoint^.z - CameraZpos; +end; + +procedure TControlPoint.ProjectPitchYaw(pPoint: PCPPoint); +var + x, y, z, zr: double; +begin + z := pPoint^.z - CameraZpos; + x := CameraMatrix[0,0]*pPoint^.x + CameraMatrix[1,0]*pPoint^.y; + y := CameraMatrix[0,1]*pPoint^.x + CameraMatrix[1,1]*pPoint^.y + CameraMatrix[2,1]*z; + zr := 1 - cameraPersp * + (CameraMatrix[0,2]*pPoint^.x + CameraMatrix[1,2]*pPoint^.y + CameraMatrix[2,2]*z); + + pPoint^.x := x / zr; + pPoint^.y := y / zr; + pPoint^.z := pPoint^.z - CameraZpos; +end; + +procedure TControlPoint.ProjectPitchDOF(pPoint: PCPPoint); +var + x, y, z, zr, dr: double; + dsin, dcos: double; + t: double; +begin + z := pPoint^.z - CameraZpos; + y := CameraMatrix[1,1]*pPoint^.y + CameraMatrix[2,1]*z; + z := CameraMatrix[1,2]*pPoint^.y + CameraMatrix[2,2]*z; + zr := 1 - cameraPersp * z; + +//{$define GAUSSIAN_DOF} +{$ifdef GAUSSIAN_DOF} + asm + fld qword ptr [eax + gauss_rnd] + fadd qword ptr [eax + gauss_rnd+8] + fadd qword ptr [eax + gauss_rnd+16] + fadd qword ptr [eax + gauss_rnd+24] + fld1 + fadd st, st + fsubp st(1),st + fmul qword ptr [eax + dofCoef] + fmul qword ptr [z] + fstp qword ptr [dr] + call System.@RandExt + mov edx, [eax + gauss_N] + fst qword ptr [eax + gauss_rnd + edx*8] + inc edx + and edx,$03 + mov [eax + gauss_N], edx + fadd st, st + fldpi + fmulp + fsincos + fstp qword ptr [dcos] + fstp qword ptr [dsin] + end; +{$else} + //sincos(random*2*pi, dsin, dcos); + t := random*2*pi; + dsin := sin(t); dcos := cos(t); + dr := random * dofCoef * z; +{ + asm + fld qword ptr [z] + fmul st, st + fmul qword ptr [eax + dofCoef] + fldpi + fadd st, st + call System.@RandExt + fmulp + fsincos + fstp qword ptr [dcos] + fstp qword ptr [dsin] + call System.@RandExt + fmulp + fstp qword ptr [dr] + end; +} +{$endif} + + pPoint^.x := (pPoint^.x + dr*dcos) / zr; + pPoint^.y := (y + dr*dsin) / zr; + pPoint^.z := pPoint^.z - CameraZpos; +end; + +procedure TControlPoint.ProjectPitchYawDOF(pPoint: PCPPoint); +var + x, y, z, zr, dr: double; + dsin, dcos: double; + t : double; +begin + z := pPoint^.z - CameraZpos; + x := CameraMatrix[0,0]*pPoint^.x + CameraMatrix[1,0]*pPoint^.y; + y := CameraMatrix[0,1]*pPoint^.x + CameraMatrix[1,1]*pPoint^.y + CameraMatrix[2,1]*z; + z := CameraMatrix[0,2]*pPoint^.x + CameraMatrix[1,2]*pPoint^.y + CameraMatrix[2,2]*z; + zr := 1 - cameraPersp * z; + +{$ifdef GAUSSIAN_DOF} + asm + fld qword ptr [eax + gauss_rnd] + fadd qword ptr [eax + gauss_rnd+8] + fadd qword ptr [eax + gauss_rnd+16] + fadd qword ptr [eax + gauss_rnd+24] + fld1 + fadd st, st + fsubp st(1),st + fmul qword ptr [eax + dofCoef] + fmul qword ptr [z] + fstp qword ptr [dr] + call System.@RandExt + mov edx, [eax + gauss_N] + fst qword ptr [eax + gauss_rnd + edx*8] + inc edx + and edx,$03 + mov [eax + gauss_N], edx + fadd st, st + fldpi + fmulp + fsincos + fstp qword ptr [dcos] + fstp qword ptr [dsin] + end; +{$else} + //sincos(random*2*pi, dsin, dcos); + t := random * 2 * pi; + dsin := sin(t); dcos := cos(t); + dr := random * dofCoef * z; +{ + asm + fld qword ptr [z] + fmul st, st + fmul qword ptr [eax + dofCoef] + fldpi + fadd st, st + call System.@RandExt + fmulp + fsincos + fstp qword ptr [dcos] + fstp qword ptr [dsin] + call System.@RandExt + fmulp + fstp qword ptr [dr] + end; +} +{$endif} + + pPoint^.x := (x + dr*dcos) / zr; + pPoint^.y := (y + dr*dsin) / zr; + pPoint^.z := pPoint^.z - CameraZpos; +end; + +{ +procedure TControlPoint.IterateXYCC(NrPoints: integer; var Points: T2CPointsArray); +var + i: Integer; + //px, py, pc1, pc2: double; + p: T2CPoint; + CurrentPoint: P2Cpoint; + + xf: TXform; +begin + p.x := 2 * random - 1; + p.y := 2 * random - 1; + p.c1 := random; + p.c2 := random; + + try + xf := xform[random(NumXForms)]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint2C(p);//px, py, pc1, pc2); + end; + + CurrentPoint := @Points[0]; +if UseFinalXform then + for i := 0 to NrPoints - 1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint2C(p);//px, py, pc1, pc2); + CurrentPoint.X := p.x; + CurrentPoint.Y := p.y; + CurrentPoint.C1 := p.c1; + CurrentPoint.C2 := p.c2; + finalXform.NextPoint2C(CurrentPoint^); + Inc(CurrentPoint); + end +else + for i := 0 to NrPoints - 1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint2C(p); + CurrentPoint.X := p.x; + CurrentPoint.Y := p.y; + CurrentPoint.C1 := p.c1; + CurrentPoint.C2 := p.c2; + Inc(CurrentPoint); + end + except + on EMathError do begin + exit; + end; + end; +end; +} + +function TControlPoint.BlowsUp(NrPoints: integer): boolean; +var + i, n: Integer; + px, py: double; + minx, maxx, miny, maxy: double; + Points: TPointsXYArray; + CurrentPoint: PXYPoint; + + xf: TXForm; +begin + Result := false; + + n := min(SUB_BATCH_SIZE, NrPoints); + SetLength(Points, n); + + px := 2 * random - 1; + py := 2 * random - 1; + + Prepare; + + try + xf := xform[random(NumXForms)]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPointXY(px,py); + end; + + CurrentPoint := @Points[0]; + for i := 0 to n-1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPointXY(px,py); + CurrentPoint.X := px; + CurrentPoint.Y := py; + Inc(CurrentPoint); + // random CPs don't use finalXform... + end; + except + on EMathError do begin + Result := True; + Exit; + end; + end; + + // It is possible that the transformation will grow very large but remain below the overflow line + minx := 1E10; + maxx := -1E10; + miny := 1E10; + maxy := -1E10; + for i := 0 to n-1 do begin + minx := min(minx, Points[i].x); + maxx := max(maxx, Points[i].x); + miny := min(miny, Points[i].y); + maxy := max(maxy, Points[i].y); + end; + + if ((Maxx - MinX) > 1000) or ((Maxy - Miny) > 1000) then + Result := True; +end; + + +procedure TControlPoint.ParseString(aString: string); +var + ParseValues: TStringList; + ParsePos: integer; + CurrentToken: string; + CurrentXForm: integer; + i: integer; + OldDecimalSperator: Char; + v: double; +begin + ParseValues := TStringList.Create; + ParseValues.CommaText := AString; + + OldDecimalSperator := FormatSettings.DecimalSeparator; + FormatSettings.DecimalSeparator := '.'; + + CurrentXForm := 0; + + ParsePos := 0; + while (ParsePos < ParseValues.Count) do begin + CurrentToken := ParseValues[ParsePos]; + if AnsiCompareText(CurrentToken, 'xform') = 0 then begin + Inc(ParsePos); + CurrentXForm := StrToInt(ParseValues[ParsePos]); + (*end else if AnsiCompareText(CurrentToken, 'plugins') = 0 then begin + used_plugins.Clear; + i := 0; + while true do begin + if (ParsePos + 1) >= ParseValues.Count then + break; + + Inc(ParsePos); + used_plugins.Add(ParseValues[ParsePos]); + Inc(i); + end; *) + end else if AnsiCompareText(CurrentToken, 'finalxformenabled') = 0 then begin + Inc(ParsePos); + finalxformenabled := StrToInt(ParseValues[ParsePos]) <> 0; + end else if AnsiCompareText(CurrentToken, 'soloxform') = 0 then begin + Inc(ParsePos); + soloxform := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'time') = 0 then begin + Inc(ParsePos); + time := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'brightness') = 0 then begin + Inc(ParsePos); + brightness := StrToFloat(ParseValues[ParsePos]) / BRIGHT_ADJUST; + end else if AnsiCompareText(CurrentToken, 'zoom') = 0 then begin // mt + Inc(ParsePos); // mt + zoom := StrToFloat(ParseValues[ParsePos]); // mt + end else if AnsiCompareText(CurrentToken, 'angle') = 0 then begin + Inc(ParsePos); + FAngle := StrToFloat(ParseValues[ParsePos]); +// 3d camera stuff + end else if AnsiCompareText(CurrentToken, 'cam_pitch') = 0 then begin + Inc(ParsePos); + cameraPitch := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'cam_yaw') = 0 then begin + Inc(ParsePos); + cameraYaw := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'cam_persp') = 0 then begin + Inc(ParsePos); + cameraPersp := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'cam_zpos') = 0 then begin + Inc(ParsePos); + cameraZpos := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'cam_dof') = 0 then begin + Inc(ParsePos); + cameraDOF := abs(StrToFloat(ParseValues[ParsePos])); +// end 3d + end else if AnsiCompareText(CurrentToken, 'contrast') = 0 then begin + Inc(ParsePos); + contrast := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'gamma') = 0 then begin + Inc(ParsePos); + gamma := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'vibrancy') = 0 then begin + Inc(ParsePos); + vibrancy := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'gamma_threshold') = 0 then begin + Inc(ParsePos); + gamma_threshold := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'hue_rotation') = 0 then begin + Inc(ParsePos); + hue_rotation := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'zoom') = 0 then begin + Inc(ParsePos); + zoom := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'imagesize') = 0 then begin + Inc(ParsePos); + Width := StrToInt(ParseValues[ParsePos]); + Inc(ParsePos); + Height := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'image_size') = 0 then begin + Inc(ParsePos); + Width := StrToInt(ParseValues[ParsePos]); + Inc(ParsePos); + Height := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'center') = 0 then begin + Inc(ParsePos); + center[0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + center[1] := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'background') = 0 then begin + Inc(ParsePos); + // Trap conversion errors for older parameters + try + background[0] := StrToInt(ParseValues[ParsePos]); + except on EConvertError do + background[0] := 0; + end; + Inc(ParsePos); + try + background[1] := StrToInt(ParseValues[ParsePos]); + except on EConvertError do + background[1] := 0; + end; + Inc(ParsePos); + try + background[2] := StrToInt(ParseValues[ParsePos]); + except on EConvertError do + background[2] := 0; + end; + end else if AnsiCompareText(CurrentToken, 'curves') = 0 then begin + for i := 0 to 3 do + begin + Inc(ParsePos);curvePoints[i][0].x := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curvePoints[i][0].y := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curveWeights[i][0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curvePoints[i][1].x := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curvePoints[i][1].y := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curveWeights[i][1] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curvePoints[i][2].x := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curvePoints[i][2].y := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curveWeights[i][2] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curvePoints[i][3].x := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curvePoints[i][3].y := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos);curveWeights[i][3] := StrToFloat(ParseValues[ParsePos]); + end; + end else if AnsiCompareText(CurrentToken, 'pulse') = 0 then begin + Inc(ParsePos); + pulse[0, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + pulse[0, 1] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + pulse[1, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + pulse[1, 1] := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'wiggle') = 0 then begin + Inc(ParsePos); + wiggle[0, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + wiggle[0, 1] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + wiggle[1, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + wiggle[1, 1] := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'pixels_per_unit') = 0 then begin + Inc(ParsePos); + pixels_per_unit := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'spatial_filter_radius') = 0 then begin + Inc(ParsePos); + spatial_filter_radius := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'spatial_oversample') = 0 then begin + Inc(ParsePos); + spatial_oversample := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'sample_density') = 0 then begin + Inc(ParsePos); + sample_density := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'nbatches') = 0 then begin + Inc(ParsePos); + nbatches := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'white_level') = 0 then begin + Inc(ParsePos); + white_level := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'cmap') = 0 then begin + Inc(ParsePos); + cmapindex := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'cmap_inter') = 0 then begin + Inc(ParsePos); + cmap_inter := StrToInt(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'palette') = 0 then begin +// Inc(ParsePos); +// cmapindex := StrToInt(ParseValues[ParsePos]); + OutputDebugString(Pchar('NYI import Palette')); + end else if AnsiCompareText(CurrentToken, 'density') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].Density := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'color') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].color := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'symmetry') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].symmetry := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'coefs') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].c[0, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].c[0, 1] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].c[1, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].c[1, 1] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].c[2, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].c[2, 1] := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'post') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].p[0, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].p[0, 1] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].p[1, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].p[1, 1] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].p[2, 0] := StrToFloat(ParseValues[ParsePos]); + Inc(ParsePos); + xform[CurrentXForm].p[2, 1] := StrToFloat(ParseValues[ParsePos]); + end else if AnsiCompareText(CurrentToken, 'postxswap') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].postXswap := (ParseValues[ParsePos] = '1'); + end else if AnsiCompareText(CurrentToken, 'autozscale') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].autoZscale := (ParseValues[ParsePos] = '1'); + end else if AnsiCompareText(CurrentToken, 'vars') = 0 then begin + for i := 0 to NRVAR - 1 do begin + xform[CurrentXForm].SetVariation(i, 0.0); + end; + + i := 0; + while true do begin + if (ParsePos + 1) >= ParseValues.Count then + break; + if CharInSet(ParseValues[ParsePos + 1][1], ['a'..'z', 'A'..'Z']) then + break; + + Inc(ParsePos); + xform[CurrentXForm].SetVariation(i, StrToFloat(ParseValues[ParsePos])); + Inc(i); + end; + end else if AnsiCompareText(CurrentToken, 'variables') = 0 then begin +{ + v := 0; + for i:= 0 to GetNrVariableNames-1 do begin + xform[CurrentXForm].SetVariable(GetVariableNameAt(i), v); + end; +} + for i:= 0 to GetNrVariableNames-1 do begin + xform[CurrentXForm].ResetVariable(GetVariableNameAt(i)); + end; + + i := 0; + while true do begin + if (ParsePos + 1) >= ParseValues.Count then + break; + if CharInSet(ParseValues[ParsePos + 1][1], ['a'..'z', 'A'..'Z']) then + break; + + Inc(ParsePos); + v := StrToFloat(ParseValues[ParsePos]); + xform[CurrentXForm].SetVariable(GetVariableNameAt(i), v); + Inc(i); + end; + + end else if AnsiCompareText(CurrentToken, 'chaos') = 0 then begin + i := 0; + while true do begin + if (ParsePos + 1) >= ParseValues.Count then + break; + if CharInSet(ParseValues[ParsePos + 1][1], ['a'..'z', 'A'..'Z']) then + break; + + Inc(ParsePos); + v := StrToFloat(ParseValues[ParsePos]); + xform[CurrentXForm].modWeights[i] := v; + Inc(i); + end; + + end else if AnsiCompareText(CurrentToken, 'plotmode') = 0 then begin + Inc(ParsePos); + if((StrToInt(ParseValues[ParsePos]) = 1)) then + xform[CurrentXForm].transOpacity := 0; + end else if AnsiCompareText(CurrentToken, 'opacity') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].transOpacity := (StrToFloat(ParseValues[ParsePos])); + end else if AnsiCompareText(CurrentToken, 'var_color') = 0 then begin + Inc(ParsePos); + xform[CurrentXForm].pluginColor := (StrToFloat(ParseValues[ParsePos])); + end else begin + OutputDebugString(Pchar('Unknown Token: ' + CurrentToken)); + end; + + Inc(ParsePos); + end; + GetCmap(cmapindex, hue_rotation, Cmap); + + ParseValues.Free; + + FormatSettings.DecimalSeparator := OldDecimalSperator; +end; + + +procedure TControlPoint.SetVariation(vari: TVariation); +var + i, j, v: integer; + rv: integer; + VarPossible: boolean; +begin + FillVarDisturb; + VarPossible := false; + for j := 0 to NRVAR - 1 do begin + VarPossible := VarPossible or Variations[j]; + end; + + if VarPossible then begin + repeat + rv := var_distrib[random(Length(var_distrib))]; + until Variations[rv]; + end else begin + rv := 0; + end; + + for i := 0 to NXFORMS - 1 do begin + for j := 0 to NRVAR - 1 do begin + xform[i].SetVariation(j, 0.0); + end; + + if vari = vRandom then + begin + if rv < 0 then + begin + if VarPossible then begin + repeat + v := Mixed_var_distrib[random(Length(mixed_var_distrib))]; + until Variations[v]; // Use only Variations set in options + end else begin + v := 0; + end; + xform[i].SetVariation(v, 1.0); + end + else + xform[i].SetVariation(rv, 1.0); + end + else + xform[i].SetVariation(integer(vari), 1); + end; +end; + +procedure TControlPoint.RandomCP(min: integer = 2; max: integer = NXFORMS; calc: boolean = true); +var + nrXforms: integer; + i, j: integer; + v, rv: integer; + VarPossible: boolean; +begin +//hue_rotation := random; + hue_rotation := 1; + cmapindex := RANDOMCMAP; + GetCmap(cmapindex, hue_rotation, cmap); + time := 0.0; + +//nrXforms := xform_distrib[random(13)]; + nrXforms := random(Max - (Min - 1)) + Min; + + FillVarDisturb; + VarPossible := false; + for j := 0 to NRVAR - 1 do begin + VarPossible := VarPossible or Variations[j]; + end; + + if VarPossible then begin + repeat + rv := var_distrib[random(Length(var_distrib))]; + until Variations[rv]; + end else begin + rv := 0; + end; + + for i := 0 to NXFORMS - 1 do begin + xform[i].density := 0; + end; + + for i := 0 to nrXforms - 1 do begin + xform[i].density := 1.0 / nrXforms; + xform[i].color := i / (nrXforms - 1); + + xform[i].c[0][0] := 2 * random - 1; + xform[i].c[0][1] := 2 * random - 1; + xform[i].c[1][0] := 2 * random - 1; + xform[i].c[1][1] := 2 * random - 1; + xform[i].c[2][0] := 4 * random - 2; + xform[i].c[2][1] := 4 * random - 2; + + for j := 0 to NRVAR - 1 do begin + xform[i].SetVariation(j, 0); + end; + + for j := 0 to NRVAR - 1 do begin + xform[i].SetVariation(j, 0); + end; + + if rv < 0 then begin + if VarPossible then begin + repeat + v := Mixed_var_distrib[random(Length(mixed_var_distrib))]; + until Variations[v]; // use only variations set in options + end else begin + v := 0; + end; + + xform[i].SetVariation(v, 1); + end else + xform[i].SetVariation(rv, 1); + + end; + if calc then + CalcBoundbox; +end; + +procedure TControlPoint.RandomCP1; +var + i, j: Integer; +begin + RandomCP; + for i := 0 to NXFORMS - 1 do begin + for j := 0 to NRVAR - 1 do begin + xform[i].SetVariation(j, 0); + end; + xform[i].SetVariation(0, 1); + end; + + CalcBoundbox; +end; + +procedure TControlPoint.CalcBoundbox; +var + Points: TPointsXYArray; + i, j: integer; + deltax, minx, maxx: double; + cntminx, cntmaxx: integer; + deltay, miny, maxy: double; + cntminy, cntmaxy: integer; + LimitOutSidePoints: integer; + px, py, sina, cosa: double; +begin +{$IFDEF TESTVARIANT} + center[0] := 0; + center[1] := 0; + pixels_per_unit := 0.7 * Min(width / (6), Height / (6)); + Exit; +{$ENDIF} + +// RandSeed := 1234567; + try + SetLength(Points, SUB_BATCH_SIZE); +{ case compatibility of + 0: iterate_Old(SUB_BATCH_SIZE, points); + 1: iterateXYC(SUB_BATCH_SIZE, points); + end; +} + cosa := cos(FAngle); + sina := sin(FAngle); + + Prepare; + + IterateXY(SUB_BATCH_SIZE, points); + + LimitOutSidePoints := Round(0.05 * SUB_BATCH_SIZE); + + minx := 1E99; + maxx := -1E99; + miny := 1E99; + maxy := -1E99; + for i := 0 to SUB_BATCH_SIZE - 1 do begin + if Points[i].x > 1e200 then continue; + minx := min(minx, Points[i].x); + maxx := max(maxx, Points[i].x); + miny := min(miny, Points[i].y); + maxy := max(maxy, Points[i].y); + end; + + deltax := (maxx - minx) * 0.25; + maxx := (maxx + minx) / 2; + minx := maxx; + + deltay := (maxy - miny) * 0.25; + maxy := (maxy + miny) / 2; + miny := maxy; + + for j := 0 to 10 do begin + cntminx := 0; + cntmaxx := 0; + cntminy := 0; + cntmaxy := 0; + for i := 0 to SUB_BATCH_SIZE - 1 do begin + if Points[i].x > 1e200 then continue; + px := points[i].x * cosa + points[i].y * sina; + py := points[i].y * cosa - points[i].x * sina; + if (Points[i].x < minx) then Inc(cntminx); + if (Points[i].x > maxx) then Inc(cntmaxx); + if (Points[i].y < miny) then Inc(cntminy); + if (Points[i].y > maxy) then Inc(cntmaxy); + end; + + if (cntMinx < LimitOutSidePoints) then begin + minx := minx + deltax; + end else begin + minx := minx - deltax; + end; + + if (cntMaxx < LimitOutSidePoints) then begin + maxx := maxx - deltax; + end else begin + maxx := maxx + deltax; + end; + + deltax := deltax / 2; + + if (cntMiny < LimitOutSidePoints) then begin + miny := miny + deltay; + end else begin + miny := miny - deltay; + end; + + if (cntMaxy < LimitOutSidePoints) then begin + maxy := maxy - deltay; + end else begin + maxy := maxy + deltay; + end; + + deltay := deltay / 2; + end; + + if ((maxx - minx) > 1000) or + ((maxy - miny) > 1000) then + raise EMathError.Create('Flame area too large'); + + center[0] := (minx + maxx) / 2; + center[1] := (miny + maxy) / 2; + if ((maxx - minx) > 0.001) and ((maxy - miny) > 0.001) then + pixels_per_unit := 0.65 * Min(width / (maxx - minx), Height / (maxy - miny)) + else + pixels_per_unit := 10; + except on E: EMathError do + begin// default + center[0] := 0; + center[1] := 0; + pixels_per_unit := 10; + end; + end; +end; + +function CalcUPRMagn(const cp: TControlPoint): double; +var + Points: TPointsXYArray; + i, j: integer; + deltax, minx, maxx: double; + cntminx, cntmaxx: integer; + deltay, miny, maxy: double; + cntminy, cntmaxy: integer; + LimitOutSidePoints: integer; + xLength, yLength: double; +begin + try + SetLength(Points, SUB_BATCH_SIZE); + cp.iterateXY(SUB_BATCH_SIZE, Points); + + LimitOutSidePoints := Round(0.05 * SUB_BATCH_SIZE); + + minx := 1E99; + maxx := -1E99; + miny := 1E99; + maxy := -1E99; + for i := 0 to SUB_BATCH_SIZE - 1 do begin + minx := min(minx, Points[i].x); + maxx := max(maxx, Points[i].x); + miny := min(miny, Points[i].y); + maxy := max(maxy, Points[i].y); + end; + + deltax := (maxx - minx) * 0.25; + maxx := (maxx + minx) / 2; + minx := maxx; + + deltay := (maxy - miny) * 0.25; + maxy := (maxy + miny) / 2; + miny := maxy; + + for j := 0 to 10 do begin + cntminx := 0; + cntmaxx := 0; + cntminy := 0; + cntmaxy := 0; + for i := 0 to SUB_BATCH_SIZE - 1 do begin + if (Points[i].x < minx) then Inc(cntminx); + if (Points[i].x > maxx) then Inc(cntmaxx); + if (Points[i].y < miny) then Inc(cntminy); + if (Points[i].y > maxy) then Inc(cntmaxy); + end; + + if (cntMinx < LimitOutSidePoints) then begin + minx := minx + deltax; + end else begin + minx := minx - deltax; + end; + + if (cntMaxx < LimitOutSidePoints) then begin + maxx := maxx - deltax; + end else begin + maxx := maxx + deltax; + end; + + deltax := deltax / 2; + + if (cntMiny < LimitOutSidePoints) then begin + miny := miny + deltay; + end else begin + miny := miny - deltay; + end; + + if (cntMaxy < LimitOutSidePoints) then begin + maxy := maxy - deltay; + end else begin + maxy := maxy + deltay; + end; + + deltay := deltay / 2; + end; + + if ((maxx - minx) > 1000) or + ((maxy - miny) > 1000) then + raise EMathError.Create('Flame area too large'); + + cp.center[0] := (minx + maxx) / 2; + cp.center[1] := (miny + maxy) / 2; + if ((maxx - minx) > 0.001) and ((maxy - miny) > 0.001) then + cp.pixels_per_unit := 0.7 * Min(cp.width / (maxx - minx), cp.height / (maxy - miny)) + else + cp.pixels_per_unit := 10; + + // Calculate magn for UPRs + xLength := maxx - minx; + yLength := maxy - miny; + if xLength >= yLength then + begin + result := 1 / xLength * 2; + end + else + begin + result := 1 / yLength * 2; + end; + + except on E: EMathError do + begin// default + cp.center[0] := 0; + cp.center[1] := 0; + cp.pixels_per_unit := 10; + raise Exception.Create('CalcUPRMagn: ' + e.Message); + end; + end; +end; + +(* +class function TControlPoint.Interpolate(cp1, cp2: TControlPoint; Time: double): TControlPoint; +var + c0, c1: double; + i, j: integer; + r, s, t: array[0..2] of double; +// totvar: double; + {z,rhtime: double;} + v1, v2: double; +begin + if (cp2.time - cp1.time) > 1E-6 then begin + c0 := (cp2.time - time) / (cp2.time - cp1.time); + c1 := 1 - c0; + end else begin + c0 := 1; + c1 := 0; + end; + + Result := TControlPoint.Create; + Result.time := Time; + + if cp1.cmap_inter = 0 then + for i := 0 to 255 do begin + r[0] := cp1.cmap[i][0] / 255; + r[1] := cp1.cmap[i][1] / 255; + r[2] := cp1.cmap[i][2] / 255; + rgb2hsv(r, s); + r[0] := cp2.cmap[i][0] / 255; + r[1] := cp2.cmap[i][1] / 255; + r[2] := cp2.cmap[i][2] / 255; + rgb2hsv(r, t); + t[0] := c0 * s[0] + c1 * t[0]; + t[1] := c0 * s[1] + c1 * t[1]; + t[2] := c0 * s[2] + c1 * t[2]; + hsv2rgb(t, r); + Result.cmap[i][0] := Round(255 * r[0]); + Result.cmap[i][1] := Round(255 * r[1]); + Result.cmap[i][2] := Round(255 * r[2]); + end; + + Result.cmapindex := -1; + + Result.brightness := c0 * cp1.brightness + c1 * cp2.brightness; + Result.contrast := c0 * cp1.contrast + c1 * cp2.contrast; + Result.gamma := c0 * cp1.gamma + c1 * cp2.gamma; + Result.vibrancy := c0 * cp1.vibrancy + c1 * cp2.vibrancy; + Result.width := cp1.width; + Result.height := cp1.height; + Result.spatial_oversample := Round(c0 * cp1.spatial_oversample + c1 * cp2.spatial_oversample); + Result.center[0] := c0 * cp1.center[0] + c1 * cp2.center[0]; + Result.center[1] := c0 * cp1.center[1] + c1 * cp2.center[1]; + Result.pixels_per_unit := c0 * cp1.pixels_per_unit + c1 * cp2.pixels_per_unit; +{ Apophysis doesn't interpolate background color - mt } +// Result.background[0] := c0 * cp1.background[0] + c1 * cp2.background[0]; +// Result.background[1] := c0 * cp1.background[1] + c1 * cp2.background[1]; +// Result.background[2] := c0 * cp1.background[2] + c1 * cp2.background[2]; + Result.spatial_filter_radius := c0 * cp1.spatial_filter_radius + c1 * cp2.spatial_filter_radius; + Result.sample_density := c0 * cp1.sample_density + c1 * cp2.sample_density; + Result.zoom := c0 * cp1.zoom + c1 * cp2.zoom; + Result.nbatches := Round(c0 * cp1.nbatches + c1 * cp2.nbatches); + Result.white_level := Round(c0 * cp1.white_level + c1 * cp2.white_level); + + for i := 0 to 3 do begin + Result.pulse[i div 2][i mod 2] := c0 * cp1.pulse[i div 2][i mod 2] + c1 * cp2.pulse[i div 2][i mod 2]; + Result.wiggle[i div 2][i mod 2] := c0 * cp1.wiggle[i div 2][i mod 2] + c1 * cp2.wiggle[i div 2][i mod 2]; + end; + + for i := 0 to NXFORMS - 1 do begin + Result.xform[i].density := c0 * cp1.xform[i].density + c1 * cp2.xform[i].density; + Result.xform[i].color := c0 * cp1.xform[i].color + c1 * cp2.xform[i].color; +// for j := 0 to NRVAR - 1 do +// Result.xform[i].vars[j] := c0 * cp1.xform[i].vars[j] + c1 * cp2.xform[i].vars[j]; + for j := 0 to NrVar-1 do + begin + Result.xform[i].vars[j] := c0 * cp1.xform[i].vars[j] + c1 * cp2.xform[i].vars[j]; + end; + for j:= 0 to GetNrVariableNames-1 do begin + cp1.xform[i].GetVariable(GetVariableNameAt(j), v1); + cp2.xform[i].GetVariable(GetVariableNameAt(j), v2); + v1 := c0 * v1 + c1 * v2; + Result.xform[i].SetVariable(GetVariableNameAt(j), v1); + end; + +{ + totvar := 0; + for j := 0 to NVARS - 1 do begin + totvar := totvar + Result.xform[i].vars[j]; + end; + for j := 0 to NVARS - 1 do begin + if totVar <> 0 then Result.xform[i].vars[j] := Result.xform[i].vars[j] / totvar; + end; +} + + // interpol matrix + for j := 0 to 2 do begin + Result.xform[i].c[j, 0] := c0 * cp1.xform[i].c[j, 0] + c1 * cp2.xform[i].c[j, 0]; + Result.xform[i].c[j, 1] := c0 * cp1.xform[i].c[j, 1] + c1 * cp2.xform[i].c[j, 1]; + end; + +{ Remainder commented out; + rhtime := time * 2 * PI / (60.0 * 30.0); + // pulse + z := 1; + for j := 0 to 1 do begin + z := z + Result.pulse[j, 0] * sin(Result.pulse[j, 1] * rhtime) + end; + + for j := 0 to 2 do begin + Result.xform[i].c[j][0] := Result.xform[i].c[j][0] * z; + Result.xform[i].c[j][1] := Result.xform[i].c[j][1] * z; + end; + + // wiggle + for j := 0 to 1 do begin + z := Result.wiggle[j,1] * rhtime; + + Result.xform[i].c[0][0] := Result.xform[i].c[0][0] + Result.wiggle[j,0] * cos(z); + Result.xform[i].c[1][0] := Result.xform[i].c[1][0] + Result.wiggle[j,0] * -sin(z); + Result.xform[i].c[0][1] := Result.xform[i].c[0][1] + Result.wiggle[j,0] * sin(z); + Result.xform[i].c[1][1] := Result.xform[i].c[1][1] + Result.wiggle[j,0] * cos(z); + end; +} + end; +end; +*) + +procedure TControlPoint.InterpolateX(cp1, cp2: TControlPoint; Tm: double); +var + result: TControlPoint; + c0, c1: double; + i, j: integer; + r, s, t: array[0..2] of double; + v1, v2: double; +// totvar: double; + {z,rhtime: double;} + + nXforms1, nXforms2: integer; +begin + if (cp2.time - cp1.time) > 1E-6 then begin + c0 := (cp2.time - tm) / (cp2.time - cp1.time); + c1 := 1 - c0; + end else begin + c0 := 1; + c1 := 0; + end; + + Result := TControlPoint.Create; + Result.time := Tm; + + if cp1.cmap_inter = 0 then + for i := 0 to 255 do begin + r[0] := cp1.cmap[i][0] / 255; + r[1] := cp1.cmap[i][1] / 255; + r[2] := cp1.cmap[i][2] / 255; + rgb2hsv(r, s); + r[0] := cp2.cmap[i][0] / 255; + r[1] := cp2.cmap[i][1] / 255; + r[2] := cp2.cmap[i][2] / 255; + rgb2hsv(r, t); + t[0] := c0 * s[0] + c1 * t[0]; + t[1] := c0 * s[1] + c1 * t[1]; + t[2] := c0 * s[2] + c1 * t[2]; + hsv2rgb(t, r); + Result.cmap[i][0] := Round(255 * r[0]); + Result.cmap[i][1] := Round(255 * r[1]); + Result.cmap[i][2] := Round(255 * r[2]); + end; + + Result.cmapindex := -1; + + Result.Fbrightness := c0 * cp1.Fbrightness + c1 * cp2.Fbrightness; + Result.contrast := c0 * cp1.contrast + c1 * cp2.contrast; + Result.gamma := c0 * cp1.gamma + c1 * cp2.gamma; + Result.vibrancy := c0 * cp1.vibrancy + c1 * cp2.vibrancy; + Result.gamma_threshold := c0 * cp1.gamma_threshold + c1 * cp2.gamma_threshold; + Result.width := cp1.width; + Result.height := cp1.height; + Result.spatial_oversample := Round(c0 * cp1.spatial_oversample + c1 * cp2.spatial_oversample); + Result.center[0] := c0 * cp1.center[0] + c1 * cp2.center[0]; + Result.center[1] := c0 * cp1.center[1] + c1 * cp2.center[1]; + Result.FAngle := c0 * cp1.FAngle + c1 * cp2.FAngle; + Result.pixels_per_unit := c0 * cp1.pixels_per_unit + c1 * cp2.pixels_per_unit; +// Result.background[0] := c0 * cp1.background[0] + c1 * cp2.background[0]; +// Result.background[1] := c0 * cp1.background[1] + c1 * cp2.background[1]; +// Result.background[2] := c0 * cp1.background[2] + c1 * cp2.background[2]; + Result.spatial_filter_radius := c0 * cp1.spatial_filter_radius + c1 * cp2.spatial_filter_radius; + Result.sample_density := c0 * cp1.sample_density + c1 * cp2.sample_density; + Result.zoom := c0 * cp1.zoom + c1 * cp2.zoom; + Result.nbatches := Round(c0 * cp1.nbatches + c1 * cp2.nbatches); + Result.white_level := Round(c0 * cp1.white_level + c1 * cp2.white_level); + + for i := 0 to 3 do begin + Result.pulse[i div 2][i mod 2] := c0 * cp1.pulse[i div 2][i mod 2] + c1 * cp2.pulse[i div 2][i mod 2]; + Result.wiggle[i div 2][i mod 2] := c0 * cp1.wiggle[i div 2][i mod 2] + c1 * cp2.wiggle[i div 2][i mod 2]; + end; + + // save finalxform from mut(il)ation ;) + nXforms1 := cp1.NumXForms; + if cp1.HasFinalXForm then + begin + if nXforms1 < NXFORMS then + begin + cp1.xform[NXFORMS].Assign(cp1.xform[nXforms1]); + cp1.xform[nXforms1].Clear; + end; + end + else begin + cp1.xform[NXFORMS].Clear; + cp1.xform[NXFORMS].symmetry := 1; + end; + + nXforms2 := cp2.NumXForms; + if cp2.HasFinalXForm then + begin + if nXforms2 < NXFORMS then + begin + cp2.xform[NXFORMS].Assign(cp2.xform[nXforms2]); + cp2.xform[nXforms2].Clear; + end; + end + else begin + cp2.xform[NXFORMS].Clear; + cp2.xform[NXFORMS].symmetry := 1; + end; + + for i := 0 to NXFORMS do begin + Result.xform[i].density := c0 * cp1.xform[i].density + c1 * cp2.xform[i].density; + Result.xform[i].color := c0 * cp1.xform[i].color + c1 * cp2.xform[i].color; + Result.xform[i].symmetry := c0 * cp1.xform[i].symmetry + c1 * cp2.xform[i].symmetry; +// for j := 0 to NrVar - 1 do +// Result.xform[i].vars[j] := c0 * cp1.xform[i].vars[j] + c1 * cp2.xform[i].vars[j]; + for j := 0 to NrVar-1 do + Result.xform[i].SetVariation(j, c0 * cp1.xform[i].GetVariation(j) + c1 * cp2.xform[i].GetVariation(j)); + //Result.xform[i].vars[j] := c0 * cp1.xform[i].vars[j] + c1 * cp2.xform[i].vars[j]; + for j:= 0 to GetNrVariableNames-1 do begin + cp1.xform[i].GetVariable(GetVariableNameAt(j), v1); + cp2.xform[i].GetVariable(GetVariableNameAt(j), v2); + v1 := c0 * v1 + c1 * v2; + Result.xform[i].SetVariable(GetVariableNameAt(j), v1); + end; +(* + totvar := 0; + for j := 0 to NVARS - 1 do begin + totvar := totvar + Result.xform[i].vars[j]; + end; + for j := 0 to NVARS - 1 do begin + if totVar <> 0 then Result.xform[i].vars[j] := Result.xform[i].vars[j] / totvar; + end; + *) + + // interpol matrix + for j := 0 to 2 do begin + Result.xform[i].c[j, 0] := c0 * cp1.xform[i].c[j, 0] + c1 * cp2.xform[i].c[j, 0]; + Result.xform[i].c[j, 1] := c0 * cp1.xform[i].c[j, 1] + c1 * cp2.xform[i].c[j, 1]; + end; + end; + + // finalxform was supposed to be mutate-able too, but somehow it's always + // getting confused by random-generated mutatns :-\ + if Result.NumXForms < NXFORMS then + begin + Result.xform[Result.NumXForms].Assign(cp1.xform[NXFORMS]); //result.xform[NXFORMS]); + Result.xform[NXFORMS].Clear; + end; + Result.finalXformEnabled := cp1.finalXformEnabled; + + // restore finalxforms in source CPs + if nXforms1 < NXFORMS then + begin + cp1.xform[nXforms1].Assign(cp1.xform[NXFORMS]); + cp1.xform[NXFORMS].Clear; + end; + if nXforms2 < NXFORMS then + begin + cp2.xform[nXforms2].Assign(cp2.xform[NXFORMS]); + cp2.xform[NXFORMS].Clear; + end; + + Copy(Result); + cmap := Result.cmap; + result.free; +end; + +procedure TControlPoint.SaveToFile(Filename: string); +var + sl: TStringlist; +begin + sl := TStringlist.Create; + + SaveToStringlist(sl); + + sl.SaveToFile(filename); + sl.Free; +end; + +procedure TControlPoint.SaveToStringlist(sl: TStringlist); +var + i, j, k: Integer; + s: string; + OldDecimalSperator: Char; + v: double; + str: string; + curves: string; +begin + OldDecimalSperator := FormatSettings.DecimalSeparator; + FormatSettings.DecimalSeparator := '.'; + + sl.add(format('time %f', [time])); + if cmapindex >= 0 then + sl.add(format('cmap %d', [cmapindex])); + sl.add(format('zoom %g', [zoom])); // mt + sl.add(format('angle %g', [FAngle])); + + sl.add(format('cam_pitch %g', [cameraPitch])); + sl.add(format('cam_yaw %g', [cameraYaw])); + sl.add(format('cam_persp %g', [cameraPersp])); + sl.add(format('cam_zpos %g', [cameraZpos])); + sl.add(format('cam_dof %g', [cameraDOF])); + + for i := 0 to 3 do + begin + curves := curves + FloatToStr(curvePoints[i][0].x) + ' '; + curves := curves + FloatToStr(curvePoints[i][0].y) + ' '; + curves := curves + FloatToStr(curveWeights[i][0]) + ' '; + + curves := curves + FloatToStr(curvePoints[i][1].x) + ' '; + curves := curves + FloatToStr(curvePoints[i][1].y) + ' '; + curves := curves + FloatToStr(curveWeights[i][1]) + ' '; + + curves := curves + FloatToStr(curvePoints[i][2].x) + ' '; + curves := curves + FloatToStr(curvePoints[i][2].y) + ' '; + curves := curves + FloatToStr(curveWeights[i][2]) + ' '; + + curves := curves + FloatToStr(curvePoints[i][3].x) + ' '; + curves := curves + FloatToStr(curvePoints[i][3].y) + ' '; + curves := curves + FloatToStr(curveWeights[i][3]) + ' '; + end; + + curves := trim(curves); + sl.Add(Format('curves %s', [curves])); + + sl.add(format('image_size %d %d center %g %g pixels_per_unit %f', + [Width, Height, center[0], center[1], pixels_per_unit])); + sl.add(format('spatial_oversample %d spatial_filter_radius %f', + [spatial_oversample, spatial_filter_radius])); + sl.add(format('sample_density %g', [sample_density])); +// sl.add(format('nbatches %d white_level %d background %f %f %f', - changed to integers - mt + sl.add(format('nbatches %d white_level %d background %d %d %d', + [nbatches, white_level, background[0], background[1], background[2]])); + sl.add(format('brightness %f gamma %f vibrancy %f gamma_threshold %f hue_rotation %f cmap_inter %d', + [Fbrightness * BRIGHT_ADJUST, gamma, vibrancy, gamma_threshold, hue_rotation, cmap_inter])); + sl.add(format('finalxformenabled %d', [ifthen(finalxformenabled, 1, 0)])); + sl.add(format('soloxform %d', [soloXform])); + + (*str := ''; + for i := 0 to used_plugins.Count-1 do begin + str := str + used_plugins[i]; + if (i = used_plugins.Count-1) then break; + str := str + ' '; + end; + sl.Add(format('plugins %s', [str])); *) + + for i := 0 to Min(NumXForms+1, NXFORMS) do + with xform[i] do begin + //if density = 0 then continue; - FinalXform has weight=0 + + sl.add(format('xform %d density %g color %g symmetry %g', [i, density, color, symmetry])); + s := 'vars'; + for j := 0 to NRVAR - 1 do begin + s := format('%s %g', [s, GetVariation(j)]); + end; + sl.add(s); + s := 'variables'; + for j:= 0 to GetNrVariableNames-1 do begin +{$ifndef VAR_STR} + GetVariable(GetVariableNameAt(j), v); + s := format('%s %g', [s, v]); +{$else} + s := s + ' ' + GetVariableStr(GetVariableNameAt(j)); +{$endif} + end; + sl.add(s); + sl.Add(format('coefs %.6f %.6f %.6f %.6f %.6f %.6f', + [c[0][0], c[0][1], c[1][0], c[1][1], c[2][0], c[2][1]])); + sl.Add(format('post %.6f %.6f %.6f %.6f %.6f %.6f', + [p[0][0], p[0][1], p[1][0], p[1][1], p[2][0], p[2][1]])); + if postXswap then + sl.Add('postxswap 1') + else + sl.Add('postxswap 0'); + if autoZscale then + sl.Add('autozscale 1') + else + sl.Add('autozscale 0'); + s := 'chaos'; + for j := 0 to NumXForms+1 do begin + s := s + format(' %g', [modWeights[j]]); + end; + sl.Add(s); + + sl.Add(format('opacity %g', [transOpacity])); + sl.Add(format('var_color %g', [pluginColor])); + + end; + FormatSettings.DecimalSeparator := OldDecimalSperator; +end; + +procedure WriteDoubles(const handle: File; data: array of double); +var + block: TBlock; + i: integer; +begin + for i := 0 to Length(data)-1 do begin + DoubleToBlock(block, 0, 0); //pad to blocksize + DoubleToBlock(block, 8, data[i]); + BlockWrite(handle, block, 1); + end; +end; +procedure WriteString(const handle: File; data: string); +var + k, l, size, chunks: Integer; + raw : THibRawString; + block: TBlock; +begin + size := Length(data); + SetLength(raw, size); + CopyMemory(@raw[0], @data[1], size); + chunks := size div HIB_BLOCKSIZE; + + if size mod HIB_BLOCKSIZE > 0 then begin + size := (1 + size div HIB_BLOCKSIZE) * HIB_BLOCKSIZE; + chunks := chunks + 1; + end; + + for k := 0 to chunks - 1 do begin + for l := 0 to HIB_MAXOFFSET do + if (k * HIB_BLOCKSIZE + l) < size then + block[l] := raw[k * HIB_BLOCKSIZE + l] + else block[l] := 0; + BlockWrite(handle, block, 1); + end; +end; + +function CalcBinaryFlameSize(cp: TControlPoint): integer; +var + (*str: string; + i, nvariations, nvariables, nchaos: Integer;*) + handle: File; +begin + // I'm a bit ashamed but this hack has do to it for now... + AssignFile(handle, GetEnvironmentVariable('TEMP') + '\CalcBinaryFlameSizeTemp.bin'); + ReWrite(handle, HIB_BLOCKSIZE); + cp.SaveToBinary(handle); + Result := FileSize(handle) * HIB_BLOCKSIZE; + CloseFile(handle); + DeleteFile(GetEnvironmentVariable('TEMP') + '\CalcBinaryFlameSizeTemp.bin'); + + (*// CP data + Result := 224; + + // Var list + str := ''; + for i := 0 to NRVAR-1 do + str := str + VarNames(i) + #13#10; + for i:= 0 to GetNrVariableNames-1 do + str := str + GetVariableNameAt(i)+ #13#10; + str := trim(str); + if Length(str) mod HIB_BLOCKSIZE > 0 then + Result := Result + (1 + Length(str) div HIB_BLOCKSIZE) * HIB_BLOCKSIZE + else + Result := Result + Length(str); + + // XForm data + nchaos := Min(cp.NumXForms+1, NXFORMS); + nvariations := NRVAR; + nvariables := GetNrVariableNames; + if nvariations mod 2 > 0 then + nvariations := nvariations + 1; + if nvariables mod 2 > 0 then + nvariables := nvariables + 1; + if nchaos mod 2 > 0 then + nchaos := nchaos + 1; + Result := Result + (144 + (nvariations + nvariables + nchaos) * 8) * + Min(cp.NumXForms+1, NXFORMS); *) +end; + +procedure TControlPoint.SaveToBinary(const handle: File); +var + i, j, nvariations, nvariables, nchaos: Integer; + v: double; + str: string; + dbl: array of double; + block: TBlock; +begin + + DoubleToBlock(block, 0, time); + DoubleToBlock(block, 8, zoom); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, FAngle); + DoubleToBlock(block, 8, pixels_per_unit); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, center[0]); + DoubleToBlock(block, 8, center[1]); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, cameraPitch); + DoubleToBlock(block, 8, cameraYaw); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, cameraPersp); + DoubleToBlock(block, 8, cameraZpos); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, cameraDOF); + DoubleToBlock(block, 8, spatial_filter_radius); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, sample_density); + DoubleToBlock(block, 8, gamma_threshold); + BlockWrite(handle, block, 1); + + Int32ToBlock(block, 0, cmapindex); + Int32ToBlock(block, 4, spatial_oversample); + Int32ToBlock(block, 8, Width); + Int32ToBlock(block, 12, Height); + BlockWrite(handle, block, 1); + + Int32ToBlock(block, 0, nbatches); + Int32ToBlock(block, 4, cmap_inter); + Int32ToBlock(block, 8, ifthen(finalxformenabled, 1, 0)); + Int32ToBlock(block, 12, soloXform); + BlockWrite(handle, block, 1); + + Int32ToBlock(block, 0, white_level); + Int32ToBlock(block, 4, background[0]); + Int32ToBlock(block, 8, background[1]); + Int32ToBlock(block, 12, background[2]); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, Fbrightness * BRIGHT_ADJUST); + DoubleToBlock(block, 8, gamma); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, vibrancy); + DoubleToBlock(block, 8, hue_rotation); + BlockWrite(handle, block, 1); + + nchaos := Min(NumXForms+1, NXFORMS); + nvariations := NRVAR; + nvariables := GetNrVariableNames; + + Int32ToBlock(block, 0, nvariations); + Int32ToBlock(block, 4, nvariables); + Int32ToBlock(block, 8, nchaos); + + str := ''; + for i := 0 to nvariations-1 do + str := str + VarNames(i) + #0; + for i:= 0 to nvariables-1 do + str := str + GetVariableNameAt(i)+ #0; + str := trim(str); + if Length(str) mod HIB_BLOCKSIZE > 0 then + Int32ToBlock(block, 12, (1 + Length(str) div HIB_BLOCKSIZE) * HIB_BLOCKSIZE) + else + Int32ToBlock(block, 12, Length(str)); + BlockWrite(handle, block, 1); + + WriteString(handle, str); + + for i := 0 to nchaos - 1 do + with xform[i] do begin + DoubleToBlock(block, 0, density); + DoubleToBlock(block, 8, color); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, symmetry); + DoubleToBlock(block, 8, transOpacity); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, pluginColor); + Int32ToBlock(block, 8, IfThen(postXswap, 1, 0)); + Int32ToBlock(block, 12, IfThen(autozscale, 1, 0)); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, c[0][0]); + DoubleToBlock(block, 8, c[0][1]); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, c[1][0]); + DoubleToBlock(block, 8, c[1][1]); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, c[2][0]); + DoubleToBlock(block, 8, c[2][1]); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, p[0][0]); + DoubleToBlock(block, 8, p[0][1]); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, p[1][0]); + DoubleToBlock(block, 8, p[1][1]); + BlockWrite(handle, block, 1); + + DoubleToBlock(block, 0, p[2][0]); + DoubleToBlock(block, 8, p[2][1]); + BlockWrite(handle, block, 1); + + SetLength(dbl, nvariations); + for j := 0 to nvariations-1 do + dbl[j] := GetVariation(j); + WriteDoubles(handle, dbl); + + SetLength(dbl, nvariables); + for j := 0 to nvariables-1 do + GetVariable(GetVariableNameAt(j), dbl[j]); + WriteDoubles(handle, dbl); + + SetLength(dbl, nchaos); + for j := 0 to nchaos-1 do + dbl[j] := xform[i].modWeights[j]; + WriteDoubles(handle, dbl); + end; +end; + + +function TControlPoint.Clone: TControlPoint; +var + i, j: integer; + sl: TStringList; +begin + sl := TStringList.Create; + SaveToStringlist(sl); + Result := TControlPoint.Create; + Result.ParseStringlist(sl); + Result.Fangle := FAngle; + Result.cmap := cmap; + Result.name := name; + Result.nick := nick; + Result.url := url; + Result.Transparency := Transparency; + Result.gamma_threshold := gamma_threshold; + Result.estimator := estimator; + Result.estimator_min := estimator_min; + Result.estimator_curve := estimator_curve; + Result.enable_de := enable_de; + Result.xdata := xdata; + + Result.Background[0] := background[0]; + Result.Background[1] := background[1]; + Result.Background[2] := background[2]; + + for i := 0 to 3 do + for j := 0 to 3 do begin + Result.CurveWeights[i,j] := curveWeights[i,j]; + Result.curvePoints[i,j].x := curvePoints[i,j].x; + Result.curvePoints[i,j].y := curvePoints[i,j].y; + end; + + result.used_plugins.Clear; + for i := 0 to used_plugins.Count-1 do + Result.used_plugins.Add(used_plugins[i]); + + for i := 0 to NXFORMS - 1 do + Result.xform[i].assign(xform[i]); + + sl.Free; +end; + +procedure TControlPoint.Copy(cp1: TControlPoint; KeepSizes: boolean = false); +var + i, j: integer; + sl: TStringList; + w, h: integer; +begin + w := Width; + h := Height; + + Clear; + sl := TStringList.Create; + + // --Z-- this is quite a weird and unoptimal way to copy things: + cp1.SaveToStringlist(sl); + ParseStringlist(sl); + + Fangle := cp1.FAngle; + center[0]:= cp1.center[0]; + center[1]:= cp1.center[1]; + pixels_per_unit := cp1.pixels_per_unit; + cmap := cp1.cmap; + name := cp1.name; + nick := cp1.nick; + url := cp1.url; + gamma_threshold := cp1.gamma_threshold; + estimator := cp1.estimator; + estimator_min := cp1.estimator_min; + estimator_curve := cp1.estimator_curve; + enable_de := cp1.enable_de; + used_plugins := cp1.used_plugins; + xdata := cp1.xdata; + + background[0] := cp1.background[0]; + background[1] := cp1.background[1]; + background[2] := cp1.background[2]; + + for i := 0 to 3 do + for j := 0 to 3 do begin + CurveWeights[i,j] := cp1.curveWeights[i,j]; + curvePoints[i,j].x := cp1.curvePoints[i,j].x; + curvePoints[i,j].y := cp1.curvePoints[i,j].y; + end; + + if KeepSizes then + AdjustScale(w, h); + + used_plugins.clear; + for i := 0 to cp1.used_plugins.Count-1 do + used_plugins.Add(cp1.used_plugins[i]); + + for i := 0 to NXFORMS do // was: NXFORMS-1 + xform[i].assign(cp1.xform[i]); + finalXformEnabled := cp1.finalXformEnabled; + + sl.Free; +end; + +procedure TControlPoint.ParseStringList(sl: TStringlist); +var + s: string; + i: integer; +begin + finalXformEnabled := false; + for i := 0 to sl.Count - 1 do begin + s := s + sl[i] + ' '; + end; + ParseString(s); +end; + +procedure TControlPoint.Clear; +var + i, j: Integer; +begin + symmetry := 0; + cmapindex := -1; + zoom := 0; + xdata := ''; + for i := 0 to NXFORMS do xform[i].Clear; + FinalXformEnabled := false; + soloxform := -1; + + for i := 0 to 3 do + begin + curvePoints[i][0].x := 0.00; curvePoints[i][0].y := 0.00; curveWeights[i][0] := 1; + curvePoints[i][1].x := 0.00; curvePoints[i][1].y := 0.00; curveWeights[i][1] := 1; + curvePoints[i][2].x := 1.00; curvePoints[i][2].y := 1.00; curveWeights[i][2] := 1; + curvePoints[i][3].x := 1.00; curvePoints[i][3].y := 1.00; curveWeights[i][3] := 1; + end; + + try + if (used_plugins <> nil) then + used_plugins.Clear + else used_plugins := tstringlist.Create; + except + // hack + used_plugins := TStringList.Create; + end; +end; + +function TControlPoint.HasFinalXForm: boolean; +var + i: integer; +begin + with xform[NumXForms] do + begin + Result := (c[0,0]<>1) or (c[0,1]<>0) or (c[1,0]<>0) or (c[1,1]<>1) or (c[2,0]<>0) or (c[2,1]<>0) or + (p[0,0]<>1) or (p[0,1]<>0) or (p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) or + (symmetry <> 1) or (GetVariation(0) <> 1); + if Result = false then + for i := 1 to NRVAR-1 do Result := Result or (GetVariation(i) <> 0); + end; +end; + +function add_symmetry_to_control_point(var cp: TControlPoint; sym: integer): integer; +const + sym_distrib: array[0..14] of integer = ( + -4, -3, + -2, -2, -2, + -1, -1, -1, + 2, 2, 2, + 3, 3, + 4, 4 + ); +var + i, j, k: integer; + a: double; +begin + result := 0; + if (0 = sym) then + if (random(1) <> 0) then + sym := sym_distrib[random(14)] + else if (random(32) <> 0) then // not correct + sym := random(13) - 6 + else + sym := random(51) - 25; + + if (1 = sym) or (0 = sym) then + begin + result := 0; + exit; + end; + + for i := 0 to NXFORMS - 1 do + if (cp.xform[i].density = 0.0) then break; + + if (i = NXFORMS) then + begin + result := 0; + exit; + end; + cp.symmetry := sym; + + if (sym < 0) then + begin + cp.xform[i].density := 1.0; + cp.xform[i].symmetry := 1; + cp.xform[i].SetVariation(0, 1.0); + for j := 1 to NRVAR - 1 do + cp.xform[i].SetVariation(j, 0.0); + cp.xform[i].color := 1.0; + cp.xform[i].c[0][0] := -1.0; + cp.xform[i].c[0][1] := 0.0; + cp.xform[i].c[1][0] := 0.0; + cp.xform[i].c[1][1] := 1.0; + cp.xform[i].c[2][0] := 0.0; + cp.xform[i].c[2][1] := 0.0; + + inc(i); + inc(result); + sym := -sym; + end; + + a := 2 * PI / sym; + +// for (k = 1; (k < sym)&&(i < NXFORMS); k + + ) { + k := 1; +// while (k < sym) and (i < NXFORMS) do + while (k < sym) and (i < SymmetryNVars) do + begin + cp.xform[i].density := 1.0; + cp.xform[i].SetVariation(0, 1); + cp.xform[i].symmetry := 1; + for j := 1 to NRVAR - 1 do + cp.xform[i].SetVariation(j, 0); + if sym < 3 then + cp.xform[i].color := 0 + else + cp.xform[i].color := (k - 1) / (sym - 2); + + if cp.xform[i].color > 1 then + begin +// ShowMessage('Color value larger than 1'); + repeat + cp.xform[i].color := cp.xform[i].color - 1 + until cp.xform[i].color <= 1; + end; + + cp.xform[i].c[0][0] := cos(k * a); + cp.xform[i].c[0][1] := sin(k * a); + cp.xform[i].c[1][0] := -cp.xform[i].c[0][1]; + cp.xform[i].c[1][1] := cp.xform[i].c[0][0]; + cp.xform[i].c[2][0] := 0.0; + cp.xform[i].c[2][1] := 0.0; + + inc(i); + inc(result); + inc(k); + end; +end; + +(* +/////////////////////////////////////////////////////////////////////////////// +function TControlPoint.HasNewVariants: boolean; +var + i,v: integer; +begin + Result := false; // flam3 will be updated anyway :-) +{ + for i:= 0 to NXFORMS - 1 do begin + if xform[i].density = 0 then + break; + + for v := NRLOCVAR to NrVar - 1 do + result := Result or (xform[i].vars[v] > 0); + + if result then + break; + end; +} +end; +*) + +/////////////////////////////////////////////////////////////////////////////// +procedure TControlPoint.ZoomtoRect(R: TSRect); +var + scale, ppu: double; + dx,dy: double; +begin + scale := power(2, zoom); + ppu := pixels_per_unit * scale; + + dx := ((r.Left + r.Right)/2 - Width/2) / ppu; + dy := ((r.Top + r.Bottom)/2 - Height/2) / ppu; + + center[0] := center[0] + cos(FAngle) * dx - sin(FAngle) * dy; + center[1] := center[1] + sin(FAngle) * dx + cos(FAngle) * dy; + + if PreserveQuality then + zoom := Log2(scale * ( Width/(abs(r.Right - r.Left) + 1))) + else + pixels_per_unit := pixels_per_unit * Width / abs(r.Right - r.Left); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TControlPoint.ZoomOuttoRect(R: TSRect); +var + ppu: double; + dx, dy: double; +begin + + if PreserveQuality then + zoom := Log2(power(2, zoom) / ( Width/(abs(r.Right - r.Left) + 1))) + else + pixels_per_unit := pixels_per_unit / Width * abs(r.Right - r.Left); + ppu := pixels_per_unit * power(2, zoom); + + dx := ((r.Left + r.Right)/2 - Width/2) / ppu; + dy := ((r.Top + r.Bottom)/2 - Height/2) / ppu; + + center[0] := center[0] - cos(FAngle) * dx + sin(FAngle) * dy; + center[1] := center[1] - sin(FAngle) * dx - cos(FAngle) * dy; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TControlPoint.ZoomIn(Factor: double); +var + scale: double; +begin + scale := power(2, zoom); + + Scale := Scale / Factor; + Zoom := Log2(Scale); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TControlPoint.MoveRect(R: TSRect); +var + scale: double; + ppux, ppuy: double; + dx,dy: double; +begin + scale := power(2, zoom); + ppux := pixels_per_unit * scale; + ppuy := pixels_per_unit * scale; + + dx := (r.Left - r.Right)/ppux; + dy := (r.Top - r.Bottom)/ppuy; + + center[0] := center[0] + cos(FAngle) * dx - sin(FAngle) * dy; + center[1] := center[1] + sin(FAngle) * dx + cos(FAngle) * dy ; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TControlPoint.Rotate(Angle: double); +begin + FAngle := FAngle + Angle; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TControlPoint.getppux: double; +begin + result := pixels_per_unit * power(2, zoom) +end; + +function TControlPoint.getppuy: double; +begin + result := pixels_per_unit * power(2, zoom) +end; + +/////////////////////////////////////////////////////////////////////////////// +function TControlPoint.GetBrightness: double; +begin + Result := Fbrightness; +end; + +procedure TControlPoint.SetBrightness(br: double); +begin + if br > 0 then begin + if Fbrightness <> 0 then gamma_threshold := (gamma_threshold / Fbrightness) * br; + Fbrightness := br; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TControlPoint.GetRelativeGammaThreshold: double; +begin + if Fbrightness <> 0 then + Result := gamma_threshold / Fbrightness + else + Result := gamma_threshold; +end; + +procedure TControlPoint.SetRelativeGammaThreshold(gtr: double); +begin + gamma_threshold := gtr * Fbrightness; +end; + +/////////////////////////////////////////////////////////////////////////////// +var + vdfilled: boolean = False; + +procedure FillVarDisturb; +const + startvar_distrib: array[0..26] of integer = (-1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7); + startmixed_var_distrib: array[0..16] of integer = (0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7); +var + i: integer; +begin + if vdfilled then + Exit; + + setlength(var_distrib, NRVAR + 19); + setlength(mixed_var_distrib, NRVAR + 9); + + for i := 0 to High(startvar_distrib) do + var_distrib[i] := startvar_distrib[i]; + + for i := High(startvar_distrib) + 1 to high(var_distrib) do + var_distrib[i] := 8 + i - High(startvar_distrib) - 1; + + for i := 0 to High(startmixed_var_distrib) do + mixed_var_distrib[i] := startmixed_var_distrib[i]; + + for i := High(startmixed_var_distrib) + 1 to high(mixed_var_distrib) do + mixed_var_distrib[i] := 8 + i - High(startmixed_var_distrib) - 1; + + vdfilled := true; +end; + +/////////////////////////////////////////////////////////////////////////////// +// +// --Z-- cp-specific functions moved here from MainForm +// + +function TControlPoint.NumXForms: integer; +var + i: integer; +begin +//... + Result := NXFORMS; + for i := 0 to NXFORMS - 1 do + begin + if xform[i].density = 0 then + begin + Result := i; + Break; + end; + end; +end; + +function TControlPoint.TrianglesFromCP(var Triangles: TTriangles): integer; +{ Sets up the triangles from the IFS code } +var + i, j: integer; + temp_x, temp_y, xset, yset: double; + left, top, bottom, right: double; +begin + top := 0; bottom := 0; right := 0; left := 0; + Result := NumXForms; +{ + if ReferenceMode > 0 then + begin + for i := 0 to Result-1 do + begin + xset := 1.0; + yset := 1.0; + for j := 0 to 5 do + with xform[i] do begin + temp_x := xset * c[0][0] + yset * c[1][0] + c[2][0]; + temp_y := xset * c[0][1] + yset * c[1][1] + c[2][1]; + xset := temp_x; + yset := temp_y; + end; + if (i = 0) then + begin + left := xset; + right := xset; + top := yset; + bottom := yset; + end + else + begin + if (xset < left) then left := xset; + if (xset > right) then right := xset; + if (yset > top) then top := yset; + if (yset < bottom) then bottom := yset; + end; + end; + + if ReferenceMode = 1 then + begin + Triangles[-1].x[0] := right-left; + Triangles[-1].y[0] := 0; + Triangles[-1].x[1] := 0; + Triangles[-1].y[1] := 0; + Triangles[-1].x[2] := 0; + Triangles[-1].y[2] := -(top-bottom); + end + else begin + Triangles[-1].x[0] := right; + Triangles[-1].y[0] := -bottom; + Triangles[-1].x[1] := left; + Triangles[-1].y[1] := -bottom; + Triangles[-1].x[2] := left; + Triangles[-1].y[2] := -top; + end; + end + else +} + begin + Triangles[-1].x[0] := 1; Triangles[-1].y[0] := 0; // "x" + Triangles[-1].x[1] := 0; Triangles[-1].y[1] := 0; // "0" + Triangles[-1].x[2] := 0; Triangles[-1].y[2] := -1; // "y" + end; + + for j := 0 to Result do + begin + for i := 0 to 2 do + with xform[j] do begin + if postXswap then begin + Triangles[j].x[i] := Triangles[-1].x[i] * p[0][0] + Triangles[-1].y[i] * p[1][0] + p[2][0]; + Triangles[j].y[i] := Triangles[-1].x[i] * p[0][1] + Triangles[-1].y[i] * p[1][1] + p[2][1]; + end + else begin + Triangles[j].x[i] := Triangles[-1].x[i] * c[0][0] + Triangles[-1].y[i] * c[1][0] + c[2][0]; + Triangles[j].y[i] := Triangles[-1].x[i] * c[0][1] + Triangles[-1].y[i] * c[1][1] + c[2][1]; + end; + end; + end; + EnableFinalXform := FinalXformEnabled; + + // I don't like this... :-/ + for j := -1 to Result do // was: Result-1 + for i := 0 to 2 do + Triangles[j].y[i] := -Triangles[j].y[i]; +end; + +procedure TControlPoint.EqualizeWeights; +var + t, i: integer; +begin + t := NumXForms; + for i := 0 to t - 1 do + xform[i].density := 0.5; +end; + +procedure TControlPoint.NormalizeWeights; +var + i: integer; + td: double; +begin + td := 0.0; + for i := 0 to NumXForms - 1 do + td := td + xform[i].Density; + if (td < 0.001) then + EqualizeWeights + else + for i := 0 to NumXForms - 1 do + xform[i].Density := xform[i].Density / td; +end; + +procedure TControlPoint.RandomizeWeights; +var + i: integer; +begin + for i := 0 to Transforms - 1 do + xform[i].Density := Random; +end; + +procedure TControlPoint.ComputeWeights(Triangles: TTriangles; t: integer); +// Caclulate transform weight from triangle areas +var + i: integer; + total_area: double; +begin + total_area := 0; + for i := 0 to t - 1 do + begin + xform[i].Density := triangle_area(Triangles[i]); + total_area := total_area + xform[i].Density; + end; + for i := 0 to t - 1 do + begin + xform[i].Density := xform[i].Density / total_area; + end; + //? cp1.NormalizeWeights; +end; + +procedure TControlPoint.GetFromTriangles(const Triangles: TTriangles; const t: integer); +var + i: integer; + v: double; +begin + for i := 0 to t do + if xform[i].postXswap then + begin + solve3(Triangles[-1].x[0], -Triangles[-1].y[0], Triangles[i].x[0], + Triangles[-1].x[1], -Triangles[-1].y[1], Triangles[i].x[1], + Triangles[-1].x[2], -Triangles[-1].y[2], Triangles[i].x[2], + xform[i].p[0][0], xform[i].p[1][0], xform[i].p[2][0]); + + solve3(Triangles[-1].x[0], -Triangles[-1].y[0], -Triangles[i].y[0], + Triangles[-1].x[1], -Triangles[-1].y[1], -Triangles[i].y[1], + Triangles[-1].x[2], -Triangles[-1].y[2], -Triangles[i].y[2], + xform[i].p[0][1], xform[i].p[1][1], xform[i].p[2][1]); + end + else begin + solve3(Triangles[-1].x[0], -Triangles[-1].y[0], Triangles[i].x[0], + Triangles[-1].x[1], -Triangles[-1].y[1], Triangles[i].x[1], + Triangles[-1].x[2], -Triangles[-1].y[2], Triangles[i].x[2], + xform[i].c[0][0], xform[i].c[1][0], xform[i].c[2][0]); + + solve3(Triangles[-1].x[0], -Triangles[-1].y[0], -Triangles[i].y[0], + Triangles[-1].x[1], -Triangles[-1].y[1], -Triangles[i].y[1], + Triangles[-1].x[2], -Triangles[-1].y[2], -Triangles[i].y[2], + xform[i].c[0][1], xform[i].c[1][1], xform[i].c[2][1]); + if xform[i].autoZscale then with xform[i] do begin + v := c[0][0]*c[1][1] - c[0][1]*c[1][0]; + //n := GetVariationIndex('pre_zscale'); + if v = 1 then + SetVariation(20, 0.0) // pre_zscale not needed + else + SetVariation(20, sign(v) * sqrt(abs(v))); + end; + end; + FinalXformEnabled := EnableFinalXform; +end; + +procedure TControlPoint.GetTriangle(var Triangle: TTriangle; const n: integer); +var + i, j: integer; +begin + for i := 0 to 2 do + with xform[n] do begin + Triangle.x[i] := MainTriangles[-1].x[i] * c[0][0] - MainTriangles[-1].y[i] * c[1][0] + c[2][0]; + Triangle.y[i] := -MainTriangles[-1].x[i] * c[0][1] + MainTriangles[-1].y[i] * c[1][1] - c[2][1]; + end; +end; + +procedure TControlPoint.GetPostTriangle(var Triangle: TTriangle; const n: integer); +var + i, j: integer; +begin + for i := 0 to 2 do + with xform[n] do begin + Triangle.x[i] := MainTriangles[-1].x[i] * p[0][0] - MainTriangles[-1].y[i] * p[1][0] + p[2][0]; + Triangle.y[i] := -MainTriangles[-1].x[i] * p[0][1] + MainTriangles[-1].y[i] * p[1][1] - p[2][1]; + end; +end; + +//////////////////////////////////////////////////////////////////////////////// +procedure TControlPoint.AdjustScale(w, h: integer); +begin +// if width >= height then + pixels_per_unit := pixels_per_unit * w/width; +// else +// pixels_per_unit := pixels_per_unit * h/height; + width := w; + height := h; +end; + +end. + diff --git a/Flame/RndFlame.pas b/Flame/RndFlame.pas new file mode 100644 index 0000000..74fad3f --- /dev/null +++ b/Flame/RndFlame.pas @@ -0,0 +1,589 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit RndFlame; + +interface + +uses + ControlPoint, Xform; + +function RandomFlame(SourceCP: TControlPoint= nil; algorithm: integer = 0): TControlPoint; + +implementation + +uses + SysUtils, Global, cmap, GradientHlpr, XFormMan, Classes; + +/////////////////////////////////////////////////////////////////////////////// +procedure RGBBlend(a, b: integer; var Palette: TColorMap); +{ Linear blend between to indices of a palette } +var + c, v: real; + vrange, range: real; + i: integer; +begin + if a = b then + begin + Exit; + end; + range := b - a; + vrange := Palette[b mod 256][0] - Palette[a mod 256][0]; + c := Palette[a mod 256][0]; + v := vrange / range; + for i := (a + 1) to (b - 1) do + begin + c := c + v; + Palette[i mod 256][0] := Round(c); + end; + vrange := Palette[b mod 256][1] - Palette[a mod 256][1]; + c := Palette[a mod 256][1]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][1] := Round(c); + end; + vrange := Palette[b mod 256][2] - Palette[a mod 256][2]; + c := Palette[a mod 256][2]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][2] := Round(c); + end; +end; + +function CreatePalette(strng: string): TColorMap; +{ Loads a palette from a gradient string } +var + Strings: TStringList; + index, i: integer; + Tokens: TStringList; + Indices, Colors: TStringList; + a, b: integer; +begin + Strings := TStringList.Create; + Tokens := TStringList.Create; + Indices := TStringList.Create; + Colors := TStringList.Create; + try + try + Strings.Text := strng; + if Pos('}', Strings.Text) = 0 then raise EFormatInvalid.Create('No closing brace'); + if Pos('{', Strings[0]) = 0 then raise EFormatInvalid.Create('No opening brace.'); + GetTokens(ReplaceTabs(strings.text), tokens); + Tokens.Text := Trim(Tokens.text); + i := 0; + while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do + begin + if Pos('index=', LowerCase(Tokens[i])) <> 0 then + Indices.Add(GetVal(Tokens[i])) + else if Pos('color=', LowerCase(Tokens[i])) <> 0 then + Colors.Add(GetVal(Tokens[i])); + inc(i) + end; + for i := 0 to 255 do + begin + Result[i][0] := 0; + Result[i][1] := 0; + Result[i][2] := 0; + end; + if Indices.Count = 0 then raise EFormatInvalid.Create('No color info'); + for i := 0 to Indices.Count - 1 do + begin + try + index := StrToInt(Indices[i]); + while index < 0 do inc(index, 400); + index := Round(Index * (255 / 399)); + indices[i] := IntToStr(index); + assert(index>=0); + assert(index<256); + Result[index][0] := StrToInt(Colors[i]) mod 256; + Result[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256; + Result[index][2] := trunc(StrToInt(Colors[i]) / 65536); + except + end; + end; + i := 1; + repeat + a := StrToInt(Trim(Indices[i - 1])); + b := StrToInt(Trim(Indices[i])); + RGBBlend(a, b, Result); + inc(i); + until i = Indices.Count; + if (Indices[0] <> '0') or (Indices[Indices.Count - 1] <> '255') then + begin + a := StrToInt(Trim(Indices[Indices.Count - 1])); + b := StrToInt(Trim(Indices[0])) + 256; + RGBBlend(a, b, Result); + end; + except on EFormatInvalid do + begin +// Result := False; + end; + end; + finally + Tokens.Free; + Strings.Free; + Indices.Free; + Colors.Free; + end; +end; + +procedure GetGradientFileGradientsNames(const filename: string; var NamesList: TStringList); +var + i, p: integer; + Title: string; + FStrings: TStringList; +begin + FStrings := TStringList.Create; + FStrings.LoadFromFile(filename); + try + if (Pos('{', FStrings.Text) <> 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos('{', FStrings[i]); + if (p <> 0) and (Pos('(3D)', FStrings[i]) = 0) then + begin + Title := Trim(Copy(FStrings[i], 1, p - 1)); + if Title <> '' then + NamesList.Add(Trim(Copy(FStrings[i], 1, p - 1))); + end; + end; + end; + finally + FStrings.Free; + end; +end; + +procedure RandomGradient(SourceCP, DestCP: TControlPoint); +var + tmpGrad: string; + tmpGrdList: TStringList; +begin + case randGradient of + 0: + begin + cmap_index := Random(NRCMAPS); + GetCMap(cmap_index, 1, DestCP.cmap); +// cmap_index := DestCP.cmapindex; + DestCP.cmapIndex := cmap_index; + end; + 1: + begin + DestCP.cmap := DefaultPalette; + DestCP.cmapIndex := cmap_index; + end; + 2: + if assigned(SourceCP) then begin + DestCP.cmap := SourceCP.cmap; + DestCP.cmapIndex := SourceCP.cmapIndex; + end else begin + cmap_index := Random(NRCMAPS); + GetCMap(cmap_index, 1, DestCP.cmap); + DestCP.cmapIndex := cmap_index; + end; + 3: + DestCP.cmap := GradientHelper.RandomGradient; + 4: + if FileExists(randGradientFile) then + begin + tmpGrdList := TStringList.Create; + GetGradientFileGradientsNames(randGradientFile, tmpGrdList); + tmpGrad := GetGradient(randGradientFile, tmpGrdList.Strings[random(tmpGrdList.Count)]); + DestCP.cmap := CreatePalette(tmpGrad); + tmpGrdList.Free; + end else + begin + cmap_index := Random(NRCMAPS); + GetCMap(cmap_index, 1, DestCP.cmap); + DestCP.cmapIndex := cmap_index; + end; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure RandomVariation(cp: TControlPoint); +{ Randomise variation parameters } +var + a, b, i, j: integer; + VarPossible: boolean; +begin + inc(MainSeed); + RandSeed := MainSeed; + + VarPossible := false; + for j := 0 to NRVAR - 1 do begin + VarPossible := VarPossible or Variations[j]; + end; + + for i := 0 to cp.NumXForms - 1 do begin + for j := 0 to NRVAR - 1 do + cp.xform[i].SetVariation(j, 0); + + if VarPossible then begin + repeat + a := random(NRVAR); + until Variations[a]; + + repeat + b := random(NRVAR); + until Variations[b]; + end else begin + a := 0; + b := 0; + end; + + if (a = b) then begin + cp.xform[i].SetVariation(a, 1); + end else begin + cp.xform[i].SetVariation(a, random); + cp.xform[i].SetVariation(b, 1 - cp.xform[i].GetVariation(a)); + end; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure SetVariation(cp: TControlPoint); +{ Set the current Variation } +var + i, j: integer; +begin + if Variation = vRandom then begin + RandomVariation(cp); + end else + for i := 0 to cp.NumXForms - 1 do begin + for j := 0 to NRVAR - 1 do + cp.xform[i].SetVariation(j, 0); + cp.xform[i].SetVariation(integer(Variation), 1); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +(* --Z-- hmm, exactly the same function exists in module Main + +function TrianglesFromCP(const cp1: TControlPoint; var Triangles: TTriangles): integer; +{ Sets up the triangles from the IFS code } +var + xforms: integer; + i, j: integer; + temp_x, temp_y, xset, yset: double; + left, top, bottom, right: double; + a, b, c, d, e, f: double; +begin + top := 0; bottom := 0; right := 0; left := 0; + xforms := NumXForms(cp1); + Result := xforms; + if not FixedReference then + begin + for i := 0 to xforms - 1 do + begin + a := cp1.xform[i].c[0][0]; + b := cp1.xform[i].c[0][1]; + c := cp1.xform[i].c[1][0]; + d := cp1.xform[i].c[1][1]; + e := cp1.xform[i].c[2][0]; + f := cp1.xform[i].c[2][1]; + xset := 1.0; + yset := 1.0; + for j := 0 to 5 do + begin + temp_x := xset * a + yset * c + e; + temp_y := xset * b + yset * d + f; + xset := temp_x; + yset := temp_y; + end; + if (i = 0) then + begin + left := xset; + right := xset; + top := yset; + bottom := yset; + end + else + begin + if (xset < left) then left := xset; + if (xset > right) then right := xset; + if (yset < top) then top := yset; + if (yset > bottom) then bottom := yset; + end; + end; + Triangles[-1].x[0] := left; + Triangles[-1].x[1] := right; + Triangles[-1].x[2] := right; + Triangles[-1].y[0] := bottom; + Triangles[-1].y[1] := bottom; + Triangles[-1].y[2] := top; + end + else + begin + Triangles[-1].x[0] := 0; Triangles[-1].y[0] := 0; + Triangles[-1].x[1] := 1; Triangles[-1].y[1] := 0; + Triangles[-1].x[2] := 1; Triangles[-1].y[2] := 1.5; + end; + + for j := 0 to xforms - 1 do + begin + a := cp1.xform[j].c[0][0]; + b := cp1.xform[j].c[0][1]; + c := cp1.xform[j].c[1][0]; + d := cp1.xform[j].c[1][1]; + e := cp1.xform[j].c[2][0]; + f := cp1.xform[j].c[2][1]; + for i := 0 to 2 do + begin + triangles[j].x[i] := Triangles[-1].x[i] * a + Triangles[-1].y[i] * + c + e; + triangles[j].y[i] := Triangles[-1].x[i] * b + Triangles[-1].y[i] * + d + f; + end; + end; + for i := -1 to xforms - 1 do + for j := 0 to 2 do + triangles[i].y[j] := -triangles[i].y[j]; +end; +*) + +/////////////////////////////////////////////////////////////////////////////// +procedure EqualizeWeights(var cp: TControlPoint); +var + t, i: integer; +begin + t := cp.NumXForms; + for i := 0 to t - 1 do + cp.xform[i].density := 1.0 / t; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure NormalizeWeights(var cp: TControlPoint); +var + i: integer; + td: double; +begin + td := 0.0; + for i := 0 to cp.NumXForms - 1 do + td := td + cp.xform[i].Density; + if (td < 0.001) then + EqualizeWeights(cp) + else + for i := 0 to cp.NumXForms - 1 do + cp.xform[i].Density := cp.xform[i].Density / td; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure ComputeWeights(var cp1: TControlPoint; Triangles: TTriangles; t: integer); +{ Caclulates transform weight from triangles } +var + i: integer; + total_area: double; +begin + total_area := 0.0; + for i := 0 to t - 1 do + begin + cp1.xform[i].Density := triangle_area(Triangles[i]); + total_area := total_area + cp1.xform[i].Density; + end; + for i := 0 to t - 1 do + begin + cp1.xform[i].Density := cp1.xform[i].Density / total_area; + end; + NormalizeWeights(cp1); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure RandomWeights(var cp1: TControlPoint); +{ Randomizes xform weights } +var + i: integer; +begin + for i := 0 to Transforms - 1 do + cp1.xform[i].Density := random; + NormalizeWeights(cp1); +end; + +/////////////////////////////////////////////////////////////////////////////// +function RandomFlame(SourceCP: TControlPoint; algorithm: integer): TControlPoint; +var + Min, Max, i, j, rnd: integer; + Triangles: TTriangles; + r, s, theta, phi: double; + skip: boolean; +begin + if Assigned(SourceCP) then + Result := SourceCP.clone + else + Result := TControlPoint.Create; + + Min := randMinTransforms; + Max := randMaxTransforms; + + inc(MainSeed); + RandSeed := MainSeed; + transforms := random(Max - (Min - 1)) + Min; + repeat + try + inc(MainSeed); + RandSeed := MainSeed; + Result.clear; + Result.RandomCP(transforms, transforms, false); + Result.SetVariation(Variation); + inc(MainSeed); + RandSeed := MainSeed; + + case algorithm of + 1: rnd := 0; + 2: rnd := 7; + 3: rnd := 9; + else + if (Variation = vLinear) or (Variation = vRandom) then + rnd := random(10) + else + rnd := 9; + end; + case rnd of + 0..6: + begin + for i := 0 to Transforms - 1 do + begin + if Random(10) < 9 then + Result.xform[i].c[0, 0] := 1 + else + Result.xform[i].c[0, 0] := -1; + Result.xform[i].c[0, 1] := 0; + Result.xform[i].c[1, 0] := 0; + Result.xform[i].c[1, 1] := 1; + Result.xform[i].c[2, 0] := 0; + Result.xform[i].c[2, 1] := 0; + Result.xform[i].color := 0; + Result.xform[i].symmetry := 0; + Result.xform[i].SetVariation(0, 1); + for j := 1 to NRVAR - 1 do + Result.xform[i].SetVariation(j, 0); + Result.xform[i].Translate(random * 2 - 1, random * 2 - 1); + Result.xform[i].Rotate(random * 360); + if i > 0 then + Result.xform[i].Scale(random * 0.8 + 0.2) + else + Result.xform[i].Scale(random * 0.4 + 0.6); + if Random(2) = 0 then + Result.xform[i].Multiply(1, random - 0.5, random - 0.5, 1); + end; + SetVariation(Result); + end; + 7, 8: + begin + { From the source to Chaos: The Software } + for i := 0 to Transforms - 1 do begin + r := random * 2 - 1; + if ((0 <= r) and (r < 0.2)) then + r := r + 0.2; + if ((r > -0.2) and (r <= 0)) then + r := r - 0.2; + s := random * 2 - 1; + if ((0 <= s) and (s < 0.2)) then + s := s + 0.2; + if ((s > -0.2) and (s <= 0)) then + s := s - -0.2; + theta := PI * random; + phi := (2 + random) * PI / 4; + Result.xform[i].c[0][0] := r * cos(theta); + Result.xform[i].c[1][0] := s * (cos(theta) * cos(phi) - sin(theta)); + Result.xform[i].c[0][1] := r * sin(theta); + Result.xform[i].c[1][1] := s * (sin(theta) * cos(phi) + cos(theta)); + { the next bit didn't translate so well, so I fudge it} + Result.xform[i].c[2][0] := random * 2 - 1; + Result.xform[i].c[2][1] := random * 2 - 1; + end; + for i := 0 to NXFORMS-1 do //NXFORMS - 1 do + Result.xform[i].density := 0; + for i := 0 to Transforms - 1 do + Result.xform[i].density := 1 / Transforms; + SetVariation(Result); + end; + 9: begin + for i := 0 to NXFORMS-1 do //NXFORMS - 1 do + Result.xform[i].density := 0; + for i := 0 to Transforms - 1 do + Result.xform[i].density := 1 / Transforms; + end; + end; // case + Result.TrianglesFromCp(Triangles); + if Random(2) > 0 then + ComputeWeights(Result, Triangles, transforms) + else + EqualizeWeights(Result); + except on E: EmathError do + begin + Continue; + end; + end; + for i := 0 to Transforms - 1 do + Result.xform[i].color := i / (transforms - 1); + if Result.xform[0].density = 1 then + Continue; + case SymmetryType of + { Bilateral } + 1: add_symmetry_to_control_point(Result, -1); + { Rotational } + 2: add_symmetry_to_control_point(Result, SymmetryOrder); + { Rotational and Reflective } + 3: add_symmetry_to_control_point(Result, -SymmetryOrder); + end; + { elimate flames with transforms that aren't affine } + skip := false; + for i := 0 to Transforms - 1 do begin + if not transform_affine(Triangles[i], Triangles) then + skip := True; + end; + if skip then + continue; + until not Result.BlowsUP(5000) and (Result.xform[0].density <> 0); + + RandomGradient(SourceCP, Result); + + Result.brightness := defBrightness; + Result.gamma := defGamma; + Result.gamma_threshold := defGammaThreshold; + Result.vibrancy := defVibrancy; + Result.sample_density := defSampleDensity; + Result.spatial_oversample := defOversample; + Result.spatial_filter_radius := defFilterRadius; + if KeepBackground and assigned(SourceCP) then begin + Result.background[0] := SourceCP.background[0]; + Result.background[1] := SourceCP.background[1]; + Result.background[2] := SourceCP.background[2]; + end else begin + Result.background[0] := 0; + Result.background[1] := 0; + Result.background[2] := 0; + end; + Result.zoom := 0; + Result.Nick := SheepNick; + Result.URl := SheepURL; + + Result.xform[Result.NumXForms].Clear; + Result.xform[Result.NumXForms].symmetry := 1; +end; + +end. diff --git a/Flame/XForm.pas b/Flame/XForm.pas new file mode 100644 index 0000000..49d0afe --- /dev/null +++ b/Flame/XForm.pas @@ -0,0 +1,1525 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +// REMOVE COMMENT TO COMPILE T-500 +//{$define T500} +//{$define Light} + +unit XForm; + +interface + +uses +{$ifdef Apo7X64} +{$else} +AsmRandom, +{$endif} + XFormMan, BaseVariation; + +const + MAX_WEIGHT = 1000.0; + {$ifndef Light} + {$ifndef T500} + NXFORMS = 100; + {$else} + NXFORMS = 500; + {$endif} + {$else} + NXFORMS = 50; + {$endif} + +type + TCPpoint = record + x, y, z, c, o: double; + end; + PCPpoint = ^TCPpoint; + + TXYpoint = record + x, y: double; + end; + PXYpoint = ^TXYpoint; + + T2Cpoint = record + x, y, c1, c2: double; + end; + + TMatrix = array[0..2, 0..2] of double; + +{$ifdef Apo7X64} +{$else} + //{$define _ASM_} +{$endif} + +type + TXForm = class + public + + c: array[0..2, 0..1] of double; // the coefs to the affine part of the function + p: array[0..2, 0..1] of double; // post-transform coefs! + density: double; // prob is this function is chosen + color: double; // color coord for this function. 0 - 1 + color2: double; // Second color coord for this function. 0 - 1 + vc: double; // Calculated color to be passed to the plugin + symmetry: double; + c00, c01, c10, c11, c20, c21: double;// unnecessary duplicated variables + p00, p01, p10, p11, p20, p21: double;// :-) + postXswap: boolean; + TransformName : string; + + autoZscale: boolean; // for 3d editing + transOpacity: double; + pluginColor: double; + +// nx,ny,x,y: double; +// script: TatPascalScripter; + + modWeights: array [0..NXFORMS] of double; + //modWeights: array of double; + PropTable: array of TXForm; + + Orientationtype: integer; + private + vars: array of double; // {normalized} interp coefs between variations + FNrFunctions: Integer; + FFunctionList: array of TCalcFunction; + FCalcFunctionList: array of TCalcFunction; + + FTx, FTy: double; // must remain in this order + FPx, FPy: double; // some asm code relies on this + + FTz, FPz: double; // 3d hack + + FAngle: double; + FSinA: double; + FCosA: double; + FLength: double; + colorC1, colorC2: double; + + // precalculated constants for some variations +// waves_f1, waves_f2, +// rings_dx, +// fan_dx, fan_dx2, +// cosine_var2, + polar_vpi, disc_vpi: double; + + gauss_rnd: array [0..3] of double; + gauss_N: integer; + + rx_sin, rx_cos, ry_sin, ry_cos: double; + px_sin, px_cos, py_sin, py_cos: double; + + FRegVariations: array of TBaseVariation; + + procedure PrecalcAngle; + procedure PrecalcSinCos; + procedure PrecalcAll; + procedure DoPostTransform; + procedure DoInvalidOperation; + + procedure Linear3D; // var[0] + procedure Sinusoidal; // var[1] + procedure Spherical; // var[2] + procedure Swirl; // var[3] + procedure Horseshoe; // var[4] + procedure Polar; // var[5] +// procedure FoldedHandkerchief; // var[6] +// procedure Heart; // var[7] + procedure Disc; // var[6] + procedure Spiral; // var[7] + procedure hyperbolic; // var[8] + procedure Square; // var[9] +// procedure Ex; // var[12] +// procedure Julia; // var[13] +// procedure Bent; // var[14] +// procedure Waves; // var[15] +// procedure Fisheye; // var[16] +// procedure Popcorn; // var[17] +// procedure Exponential; // var[11] +// procedure Power; // var[19] +// procedure Cosine; // var[20] +// procedure Rings; // var[21] +// procedure Fan; // var[22] + procedure Eyefish; + procedure Bubble; + procedure Cylinder; + procedure Noise; + procedure Blur; + procedure Gaussian; + procedure ZBlur; + procedure Blur3D; + + procedure PreBlur; + procedure PreZScale; + procedure PreZTranslate; + procedure PreRotateX; + procedure PreRotateY; + + procedure Flatten; + procedure ZScale; + procedure ZTranslate; + procedure ZCone; + + procedure PostRotateX; + procedure PostRotateY; + + function Mul33(const M1, M2: TMatrix): TMatrix; + function Identity: TMatrix; + + procedure BuildFunctionlist; + procedure AddRegVariations; + + public + constructor Create; + destructor Destroy; override; + procedure Clear; + procedure Prepare; + procedure PrepareInvalidXForm; + + procedure Assign(Xform: TXForm); + + procedure NextPoint(var CPpoint: TCPpoint); + procedure NextPointTo(var CPpoint, ToPoint: TCPpoint); + procedure NextPointXY(var px, py: double); + procedure NextPoint2C(var p: T2CPoint); + + procedure Rotate(const degrees: double); + procedure Translate(const x, y: double); + procedure Multiply(const a, b, c, d: double); + procedure Scale(const s: double); + + procedure GetVariable(const name: string; var Value: double); + procedure SetVariable(const name: string; var Value: double); + procedure ResetVariable(const name: string); + + function GetVariableStr(const name: string): string; + procedure SetVariableStr(const name: string; var Value: string); + + function ToXMLString: string; + function FinalToXMLString(IsEnabled: boolean): string; + + function GetVariation(index : integer) : double; + procedure SetVariation(index : integer; value : double); + function NumVariations : integer; + end; + +implementation + +uses + SysUtils, Math, StrUtils; + +const + EPS: double = 1E-300; + +function TXForm.NumVariations : integer; +begin + Result := length(vars); +end; +function TXForm.GetVariation(index : integer) : double; +begin + Result := vars[index]; +end; +procedure TXForm.SetVariation(index : integer; value : double); +begin + if (vars[index] = 0) and (value <> 0) then begin + // Activate var here + end else begin + // Deactivate var here + end; + vars[index] := value; +end; + + +{ TXForm } + +/////////////////////////////////////////////////////////////////////////////// +constructor TXForm.Create; +begin + AddRegVariations; + BuildFunctionlist; + SetLength(vars, NRLOCVAR + Length(FRegVariations)); + + Clear; +end; + +procedure TXForm.Clear; +var + i: Integer; +begin + density := 0; + color := 0; + symmetry := 0; + postXswap := false; + autoZscale := false; + + c[0, 0] := 1; + c[0, 1] := 0; + c[1, 0] := 0; + c[1, 1] := 1; + c[2, 0] := 0; + c[2, 1] := 0; + + p[0, 0] := 1; + p[0, 1] := 0; + p[1, 0] := 0; + p[1, 1] := 1; + p[2, 0] := 0; + p[2, 1] := 0; + + vars[0] := 1; + for i := 1 to High(vars) do + vars[i] := 0; + + for i := 0 to NXFORMS do + modWeights[i] := 1; + + transOpacity := 1; + pluginColor := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Prepare; +var + i: integer; + CalculateAngle, CalculateSinCos, CalculateLength: boolean; +begin + c00 := c[0][0]; + c01 := c[0][1]; + c10 := c[1][0]; + c11 := c[1][1]; + c20 := c[2][0]; + c21 := c[2][1]; + + colorC1 := (1 + symmetry)/2; + colorC2 := color*(1 - symmetry)/2; + + FNrFunctions := 0; + + for i := 0 to High(FRegVariations) do begin + FRegVariations[i].FPX := @FPX; + FRegVariations[i].FPY := @FPY; + FRegVariations[i].FPz := @FPz; + FRegVariations[i].FTX := @FTX; + FRegVariations[i].FTY := @FTY; + FRegVariations[i].FTz := @FTz; + FRegVariations[i].a := c00; + FRegVariations[i].b := c01; + FRegVariations[i].c := c10; + FRegVariations[i].d := c11; + FRegVariations[i].e := c20; + FRegVariations[i].f := c21; + FRegVariations[i].color := @vc; + + FRegVariations[i].vvar := vars[i + NRLOCVAR]; + FRegVariations[i].Prepare; + FRegVariations[i].GetCalcFunction(FFunctionList[NRLOCVAR + i]); + end; + + SetLength(FCalcFunctionList, NrVar + 2); + + CalculateAngle := (vars[6] <> 0.0) or (vars[7] <> 0.0); +// CalculateLength := False; + CalculateSinCos := (vars[8] <> 0.0) or (vars[10] <> 0.0); + + // Pre- variations + for i := 0 to NrVar - 1 do begin + if (vars[i] <> 0.0) and (LeftStr(Varnames(i), 4) = 'pre_') then begin + FCalcFunctionList[FNrFunctions] := FFunctionList[i]; + Inc(FNrFunctions); + end; + end; + + // Precalc must be called after pre- vars + if CalculateAngle or CalculateSinCos then + begin + if CalculateAngle and CalculateSinCos then + FCalcFunctionList[FNrFunctions] := PrecalcAll + else if CalculateAngle then + FCalcFunctionList[FNrFunctions] := PrecalcAngle + else //if CalculateSinCos then + FCalcFunctionList[FNrFunctions] := PrecalcSinCos; + Inc(FNrFunctions); + end; + + // Normal variations + for i := 0 to NrVar - 1 do begin + if (vars[i] <> 0.0) then begin + if (LeftStr(Varnames(i), 4) = 'pre_') or + (LeftStr(Varnames(i), 5) = 'post_') or + (Varnames(i) = 'flatten') then continue; + + FCalcFunctionList[FNrFunctions] := FFunctionList[i]; + Inc(FNrFunctions); + end; + end; + + // Post- variations + for i := 0 to NrVar - 1 do begin + if (vars[i] <> 0.0) and ( + (LeftStr(Varnames(i), 5) = 'post_') or + (Varnames(i) = 'flatten')) then begin + FCalcFunctionList[FNrFunctions] := FFunctionList[i]; + Inc(FNrFunctions); + end; + end; + +// waves_f1 := 1 / (sqr(c20) + EPS); +// waves_f2 := 1 / (sqr(c21) + EPS); + +// rings_dx := sqr(c20) + EPS; +// fan_dx := PI * (sqr(c20) + EPS); +// fan_dx2 := fan_dx/2; + +// cosine_var2 := vars[20]/2; + + polar_vpi := vars[6]/pi; + disc_vpi := vars[7]/pi; + + gauss_rnd[0] := random; + gauss_rnd[1] := random; + gauss_rnd[2] := random; + gauss_rnd[3] := random; + gauss_N := 0; + + rx_sin := sin(vars[22] * pi/2); + rx_cos := cos(vars[22] * pi/2); + ry_sin := sin(vars[23] * pi/2); + ry_cos := cos(vars[23] * pi/2); + + px_sin := sin(vars[27] * pi/2); + px_cos := cos(vars[27] * pi/2); + py_sin := sin(vars[28] * pi/2); + py_cos := cos(vars[28] * pi/2); + + if (p[0,0]<>1) or (p[0,1]<>0) or(p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) then + begin + p00 := p[0][0]; + p01 := p[0][1]; + p10 := p[1][0]; + p11 := p[1][1]; + p20 := p[2][0]; + p21 := p[2][1]; + + FCalcFunctionList[FNrFunctions] := DoPostTransform; + Inc(FNrFunctions); + end; + +(* + if (vars[27] <> 0.0) then begin + FFunctionList[FNrFunctions] := TestScript; + Inc(FNrFunctions); + + Script := TatPascalScripter.Create(nil); + Script.SourceCode.Text := + 'function test(x, y; var nx, ny);' + #10#13 + + 'begin' + #10#13 + + 'nx := x;' + #10#13 + + 'ny := y;' + #10#13 + + 'end;' + #10#13 + + 'function test2;' + #10#13 + + 'begin' + #10#13 + + 'nx := x;' + #10#13 + + 'ny := y;' + #10#13 + + 'end;' + #10#13 + + 'nx := x;' + #10#13 + + 'ny := y;' + #10#13; + Script.AddVariable('x',x); + Script.AddVariable('y',y); + Script.AddVariable('nx',nx); + Script.AddVariable('ny',ny); + Script.Compile; + end; + + if (vars[NRLOCVAR -1] <> 0.0) then begin + FFunctionList[FNrFunctions] := TestVar; + Inc(FNrFunctions); + end; +*) +end; + +procedure TXForm.PrepareInvalidXForm; +begin + c00 := 1; + c01 := 0; + c10 := 0; + c11 := 1; + c20 := 0; + c21 := 0; + + colorC1 := 1; + colorC2 := 0; + + FNrFunctions := 1; + SetLength(FCalcFunctionList, 1); + FCalcFunctionList[0] := DoInvalidOperation; +end; + +procedure TXForm.PrecalcAngle; +{$ifndef _ASM_} +begin + FAngle := arctan2(FTx, FTy); +{$else} +asm + fld qword ptr [eax + FTx] + fld qword ptr [eax + FTy] + fpatan + fstp qword ptr [eax + FAngle] + //fwait +{$endif} +end; + +procedure TXForm.PrecalcSinCos; +{$ifndef _ASM_} +begin + FLength := sqrt(sqr(FTx) + sqr(FTy)) + EPS; + FSinA := FTx / FLength; + FCosA := FTy / FLength; +{$else} +asm + fld qword ptr [eax + FTx] + fld qword ptr [eax + FTy] + fld st(1) + fmul st, st + fld st(1) + fmul st, st + faddp + fsqrt + fadd qword ptr [EPS] // avoid divide by zero...(?) + fdiv st(1), st + fdiv st(2), st + fstp qword ptr [eax + FLength] + fstp qword ptr [eax + FCosA] + fstp qword ptr [eax + FSinA] + //fwait +{$endif} +end; + +procedure TXForm.PrecalcAll; +{$ifndef _ASM_} +begin + FLength := sqrt(sqr(FTx) + sqr(FTy)) + EPS; + FSinA := FTx / FLength; + FCosA := FTy / FLength; + FAngle := arctan2(FTx, FTy); +{$else} +asm + fld qword ptr [eax + FTx] + fld qword ptr [eax + FTy] + fld st(1) + fld st(1) + fpatan + fstp qword ptr [eax + FAngle] + fld st(1) + fmul st, st + fld st(1) + fmul st, st + faddp + fsqrt + fadd qword ptr [EPS] // avoid divide by zero...(?) + fdiv st(1), st + fdiv st(2), st + fstp qword ptr [eax + FLength] + fstp qword ptr [eax + FCosA] + fstp qword ptr [eax + FSinA] + //fwait +{$endif} +end; + +procedure TXForm.DoPostTransform; +{$ifndef _ASM_} +var + tmp: double; +begin + tmp := FPx; + FPx := p00 * FPx + p10 * FPy + p20; + FPy := p01 * tmp + p11 * FPy + p21; +{$else} +asm + fld qword ptr [eax + FPy] + fld qword ptr [eax + FPx] + fld st(1) + fmul qword ptr [eax + p10] + fld st(1) + fmul qword ptr [eax + p00] + faddp + fadd qword ptr [eax + p20] + fstp qword ptr [eax + FPx] + fmul qword ptr [eax + p01] + fld qword ptr [eax + p11] + fmulp st(2), st + faddp + fadd qword ptr [eax + p21] + fstp qword ptr [eax + FPy] + fwait +{$endif} +end; + +procedure TXForm.DoInvalidOperation; +begin + raise EMathError.Create('FCalcFunction not initialized!? Probably corrupted flame.'); +end; + +//--0--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Linear3D; +{$ifndef _ASM_} +begin + FPx := FPx + vars[0] * FTx; + FPy := FPy + vars[0] * FTy; + FPz := FPz + vars[0] * FTz; +{$else} +asm + mov edx, [eax + vars] + fld qword ptr [edx] + + fld qword ptr [eax + FTz] + fmul st, st(1) + fadd qword ptr [eax + FPz] + fstp qword ptr [eax + FPz] + + fld qword ptr [eax + FTx] + fmul st, st(1) + fadd qword ptr [eax + FPx] + fstp qword ptr [eax + FPx] + fld qword ptr [eax + FTy] + fmulp + fadd qword ptr [eax + FPy] + fstp qword ptr [eax + FPy] + fwait +{$endif} +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Flatten; +begin + FPz := 0; +end; + +//--1--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Sinusoidal; +{$ifndef _ASM_} +begin + FPx := FPx + vars[2] * sin(FTx); + FPy := FPy + vars[2] * sin(FTy); + FPz := FPz + FTz * vars[2]; +{$else} +asm + mov edx, [eax + vars] + fld qword ptr [edx + 2*8] + fld qword ptr [eax + FTz] + fmul st, st(1) + fadd qword ptr [eax + FPz] + fstp qword ptr [eax + FPz] + fld qword ptr [eax + FTx] + fsin + fmul st, st(1) + fadd qword ptr [eax + FPx] + fstp qword ptr [eax + FPx] + fld qword ptr [eax + FTy] + fsin + fmulp + fadd qword ptr [eax + FPy] + fstp qword ptr [eax + FPy] + fwait +{$endif} +end; + +//--2--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Spherical; +{$ifndef _ASM_} +var + r: double; +begin + r := vars[3] / (sqr(FTx) + sqr(FTy) + EPS); + FPx := FPx + FTx * r; + FPy := FPy + FTy * r; + FPz := FPz + FTz * vars[3]; +{$else} +asm + mov edx, [eax + vars] + fld qword ptr [edx + 3*8] + fld qword ptr [eax + FTz] + fmul st, st(1) + fadd qword ptr [eax + FPz] + fstp qword ptr [eax + FPz] + fstp st + + fld qword ptr [eax + FTy] + fld qword ptr [eax + FTx] + fld st(1) + fmul st, st + fld st(1) + fmul st, st + faddp + fadd qword ptr [EPS] + fdivr qword ptr [edx + 3*8] + fmul st(2), st + fmulp + fadd qword ptr [eax + FPx] + fstp qword ptr [eax + FPx] + fadd qword ptr [eax + FPy] + fstp qword ptr [eax + FPy] + fwait +{$endif} +end; + +//--3--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Swirl; +var + sinr, cosr: double; +begin + SinCos(sqr(FTx) + sqr(FTy), sinr, cosr); + FPx := FPx + vars[4] * (sinr * FTx - cosr * FTy); + FPy := FPy + vars[4] * (cosr * FTx + sinr * FTy); + FPz := FPz + FTz * vars[4]; +end; + +//--4--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Horseshoe; +var + r: double; +begin + r := vars[5] / (sqrt(sqr(FTx) + sqr(FTy)) + EPS); + FPx := FPx + (FTx - FTy) * (FTx + FTy) * r; + FPy := FPy + (2*FTx*FTy) * r; + FPz := FPz + FTz * vars[5]; +end; + +//--5--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Polar; +begin + FPx := FPx + polar_vpi * FAngle; //vars[5] * FAngle / PI; + FPy := FPy + vars[6] * (sqrt(sqr(FTx) + sqr(FTy)) - 1.0); + FPz := FPz + FTz * vars[6]; +end; + +//--6--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Disc; +{$ifndef _ASM_} +var + r, sinr, cosr: double; +begin + SinCos(PI * sqrt(sqr(FTx) + sqr(FTy)), sinr, cosr); + r := disc_vpi * FAngle; //vars[7] * FAngle / PI; + FPx := FPx + sinr * r; + FPy := FPy + cosr * r; + FPz := FPz + FTz * vars[7]; +{$else} +asm + mov edx, [eax + vars] + fld qword ptr [edx + 7*8] + fld qword ptr [eax + FTz] + fmul st, st(1) + fadd qword ptr [eax + FPz] + fstp qword ptr [eax + FPz] + fstp st + + fld qword ptr [eax + disc_vpi] + fmul qword ptr [eax + FAngle] + fld qword ptr [eax + FTx] + fmul st, st + fld qword ptr [eax + FTy] + fmul st, st + faddp + fsqrt + fldpi + fmulp + fsincos + fmul st, st(2) + fadd qword ptr [eax + FPy] + fstp qword ptr [eax + FPy] + fmulp + fadd qword ptr [eax + FPx] + fstp qword ptr [eax + FPx] + fwait +{$endif} +end; + +//--7--//////////////////////////////////////////////////////////////////////// +procedure TXForm.Spiral; +var + r, sinr, cosr: double; +begin + r := Flength + 1E-6; + SinCos(r, sinr, cosr); + r := vars[8] / r; + FPx := FPx + (FCosA + sinr) * r; + FPy := FPy + (FsinA - cosr) * r; + FPz := FPz + FTz * vars[8]; +end; + +//--10--/////////////////////////////////////////////////////////////////////// +procedure TXForm.Hyperbolic; +begin + FPx := FPx + vars[9] * FTx / (sqr(FTx) + sqr(FTy) + EPS); + FPy := FPy + vars[9] * FTy; + FPz := FPz + FTz * vars[9]; +end; + +//--11--/////////////////////////////////////////////////////////////////////// +procedure TXForm.Square; +var + sinr, cosr: double; +begin + SinCos(FLength, sinr, cosr); + FPx := FPx + vars[10] * FSinA * cosr; + FPy := FPy + vars[10] * FCosA * sinr; + FPz := FPz + FTz * vars[10]; +end; + +//--12--/////////////////////////////////////////////////////////////////////// +procedure TXForm.Eyefish; +var + r: double; +begin + r := 2 * vars[11] / (sqrt(sqr(FTx) + sqr(FTy)) + 1); + FPx := FPx + r * FTx; + FPy := FPy + r * FTy; + FPz := FPz + FTz * vars[11]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Bubble; +{$ifndef _ASM_} +var + r: double; +begin + r := (sqr(FTx) + sqr(FTy))/4 + 1; + FPz := FPz + vars[12] * (2 / r - 1); + + r := vars[12] / r; + + FPx := FPx + r * FTx; + FPy := FPy + r * FTy; +{$else} +asm + fld qword ptr [eax + FTy] + fld qword ptr [eax + FTx] + fld st(1) + fmul st, st + fld st(1) + fmul st, st + faddp + fld1 + fadd st, st + fadd st, st + fdivp st(1), st + + mov edx, [eax + vars] + fld qword ptr [edx + 12*8] + + fld1 + fadd st(2), st + fdivr st(2), st + + fld st(2) + fadd st, st + fsubrp st(1), st + fmul st, st(1) + fadd qword ptr [eax + FPz] + fstp qword ptr [eax + FPz] + + fmulp + + fmul st(2), st + fmulp + fadd qword ptr [eax + FPx] + fstp qword ptr [eax + FPx] + fadd qword ptr [eax + FPy] + fstp qword ptr [eax + FPy] + fwait +{$endif} +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Cylinder; +{$ifndef _ASM_} +begin + FPx := FPx + vars[13] * sin(FTx); + FPy := FPy + vars[13] * FTy; + FPz := FPz + vars[13] * cos(FTx); +{$else} +asm + mov edx, [eax + vars] + fld qword ptr [edx + 13*8] + fld qword ptr [eax + FTx] + fsincos + fmul st, st(2) + fadd qword ptr [eax + FPz] + fstp qword ptr [eax + FPz] + fld qword ptr [eax + FTy] + fmul st, st(2) + fadd qword ptr [eax + FPy] + fstp qword ptr [eax + FPy] + fmulp + fadd qword ptr [eax + FPx] + fstp qword ptr [eax + FPx] + fwait +{$endif} +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Noise; +var + r, s, sinr, cosr: double; +begin + // Randomize here = HACK! Fix me... + Randomize; SinCos(random * 2*pi, sinr, cosr); + s := vars[14]; + r := s * random; + FPx := FPx + FTx * r * cosr; + FPy := FPy + FTy * r * sinr; + FPz := FPz + FTz * s; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Blur; +var + r, s, z, sina, cosa: double; +begin + // Randomize here = HACK! Fix me... + Randomize; SinCos(random * 2*pi, sina, cosa); + s := vars[15]; z := FTz; + r := s * random; + FPx := FPx + r * cosa; + FPy := FPy + r * sina; + FPz := FPz + s * z; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Gaussian; +var + r, s, z, sina, cosa: double; +begin + // Randomize here = HACK! Fix me... + Randomize; SinCos(random * 2*pi, sina, cosa); + s := vars[16]; z := FTz; + r := s * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2); + gauss_rnd[gauss_N] := random; + gauss_N := (gauss_N+1) and $3; + + FPx := FPx + r * cosa; + FPy := FPy + r * sina; + FPz := FPz + s * z; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.ZBlur; +begin + FPz := FPz + vars[17] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2); + gauss_rnd[gauss_N] := random; + gauss_N := (gauss_N+1) and $3; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Blur3D; +var + r, sina, cosa, sinb, cosb: double; +begin + // Randomize here = HACK! Fix me... + Randomize; SinCos(random * 2*pi, sina, cosa); + r := vars[18] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2); + gauss_rnd[gauss_N] := random; + gauss_N := (gauss_N+1) and $3; + + SinCos(random * pi, sinb, cosb); + FPx := FPx + r * sinb * cosa; + FPy := FPy + r * sinb * sina; + FPz := FPz + r * cosb; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.PreBlur; +var + r, sina, cosa: double; +begin + // Randomize here = HACK! Fix me... + Randomize; SinCos(random * 2*pi, sina, cosa); + r := vars[19] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2); + gauss_rnd[gauss_N] := random; + gauss_N := (gauss_N+1) and $3; + + FTx := FTx + r * cosa; + FTy := FTy + r * sina; +end; + + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.PreZScale; +begin + FTz := FTz * vars[20]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.PreZTranslate; +begin + FTz := FTz + vars[21]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.PreRotateX; +var + z: double; +begin + z := rx_cos * FTz - rx_sin * FTy; + FTy := rx_sin * FTz + rx_cos * FTy; + FTz := z; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.PreRotateY; +var + x: double; +begin + x := ry_cos * FTx - ry_sin * FTz; + FTz := ry_sin * FTx + ry_cos * FTz; + FTx := x; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.ZScale; +{$ifndef _ASM_} +begin + FPz := FPz + vars[24] * FTz; +{$else} +asm + fld qword ptr [eax + FTz] + mov edx, [ebx + vars] + fmul qword ptr [edx + 24*8] + fadd qword ptr [ebx + FPz] + fstp qword ptr [ebx + FPz] + fwait +{$endif} +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.ZTranslate; +begin + FPz := FPz + vars[25]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.ZCone; +{$ifndef _ASM_} +begin + FPz := FPz + vars[26] * sqrt(sqr(FTx) + sqr(FTy)); +{$else} +asm + fld qword ptr [eax + FTx] + fmul st,st + fld qword ptr [eax + FTy] + fmul st,st + faddp + fsqrt + mov edx, [ebx + vars] + fmul qword ptr [edx + 26*8] + fadd qword ptr [ebx + FPz] + fstp qword ptr [ebx + FPz] + fwait +{$endif} +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.PostRotateX; +var + z: double; +begin + z := px_cos * FPz - px_sin * FPy; + FPy := px_sin * FPz + px_cos * FPy; + FPz := z; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.PostRotateY; +var + x: double; +begin + x := py_cos * FPx - py_sin * FPz; + FPz := py_sin * FPx + py_cos * FPz; + FPx := x; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.NextPoint(var CPpoint: TCPpoint); +var + i: Integer; +begin + // first compute the color coord +// CPpoint.c := (CPpoint.c + color) * 0.5 * (1 - symmetry) + symmetry * CPpoint.c; + CPpoint.c := CPpoint.c * colorC1 + colorC2; + vc := CPpoint.c; + + FTx := c00 * CPpoint.x + c10 * CPpoint.y + c20; + FTy := c01 * CPpoint.x + c11 * CPpoint.y + c21; + FTz := CPpoint.z; + + Fpx := 0; + Fpy := 0; + Fpz := 0; + + for i:= 0 to FNrFunctions-1 do + FCalcFunctionList[i]; + + CPpoint.c := CPpoint.c + pluginColor * (vc - CPpoint.c); + CPpoint.x := FPx; + CPpoint.y := FPy; + CPPoint.z := FPz; +end; + +procedure TXForm.NextPointTo(var CPpoint, ToPoint: TCPpoint); +var + i: Integer; +begin + ToPoint.c := CPpoint.c * colorC1 + colorC2; + vc := ToPoint.c; + + FTx := c00 * CPpoint.x + c10 * CPpoint.y + c20; + FTy := c01 * CPpoint.x + c11 * CPpoint.y + c21; + FTz := CPpoint.z; + + Fpx := 0; + Fpy := 0; + Fpz := 0; + + for i:= 0 to FNrFunctions-1 do + FCalcFunctionList[i]; + + ToPoint.c := ToPoint.c + pluginColor * (vc - ToPoint.c); + ToPoint.x := FPx; + ToPoint.y := FPy; + ToPoint.z := FPz; //? +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.NextPoint2C(var p: T2CPoint); +var + i: Integer; +begin + // first compute the color coord +// pc1 := (pc1 + color) * 0.5 * (1 - symmetry) + symmetry * pc1; +// pc2 := (pc2 + color) * 0.5 * (1 - symmetry) + symmetry * pc2; + p.c1 := p.c1 * colorC1 + colorC2; + p.c2 := p.c2 * colorC1 + colorC2; + + FTx := c00 * p.x + c10 * p.y + c20; + FTy := c01 * p.x + c11 * p.y + c21; + + Fpx := 0; + Fpy := 0; + + for i:= 0 to FNrFunctions-1 do + FCalcFunctionList[i]; + + p.x := FPx; + p.y := FPy; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.NextPointXY(var px, py: double); +var + i: integer; +begin + FTx := c00 * px + c10 * py + c20; + FTy := c01 * px + c11 * py + c21; + FTz := 0; + + Fpx := 0; + Fpy := 0; + + for i:= 0 to FNrFunctions-1 do + FCalcFunctionList[i]; + + px := FPx; + py := FPy; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TXForm.Mul33(const M1, M2: TMatrix): TMatrix; +begin + result[0, 0] := M1[0][0] * M2[0][0] + M1[0][1] * M2[1][0] + M1[0][2] * M2[2][0]; + result[0, 1] := M1[0][0] * M2[0][1] + M1[0][1] * M2[1][1] + M1[0][2] * M2[2][1]; + result[0, 2] := M1[0][0] * M2[0][2] + M1[0][1] * M2[1][2] + M1[0][2] * M2[2][2]; + result[1, 0] := M1[1][0] * M2[0][0] + M1[1][1] * M2[1][0] + M1[1][2] * M2[2][0]; + result[1, 1] := M1[1][0] * M2[0][1] + M1[1][1] * M2[1][1] + M1[1][2] * M2[2][1]; + result[1, 2] := M1[1][0] * M2[0][2] + M1[1][1] * M2[1][2] + M1[1][2] * M2[2][2]; + result[2, 0] := M1[2][0] * M2[0][0] + M1[2][1] * M2[1][0] + M1[2][2] * M2[2][0]; + result[2, 0] := M1[2][0] * M2[0][1] + M1[2][1] * M2[1][1] + M1[2][2] * M2[2][1]; + result[2, 0] := M1[2][0] * M2[0][2] + M1[2][1] * M2[1][2] + M1[2][2] * M2[2][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TXForm.Identity: TMatrix; +var + i, j: integer; +begin + for i := 0 to 2 do + for j := 0 to 2 do + Result[i, j] := 0; + Result[0][0] := 1; + Result[1][1] := 1; + Result[2][2] := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Rotate(const degrees: double); +var + r: double; + Matrix, M1: TMatrix; +begin + r := degrees * pi / 180; + M1 := Identity; + M1[0, 0] := cos(r); + M1[0, 1] := -sin(r); + M1[1, 0] := sin(r); + M1[1, 1] := cos(r); + Matrix := Identity; + + Matrix[0][0] := c[0, 0]; + Matrix[0][1] := c[0, 1]; + Matrix[1][0] := c[1, 0]; + Matrix[1][1] := c[1, 1]; + Matrix[0][2] := c[2, 0]; + Matrix[1][2] := c[2, 1]; + Matrix := Mul33(Matrix, M1); + c[0, 0] := Matrix[0][0]; + c[0, 1] := Matrix[0][1]; + c[1, 0] := Matrix[1][0]; + c[1, 1] := Matrix[1][1]; + c[2, 0] := Matrix[0][2]; + c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Translate(const x, y: double); +var + Matrix, M1: TMatrix; +begin + M1 := Identity; + M1[0, 2] := x; + M1[1, 2] := y; + Matrix := Identity; + + Matrix[0][0] := c[0, 0]; + Matrix[0][1] := c[0, 1]; + Matrix[1][0] := c[1, 0]; + Matrix[1][1] := c[1, 1]; + Matrix[0][2] := c[2, 0]; + Matrix[1][2] := c[2, 1]; + Matrix := Mul33(Matrix, M1); + c[0, 0] := Matrix[0][0]; + c[0, 1] := Matrix[0][1]; + c[1, 0] := Matrix[1][0]; + c[1, 1] := Matrix[1][1]; + c[2, 0] := Matrix[0][2]; + c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Multiply(const a, b, c, d: double); +var + Matrix, M1: TMatrix; +begin + M1 := Identity; + M1[0, 0] := a; + M1[0, 1] := b; + M1[1, 0] := c; + M1[1, 1] := d; + Matrix := Identity; + Matrix[0][0] := Self.c[0, 0]; + Matrix[0][1] := Self.c[0, 1]; + Matrix[1][0] := Self.c[1, 0]; + Matrix[1][1] := Self.c[1, 1]; + Matrix[0][2] := Self.c[2, 0]; + Matrix[1][2] := Self.c[2, 1]; + Matrix := Mul33(Matrix, M1); + Self.c[0, 0] := Matrix[0][0]; + Self.c[0, 1] := Matrix[0][1]; + Self.c[1, 0] := Matrix[1][0]; + Self.c[1, 1] := Matrix[1][1]; + Self.c[2, 0] := Matrix[0][2]; + Self.c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Scale(const s: double); +var + Matrix, M1: TMatrix; +begin + M1 := Identity; + M1[0, 0] := s; + M1[1, 1] := s; + Matrix := Identity; + Matrix[0][0] := c[0, 0]; + Matrix[0][1] := c[0, 1]; + Matrix[1][0] := c[1, 0]; + Matrix[1][1] := c[1, 1]; + Matrix[0][2] := c[2, 0]; + Matrix[1][2] := c[2, 1]; + Matrix := Mul33(Matrix, M1); + c[0, 0] := Matrix[0][0]; + c[0, 1] := Matrix[0][1]; + c[1, 0] := Matrix[1][0]; + c[1, 1] := Matrix[1][1]; + c[2, 0] := Matrix[0][2]; + c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +destructor TXForm.Destroy; +var + i: integer; +begin +// if assigned(Script) then +// Script.Free; + + for i := 0 to High(FRegVariations) do + FRegVariations[i].Free; + + inherited; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.BuildFunctionlist; +begin + SetLength(FFunctionList, NrVar + Length(FRegVariations)); + + //fixed + FFunctionList[0] := Linear3D; + FFunctionList[1] := Flatten; + FFunctionList[2] := Sinusoidal; + FFunctionList[3] := Spherical; + FFunctionList[4] := Swirl; + FFunctionList[5] := Horseshoe; + FFunctionList[6] := Polar; + FFunctionList[7] := Disc; + FFunctionList[8] := Spiral; + FFunctionList[9] := Hyperbolic; + FFunctionList[10] := Square; + FFunctionList[11] := Eyefish; + FFunctionList[12] := Bubble; + FFunctionList[13] := Cylinder; + FFunctionList[14] := Noise; + FFunctionList[15] := Blur; + FFunctionList[16] := Gaussian; + FFunctionList[17] := ZBlur; + FFunctionList[18] := Blur3D; + + FFunctionList[19] := PreBlur; + FFunctionList[20] := PreZScale; + FFunctionList[21] := PreZTranslate; + FFunctionList[22] := PreRotateX; + FFunctionList[23] := PreRotateY; + + FFunctionList[24] := ZScale; + FFunctionList[25] := ZTranslate; + FFunctionList[26] := ZCone; + + FFunctionList[27] := PostRotateX; + FFunctionList[28] := PostRotateY; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.AddRegVariations; +var + i: integer; +begin + SetLength(FRegVariations, GetNrRegisteredVariations); + for i := 0 to GetNrRegisteredVariations - 1 do begin + FRegVariations[i] := GetRegisteredVariation(i).GetInstance; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Assign(XForm: TXForm); +var + i,j: integer; + Name: string; + Value: double; +begin + if Not assigned(XForm) then + Exit; + + for i := 0 to High(vars) do + vars[i] := XForm.vars[i]; + + c := Xform.c; + p := Xform.p; + density := XForm.density; + color := XForm.color; + color2 := XForm.color2; + symmetry := XForm.symmetry; + Orientationtype := XForm.Orientationtype; + TransformName := XForm.TransformName; + + postXswap := Xform.postXswap; + autoZscale := Xform.autoZscale; + + for i := 0 to High(FRegVariations) do begin + for j := 0 to FRegVariations[i].GetNrVariables - 1 do begin + Name := FRegVariations[i].GetVariableNameAt(j); + XForm.FRegVariations[i].GetVariable(Name, Value); + FRegVariations[i].SetVariable(Name, Value); + end; + end; + + for i := 0 to High(modWeights) do + modWeights[i] := xform.modWeights[i]; + + transOpacity := xform.transOpacity; + pluginColor := xform.pluginColor; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TXForm.ToXMLString: string; +var + i, j: integer; + Name: string; + Value: double; + numChaos: integer; +begin + result := Format(' 0 then result := result + format('symmetry="%g" ', [symmetry]); + + for i := 0 to nrvar - 1 do begin + if vars[i] <> 0 then + Result := Result + varnames(i) + format('="%g" ', [vars[i]]); + end; + Result := Result + Format('coefs="%g %g %g %g %g %g" ', [c[0,0], c[0,1], c[1,0], c[1,1], c[2,0], c[2,1]]); + if (p[0,0]<>1) or (p[0,1]<>0) or(p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) then + Result := Result + Format('post="%g %g %g %g %g %g" ', [p[0,0], p[0,1], p[1,0], p[1,1], p[2,0], p[2,1]]); + + for i := 0 to High(FRegVariations) do begin + if vars[i+NRLOCVAR] <> 0 then + for j := 0 to FRegVariations[i].GetNrVariables - 1 do begin + Name := FRegVariations[i].GetVariableNameAt(j); +// FRegVariations[i].GetVariable(Name,Value); +// Result := Result + Format('%s="%g" ', [name, value]); + Result := Result + Format('%s="%s" ', [name, FRegVariations[i].GetVariableStr(Name)]); + end; + end; + + numChaos := -1; + for i := NXFORMS-1 downto 0 do + if modWeights[i] <> 1 then begin + numChaos := i; + break; + end; + if numChaos >= 0 then begin + Result := Result + 'chaos="'; + for i := 0 to numChaos do + Result := Result + Format('%g ', [modWeights[i]]); + Result := Result + '" '; + end; + + Result := Result + Format('opacity="%g" ', [transOpacity]); + + if TransformName <> '' then + Result := Result + 'name="' + TransformName + '"'; + + if pluginColor <> 1 then + Result := Result + Format('var_color="%g" ', [pluginColor]); + + Result := Result + '/>'; +end; + +function TXForm.FinalToXMLString(IsEnabled: boolean): string; +var + i, j: integer; + Name: string; + Value: double; +begin + // result := Format(' 0 then result := result + format('symmetry="%g" ', [symmetry]); + + for i := 0 to nrvar - 1 do begin + if vars[i] <> 0 then + Result := Result + varnames(i) + format('="%g" ', [vars[i]]); + end; + Result := Result + Format('coefs="%g %g %g %g %g %g" ', [c[0,0], c[0,1], c[1,0], c[1,1], c[2,0], c[2,1]]); + if (p[0,0]<>1) or (p[0,1]<>0) or(p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) then + Result := Result + Format('post="%g %g %g %g %g %g" ', [p[0,0], p[0,1], p[1,0], p[1,1], p[2,0], p[2,1]]); + if pluginColor <> 1 then + Result := Result + Format('var_color="%g" ', [pluginColor]); + + for i := 0 to High(FRegVariations) do begin + if vars[i+NRLOCVAR] <> 0 then + for j := 0 to FRegVariations[i].GetNrVariables - 1 do begin + Name := FRegVariations[i].GetVariableNameAt(j); +// FRegVariations[i].GetVariable(Name,Value); +// Result := Result + Format('%s="%g" ', [name, value]); + Result := Result + Format('%s="%s" ', [name, FRegVariations[i].GetVariableStr(Name)]); + end; + end; + + Result := Result + '/>'; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.GetVariable(const name: string; var Value: double); +var + i: integer; +begin + for i := 0 to High(FRegVariations) do + if FRegVariations[i].GetVariable(name, value) then + break; +end; + +procedure TXForm.SetVariable(const name: string; var Value: double); +var + i: integer; +begin + for i := 0 to High(FRegVariations) do + if FRegVariations[i].SetVariable(name, value) then + break; +end; + +procedure TXForm.ResetVariable(const name: string); +var + i: integer; +begin + for i := 0 to High(FRegVariations) do + if FRegVariations[i].ResetVariable(name) then + break; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TXForm.GetVariableStr(const name: string): string; +var + i: integer; +begin + for i := 0 to High(FRegVariations) do begin + Result := FRegVariations[i].GetVariableStr(name); + if Result <> '' then break; + end; +end; + +procedure TXForm.SetVariableStr(const name: string; var Value: string); +var + i: integer; +begin + for i := 0 to High(FRegVariations) do begin + if FRegVariations[i].SetVariableStr(name, value) then break; + end; +end; + +end. diff --git a/Forms/About.dfm b/Forms/About.dfm new file mode 100644 index 0000000..8bdb4f4 --- /dev/null +++ b/Forms/About.dfm @@ -0,0 +1,1756 @@ +object AboutForm: TAboutForm + Left = 461 + Top = 320 + BorderStyle = bsDialog + Caption = 'Apophysis' + ClientHeight = 342 + ClientWidth = 417 + Color = clWindow + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + OnCreate = FormCreate + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Image1: TImage + Left = 8 + Top = 8 + Width = 377 + Height = 57 + Picture.Data = { + 07544269746D617006BB0000424D06BB00000000000036000000280000004501 + 0000310000000100180000000000D0BA0000120B0000120B0000000000000000 + 0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF6F6F6EFEFEF + E8E8E8E2E2E2DFDFDFE0E0E0E6E6E6EEEEEEF5F5F5FAFAFAFEFEFEFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFEFEFBFBFBF6F6F6EFEFEFE8E8E8E2E2E2DFDFDFE0E0E0E6E6E6 + EEEEEEF5F5F5FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFEFEFCFCFCF8F8F8F2F2F2EAEAEAE3E3E3DFDFDFDEDEDEE2E2E2 + E9E9E9F1F1F1F7F7F7FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFEFEFEF8F8F8F0F0F0E6E6E6D8D8D8CECECECACACACCCCCCD4D4D4E2 + E2E2EEEEEEF7F7F7FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8F0F0F0E6E6 + E6D8D8D8CECECECACACACCCCCCD4D4D4E2E2E2EEEEEEF7F7F7FCFCFCFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF5F5F5EBEB + EBDEDEDED2D2D2CACACAC8C8C8CDCDCDD8D8D8E5E5E5F0F0F0F8F8F8FDFDFDFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF5F5F5E9E9E9D9D9D9 + C4C4C4B5B5B5B0B0B0B3B3B3BFBFBFD4D4D4E6E6E6F2F2F2FBFBFBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFCFCFCF5F5F5E9E9E9D9D9D9C4C4C4B5B5B5B0B0B0B3B3B3BFBFBF + D4D4D4E6E6E6F2F2F2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFEFEFAFAFAF1F1F1E3E3E3D1D1D1BFBFBFB2B2B2ADADADB3B3B3 + C2C2C2D4D4D4E6E6E6F2F2F2FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFBFBFBF2F2F2E3E3E3CECECEB4B4B4A1A1A19A9A9A9E9E9EAEAEAEC8 + C8C8DFDFDFEFEFEFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF2F2F2E3E3E3CECE + CEB4B4B4A1A1A19A9A9A9E9E9EAEAEAEC8C8C8DFDFDFEFEFEFFAFAFAFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF0F0F0E0E0 + E0CBCBCBB3B3B3A1A1A19999999D9D9DADADADC3C3C3DADADAECECECF8F8F8FD + FDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF0F0F0DFDFDFC7C7C7 + A9A9A99292928A8A8A8F8F8FA1A1A1BFBFBFDADADAECECECF9F9F9FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFBFBFBF0F0F0DFDFDFC7C7C7A9A9A99292928A8A8A8F8F8FA1A1A1 + BFBFBFDADADAECECECF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFEFEFBFBFBF1F1F1E1E1E1CACACAB0B0B09898988C8C8C8C8C8C + 9A9A9AB2B2B2CDCDCDE3E3E3F2F2F2FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFCFCFCF9F9F9FFFFFFFFFFFFFFFFFFEFEFEFBABABA858585999999B9 + B9B9D6D6D6EBEBEBF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF9F9F9FFFFFFFFFF + FFFFFFFFEFEFEFBABABA858585999999B9B9B9D6D6D6EBEBEBF9F9F9FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFFFFFFFFFF + FFFFFFFFFFFFFFD5D5D58686868181818C8C8CA2A2A2BFBFBFD8D8D8ECECECF8 + F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB9B9B98A8A8A8A8A8A + 8A8A8A9A9A9AEDEDED808080949494B6B6B6D2D2D2E7E7E7F5F5F5FAFAFAF9F9 + F9F8F8F8F8F8F8F9F9F9FAFAFAFBFBFBFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFEFEFEFEFEFEFDFDFDFCFCFCFBFBFBFAFAFAF8F8F8F8F8F8F8F8F8F9F9 + F9FAFAFAFBFBFBFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFDFDFDB9B9B98A8A8A8A8A8A8A8A8A9A9A9AEDEDED808080949494 + B6B6B6D2D2D2E7E7E7F5F5F5FAFAFAF9F9F9F8F8F8F8F8F8F9F9F9FAFAFAFBFB + FBFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFB9B9B98A8A8A8A8A8A8A8A8A8A8A8AF0F0F09E9E9E7D7D7D + 828282959595B0B0B0CCCCCCE3E3E3F3F3F3FBFBFBFEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + FEFEFEFEFEFDFDFDFBFBFBFBFBFBF9F9F9F8F8F8F8F8F8F8F8F8F8F8F8F9F9F9 + FAFAFAFBFBFBFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFDFDFDFBFBFBFBFBFB + F9F9F9F8F8F8F8F8F8F8F8F8F8F8F8F9F9F9FAFAFAFBFBFBFCFCFCFEFEFEFEFE + FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2EFFFFFFFEFEFEFEFEFEFDFDFDFBFB + FBFBFBFBFAFAFAFAFAFAFAFAFAFBFBFBFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFEFEFEFEFEFEFDFDFDFBFBFBFAFAFAF9F9F9F9F9F9FAFAFAFBFB + FBFCFCFCFDFDFDB9B9B98B8B8B8B8B8B8B8B8B9A9A9AEDEDED7E7E7E929292B1 + B1B1CBCBCBDEDEDEE9E9E9EDEDEDEBEBEBEAEAEAEAEAEAECECECEEEEEEF1F1F1 + F5F5F5F8F8F8FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFCFCFCF9F9F9F6F6F6F2F2F2EF + EFEFECECECEBEBEBE9E9E9EAEAEAEBEBEBEDEDEDF0F0F0F3F3F3F7F7F7FAFAFA + FCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB9B9B98B8B8B8B8B + 8B8B8B8B9A9A9AEDEDED7E7E7E929292B1B1B1CBCBCBDEDEDEE9E9E9EDEDEDEB + EBEBEAEAEAEAEAEAECECECEEEEEEF1F1F1F5F5F5F8F8F8FBFBFBFDFDFDFEFEFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFDFDFDFBFB + FBFAFAFAFAFAFAFAFAFAFBFBFBFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFCFCFCFBFBFBFAFAFAFAFAFAFAFAFA + FBFBFBFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8B8B8B8B8B + 8B8B8B8B8B8B8BB9B9B9D3D3D38282827F7F7F8B8B8BA3A3A3BFBFBFDADADAEC + ECECF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFEFEFEFDFDFDFBFBFBFAFAFAF7F7F7F4F4F4F1F1F1EEEEEEECEC + ECEAEAEAE9E9E9E9E9E9E9E9E9ECECECEEEEEEF0F0F0F4F4F4F7F7F7FAFAFAFC + FCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFDFDFDFBFBFBFBFBFB + FAFAFAFAFAFAFBFBFBFCFCFCFEFEFEFEFEFEFEFEFEFFFFFFFEFEFEFDFDFDFBFB + FBFAFAFAF7F7F7F4F4F4F1F1F1EEEEEEECECECEAEAEAE9E9E9E9E9E9E9E9E9EC + ECECEEEEEEF0F0F0F4F4F4F7F7F7FAFAFAFCFCFCFEFEFEFEFEFEFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFEFEFEFEFEFEFCFCFCFBFBFBFAFAFAF9F9F9F9F9F9FAFAFAFBFBFBFD + FDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFCFCFCFBFBFBFAFA + FAF9F9F9F9F9F9FBFBFBFCFCFCFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFE + FCFCFCFBFBFBFAFAFAF9F9F9F9F9F9FAFAFAFBFBFBFDFDFDFEFEFEFEFEFEFFFF + FF00FFFFFFFEFEFEFCFCFCF9F9F9F5F5F5F2F2F2EFEFEFEFEFEFEFEFEFF3F3F3 + F7F7F7FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFBFBFBF8F8F8F4 + F4F4F0F0F0EEEEEEEEEEEEEFEFEFF3F3F3F8F8F8FBFBFBBABABA8C8C8C8C8C8C + 8C8C8C9C9C9CEDEDED7A7A7A8B8B8BA7A7A7BFBFBFCECECED7D7D7D8D8D8D5D5 + D5D4D4D4D4D4D4D6D6D6DADADAE0E0E0E6E6E6ECECECF2F2F2F8F8F8FBFBFBFD + FDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFCFCFC + F8F8F8F4F4F4EFEFEFE8E8E8E2E2E2DDDDDDD7D7D7D4D4D4D4D4D4D4D4D4D5D5 + D5D9D9D9DDDDDDE3E3E3E9E9E9F0F0F0F5F5F5F9F9F9FCFCFCFEFEFEFFFFFFFF + FFFFFFFFFFFDFDFDBABABA8C8C8C8C8C8C8C8C8C9C9C9CEDEDED7A7A7A8B8B8B + A7A7A7BFBFBFCECECED7D7D7D8D8D8D5D5D5D4D4D4D4D4D4D6D6D6DADADAE0E0 + E0E6E6E6ECECECF2F2F2F8F8F8FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFEFEFEFDFDFDFBFBFBF8F8F8F3F3F3F0F0F0EFEFEFF0F0F0F2F2F2F6F6F6 + FAFAFAFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFBFB + FBF7F7F7F3F3F3F0F0F0EFEFEFF0F0F0F3F3F3F7F7F7FBFBFBFDFDFDFEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFBABABA8C8C8C8C8C8C8C8C8C8C8C8CF0F0F09E9E9E + 7E7E7E838383969696B1B1B1CECECEE4E4E4F4F4F4FBFBFBFEFEFEFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFBFBFBF8F8F8F3F3F3EF + EFEFE9E9E9E3E3E3DFDFDFDADADAD7D7D7D4D4D4D3D3D3D3D3D3D4D4D4D6D6D6 + DADADADEDEDEE3E3E3E9E9E9EFEFEFF5F5F5F9F9F9FCFCFCFEFEFEFFFFFFFEFE + FEFEFEFEFBFBFBF8F8F8F4F4F4F1F1F1EFEFEFEFEFEFF2F2F2F6F6F6FAFAFAFC + FCFCFEFEFEFDFDFDFBFBFBF8F8F8F3F3F3EFEFEFE9E9E9E3E3E3DFDFDFDADADA + D7D7D7D4D4D4D3D3D3D3D3D3D4D4D4D6D6D6DADADADEDEDEE3E3E3E9E9E9EFEF + EFF5F5F5F9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFBFBFBF7F7F7F2F2F2 + EFEFEFEEEEEEEEEEEEF0F0F0F4F4F4F8F8F8FBFBFBFEFEFEFEFEFEFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + FEFEFDFDFDFBFBFBF7F7F7F2F2F2EFEFEFEEEEEEEEEEEEF0F0F0F4F4F4F8F8F8 + FBFBFBFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFEFEFEFCFCFCF9F9F9F5F5F5F1F1F1EEEEEEEDEDEDEEEEEEF0 + F0F0F5F5F5F8F8F8FBFBFBFEFEFEFFFFFF00FFFFFFFDFDFDF9F9F9F4F4F4EDED + EDE5E5E5E0E0E0DEDEDEE0E0E0E6E6E6EEEEEEF5F5F5FAFAFAFEFEFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFEFEFEFBFBFBF6F6F6EFEFEFE7E7E7E0E0E0DDDDDDDDDDDDE1E1E1E9E9 + E9F1F1F1FAFAFABABABA8D8D8D8D8D8D8D8D8D9D9D9DEDEDED75757582828299 + 9999ACACACB7B7B7BCBCBCBCBCBCB8B8B8B6B6B6B6B6B6B9B9B9BFBFBFC6C6C6 + CFCFCFDADADAE3E3E3ECECECF4F4F4F9F9F9FDFDFDFEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFFEFEFEFEFEFEFBFBFBF6F6F6EFEFEFE7E7E7DDDDDDD3D3D3C9C9C9C2 + C2C2BCBCBCB7B7B7B6B6B6B6B6B6B8B8B8BDBDBDC4C4C4CBCBCBD5D5D5DFDFDF + E9E9E9F1F1F1F8F8F8FBFBFBFEFEFEFFFFFFFFFFFFFDFDFDBABABA8D8D8D8D8D + 8D8D8D8D9D9D9DEDEDED757575828282999999ACACACB7B7B7BCBCBCBCBCBCB8 + B8B8B6B6B6B6B6B6B9B9B9BFBFBFC6C6C6CFCFCFDADADAE3E3E3ECECECF4F4F4 + F9F9F9FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF6F6F6EFEFEFE8E8 + E8E2E2E2DFDFDFE0E0E0E6E6E6EEEEEEF5F5F5FAFAFAFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFEFEFEFBFBFBF5F5F5EFEFEFE6E6E6E1E1E1DFDFDFE1E1E1 + E6E6E6EFEFEFF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFF0F0F08D8D + 8D8D8D8D8D8D8D8D8D8DBABABAD3D3D37F7F7F7D7D7D8A8A8AA3A3A3C0C0C0DA + DADAEDEDEDF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FDFDFDFBFBFBF5F5F5EFEFEFE6E6E6DDDDDDD4D4D4CDCDCDC6C6C6C2C2C2BEBE + BEBCBCBCBBBBBBBBBBBBBCBCBCBFBFBFC2C2C2C7C7C7CECECED6D6D6DFDFDFE8 + E8E8F0F0F0F7F7F7FBFBFBFEFEFEFEFEFEFBFBFBF7F7F7F1F1F1E9E9E9E2E2E2 + DFDFDFE0E0E0E5E5E5EDEDEDF4F4F4F9F9F9FBFBFBFBFBFBF5F5F5EFEFEFE6E6 + E6DDDDDDD4D4D4CDCDCDC6C6C6C2C2C2BEBEBEBCBCBCBBBBBBBBBBBBBCBCBCBF + BFBFC2C2C2C7C7C7CECECED6D6D6DFDFDFE8E8E8F0F0F0F7F7F7FBFBFBFEFEFE + FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFEFBFBFBF7F7F7F0F0F0E8E8E8E1E1E1DDDDDDDDDDDDE0E0E0E7E7E7EF + EFEFF6F6F6FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF7F7F7F0F0F0E9E9E9E1E1 + E1DDDDDDDDDDDDE0E0E0E7E7E7EFEFEFF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF7F7F7F1F1F1 + E9E9E9E1E1E1DCDCDCDBDBDBDDDDDDE3E3E3ECECECF3F3F3F9F9F9FDFDFDFEFE + FE00FFFFFFFCFCFCF7F7F7EEEEEEE3E3E3D5D5D5CBCBCBC8C8C8CBCBCBD3D3D3 + E0E0E0ECECECF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7EFEFEFE3E3E3D5 + D5D5CBCBCBC6C6C6C7C7C7CECECEDBDBDBE9E9E9F8F8F8BBBBBB8E8E8E8E8E8E + 8E8E8E9D9D9DECECEC6E6E6E7676768888889595959E9E9EA1A1A19E9E9E9A9A + 9A9898989898989A9A9A9F9F9FA7A7A7B3B3B3BFBFBFCECECEDCDCDCE8E8E8F2 + F2F2F8F8F8FCFCFCFEFEFEFFFFFFFFFFFFFEFEFEFDFDFDFAFAFAF5F5F5ECECEC + E0E0E0D3D3D3C5C5C5B7B7B7ABABABA3A3A39C9C9C9898989696969797979898 + 989E9E9EA4A4A4AEAEAEBABABAC8C8C8D6D6D6E3E3E3EEEEEEF6F6F6FBFBFBFE + FEFEFFFFFFFDFDFDBBBBBB8E8E8E8E8E8E8E8E8E9D9D9DECECEC6E6E6E767676 + 8888889595959E9E9EA1A1A19E9E9E9A9A9A9898989898989A9A9A9F9F9FA7A7 + A7B3B3B3BFBFBFCECECEDCDCDCE8E8E8F2F2F2F8F8F8FCFCFCFEFEFEFFFFFFFF + FFFFFEFEFEF8F8F8F0F0F0E6E6E6D8D8D8CECECECACACACCCCCCD4D4D4E2E2E2 + EEEEEEF7F7F7FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF8F8F8EFEF + EFE4E4E4D6D6D6CDCDCDCACACACDCDCDD6D6D6E4E4E4EFEFEFF8F8F8FDFDFDFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB8E8E8E8E8E8E8E8E8E969696F8F8F8 + 8888887878787F7F7F949494B2B2B2CFCFCFE6E6E6F4F4F4FCFCFCFEFEFEFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF6F6F6EEEEEEE2E2E2D4D4D4C7 + C7C7BCBCBCB2B2B2ABABABA7A7A7A4A4A4A4A4A4A3A3A3A4A4A4A4A4A4A7A7A7 + AAAAAAAEAEAEB5B5B5BEBEBEC9C9C9D6D6D6E3E3E3EDEDEDF5F5F5FBFBFBFCFC + FCF9F9F9F2F2F2E7E7E7DADADACECECECACACACBCBCBD3D3D3E0E0E0EDEDEDF5 + F5F5F8F8F8F6F6F6EEEEEEE2E2E2D4D4D4C7C7C7BCBCBCB2B2B2ABABABA7A7A7 + A4A4A4A4A4A4A3A3A3A4A4A4A4A4A4A7A7A7AAAAAAAEAEAEB5B5B5BEBEBEC9C9 + C9D6D6D6E3E3E3EDEDEDF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF2F2F2E9E9E9DCDCDC + CFCFCFC8C8C8C6C6C6CBCBCBD5D5D5E2E2E2EEEEEEF6F6F6FCFCFCFEFEFEFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + FEFEFAFAFAF3F3F3E9E9E9DDDDDDD1D1D1C8C8C8C6C6C6CACACAD4D4D4E0E0E0 + ECECECF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFEFCFCFCF7F7F7EFEFEFE4E4E4D7D7D7CBCBCBC5C5C5C5C5C5CACACAD4 + D4D4E2E2E2EDEDEDF6F6F6FBFBFBFEFEFE00FEFEFEFBFBFBF4F4F4E7E7E7D7D7 + D7C2C2C2B3B3B3ADADADB0B0B0BCBCBCCECECEE1E1E1EFEFEFF9F9F9FEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FEFEFEFBFBFBF2F2F2E5E5E5D3D3D3BFBFBFB0B0B0AAAAAAADADADB9B9B9CCCC + CCE0E0E0F6F6F6BCBCBC8F8F8F8F8F8F8F8F8F9E9E9EECECEC6767676B6B6B78 + 78788383838989898C8C8C8C8C8C8888888686868585858686868888888D8D8D + 969696A3A3A3B3B3B3C5C5C5D7D7D7E6E6E6F1F1F1F8F8F8FDFDFDFEFEFEFFFF + FFFEFEFEFBFBFBF4F4F4EAEAEADCDCDCCBCBCBB9B9B9A9A9A99B9B9B9090908A + 8A8A8686868585858585858585858686868787878C8C8C9292929E9E9EACACAC + BEBEBECFCFCFE0E0E0EDEDEDF6F6F6FBFBFBFEFEFEFDFDFDBCBCBC8F8F8F8F8F + 8F8F8F8F9E9E9EECECEC6767676B6B6B7878788383838989898C8C8C8C8C8C88 + 88888686868585858686868888888D8D8D969696A3A3A3B3B3B3C5C5C5D7D7D7 + E6E6E6F1F1F1F8F8F8FDFDFDFEFEFEFFFFFFFCFCFCF5F5F5E9E9E9D9D9D9C4C4 + C4B5B5B5B0B0B0B3B3B3BFBFBFD4D4D4E6E6E6F2F2F2FBFBFBFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFCFCFCF4F4F4E7E7E7D6D6D6C2C2C2B4B4B4B0B0B0B4B4B4 + C2C2C2D6D6D6E7E7E7F4F4F4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0 + F08F8F8F8F8F8F8F8F8F8F8F8FCBCBCBC2C2C2737373757575868686A2A2A2C2 + C2C2DCDCDCEEEEEEF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE + F9F9F9F1F1F1E4E4E4D3D3D3C0C0C0B0B0B0A3A3A39B9B9B9797979696969797 + 979898989999999B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9E9E9EA5A5A5B0B0B0BF + BFBFCFCFCFE0E0E0EDEDEDF6F6F6FAFAFAF5F5F5EBEBEBDBDBDBC7C7C7B6B6B6 + B0B0B0B1B1B1BCBCBCD1D1D1E3E3E3F0F0F0F5F5F5F1F1F1E4E4E4D3D3D3C0C0 + C0B0B0B0A3A3A39B9B9B9797979696969797979898989999999B9B9B9B9B9B9B + 9B9B9B9B9B9B9B9B9E9E9EA5A5A5B0B0B0BFBFBFCFCFCFE0E0E0EDEDEDF6F6F6 + FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFEF8F8F8EFEFEFE0E0E0CECECEBCBCBCAFAFAFAAAAAAAFAFAFBDBDBDCF + CFCFE1E1E1EFEFEFF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF8F8F8EFEFEFE2E2E2D0D0D0BEBE + BEB1B1B1ABABABAFAFAFBCBCBCCDCDCDDEDEDEECECECF7F7F7FCFCFCFEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9F0F0F0E3E3E3D1D1D1 + BFBFBFB0B0B0A8A8A8AAAAAAB3B3B3C4C4C4D7D7D7E7E7E7F3F3F3FBFBFBFEFE + FE00FFFFFFFBFBFBF3F3F3E4E4E4D1D1D1B8B8B8A3A3A3989898999999A6A6A6 + BCBCBCD4D4D4E8E8E8F5F5F5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7EBEBEBDADADAC2C2C2A9 + A9A99898989393939A9A9AABABABC4C4C4DBDBDBF6F6F6BDBDBD909090909090 + 9090909F9F9FEBEBEB6262626464647070707A7A7A8282828686868888888686 + 868484848282828080807F7F7F7F7F7F8383838C8C8C9A9A9AADADADC1C1C1D5 + D5D5E6E6E6F2F2F2FAFAFAFEFEFEFEFEFEFBFBFBF5F5F5EBEBEBDCDCDCC8C8C8 + B3B3B3A0A0A08F8F8F8686868080807F7F7F8080808181818383838383838181 + 818080807F7F7F818181878787939393A4A4A4B8B8B8CDCDCDE0E0E0EEEEEEF8 + F8F8FCFCFCFDFDFDBDBDBD9090909090909090909F9F9FEBEBEB626262646464 + 7070707A7A7A8282828686868888888686868484848282828080807F7F7F7F7F + 7F8383838C8C8C9A9A9AADADADC1C1C1D5D5D5E6E6E6F2F2F2FAFAFAFEFEFEFF + FFFFFBFBFBF2F2F2E3E3E3CECECEB4B4B4A1A1A19A9A9A9E9E9EAEAEAEC8C8C8 + DFDFDFEFEFEFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF1F1F1E1E1 + E1CBCBCBB1B1B1A0A0A09A9A9AA0A0A0B1B1B1CBCBCBE1E1E1F1F1F1FBFBFBFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBD909090909090909090989898 + F8F8F87676766B6B6B787878939393B3B3B3D0D0D0E6E6E6F5F5F5FCFCFCFEFE + FEFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7ECECECDBDBDBC6C6C6B0B0B0A0 + A0A09595958F8F8F9090909494949898989C9C9C9F9F9FA1A1A1A1A1A19E9E9E + 9A9A9A9696969292929393939A9A9AA7A7A7B9B9B9CECECEE1E1E1EFEFEFF5F5 + F5F2F2F2E6E6E6D1D1D1B7B7B7A3A3A39A9A9A9D9D9DABABABC5C5C5DCDCDCEC + ECECF1F1F1ECECECDBDBDBC6C6C6B0B0B0A0A0A09595958F8F8F909090949494 + 9898989C9C9C9F9F9FA1A1A1A1A1A19E9E9E9A9A9A9696969292929393939A9A + 9AA7A7A7B9B9B9CECECEE1E1E1EFEFEFF8F8F8FDFDFDFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8EEEEEEDEDEDEC8C8C8 + B1B1B19E9E9E959595989898A6A6A6BCBCBCD3D3D3E6E6E6F3F3F3FBFBFBFEFE + FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + FEFEF8F8F8EFEFEFE0E0E0CBCBCBB6B6B6A3A3A3989898989898A4A4A4B7B7B7 + CDCDCDE0E0E0EFEFEFF8F8F8FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFEFE + FEFBFBFBF3F3F3E6E6E6D3D3D3BDBDBDA7A7A7989898929292989898A8A8A8BD + BDBDD4D4D4E6E6E6F3F3F3FBFBFBFEFEFE00FFFFFFFCFCFCF4F4F4E5E5E5CFCF + CFB3B3B39A9A9A8A8A8A898989949494ABABABC7C7C7DFDFDFF0F0F0FAFAFAFE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE + FCFCFCF3F3F3E3E3E3CDCDCDB1B1B19797978686868383838F8F8FA5A5A5C2C2 + C2DBDBDBF6F6F6BDBDBD9191919191919191919F9F9FEBEBEB626262A3A3A3BB + BBBBF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFE9E9E9C3C3C39A9A9A8484847E7E7E + 7B7B7B7D7D7D858585959595AAAAAAC2C2C2D8D8D8E9E9E9F5F5F5FBFBFBFCFC + FCF8F8F8EEEEEEDFDFDFCACACAB2B2B2A0A0A0C1C1C1CACACAFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFF0F0F0C3C3C3B2B2B28787878181817C7C7C7B7B7B808080 + 8E8E8EA1A1A1B8B8B8D0D0D0E3E3E3F1F1F1FAFAFAFDFDFDBDBDBD9191919191 + 919191919F9F9FEBEBEB626262A3A3A3BBBBBBF6F6F6FFFFFFFFFFFFFFFFFFFF + FFFFE9E9E9C3C3C39A9A9A8484847E7E7E7B7B7B7D7D7D858585959595AAAAAA + C2C2C2D8D8D8E9E9E9F5F5F5FBFBFBFEFEFEFBFBFBF0F0F0DFDFDFC7C7C7A9A9 + A99292928A8A8A8F8F8FA1A1A1BFBFBFDADADAECECECF9F9F9FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFAFAFAEFEFEFDCDCDCC3C3C3A5A5A59191918A8A8A919191 + A5A5A5C3C3C3DCDCDCEFEFEFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFE + FEF0F0F0919191919191919191919191CCCCCCB5B5B56161616C6C6C848484A4 + A4A4C3C3C3DDDDDDEFEFEFF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD + F5F5F5E9E9E9D7D7D7C0C0C0C1C1C1CACACAD3D3D3FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFECECECD8D8D8CBCBCBA9A9A99E9E9E9393938B8B8B8A8A8A93 + 9393A4A4A4BBBBBBD3D3D3E6E6E6F0F0F0EFEFEFE1E1E1CACACAACACAC959595 + 8A8A8A8D8D8D9E9E9EBCBCBCD7D7D7E9E9E9EFEFEFE9E9E9D7D7D7C0C0C0C1C1 + C1CACACAD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECD8D8D8CB + CBCBA9A9A99E9E9E9393938B8B8B8A8A8A939393A4A4A4BBBBBBD3D3D3E6E6E6 + F4F4F4FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFEF9F9F9F0F0F0E0E0E0C9C9C9AFAFAF989898898989878787929292A8 + A8A8C2C2C2DADADAECECECF7F7F7FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF2F2F2E3E3E3CECECEB6B6 + B69F9F9F8F8F8F898989919191A2A2A2B9B9B9D1D1D1E4E4E4F2F2F2FAFAFAFE + FEFEFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF5F5F5EAEAEAD7D7D7C1C1C1A7A7A7 + 929292868686858585919191A6A6A6BFBFBFD7D7D7E9E9E9F5F5F5FCFCFCFEFE + FE00FFFFFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFD5D5D59393937D7D7D868686 + 9C9C9CB9B9B9D5D5D5E9E9E9F7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9EDEDEDF0F0F0FFFFFFFFFFFFFF + FFFFFFFFFFDCDCDCB0B0B0A7A7A7C5C5C5DEDEDEF7F7F7BFBFBF939393939393 + 939393A2A2A2EBEBEBFFFFFFD4D4D4CDCDCD9A9A9A9393939393939393939393 + 93A9A9A9CDCDCDF1F1F1DDDDDDA9A9A98181817A7A7A7A7A7A838383959595AD + ADADC8C8C8DEDEDEEFEFEFF8F8F8F9F9F9F2F2F2E5E5E5D0D0D0BFBFBFD7D7D7 + FFFFFFCDCDCDCDCDCD939393939393939393939393939393A2A2A2CDCDCDDBDB + DBF9F9F9CBCBCB8686867C7C7C7878787E7E7E8D8D8DA4A4A4BEBEBED6D6D6E9 + E9E9F5F5F5FCFCFCBFBFBF939393939393939393A2A2A2EBEBEBFFFFFFD4D4D4 + CDCDCD9A9A9A939393939393939393939393A9A9A9CDCDCDF1F1F1DDDDDDA9A9 + A98181817A7A7A7A7A7A838383959595ADADADC8C8C8DEDEDEEFEFEFF8F8F8FE + FEFEFCFCFCF9F9F9FFFFFFFFFFFFFFFFFFEFEFEFBABABA858585999999B9B9B9 + D6D6D6EBEBEBF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCFAFAFAFFFF + FFFFFFFFFFFFFFDFDFDFA9A9A98686869D9D9DBEBEBED9D9D9EDEDEDFAFAFAFF + FFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBFAFAFABFBFBF939393939393939393 + 9A9A9AF4F4F4595959626262787878959595B6B6B6D1D1D1E7E7E7F5F5F5FCFC + FCFEFEFEFFFFFFFFFFFFFFFFFFFDFDFDF5F5F5EFEFEFEFEFEFFFFFFFE2E2E2CD + CDCDC5C5C5939393939393939393939393939393939393B0B0B0CDCDCDDBDBDB + FBFBFBD8D8D8A2A2A28C8C8C828282858585929292A9A9A9C5C5C5DDDDDDECEC + ECF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFCBCBCB838383959595B6B6B6D3D3D3E7 + E7E7EEEEEEEFEFEFEFEFEFFFFFFFE2E2E2CDCDCDC5C5C5939393939393939393 + 939393939393939393B0B0B0CDCDCDDBDBDBFBFBFBD8D8D8A2A2A28C8C8C8282 + 82858585929292A9A9A9C5C5C5DDDDDDEEEEEEF9F9F9FEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF + FFFFFFD5D5D58686867D7D7D838383959595B0B0B0CBCBCBE1E1E1F1F1F1FAFA + FAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + FEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFDADADA909090838383848484909090 + A6A6A6BFBFBFD6D6D6E9E9E9F5F5F5FBFBFBFEFEFEFFFFFFFEFEFEFDFDFDF8F8 + F8EEEEEEDDDDDDE0E0E0F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFD4D4D4BCBCBCC7 + C7C7DDDDDDEEEEEEF8F8F8FDFDFDFFFFFF00FFFFFFE3E3E39494949494949494 + 94949494C5C5C5C7C7C77A7A7A7D7D7D8F8F8FADADADCACACAE3E3E3F2F2F2FB + FBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD + F5F5F5F0F0F0D4D4D4949494949494949494949494B1B1B1E1E1E1ADADADCBCB + CBE3E3E3F9F9F9BFBFBF9494949494949494949B9B9BCECECE94949494949494 + 9494949494949494949494949494949494949494949494949494B8B8B8E9E9E9 + D3D3D38383837878787979798686869B9B9BB6B6B6D1D1D1E6E6E6F2F2F2F5F5 + F5ECECECDADADADDDDDDF3F3F3C5C5C594949494949494949494949494949494 + 94949494949494949494949494949494949B9B9BD4D4D4E4E4E4AEAEAE7A7A7A + 7777777F7F7F929292ACACACC8C8C8E0E0E0F0F0F0FBFBFBBFBFBF9494949494 + 949494949B9B9BCECECE94949494949494949494949494949494949494949494 + 9494949494949494949494B8B8B8E9E9E9D3D3D3838383787878797979868686 + 9B9B9BB6B6B6D1D1D1E6E6E6F4F4F4FCFCFCFDFDFDBFBFBF9494949494949494 + 94A2A2A2EDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFEFEFEB1B1B1949494949494949494B1B1B1DCDCDC828282 + 989898BBBBBBD7D7D7ECECECFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8 + F8F0F0F0F1F1F1949494949494949494949494D4D4D4A3A3A35D5D5D6F6F6F89 + 8989A8A8A8C5C5C5DEDEDEEFEFEFFAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFDFDFD + FBFBFBE3E3E3C5C5C59494949494949494949494949494949494949494949494 + 949494949494949494949494949494949B9B9BCECECEEEEEEEBCBCBC7F7F7F7B + 7B7B8585859A9A9AB8B8B8D4D4D4F2F2F2CECECE949494949494949494949494 + FFFFFF7D7D7D909090B3B3B3D1D1D1E6E6E6F8F8F8E3E3E3C5C5C59494949494 + 9494949494949494949494949494949494949494949494949494949494949494 + 94949B9B9BCECECEEEEEEEBCBCBC7F7F7F7B7B7B8585859A9A9AB8B8B8D4D4D4 + E9E9E9F7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFF4F0FC7240D65C23CF5C23CF5C23CF5C23CFD3C4F2B8B8B87C7C7C7A7A7A87 + 87879E9E9EBABABAD4D4D4E9E9E9F5F5F5FCFCFCFEFEFEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E2F97240D65C23CF5C23CF5C23CF5C23 + CFDED3F5C8C8C8888888808080848484949494ABABABC5C5C5DBDBDBECECECF7 + F7F7FCFCFCFEFEFEFDFDFDF9F9F9F1F1F1E2E2E2DADADAF4F0FC7240D65C23CF + 5C23CF5C23CF5C23CF9D7BE2E4E4E4D3D3D3E6E6E6F3F3F3FBFBFBFEFEFEFFFF + FF00FFFFFFFFFFFFABABAB9696969696969696969D9D9DF8F8F88686867A7A7A + 8686869E9E9EBCBCBCD5D5D5E7E7E7F2F2F2F7F7F7F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F7F7F7F4F4F4EBEBEBF5F5F5B2B2B296969696969696 + 9696969696DCDCDCBCBCBCBABABAD6D6D6EBEBEBFAFAFAC0C0C0969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 96969696969696969696969696969696DCDCDCD2D2D28787877777777B7B7B8C + 8C8CA7A7A7C4C4C4DDDDDDECECECEEEEEEE3E3E3E8E8E8EAEAEAA4A4A4969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 96969696969696B2B2B2F8F8F8B5B5B57878787878788585859C9C9CB9B9B9D5 + D5D5E9E9E9FAFAFAC0C0C0969696969696969696969696969696969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 96DCDCDCD2D2D28787877777777B7B7B8C8C8CA7A7A7C4C4C4DDDDDDEFEFEFFA + FAFAFDFDFDC0C0C0969696969696969696A4A4A4EDEDED808080959595B6B6B6 + D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB2B2B29696 + 96969696969696B2B2B2DCDCDC828282989898BBBBBBD7D7D7ECECECFAFAFAFF + FFFFFFFFFFFFFFFFFEFEFEFBFBFBF4F4F4EAEAEAF1F1F1969696969696969696 + 969696A4A4A4E9E9E95E5E5E6B6B6B8080809B9B9BB8B8B8D3D3D3E9E9E9F6F6 + F6FDFDFDFFFFFFFFFFFFFFFFFFFEFEFED5D5D596969696969696969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 969696969696ABABABF1F1F1B9B9B97676767C7C7C8F8F8FAEAEAECECECEEFEF + EFCECECE969696969696969696969696FFFFFF7D7D7D909090B3B3B3D1D1D1F0 + F0F0D5D5D5969696969696969696969696969696969696969696969696969696 + 969696969696969696969696969696969696969696969696ABABABF1F1F1B9B9 + B97676767C7C7C8F8F8FAEAEAECECECEE5E5E5F5F5F5FDFDFDFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4C5F35E25D15E25D15E25D1 + 5E25D17E50DAEBEBEB8B8B8B7A7A7A7E7E7E8F8F8FAAAAAAC5C5C5DDDDDDEFEF + EFF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFDFD3F65E25D15E25D15E25D15E25D17442D7F4F0FCB0B0B0868686808080 + 878787999999B2B2B2CBCBCBE0E0E0EFEFEFF8F8F8FBFBFBFAFAFAF3F3F3E6E6 + E6D6D6D6E8E8E8946EE05E25D15E25D15E25D15E25D17E50DAF0F0F0D7D7D7E3 + E3E3F1F1F1F9F9F9FEFEFEFFFFFFFFFFFF00FFFFFFFFFFFFD5D5D59797979797 + 97979797979797D5D5D5B5B5B57979797E7E7E909090AAAAAAC3C3C3D6D6D6E2 + E2E2E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E3E3E3 + DEDEDEF1F1F1979797979797979797979797A5A5A5F0F0F0A8A8A8C6C6C6E0E0 + E0F1F1F1FBFBFBC1C1C197979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 979797CECECECFCFCF7A7A7A777777828282999999B7B7B7D4D4D4E4E4E4E6E6 + E6EBEBEBEAEAEA9D9D9D97979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797ACACACF8F8F8 + A0A0A07676767C7C7C8F8F8FADADADCBCBCBE3E3E3F9F9F9C1C1C19797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797CECECECFCFCF7A7A7A777777 + 828282999999B7B7B7D4D4D4E9E9E9F7F7F7FDFDFDC1C1C19797979797979797 + 97A5A5A5EDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFEFEFEB3B3B3979797979797979797B3B3B3DCDCDC828282 + 989898BBBBBBD7D7D7ECECECFAFAFAFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9EEEE + EEF1F1F1C1C1C1979797979797979797979797979797D5D5D5ABABAB6B6B6B7A + 7A7A8F8F8FAAAAAAC7C7C7DFDFDFF0F0F0FAFAFAFEFEFEFFFFFFFFFFFFFEFEFE + D5D5D5979797979797979797979797979797B3B3B3CECECEF1F1F1FFFFFFFFFF + FFFFFFFFFFFFFFD5D5D5C1C1C1979797979797979797979797A5A5A5F8F8F88D + 8D8D7777778B8B8BAAAAAACBCBCBEEEEEECECECE979797979797979797979797 + FFFFFF7D7D7D909090B3B3B3D1D1D1F1F1F1D5D5D59797979797979797979797 + 97979797B3B3B3CECECEF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFD5D5D5C1C1C197 + 9797979797979797979797A5A5A5F8F8F88D8D8D7777778B8B8BAAAAAACBCBCB + E3E3E3F4F4F4FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFF9F7DE46027D36027D36027D36027D3B59BEACACACA7F7F7F7A + 7A7A848484999999B5B5B5D0D0D0E5E5E5F3F3F3FBFBFBFEFEFEFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB59BEA6027D36027D36027 + D36027D3956EE2E2E2E29898988383838181818C8C8C9F9F9FB8B8B8D1D1D1E4 + E4E4F2F2F2F7F7F7F4F4F4EAEAEAD9D9D9E2E2E2B59BEA6027D36027D36027D3 + 6027D36A35D6EAE2F9DDDDDDDEDEDEEEEEEEF8F8F8FDFDFDFEFEFEFFFFFFFFFF + FF00FFFFFFFFFFFFF8F8F8A0A0A0999999999999999999B4B4B4E0E0E07A7A7A + 787878838383979797ADADADBFBFBFCACACAD0D0D0D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1CCCCCCE2E2E2CFCFCF99999999999999999999 + 9999CFCFCFC6C6C6B5B5B5D1D1D1E7E7E7F5F5F5FCFCFCC2C2C2999999999999 + 999999999999999999B4B4B4CFCFCFEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFEBEB + EBCFCFCF999999999999999999999999999999999999DDDDDDC2C2C27676767B + 7B7B8E8E8EACACACCBCBCBDCDCDCE5E5E5F8F8F8A6A6A6999999999999999999 + 999999999999C2C2C2DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFCFCFCFB4B4B49999 + 99999999999999999999999999BBBBBBD7D7D7787878787878868686A1A1A1C2 + C2C2DDDDDDF7F7F7C2C2C2999999999999999999999999999999B4B4B4CFCFCF + EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBCFCFCF9999999999999999999999 + 99999999999999DDDDDDC2C2C27676767B7B7B8E8E8EACACACCBCBCBE3E3E3F4 + F4F4FCFCFCC2C2C2999999999999999999A6A6A6EDEDED808080959595B6B6B6 + D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB4B4B49999 + 99999999999999B4B4B4DCDCDC828282989898BBBBBBD7D7D7ECECECFAFAFAFF + FFFFFFFFFFFEFEFEFCFCFCF5F5F5E8E8E8F8F8F8A0A0A0999999999999999999 + 999999999999A6A6A6ECECEC7272727878788686869D9D9DB9B9B9D4D4D4E9E9 + E9F6F6F6FDFDFDFFFFFFFFFFFFFEFEFED6D6D6999999999999999999C9C9C9F8 + F8F8FCFCFCF9F9F9F5F5F5F4F4F4F2F2F2EFEFEFECECECF2F2F2F5F5F5E4E4E4 + A0A0A0999999999999999999C2C2C2C6C6C67777778C8C8CACACACCBCBCBEEEE + EECFCFCF999999999999999999999999FFFFFF7D7D7D909090B3B3B3D1D1D1F1 + F1F1D6D6D6999999999999999999C9C9C9F8F8F8FCFCFCF9F9F9F5F5F5F4F4F4 + F2F2F2EFEFEFECECECF2F2F2F5F5F5E4E4E4A0A0A0999999999999999999C2C2 + C2C6C6C67777778C8C8CACACACCBCBCBE3E3E3F4F4F4FDFDFDFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAE2F96C37D86229D5 + 6229D56229D56C37D8F4F1FC9E9E9E7B7B7B7D7D7D8C8C8CA4A4A4C0C0C0DADA + DAECECECF7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFF9771E36229D56229D56229D56229D5B69BEBD9D9D98E8E8E + 8282828383838F8F8FA5A5A5BFBFBFD5D5D5E6E6E6EDEDEDEAEAEADDDDDDDDDD + DDEAE2F96C37D86229D56229D56229D56229D5CBB8F1E2E2E2D9D9D9EBEBEBF5 + F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFC3C3C39A9A + 9A9A9A9A9A9A9A9A9A9AF1F1F18F8F8F747474767676838383939393A1A1A1AC + ACACB1B1B1B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B2B2B2ADADAD + F9F9F9A1A1A19A9A9A9A9A9A9A9A9A9A9A9AF1F1F1AEAEAEC1C1C1DBDBDBEEEE + EEF9F9F9FDFDFDC3C3C39A9A9A9A9A9A9A9A9AA1A1A1F9F9F9DDDDDDC6C6C6C5 + C5C5D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFF9F9F9BBBBBB9A9A9A9A9A9A + 9A9A9A9A9A9AA1A1A1F9F9F9808080777777868686A3A3A3C2C2C2D4D4D4EFEF + EFC3C3C39A9A9A9A9A9A9A9A9A9A9A9AA7A7A7EAEAEAE3E3E3E2E2E2E9E9E9F7 + F7F7FDFDFDFEFEFEFFFFFFFFFFFFDEDEDE9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A + D6D6D6B8B8B8777777818181999999BBBBBBD7D7D7F6F6F6C3C3C39A9A9A9A9A + 9A9A9A9AA1A1A1F9F9F9DDDDDDC6C6C6C5C5C5D4D4D4EAEAEAF8F8F8FFFFFFFF + FFFFFFFFFFF9F9F9BBBBBB9A9A9A9A9A9A9A9A9A9A9A9AA1A1A1F9F9F9808080 + 777777868686A3A3A3C4C4C4DEDEDEF1F1F1FCFCFCC3C3C39A9A9A9A9A9A9A9A + 9AA7A7A7EDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFEFEFEB5B5B59A9A9A9A9A9A9A9A9AB5B5B5DCDCDC828282 + 989898BBBBBBD7D7D7ECECECFAFAFAFFFFFFFFFFFFFEFEFEF9F9F9EFEFEFEFEF + EFD0D0D09A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9AE4E4E4A7A7A77B + 7B7B808080919191ACACACC8C8C8E0E0E0F1F1F1FBFBFBFEFEFEFFFFFFFFFFFF + D6D6D69A9A9AB5B5B5F1F1F1FCFCFCF6F6F6F3F3F3EFEFEFECECECE7E7E7E2E2 + E2DDDDDDD8D8D8D3D3D3CDCDCDE3E3E3D0D0D09A9A9A9A9A9A9A9A9A9A9A9AF1 + F1F18E8E8E939393B3B3B3D0D0D0F0F0F0D0D0D09A9A9A9A9A9A9A9A9A9A9A9A + FFFFFF7D7D7D909090B3B3B3D1D1D1F1F1F1D6D6D69A9A9AB5B5B5F1F1F1FCFC + FCF6F6F6F3F3F3EFEFEFECECECE7E7E7E2E2E2DDDDDDD8D8D8D3D3D3CDCDCDE3 + E3E3D0D0D09A9A9A9A9A9A9A9A9A9A9A9AF1F1F18E8E8E939393B3B3B3D0D0D0 + E6E6E6F5F5F5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFB79CED642BD7642BD7642BD7642BD7A280E7D5D5D582 + 82827A7A7A818181959595B0B0B0CBCBCBE2E2E2F2F2F2FAFAFAFEFEFEFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F1FC7947DC642B + D7642BD7642BD7642BD7E0D5F7CACACA8A8A8A828282868686959595ABABABC3 + C3C3D5D5D5DEDEDEDADADAD1D1D1F0F0F08355DF642BD7642BD7642BD7642BD7 + AC8EEAE3E3E3D4D4D4E7E7E7F4F4F4FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFEBEBEB9B9B9B9B9B9B9B9B9B9B9B9BCACACAC6C6C6 + 7373736B6B6B6F6F6F7979798383838C8C8C9191919393939494949494949494 + 94949494949494939393929292B4B4B4DDDDDD9B9B9B9B9B9B9B9B9B9B9B9BBC + BCBCDADADAAFAFAFCDCDCDE4E4E4F4F4F4FCFCFCFDFDFDC3C3C39B9B9B9B9B9B + 9B9B9BA8A8A8EDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFBCBCBC9B9B9B9B9B9B9B9B9B9B9B9BD1D1D1BFBFBF76 + 76768282829C9C9CBCBCBCD8D8D8EBEBEB9B9B9B9B9B9B9B9B9B9B9B9BA1A1A1 + F1F1F1CBCBCBC0C0C0DBDBDBEFEFEFFBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFF + FFDDDDDD9B9B9B9B9B9B9B9B9B9B9B9BA8A8A8EEEEEE7777777D7D7D949494B6 + B6B6D4D4D4F5F5F5C3C3C39B9B9B9B9B9B9B9B9BA8A8A8EDEDED808080959595 + B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC9B9B + 9B9B9B9B9B9B9B9B9B9BD1D1D1BFBFBF7676768282829C9C9CBFBFBFDADADAEE + EEEEFBFBFBC3C3C39B9B9B9B9B9B9B9B9BA8A8A8EDEDED808080959595B6B6B6 + D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB6B6B69B9B + 9B9B9B9B9B9B9BB6B6B6DCDCDC828282989898BBBBBBD7D7D7ECECECFAFAFAFF + FFFFFFFFFFFCFCFCF5F5F5E9E9E9F8F8F8A1A1A19B9B9B9B9B9B9B9B9B9B9B9B + 9B9B9B9B9B9B9B9B9BB6B6B6E0E0E08181817E7E7E8888889E9E9EBBBBBBD6D6 + D6EAEAEAF7F7F7FDFDFDFFFFFFFFFFFFD7D7D7D1D1D1FEFEFEFCFCFCF6F6F6F1 + F1F1E9E9E9E2E2E2DADADAD1D1D1C9C9C9C2C2C2BCBCBCB5B5B5AEAEAEB8B8B8 + EBEBEB9B9B9B9B9B9B9B9B9B9B9B9BD1D1D1C0C0C0A0A0A0BEBEBED8D8D8F3F3 + F3D1D1D19B9B9B9B9B9B9B9B9B9B9B9BFFFFFF7D7D7D909090B3B3B3D1D1D1F1 + F1F1D7D7D7D1D1D1FEFEFEFCFCFCF6F6F6F1F1F1E9E9E9E2E2E2DADADAD1D1D1 + C9C9C9C2C2C2BCBCBCB5B5B5AEAEAEB8B8B8EBEBEB9B9B9B9B9B9B9B9B9B9B9B + 9BD1D1D1C0C0C0A0A0A0BEBEBED8D8D8EBEBEBF8F8F8FEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8557E1 + 662DD9662DD9662DD9662DD9D6C7F5B9B9B97D7D7D7C7C7C8989899F9F9FBBBB + BBD5D5D5E9E9E9F5F5F5FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFEAE3FA703BDB662DD9662DD9662DD97B49DEF4F1FD + B2B2B2888888828282898989999999AEAEAEBFBFBFC8C8C8C4C4C4E1E1E1AD8F + EB662DD9662DD9662DD9662DD98557E1F0F0F0D5D5D5E3E3E3F2F2F2F9F9F9FE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFB7B7 + B79D9D9D9D9D9D9D9D9DA4A4A4F7F7F776767668686863636368686870707078 + 78787F7F7F828282848484858585858585858585848484838383808080D3D3D3 + BEBEBE9D9D9D9D9D9D9D9D9D9D9D9DE5E5E5B6B6B6BCBCBCD7D7D7EBEBEBF8F8 + F8FEFEFEFDFDFDC4C4C49D9D9D9D9D9D9D9D9DAAAAAAEDEDED808080959595B6 + B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A4A4A4 + 9D9D9D9D9D9D9D9D9DA4A4A4F6F6F67575757F7F7F979797B8B8B8EAEAEAC4C4 + C49D9D9D9D9D9D9D9D9D9D9D9DD8D8D8C5C5C5A5A5A5C6C6C6E0E0E0F2F2F2FC + FCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C49D9D9D9D9D9D9D9D9D + 9D9D9DDEDEDEA4A4A47C7C7C909090B2B2B2D1D1D1F4F4F4C4C4C49D9D9D9D9D + 9D9D9D9DAAAAAAEDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFF9F9F9A4A4A49D9D9D9D9D9D9D9D9DA4A4A4F6F6F6 + 7575757F7F7F979797BABABAD7D7D7ECECECFBFBFBC4C4C49D9D9D9D9D9D9D9D + 9DAAAAAAEDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFEFEFEB7B7B79D9D9D9D9D9D9D9D9DB7B7B7DCDCDC828282 + 989898BBBBBBD7D7D7ECECECFAFAFAFFFFFFFEFEFEFAFAFAF0F0F0EDEDEDD1D1 + D19D9D9D9D9D9D9D9D9D9D9D9DB7B7B79D9D9D9D9D9D9D9D9D9D9D9DE5E5E5B0 + B0B07F7F7F828282929292ADADADCACACAE2E2E2F2F2F2FBFBFBFEFEFEFFFFFF + FFFFFFFEFEFEFBFBFBF6F6F6EEEEEEE4E4E4D7D7D7CBCBCBBFBFBFB4B4B4ABAB + ABA3A3A39D9D9D9797979292929B9B9BF2F2F29D9D9D9D9D9D9D9D9D9D9D9DD1 + D1D1C9C9C9B2B2B2CCCCCCE1E1E1F5F5F5D1D1D19D9D9D9D9D9D9D9D9D9D9D9D + FFFFFF7D7D7D909090B3B3B3D1D1D1E8E8E8FBFBFBFEFEFEFBFBFBF6F6F6EEEE + EEE4E4E4D7D7D7CBCBCBBFBFBFB4B4B4ABABABA3A3A39D9D9D9797979292929B + 9B9BF2F2F29D9D9D9D9D9D9D9D9D9D9D9DD1D1D1C9C9C9B2B2B2CCCCCCE1E1E1 + F1F1F1FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFE1D5F8682FDB682FDB682FDB682FDB8758E2EB + EBEB8D8D8D7C7C7C808080919191AAAAAAC6C6C6DEDEDEEFEFEFF9F9F9FEFEFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDB9 + F3682FDB682FDB682FDB682FDB9A74E7E3E3E39A9A9A8686868383838B8B8B99 + 9999A7A7A7AEAEAED6D6D6CDB9F3682FDB682FDB682FDB682FDB723CDDEBE4FA + DFDFDFE0E0E0EFEFEFF8F8F8FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFD8D8D89E9E9E9E9E9E9E9E9E9E9E9EDFDFDF + A8A8A86868685F5F5F5F5F5F6666667070707979797F7F7F8383838585858585 + 858585858383838080808C8C8CF2F2F29E9E9E9E9E9E9E9E9E9E9E9EABABABEF + EFEFA8A8A8C7C7C7E0E0E0F1F1F1FBFBFBFEFEFEFDFDFDC5C5C59E9E9E9E9E9E + 9E9E9EABABABEDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D19E9E9E9E9E9E9E9E9E9E9E9EDFDFDFA3 + A3A37D7D7D959595B5B5B5FBFBFBA4A4A49E9E9E9E9E9E9E9E9EABABABEDEDED + 898989A7A7A7C8C8C8E2E2E2F3F3F3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF2F2F29E9E9E9E9E9E9E9E9E9E9E9EC5C5C5C9C9C97B7B7B8F8F8FB0 + B0B0CFCFCFF3F3F3C5C5C59E9E9E9E9E9E9E9E9EABABABEDEDED808080959595 + B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1 + D19E9E9E9E9E9E9E9E9E9E9E9EDFDFDFA3A3A37D7D7D959595B8B8B8D5D5D5EB + EBEBFBFBFBC5C5C59E9E9E9E9E9E9E9E9EABABABEDEDED808080959595B6B6B6 + D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB8B8B89E9E + 9E9E9E9E9E9E9EB8B8B8DCDCDC828282989898BBBBBBD7D7D7ECECECFAFAFAFF + FFFFFDFDFDF6F6F6E9E9E9F9F9F9ABABAB9E9E9E9E9E9E9E9E9EA4A4A4F8F8F8 + ABABAB9E9E9E9E9E9E9E9E9EB8B8B8E3E3E38383837E7E7E898989A0A0A0BCBC + BCD7D7D7EBEBEBF8F8F8FEFEFEFFFFFFFEFEFEFCFCFCF6F6F6EDEDEDE0E0E0D1 + D1D1BFBFBFAFAFAFA1A1A19696968F8F8F8A8A8A878787858585838383C3C3C3 + D8D8D89E9E9E9E9E9E9E9E9E9E9E9ED1D1D1D5D5D5C6C6C6DBDBDBEBEBEBF8F8 + F8D1D1D19E9E9E9E9E9E9E9E9E9E9E9EFFFFFF7D7D7D909090B3B3B3D1D1D1E8 + E8E8F7F7F7FCFCFCF6F6F6EDEDEDE0E0E0D1D1D1BFBFBFAFAFAFA1A1A1969696 + 8F8F8F8A8A8A878787858585838383C3C3C3D8D8D89E9E9E9E9E9E9E9E9E9E9E + 9ED1D1D1D5D5D5C6C6C6DBDBDBEBEBEBF6F6F6FCFCFCFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + A684EC6B32DE6B32DE6B32DE6B32DEBAA0EFCBCBCB8080807C7C7C8686869B9B + 9BB6B6B6D1D1D1E6E6E6F4F4F4FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB092ED6B32DE6B32DE6B32DE6B32DE + BAA0EFDADADA9090908484848282828787878F8F8FBDBDBDEBE3FA753FE06B32 + DE6B32DE6B32DE6B32DECEBBF4E3E3E3DBDBDBECECECF7F7F7FCFCFCFEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4EFFFFFFFFFFFFFFFFFFFFFFFFF8F8 + F8A6A6A6A0A0A0A0A0A0A0A0A0B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3 + A0A0A0A0A0A0A0A0A0A0A0A0D3D3D3C6C6C6B5B5B5D2D2D2E8E8E8F6F6F6FDFD + FDFFFFFFFDFDFDC6C6C6A0A0A0A0A0A0A0A0A0ADADADEDEDED808080959595B6 + B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC + A0A0A0A0A0A0A0A0A0A0A0A0CCCCCCBFBFBF7D7D7D939393C3C3C3ECECECA0A0 + A0A0A0A0A0A0A0A0A0A0CCCCCCC0C0C0898989A7A7A7C8C8C8E2E2E2F3F3F3FD + FDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB3B3B3A0A0A0A0A0A0 + A0A0A0ADADADEDEDED7B7B7B8F8F8FB0B0B0CFCFCFF3F3F3C6C6C6A0A0A0A0A0 + A0A0A0A0ADADADEDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA0A0A0A0A0A0A0A0A0A0A0A0CCCCCC + BFBFBF7D7D7D939393B7B7B7D4D4D4EAEAEAFBFBFBC6C6C6A0A0A0A0A0A0A0A0 + A0ADADADEDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFDFDFDB9B9B9A0A0A0A0A0A0A0A0A0B9B9B9DCDCDC828282 + 989898BBBBBBD7D7D7ECECECF9F9F9FEFEFEFBFBFBF1F1F1EEEEEED9D9D9A0A0 + A0A0A0A0A0A0A0A0A0A0D3D3D3D1D1D1D9D9D9A0A0A0A0A0A0A0A0A0A0A0A0EC + ECECA1A1A17F7F7F828282949494AFAFAFCBCBCBE3E3E3F2F2F2FBFBFBFEFEFE + FEFEFEF8F8F8F0F0F0E2E2E2CFCFCFB9B9B9A5A5A59494948888888181817F7F + 7F7F7F7FAAAAAABCBCBCE6E6E6E6E6E6A6A6A6A0A0A0A0A0A0A0A0A0A0A0A0DF + DFDFDADADADADADAE9E9E9F3F3F3FBFBFBD3D3D3A0A0A0A0A0A0A0A0A0A0A0A0 + FFFFFF7D7D7D909090B3B3B3D1D1D1E8E8E8F6F6F6F8F8F8F0F0F0E2E2E2CFCF + CFB9B9B9A5A5A59494948888888181817F7F7F7F7F7FAAAAAABCBCBCE6E6E6E6 + E6E6A6A6A6A0A0A0A0A0A0A0A0A0A0A0A0DFDFDFDADADADADADAE9E9E9F3F3F3 + FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F2FD7843E36E35E16E35E16E35E178 + 43E3F5F2FDA1A1A17D7D7D7E7E7E8D8D8DA5A5A5C1C1C1DADADAECECECF8F8F8 + FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFF8B5DE76E35E16E35E16E35E16E35E1E2D7F9CBCBCB8C8C8C8080807A + 7A7A8A8A8AE4E4E48B5DE76E35E16E35E16E35E16E35E1BCA1F1E4E4E4D6D6D6 + E9E9E9F5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECEA2A2A2A2A2A2A2A2A2A2A2A2 + A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2 + A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2F9F9F9A7 + A7A7C2C2C2DCDCDCEFEFEFFAFAFAFEFEFEFFFFFFFDFDFDC7C7C7A2A2A2A2A2A2 + A2A2A2AEAEAEEDEDED808080959595B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFA8A8A8A2A2A2A2A2A2A2A2A2BBBBBBDA + DADA7D7D7D959595CECECEE0E0E0A2A2A2A2A2A2A2A2A2A2A2A2E0E0E0A5A5A5 + 878787A5A5A5C6C6C6E0E0E0F2F2F2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFDFDFDC7C7C7A2A2A2A2A2A2A2A2A2A2A2A2FFFFFF7C7C7C909090B3 + B3B3D1D1D1F4F4F4C7C7C7A2A2A2A2A2A2A2A2A2AEAEAEEDEDED808080959595 + B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFF + FFA8A8A8A2A2A2A2A2A2A2A2A2BBBBBBDADADA7D7D7D959595B8B8B8D5D5D5EB + EBEBFBFBFBC7C7C7A2A2A2A2A2A2A2A2A2AEAEAEEDEDED808080959595B6B6B6 + D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBBBBBBA2A2 + A2A2A2A2A2A2A2BBBBBBDCDCDC818181989898BBBBBBD7D7D7ECECECF9F9F9FD + FDFDF7F7F7EAEAEAF9F9F9AEAEAEA2A2A2A2A2A2A2A2A2A8A8A8F9F9F9B2B2B2 + FBFBFBA8A8A8A2A2A2A2A2A2A2A2A2C7C7C7D4D4D48383837F7F7F8A8A8AA1A1 + A1BFBFBFD9D9D9ECECECF8F8F8FDFDFDFCFCFCF5F5F5E8E8E8D4D4D4BCBCBCA3 + A3A38E8E8EB3B3B3B7B7B7D2D2D2FFFFFFFFFFFFE0E0E0D4D4D4B4B4B4A2A2A2 + A2A2A2A2A2A2A2A2A2A2A2A2A8A8A8F9F9F9E0E0E0E9E9E9F3F3F3F9F9F9FCFC + FCD4D4D4A2A2A2A2A2A2A2A2A2A2A2A2FFFFFF7D7D7D909090B3B3B3D1D1D1E8 + E8E8F5F5F5F5F5F5E8E8E8D4D4D4BCBCBCA3A3A38E8E8EB3B3B3B7B7B7D2D2D2 + FFFFFFFFFFFFE0E0E0D4D4D4B4B4B4A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A8A8 + A8F9F9F9E0E0E0E9E9E9F3F3F3F9F9F9FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFC7AFF47138E47138E47138E47138E4A987EFD6D6D68484847D7D7D8383 + 83969696B0B0B0CBCBCBE2E2E2F2F2F2FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECE4FB7A45E57138E47138E4 + 7138E48453E8F6F2FDB2B2B2828282737373C2C2C2B496F17138E47138E47138 + E47138E4A07BEDE7E7E7D2D2D2E4E4E4F2F2F2FAFAFAFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFF3F3F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3 + A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3 + A3A3A3A3A3A3A3A3A3C7C7C7D2D2D2AFAFAFCDCDCDE4E4E4F4F4F4FCFCFCFFFF + FFFFFFFFFDFDFDC7C7C7A3A3A3A3A3A3A3A3A3AFAFAFEDEDED7F7F7F949494B6 + B6B6D4D4D4EAEAEAF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFD + B5B5B5A3A3A3A3A3A3A3A3A3AFAFAFECECEC7E7E7E989898D5D5D5DADADAA3A3 + A3A3A3A3A3A3A3A3A3A3E6E6E69B9B9B848484A1A1A1C2C2C2DCDCDCEFEFEFFB + FBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBD4D4D4A3A3A3A3A3A3 + A3A3A3A3A3A3F3F3F38F8F8F949494B6B6B6D4D4D4F5F5F5C7C7C7A3A3A3A3A3 + A3A3A3A3AFAFAFEDEDED7F7F7F949494B6B6B6D4D4D4EAEAEAF8F8F8FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDB5B5B5A3A3A3A3A3A3A3A3A3AFAFAF + ECECEC7E7E7E989898BBBBBBD7D7D7ECECECFBFBFBC7C7C7A3A3A3A3A3A3A3A3 + A3AFAFAFEDEDED7F7F7F949494B6B6B6D4D4D4E9E9E9F8F8F8FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFDFDFDBBBBBBA3A3A3A3A3A3A3A3A3BBBBBBDBDBDB818181 + 989898BBBBBBD7D7D7ECECECF9F9F9FBFBFBF2F2F2EBEBEBE6E6E6A3A3A3A3A3 + A3A3A3A3A3A3A3D4D4D4CFCFCFB9B9B9EAEAEAD4D4D4A3A3A3A3A3A3A3A3A3A3 + A3A3F3F3F39F9F9F7E7E7E838383959595B0B0B0CDCDCDE4E4E4F3F3F3FBFBFB + FAFAFAF0F0F0DFDFDFC8C8C8C6C6C6E1E1E1FFFFFFDADADAD4D4D4C1C1C1A3A3 + A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3E0E0E0F3 + F3F3EEEEEEF5F5F5FAFAFAFDFDFDFDFDFDD4D4D4A3A3A3A3A3A3A3A3A3A3A3A3 + FFFFFF7D7D7D909090B3B3B3D1D1D1E8E8E8F2F2F2F0F0F0DFDFDFC8C8C8C6C6 + C6E1E1E1FFFFFFDADADAD4D4D4C1C1C1A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3 + A3A3A3A3A3A3A3A3A3A3A3A3A3A3E0E0E0F3F3F3EEEEEEF5F5F5FAFAFAFDFDFD + FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF986FED733AE6733AE673 + 3AE6733AE6E4D7FABABABA8080807D7D7D898989A0A0A0BCBCBCD5D5D5E9E9E9 + F5F5F5FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFE4D7FA733AE6733AE6733AE6733AE6A27BEEE0E0E08D8D8DBB + BBBBD0BEF7733AE6733AE6733AE6733AE68654EAF6F2FDD4D4D4DDDDDDEEEEEE + F8F8F8FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDA5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5E7E7E7B6B6B6BC + BCBCD7D7D7ECECECF8F8F8FEFEFEFFFFFFFFFFFFFDFDFDC9C9C9A5A5A5A5A5A5 + A5A5A5B1B1B1EDEDED7D7D7D919191B2B2B2D0D0D0E7E7E7F6F6F6FEFEFEFEFE + FEFFFFFFFFFFFFFEFEFEFCFCFCFCFCFCBDBDBDA5A5A5A5A5A5A5A5A5ABABABF6 + F6F68181819C9C9CDCDCDCD5D5D5A5A5A5A5A5A5A5A5A5A5A5A5F3F3F3898989 + 808080999999B9B9B9D5D5D5EAEAEAF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFEFE + FEFCFCFCF9F9F9D5D5D5A5A5A5A5A5A5A5A5A5A5A5A5F3F3F39292929A9A9ABC + BCBCD8D8D8F6F6F6C9C9C9A5A5A5A5A5A5A5A5A5B1B1B1EDEDED7D7D7D919191 + B2B2B2D0D0D0E7E7E7F6F6F6FEFEFEFEFEFEFFFFFFFFFFFFFEFEFEFCFCFCFCFC + FCBDBDBDA5A5A5A5A5A5A5A5A5ABABABF6F6F68181819C9C9CBFBFBFDADADAEE + EEEEFBFBFBC9C9C9A5A5A5A5A5A5A5A5A5B1B1B1EDEDED7D7D7D909090B2B2B2 + CFCFCFE6E6E6F6F6F6FEFEFEFEFEFEFFFFFFFFFFFFFEFEFEFDFDFDBDBDBDA5A5 + A5A5A5A5A5A5A5BDBDBDDBDBDB818181999999BCBCBCD8D8D8ECECECF8F8F8F8 + F8F8EBEBEBF4F4F4BDBDBDA5A5A5A5A5A5A5A5A5A5A5A5F3F3F3B4B4B4C7C7C7 + E1E1E1F9F9F9ABABABA5A5A5A5A5A5A5A5A5C9C9C9D3D3D38181817E7E7E8B8B + 8BA3A3A3C0C0C0DADADAEDEDEDF8F8F8F7F7F7ECECECE5E5E5EDEDEDE1E1E1BD + BDBDA5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5E1E1E1F8F8F8F2F2F2F7F7F7FAFAFAFCFCFCFEFEFEFDFD + FDD5D5D5A5A5A5A5A5A5A5A5A5A5A5A5FFFFFF7D7D7D909090B3B3B3D1D1D1E7 + E7E7F1F1F1ECECECE5E5E5EDEDEDE1E1E1BDBDBDA5A5A5A5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5E1E1E1F8F8 + F8F2F2F2F7F7F7FAFAFAFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFEDE5FC763DE9763DE9763DE9763DE99264EDECECEC8888887D7D + 7D808080929292ABABABC6C6C6DEDEDEEFEFEFF9F9F9FEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFA4F5763DE9 + 763DE9763DE9763DE9BFA4F5CFCFCFEDE5FC7F49EA763DE9763DE9763DE9763D + E9E4D8FAD4D4D4CECECEE4E4E4F4F4F4FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFDCDCDCA7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7 + A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7 + A7A7A7A7A7A7B3B3B3F0F0F0A9A9A9C8C8C8E0E0E0F2F2F2FBFBFBFEFEFEFFFF + FFFFFFFFFDFDFDCACACAA7A7A7A7A7A7A7A7A7B3B3B3EDEDED7979798B8B8BAA + AAAAC8C8C8DFDFDFEFEFEFF9F9F9FBFBFBFDFDFDFEFEFEFCFCFCF8F8F8FAFAFA + BEBEBEA7A7A7A7A7A7A7A7A7A7A7A7FFFFFF868686A3A3A3DFDFDFD6D6D6A7A7 + A7A7A7A7A7A7A7A7A7A7F3F3F38989897C7C7C8F8F8FADADADC9C9C9E0E0E0F0 + F0F0F9F9F9FCFCFCFEFEFEFEFEFEFBFBFBF7F7F7F5F5F5D6D6D6A7A7A7A7A7A7 + A7A7A7A7A7A7F3F3F3979797A2A2A2C2C2C2DDDDDDF7F7F7CACACAA7A7A7A7A7 + A7A7A7A7B3B3B3EDEDED7979798B8B8BAAAAAAC8C8C8DFDFDFEFEFEFF9F9F9FB + FBFBFDFDFDFEFEFEFCFCFCF8F8F8FAFAFABEBEBEA7A7A7A7A7A7A7A7A7A7A7A7 + FFFFFF868686A3A3A3C4C4C4DEDEDEF1F1F1FCFCFCCACACAA7A7A7A7A7A7A7A7 + A7B3B3B3EDEDED787878898989A9A9A9C6C6C6DDDDDDEFEFEFF8F8F8FBFBFBFD + FDFDFEFEFEFCFCFCFCFCFCBEBEBEA7A7A7A7A7A7A7A7A7BEBEBEDADADA818181 + 9B9B9BBEBEBEDADADAEDEDEDF6F6F6F2F2F2EAEAEAE8E8E8A7A7A7A7A7A7A7A7 + A7A7A7A7CACACAD6D6D6B6B6B6D3D3D3E8E8E8FAFAFAD6D6D6A7A7A7A7A7A7A7 + A7A7A7A7A7F3F3F39898987D7D7D838383969696B2B2B2CECECEE5E5E5F3F3F3 + F4F4F4F3F3F3F3F3F3BEBEBEA7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7 + A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7D0D0D0F3F3F3FAFAFAF5F5F5F6 + F6F6F7F7F7F8F8F8FBFBFBFCFCFCFCFCFCD6D6D6A7A7A7A7A7A7A7A7A7A7A7A7 + FFFFFF7D7D7D909090B3B3B3D1D1D1E7E7E7EFEFEFF3F3F3F3F3F3BEBEBEA7A7 + A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7 + A7A7A7A7A7D0D0D0F3F3F3FAFAFAF5F5F5F6F6F6F7F7F7F8F8F8FBFBFBFCFCFC + FEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0A6F67940EC79 + 40EC7940EC7940ECC9B3F7CCCCCC8282827D7D7D8686869B9B9BB6B6B6D1D1D1 + E6E6E6F4F4F4FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFA680F27940EC7940EC7940EC7940ECE5D9FB94 + 67F07940EC7940EC7940EC7940ECC0A6F6D3D3D3B3B3B3CFCFCFE6E6E6F5F5F5 + FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEA8A8A8A8A8A8 + A8A8A8BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFD6D6D6A8A8A8A8A8A8A8A8A8A8A8A8D6D6D6C8C8C8B6B6B6D3 + D3D3E9E9E9F6F6F6FDFDFDFFFFFFFFFFFFFFFFFFFDFDFDCACACAA8A8A8A8A8A8 + A8A8A8B4B4B4ECECEC7373738181819D9D9DB9B9B9D0D0D0E1E1E1ECECECF1F1 + F1F4F4F4F5F5F5F2F2F2ECECECF6F6F6BFBFBFA8A8A8A8A8A8A8A8A8B4B4B4ED + EDED8D8D8DACACACE0E0E0DCDCDCA8A8A8A8A8A8A8A8A8A8A8A8E7E7E79D9D9D + 7878788585859E9E9EB8B8B8D0D0D0E2E2E2EDEDEDF2F2F2F5F5F5F4F4F4F1F1 + F1EAEAEAEDEDEDD6D6D6A8A8A8A8A8A8A8A8A8A8A8A8F3F3F39E9E9EADADADCB + CBCBE3E3E3F9F9F9CACACAA8A8A8A8A8A8A8A8A8B4B4B4ECECEC737373818181 + 9D9D9DB9B9B9D0D0D0E1E1E1ECECECF1F1F1F4F4F4F5F5F5F2F2F2ECECECF6F6 + F6BFBFBFA8A8A8A8A8A8A8A8A8B4B4B4EDEDED8D8D8DACACACCBCBCBE3E3E3F4 + F4F4FCFCFCCACACAA8A8A8A8A8A8A8A8A8B4B4B4ECECEC7272728080809B9B9B + B7B7B7CECECEE0E0E0EBEBEBF0F0F0F3F3F3F5F5F5F2F2F2F9F9F9BFBFBFA8A8 + A8A8A8A8A8A8A8BFBFBFDADADA8383839F9F9FC1C1C1DCDCDCEEEEEEF4F4F4EC + ECECF2F2F2C5C5C5A8A8A8A8A8A8A8A8A8A8A8A8F3F3F3B8B8B8C4C4C4DDDDDD + EFEFEFFAFAFAF9F9F9A8A8A8A8A8A8A8A8A8A8A8A8D6D6D6CACACA8080807E7E + 7E8C8C8CA4A4A4C1C1C1DBDBDBECECECF3F3F3F9F9F9B4B4B4A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8D0D0D0D6D6D6E2E2E2 + FFFFFFFCFCFCF6F6F6F2F2F2F0F0F0EFEFEFEFEFEFF2F2F2F5F5F5F9F9F9FBFB + FBD6D6D6A8A8A8A8A8A8A8A8A8A8A8A8FFFFFF7D7D7D909090B3B3B3D1D1D1E7 + E7E7F2F2F2F9F9F9B4B4B4A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8D0D0D0D6D6D6E2E2E2FFFFFFFCFCFCF6F6F6F2F2F2F0F0 + F0EFEFEFEFEFEFF2F2F2F5F5F5F9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFF6F2FE8D5CF17C43EF7C43EF7C43EF8450F0F6F2FEA2A2 + A27F7F7F8080808E8E8EA6A6A6C2C2C2DADADAECECECF8F8F8FDFDFDFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDF6F2FE + 8D5CF17C43EF7C43EF7C43EF7C43EF7C43EF7C43EF7C43EF7C43EFA881F4D1D1 + D1959595ADADADC8C8C8E0E0E0F0F0F0F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFD8D8D8AAAAAAAAAAAAAAAAAAAAAAAAF3F3F39393937C7C7C85 + 85859B9B9BB9B9B9D5D5D5E9E9E9F2F2F2ECECECFAFAFAB5B5B5AAAAAAAAAAAA + AAAAAAAFAFAFF9F9F9AAAAAAC2C2C2DDDDDDEFEFEFFAFAFAFEFEFEFFFFFFFFFF + FFFFFFFFFDFDFDCCCCCCAAAAAAAAAAAAAAAAAAB5B5B5ECECEC6B6B6B7676768D + 8D8DA6A6A6BBBBBBCCCCCCD8D8D8DFDFDFE3E3E3E3E3E3E1E1E1D9D9D9F8F8F8 + B5B5B5AAAAAAAAAAAAAAAAAAB5B5B5EEEEEE989898B6B6B6E2E2E2E3E3E3AAAA + AAAAAAAAAAAAAAAAAAAAE3E3E3ABABAB7878787D7D7D8D8D8DA4A4A4BABABACD + CDCDDADADAE1E1E1E3E3E3E3E3E3DFDFDFD6D6D6E9E9E9CCCCCCAAAAAAAAAAAA + AAAAAAAAAAAAFFFFFF9C9C9CB9B9B9D5D5D5E9E9E9FAFAFACCCCCCAAAAAAAAAA + AAAAAAAAB5B5B5ECECEC6B6B6B7676768D8D8DA6A6A6BBBBBBCCCCCCD8D8D8DF + DFDFE3E3E3E3E3E3E1E1E1D9D9D9F8F8F8B5B5B5AAAAAAAAAAAAAAAAAAB5B5B5 + EEEEEE989898B6B6B6D4D4D4E9E9E9F7F7F7FDFDFDCCCCCCAAAAAAAAAAAAAAAA + AAB5B5B5ECECEC6B6B6B7474748B8B8BA4A4A4B9B9B9CACACAD7D7D7DDDDDDE2 + E2E2E3E3E3E1E1E1F4F4F4C0C0C0AAAAAAAAAAAAAAAAAAC0C0C0DADADA888888 + A6A6A6C6C6C6DFDFDFEEEEEEF0F0F0E9E9E9F3F3F3AAAAAAAAAAAAAAAAAAAAAA + AAC0C0C0E3E3E3B4B4B4D1D1D1E6E6E6F5F5F5FCFCFCFFFFFFCCCCCCAAAAAAAA + AAAAAAAAAAAFAFAFF9F9F98E8E8E7D7D7D838383979797B3B3B3CFCFCFE5E5E5 + F7F7F7CCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7C7C7D8D8D8EEEE + EEFFFFFFFFFFFFFAFAFAF9F9F9F8F8F8F2F2F2EFEFEFE9E9E9E4E4E4E0E0E0DE + DEDEE0E0E0E6E6E6EDEDEDF5F5F5FAFAFAD8D8D8AAAAAAAAAAAAAAAAAAAAAAAA + FFFFFF7D7D7D909090B3B3B3D1D1D1E7E7E7F9F9F9CCCCCCAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAC7C7C7D8D8D8EEEEEEFFFFFFFFFFFFFAFAFAF9F9F9F8 + F8F8F2F2F2EFEFEFE9E9E9E4E4E4E0E0E0DEDEDEE0E0E0E6E6E6EDEDEDF5F5F5 + FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4C1FB7F + 46F27F46F27F46F27F46F2B28FF7D7D7D78686867D7D7D848484979797B1B1B1 + CCCCCCE3E3E3F2F2F2FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFEFEFEFDFDFDF8F8F8F6F6F6E5DAFC8852F37F46F27F46F27F46F27F + 46F27F46F27F46F2905FF4F6F3FE999999898989A1A1A1BBBBBBD4D4D4E7E7E7 + F4F4F4FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4ABABABABABAB + ABABABABABABD8D8D8C7C7C77D7D7D808080919191ADADADCBCBCBE0E0E0E9E9 + E9EDEDEDE3E3E3ABABABABABABABABABABABABCCCCCCD3D3D3B0B0B0CECECEE5 + E5E5F4F4F4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCCCCCCABABABABABAB + ABABABB7B7B7EBEBEB6565656B6B6B7D7D7D929292A4A4A4B3B3B3BFBFBFC5C5 + C5CACACACBCBCBC8C8C8C3C3C3F9F9F9ABABABABABABABABABABABABC7C7C7D8 + D8D8A5A5A5C3C3C3E4E4E4EFEFEFABABABABABABABABABABABABD2D2D2CACACA + 7D7D7D7979798080808F8F8FA1A1A1B2B2B2BFBFBFC8C8C8CBCBCBCBCBCBC5C5 + C5BBBBBBEFEFEFBCBCBCABABABABABABABABABBCBCBCE9E9E9ACACACC8C8C8E0 + E0E0F0F0F0FBFBFBCCCCCCABABABABABABABABABB7B7B7EBEBEB6565656B6B6B + 7D7D7D929292A4A4A4B3B3B3BFBFBFC5C5C5CACACACBCBCBC8C8C8C3C3C3F9F9 + F9ABABABABABABABABABABABABC7C7C7D8D8D8A5A5A5C3C3C3DDDDDDEFEFEFF9 + F9F9FDFDFDCCCCCCABABABABABABABABABB7B7B7EBEBEB6565656A6A6A7C7C7C + 8F8F8FA1A1A1B0B0B0BCBCBCC5C5C5CACACACBCBCBC8C8C8F2F2F2BCBCBCABAB + ABABABABABABABC1C1C1DCDCDC909090AFAFAFCECECEE3E3E3EEEEEEEBEBEBF0 + F0F0CCCCCCABABABABABABABABABABABABE9E9E9C1C1C1C2C2C2DCDCDCEEEEEE + F9F9F9FEFEFEFFFFFFF4F4F4ABABABABABABABABABABABABD8D8D8C9C9C97F7F + 7F7E7E7E8C8C8CA5A5A5C2C2C2DDDDDDF9F9F9B0B0B0ABABABABABABABABABAB + ABABCCCCCCF9F9F9D8D8D8CDCDCDC8C8C8CECECEDCDCDCE3E3E3E5E5E5E4E4E4 + E0E0E0DBDBDBD4D4D4CDCDCDC8C8C8C8C8C8CCCCCCD7D7D7E3E3E3EFEFEFF9F9 + F9D8D8D8ABABABABABABABABABABABABFFFFFF7D7D7D909090B3B3B3D1D1D1EA + EAEAF9F9F9B0B0B0ABABABABABABABABABABABABCCCCCCF9F9F9D8D8D8CDCDCD + C8C8C8CECECEDCDCDCE3E3E3E5E5E5E4E4E4E0E0E0DBDBDBD4D4D4CDCDCDC8C8 + C8C8C8C8CCCCCCD7D7D7E3E3E3EFEFEFF8F8F8FDFDFDFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC86F88249F58249F58249F58249F5E6DB + FDBCBCBC8181817F7F7F8A8A8AA1A1A1BCBCBCD6D6D6E9E9E9F6F6F6FCFCFCFE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF2F2F2E5E5E5 + E9E9E9D5C2FC8249F58249F58249F58249F58249F58249F5E6DBFDB5B5B57A7A + 7A838383939393AAAAAAC3C3C3DADADAEBEBEBF6F6F6FBFBFBFEFEFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFC2C2C2ADADADADADADADADADB3B3B3F8F8F88080807D + 7D7D898989A1A1A1BFBFBFD6D6D6DFDFDFF2F2F2C8C8C8ADADADADADADADADAD + ADADADEAEAEAB8B8B8BDBDBDD8D8D8ECECECF8F8F8FEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFFDFDFDCECECEADADADADADADADADADB8B8B8ECECEC6868686A6A6A77 + 77778585859191919C9C9CA4A4A4A9A9A9ADADADADADADA9A9A9C0C0C0E4E4E4 + ADADADADADADADADADADADADD3D3D3D0D0D0B6B6B6D1D1D1E6E6E6FEFEFEB3B3 + B3ADADADADADADADADADBDBDBDECECEC8989897D7D7D7A7A7A8080808B8B8B97 + 9797A1A1A1A9A9A9ACACACABABABA7A7A7B0B0B0F4F4F4ADADADADADADADADAD + ADADADCECECEDBDBDBBEBEBED7D7D7E9E9E9F5F5F5FCFCFCCECECEADADADADAD + ADADADADB8B8B8ECECEC6868686A6A6A7777778585859191919C9C9CA4A4A4A9 + A9A9ADADADADADADA9A9A9C0C0C0E4E4E4ADADADADADADADADADADADADD3D3D3 + D0D0D0B6B6B6D1D1D1E6E6E6F4F4F4FBFBFBFDFDFDCECECEADADADADADADADAD + ADB8B8B8EBEBEB6262626565657373738181818F8F8F9A9A9AA3A3A3A8A8A8AC + ACACADADADAAAAAAF2F2F2B8B8B8ADADADADADADADADADC2C2C2DEDEDE9E9E9E + BCBCBCD7D7D7E8E8E8EEEEEEE9E9E9F4F4F4ADADADADADADADADADADADADC2C2 + C2E3E3E3B3B3B3CFCFCFE6E6E6F4F4F4FCFCFCFEFEFEFFFFFFFFFFFFCECECEAD + ADADADADADADADADB3B3B3F9F9F99090908181818989899E9E9EB9B9B9DDDDDD + EEEEEEADADADADADADADADADADADADC2C2C2DEDEDE989898868686979797AAAA + AAB9B9B9C5C5C5CBCBCBCECECECCCCCCC8C8C8C2C2C2BBBBBBB3B3B3B0B0B0B3 + B3B3BBBBBBCBCBCBDCDCDCEBEBEBF8F8F8D9D9D9ADADADADADADADADADADADAD + FFFFFF838383959595B6B6B6D3D3D3EDEDEDEEEEEEADADADADADADADADADADAD + ADC2C2C2DEDEDE989898868686979797AAAAAAB9B9B9C5C5C5CBCBCBCECECECC + CCCCC8C8C8C2C2C2BBBBBBB3B3B3B0B0B0B3B3B3BBBBBBCBCBCBDCDCDCEBEBEB + F5F5F5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF + E7FE8E59F9864DF9864DF9864DF99E71FAECECEC8A8A8A7F7F7F828282929292 + ACACACC7C7C7DEDEDEEFEFEFF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFEFBFBFBF5F5F5E9E9E9D6D6D6E0E0E0D7C4FD864DF9864DF9864DF986 + 4DF9864DF99665FAF7F3FFA7A7A7828282808080888888989898B0B0B0C8C8C8 + DEDEDEEEEEEEF8F8F8FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5AFAFAF + AFAFAFAFAFAFAFAFAFE5E5E5AEAEAE7C7C7C828282969696B2B2B2C9C9C9D8D8 + D8F4F4F4AFAFAFAFAFAFAFAFAFAFAFAFBFBFBFE8E8E8AAAAAAC9C9C9E1E1E1F2 + F2F2FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCFCFCFAFAFAFAFAFAF + AFAFAFB9B9B9EEEEEE7373737373737B7B7B8484848A8A8A8F8F8F9292929292 + 929292929191918E8E8ECFCFCFCFCFCFAFAFAFAFAFAFAFAFAFAFAFAFE5E5E5C8 + C8C8C7C7C7DDDDDDEEEEEEFCFCFCD5D5D5AFAFAFAFAFAFAFAFAFAFAFAFE9E9E9 + C9C9C98B8B8B8080807D7D7D7F7F7F8383838989898D8D8D8F8F8F8F8F8F8C8C + 8CCFCFCFCFCFCFAFAFAFAFAFAFAFAFAFAFAFAFE5E5E5D0D0D0D0D0D0E3E3E3F2 + F2F2FAFAFAFDFDFDCFCFCFAFAFAFAFAFAFAFAFAFB9B9B9EEEEEE737373737373 + 7B7B7B8484848A8A8A8F8F8F9292929292929292929191918E8E8ECFCFCFCFCF + CFAFAFAFAFAFAFAFAFAFAFAFAFE5E5E5C8C8C8C7C7C7DDDDDDEEEEEEF8F8F8FE + FEFEFDFDFDCFCFCFAFAFAFAFAFAFAFAFAFB9B9B9EBEBEB777777666666737373 + 7E7E7E8787878D8D8D919191929292929292929292969696FAFAFAAFAFAFAFAF + AFAFAFAFAFAFAFC9C9C9DCDCDCAEAEAECACACAE0E0E0EDEDEDEFEFEFF2F2F2DA + DADAAFAFAFAFAFAFAFAFAFAFAFAFDFDFDFCACACAC3C3C3DBDBDBEDEDEDF8F8F8 + FEFEFEFFFFFFFFFFFFFFFFFFE9E9E9AFAFAFAFAFAFAFAFAFAFAFAFDADADAC6C6 + C68B8B8B8E8E8E9E9E9EB6B6B6DDDDDDE9E9E9AFAFAFAFAFAFAFAFAFAFAFAFDA + DADAC6C6C68989898888888F8F8F9B9B9BA6A6A6AFAFAFB4B4B4B6B6B6B4B4B4 + B0B0B0AAAAAAA4A4A49E9E9E9E9E9EA4A4A4B1B1B1C4C4C4D9D9D9E9E9E9F8F8 + F8DADADAAFAFAFAFAFAFAFAFAFAFAFAFFFFFFF8D8D8D9E9E9EBCBCBCD7D7D7F0 + F0F0E9E9E9AFAFAFAFAFAFAFAFAFAFAFAFDADADAC6C6C68989898888888F8F8F + 9B9B9BA6A6A6AFAFAFB4B4B4B6B6B6B4B4B4B0B0B0AAAAAAA4A4A49E9E9E9E9E + 9EA4A4A4B1B1B1C4C4C4D9D9D9E9E9E9F5F5F5FDFDFDFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8ADFE8950FC8950FC8950FC8950 + FCD0B9FECDCDCD8484847F7F7F8888889C9C9CB7B7B7D1D1D1E6E6E6F4F4F4FB + FBFBFEFEFEFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF7F7F7ECECECDBDBDBDCDCDC + EFE8FF905CFC8950FC8950FC8950FC8950FC8950FC8950FCB08AFDDFDFDF9696 + 968585858282828A8A8A9D9D9DB6B6B6CECECEE2E2E2F0F0F0F9F9F9FDFDFDFE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB0B0B0B0B0B0B0B0B0C5C5C5E1E1E17E + 7E7E7E7E7E8C8C8CA4A4A4B9B9B9DFDFDFDADADAB0B0B0B0B0B0B0B0B0B0B0B0 + E0E0E0C1C1C1B7B7B7D4D4D4E9E9E9F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFDFDFDD0D0D0B0B0B0B0B0B0B0B0B0B0B0B0E0E0E0E7E7E7B6B6B68C + 8C8C9191919292929191918E8E8E8B8B8B888888858585BBBBBBEFEFEFB0B0B0 + B0B0B0B0B0B0B0B0B0B5B5B5FAFAFAC6C6C6D8D8D8E9E9E9F5F5F5FCFCFCF5F5 + F5B0B0B0B0B0B0B0B0B0B0B0B0BBBBBBFAFAFAC5C5C590909086868681818180 + 8080808080828282838383838383CBCBCBEAEAEAB0B0B0B0B0B0B0B0B0B0B0B0 + BBBBBBF6F6F6CECECEE0E0E0EFEFEFF8F8F8FCFCFCFDFDFDD0D0D0B0B0B0B0B0 + B0B0B0B0B0B0B0E0E0E0E7E7E7B6B6B68C8C8C9191919292929191918E8E8E8B + 8B8B888888858585BBBBBBEFEFEFB0B0B0B0B0B0B0B0B0B0B0B0B5B5B5FAFAFA + C6C6C6D8D8D8E9E9E9F5F5F5FBFBFBFEFEFEFDFDFDD0D0D0B0B0B0B0B0B0B0B0 + B0B0B0B0D5D5D5F5F5F5BABABA7C7C7C8787878D8D8D8F8F8F8F8F8F8B8B8B88 + 8888868686BBBBBBE0E0E0B0B0B0B0B0B0B0B0B0B0B0B0D5D5D5D7D7D7C2C2C2 + D8D8D8E9E9E9F2F2F2F0F0F0FAFAFAB5B5B5B0B0B0B0B0B0B0B0B0BBBBBBF3F3 + F3BABABAD2D2D2E6E6E6F4F4F4FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFC5 + C5C5B0B0B0B0B0B0B0B0B0BBBBBBF3F3F39B9B9B9B9B9BA5A5A5B9B9B9DADADA + EFEFEFB0B0B0B0B0B0B0B0B0B0B0B0DADADAD1D1D19A9A9A9292929191919494 + 949898989D9D9DA0A0A0A1A1A19F9F9F9D9D9D9A9A9A9C9C9CC6C6C6C8C8C8A7 + A7A7B1B1B1C5C5C5DADADAEAEAEAF9F9F9DADADAB0B0B0B0B0B0B0B0B0B0B0B0 + FFFFFF9D9D9DABABABC5C5C5DCDCDCF1F1F1EFEFEFB0B0B0B0B0B0B0B0B0B0B0 + B0DADADAD1D1D19A9A9A9292929191919494949898989D9D9DA0A0A0A1A1A19F + 9F9F9D9D9D9A9A9A9C9C9CC6C6C6C8C8C8A7A7A7B1B1B1C5C5C5DADADAEAEAEA + F6F6F6FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF9B6AFF8C53FF8C53FF8C53FF935FFFF8F4FF9C9C9C808080818181 + 8F8F8FA7A7A7C2C2C2DADADAECECECF8F8F8FDFDFDFFFFFFFFFFFFFEFEFEFDFD + FDF8F8F8EFEFEFE0E0E0D8D8D8EFEFEFA375FF8C53FF8C53FF8C53FF8C53FF8C + 53FF8C53FF8C53FF8C53FFC9AEFFD9D9D98F8F8F8383838282828D8D8DA2A2A2 + BBBBBBD3D3D3E6E6E6F3F3F3FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB + B2B2B2B2B2B2B2B2B2B2B2B2F4F4F49494947D7D7D848484969696A9A9A9F5F5 + F5BCBCBCB2B2B2B2B2B2B2B2B2B7B7B7FAFAFAABABABC3C3C3DDDDDDEFEFEFFA + FAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED1D1D1B2B2B2B2B2B2 + B2B2B2B2B2B2B2B2B2C2C2C2EBEBEBF3F3F3D1D1D1B7B7B7A0A0A09999999292 + 92A3A3A3CECECEF4F4F4BCBCBCB2B2B2B2B2B2B2B2B2B2B2B2D6D6D6E3E3E3D6 + D6D6E6E6E6F2F2F2FAFAFAFEFEFEFFFFFFD1D1D1B2B2B2B2B2B2B2B2B2B2B2B2 + C2C2C2F4F4F4DCDCDCBCBCBC9191918B8B8B8787878C8C8CBEBEBEDEDEDEE5E5 + E5B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2E0E0E0E5E5E5E0E0E0EDEDEDF6F6F6FB + FBFBFEFEFEFEFEFED1D1D1B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2C2C2C2EBEBEB + F3F3F3D1D1D1B7B7B7A0A0A0999999929292A3A3A3CECECEF4F4F4BCBCBCB2B2 + B2B2B2B2B2B2B2B2B2B2D6D6D6E3E3E3D6D6D6E6E6E6F2F2F2FAFAFAFEFEFEFF + FFFFFDFDFDD1D1D1B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B7B7B7E0E0E0FFFFFF + D5D5D5B8B8B89E9E9E9B9B9B939393959595C7C7C7F4F4F4BCBCBCB2B2B2B2B2 + B2B2B2B2B2B2B2E5E5E5D6D6D6D4D4D4E6E6E6F2F2F2F5F5F5F9F9F9DBDBDBB2 + B2B2B2B2B2B2B2B2B2B2B2E0E0E0D9D9D9CDCDCDE0E0E0EFEFEFF8F8F8FEFEFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBB2B2B2B2B2B2B2B2B2B2B2B2E0E0 + E0D4D4D4AEAEAEB5B5B5C3C3C3D7D7D7FDFDFDB7B7B7B2B2B2B2B2B2B2B2B2CB + CBCBEAEAEAB5B5B5A5A5A59E9E9E9B9B9B9A9A9A9A9A9A9B9B9B9B9B9B9A9A9A + 9F9F9FCECECEF8F8F8DBDBDBDBDBDBD3D3D3BCBCBCCECECEE0E0E0EFEFEFFAFA + FADBDBDBB2B2B2B2B2B2B2B2B2B2B2B2FFFFFFB1B1B1BCBCBCD1D1D1E3E3E3F2 + F2F2FFFFFFB7B7B7B2B2B2B2B2B2B2B2B2CBCBCBEAEAEAB5B5B5A5A5A59E9E9E + 9B9B9B9A9A9A9A9A9A9B9B9B9B9B9B9A9A9A9F9F9FCECECEF8F8F8DBDBDBDBDB + DBD3D3D3BCBCBCCECECEE0E0E0EFEFEFF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1D2FF9059FF9059FF9059 + FF9059FFC3A6FFD6D6D6888888808080858585989898B2B2B2CDCDCDE3E3E3F2 + F2F2FBFBFBFEFEFEFFFFFFFEFEFEFAFAFAF2F2F2E4E4E4D4D4D4E7E7E7B591FF + 9059FF9059FF9059FF9059FFC3A6FFB591FF9059FF9059FF9059FF9059FFE8DE + FFD1D1D18C8C8C818181838383929292A7A7A7C0C0C0D7D7D7E9E9E9F5F5F5FB + FBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5B3B3B3B3B3B3B3B3B3B3B3B3DBDBDBC7 + C7C77D7D7D7D7D7D888888B9B9B9E6E6E6B3B3B3B3B3B3B3B3B3B3B3B3D2D2D2 + D4D4D4B1B1B1CFCFCFE6E6E6F5F5F5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFD2D2D2B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3BD + BDBDDBDBDBEFEFEFFFFFFFFFFFFFFFFFFFEFEFEFDBDBDBB3B3B3B3B3B3B3B3B3 + B3B3B3B3B3B3B8B8B8FAFAFADEDEDEE7E7E7F2F2F2F8F8F8FDFDFDFEFEFEFFFF + FFFAFAFABDBDBDB3B3B3B3B3B3B3B3B3B3B3B3B3B3B3D7D7D7E6E6E6FFFFFFFF + FFFFFFFFFFFFFFFFDBDBDBC7C7C7B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3CCCCCC + F2F2F2E3E3E3EFEFEFF6F6F6FBFBFBFEFEFEFFFFFFFFFFFFD2D2D2B3B3B3B3B3 + B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3BDBDBDDBDBDBEFEFEFFFFFFFFFFFFFFF + FFFFEFEFEFDBDBDBB3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B8B8B8FAFAFADEDEDE + E7E7E7F2F2F2F8F8F8FDFDFDFEFEFEFFFFFFFDFDFDD2D2D2B3B3B3B3B3B3B3B3 + B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3DBDBDBEBEBEBFFFFFFFFFFFFFFFFFFFA + FAFADBDBDBB8B8B8B3B3B3B3B3B3B3B3B3B3B3B3BDBDBDF8F8F8D7D7D7E6E6E6 + F1F1F1F8F8F8F9F9F9FEFEFEB8B8B8B3B3B3B3B3B3B3B3B3B8B8B8FBFBFBD3D3 + D3E0E0E0ECECECF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFC7C7C7B3B3B3B3B3B3B3B3B3BDBDBDF8F8F8C8C8C8CCCCCCD5D5D5E3E3E3 + F7F7F7DBDBDBB3B3B3B3B3B3B3B3B3B3B3B3DBDBDBF1F1F1DDDDDDB9B9B9AEAE + AEA9A9A9A7A7A7B0B0B0CECECEE1E1E1FFFFFFDBDBDBB8B8B8B3B3B3DBDBDBDE + DEDECECECEDDDDDDEAEAEAF4F4F4FBFBFBDBDBDBB3B3B3B3B3B3B3B3B3B3B3B3 + FFFFFFC5C5C5CECECEDDDDDDEBEBEBF5F5F5FDFDFDDBDBDBB3B3B3B3B3B3B3B3 + B3B3B3B3DBDBDBF1F1F1DDDDDDB9B9B9AEAEAEA9A9A9A7A7A7B0B0B0CECECEE1 + E1E1FFFFFFDBDBDBB8B8B8B3B3B3DBDBDBDEDEDECECECEDDDDDDEAEAEAF4F4F4 + FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFDFD + FDFBFBFBFAFAFAF9F9F9F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8FCFCFCBE9DFF935DFF935DFF935DFF935DFFEADFFFB2B2B27E7E7E + 7D7D7D8A8A8AA1A1A1BEBEBED8D8D8EBEBEBF7F7F7FDFDFDFEFEFEFBFBFBF5F5 + F5E9E9E9D6D6D6E4E4E4CCB3FF935DFF935DFF935DFF935DFFA97EFFEFEFEFF8 + F4FFA172FF935DFF935DFF935DFF9A68FFF1EAFFC1C1C1878787808080858585 + 959595ADADADC5C5C5DCDCDCECECECF7F7F7FCFCFCFEFEFEFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + CECECEB5B5B5B5B5B5B5B5B5BABABAF8F8F88080807A7A7A7C7C7CD6D6D6CECE + CEB5B5B5B5B5B5B5B5B5B5B5B5F0F0F0B2B2B2BEBEBED9D9D9ECECECF8F8F8FE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3B5B5B5B5B5B5 + B5B5B5BABABAB5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5E6E6E6F0F0F0EAEAEAF2 + F2F2F8F8F8FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFF0F0F0BABABAB5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5C3C3C3FAFAFAEFEFEFF2F2F2F8F8F8FBFBFBFEFEFEFF + FFFFFFFFFFFFFFFFD3D3D3B5B5B5B5B5B5B5B5B5BABABAB5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5E6E6E6F0F0F0EAEAEAF2F2F2F8F8F8FCFCFCFEFEFEFFFFFFFF + FFFFFDFDFDD3D3D3B5B5B5B5B5B5B5B5B5BABABABABABAB5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5E1E1E1EDEDEDE9E9E9F2F2F2F8F8F8FBFBFBFDFDFDE1E1E1B5B5B5B5 + B5B5B5B5B5B5B5B5DCDCDCF0F0F0E6E6E6EEEEEEF5F5F5FAFAFAFEFEFEFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1B5B5B5B5B5B5B5B5B5B5B5 + B5E1E1E1EBEBEBE0E0E0E5E5E5EDEDEDF5F5F5FEFEFEC3C3C3B5B5B5B5B5B5B5 + B5B5B5B5B5C8C8C8DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5DCDCDCCECECE + B5B5B5B5B5B5B5B5B5B5B5B5DCDCDCEAEAEAE1E1E1EAEAEAF2F2F2F8F8F8FDFD + FDDCDCDCB5B5B5B5B5B5B5B5B5B5B5B5FFFFFFCFCFCFD6D6D6E3E3E3EEEEEEF6 + F6F6FCFCFCFFFFFFC3C3C3B5B5B5B5B5B5B5B5B5B5B5B5C8C8C8DCDCDCFFFFFF + FFFFFFFFFFFFFFFFFFF5F5F5DCDCDCCECECEB5B5B5B5B5B5B5B5B5B5B5B5DCDC + DCEAEAEAE1E1E1EAEAEAF2F2F2F8F8F8FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFEFEFEFBFBFBF8F8F8F4F4F4F0F0F0ECECECEAEAEAE9E9E9 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8ECECECF8F4FF9C6AFF9560 + FF9560FF9560FFB28AFFE1E1E17D7D7D7676767E7E7E929292AFAFAFCCCCCCE3 + E3E3F3F3F3FBFBFBFCFCFCF7F7F7ECECECDBDBDBDFDFDFEAE0FF9560FF9560FF + 9560FF9560FF9C6AFFF1EAFFDCDCDCEBEBEBEAE0FF9560FF9560FF9560FF9560 + FFAB80FFEEEEEEA1A1A18484848080808787879A9A9AB2B2B2CBCBCBE0E0E0EF + EFEFF8F8F8FDFDFDFEFEFEFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECB6B6B6B6B6B6B6B6B6B6B6B6E7 + E7E7AEAEAE7878787B7B7BFAFAFAB6B6B6B6B6B6B6B6B6B6B6B6C9C9C9E1E1E1 + ACACACCACACAE2E2E2F2F2F2FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFD3D3D3B6B6B6B6B6B6B6B6B6BFBFBFF1F1F1C5C5C5B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6DDDDDDF6F6F6F0F0F0F5F5F5FAFAFAFDFDFDFEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF1F1F1BFBFBFB6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6CECECEFBFBFBF6F6F6 + F5F5F5FAFAFAFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3B6B6B6B6B6 + B6B6B6B6BFBFBFF1F1F1C5C5C5B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6DDDDDDF6F6F6F0F0F0F5F5F5 + FAFAFAFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFDFDFDD3D3D3B6B6B6B6B6B6B6B6 + B6BFBFBFF5F5F5C9C9C9B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6D3D3D3F6F6F6EFEFEFF5F5F5F9F9F9 + FCFCFCFEFEFEFFFFFFBFBFBFB6B6B6B6B6B6B6B6B6BBBBBBFAFAFAF0F0F0F3F3 + F3F7F7F7FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFBFBFBFB6B6B6B6B6B6B6B6B6C5C5C5FCFCFCEFEFEFF2F2F2F5F5F5 + F9F9F9FDFDFDFAFAFAC9C9C9B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6DDDDDDF4 + F4F4F0F0F0F5F5F5F9F9F9FCFCFCFDFDFDDDDDDDB6B6B6B6B6B6B6B6B6B6B6B6 + FFFFFFCECECED4D4D4E1E1E1ECECECF5F5F5FBFBFBFEFEFEFAFAFAC9C9C9B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6DDDDDDF4F4F4F0F0F0F5F5F5F9F9F9FCFCFC + FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF8F8F8F1F1 + F1E9E9E9E0E0E0DADADAD5D5D5D2D2D2D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1E9E9E9D6C2FF9865FF9865FF9865FF9865FFD6C2FFBEBEBE + 6F6F6F747474868686A2A2A2C2C2C2DCDCDCEFEFEFF8F8F8F8F8F8EFEFEFE0E0 + E0D8D8D8F8F5FFA679FF9865FF9865FF9865FF9865FFCFB7FFE0E0E0D6D6D6E9 + E9E9FBFBFBCFB7FF9865FF9865FF9865FF9865FFC8ACFFDADADA8F8F8F818181 + 8080808A8A8A9E9E9EB8B8B8D0D0D0E4E4E4F2F2F2FAFAFAFEFEFEFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFC2C2C2B8B8B8B8B8B8B8B8B8CBCBCBE1E1E1797979B0B0B0DEDEDEB8B8 + B8B8B8B8B8B8B8B8B8B8E3E3E3C2C2C2B9B9B9D4D4D4E9E9E9F7F7F7FEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4B8B8B8B8B8B8 + B8B8B8C2C2C2FEFEFEFEFEFEE3E3E3C2C2C2B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8BDBDBDE7E7E7FAFAFAF6F6F6FAFAFAFCFCFCFE + FEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8C2C2C2E3E3E3FBFBFBF9F9F9FAFAFAFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFD4D4D4B8B8B8B8B8B8B8B8B8C2C2C2FEFEFEFEFEFEE3E3E3 + C2C2C2B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8BDBD + BDE7E7E7FAFAFAF6F6F6FAFAFAFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFDFDFDD4D4D4B8B8B8B8B8B8B8B8B8C2C2C2EDEDEDDDDDDDE7E7E7C7C7C7 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8DEDE + DEFAFAFAF7F7F7F9F9F9FBFBFBFEFEFEFEFEFEFFFFFFE3E3E3B8B8B8B8B8B8B8 + B8B8B8B8B8D9D9D9FCFCFCFAFAFAFBFBFBFDFDFDFEFEFEFEFEFEFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3B8B8B8B8B8B8B8B8 + B8B8B8B8ECECECFBFBFBFBFBFBFBFBFBFDFDFDFEFEFEFEFEFEFFFFFFE3E3E3BD + BDBDB8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8D9D9D9F1F1F1F9F9F9FAFAFAFCFCFCFEFEFEFEFEFEFDFD + FDDEDEDEB8B8B8B8B8B8B8B8B8B8B8B8FFFFFFC1C1C1CACACADADADAE8E8E8F2 + F2F2FAFAFAFEFEFEFFFFFFFFFFFFE3E3E3BDBDBDB8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8D9D9D9F1F1 + F1F9F9F9FAFAFAFCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFEFEFAFAFAF2F2F2E8E8E8DADADACCCCCCC2C2C2B9B9B9B4B4B4 + B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3F0F0F0AF87 + FF9B69FF9B69FF9B69FFA273FFF8F5FF7A7A7A6C6C6C7D7D7D989898B9B9B9D6 + D6D6E9E9E9F3F3F3F2F2F2E4E4E4D3D3D3E7E7E7BC9BFF9B69FF9B69FF9B69FF + 9B69FFBC9BFFE7E7E7D3D3D3E4E4E4F2F2F2FAFAFAFFFFFFBC9BFF9B69FF9B69 + FF9B69FF9B69FFDECDFFD1D1D18A8A8A7F7F7F8080808E8E8EA4A4A4BDBDBDD5 + D5D5E7E7E7F4F4F4FBFBFBFEFEFEFFFFFFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEB9B9B9B9B9B9B9B9B9B9 + B9B9F6F6F6929292ECECECC3C3C3B9B9B9B9B9B9B9B9B9BDBDBDFAFAFAADADAD + C5C5C5DEDEDEF0F0F0FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFECECECDEDEDEC3C3C3B9B9B9B9B9B9B9B9B9B9B9B9D5D5D5E3E3E3FFFFFF + FDFDFDFCFCFCFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEDEDEDEB9B9B9B9B9B9B9 + B9B9B9B9B9B9B9B9C3C3C3DEDEDEE7E7E7FEFEFEFDFDFDFCFCFCFEFEFEFEFEFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECDEDEDEC3C3C3B9B9B9B9 + B9B9B9B9B9B9B9B9D5D5D5E3E3E3FFFFFFFDFDFDFCFCFCFDFDFDFEFEFEFEFEFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD5D5D5B9B9B9B9B9B9B9B9 + B9C3C3C3EDEDED808080BEBEBEF0F0F0F1F1F1DEDEDEC7C7C7B9B9B9B9B9B9B9 + B9B9B9B9B9CBCBCBDEDEDEFAFAFAFDFDFDFBFBFBFDFDFDFEFEFEFEFEFEFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECDEDEDECBCBCBB9B9B9B9B9 + B9B9B9B9B9B9B9B9B9B9BDBDBDDEDEDEDEDEDEF1F1F1FFFFFFFEFEFEFDFDFDFE + FEFEFEFEFEFFFFFFFFFFFFFFFFFFFBFBFBFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF + DDDDDDB0B0B0BBBBBBCECECEE1E1E1EFEFEFF8F8F8FEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFECECECDEDEDECBCBCBB9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BDBDBDDE + DEDEDEDEDEF1F1F1FFFFFFFEFEFEFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8EDEDEDDFDF + DFCBCBCBB8B8B8A9A9A99E9E9E97979794949494949494949494949494949494 + 9494949494949494949494BEBEBEEBE2FF9E6EFF9E6EFF9E6EFF9E6EFFCBB1FF + C0C0C06B6B6B7A7A7A959595B6B6B6D3D3D3E6E6E6EFEFEFECECECDBDBDBE7E7 + E7D2BBFF9E6EFF9E6EFF9E6EFF9E6EFFAB81FFF8F5FFD8D8D8E0E0E0EFEFEFF8 + F8F8FDFDFDFEFEFEF8F5FFAB81FF9E6EFF9E6EFF9E6EFFA477FFEBE2FFC8C8C8 + 888888808080868686989898B0B0B0C8C8C8DEDEDEEFEFEFF8F8F8FDFDFDFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFAFAFABABABABABABABABABABABABADFDFDFC9C9C9EDEDEDBABABABABA + BABABABABABABADBDBDBD0D0D0B7B7B7D2D2D2E7E7E7F5F5F5FDFDFDFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFDFDFDD5D5D5BABABABABABABABABAC3C3C3EDEDED808080959595B6B6B6 + DDDDDDF4F4F4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB + FBF2F2F2E3E3E3D1D1D1B9B9B9A8A8A8A1A1A1A4A4A4B1B1B1C8C8C8DDDDDDEC + ECECF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFDFDFDF6F6F6EBEBEBDADADAC5C5C5AEAEAE9C9C9C8F8F8F888888 + 858585858585858585858585858585858585858585858585858585858585CDCD + CDCCB4FFA071FFA071FFA071FFA071FFECE3FF9F9F9F8282829A9A9AB9B9B9D4 + D4D4E6E6E6ECECECE6E6E6E8E8E8ECE3FFA071FFA071FFA071FFA071FFA071FF + ECE3FFDFDFDFDADADAECECECF6F6F6FCFCFCFEFEFEFFFFFFFFFFFFECE3FFA071 + FFA071FFA071FFA071FFAD84FFF9F5FFB2B2B28A8A8A898989949494A8A8A8C0 + C0C0D7D7D7E9E9E9F5F5F5FCFCFCFEFEFE00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7BCBCBCBCBCBCBC + BCBCC1C1C1F9F9F9D2D2D2BCBCBCBCBCBCBCBCBCBCBCBCF6F6F6B9B9B9C7C7C7 + DDDDDDEEEEEEF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD7D7D7BCBCBCBCBCBCBCBC + BCC5C5C5EEEEEE858585999999B9B9B9D6D6D6EBEBEBF9F9F9FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF2F2F2E3E3E3D1D1D1B9B9B9A8A8A8 + A1A1A1A4A4A4B1B1B1C8C8C8DDDDDDECECECF8F8F8FEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF6F6F6EBEBEBDADA + DAC5C5C5AEAEAE9C9C9C8F8F8F88888885858585858585858585858585858585 + 8585858585858585858585858585949494F9F6FFAF86FFA274FFA274FFA274FF + BB99FFDEDEDE919191A6A6A6C2C2C2D9D9D9E7E7E7EBEBEBEBEBEBF9F6FFAF86 + FFA274FFA274FFA274FFA274FFD4BEFFE5E5E5D6D6D6E8E8E8F4F4F4FBFBFBFE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFD4BEFFA274FFA274FFA274FFA274FFC1A2FF + E4E4E4A1A1A19696969B9B9BAAAAAABFBFBFD4D4D4E7E7E7F4F4F4FBFBFBFEFE + FE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFEDEDEDBDBDBDBDBDBDBDBDBDBDBDBDE4E4E4BDBDBDBDBDBDBDBD + BDBDBDBDCFCFCFEAEAEAC3C3C3D7D7D7E8E8E8F4F4F4FBFBFBFEFEFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFDFDFDD7D7D7BDBDBDBDBDBDBDBDBDC6C6C6EFEFEF8F8F8FA1A1A1BFBFBF + DADADAECECECF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFD + FDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDB0B0B0BBBBBBCECECEE1E1E1EF + EFEFF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFEFEFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFE1D2FFA477FFA477FFA477FFA477FFF3EDFFB3B3B3B8B8B8CECECEE0 + E0E0EAEAEAEDEDEDF6F6F6C2A4FFA477FFA477FFA477FFA477FFC2A4FFEBEBEB + D6D6D6E5E5E5F2F2F2FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFC2A4FFA477FFA477FFA477FFA477FFD5C0FFE0E0E0ABABABACACACB5B5B5C5 + C5C5D7D7D7E8E8E8F3F3F3FBFBFBFEFEFE00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6BEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEE5E5E5E0E0E0D9D9D9E6E6E6 + F1F1F1F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD8D8D8BEBEBEBEBEBEBEBE + BEC6C6C6F2F2F29E9E9EAEAEAEC8C8C8DFDFDFEFEFEFFAFAFAFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6BEBEBEBEBEBEBEBEBEBEBEBE + EEEEEED5D5D5CECECEDDDDDDE9E9E9F3F3F3FBFBFBFEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDBCAFFA67AFFA67A + FFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA6 + 7AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFF + A67AFFF3EDFFCCCCCCD0D0D0DEDEDEEAEAEAF1F1F1F9F9F9D5C1FFA67AFFA67A + FFA67AFFA67AFFB28CFFF9F6FFE3E3E3E6E6E6F0F0F0F8F8F8FDFDFDFEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F6FFB28CFFA67AFFA67AFFA67AFF + A67AFFEDE4FFE4E4E4C6C6C6CBCBCBD5D5D5E2E2E2EDEDEDF6F6F6FBFBFBFEFE + FE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFE1E1E1BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF + BFC3C3C3FDFDFDE1E1E1E9E9E9F2F2F2F8F8F8FCFCFCFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFEFEFED8D8D8BFBFBFBFBFBFBFBFBFC8C8C8F4F4F4B3B3B3BFBFBFD4D4D4 + E6E6E6F2F2F2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFC8C8C8BFBFBFBFBFBFBFBFBFBFBFBFEEEEEEE6E6E6E2E2E2EAEAEAF2F2F2F8 + F8F8FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFEFEDCCBFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFF + A87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87D + FFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFF4EEFFE1E1E1E3E3E3ECECECF2 + F2F2FAFAFAEDE5FFA87DFFA87DFFA87DFFA87DFFA87DFFE2D4FFEFEFEFEAEAEA + F2F2F2F8F8F8FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFEDE5FFA87DFFA87DFFA87DFFA87DFFAE86FFF4EEFFEAEAEADEDEDEE3 + E3E3ECECECF3F3F3F9F9F9FDFDFDFEFEFE00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC4C4C4C0 + C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0E2E2E2F6F6F6F0F0F0F5F5F5F8F8F8 + FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9C0C0C0C0C0C0C0C0 + C0C8C8C8F8F8F8CCCCCCD4D4D4E2E2E2EEEEEEF7F7F7FCFCFCFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8C0C0C0C0C0C0C0C0C0C0C0C0 + EEEEEEF3F3F3F0F0F0F5F5F5F8F8F8FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDCCFFAA80FFAA80 + FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA + 80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FF + AA80FFF4EEFFEFEFEFF1F1F1F5F5F5FAFAFAF9F7FFB590FFAA80FFAA80FFAA80 + FFAA80FFD2BBFFF8F8F8F2F2F2F5F5F5F9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7C4FFAA80FFAA80FF + AA80FFAA80FFBB99FFFBFBFBF1F1F1F0F0F0F5F5F5F8F8F8FBFBFBFEFEFEFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFDADADAC1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1 + C1F7F7F7FAFAFAFBFBFBFCFCFCFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFDADADAC1C1C1C1C1C1C1C1C1C9C9C9FBFBFBE0E0E0E6E6E6EEEEEE + F5F5F5FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFC9C9C9C1C1C1C1C1C1C1C1C1C1C1C1EEEEEEFBFBFBFAFAFAFBFBFBFDFDFDFE + FEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFDDCDFFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FF + AB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81 + FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFF4EEFFFAFAFAFBFBFBFCFCFCFE + FEFEC1A2FFAB81FFAB81FFAB81FFAB81FFBC9AFFFEFEFEFBFBFBFBFBFBFCFCFC + FEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFC7ABFFAB81FFAB81FFAB81FFAB81FFCDB3FFFDFDFDFA + FAFAFBFBFBFDFDFDFEFEFEFEFEFEFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAC2C2C2C2C2C2C2C2 + C2CACACAFDFDFDF0F0F0F2F2F2F6F6F6FAFAFAFDFDFDFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFDADADAC2C2C2C2C2C2C2C2C2CACACAFEFEFEFAFAFAFBFBFBFCFCFC + FEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00} + end + object Label3: TLabel + Left = 16 + Top = 180 + Width = 166 + Height = 13 + Caption = 'This application was created using:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + end + object Label4: TLabel + Left = 16 + Top = 64 + Width = 215 + Height = 13 + Cursor = crHandPoint + Hint = 'http://sourceforge.net/projects/apophysis7x/' + Caption = 'http://sourceforge.net/projects/apophysis7x/' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Label10: TLabel + Left = 16 + Top = 230 + Width = 178 + Height = 13 + Caption = 'flame - cosmic recursive fractal flames' + end + object Label11: TLabel + Left = 16 + Top = 254 + Width = 178 + Height = 13 + Caption = 'Copyright '#169' 1992-2013 Scott Draves' + end + object lblFlamecom: TLabel + Left = 16 + Top = 270 + Width = 79 + Height = 13 + Cursor = crHandPoint + Hint = 'http://flam3.com' + Caption = 'http://flam3.com' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Bevel1: TBevel + Left = 16 + Top = 242 + Width = 385 + Height = 9 + Shape = bsBottomLine + end + object Label7: TLabel + Left = 175 + Top = 148 + Width = 71 + Height = 13 + Cursor = crHandPoint + Hint = 'http://zueuk.deviantart.com' + Caption = 'Peter Sdobnov' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Label8: TLabel + Left = 252 + Top = 148 + Width = 53 + Height = 13 + Cursor = crHandPoint + Hint = 'http://utak3r.pl' + Caption = 'Piotr Borys ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Label9: TLabel + Left = 99 + Top = 148 + Width = 70 + Height = 13 + Caption = 'Ronald Hordijk' + end + object Label12: TLabel + Left = 16 + Top = 116 + Width = 56 + Height = 13 + Caption = 'Contributors' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + end + object Label13: TLabel + Left = 16 + Top = 204 + Width = 69 + Height = 13 + Cursor = crHandPoint + Hint = 'http://www.tmssoftware.com/' + Caption = 'Scripter Studio' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Label14: TLabel + Left = 96 + Top = 204 + Width = 55 + Height = 13 + Cursor = crHandPoint + Hint = 'http://www.destructor.de/' + Caption = 'XML Parser' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Bevel3: TBevel + Left = 16 + Top = 126 + Width = 385 + Height = 11 + Shape = bsBottomLine + end + object Label17: TLabel + Left = 311 + Top = 148 + Width = 65 + Height = 13 + Cursor = crHandPoint + Hint = 'http://xyrus-worx.org' + Caption = 'Georg Kiehne' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Label16: TLabel + Left = 8 + Top = 408 + Width = 5 + Height = 13 + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + end + object Label2: TLabel + Left = 16 + Top = 148 + Width = 77 + Height = 13 + Caption = 'Mark Townsend' + end + object Bevel2: TBevel + Left = 16 + Top = 190 + Width = 385 + Height = 11 + Shape = bsBottomLine + end + object Label19: TLabel + Left = 160 + Top = 204 + Width = 77 + Height = 13 + Cursor = crHandPoint + Hint = 'http://www.regular-expressions.info' + Caption = 'PCRE for Delphi' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsUnderline] + ParentFont = False + OnClick = DevelopersClick + end + object Label5: TLabel + Left = 16 + Top = 88 + Width = 385 + Height = 13 + AutoSize = False + Visible = False + end + object btnOK: TButton + Left = 320 + Top = 310 + Width = 91 + Height = 25 + Caption = 'OK' + TabOrder = 0 + OnClick = btnOKClick + end +end diff --git a/Forms/About.pas b/Forms/About.pas new file mode 100644 index 0000000..618f1fb --- /dev/null +++ b/Forms/About.pas @@ -0,0 +1,113 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit About; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls, Global, Translation; + +type + TAboutForm = class(TForm) + btnOK: TButton; + Label3: TLabel; + Label4: TLabel; + Label10: TLabel; + Label11: TLabel; + lblFlamecom: TLabel; + Bevel1: TBevel; + Label7: TLabel; + Label8: TLabel; + Label9: TLabel; + Label12: TLabel; + Label13: TLabel; + Label14: TLabel; + Bevel3: TBevel; + Label17: TLabel; + Label16: TLabel; + Label2: TLabel; + Bevel2: TBevel; + Label19: TLabel; + Label5: TLabel; + Image1: TImage; + procedure btnOKClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure lblCreditClick(Sender: TObject); + procedure DevelopersClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + { Private declarations } + URL :String; + public + { Public declarations } + end; + +var + AboutForm: TAboutForm; + +implementation + +uses Main, ShellAPI; + +{$R *.DFM} + +procedure TAboutForm.btnOKClick(Sender: TObject); +begin + ModalResult := mrOK; +end; + +procedure TAboutForm.FormShow(Sender: TObject); +begin + //lblCredit.Caption := MainCp.Nick; + //URL := MainCp.URL; + //if URL <> '' then lblCredit.Font.color := clBlue else lblCredit.Font.color := clBlack; +end; + +procedure TAboutForm.lblCreditClick(Sender: TObject); +begin + if URL <> '' then + ShellExecute(ValidParentForm(Self).Handle, 'open', PChar(URL), + nil, nil, SW_SHOWNORMAL); +end; + +procedure TAboutForm.DevelopersClick(Sender: TObject); +begin + ShellExecute(ValidParentForm(Self).Handle, 'open', PChar(TLabel(Sender).Hint), + nil, nil, SW_SHOWNORMAL); +end; + +procedure TAboutForm.FormCreate(Sender: TObject); +var s1, s2, s3:string; +begin + btnOK.Caption := TextByKey('common-close'); + if (LanguageFile <> AvailableLanguages.Strings[0]) and (LanguageFile <> '') then + begin + LanguageInfo(LanguageFile, s1, s2); + s3 := LanguageAuthor(LanguageFile); + Label5.Visible := (s1 <> '') and (s3 <> ''); + Label5.Caption := s1 + ' translation contributed by: ' + s3; + end; +end; + +end. diff --git a/Forms/Adjust.dfm b/Forms/Adjust.dfm new file mode 100644 index 0000000..219107c --- /dev/null +++ b/Forms/Adjust.dfm @@ -0,0 +1,1765 @@ +object AdjustForm: TAdjustForm + Left = 164 + Top = 279 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSingle + Caption = 'Adjustment' + ClientHeight = 292 + ClientWidth = 467 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + Icon.Data = { + 0000010001001010000001002000680400001600000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000B7A2 + 93FF604632FF634935FF634935FF634935FF634935FF634935FF634935FF6349 + 35FF634935FF634935FF684E3AFF00000000000000000000000000000000BDA8 + 99FFFCFEFCFFE7E6E4FFE7E2DCFFE6DCD4FFE5D6CBFFE4CFC1FFE3CAB8FFE3C5 + B1FFE2C2ACFFC7AA98FF684E3AFF00000000000000000000000000000000C6B0 + A1FFFCFEFCFFD8C4B9FFD6C0B5FFD3BCAFFFFAEFE6FFCFB3A5FFCCAF9FFFCCAF + 9FFFF6DBC8FFC7AA98FF684E3AFF00000000000000000000000000000000CCB6 + A7FFFCFEFCFFFCFEFCFFFCFEFCFFFBFAF7FFFBF5EFFF75716EFF575451FF0000 + 00FFD2C2B5FFCBB2A1FF684E3AFF00000000000000000000000000000000CCB6 + A7FFFCFEFCFFDBCAC0FFDAC8BDFFD8C4B9FFFBFAF7FFA39D98FFFDFEFEFF5193 + A9FF0E1216FFB8B1A8FF78604DFF00000000000000000000000000000000CCB6 + A7FFFCFEFCFFFCFEFCFFFCFEFCFFFCFEFCFFFCFEFCFFA39D98FF88B7C7FF74CE + E2FF499AB2FF0E1216FF7C7266FFE5D6CB01000000000000000000000000CCB6 + A7FFFCFEFCFFDBCAC0FFDBCAC0FFDBCAC0FFFCFEFCFFC1B9B4FF4D9CB3FF8CE0 + EEFF62BFD7FF499AB2FF0E1216FF2D62753B000000000000000000000000CCB6 + A7FFFCFEFCFFFCFEFCFFFCFEFCFFFCFEFCFFFCFEFCFFFBF8F3FFD5CEC8FF57A0 + B5FF8CE0EEFF62BFD7FF499AB2FF0E1216FF2D62753B0000000000000000EBAC + 8DFFEAAA8CFFEAA989FFE9A27EFFE89971FFE68F63FFE58758FFE69265FFCDA9 + 95FF65A6B7FF8CE0EEFF62BFD7FF499AB2FF0E1216FF2855663000000000EBAC + 8DFFFFC3A2FFFEBF9DFFFCBB98FFFBB692FFFAB08BFFF8AB84FFF8A67CFFF3A6 + 80FFD2B09EFF73ACB9FF8CE0EEFF6CC4D9FF7D8686FF353590FF2F39834EEBAC + 8DFFEAAA8BFFEAAA8BFFEAA889FFE9A281FFE89C77FFE7946BFFE68C60FFE586 + 55FFE68D5FFFCA997FFF7DB0BBFFCAB8ACFF7385D1FF5E6CADFF353590FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000EBAC8D037F9FAD465E6CADFF708FDFFF5E76D0FF5E6CADFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000687EC2495E6CADFF5E6CADFF6579BC300000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000FFFF0000000F0000000F0000000F0000000F0000000F0000000700000007 + 000000030000000100000000000000000000FFC00000FFF00000FFFF0000} + OldCreateOrder = False + Position = poDefault + OnActivate = FormActivate + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + DesignSize = ( + 467 + 292) + PixelsPerInch = 96 + TextHeight = 13 + object btnUndo: TSpeedButton + Left = 415 + Top = 10 + Width = 23 + Height = 21 + Hint = 'Undo' + Anchors = [akTop, akRight] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFBD7C5F8D5C3FF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFF8DCCFF38A57E19571FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFEECBBAF08550DA86 + 5EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFCA805CF08855EAC8B7FF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFE1CDC3DB78 + 47EF9367FF00FFFF00FFFF00FFFF00FFFF00FF8A4625954C28A4542EB65F34C7 + 693AD67240FF00FFFF00FFFF00FFAE5C36EC8652F2CFBDFF00FFFF00FFFF00FF + FF00FF954C28DF7336EA8249F39A6AF5B594FF00FFFF00FFFF00FFFF00FFA366 + 48E98452F7C2A7FF00FFFF00FFFF00FFFF00FFA3552EEC824BF38D5BEC9C76B6 + 866FE9D5CBFF00FFFF00FFFF00FFA97459E18254F7BE9EFF00FFFF00FFFF00FF + FF00FFB55F34F39A6AF49C71F294659D5330AA613BDAB8A7FF00FFF6C5AE9D64 + 46DE8051F7BDA1FF00FFFF00FFFF00FFFF00FFC7693BF7CAAEFBDDCBF4A376F3 + 9464B46239B0643EBF8162BB8460A15E39EE8B5AF6C8B0FF00FFFF00FFFF00FF + FF00FFD67240FF00FFFF00FFFBDECFF5A57EF49D72C97347B7663CB6653DE281 + 53F6BCA1F6CBB7FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFB + DACAF5A67EF6B696F5B28FF6B091F6C1A8F6C5AEFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFBE0D2F6C3A9F7CFBBF9DB + CDFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + Transparent = False + OnClick = btnUndoClick + end + object btnRedo: TSpeedButton + Left = 438 + Top = 10 + Width = 23 + Height = 21 + Hint = 'Redo' + Anchors = [akTop, akRight] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFF8D5C3FBD7C5FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFE19571F38A57F8DCCFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFDA865EF08550EECBBAFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFEAC8B7F08855CA805CFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + EF9367DB7847E1CDC3FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFF2CFBDEC8652AE5C36FF00FFFF00FFFF00FFD6 + 7240C7693AB65F34A4542E954C288A4625FF00FFFF00FFFF00FFFF00FFF7C2A7 + E98452A36648FF00FFFF00FFFF00FFFF00FFF5B594F39A6AEA8249DF7336954C + 28FF00FFFF00FFFF00FFFF00FFF7BE9EE18254A97459FF00FFFF00FFFF00FFE9 + D5CBB6866FEC9C76F38D5BEC824BA3552EFF00FFFF00FFFF00FFFF00FFF7BDA1 + DE80519D6446F6C5AEFF00FFDAB8A7AA613B9D5330F29465F49C71F39A6AB55F + 34FF00FFFF00FFFF00FFFF00FFF6C8B0EE8B5AA15E39BB8460BF8162B0643EB4 + 6239F39464F4A376FBDDCBF7CAAEC7693BFF00FFFF00FFFF00FFFF00FFF6CBB7 + F6BCA1E28153B6653DB7663CC97347F49D72F5A57EFBDECFFF00FFFF00FFD672 + 40FF00FFFF00FFFF00FFFF00FFFF00FFF6C5AEF6C1A8F6B091F5B28FF6B696F5 + A67EFBDACAFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFF9DBCDF7CFBBF6C3A9FBE0D2FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + Transparent = False + OnClick = btnRedoClick + end + object PrevPnl: TPanel + Left = 8 + Top = 5 + Width = 216 + Height = 148 + Cursor = crCross + BevelOuter = bvLowered + Color = clAppWorkSpace + TabOrder = 0 + OnDblClick = PreviewImageDblClick + OnMouseDown = PreviewImageMouseDown + OnMouseMove = PreviewImageMouseMove + OnMouseUp = PreviewImageMouseUp + object PreviewImage: TImage + Left = 1 + Top = 1 + Width = 210 + Height = 142 + IncrementalDisplay = True + PopupMenu = QualityPopup + Proportional = True + OnDblClick = PreviewImageDblClick + OnMouseDown = PreviewImageMouseDown + OnMouseMove = PreviewImageMouseMove + OnMouseUp = PreviewImageMouseUp + end + end + object PageControl: TPageControl + Left = 8 + Top = 157 + Width = 451 + Height = 130 + ActivePage = TabSheet3 + Anchors = [akLeft, akTop, akRight, akBottom] + Images = MainForm.Buttons + TabOrder = 1 + object TabSheet1: TTabSheet + Caption = 'Camera' + ImageIndex = 18 + DesignSize = ( + 443 + 101) + object scrollZoom: TScrollBar + Left = 112 + Top = 7 + Width = 259 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 100 + Max = 3000 + Min = -3000 + PageSize = 0 + SmallChange = 10 + TabOrder = 0 + OnChange = scrollZoomChange + OnScroll = scrollZoomScroll + end + object txtZoom: TEdit + Left = 380 + Top = 4 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 1 + Text = '0' + OnChange = txtZoomChange + OnEnter = txtZoomEnter + OnExit = txtZoomExit + OnKeyPress = txtZoomKeyPress + end + object scrollCenterX: TScrollBar + Left = 112 + Top = 31 + Width = 259 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 100 + Max = 10000 + Min = -10000 + PageSize = 0 + SmallChange = 10 + TabOrder = 2 + OnChange = scrollCenterXChange + OnScroll = scrollCenterXScroll + end + object txtCenterX: TEdit + Left = 380 + Top = 28 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 3 + Text = '0' + OnEnter = txtCenterXEnter + OnExit = txtCenterXExit + OnKeyPress = txtCenterXKeyPress + end + object scrollCenterY: TScrollBar + Left = 112 + Top = 55 + Width = 259 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 100 + Max = 10000 + Min = -10000 + PageSize = 0 + SmallChange = 10 + TabOrder = 4 + OnChange = scrollCenterYChange + OnScroll = scrollCenterYScroll + end + object txtCenterY: TEdit + Left = 380 + Top = 52 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 5 + Text = '0' + OnEnter = txtCenterYEnter + OnExit = txtCenterYExit + OnKeyPress = txtCenterYKeyPress + end + object scrollAngle: TScrollBar + Left = 112 + Top = 79 + Width = 259 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 1500 + Max = 36000 + Min = -36000 + PageSize = 0 + SmallChange = 100 + TabOrder = 6 + OnChange = scrollAngleChange + OnScroll = scrollAngleScroll + end + object txtAngle: TEdit + Left = 380 + Top = 76 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 7 + Text = '0' + OnEnter = txtAngleEnter + OnExit = txtAngleExit + OnKeyPress = txtAngleKeyPress + end + object pnlZoom: TPanel + Left = 4 + Top = 4 + Width = 101 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = 'Zoom' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlXpos: TPanel + Left = 4 + Top = 28 + Width = 101 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = 'X position' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlYpos: TPanel + Left = 4 + Top = 52 + Width = 101 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = 'Y position' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlAngle: TPanel + Left = 4 + Top = 76 + Width = 101 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = 'Rotation' + ParentShowHint = False + ShowHint = True + TabOrder = 11 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + end + object TabSheet2: TTabSheet + Caption = 'Rendering' + ImageIndex = 35 + DesignSize = ( + 443 + 101) + object pnlGamma: TPanel + Left = 4 + Top = 4 + Width = 101 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = 'Gamma' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object scrollGamma: TScrollBar + Left = 112 + Top = 7 + Width = 259 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 10 + Max = 500 + Min = 100 + PageSize = 0 + Position = 500 + TabOrder = 0 + OnChange = scrollGammaChange + OnScroll = scrollGammaScroll + end + object txtGamma: TEdit + Left = 372 + Top = 4 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 1 + Text = '0' + OnEnter = txtGammaEnter + OnExit = txtGammaExit + OnKeyPress = txtGammaKeyPress + end + object scrollBrightness: TScrollBar + Left = 112 + Top = 31 + Width = 259 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 100 + Max = 10000 + PageSize = 0 + TabOrder = 2 + OnChange = scrollBrightnessChange + OnScroll = scrollBrightnessScroll + end + object txtBrightness: TEdit + Left = 372 + Top = 28 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 3 + Text = '0' + OnEnter = txtBrightnessEnter + OnExit = txtBrightnessExit + OnKeyPress = txtBrightnessKeyPress + end + object scrollVibrancy: TScrollBar + Left = 112 + Top = 55 + Width = 259 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 10 + Max = 1000 + PageSize = 0 + TabOrder = 4 + OnChange = scrollVibrancyChange + OnScroll = scrollVibrancyScroll + end + object txtVibrancy: TEdit + Left = 372 + Top = 52 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 5 + Text = '0' + OnEnter = txtVibrancyEnter + OnExit = txtVibrancyExit + OnKeyPress = txtVibrancyKeyPress + end + object chkTransparent: TCheckBox + Left = 112 + Top = 78 + Width = 81 + Height = 17 + Caption = 'Transparent' + Enabled = False + TabOrder = 7 + Visible = False + end + object pnlBrightness: TPanel + Left = 4 + Top = 28 + Width = 101 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = 'Brightness' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlVibrancy: TPanel + Left = 4 + Top = 52 + Width = 101 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = 'Vibrancy' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlGammaThreshold: TPanel + Left = 250 + Top = 76 + Width = 121 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + Anchors = [akTop, akRight] + BevelOuter = bvLowered + Caption = ' Gamma threshold' + ParentShowHint = False + ShowHint = True + TabOrder = 11 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object txtGammaThreshold: TEdit + Left = 372 + Top = 76 + Width = 63 + Height = 21 + Anchors = [akTop, akRight] + TabOrder = 12 + Text = '0' + OnEnter = txtGammaThresholdEnter + OnExit = txtGammaThresholdExit + OnKeyPress = txtGammaThresholdKeyPress + end + object ColorPanel: TPanel + Left = 112 + Top = 76 + Width = 131 + Height = 21 + Cursor = crHandPoint + Anchors = [akLeft, akTop, akRight] + BevelInner = bvRaised + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clBlack + TabOrder = 6 + OnClick = ColorPanelClick + object Shape1: TShape + Left = 2 + Top = 2 + Width = 123 + Height = 13 + Align = alClient + Brush.Color = clBlack + Pen.Style = psClear + OnMouseUp = Shape1MouseUp + end + end + object pnlBackground: TPanel + Left = 4 + Top = 76 + Width = 101 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Background' + ParentShowHint = False + ShowHint = True + TabOrder = 13 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + end + object TabSheet3: TTabSheet + Caption = 'Gradient' + ImageIndex = 11 + DesignSize = ( + 443 + 101) + object lblVal: TLabel + Left = 430 + Top = 79 + Width = 6 + Height = 13 + Caption = '0' + Visible = False + end + object btnMenu: TSpeedButton + Left = 4 + Top = 41 + Width = 109 + Height = 21 + Hint = 'Click for menu' + Anchors = [akLeft, akBottom] + Caption = 'Rotate' + Glyph.Data = { + 5E040000424D5E04000000000000360400002800000005000000050000000100 + 08000000000028000000120B0000120B0000000100000000000000000000FFFF + FF00DEDAD800FFFFFF0000000000000000000000000000000000000000000000 + 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 + 0000000000000000000000000000000000000000000000000000020202020200 + 0000020200020200000002000000020000000000000000000000020202020200 + 0000} + Layout = blGlyphRight + ParentShowHint = False + ShowHint = True + OnClick = btnMenuClick + ExplicitTop = 46 + end + object btnOpen: TSpeedButton + Left = 396 + Top = 66 + Width = 23 + Height = 21 + Hint = 'Open Gradient Browser' + Anchors = [akRight, akBottom] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFB7A29363493563493563493563493563 + 4935634935634935634935634935634935FF00FFFF00FFFF00FFFF00FFFF00FF + B7A293FFFFFFB7A293B7A293B7A293B7A293B7A293B7A293B7A293B7A2936349 + 35FF00FFFF00FFFF00FFFF00FFFF00FFB7A293FFFFFFFFFFFFFCFAF9F7F1EEF1 + E7E1ECDDD5E6D3C9E1CABDB7A293634935FF00FFFF00FFFF00FFFF00FFFF00FF + B7A293FFFFFFFFFFFFFEFEFEFAF7F5F5EDE9EFE3DCEAD9D1E4CFC4B7A2936349 + 35FF00FFFF00FFFF00FFFF00FFFF00FFB7A293FFFFFF4454FA9A7CE8C52BBFE1 + 769FF6EB6DF6E242E7D5CBB7A293634935FF00FFFF00FFFF00FFFF00FFFF00FF + BAA596FFFFFF7370FFB489F4D432D8E877BDF6EB99F6E581EBDBD3B7A2936349 + 35FF00FFFF00FFFF00FFFF00FFFF00FFBEA99AFFFFFF38BFFF76D4DB42D87A84 + B776E27A83D55963EEE1DAB7A293634935FF00FFFF00FFFF00FFFF00FFFF00FF + C3AE9EFFFFFF03CFFF53E3D20DED5A6AC35AF37974E95651F1E7E1B7A2936349 + 35FF00FFFF00FFFF00FFFF00FFFF00FFC8B2A3FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFEFEFEFAF7F5F5EDE9B7A293634935FF00FFFF00FFFF00FFFF00FFFF00FF + CCB6A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFBB7A293B7A293644A + 36FF00FFFF00FFFF00FFFF00FFFF00FFD1BBABFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFB7A293644A36644A36644A36FF00FFFF00FFFF00FFFF00FFFF00FF + D5BFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9A495D4C5BA644A36E1D5 + CDFF00FFFF00FFFF00FFFF00FFFF00FFD8C2B2FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFC0AB9C644A36E2D6CDFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + D8C2B2D8C2B2D8C2B2D8C2B2D8C2B2D4BEAECFB9A9C9B3A4E2D6CDFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + Transparent = False + OnClick = btnOpenClick + ExplicitTop = 71 + end + object btnSmoothPalette: TSpeedButton + Left = 419 + Top = 66 + Width = 23 + Height = 21 + Hint = 'Smooth Palette' + Anchors = [akRight, akBottom] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000BEA99A634935 + 6349356349356349356349356349356349356349356349356349356349356349 + 35634935634935634935BFAA9BFEF0E8FEEFE6FEEDE3FEECE1FEEADFFEE9DDFE + E7DBFFE6D9FFE5D7FFE3D5FFE2D3FFE1D2FFE0D0FFDFCF634935C0AB9CFEF1EA + 2C2C2C3C3C3C4E4E4E6161617676768989899E9E9EB1B1B1C3C3C3D3D3D3E2E2 + E2EEEEEEFFE0D0634935C1AB9CFEF3EC2C2C2C3C3C3C4E4E4E61616176767689 + 89899E9E9EB1B1B1C3C3C3D3D3D3E2E2E2EEEEEEFFE1D2634935C2AC9DFEF4EE + 2C2C2C3C3C3C4E4E4E6161617676768989899E9E9EB1B1B1C3C3C3D3D3D3E2E2 + E2EEEEEEFFE2D3634935C2AD9EFEF6F02C2C2C3C3C3C4E4E4E61616176767689 + 89899E9E9EB1B1B1C3C3C3D3D3D3E2E2E2EEEEEEFFE3D5634935C3AE9FFDF7F2 + 2C2C2C3C3C3C4E4E4E6161617676768989899E9E9EB1B1B1C3C3C3D3D3D3E2E2 + E2EEEEEEFFE5D7634935C5AFA0FDF8F42C2C2C3C3C3C4E4E4E61616176767689 + 89899E9E9EB1B1B1C3C3C3D3D3D3E2E2E2EEEEEEFFE6D9634935C6B0A1FDFAF6 + 2C2C2C3C3C3C4E4E4E6161617676768989899E9E9EB1B1B1C3C3C3D3D3D3E2E2 + E2EEEEEEFEE7DB634935C7B1A2FDFBF82C2C2C3C3C3C4E4E4E61616176767689 + 89899E9E9EB1B1B1C3C3C3D3D3D3E2E2E2EEEEEEFEE9DD634935C7B2A3FDFCF9 + 2C2C2C3C3C3C4E4E4E6161617676768989899E9E9EB1B1B1C3C3C3D3D3D3E2E2 + E2EEEEEEFEEADF634935C8B3A4FDFDFB2C2C2C3C3C3C4E4E4E61616176767689 + 89899E9E9EB1B1B1C3C3C3D3D3D3E2E2E2EEEEEEFEECE1634935C9B3A4FDFEFC + 2C2C2C3C3C3C4E4E4E6161617676768989899E9E9EB1B1B1C3C3C3D3D3D3E2E2 + E2EEEEEEFEEDE3634935CAB4A5FDFEFD2C2C2C3C3C3C4E4E4E61616176767689 + 89899E9E9EB1B1B1C3C3C3D3D3D3E2E2E2EEEEEEFEEFE6634935CBB5A6FDFFFE + FDFEFDFDFEFCFDFDFBFDFCF9FDFBF8FDFAF6FDF8F4FDF7F2FEF6F0FEF4EEFEF3 + ECFEF1EAFEF0E8634935CBB5A6CBB5A6CAB4A5C9B3A4C8B3A4C7B2A3C7B1A2C6 + B0A1C5AFA0C3AE9FC2AD9EC2AC9DC1AB9CC0AB9CBFAA9BBEA99A} + ParentShowHint = False + ShowHint = True + Transparent = False + OnClick = mnuSmoothPaletteClick + ExplicitTop = 71 + end + object btnPaste: TSpeedButton + Left = 373 + Top = 66 + Width = 23 + Height = 21 + Hint = 'Paste gradient from clipboard' + Anchors = [akRight, akBottom] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000C30E0000C30E00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF81685526 + 2F38262F38262F38262F38262F38262F38262F38262F38262F38BCCCD2647E8E + 4F5E6F45526137414D262F3889715EE8DCD3B7A293B7A293B7A293B7A293B7A2 + 93B7A293B7A293262F38717F8B22B6EC008FCD008FCD008FCD008FCD917966EF + E6E1E8DBD3E0D0C6DAC6BCD4BFB2CFB9ABCCB6A8B7A293262F3875849068C8EA + 10B5F008ACEB03A4E30096D49A826FF7F1EFC3AE9EC3AE9EBDA898B7A293D4BF + B2B7A293B7A293262F3879899474D0ED28BDF111B5F007ABEA009DDCA28A78FD + FBFAF7F2EEEFE6E1E8DBD3E0D0C6705A4A6152465048423F3D3E7E8E9A83D9F0 + 46C9F22DBFF216B7F100A0E2A99280FFFFFFC3AE9EC3AE9EBDA899E8DCD37A60 + 4DD4C5BA615247FF00FF82949E91E2F366D5F44CCBF332C2F215AFE9B09988FF + FFFFFFFFFFFCFBF9F7F1EFEFE7E18168567A604DFF00FFFF00FF8699A29FEAF6 + 83E1F66BD8F553CEF40EB3F0B6A08EB09988A99280A28A789A82709179678971 + 5EFF00FFFF00FFFF00FF8A9EA6A9F0F899EAF888E3F56DD1EA13A1D413A1D412 + A0D30D97CF0791CA008FCD008FCD303944FF00FFFF00FFFF00FF8DA1AAAAF1F9 + A7F0F95E7D8A58737F566D7A5269774F66734C6170445A68236F90008FCD3E4A + 58FF00FFFF00FFFF00FF8FA4ACAAF1F9A8F1F95D86968CC6CF93E4F07AD5E762 + C6DE4F9AB23E5A671C7DA5008FCD4B5969FF00FFFF00FFFF00FF8FA4ACABF0F7 + AAF1F9A6EFF77397A2A1ECF5667D8A78C5D64C6C7C3461785FC3E822B6EC4E5E + 6FFF00FFFF00FFFF00FFB7CACF8FA4AC8FA4AC8FA4AC5B8D9FA5E8EF9BE8F48C + D5E246667673858F7A8A95758591BDCED3FF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FF86B3C382ADBD799FB0BCCED3FF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + Transparent = False + OnClick = btnPasteClick + ExplicitTop = 71 + end + object btnCopy: TSpeedButton + Left = 350 + Top = 66 + Width = 23 + Height = 21 + Hint = 'Copy gradient to clipboard' + Anchors = [akRight, akBottom] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFBA6E47AA5429AA5429A250279B4C259648238F46 + 228A4321864120FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC17955FD + F9F6CEB09CCCAF9BCAAD9AC7AC99C6AB98C4A997894321FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC98564FFFFFFDA8C5CD18351D18351D18351D183 + 51C6AB988E4522FF00FFB7A293634935634935634935634935634935D19273FF + FFFFFEFDFBFBEFEAF5DED3F0CEBEEDC3AFC7AC99924723FF00FFB7A293F8F3F0 + EADFD7E6D9CFE1D2C7DDCBBFD89F82FFFFFFF3A77FE7976EDA8C5CD18351D183 + 51CAAE9A984A25FF00FFB7A293FBF8F7E5AE81DEA173DA9C6ED59768E0AA90FF + FFFFFFFFFFFFFFFFFBF4F0F7E4DBF2D3C5CCAE9A9D4D25FF00FFBBA697FEFDFC + FBF6F5F6EFEBF1E6E0ECDED6E7B59CFFFFFFFCAE8AFCAE8AF1DBD2E78E60B357 + 2AAC5429A45027FF00FFC1AB9CFFFFFFFAC59FF0B88EE5AE81DEA173ECBDA6FF + FFFFFFFFFFFFFFFFFFFFFFEA9A72F0C9B2B1572BEDD7CDFF00FFC7B2A3FFFFFF + FFFFFFFCFAF9F8F2F0F3EAE6F0C4AEFFFFFFFFFFFFFFFFFFFFFFFFEBA785C565 + 35F1DBCFFF00FFFF00FFCFB9A9FFFFFFFFDABAFFD0AEF0DED2B7A293F0C4AEEF + C2ABEFC1AAEFB9A0EDB092EDB092F9E4D9FF00FFFF00FFFF00FFD4BEAFFFFFFF + FFFFFFFFFFFFFEFDFCBBA696D4C5BA8F725BE2DDD9FF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFD8C2B2FFFFFFFFFFFFFFFFFFFFFFFFC7B1A2A58266E2 + DDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD8C2B2D8C2B2 + D4BFAED4BFAECEB8A9C8B2A3E9E2DEFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + Transparent = False + OnClick = btnCopyClick + ExplicitTop = 71 + end + object btnColorPreset: TSpeedButton + Left = 4 + Top = 67 + Width = 109 + Height = 21 + Hint = 'Click to choose random preset' + Anchors = [akLeft, akBottom] + Caption = 'Preset' + ParentShowHint = False + ShowHint = True + OnClick = btnColorPresetClick + ExplicitTop = 72 + end + object GradientPnl: TPanel + Left = 0 + Top = 0 + Width = 443 + Height = 38 + Align = alTop + Anchors = [akLeft, akTop, akRight, akBottom] + BevelInner = bvRaised + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clAppWorkSpace + TabOrder = 0 + object GradientImage: TImage + Left = 2 + Top = 2 + Width = 435 + Height = 30 + Cursor = crHandPoint + Align = alClient + PopupMenu = GradientPopup + Stretch = True + OnDblClick = GradientImageDblClick + OnMouseDown = GradImageMouseDown + OnMouseMove = GradImageMouseMove + OnMouseUp = GradImageMouseUp + ExplicitHeight = 36 + end + end + object ScrollBar: TScrollBar + Left = 120 + Top = 44 + Width = 179 + Height = 15 + Anchors = [akLeft, akRight, akBottom] + LargeChange = 16 + Max = 128 + Min = -128 + PageSize = 0 + TabOrder = 1 + OnChange = ScrollBarChange + OnScroll = ScrollBarScroll + end + object cmbPalette: TComboBox + Left = 120 + Top = 67 + Width = 227 + Height = 21 + BevelInner = bvLowered + BevelOuter = bvRaised + Style = csOwnerDrawFixed + Anchors = [akLeft, akRight, akBottom] + Color = clBlack + DropDownCount = 20 + Font.Charset = ANSI_CHARSET + Font.Color = clWhite + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ItemHeight = 15 + ParentFont = False + ParentShowHint = False + ShowHint = False + TabOrder = 2 + OnChange = cmbPaletteChange + OnDrawItem = cmbPaletteDrawItem + Items.Strings = ( + 'south-sea-bather' + 'sky-flesh' + 'blue-bather' + 'no-name' + 'pillows' + 'mauve-splat' + 'facial-treescape 6' + 'fasion-bug' + 'leafy-face' + 'mouldy-sun' + 'sunny-harvest' + 'peach-tree' + 'fire-dragon' + 'ice-dragon' + 'german-landscape' + 'no-name' + 'living-mud-bomb' + 'cars' + 'unhealthy-tan' + 'daffodil' + 'rose' + 'healthy-skin' + 'orange' + 'white-ivy' + 'summer-makeup' + 'glow-buzz' + 'deep-water' + 'afternoon-beach' + 'dim-beach' + 'cloudy-brick' + 'burning-wood' + 'aquatic-garden' + 'no-name' + 'fall-quilt' + 'night-blue-sky' + 'shadow-iris' + 'solid-sky' + 'misty-field' + 'wooden-highlight' + 'jet-tundra' + 'pastel-lime' + 'hell' + 'indian-coast' + 'dentist-decor' + 'greenland' + 'purple-dress' + 'no-name' + 'spring-flora' + 'andi' + 'gig-o835' + 'rie02' + 'rie05' + 'rie11' + 'etretat.ppm' + 'the-hollow-needle-at-etretat.ppm' + 'rouen-cathedral-sunset.ppm' + 'the-houses-of-parliament.ppm' + 'starry-night.ppm' + 'water-lilies-sunset.ppm' + 'gogh.chambre-arles.ppm' + 'gogh.entrance.ppm' + 'gogh.the-night-cafe.ppm' + 'gogh.vegetable-montmartre.ppm' + 'matisse.bonheur-vivre.ppm' + 'matisse.flowers.ppm' + 'matisse.lecon-musique.ppm' + 'modigliani.nude-caryatid.ppm' + 'braque.instruments.ppm' + 'calcoast09.ppm' + 'dodge102.ppm' + 'ernst.anti-pope.ppm' + 'ernst.ubu-imperator.ppm' + 'fighting-forms.ppm' + 'fog25.ppm' + 'geyser27.ppm' + 'gris.josette.ppm' + 'gris.landscape-ceret.ppm' + 'kandinsky.comp-9.ppm' + 'kandinsky.yellow-red-blue.ppm' + 'klee.insula-dulcamara.ppm' + 'nile.ppm' + 'picasso.jfille-chevre.ppm' + 'pollock.lavender-mist.ppm' + 'yngpaint.ppm') + end + object txtVal: TEdit + Left = 306 + Top = 41 + Width = 49 + Height = 21 + Anchors = [akRight, akBottom] + TabOrder = 3 + Text = '0' + OnExit = txtValExit + OnKeyPress = txtValKeyPress + end + object btnReset: TButton + Left = 363 + Top = 41 + Width = 79 + Height = 21 + Anchors = [akRight, akBottom] + Caption = 'Reset' + TabOrder = 4 + OnClick = btnResetClick + end + end + object TabSheet4: TTabSheet + Caption = 'Image Size' + ImageIndex = 51 + DesignSize = ( + 443 + 101) + object Bevel2: TBevel + Left = 4 + Top = 4 + Width = 173 + Height = 93 + Shape = bsFrame + end + object Bevel1: TBevel + Left = 184 + Top = 4 + Width = 138 + Height = 92 + Anchors = [akLeft, akTop, akRight, akBottom] + Shape = bsFrame + ExplicitHeight = 94 + end + object Bevel3: TBevel + Left = 330 + Top = 4 + Width = 111 + Height = 93 + Anchors = [akTop, akRight] + Shape = bsFrame + end + object btnSet1: TSpeedButton + Left = 288 + Top = 12 + Width = 25 + Height = 25 + Anchors = [akTop, akRight] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFEFCECFC36465AA5556A452539F4F509A4D4D94 + 4A4A8F4747894444834141783B3C783B3C7239396E3637FF00FFFF00FFCF6B6C + F38E8FE68081AA4424473221C3B4ABC6BBB3CAC1BCCEC8C4564D489E3E339C3D + 36983931723939FF00FFFF00FFD16F70FF999AEC8687E68081715B4B473C348D + 7868EDE0D8F1E7E08F7F73A34135A2423C9C3D35783B3CFF00FFFF00FFD47576 + FF9FA0F59091EC8687715B4B000000473C34E9D9CEECDDD4857467AE4B43AA49 + 44A3423C7D3E3EFF00FFFF00FFD77B7CFFA9AAFB9FA0F59394715B4B715B4B71 + 5B4B715B4B7662527D6A5BBA5654B24F4CAA4944834141FF00FFFF00FFDB8384 + FFB3B4FFADAEFCA3A4F48E8FEC8687E68081DF797AD77172D16B6CC15D5CBA56 + 54B2504C894444FF00FFFF00FFDF8A8BFFBBBCFFB6B7C96360C45E56BE584BB8 + 523FB34D34AD4728A7411CA13B11C15D5CBA56548F4747FF00FFFF00FFE29192 + FFBDBECC6667FFFFFFFFFFFFFBF8F6F6EEEAF0E5DEEADBD2E5D1C6E1CABDA13B + 11C25D5C944A4AFF00FFFF00FFE59798FFBDBED36D6EFFFFFFFFFFFFFFFFFFFB + F8F6F6EEEAF0E5DEEADBD2E5D1C6A7411CCC67679A4D4DFF00FFFF00FFE99E9F + FFBDBEDC7677FFFFFFFFFFFFFFFFFFFFFFFFFBF8F6F6EEEAF0E5DEEADBD2AD47 + 28D771729F4F50FF00FFFF00FFEDA6A7FFBDBEE68081FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFBF8F6F6EEEAF0E5DEB34D34DF797AA45253FF00FFFF00FFF0ACAD + FFBDBEEF898AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F6F6EEEAB852 + 3F673333AA5556FF00FFFF00FFF3B2B3FFBDBEF89293FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFBF8F6BE584BB05859B05859FF00FFFF00FFF5B6B7 + F5B6B7F3B2B3F1ADAEEEA7A8EAA1A2E79A9BE49394E08E8FDD8788DA8081D67A + 7BD37475D16F70FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnSet1Click + end + object btnSet2: TSpeedButton + Left = 288 + Top = 38 + Width = 25 + Height = 25 + Anchors = [akTop, akRight] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFEFCECFC36465AA5556A452539F4F509A4D4D94 + 4A4A8F4747894444834141783B3C783B3C7239396E3637FF00FFFF00FFCF6B6C + F38E8FE68081AA4424473221C3B4ABC6BBB3CAC1BCCEC8C4564D489E3E339C3D + 36983931723939FF00FFFF00FFD16F70FF999AEC8687E68081715B4B473C348D + 7868EDE0D8F1E7E08F7F73A34135A2423C9C3D35783B3CFF00FFFF00FFD47576 + FF9FA0F59091EC8687715B4B000000473C34E9D9CEECDDD4857467AE4B43AA49 + 44A3423C7D3E3EFF00FFFF00FFD77B7CFFA9AAFB9FA0F59394715B4B715B4B71 + 5B4B715B4B7662527D6A5BBA5654B24F4CAA4944834141FF00FFFF00FFDB8384 + FFB3B4FFADAEFCA3A4F48E8FEC8687E68081DF797AD77172D16B6CC15D5CBA56 + 54B2504C894444FF00FFFF00FFDF8A8BFFBBBCFFB6B7C96360C45E56BE584BB8 + 523FB34D34AD4728A7411CA13B11C15D5CBA56548F4747FF00FFFF00FFE29192 + FFBDBECC6667FFFFFFFFFFFFFBF8F6F6EEEAF0E5DEEADBD2E5D1C6E1CABDA13B + 11C25D5C944A4AFF00FFFF00FFE59798FFBDBED36D6EFFFFFFFFFFFFFFFFFFFB + F8F6F6EEEAF0E5DEEADBD2E5D1C6A7411CCC67679A4D4DFF00FFFF00FFE99E9F + FFBDBEDC7677FFFFFFFFFFFFFFFFFFFFFFFFFBF8F6F6EEEAF0E5DEEADBD2AD47 + 28D771729F4F50FF00FFFF00FFEDA6A7FFBDBEE68081FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFBF8F6F6EEEAF0E5DEB34D34DF797AA45253FF00FFFF00FFF0ACAD + FFBDBEEF898AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F6F6EEEAB852 + 3F673333AA5556FF00FFFF00FFF3B2B3FFBDBEF89293FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFBF8F6BE584BB05859B05859FF00FFFF00FFF5B6B7 + F5B6B7F3B2B3F1ADAEEEA7A8EAA1A2E79A9BE49394E08E8FDD8788DA8081D67A + 7BD37475D16F70FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnSet2Click + end + object btnSet3: TSpeedButton + Left = 288 + Top = 64 + Width = 25 + Height = 25 + Anchors = [akTop, akRight] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFEFCECFC36465AA5556A452539F4F509A4D4D94 + 4A4A8F4747894444834141783B3C783B3C7239396E3637FF00FFFF00FFCF6B6C + F38E8FE68081AA4424473221C3B4ABC6BBB3CAC1BCCEC8C4564D489E3E339C3D + 36983931723939FF00FFFF00FFD16F70FF999AEC8687E68081715B4B473C348D + 7868EDE0D8F1E7E08F7F73A34135A2423C9C3D35783B3CFF00FFFF00FFD47576 + FF9FA0F59091EC8687715B4B000000473C34E9D9CEECDDD4857467AE4B43AA49 + 44A3423C7D3E3EFF00FFFF00FFD77B7CFFA9AAFB9FA0F59394715B4B715B4B71 + 5B4B715B4B7662527D6A5BBA5654B24F4CAA4944834141FF00FFFF00FFDB8384 + FFB3B4FFADAEFCA3A4F48E8FEC8687E68081DF797AD77172D16B6CC15D5CBA56 + 54B2504C894444FF00FFFF00FFDF8A8BFFBBBCFFB6B7C96360C45E56BE584BB8 + 523FB34D34AD4728A7411CA13B11C15D5CBA56548F4747FF00FFFF00FFE29192 + FFBDBECC6667FFFFFFFFFFFFFBF8F6F6EEEAF0E5DEEADBD2E5D1C6E1CABDA13B + 11C25D5C944A4AFF00FFFF00FFE59798FFBDBED36D6EFFFFFFFFFFFFFFFFFFFB + F8F6F6EEEAF0E5DEEADBD2E5D1C6A7411CCC67679A4D4DFF00FFFF00FFE99E9F + FFBDBEDC7677FFFFFFFFFFFFFFFFFFFFFFFFFBF8F6F6EEEAF0E5DEEADBD2AD47 + 28D771729F4F50FF00FFFF00FFEDA6A7FFBDBEE68081FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFBF8F6F6EEEAF0E5DEB34D34DF797AA45253FF00FFFF00FFF0ACAD + FFBDBEEF898AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F6F6EEEAB852 + 3F673333AA5556FF00FFFF00FFF3B2B3FFBDBEF89293FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFBF8F6BE584BB05859B05859FF00FFFF00FFF5B6B7 + F5B6B7F3B2B3F1ADAEEEA7A8EAA1A2E79A9BE49394E08E8FDD8788DA8081D67A + 7BD37475D16F70FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentShowHint = False + ShowHint = True + OnClick = btnSet3Click + end + object Label7: TLabel + Left = 136 + Top = 30 + Width = 26 + Height = 13 + Caption = 'pixels' + Visible = False + end + object Label6: TLabel + Left = 120 + Top = 16 + Width = 15 + Height = 36 + Caption = '}' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -32 + Font.Name = 'Times New Roman' + Font.Style = [] + ParentFont = False + Visible = False + end + object btnPreset1: TButton + Left = 192 + Top = 12 + Width = 95 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Caption = 'Preset 1' + TabOrder = 0 + OnClick = btnPreset1Click + end + object btnPreset2: TButton + Left = 192 + Top = 38 + Width = 95 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Caption = 'Preset 2' + TabOrder = 1 + OnClick = btnPreset2Click + end + object btnPreset3: TButton + Left = 192 + Top = 64 + Width = 95 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Caption = 'Preset 3' + TabOrder = 2 + OnClick = btnPreset3Click + end + object btnApplySize: TBitBtn + Left = 336 + Top = 64 + Width = 99 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Caption = 'Apply' + TabOrder = 3 + OnClick = btnApplySizeClick + end + object chkMaintain: TCheckBox + Left = 14 + Top = 70 + Width = 157 + Height = 19 + Anchors = [akLeft, akTop, akRight] + Caption = 'Keep aspect ratio' + TabOrder = 4 + OnClick = chkMaintainClick + end + object chkResizeMain: TCheckBox + Left = 336 + Top = 10 + Width = 99 + Height = 39 + Alignment = taLeftJustify + Anchors = [akLeft, akTop, akRight, akBottom] + Caption = 'Resize Main Window' + Checked = True + State = cbChecked + TabOrder = 7 + WordWrap = True + end + object pnlWidth: TPanel + Left = 12 + Top = 12 + Width = 85 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Width' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlHeight: TPanel + Left = 12 + Top = 38 + Width = 85 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Height' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object txtHeight: TComboBox + Left = 96 + Top = 38 + Width = 75 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 6 + Text = '384' + OnChange = txtHeightChange + OnKeyPress = txtSizeKeyPress + Items.Strings = ( + '384' + '400' + '480' + '512' + '600' + '768' + '960' + '1024') + end + object txtWidth: TComboBox + Left = 96 + Top = 12 + Width = 75 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 5 + Text = '512' + OnChange = txtWidthChange + OnKeyPress = txtSizeKeyPress + Items.Strings = ( + '512' + '640' + '800' + '1024' + '1280') + end + end + object TabSheet6: TTabSheet + Caption = 'Curves' + ImageIndex = 69 + object CurvesPanel: TPanel + Left = 3 + Top = 1 + Width = 323 + Height = 97 + BevelOuter = bvLowered + Color = clBlack + ParentBackground = False + TabOrder = 0 + end + object tbWeightLeft: TScrollBar + Left = 111 + Top = 67 + Width = 75 + Height = 15 + Max = 160 + PageSize = 0 + Position = 10 + TabOrder = 1 + Visible = False + OnChange = WeightChange + OnScroll = WeightScroll + end + object tbWeightRight: TScrollBar + Left = 111 + Top = 83 + Width = 129 + Height = 15 + Max = 160 + PageSize = 0 + Position = 10 + TabOrder = 2 + Visible = False + OnChange = WeightChange + OnScroll = WeightScroll + end + object Panel3: TPanel + Left = 111 + Top = 88 + Width = 121 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = ' First CP weight:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + TabOrder = 3 + Visible = False + end + object Panel4: TPanel + Left = 119 + Top = 88 + Width = 121 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = ' Second CP weight:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + TabOrder = 4 + Visible = False + end + object Panel5: TPanel + Left = 332 + Top = 3 + Width = 108 + Height = 21 + Cursor = crHandPoint + Alignment = taLeftJustify + BevelOuter = bvNone + Caption = ' Selected curve:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object cbChannel: TComboBox + Left = 332 + Top = 30 + Width = 107 + Height = 21 + Style = csDropDownList + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ItemIndex = 0 + ParentFont = False + TabOrder = 6 + Text = 'Overall' + OnChange = curveChange + Items.Strings = ( + 'Overall' + 'Red' + 'Green' + 'Blue') + end + object btnResetCurves: TButton + Left = 332 + Top = 75 + Width = 107 + Height = 21 + Caption = 'Reset' + TabOrder = 7 + OnClick = btnResetCurvesClick + end + end + end + object pnlPitch: TPanel + Left = 232 + Top = 34 + Width = 105 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Pitch' + ParentShowHint = False + ShowHint = True + TabOrder = 2 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlYaw: TPanel + Left = 232 + Top = 58 + Width = 105 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Yaw' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlPersp: TPanel + Left = 232 + Top = 106 + Width = 105 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Perspective' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + TabOrder = 4 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object txtPitch: TEdit + Left = 336 + Top = 34 + Width = 124 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 6 + Text = '0' + OnEnter = txtCamEnter + OnExit = txtCamPitchExit + OnKeyPress = txtCamPitchKeyPress + end + object txtYaw: TEdit + Left = 336 + Top = 58 + Width = 124 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 7 + Text = '0' + OnEnter = txtCamEnter + OnExit = txtCamYawExit + OnKeyPress = txtCamYawKeyPress + end + object txtPersp: TEdit + Left = 336 + Top = 106 + Width = 124 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 8 + Text = '0' + OnEnter = txtCamEnter + OnExit = txtCamDistExit + OnKeyPress = txtCamDistKeyPress + end + object pnlMasterScale: TPanel + Left = 232 + Top = 130 + Width = 105 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Scale' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object editPPU: TEdit + Left = 336 + Top = 130 + Width = 124 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 5 + Text = '0' + OnExit = editPPUValidate + OnKeyPress = editPPUKeyPress + end + object pnlZpos: TPanel + Left = 232 + Top = 82 + Width = 105 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Height' + ParentShowHint = False + ShowHint = True + TabOrder = 11 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object txtZpos: TEdit + Left = 336 + Top = 82 + Width = 124 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 9 + Text = '0' + OnEnter = txtCamEnter + OnExit = txtCamDistExit + OnKeyPress = txtCamDistKeyPress + end + object Panel1: TPanel + Left = 8 + Top = 300 + Width = 401 + Height = 46 + BevelOuter = bvNone + BorderStyle = bsSingle + Color = clInfoBk + Ctl3D = False + ParentCtl3D = False + TabOrder = 12 + object Label1: TLabel + Left = 8 + Top = 8 + Width = 384 + Height = 26 + Caption = + 'WARNING! Using the "Zoom" setting will drastically decrease rend' + + 'er speed. Use this setting only when you are sure what you are d' + + 'oing.' + WordWrap = True + end + end + object pnlDOF: TPanel + Left = 232 + Top = 10 + Width = 105 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Depth blur' + ParentShowHint = False + ShowHint = True + TabOrder = 13 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object txtDOF: TEdit + Left = 336 + Top = 10 + Width = 76 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 14 + Text = '0' + OnEnter = txtCamEnter + OnExit = txtCamDofExit + OnKeyPress = txtCamDofKeyPress + end + object QualityPopup: TPopupMenu + Images = MainForm.Buttons + Left = 168 + Top = 16 + object mnuLowQuality: TMenuItem + Caption = 'Low Quality' + RadioItem = True + OnClick = mnuLowQualityClick + end + object mnuMediumQuality: TMenuItem + Caption = 'Medium Quality' + Checked = True + RadioItem = True + OnClick = mnuMediumQualityClick + end + object mnuHighQuality: TMenuItem + Caption = 'High Quality' + RadioItem = True + OnClick = mnuHighQualityClick + end + object N8: TMenuItem + Caption = '-' + end + object mnuInstantPreview: TMenuItem + Caption = 'Instant Preview' + Checked = True + OnClick = mnuInstantPreviewClick + end + end + object ColorDialog: TColorDialog + Options = [cdFullOpen] + Left = 200 + Top = 16 + end + object GradientPopup: TPopupMenu + Images = MainForm.Buttons + Left = 168 + Top = 56 + object mnuRandomize: TMenuItem + Caption = 'Randomize' + OnClick = mnuRandomizeClick + end + object N7: TMenuItem + Caption = '-' + end + object mnuInvert: TMenuItem + Caption = 'Invert' + OnClick = mnuInvertClick + end + object mnuReverse: TMenuItem + Caption = '&Reverse' + OnClick = mnuReverseClick + end + object N3: TMenuItem + Caption = '-' + end + object mnuSmoothPalette: TMenuItem + Caption = 'Smooth Palette...' + ImageIndex = 34 + OnClick = mnuSmoothPaletteClick + end + object mnuGradientBrowser: TMenuItem + Caption = 'Gradient Browser...' + ImageIndex = 22 + OnClick = btnOpenClick + end + object N4: TMenuItem + Caption = '-' + end + object SaveGradient1: TMenuItem + Caption = 'Save Gradient...' + ImageIndex = 2 + OnClick = SaveGradient1Click + end + object SaveasMapfile1: TMenuItem + Caption = 'Save as Map file...' + OnClick = SaveasMapfile1Click + end + object N6: TMenuItem + Caption = '-' + end + object mnuSaveasDefault: TMenuItem + Caption = 'Save as Default' + OnClick = mnuSaveasDefaultClick + end + object N5: TMenuItem + Caption = '-' + end + object mnuCopy: TMenuItem + Caption = 'Copy' + ImageIndex = 7 + OnClick = btnCopyClick + end + object mnuPaste: TMenuItem + Caption = 'Paste' + ImageIndex = 8 + OnClick = btnPasteClick + end + end + object scrollModePopup: TPopupMenu + AutoHotkeys = maManual + AutoPopup = False + Left = 200 + Top = 56 + object mnuRotate: TMenuItem + Caption = 'Rotate' + OnClick = mnuRotateClick + end + object N1: TMenuItem + Caption = '-' + end + object mnuHue: TMenuItem + Caption = 'Hue' + OnClick = mnuHueClick + end + object mnuSaturation: TMenuItem + Caption = 'Saturation' + OnClick = mnuSaturationClick + end + object mnuBrightness: TMenuItem + Caption = 'Brightness' + OnClick = mnuBrightnessClick + end + object Contrast1: TMenuItem + Caption = 'Contrast' + OnClick = mnuContrastClick + end + object N2: TMenuItem + Caption = '-' + end + object mnuBlur: TMenuItem + Caption = 'Blur' + OnClick = mnuBlurClick + end + object mnuFrequency: TMenuItem + Caption = 'Frequency' + OnClick = mnuFrequencyClick + end + end + object SaveDialog: TSaveDialog + DefaultExt = 'map' + Filter = 'Map files|*.map' + Left = 168 + Top = 96 + end + object ApplicationEvents: TApplicationEvents + OnActivate = ApplicationEventsActivate + Left = 200 + Top = 96 + end +end diff --git a/Forms/Adjust.pas b/Forms/Adjust.pas new file mode 100644 index 0000000..b3b4aee --- /dev/null +++ b/Forms/Adjust.pas @@ -0,0 +1,2733 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Adjust; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls, ComCtrls, Buttons, Menus, AppEvnts, CurvesControl, + ControlPoint, Cmap, RenderingInterface, Translation; + +const + WM_UPDATE_PARAMS = WM_APP + 5439; + +const + PixelCountMax = 32768; + +type + pRGBTripleArray = ^TRGBTripleArray; + TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple; + +type + TAdjustForm = class(TForm) + QualityPopup: TPopupMenu; + mnuLowQuality: TMenuItem; + mnuMediumQuality: TMenuItem; + mnuHighQuality: TMenuItem; + ColorDialog: TColorDialog; + PrevPnl: TPanel; + PreviewImage: TImage; + PageControl: TPageControl; + TabSheet1: TTabSheet; + scrollZoom: TScrollBar; + txtZoom: TEdit; + scrollCenterX: TScrollBar; + txtCenterX: TEdit; + scrollCenterY: TScrollBar; + txtCenterY: TEdit; + TabSheet2: TTabSheet; + scrollGamma: TScrollBar; + txtGamma: TEdit; + scrollBrightness: TScrollBar; + txtBrightness: TEdit; + scrollVibrancy: TScrollBar; + txtVibrancy: TEdit; + ColorPanel: TPanel; + TabSheet3: TTabSheet; + scrollAngle: TScrollBar; + txtAngle: TEdit; + GradientPnl: TPanel; + GradientImage: TImage; + lblVal: TLabel; + ScrollBar: TScrollBar; + btnMenu: TSpeedButton; + btnOpen: TSpeedButton; + btnSmoothPalette: TSpeedButton; + btnPaste: TSpeedButton; + btnCopy: TSpeedButton; + cmbPalette: TComboBox; + GradientPopup: TPopupMenu; + mnuRandomize: TMenuItem; + N7: TMenuItem; + mnuInvert: TMenuItem; + mnuReverse: TMenuItem; + N3: TMenuItem; + mnuSmoothPalette: TMenuItem; + mnuGradientBrowser: TMenuItem; + N4: TMenuItem; + SaveGradient1: TMenuItem; + SaveasMapfile1: TMenuItem; + N6: TMenuItem; + mnuSaveasDefault: TMenuItem; + N5: TMenuItem; + mnuCopy: TMenuItem; + mnuPaste: TMenuItem; + scrollModePopup: TPopupMenu; + mnuRotate: TMenuItem; + N1: TMenuItem; + mnuHue: TMenuItem; + mnuSaturation: TMenuItem; + mnuBrightness: TMenuItem; + Contrast1: TMenuItem; + N2: TMenuItem; + mnuBlur: TMenuItem; + mnuFrequency: TMenuItem; + SaveDialog: TSaveDialog; + ApplicationEvents: TApplicationEvents; + TabSheet4: TTabSheet; + btnPreset1: TButton; + btnPreset2: TButton; + btnPreset3: TButton; + chkTransparent: TCheckBox; + btnColorPreset: TSpeedButton; + Bevel1: TBevel; + btnApplySize: TBitBtn; + chkMaintain: TCheckBox; + txtWidth: TComboBox; + txtHeight: TComboBox; + Bevel2: TBevel; + N8: TMenuItem; + mnuInstantPreview: TMenuItem; + pnlZoom: TPanel; + pnlXpos: TPanel; + pnlYpos: TPanel; + pnlAngle: TPanel; + pnlGamma: TPanel; + pnlBrightness: TPanel; + pnlVibrancy: TPanel; + chkResizeMain: TCheckBox; + Bevel3: TBevel; + pnlPitch: TPanel; + pnlYaw: TPanel; + pnlPersp: TPanel; + txtPitch: TEdit; + txtYaw: TEdit; + txtPersp: TEdit; + pnlMasterScale: TPanel; + editPPU: TEdit; + pnlZpos: TPanel; + txtZpos: TEdit; + pnlGammaThreshold: TPanel; + txtGammaThreshold: TEdit; + Panel1: TPanel; + Label1: TLabel; + btnUndo: TSpeedButton; + btnRedo: TSpeedButton; + pnlDOF: TPanel; + txtDOF: TEdit; + btnSet1: TSpeedButton; + btnSet2: TSpeedButton; + btnSet3: TSpeedButton; + Label7: TLabel; + Label6: TLabel; + Shape1: TShape; + txtVal: TEdit; + btnReset: TButton; + pnlWidth: TPanel; + pnlHeight: TPanel; + pnlBackground: TPanel; + TabSheet6: TTabSheet; + CurvesPanel: TPanel; + tbWeightLeft: TScrollBar; + tbWeightRight: TScrollBar; + Panel3: TPanel; + Panel4: TPanel; + Panel5: TPanel; + cbChannel: TComboBox; + btnResetCurves: TButton; + procedure FormCreate(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormDestroy(Sender: TObject); + procedure DrawPreview; +// procedure btnOKClick(Sender: TObject); +// procedure btnCancelClick(Sender: TObject); +// procedure btnCanelClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure mnuLowQualityClick(Sender: TObject); + procedure mnuMediumQualityClick(Sender: TObject); + procedure mnuHighQualityClick(Sender: TObject); + procedure txtZoomKeyPress(Sender: TObject; var Key: Char); + procedure txtZoomExit(Sender: TObject); + procedure txtCenterXKeyPress(Sender: TObject; var Key: Char); + procedure txtCenterXExit(Sender: TObject); + procedure txtCenterYKeyPress(Sender: TObject; var Key: Char); + procedure txtCenterYExit(Sender: TObject); + procedure txtGammaKeyPress(Sender: TObject; var Key: Char); + procedure txtGammaExit(Sender: TObject); + procedure txtBrightnessKeyPress(Sender: TObject; var Key: Char); + procedure txtBrightnessExit(Sender: TObject); + procedure txtVibrancyKeyPress(Sender: TObject; var Key: Char); + procedure txtVibrancyExit(Sender: TObject); + procedure scrollZoomScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure scrollCenterXScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure scrollCenterYScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure scrollGammaScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure scrollBrightnessScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); + procedure scrollVibrancyScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); + procedure scrollVibrancyChange(Sender: TObject); + procedure scrollGammaChange(Sender: TObject); + procedure scrollBrightnessChange(Sender: TObject); + procedure scrollZoomChange(Sender: TObject); + procedure scrollCenterXChange(Sender: TObject); + procedure scrollCenterYChange(Sender: TObject); + procedure ColorPanelClick(Sender: TObject); + procedure scrollContrastScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); + procedure txtGammaEnter(Sender: TObject); + procedure txtBrightnessEnter(Sender: TObject); + procedure txtVibrancyEnter(Sender: TObject); + procedure txtZoomEnter(Sender: TObject); + procedure txtCenterXEnter(Sender: TObject); + procedure txtCenterYEnter(Sender: TObject); + procedure scrollAngleChange(Sender: TObject); + procedure scrollAngleScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure txtAngleEnter(Sender: TObject); + procedure txtAngleExit(Sender: TObject); + procedure txtAngleKeyPress(Sender: TObject; var Key: Char); + + // --Z-- // gradient functions + procedure cmbPaletteChange(Sender: TObject); +// procedure DrawPalette; + procedure mnuReverseClick(Sender: TObject); + procedure mnuInvertClick(Sender: TObject); + procedure btnMenuClick(Sender: TObject); + procedure mnuRotateClick(Sender: TObject); + procedure mnuHueClick(Sender: TObject); + procedure mnuSaturationClick(Sender: TObject); + procedure ScrollBarChange(Sender: TObject); + procedure mnuBrightnessClick(Sender: TObject); + procedure mnuBlurClick(Sender: TObject); + procedure btnOpenClick(Sender: TObject); + procedure mnuSmoothPaletteClick(Sender: TObject); + procedure SaveGradient1Click(Sender: TObject); + procedure SaveasMapfile1Click(Sender: TObject); + procedure cmbPaletteDrawItem(Control: TWinControl; Index: Integer; + Rect: TRect; State: TOwnerDrawState); + procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure btnCopyClick(Sender: TObject); + procedure btnPasteClick(Sender: TObject); + procedure ApplicationEventsActivate(Sender: TObject); + procedure mnuSaveasDefaultClick(Sender: TObject); + procedure mnuRandomizeClick(Sender: TObject); + procedure mnuFrequencyClick(Sender: TObject); + procedure mnuContrastClick(Sender: TObject); + + procedure GradImageMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure GradImageMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure GradImageMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + + procedure btnSet1Click(Sender: TObject); + procedure btnSet2Click(Sender: TObject); + procedure btnSet3Click(Sender: TObject); + procedure btnPreset1Click(Sender: TObject); + procedure btnPreset2Click(Sender: TObject); + procedure btnPreset3Click(Sender: TObject); + procedure txtWidthChange(Sender: TObject); + procedure txtHeightChange(Sender: TObject); + procedure txtSizeKeyPress(Sender: TObject; var Key: Char); + procedure chkMaintainClick(Sender: TObject); + procedure SetMainWindowSize; + procedure GetMainWindowSize; + procedure btnUndoClick(Sender: TObject); + procedure btnRedoClick(Sender: TObject); + procedure GradientImageDblClick(Sender: TObject); + procedure btnColorPresetClick(Sender: TObject); + procedure btnApplySizeClick(Sender: TObject); + procedure mnuInstantPreviewClick(Sender: TObject); + procedure editPPUKeyPress(Sender: TObject; var Key: Char); + procedure editPPUValidate(Sender: TObject); + + procedure DragPanelMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure DragPanelMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure DragPanelMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure DragPanelDblClick(Sender: TObject); + procedure FormActivate(Sender: TObject); + procedure txtCamEnter(Sender: TObject); + procedure txtCamPitchExit(Sender: TObject); + procedure txtCamPitchKeyPress(Sender: TObject; var Key: Char); + procedure txtCamYawExit(Sender: TObject); + procedure txtCamYawKeyPress(Sender: TObject; var Key: Char); + procedure txtCamDistExit(Sender: TObject); + procedure txtCamDistKeyPress(Sender: TObject; var Key: Char); + procedure txtCamZposExit(Sender: TObject); + procedure txtCamZposKeyPress(Sender: TObject; var Key: Char); + procedure txtCamDofExit(Sender: TObject); + procedure txtCamDofKeyPress(Sender: TObject; var Key: Char); + procedure PreviewImageMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure PreviewImageMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure PreviewImageMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure PreviewImageDblClick(Sender: TObject); + procedure txtGammaThresholdKeyPress(Sender: TObject; var Key: Char); + procedure txtGammaThresholdEnter(Sender: TObject); + procedure txtGammaThresholdExit(Sender: TObject); + procedure txtZoomChange(Sender: TObject); + procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure btnResetClick(Sender: TObject); + procedure txtValKeyPress(Sender: TObject; var Key: Char); + procedure txtValExit(Sender: TObject); + procedure WeightScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure WeightChange(Sender: TObject); + procedure curveChange(Sender: TObject); + procedure btnResetCurvesClick(Sender: TObject); + + private + CurvesControl: TCurvesControl; + Resetting: boolean; + Render: TRenderer; + bm: TBitmap; + EditBoxValue: string; + + cp: TControlPoint; + + pnlDragMode, pnlDragged, pnlMM: boolean; + pnlDragPos, pnlDragOld: integer; + pnlDragValue: double; + mousepos: TPoint; + + camDragMode, camDragged, camMM: boolean; + camDragPos, camDragOld: TPoint; + camDragValueX, camDragValueY: double; + + private // gradient stuff + Palette, BackupPal: TColorMap; + tmpBackupPal: TColorMap; + + scrollMode: (modeRotate, + modeHue, modeSaturation, modeBrightness, modeContrast, + modeBlur, modeFrequency); + GradientChanged: boolean; + imgDragMode: (imgDragNone, imgDragRotate, imgDragStretch); + dragX, oldX: integer; + oldpos, offset: integer; // for display...? :-\ + + procedure Apply; + procedure SetCurvesCp(ccp: TControlPoint); + function Blur(const radius: integer; const pal: TColorMap): TColorMap; + function Frequency(const times: Integer; const pal: TColorMap): TColorMap; + procedure SaveMap(FileName: string); + + procedure UpdateGradient(Pal: TColorMap); + + private // image size stuff + ImageHeight, ImageWidth: integer; + Preset: array[1..3] of record + Left, Top, Width, Height: integer; + end; + ratio: double; + + procedure ReadPreset(n: integer); + procedure WritePreset(n: integer); + function PresetToStr(n: integer): string; + + public + PreviewDensity: double; + +// cmap: TColorMap; +// Sample_Density, Zoom: double; +// Center: array[0..1] of double; + procedure UpdateDisplay(PreviewOnly: boolean = false); + procedure UpdateFlame(bBgOnly: boolean = false); + procedure TemplateRandomizeGradient; + + end; + +var + AdjustForm: TAdjustForm; + +function GradientInClipboard: boolean; +procedure RGBToHSV(R, G, B: byte; var H, S, V: real); +procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer); + +implementation + +//uses Main, Global, Registry, Mutate, Editor, Save, Browser; +uses + RndFlame, Main, cmapdata, Math, Browser, Editor, Global, + Save, Mutate, ClipBrd, GradientHlpr, Registry, Curves; + +{$R *.DFM} + +procedure TAdjustForm.SetCurvesCp(ccp: TControlPoint); +begin + if CurvesControl = nil then Exit; + CurvesControl.SetCp(ccp); +end; + +procedure TAdjustForm.UpdateDisplay(PreviewOnly: boolean = false); +var + pw, ph: integer; + r: double; +begin + cp.copy(MainCp); + SetCurvesCp(MainCp); + + tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10); + tbWeightRight.Position := Round(CurvesControl.WeightRight * 10); + + pw := PrevPnl.Width -2; + ph := PrevPnl.Height -2; + if (cp.width / cp.height) > (PrevPnl.Width / PrevPnl.Height) then + begin + PreviewImage.Width := pw; + r := cp.width / PreviewImage.Width; + PreviewImage.height := round(cp.height / r); + PreviewImage.Left := 1; + PreviewImage.Top := (ph - PreviewImage.Height) div 2; + end + else begin + PreviewImage.Height := ph; + r := cp.height / PreviewImage.height; + PreviewImage.Width := round(cp.Width / r); + PreviewImage.Top := 1; + PreviewImage.Left := (pw - PreviewImage.Width) div 2; + end; + cp.AdjustScale(PreviewImage.Width, PreviewImage.Height); + + cp.cmap := MainCp.cmap; + + if not PreviewOnly then begin //*** + +// zoom := MainForm.zoom; +// cp.zoom := zoom; + Resetting := True; // So the preview doesn't get drawn with these changes.. + scrollGamma.Position := trunc(cp.Gamma * 100); + scrollBrightness.Position := trunc(cp.Brightness * 100); + scrollVibrancy.Position := trunc(cp.vibrancy * 100); + scrollZoom.Position := trunc(cp.zoom * 1000); +// ScrollAngle.Position := Trunc(cp.FAngle * 18000.0 / PI) mod scrollAngle.Max; + scrollAngle.Position := Trunc(cp.FAngle * 18000.0 / PI) mod 36000; + + if (abs(cp.Center[0]) < 1000) and (abs(cp.Center[1]) < 1000) then begin + scrollCenterX.Position := trunc(cp.Center[0] * 1000); + scrollCenterY.Position := trunc(cp.Center[1] * 1000); + end else begin + scrollCenterX.Position := 0; + scrollCenterY.Position := 0; + end; + + ColorPanel.color := cp.background[2] shl 16 + cp.background[1] shl 8 + cp.background[0]; + Shape1.Brush.Color := ColorPanel.Color; + //cbColor.text := IntToHex(integer(ColorPanel.Color), 6); + + GetMainWindowSize; + + // gradient + if cp.cmapindex >= 0 then + cmbPalette.ItemIndex := cp.cmapindex; + ScrollBar.Position := 0; + Palette := cp.cmap; + BackupPal := cp.cmap; + + Resetting := False; + editPPU.Text := Format('%.6g', [100*cp.pixels_per_unit/PreviewImage.Width]); + + txtGammaThreshold.Text := Format('%.3g', [cp.gammaThreshRelative]); + + // 3d camera + txtPitch.Text := Format('%.6g', [cp.cameraPitch * 180 / PI]); + txtYaw.Text := Format('%.6g', [cp.cameraYaw * 180 / PI]); + txtPersp.Text := Format('%.6g', [cp.cameraPersp]); + txtZpos.Text := Format('%.6g', [cp.cameraZpos]); + txtDOF.Text := Format('%.6g', [cp.cameraDof]); + end; //*** + DrawPreview; +end; + +procedure TAdjustForm.UpdateFlame(bBgOnly: boolean = false); +begin + if not bBgOnly then + MainForm.StopThread; + MainForm.UpdateUndo; + MainCp.Copy(cp, true); + SetCurvesCp(cp); + + if EditForm.Visible then EditForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + if CurvesForm.Visible then CurvesForm.SetCp(cp); + + if bBgOnly then + MainForm.tbShowAlphaClick(Self) + else + MainForm.RedrawTimer.enabled := true; +end; + +procedure TAdjustForm.DrawPreview; +var + i: integer; + Row: pRGBTripleArray; + BitMap: TBitMap; +begin + if Resetting then exit; + + Render.Stop; +// AdjustScale(cp, PreviewImage.Width, PreviewImage.Height); + cp.sample_density := PreviewDensity; + cp.spatial_oversample := defOversample; + cp.spatial_filter_radius := defFilterRadius; +// cp.Zoom := Zoom; +// cp.center[0] := Center[0]; +// cp.center[1] := Center[1]; +// Render.Compatibility := compatibility; + Render.SetCP(cp); + Render.Render; + BM.Assign(Render.GetImage); + PreviewImage.Picture.Graphic := bm; + + if mnuInstantPreview.Checked then PreviewImage.Refresh; + +//--begin DrawPalette + BitMap := TBitMap.Create; + try + Bitmap.PixelFormat := pf24bit; + BitMap.Width := 256; + BitMap.Height := 1; + Row := Bitmap.Scanline[0]; + for i := 0 to 255 do + with Row[i] do + begin + rgbtRed := cp.cmap[i][0]; + rgbtGreen := cp.cmap[i][1]; + rgbtBlue := cp.cmap[i][2]; + end; + + GradientImage.Picture.Graphic := Bitmap; + GradientImage.Refresh; + finally + BitMap.Free; + end; +//--end DrawPalette +end; + +procedure TAdjustForm.FormCreate(Sender: TObject); +begin + mnuCopy.Caption := TextByKey('common-copy'); + mnuPaste.Caption := TextByKey('common-paste'); + btnApplySize.Caption := TextByKey('common-apply'); + mnuLowQuality.Caption := TextByKey('common-lowquality'); + mnuMediumQuality.Caption := TextByKey('common-mediumquality'); + mnuHighQuality.Caption := TextByKey('common-highquality'); + btnCopy.Hint := TextByKey('common-copy'); + btnPaste.Hint := TextByKey('common-paste'); + btnUndo.Hint := TextByKey('common-undo'); + btnRedo.Hint := TextByKey('common-redo'); + pnlWidth.Caption := TextByKey('common-width'); + pnlHeight.Caption := TextByKey('common-height'); + Label7.Caption := TextByKey('common-pixels'); + chkMaintain.Caption := TextByKey('common-keepaspect'); + pnlGamma.Caption := TextByKey('common-gamma'); + pnlBrightness.Caption := TextByKey('common-brightness'); + pnlVibrancy.Caption := TextByKey('common-vibrancy'); + pnlBackground.Caption := TextByKey('common-background'); + pnlGammaThreshold.Caption := TextByKey('common-gammathreshold'); + pnlDOF.Hint := TextByKey('common-dragpanelhint'); + pnlPitch.Hint := TextByKey('common-dragpanelhint'); + pnlYaw.Hint := TextByKey('common-dragpanelhint'); + pnlZpos.Hint := TextByKey('common-dragpanelhint'); + pnlPersp.Hint := TextByKey('common-dragpanelhint'); + pnlMasterScale.Hint := TextByKey('common-dragpanelhint'); + pnlZoom.Hint := TextByKey('common-dragpanelhint'); + pnlXpos.Hint := TextByKey('common-dragpanelhint'); + pnlYpos.Hint := TextByKey('common-dragpanelhint'); + pnlAngle.Hint := TextByKey('common-dragpanelhint'); + pnlGamma.Hint := TextByKey('common-dragpanelhint'); + pnlBrightness.Hint := TextByKey('common-dragpanelhint'); + pnlVibrancy.Hint := TextByKey('common-dragpanelhint'); + pnlGammaThreshold.Hint := TextByKey('common-dragpanelhint'); + self.Caption := TextByKey('adjustment-title'); + pnlDOF.Caption := TextByKey('adjustment-common-depthblur'); + pnlPitch.Caption := TextByKey('adjustment-common-pitch'); + pnlYaw.Caption := TextByKey('adjustment-common-yaw'); + pnlZpos.Caption := TextByKey('adjustment-common-height'); + pnlPersp.Caption := TextByKey('adjustment-common-perspective'); + pnlMasterScale.Caption := TextByKey('adjustment-common-scale'); + TabSheet1.Caption := TextByKey('adjustment-tab-camera-title'); + pnlZoom.Caption := TextByKey('adjustment-tab-camera-zoom'); + pnlXPos.Caption := TextByKey('adjustment-tab-camera-xpos'); + pnlYPos.Caption := TextByKey('adjustment-tab-camera-ypos'); + pnlAngle.Caption := TextByKey('adjustment-tab-camera-rotation'); + TabSheet2.Caption := TextByKey('adjustment-tab-rendering-title'); + chkTransparent.Caption := TextByKey('adjustment-tab-rendering-istransparent'); + TabSheet3.Caption := TextByKey('adjustment-tab-gradient-title'); + mnuRotate.Caption := TextByKey('adjustment-tab-gradient-moderotate'); + mnuHue.Caption := TextByKey('adjustment-tab-gradient-modehue'); + mnuSaturation.Caption := TextByKey('adjustment-tab-gradient-modesaturation'); + mnuBrightness.Caption := TextByKey('adjustment-tab-gradient-modebrightness'); + Contrast1.Caption := TextByKey('adjustment-tab-gradient-modecontrast'); + mnuBlur.Caption := TextByKey('adjustment-tab-gradient-modeblur'); + mnuFrequency.Caption := TextByKey('adjustment-tab-gradient-modefrequency'); + btnColorPreset.Caption := TextByKey('adjustment-tab-gradient-preset'); + btnReset.Caption := TextByKey('adjustment-tab-gradient-reset'); + btnMenu.Hint := TextByKey('adjustment-tab-gradient-modehint'); + btnPreset1.Hint := TextByKey('adjustment-tab-gradient-presethint'); + btnPreset2.Hint := TextByKey('adjustment-tab-gradient-presethint'); + btnPreset3.Hint := TextByKey('adjustment-tab-gradient-presethint'); + TabSheet4.Caption := TextByKey('adjustment-tab-size-title'); + btnPreset1.Caption := TextByKey('adjustment-tab-size-preset'); + btnPreset2.Caption := TextByKey('adjustment-tab-size-preset'); + btnPreset3.Caption := TextByKey('adjustment-tab-size-preset'); + TabSheet6.Caption := TextByKey('adjustment-tab-curves-title'); + btnResetCurves.Caption := TextByKey('adjustment-tab-curves-reset'); + Panel5.Caption := TextByKey('adjustment-tab-curves-selected'); + cbChannel.Items[0] := TextByKey('adjustment-tab-curves-overall'); + cbChannel.Items[1] := TextByKey('adjustment-tab-curves-red'); + cbChannel.Items[2] := TextByKey('adjustment-tab-curves-green'); + cbChannel.Items[3] := TextByKey('adjustment-tab-curves-blue'); + chkResizeMain.Caption := TextByKey('adjustment-tab-size-resizemain'); + mnuInstantPreview.Caption := TextByKey('adjustment-popup-quality-instantpreview'); + mnuRandomize.Caption := TextByKey('adjustment-popup-gradient-randomize'); + mnuInvert.Caption := TextByKey('adjustment-popup-gradient-invert'); + mnuReverse.Caption := TextByKey('adjustment-popup-gradient-reverse'); + mnuSmoothPalette.Caption := TextByKey('adjustment-popup-gradient-smooth'); + btnSmoothPalette.Hint := TextByKey('adjustment-popup-gradient-smooth'); + mnuGradientBrowser.Caption := TextByKey('adjustment-popup-gradient-browser'); + btnOpen.Hint := TextByKey('adjustment-popup-gradient-browser'); + SaveGradient1.Caption := TextByKey('adjustment-popup-gradient-saveasugr'); + SaveasMapfile1.Caption := TextByKey('adjustment-popup-gradient-saveasmap'); + mnuSaveAsDefault.Caption := TextByKey('adjustment-popup-gradient-saveasdefault'); + btnMenu.Caption := TextByKey('adjustment-tab-gradient-moderotate'); + + cbChannel.ItemIndex := 0; + + if not (assigned(curvesControl)) then + begin + CurvesControl := TCurvesControl.Create(self); + CurvesControl.Align := alClient; + CurvesControl.Parent := CurvesPanel; + end; + + tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10); + tbWeightRight.Position := Round(CurvesControl.WeightRight * 10); + + bm := TbitMap.Create; + cp := TControlPoint.Create; + Render := TRenderer.Create; + case AdjustPrevQual of + 0: begin + mnuLowQuality.Checked := true; + PreviewDensity := prevLowQuality; + end; + 1: begin + mnuMediumQuality.Checked := true; + PreviewDensity := prevMediumQuality; + end; + 2: begin + mnuHighQuality.Checked := true; + PreviewDensity := prevHighQuality; + end; + end; + + Sendmessage(cmbPalette.Handle, CB_SETDROPPEDWIDTH , cmbPalette.width * 2, 0); + SetCurvesCp(MainCp); +end; + +procedure TAdjustForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + Render.Stop; + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Adjust', True) then + begin + Registry.WriteInteger('Top', AdjustForm.Top); + Registry.WriteInteger('Left', AdjustForm.Left); + Registry.WriteBool('InstantPreview', mnuInstantPreview.Checked); + Registry.WriteBool('ResizeMain', chkResizeMain.Checked); + end; + finally + Registry.Free; + end; +// bStop := True; +end; + +procedure TAdjustForm.FormDestroy(Sender: TObject); +begin + bm.free; + cp.free; + Render.free; +end; + +procedure TAdjustForm.FormShow(Sender: TObject); +var + Registry: TRegistry; + i: integer; + strx, stry, strw, strh: string; +begin + if LimitVibrancy then scrollVibrancy.Max := 100 else scrollVibrancy.Max := 3000; + { Read posution from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Adjust', False) then + begin + if Registry.ValueExists('Left') then + AdjustForm.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + AdjustForm.Top := Registry.ReadInteger('Top'); + if Registry.ValueExists('InstantPreview') then + mnuInstantPreview.Checked := Registry.ReadBool('InstantPreview'); + if Registry.ValueExists('ResizeMain') then + chkResizeMain.Checked := Registry.ReadBool('ResizeMain'); + Registry.CloseKey; + end; + + if Registry.OpenKey('Software\' + APP_NAME + '\ImageSizePresets', False) then + begin + for i:=1 to 3 do begin + strx:='Preset'+IntToStr(i)+'Left'; + stry:='Preset'+IntToStr(i)+'Top'; + strw:='Preset'+IntToStr(i)+'Width'; + strh:='Preset'+IntToStr(i)+'Height'; + if Registry.ValueExists(strw) and Registry.ValueExists(strh) + then begin + Preset[i].Left := Registry.ReadInteger(strx); + Preset[i].Top := Registry.ReadInteger(stry); + Preset[i].Width := Registry.ReadInteger(strw); + Preset[i].Height := Registry.ReadInteger(strh); + if (Preset[1].Width>0) and (Preset[1].Height>0) then continue; + end; + Preset[i].Left := MainForm.Left; + Preset[i].Top := MainForm.Top; + Preset[i].Width := 512; + Preset[i].Height := 384; + end; + end + else + for i:=1 to 3 do begin + Preset[i].Left := MainForm.Left; + Preset[i].Top := MainForm.Top; + Preset[i].Width := 512; + Preset[i].Height := 384; + end; + Registry.CloseKey; + finally + Registry.Free; + end; + GetMainWindowSize; + + btnPreset1.Caption := PresetToStr(1); + btnPreset2.Caption := PresetToStr(2); + btnPreset3.Caption := PresetToStr(3); +end; + +procedure TAdjustForm.mnuLowQualityClick(Sender: TObject); +begin + mnuLowQuality.Checked := True; + PreviewDensity := prevLowQuality; + AdjustPrevQual := 0; + DrawPreview; +end; + +procedure TAdjustForm.mnuMediumQualityClick(Sender: TObject); +begin + mnuMediumQuality.Checked := True; + PreviewDensity := prevMediumQuality; + AdjustPrevQual := 1; + DrawPreview; +end; + +procedure TAdjustForm.mnuHighQualityClick(Sender: TObject); +begin + mnuHighQuality.Checked := True; + PreviewDensity := prevHighQuality; + AdjustPrevQual := 2; + DrawPreview; +end; + +procedure TAdjustForm.txtZoomEnter(Sender: TObject); +begin + EditBoxValue := txtZoom.Text; +end; + +procedure TAdjustForm.txtZoomKeyPress(Sender: TObject; var Key: Char); +var v: integer; +begin + if ((key = #13) and (EditBoxValue <> txtZoom.Text)) then + begin + key := #0; + txtZoomExit(sender); + end; +end; + +procedure TAdjustForm.txtZoomExit(Sender: TObject); +var + v: integer; +begin + if (EditBoxValue <> txtZoom.Text) then + try + v := Trunc(StrToFloat(txtZoom.Text) * 1000); + if v > scrollZoom.Max then v := scrollZoom.Max; + if v < scrollZoom.Min then v := scrollZoom.Min; + if v <> ScrollZoom.Position then begin + ScrollZoom.Position := v; + UpdateFlame; + end; + except on EConvertError do + txtZoom.Text := FloatToStr(cp.zoom) + end; +end; + +procedure TAdjustForm.txtCenterXEnter(Sender: TObject); +begin + EditBoxValue := txtCenterX.Text; +end; + +procedure TAdjustForm.txtCenterXKeyPress(Sender: TObject; var Key: Char); +var + v: integer; +begin + if ((key = #13) and (EditBoxValue <> txtCenterX.Text)) then + begin + key := #0; + txtCenterXExit(sender); + end; +end; + +procedure TAdjustForm.txtCenterXExit(Sender: TObject); +var + v: integer; +begin + if (EditBoxValue <> txtCenterX.Text) then + try + v := Trunc(StrToFloat(txtCenterX.Text) * 1000); + if v > scrollCenterX.Max then v := scrollCenterX.Max; + if v < scrollCenterX.Min then v := scrollCenterX.Min; + ScrollCenterX.Position := v; + UpdateFlame; + except on EConvertError do + txtCenterX.Text := FloatToStr(cp.center[0]); + end; +end; + +procedure TAdjustForm.txtCenterYEnter(Sender: TObject); +begin + EditBoxValue := txtCenterY.Text; +end; + +procedure TAdjustForm.txtCenterYKeyPress(Sender: TObject; var Key: Char); +var + v: integer; +begin + if ((key = #13) and (EditBoxValue <> txtCenterY.Text)) then + begin + key := #0; + txtCenterYExit(sender); + end; +end; + +procedure TAdjustForm.txtCenterYExit(Sender: TObject); +var + v: integer; +begin + if (EditBoxValue <> txtCenterY.Text) then + try + v := Trunc(StrToFloat(txtCenterY.Text) * 1000); + if v > ScrollCenterY.Max then v := ScrollCenterY.Max; + if v < ScrollCenterY.Min then v := ScrollCenterY.Min; + ScrollCenterY.Position := v; + UpdateFlame; + except on EConvertError do + txtCenterY.Text := FloatToStr(cp.center[1]); + end; +end; + +procedure TAdjustForm.txtGammaEnter(Sender: TObject); +begin + EditBoxValue := txtGamma.Text; +end; + +procedure TAdjustForm.txtGammaExit(Sender: TObject); +var + v: integer; +begin + if (txtGamma.Text <> EditBoxValue) then + try + v := Trunc(StrToFloat(txtGamma.Text) * 100); + if v > scrollGamma.Max then v := scrollGamma.Max; + if v < scrollGamma.Min then v := scrollGamma.Min; + ScrollGamma.Position := v; + UpdateFlame; + except on EConvertError do + txtGamma.Text := FloatToStr(cp.gamma); + end; +end; + +procedure TAdjustForm.txtGammaKeyPress(Sender: TObject; var Key: Char); +var + v: integer; +begin + if ((key = #13) and (txtGamma.Text <> EditBoxValue)) then + begin + key := #0; + txtGammaExit(sender); + end; +end; + +procedure TAdjustForm.txtBrightnessEnter(Sender: TObject); +begin + EditBoxValue := txtBrightness.Text; +end; + +procedure TAdjustForm.txtBrightnessExit(Sender: TObject); +var + v: integer; +begin + if (txtBrightness.Text <> EditBoxValue) then + try + v := Trunc(StrToFloat(txtBrightness.Text) * 100); + if v > scrollBrightness.Max then v := scrollBrightness.Max; + if v < scrollBrightness.Min then v := scrollBrightness.Min; + ScrollBrightness.Position := v; + UpdateFlame; + except on EConvertError do + txtBrightness.Text := FloatToStr(cp.brightness); + end; +end; + +procedure TAdjustForm.txtBrightnessKeyPress(Sender: TObject; + var Key: Char); +var + v: integer; +begin + if ((key = #13) and (txtBrightness.Text <> EditBoxValue)) then + begin + key := #0; + txtBrightnessExit(sender); + end; +end; + +procedure TAdjustForm.txtVibrancyEnter(Sender: TObject); +begin + EditBoxValue := txtVibrancy.Text; +end; + +procedure TAdjustForm.txtVibrancyKeyPress(Sender: TObject; var Key: Char); +var + v: integer; +begin + if ((key = #13) and (txtVibrancy.Text <> EditBoxValue)) then + begin + key := #0; + txtVibrancyExit(sender); + end; +end; + +procedure TAdjustForm.txtVibrancyExit(Sender: TObject); +var + v: integer; +begin + if (txtVibrancy.Text <> EditBoxValue) then + try + v := Trunc(StrToFloat(txtVibrancy.Text) * 100); + if v > scrollVibrancy.Max then v := scrollVibrancy.Max; + if v < scrollVibrancy.Min then v := scrollVibrancy.Min; + ScrollVibrancy.Position := v; + UpdateFlame; + except on EConvertError do + txtVibrancy.Text := FloatToStr(cp.Vibrancy); + end; +end; + +procedure TAdjustForm.scrollZoomScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; + (*if (ScrollPos<>0) then + AdjustForm.Height := 390 + else + AdjustForm.Height := 332; *) +end; + +procedure TAdjustForm.scrollCenterXScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; +end; + +procedure TAdjustForm.scrollCenterYScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; +end; + +procedure TAdjustForm.scrollGammaScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; +end; + +procedure TAdjustForm.scrollBrightnessScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; +end; + +procedure TAdjustForm.scrollVibrancyScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; +end; + +procedure TAdjustForm.scrollVibrancyChange(Sender: TObject); +begin + cp.Vibrancy := ScrollVibrancy.Position / 100; + txtVibrancy.text := FloatToStr(cp.Vibrancy); + txtVibrancy.Refresh; + DrawPreview; +end; + +procedure TAdjustForm.scrollGammaChange(Sender: TObject); +begin + cp.Gamma := scrollGamma.Position / 100; + txtGamma.text := FloatToStr(cp.Gamma); + txtGamma.Refresh; + DrawPreview; +end; + +procedure TAdjustForm.scrollBrightnessChange(Sender: TObject); +begin + cp.Brightness := ScrollBrightness.Position / 100; + txtBrightness.text := FloatToStr(cp.Brightness); + txtBrightness.Refresh; + DrawPreview; +end; + +procedure TAdjustForm.scrollZoomChange(Sender: TObject); +begin + cp.zoom := scrollZoom.Position / 1000; + txtZoom.text := FloatToStr(cp.zoom); + txtZoom.Refresh; + DrawPreview; +(* if (scrollZoom.Position<>0) then + AdjustForm.Height := 390 + else + AdjustForm.Height := 332; *) +end; + +procedure TAdjustForm.scrollCenterXChange(Sender: TObject); +begin + cp.center[0] := scrollCenterX.Position / 1000; + txtCenterX.text := FloatToStr(cp.center[0]); + txtCenterX.Refresh; + DrawPreview; +end; + +procedure TAdjustForm.scrollCenterYChange(Sender: TObject); +begin + cp.center[1] := scrollCenterY.Position / 1000; + txtCenterY.text := FloatToStr(cp.center[1]); + txtCenterY.Refresh; + DrawPreview; +end; + +procedure TAdjustForm.ColorPanelClick(Sender: TObject); +var + col: Longint; +begin + ColorDialog.Color := COlorPanel.Color; + if ColorDialog.Execute then + begin + ColorPanel.Color := ColorDialog.Color; + Shape1.Brush.Color := ColorPanel.Color; + //cbColor.text := IntToHex(integer(ColorDialog.Color), 6); + col := ColorToRGB(ColorDialog.Color); + cp.background[0] := col and 255; + cp.background[1] := col shr 8 and 255; + cp.background[2] := col shr 16 and 255; + DrawPreview; + UpdateFlame(true); + end; +end; + +procedure TAdjustForm.curveChange(Sender: TObject); +begin + if CurvesControl = nil then Exit; + CurvesControl.ActiveChannel := TCurvesChannel(cbChannel.ItemIndex); + tbWeightLeft.Position := Round(cp.curveWeights[cbChannel.ItemIndex][1] * 10); //Round(CurvesControl.WeightLeft * 10); + tbWeightRight.Position := Round(cp.curveWeights[cbChannel.ItemIndex][2] * 10); //Round(CurvesControl.WeightRight * 10); +end; + +procedure TAdjustForm.scrollContrastScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; +end; + +procedure TAdjustForm.scrollAngleChange(Sender: TObject); +begin + cp.FAngle := scrollAngle.Position * PI / 18000.0; + txtAngle.text := FloatToStr(cp.FAngle * 180 / PI); + txtAngle.Refresh; + DrawPreview; +end; + +procedure TAdjustForm.scrollAngleScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then UpdateFlame; +end; + +procedure TAdjustForm.txtAngleEnter(Sender: TObject); +begin + EditBoxValue := txtAngle.Text; +end; + +procedure TAdjustForm.txtAngleKeyPress(Sender: TObject; var Key: Char); +var + v: integer; +begin + if ((key = #13) and (txtAngle.Text <> EditBoxValue)) then + begin + key := #0; + try + v := Trunc(StrToFloat(txtAngle.Text) * 100) mod scrollAngle.Max; + //if v > scrollAngle.Max then v := v - scrollAngle.Max*2 + if v < scrollAngle.Min then v := v + scrollAngle.Max; + ScrollAngle.Position := v; + UpdateFlame; + EditBoxValue := txtAngle.Text; + except on EConvertError do + end; + end; +end; + +procedure TAdjustForm.txtAngleExit(Sender: TObject); +var + v: integer; +begin + if (txtAngle.Text <> EditBoxValue) then + try + v := Trunc(StrToFloat(txtAngle.Text) * 100) mod scrollAngle.Max; +// if v > scrollAngle.Max then v := v - scrollAngle.Max*2 +// else if v < scrollAngle.Min then v := v + scrollAngle.Max*2; + ScrollAngle.Position := v; + UpdateFlame; + except on EConvertError do + txtAngle.Text := FloatToStr(cp.FAngle * 180 / PI); + end; +end; + +// --Z-- // gradient stuff implementation -------------------------------------- + +procedure TAdjustForm.Apply; +begin + MainForm.StopThread; + MainForm.UpdateUndo; + + MainCp.CmapIndex := cmbPalette.ItemIndex; + MainCp.cmap := Palette; + SetCurvesCp(MainCp); + + if EditForm.visible then EditForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + if CurvesForm.Visible then CurvesForm.SetCp(MainCp); + + if mnuInstantPreview.Checked then DrawPreview; + + MainForm.RedrawTimer.enabled := true; +end; + +procedure TAdjustForm.SaveMap(FileName: string); +var + i: Integer; + l: string; + MapFile: TextFile; +begin +{ Save a map file } + AssignFile(MapFile, FileName); + try + ReWrite(MapFile); + { first line with comment } + l := Format(' %3d %3d %3d Exported from Apophysis 2.0', [Palette[0][0], palette[0][1], + palette[0][2]]); + Writeln(MapFile, l); + { now the rest } + for i := 1 to 255 do + begin + l := Format(' %3d %3d %3d', [Palette[i][0], palette[i][1], + palette[i][2]]); + Writeln(MapFile, l); + end; + CloseFile(MapFile); + except + on EInOutError do Application.MessageBox(PChar(Format(TextByKey('common-genericopenerror'), [FileName])), 'Apophysis', 16); + end; +end; + +procedure TAdjustForm.UpdateGradient(Pal: TColorMap); +begin + ScrollBar.Position := 0; + + Palette := Pal; + BackupPal := Pal; +// DrawPalette; + + cp.cmap := pal; +// cp.copy(MainCp); + + if mnuInstantPreview.Checked then DrawPreview; +end; + +procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer); +var + R, G, B, Sa, Va, Hue, i, f, p, q, t: real; +begin + R := 0; + G := 0; + B := 0; + Sa := S / 100; + Va := V / 100; + if S = 0 then + begin + R := Va; + G := Va; + B := Va; + end + else + begin + Hue := H / 60; + if Hue = 6 then Hue := 0; + i := Int(Hue); + f := Hue - i; + p := Va * (1 - Sa); + q := Va * (1 - (Sa * f)); + t := Va * (1 - (Sa * (1 - f))); + case Round(i) of + 0: begin + R := Va; + G := t; + B := p; + end; + 1: begin + R := q; + G := Va; + B := p; + end; + 2: begin + R := p; + G := Va; + B := t; + end; + 3: begin + R := p; + G := q; + B := Va; + end; + 4: begin + R := t; + G := p; + B := Va; + end; + 5: begin + R := Va; + G := p; + B := q; + end; + end; + end; + Rb := Round(Int(255.9999 * R)); + Gb := Round(Int(255.9999 * G)); + Bb := Round(Int(255.9999 * B)); +end; + +procedure RGBToHSV(R, G, B: byte; var H, S, V: real); +var + vRed, vGreen, vBlue, Mx, Mn, Va, Sa, rc, gc, bc: real; +begin + vRed := R / 255; + vGreen := G / 255; + vBlue := B / 255; + Mx := vRed; + if vGreen > Mx then Mx := vGreen; + if vBlue > Mx then Mx := vBlue; + Mn := vRed; + if vGreen < Mn then Mn := vGreen; + if vBlue < Mn then Mn := vBlue; + Va := Mx; + if Mx <> 0 then + Sa := (Mx - Mn) / Mx + else + Sa := 0; + if Sa = 0 then + H := 0 + else + begin + rc := (Mx - vRed) / (Mx - Mn); + gc := (Mx - vGreen) / (Mx - Mn); + bc := (Mx - vBlue) / (Mx - Mn); + if Mx = vRed then + H := bc - gc + else if Mx = vGreen then + H := 2 + rc - bc + else if Mx = vBlue then + H := 4 + gc - rc; + H := H * 60; + if H < 0 then H := H + 360; + end; + S := Sa * 100; + V := Va * 100; +end; + +function TAdjustForm.Blur(const Radius: Integer; const pal: TColorMap): TColorMap; +var + r, g, b, n, i, j, k: Integer; +begin + Result := Pal; + if Radius <> 0 then + for i := 0 to 255 do + begin + n := -1; + r := 0; + g := 0; + b := 0; + for j := i - radius to i + radius do + begin + inc(n); + k := (256 + j) mod 256; + if k <> i then begin + r := r + Pal[k][0]; + g := g + Pal[k][1]; + b := b + Pal[k][2]; + end; + end; + if n <> 0 then begin + Result[i][0] := r div n; + Result[i][1] := g div n; + Result[i][2] := b div n; + end; + end; +end; + +function TAdjustForm.Frequency(const times: Integer; const pal: TColorMap): TColorMap; +{ This can be improved } +var + n, i, j: Integer; +begin + Result := Pal; + if times <> 1 then + begin + n := 256 div times; + for j := 0 to times do + for i := 0 to n do + begin + if (i + j * n) < 256 then + begin + Result[i + j * n][0] := pal[i * times][0]; + Result[i + j * n][1] := pal[i * times][1]; + Result[i + j * n][2] := pal[i * times][2]; + end; + end; + end; +end; + +procedure TAdjustForm.cmbPaletteChange(Sender: TObject); +var + i: integer; +begin + if Resetting then exit; + + i := cmbPalette.ItemIndex; + GetCmap(i, 1, Palette); + BackupPal := Palette; + ScrollBar.Position := 0; + //DrawPalette; +// MainForm.UpdateUndo; + Apply; +end; + +procedure TAdjustForm.mnuReverseClick(Sender: TObject); +var + i: integer; + pal: TColorMap; +begin + for i := 0 to 255 do begin + pal[i][0] := Palette[255 - i][0]; + pal[i][1] := Palette[255 - i][1]; + pal[i][2] := Palette[255 - i][2]; + end; + UpdateGradient(pal); +// MainForm.UpdateUndo; + Apply; +end; + +procedure TAdjustForm.mnuInvertClick(Sender: TObject); +var + i: integer; +begin + for i := 0 to 255 do + begin + Palette[i][0] := 255 - Palette[i][0]; + Palette[i][1] := 255 - Palette[i][1]; + Palette[i][2] := 255 - Palette[i][2]; + end; + UpdateGradient(palette); +// MainForm.UpdateUndo; + Apply; +end; + +procedure TAdjustForm.btnMenuClick(Sender: TObject); +begin + scrollModePopup.Popup(btnMenu.ClientOrigin.x, btnMenu.ClientOrigin.y + btnMenu.Height); +end; + +procedure TAdjustForm.ScrollBarChange(Sender: TObject); +var + intens, i, r, g, b: integer; + h, s, v: real; +begin + lblVal.Caption := IntToStr(ScrollBar.Position); + txtVal.Text := IntToStr(ScrollBar.Position); + lblVal.Refresh; + txtVal.Refresh; + + if Resetting then exit; + + GradientChanged:=true; // hmm + + case scrollMode of + modeHue: + for i := 0 to 255 do + begin + RGBToHSV(BackupPal[i][0], BackupPal[i][1], BackupPal[i][2], h, s, v); + if s <> 0 then // --Z-- //(?) + begin + h := Round(360 + h + ScrollBar.Position) mod 360; + HSVToRGB(h, s, v, Palette[i][0], Palette[i][1], Palette[i][2]); + end; + end; + modeSaturation: + for i := 0 to 255 do + begin + RGBToHSV(BackupPal[i][0], BackupPal[i][1], BackupPal[i][2], h, s, v); + if s <> 0 then // --Z-- //(?) + begin + s := s + ScrollBar.Position; + if s > 100 then s := 100; + if s < 0 then s := 0; + HSVToRGB(h, s, v, Palette[i][0], Palette[i][1], Palette[i][2]); + end; + end; + modeContrast: + begin + intens := scrollBar.Position; + if intens > 0 then intens := intens * 2; + for i := 0 to 255 do + begin + r := BackupPal[i][0]; + g := BackupPal[i][1]; + b := BackupPal[i][2]; + r := round(r + intens / 100 * (r - 127)); + g := round(g + intens / 100 * (g - 127)); + b := round(b + intens / 100 * (b - 127)); + if R > 255 then R := 255 else if R < 0 then R := 0; + if G > 255 then G := 255 else if G < 0 then G := 0; + if B > 255 then B := 255 else if B < 0 then B := 0; + Palette[i][0] := r; + Palette[i][1] := g; + Palette[i][2] := b; + end; + end; + modeBrightness: + for i := 0 to 255 do + begin + Palette[i][0] := BackupPal[i][0] + ScrollBar.Position; + if Palette[i][0] > 255 then Palette[i][0] := 255; + if Palette[i][0] < 0 then Palette[i][0] := 0; + Palette[i][1] := BackupPal[i][1] + ScrollBar.Position; + if Palette[i][1] > 255 then Palette[i][1] := 255; + if Palette[i][1] < 0 then Palette[i][1] := 0; + Palette[i][2] := BackupPal[i][2] + ScrollBar.Position; + if Palette[i][2] > 255 then Palette[i][2] := 255; + if Palette[i][2] < 0 then Palette[i][2] := 0; + end; + modeRotate: + for i := 0 to 255 do + begin + Palette[i][0] := BackupPal[(256 + i - ScrollBar.Position) mod 256][0]; + Palette[i][1] := BackupPal[(256 + i - ScrollBar.Position) mod 256][1]; + Palette[i][2] := BackupPal[(256 + i - ScrollBar.Position) mod 256][2]; + end; + modeBlur: + Palette := Blur(ScrollBar.Position, BackupPal); + modeFrequency: + Palette := Frequency(ScrollBar.Position, BackupPal); + end; + + cp.cmap:=Palette; + DrawPreview; +end; + +procedure TAdjustForm.ScrollBarScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then + begin + GradientChanged:=false; + Apply; + end; +end; + +{ ***************************** Adjust menu ********************************* } + +procedure TAdjustForm.mnuRotateClick(Sender: TObject); +begin + btnMenu.Caption := TextByKey('adjustment-tab-gradient-moderotate'); + scrollMode:=modeRotate; + + BackupPal := Palette; + ScrollBar.Min := -128; + ScrollBar.Max := 128; + ScrollBar.LargeChange := 16; + ScrollBar.Position := 0; +end; + +procedure TAdjustForm.mnuHueClick(Sender: TObject); +begin + btnMenu.Caption := TextByKey('adjustment-tab-gradient-modehue'); + scrollMode:=modeHue; + + BackupPal := Palette; + ScrollBar.Min := -180; + ScrollBar.Max := 180; + ScrollBar.LargeChange := 15; + ScrollBar.Position := 0; +end; + +procedure TAdjustForm.mnuSaturationClick(Sender: TObject); +begin + btnMenu.Caption := TextByKey('adjustment-tab-gradient-modesaturation'); + scrollMode:=modeSaturation; + + BackupPal := Palette; + ScrollBar.Min := -100; + ScrollBar.Max := 100; + ScrollBar.LargeChange := 15; + ScrollBar.Position := 0; +end; + +procedure TAdjustForm.mnuBrightnessClick(Sender: TObject); +begin + btnMenu.Caption := TextByKey('adjustment-tab-gradient-modebrightness'); + scrollMode:=modeBrightness; + + BackupPal := Palette; + ScrollBar.Min := -255; + ScrollBar.Max := 255; + ScrollBar.LargeChange := 15; + ScrollBar.Position := 0; +end; + +procedure TAdjustForm.mnuContrastClick(Sender: TObject); +begin + btnMenu.Caption := TextByKey('adjustment-tab-gradient-modecontrast'); + scrollMode := modeContrast; + BackupPal := Palette; + + ScrollBar.Min := -100; + ScrollBar.Max := 100; + ScrollBar.LargeChange := 15; + ScrollBar.Position := 0; +end; + +procedure TAdjustForm.mnuBlurClick(Sender: TObject); +begin + btnMenu.Caption := TextByKey('adjustment-tab-gradient-modeblur'); + scrollMode:=modeBlur; + + BackupPal := Palette; + ScrollBar.Min := 0; + ScrollBar.Max := 127; + ScrollBar.LargeChange := 15; + ScrollBar.Position := 0; +end; + +procedure TAdjustForm.mnuFrequencyClick(Sender: TObject); +begin + btnMenu.Caption := TextByKey('adjustment-tab-gradient-modefrequency'); + scrollMode:=modeFrequency; + + BackupPal := Palette; + ScrollBar.Min := 1; + ScrollBar.Max := 10; + ScrollBar.LargeChange := 1; + ScrollBar.Position := 1; +end; + +// ----------------------------------------------------------------------------- + +procedure TAdjustForm.btnOpenClick(Sender: TObject); +begin + GradientBrowser.Filename := GradientFile; + GradientBrowser.Show; +end; + +procedure TAdjustForm.mnuSmoothPaletteClick(Sender: TObject); +begin + MainForm.SmoothPalette; +end; + +procedure TAdjustForm.SaveGradient1Click(Sender: TObject); +var + gradstr: TStringList; +begin + gradstr := TStringList.Create; + try + SaveForm.SaveType := stSaveGradient; + SaveForm.Filename := GradientFile; + SaveForm.Title := MainCp.name; + if SaveForm.ShowModal = mrOK then + begin + gradstr.add(CleanIdentifier(SaveForm.Title) + ' {'); + gradstr.add(MainForm.GradientFromPalette(Palette, SaveForm.Title)); + gradstr.add('}'); + if MainForm.SaveGradient(gradstr.text, SaveForm.Title, SaveForm.Filename) then + GradientFile := SaveForm.FileName; + end; + finally + gradstr.free + end; +end; + +procedure TAdjustForm.SaveasMapfile1Click(Sender: TObject); +begin + SaveDialog.Filename := MainCp.name + '.map'; + SaveDialog.Filter := Format('%s|*.map|%s|*.*', [ + TextByKey('common-filter-fractintfiles'), + TextByKey('common-filter-allfiles')]); + if SaveDialog.execute then + SaveMap(SaveDialog.Filename); +end; + +procedure TAdjustForm.cmbPaletteDrawItem(Control: TWinControl; + Index: Integer; Rect: TRect; State: TOwnerDrawState); +var + i, j: integer; + Row: pRGBTripleArray; + Bitmap: TBitmap; + pal: TColorMap; + PalName: string; +begin +{ Draw the preset palettes on the combo box items } + GetCMap(index, 1, pal); + GetCmapName(index, PalName); + + BitMap := TBitMap.create; + Bitmap.PixelFormat := pf24bit; + BitMap.Width := 256; + BitMap.Height := 100; + + for j := 0 to Bitmap.Height - 1 do + begin + Row := Bitmap.Scanline[j]; + for i := 0 to Bitmap.Width - 1 do + begin + with Row[i] do + begin + rgbtRed := Pal[i][0]; + rgbtGreen := Pal[i][1]; + rgbtBlue := Pal[i][2]; + end + end + end; + with Control as TComboBox do + begin + Canvas.Rectangle(Rect); + + Canvas.TextOut(4, Rect.Top, PalName); + Rect.Left := (Rect.Left + rect.Right) div 2; + Canvas.StretchDraw(Rect, Bitmap); + end; + BitMap.Free; +end; + +procedure TAdjustForm.btnCopyClick(Sender: TObject); +var + gradstr: TStringList; +begin + gradstr := TStringList.Create; + try + gradstr.add(CleanIdentifier(MainCp.name) + ' {'); + gradstr.add('gradient:'); + gradstr.add(' title="' + MainCp.name + '" smooth=no'); + gradstr.add(GradientString(Palette)); + gradstr.add('}'); + Clipboard.SetTextBuf(PChar(gradstr.text)); + btnPaste.enabled := true; + mnuPaste.enabled := true; +//z MainForm.btnPaste.enabled := False; + MainForm.mnuPaste.enabled := False; + finally + gradstr.free + end; +end; + +procedure TAdjustForm.btnPasteClick(Sender: TObject); +begin + if Clipboard.HasFormat(CF_TEXT) then + begin + UpdateGradient(CreatePalette(Clipboard.AsText)); +// MainForm.UpdateUndo; + Apply; + end; +end; + +function GradientInClipboard: boolean; +var + gradstr: TStringList; +begin + { returns true if gradient in clipboard - can be tricked } + result := true; + if Clipboard.HasFormat(CF_TEXT) then + begin + gradstr := TStringList.Create; + try + gradstr.text := ''; + try + gradstr.text := Clipboard.AsText; + finally + end; + if (Pos('}', gradstr.text) = 0) or (Pos('{', gradstr.text) = 0) or + (Pos('gradient:', gradstr.text) = 0) or (Pos('fractal:', gradstr.text) <> 0) then + begin + result := false; + exit; + end; + finally + gradstr.free; + end; + end + else + result := false; +end; + +procedure TAdjustForm.ApplicationEventsActivate(Sender: TObject); +begin + if GradientInClipboard then begin + mnuPaste.enabled := true; + btnPaste.enabled := true; + end + else + begin + mnuPaste.enabled := false; + btnPaste.enabled := false; + end; +end; + +procedure TAdjustForm.mnuSaveasDefaultClick(Sender: TObject); +begin + DefaultPalette := Palette; + SaveMap(AppPath + 'default.map'); +end; + +procedure TAdjustForm.mnuRandomizeClick(Sender: TObject); +begin + UpdateGradient(GradientHelper.RandomGradient); + Apply; +end; + +procedure TAdjustForm.GradientImageDblClick(Sender: TObject); +begin + mnuRandomizeClick(Sender); +end; + +procedure TAdjustForm.GradImageMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if Button = mbLeft then + begin + dragX:=x; + oldX:=x; // hmmm + oldpos := ( ((x) shl 8) div GradientImage.Width) mod 256; +if oldpos = 0 then oldpos := 1; + tmpBackupPal := BackupPal; + if ssCtrl in Shift then + imgDragMode := imgDragStretch + else + imgDragMode := imgDragRotate; + GradientChanged:=false; + end; +end; + +procedure TAdjustForm.GradImageMouseMove(Sender: TObject; + Shift: TShiftState; X, Y: Integer); + procedure StretchGradient(i0, i1, j0, j1: integer); + var + k, f: double; + i, j, jj, n: integer; + begin + k := (j1 - j0) / (i1 - i0); + + if k >= 1 then + begin + for i := i0 to i1-1 do + begin + j := j0 + round((i - i0) * k); + +assert(j >= 0); +assert(j < 256); + + cp.cmap[i] := Palette[j]; + BackupPal[i] := tmpBackupPal[j]; //? + end; + end + else begin + for i := i0 to i1-1 do + begin + f := (i - i0) * k; + j := j0 + trunc(f); + f := frac(f); + +assert(j >= 0); +assert(j < 256); + + if j < 255 then jj := j + 1 + else jj := 0; + for n := 0 to 2 do begin + cp.cmap[i][n] := round( Palette[j][n]*(1-f) + Palette[jj][n]*f ); + BackupPal[i][n] := round( tmpBackupPal[j][n]*(1-f) + tmpBackupPal[jj][n]*f ); //? + end; + end; + end; + end; +var + i, j: integer; + k: double; +begin + if (imgDragMode <> imgDragNone) and (oldX<>x) then + begin + oldX:=x; + offset := ( ((x - dragX) shl 8) div GradientImage.Width) mod 256; + txtVal.Text:=IntToStr(offset); + txtVal.Refresh; + //ScrollBar.Position := offset; + GradientChanged := true; + + if imgDragmode = imgDragRotate then begin + for i := 0 to 255 do + begin + cp.cmap[i] := Palette[(256 + i - offset) and $FF]; + + BackupPal[i] := tmpBackupPal[(256 + i - offset) and $FF]; + end; + end + else begin + offset := ( (x shl 8) div GradientImage.Width); + if offset <= 0 then offset := 1 + else if offset > 255 then offset := 255; + + StretchGradient(0, offset, 0, oldpos); + StretchGradient(offset, 256, oldpos, 256); + end; + + DrawPreview; + end; +end; + +procedure TAdjustForm.GradImageMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if imgDragMode <> imgDragNone then + begin + imgDragMode := imgDragNone; + //lblOffset.Caption:=''; + txtVal.Text := '0'; + + Palette := cp.cmap; + + if GradientChanged then Apply; + end; +end; + +// --Z-- // image size functions ----------------------------------------------- + +function TAdjustForm.PresetToStr(n: integer): string; +begin + Result:=IntToStr(Preset[n].Width) + ' x ' + IntToStr(Preset[n].Height) +end; + +procedure TAdjustForm.ReadPreset(n: integer); +begin + ImageWidth := Preset[n].Width; + ImageHeight := Preset[n].Height; + txtWidth.Text := IntToStr(ImageWidth); + txtHeight.Text := IntToStr(ImageHeight); + + if chkResizeMain.Checked then begin + MainForm.Left:=Preset[n].Left; + MainForm.Top:=Preset[n].Top; + end; + + SetMainWindowSize; +end; + +procedure TAdjustForm.WeightChange(Sender: TObject); +begin + CurvesControl.WeightLeft := tbWeightLeft.Position / 10.0; + CurvesControl.WeightRight := tbWeightRight.Position / 10.0; + + cp.curveWeights[cbChannel.ItemIndex][1] := tbWeightLeft.Position / 10.0; + cp.curveWeights[cbChannel.ItemIndex][2] := tbWeightRight.Position / 10.0; + + DrawPreview; +end; + +procedure TAdjustForm.WeightScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); +begin + if ScrollCode <> scEndScroll then Exit; + + MainForm.StopThread; + MainForm.UpdateUndo; + MainCp.Copy(cp, true); + + if EditForm.Visible then EditForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + if CurvesForm.Visible then CurvesForm.SetCp(cp); + + MainForm.RedrawTimer.enabled := true; +{ if ScrollCode = scEndScroll then + CurvesControl.UpdateFlame; } +end; + +procedure TAdjustForm.WritePreset(n: integer); +var + Registry: TRegistry; + w,h: integer; +begin + // Write preset to registry + Registry := TRegistry.Create; + try + w:=StrToInt(txtWidth.text); + h:=StrToInt(txtHeight.text); + if (w>0) and (h>0) then begin + Preset[n].Left:=MainForm.Left; + Preset[n].Top:=MainForm.Top; + Preset[n].Width:=w; + Preset[n].Height:=h; + end + else exit; + + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\ImageSizePresets', True) then + begin + Registry.WriteInteger('Preset'+IntToStr(n)+'Left', Preset[n].Left); + Registry.WriteInteger('Preset'+IntToStr(n)+'Top', Preset[n].Top); + Registry.WriteInteger('Preset'+IntToStr(n)+'Width', Preset[n].Width); + Registry.WriteInteger('Preset'+IntToStr(n)+'Height', Preset[n].Height); + end; + except + end; +end; + +function IsNumeric(s: string): boolean; +var + i: integer; + start:integer; +begin + Result := True; + s := trim(s); + if Length(s) = 0 then begin + result := false; + exit; + end; + + start := 1; + if (s[1] = '-') then + start := 2; + + for i:=start to length(s) do + if not (CharInSet(s[i],['0'..'9'])) then + begin + Result := False; + exit; + end; +end; + +procedure TAdjustForm.txtValExit(Sender: TObject); +begin + if (not IsNumeric(txtVal.Text)) then begin + { It's not, so we restore the old value } + txtVal.Text := IntToStr(ScrollBar.Position); + exit; + end; + + ScrollBar.Position := StrToInt(Trim(txtVal.Text)); + txtVal.Text := Trim(txtVal.Text); + + UpdateFlame; +end; + +procedure TAdjustForm.txtSizeKeyPress(Sender: TObject; var Key: Char); +begin + if key = #13 then + begin + key := #0; + SetMainWindowSize; + end; +end; + +procedure TAdjustForm.chkMaintainClick(Sender: TObject); +begin + Ratio := ImageWidth / ImageHeight; +end; + +procedure TAdjustForm.SetMainWindowSize; +var + l, t, w, h: integer; +begin + MainCp.AdjustScale(ImageWidth, ImageHeight); + MainForm.ResizeImage; //? + + if chkResizeMain.Checked then begin + l := MainForm.Left; + t := MainForm.Top; + w := ImageWidth + MainForm.Width - (MainForm.BackPanel.Width - 2); + h := ImageHeight + MainForm.Height - (MainForm.BackPanel.Height - 2); + if w > Screen.Width then + begin + l := 0; + w := Screen.width; + end; + if h > Screen.height then + begin + t := 0; + h := Screen.height; + end; + + MainForm.SetBounds(l, t, w, h); + end; + MainForm.RedrawTimer.Enabled := true; +end; + +procedure TAdjustForm.GetMainWindowSize; +begin + ImageWidth := MainCP.Width; + ImageHeight := MainCP.Height; + txtWidth.text := IntToStr(ImageWidth); + txtHeight.text := IntToStr(ImageHeight); +end; + +procedure TAdjustForm.btnSet1Click(Sender: TObject); +begin + WritePreset(1); + btnPreset1.Caption := PresetToStr(1); + SetMainWindowSize; +end; + +procedure TAdjustForm.btnSet2Click(Sender: TObject); +begin + WritePreset(2); + btnPreset2.Caption := PresetToStr(2); + SetMainWindowSize; +end; + +procedure TAdjustForm.btnSet3Click(Sender: TObject); +begin + WritePreset(3); + btnPreset3.Caption := PresetToStr(3); + SetMainWindowSize; +end; + +procedure TAdjustForm.btnPreset1Click(Sender: TObject); +begin + ReadPreset(1); +end; + +procedure TAdjustForm.btnPreset2Click(Sender: TObject); +begin + ReadPreset(2); +end; + +procedure TAdjustForm.btnPreset3Click(Sender: TObject); +begin + ReadPreset(3); +end; + +procedure TAdjustForm.txtWidthChange(Sender: TObject); +begin + try + ImageWidth := StrToInt(txtWidth.Text); + if chkMaintain.checked and txtWidth.Focused then + begin + ImageHeight := Round(ImageWidth / ratio); + txtHeight.Text := IntToStr(ImageHeight) + end; + except + end; +end; + +procedure TAdjustForm.txtHeightChange(Sender: TObject); +begin + try + ImageHeight := StrToInt(txtHeight.Text); + if chkMaintain.checked and txtHeight.Focused then + begin + ImageWidth := Round(ImageHeight * ratio); + txtWidth.Text := IntToStr(ImageWidth) + end; + except + end; +end; + +procedure TAdjustForm.btnUndoClick(Sender: TObject); +begin + MainForm.Undo; +end; + +procedure TAdjustForm.btnRedoClick(Sender: TObject); +begin + MainForm.Redo; +end; + +procedure TAdjustForm.btnColorPresetClick(Sender: TObject); +begin + cmbPalette.ItemIndex := Random(NRCMAPS); + cmbPaletteChange(Sender); +end; + +procedure TAdjustForm.btnApplySizeClick(Sender: TObject); +begin + SetMainWindowSize; +end; + +procedure TAdjustForm.mnuInstantPreviewClick(Sender: TObject); +begin + mnuInstantPreview.Checked := not mnuInstantPreview.Checked; +end; + +procedure TAdjustForm.editPPUKeyPress(Sender: TObject; var Key: Char); +begin + if key=#13 then + begin + key := #0; + editPPUValidate(Sender); + end; +end; + +procedure TAdjustForm.editPPUValidate(Sender: TObject); +var + v: double; +begin + try + v := strtofloat(editPPU.Text); + except + exit; + end; + v := v/100*PreviewImage.Width; + if (v > 0) and (cp.pixels_per_unit <> v) then begin + MainForm.UpdateUndo; + cp.pixels_per_unit := v; + UpdateFlame; + end; +end; + +// ----------------------------------------------------------------------------- + +procedure TAdjustForm.DragPanelMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +var enableDrag : boolean ; +begin + if Button <> mbLeft then exit; + + enableDrag := true; + if (Sender = pnlMasterScale) then + pnlDragValue := cp.pixels_per_unit / PreviewImage.Width + else if (Sender = pnlZoom) then + pnlDragValue := cp.zoom + else if (Sender = pnlXpos) then + pnlDragValue := cp.Center[0] + else if (Sender = pnlYpos) then + pnlDragValue := cp.Center[1] + else if (Sender = pnlAngle) then + pnlDragValue := cp.FAngle + else if (Sender = pnlGamma) then + pnlDragValue := cp.gamma + else if (Sender = pnlBrightness) then + pnlDragValue := cp.brightness + else if (Sender = pnlVibrancy) then + pnlDragValue := cp.vibrancy + // 3d camera controls + else if (Sender = pnlPitch) then + pnlDragValue := cp.cameraPitch * 180.0 / PI + else if (Sender = pnlYaw) then + pnlDragValue := cp.cameraYaw * 180.0 / PI + else if (Sender = pnlPersp) then + pnlDragValue := cp.cameraPersp + else if (Sender = pnlZpos) then + pnlDragValue := cp.cameraZpos + else if (Sender = pnlDOF) then + pnlDragValue := cp.cameraDOF + else if (Sender = pnlGammaThreshold) then + pnlDragValue := cp.gammaThreshRelative + else enableDrag := false; //assert(false)}; + + if enableDrag then begin + pnlDragMode := true; + pnlDragPos := 0; + pnlDragOld := x; + pnlMM := false; + //SetCaptureControl(TControl(Sender)); + + Screen.Cursor := crHSplit; + //GetCursorPos(mousepos); // hmmm + mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); + pnlDragged := false; + end; +end; + +procedure TAdjustForm.DragPanelMouseMove(Sender: TObject; Shift: TShiftState; + X, Y: Integer); +var + sc, v: double; +begin + if pnlMM then // hack: to skip MouseMove event + begin + pnlMM:=false; + end + else + if pnlDragMode and (x <> pnlDragOld) then + begin + Inc(pnlDragPos, x - pnlDragOld); + + if GetKeyState(VK_MENU) < 0 then sc := 100000 + else if GetKeyState(VK_CONTROL) < 0 then sc := 10000 + else if GetKeyState(VK_SHIFT) < 0 then sc := 100 + else sc := 1000; + + if (Sender = pnlPitch) or (Sender = pnlYaw) then sc := sc / 50 + else if Sender = pnlPersp then sc := sc * 10; + + v := Round6(pnlDragValue + pnlDragPos / sc); + + SetCursorPos(MousePos.x, MousePos.y); // hmmm + pnlMM:=true; + + if (Sender = pnlMasterScale) then + begin + v := Round6(pnlDragValue * power(2, pnlDragPos / sc / 2)); + if v <= 0.0001 then v := 0.0001; + cp.pixels_per_unit := v*PreviewImage.Width; + editPPU.Text := FloatToStr(v*100); + end + else if (Sender = pnlZoom) then + begin + scrollZoom.Position := trunc(v * 1000); + end + else if (Sender = pnlXpos) then + begin + scrollCenterX.Position := trunc(v * 1000); + end + else if (Sender = pnlYpos) then + begin + scrollCenterY.Position := trunc(v * 1000); + end + else if (Sender = pnlAngle) then + begin + scrollAngle.Position := Trunc(v * 18000.0 / PI) mod 36000; + end + else if (Sender = pnlGamma) then + begin + scrollGamma.Position := trunc(v * 100); + end + else if (Sender = pnlBrightness) then + begin + scrollBrightness.Position := trunc(v * 100); + end + else if (Sender = pnlVibrancy) then + begin + scrollVibrancy.Position := trunc(v * 100); + end + else if (Sender = pnlPitch) then // 3d camera controls + begin + v := v - 360*Trunc(v/360); + cp.cameraPitch := v * PI / 180.0; + txtPitch.Text := FloatToStr(v); + end + else if (Sender = pnlYaw) then + begin + v := v - 360*Trunc(v/360); + cp.cameraYaw := v * PI / 180.0; + txtYaw.Text := FloatToStr(v); + end + else if (Sender = pnlPersp) then + begin + cp.cameraPersp := v; + txtPersp.Text := FloatToStr(v); + end + else if (Sender = pnlZpos) then + begin + cp.cameraZpos := v; + txtZpos.Text := FloatToStr(v); + end + else if (Sender = pnlDOF) then + begin + if v < 0 then v := 0; + cp.cameraDOF := v; + txtDOF.Text := FloatToStr(v); + end + else if (Sender = pnlGammaThreshold) then + begin + if v < 0 then v := 0; + cp.gammaThreshRelative := v; + txtGammaThreshold.Text := FloattoStr(cp.gammaThreshRelative); + end else exit; + //pEdit^.Text := FloatToStr(v); + //pEdit.Refresh; + pnlDragged := True; + DrawPreview; + end; +end; + +procedure TAdjustForm.DragPanelMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + if Button <> mbLeft then exit; + + if pnlDragMode then + begin + //SetCaptureControl(nil); + + pnlDragMode := false; + Screen.Cursor := crDefault; + + if pnlDragged then + begin + UpdateFlame; + pnlDragged := False; + end; + end; +end; + +procedure TAdjustForm.DragPanelDblClick(Sender: TObject); +var + pValue: ^double; +begin + if (Sender = pnlMasterScale) then + begin + pValue := @cp.pixels_per_unit; + if pValue^ = PreviewImage.Width/4 then exit; + pValue^ := PreviewImage.Width/4; + editPPU.Text := FloatToStr(100*pValue^/PreviewImage.Width); + end + else if (Sender = pnlZoom) then + begin + scrollZoom.Position := 0; + end + else if (Sender = pnlXpos) then + begin + scrollCenterX.Position := 0; + end + else if (Sender = pnlYpos) then + begin + scrollCenterY.Position := 0; + end + else if (Sender = pnlAngle) then + begin + scrollAngle.Position := 0; + end + else if (Sender = pnlGamma) then + begin + scrollGamma.Position := Round(defGamma * 100); + end + else if (Sender = pnlBrightness) then + begin + scrollBrightness.Position := Round(defBrightness * 100); + end + else if (Sender = pnlVibrancy) then + begin + scrollVibrancy.Position := Round(defVibrancy * 100); + end + // 3d camera controls + else if (Sender = pnlPitch) then + begin + cp.cameraPitch := 0; + txtPitch.Text := '0'; + end + else if (Sender = pnlYaw) then + begin + cp.cameraYaw := 0; + txtYaw.Text := '0'; + end + else if (Sender = pnlPersp) then + begin + if cp.cameraPersp = 0 then cp.cameraPersp := 0.125 + else cp.cameraPersp := 0; + txtPersp.Text := FloatToStr(cp.cameraPersp); + end + else if (Sender = pnlZpos) then + begin + cp.cameraZpos := 0; + txtZpos.Text := '0'; + end + else if (Sender = pnlDOF) then + begin + cp.cameraDOF := 0; + txtDOF.Text := '0'; + end + else if (Sender = pnlGammaThreshold) then + begin + if cp.gammaThreshRelative = defGammaThreshold then exit; + cp.gammaThreshRelative := defGammaThreshold; + txtGammaThreshold.Text := FloatToStr(defGammaThreshold); + end + else exit;//assert(false); + + UpdateFlame; +end; + +procedure TAdjustForm.FormActivate(Sender: TObject); +begin + txtVibrancy.text := FloatToStr(cp.Vibrancy); + txtGamma.text := FloatToStr(cp.Gamma); + txtBrightness.text := FloatToStr(cp.Brightness); + txtZoom.text := FloatToStr(cp.zoom); + txtCenterX.text := FloatToStr(cp.center[0]); + txtCentery.text := FloatToStr(cp.center[1]); + txtAngle.text := FloatToStr(cp.FAngle * 180 / PI); +end; + +/////////////////////////////////////////////////////////////////////////////// + +procedure TAdjustForm.txtCamEnter(Sender: TObject); +begin + EditBoxValue := (Sender as TEdit).Text; +end; + +procedure TAdjustForm.txtCamPitchExit(Sender: TObject); +var + v: double; +begin + if (EditBoxValue <> txtPitch.Text) then + try + v := StrToFloat(txtPitch.Text); + v := v - 360*Trunc(v/360); + txtPitch.Text := FloatToStr(v); + cp.cameraPitch := v * PI / 180; + UpdateFlame; + except on EConvertError do + txtPitch.Text := FloatToStr(cp.cameraPitch / PI * 180); + end; +end; + +procedure TAdjustForm.txtCamPitchKeyPress(Sender: TObject; var Key: Char); +begin + if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then + begin + key := #0; + txtCamPitchExit(Sender); + end; +end; + +procedure TAdjustForm.txtCamYawExit(Sender: TObject); +var + v: double; +begin + if (EditBoxValue <> txtYaw.Text) then + try + v := StrToFloat(txtYaw.Text); + v := v - 360*Trunc(v/360); + txtYaw.Text := FloatToStr(v); + cp.cameraYaw := v * PI / 180; + UpdateFlame; + except on EConvertError do + txtYaw.Text := FloatToStr(cp.cameraYaw / PI * 180); + end; +end; + +procedure TAdjustForm.txtCamYawKeyPress(Sender: TObject; var Key: Char); +begin + if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then + begin + key := #0; + txtCamYawExit(Sender); + end; +end; + +procedure TAdjustForm.txtCamDistExit(Sender: TObject); +begin + if (EditBoxValue <> txtPersp.Text) then + try + cp.cameraPersp := StrToFloat(txtPersp.Text); + UpdateFlame; + except on EConvertError do + txtPersp.Text := FloatToStr(cp.cameraPersp); + end; +end; + +procedure TAdjustForm.txtCamDistKeyPress(Sender: TObject; var Key: Char); +begin + if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then + begin + key := #0; + txtCamDistExit(Sender); + end; +end; + +procedure TAdjustForm.txtCamZposExit(Sender: TObject); +begin + if (EditBoxValue <> txtZpos.Text) then + try + cp.cameraZpos := StrToFloat(txtZpos.Text); + txtZpos.Text := FloatToStr(cp.cameraZpos); + UpdateFlame; + except on EConvertError do + txtZpos.Text := FloatToStr(cp.cameraZpos); + end; +end; + +procedure TAdjustForm.txtCamZposKeyPress(Sender: TObject; var Key: Char); +begin + if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then + begin + key := #0; + txtCamZposExit(Sender); + end; +end; + +procedure TAdjustForm.txtCamDofExit(Sender: TObject); +begin + if (EditBoxValue <> txtDof.Text) then + try + cp.cameraDOF := StrToFloat(txtDof.Text); + txtDof.Text := FloatToStr(cp.cameraDOF); + UpdateFlame; + except on EConvertError do + txtDof.Text := FloatToStr(cp.cameraDOF); + end; +end; + +procedure TAdjustForm.txtCamDofKeyPress(Sender: TObject; var Key: Char); +begin + if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then + begin + key := #0; + txtCamDofExit(Sender); + end; +end; + +procedure TAdjustForm.PreviewImageMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if Button <> mbLeft then exit; + + camDragValueY := cp.cameraPitch * 180.0 / PI; + camDragValueX := cp.cameraYaw * 180.0 / PI; + + camDragMode := true; + camDragPos.x := 0; + camDragPos.y := 0; + camDragOld.x := x; + camDragOld.y := y; + camMM := false; + //SetCaptureControl(TControl(Sender)); + + Screen.Cursor := crNone; + //GetCursorPos(mousepos); // hmmm + mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); + camDragged := false; +end; + +procedure TAdjustForm.PreviewImageMouseMove(Sender: TObject; + Shift: TShiftState; X, Y: Integer); +var + sc, vx, vy: double; +begin + if camMM then // hack: to skip MouseMove event + begin + camMM:=false; + end + else + if camDragMode and ( (x <> camDragOld.x) or (y <> camDragOld.y) ) then + begin + Inc(camDragPos.x, x - camDragOld.x); + Inc(camDragPos.y, y - camDragOld.y); + + vx := Round6(camDragValueX + camDragPos.x / 10); + vy := Round6(camDragValueY - camDragPos.y / 10); + + cp.cameraPitch := vy * PI / 180.0; + txtPitch.Text := FloatToStr(vy); + txtPitch.Refresh; + cp.cameraYaw := vx * PI / 180.0; + txtYaw.Text := FloatToStr(vx); + txtYaw.Refresh; + + SetCursorPos(MousePos.x, MousePos.y); // hmmm + pnlMM:=true; + + camDragged := True; + DrawPreview; + end; +end; + +procedure TAdjustForm.PreviewImageMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if Button <> mbLeft then exit; + + if camDragMode then + begin + camDragMode := false; + Screen.Cursor := crDefault; + + if camDragged then + begin + UpdateFlame; + camDragged := False; + end; + end; +end; + +procedure TAdjustForm.PreviewImageDblClick(Sender: TObject); +begin + cp.cameraPitch := 0; + txtPitch.Text := '0'; + cp.cameraYaw := 0; + txtYaw.Text := '0'; +// cp.cameraZpos := 0; +// txtZpos.Text := '0'; + scrollCenterX.Position := 0; + scrollCenterY.Position := 0; + + UpdateFlame; +end; + +procedure TAdjustForm.txtGammaThresholdEnter(Sender: TObject); +begin + EditBoxValue := txtGammaThreshold.Text; +end; + +procedure TAdjustForm.txtGammaThresholdExit(Sender: TObject); +var + v: double; +begin + try + v := strtofloat(txtGammaThreshold.Text); + except + exit; + end; + if v < 0 then v := 0; + if v <> cp.gammaThreshRelative then begin + MainForm.UpdateUndo; + cp.gammaThreshRelative := v; + txtGammaThreshold.Text := FloatToStr(cp.gammaThreshRelative); + UpdateFlame; + EditBoxValue := txtGammaThreshold.Text; + end; +end; + +procedure TAdjustForm.txtGammaThresholdKeyPress(Sender: TObject; + var Key: Char); +begin + if key=#13 then + begin + key := #0; + txtGammaThresholdExit(Sender); + end; +end; + +procedure TAdjustForm.txtZoomChange(Sender: TObject); +begin +(* if (txtZoom.Text<>'0') then + AdjustForm.Height := 390 + else + AdjustForm.Height := 332; *) +end; + +procedure TAdjustForm.Shape1MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + ColorPanelClick(nil); +end; + +procedure TAdjustForm.btnResetClick(Sender: TObject); +begin + ScrollBar.Position := 0; +end; + +procedure TAdjustForm.btnResetCurvesClick(Sender: TObject); +var i: integer; +begin + tbWeightLeft.Position := 10; + tbWeightRight.Position := 10; + + with cp do for i := 0 to 3 do + begin + curvePoints[i][0].x := 0.00; curvePoints[i][0].y := 0.00; curveWeights[i][0] := 1; + curvePoints[i][1].x := 0.00; curvePoints[i][1].y := 0.00; curveWeights[i][1] := 1; + curvePoints[i][2].x := 1.00; curvePoints[i][2].y := 1.00; curveWeights[i][2] := 1; + curvePoints[i][3].x := 1.00; curvePoints[i][3].y := 1.00; curveWeights[i][3] := 1; + end; + MainCp.Copy(cp, true); + SetCurvesCp(MainCp); + + Apply; +end; + +procedure TAdjustForm.txtValKeyPress(Sender: TObject; var Key: Char); +begin + if Key=#13 then begin + Key := #0; + txtValExit(sender); + end; +end; + +procedure TAdjustForm.TemplateRandomizeGradient; +begin + mnuRandomizeClick(nil); +end; + +end. + diff --git a/Forms/Browser.dfm b/Forms/Browser.dfm new file mode 100644 index 0000000..b5e5282 --- /dev/null +++ b/Forms/Browser.dfm @@ -0,0 +1,872 @@ +object GradientBrowser: TGradientBrowser + Left = 494 + Top = 299 + Width = 544 + Height = 335 + BorderIcons = [biSystemMenu, biMinimize] + Caption = 'Gradient Browser' + Color = clBtnFace + Constraints.MinHeight = 120 + Constraints.MinWidth = 380 + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + Icon.Data = { + 0000010001001010000001002000680400001600000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000045C6F00100000000000000002DA5D654247EACE51F89B8FD1F7D + A8FC2385AFFA209DD2A01DA9DF53000000000000000000000000000000000000 + 00000000000000000000000000003AB6E247228CC1F143C2EAFF48C3E7FF4EC9 + ECFF44C1E2F538A3C7FB1A7CABF9199BD1830000000000000000000000000000 + 000063D2F201000000000000000020B5E9FF34B0DBCE59D2F0FF5CD4F0FF5CD7 + F2FF5AD6F2FD51CFECFB37AED7F4187BA9FD1A94C98F00000000000000000000 + 000070D8F302000000000000000022B3E7FE1C97C9E751CAE9FF5FD7F2FF0AB3 + 67FF006F00FF008825FF53D1EEFA2E9FCCEE187DACFE0B87BD020000000082DF + F4027CDCF40700000000000000006AD4F36C1181B2FD52CAE8FE62DAF3FF23D9 + 71FF00912BFF006000FF62D9F3FF49C3E5EF1280B0FE1B9BCE73000000000000 + 000089E2F42084DFF4421D99C2FD37A4C9FF46C2EBFF65D4F0FB66DAF3FE3EDB + 8CFF00BA50FF00AB67FF63D9F3FF51CBEBF41E8BB9F81D95C8A7000000000000 + 000076DCF4693BB4DCF78BE2F4B59AE7F7E895E6F6FE95E8F6FE8CE3F5FF85E3 + F4FF70DEF4FF68DCF4FF6ADBF4FF5CD4EFF4208BB9F72297C9AB000000000000 + 000054CBF3F98EE3F5CFB6F1F8FFB6F1F8FF9EEAF6FE93E9F6FF94E8F6FFB359 + 23FFB30F00FFAB2B00FF73DEF4FB63D7EFEE1D84B4F8279DCE94000000000000 + 000070D4F5FFA4EDF6E6B6F1F8FF2959F3FF00007AFF001FDBFF93E9F6FFB08C + 64FFB03A00FF610000FF73DEF4F45CC3E3DE2781AEEF64D3F23E000000000000 + 000070D4F5FFACF0F7EBB6F1F8FF5490FFFF0022D9FF000058FFB2F0F8FFB4B6 + 97FFB38D64FFB6AB8CFF78D3ECE8359AC9EC51B6DB8F00000000000000000000 + 00007AD8F5F89EEAF6E6B6F1F8FF6DAFFFFF5590FFFF6DB0FFFFB6F1F8FFA5EC + F7FEA7ECF7FE98E7F5F14DB0D9F55DBBDDAB84DFF44000000000000000000000 + 0000A9EFF7786BD4F4FB9DEAF6EEAFF1F7F4B6F1F8FFB6F1F8FFB6F1F8FFA6EE + F6F9A0EAF6EF70D2EDE354C6EDF895E7F5580000000000000000000000000000 + 000000000000AAEFF78F5ACFF3F998E8F6E0B6F1F8FFB6F1F8FFB6F1F8FF92E7 + F6E46CD4F4FA65D2F4E984D4E874000000000000000000000000000000000000 + 00000000000000000000A9EFF7737CD9F6F476D6F5FA72D4F5FD75D6F5FB5ECF + F4F190E6F5930000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000D80F0000F0070000B0030000B00100003001000080010000800100008001 + 000080010000800300008003000080070000C00F0000E03F0000FFFF0000} + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnResize = FormResize + OnShow = FormShow + DesignSize = ( + 536 + 306) + PixelsPerInch = 96 + TextHeight = 13 + object btnDefGradient: TSpeedButton + Left = 411 + Top = 7 + Width = 23 + Height = 21 + Hint = 'Open...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnDefGradientClick + end + object ListView: TListView + Left = 7 + Top = 7 + Width = 398 + Height = 234 + Anchors = [akLeft, akTop, akRight, akBottom] + Columns = < + item + Caption = 'Title' + Width = 150 + end> + HideSelection = False + LargeImages = LargeImages + ReadOnly = True + RowSelect = True + ParentShowHint = False + PopupMenu = PopupMenu + ShowHint = True + SmallImages = SmallImages + SortType = stText + TabOrder = 1 + ViewStyle = vsList + OnChange = ListViewChange + OnDblClick = SpeedButton1Click + OnEdited = ListViewEdited + OnInfoTip = ListViewInfoTip + OnKeyPress = ListViewKeyPress + end + object pnlMain: TPanel + Left = 0 + Top = 0 + Width = 536 + Height = 4 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + end + object pnlPreview: TPanel + Left = 0 + Top = 268 + Width = 487 + Height = 25 + Anchors = [akLeft, akRight, akBottom] + BevelOuter = bvLowered + TabOrder = 2 + object Image: TImage + Left = 1 + Top = 1 + Width = 485 + Height = 23 + Align = alClient + Stretch = True + end + end + object SmallImages: TImageList + Left = 8 + Top = 16 + Bitmap = { + 494C010101000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000001000000001002000000000000010 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00808080008080 + 8000808080008080800080808000FFFFFF000000000000808000008080000080 + 8000000000007F7F7F0000000000000000007F7F7F0000000000000000007F7F + 7F000000000000000000BBCCD500BBCCD5000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000007F7F + 7F0000000000000000007F7F7F00000000000080800000808000000000000000 + 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFF5F000FFF1 + E900FFEFE600FFEFE600FFF0E700FFF1E800FFF1E900FFF3EB00FFF3EC00FFF4 + ED00FFF6F0000000000000000000000000000000000000808000008080000080 + 8000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFF4ED00FFEE + E400FFEBDF00FFEBDF00FFEBE000FFECE200FFEDE200FFEEE400FFEFE500FFEF + E600FFF1EA00000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFF1E900CD52 + 0800CD520800CD520800CD520800CD520800CD520800CD520800CD520800CD52 + 0800FFEDE300000000000000000000000000FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00000000007F7F + 7F000000000000000000BBCCD500BBCCD5000000000000000000FFEFE600CD52 + 0800E2651800EB7A3700FFA77200FFD1B200FFF7ED00C2E9FF0042ADF700CD52 + 0800FFE9DC00000000000000000000000000FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFEDE200CD52 + 0800E1651900E9783500FFA77000FFD1B200FFF7EC00C2E9FF0040ADF700CD52 + 0800FFE5D6000000000000000000000000000000000000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF000000000000000000688DA200688D + A200688DA200688DA200688DA200688DA200FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFEBDF00CD52 + 0800E1651800EB783600FFA77000FFD1B200FFF7EC00C2E9FF0042ADF700CD52 + 0800FFE1D000000000000000000000000000FFF1EA0000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF000000000000000000000000000000 + 000000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF0000000000FFF5F000FFF1E900FFEFE600FFEFE600FFF0E700FFF1 + E800FFF1E900FFF3EB00FFF3EC00FFF4ED00FFF6F00000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFE9DB00CD52 + 0800E1651900EC793500FFA77000FFD0B200FFF7EC00C2E9FF0040AEF700CD52 + 0800FFDFCD00000000000000000000000000FFE9DC0000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF0000000000FFF1E900CD520800CD520800CD520800CD520800CD52 + 0800CD520800CD520800CD520800CD520800FFEDE30000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00688DA200688DA200688D + A200688DA200688DA200688DA200688DA2000000000000000000FFE7D800CD52 + 0800E1651900EB793500FFA57000FFD1B200FFF7EC00C2E9FF0040ADF700CD52 + 0800FFE1D000000000000000000000000000FFE1D00000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00688D + A200FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF0000000000FFEDE200CD520800E1651900E9783500FFA77000FFD1 + B200FFF7EC00C2E9FF0040ADF700CD520800FFE5D60000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00BBCCD500000000000000 + 0000000000000000000000000000000000000000000000000000FFE4D500CD52 + 0800E3651A00EB7A3900FFA87400FFD1B300FFF7EC00C4E9FF0044AEF700CD52 + 0800FFE9DC00000000000000000000000000FFE1D00000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF0000000000FFE9DB00CD520800E1651900EC793500FFA77000FFD0 + B200FFF7EC00C2E9FF0040AEF700CD520800FFDFCD0000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD5000000000000000000FFE3D100CD52 + 0800ED793500F9945700FFBC8D00FFE1C500FFFFF90000000000000000000000 + 0000000000000000000000000000000000000000000000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00688D + A200FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF0000000000FFE4D500CD520800E3651A00EB7A3900FFA87400FFD1 + B300FFF7EC00C4E9FF0044AEF700CD520800FFE9DC0000000000FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD5000000000000000000FFE1CF00CD52 + 0800CD520800CD520800CD520800CD520800CD52080000000000E17D4100EB92 + 5E0000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF0000000000FFE1CF00CD520800CD520800CD520800CD520800CD52 + 0800CD52080000000000E17D4100EB925E0000000000FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00BBCCD500BBCCD5000000000000000000FFE2D100FFD7 + BF00FFD0B400FFCEB100FFCFB300FFD0B400FFD3B80000000000F5A779000000 + 000000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF0000000000FFE7DA00FFE2D000FFDECB00FFDECA00FFDDC900FFDE + CA00FFDFCD000000000000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFE7DA00FFE2 + D000FFDECB00FFDECA00FFDDC900FFDECA00FFDFCD0000000000000000000000 + 000000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00 + FF00FF00FF00FF00FF00FF00FF00FF00FF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00BBCCD500BBCCD500424D3E000000000000003E000000 + 2800000040000000100000000100010000000000800000000000000000000000 + 000000000000000000000000FFFFFF00FFFFCD00000000008003C900FFDECA00 + 8003CB00FFDECA008003DA00FFE2D0008003EA00000000008003EA00DDE6EA00 + 8003EA00DDE6EA008003EA00DDE6EA0080030000000000008003000000000000 + 800300000000000080030000000000008007EA0000000000800F000000000000 + 801F000020000000803F8F1F0000000000000000000000000000000000000000 + 000000000000} + end + object PopupMenu: TPopupMenu + Left = 40 + Top = 16 + object DeleteItem: TMenuItem + Caption = 'Delete' + ShortCut = 16430 + OnClick = DeleteItemClick + end + object RenameItem: TMenuItem + Caption = 'Rename' + ShortCut = 113 + OnClick = RenameItemClick + end + end + object OpenDialog: TOpenDialog + DefaultExt = 'ugr' + Filter = 'Gradient files (*.ugr)|*.ugr|Fractint map files (*.map)|*.map' + Left = 72 + Top = 16 + end + object LargeImages: TImageList + Height = 32 + Width = 32 + Left = 104 + Top = 16 + Bitmap = { + 494C010101000400040020002000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000800000002000000001002000000000000040 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000DDE6EA00DDE6EA0000000000FDEB + E000FDE2D300FCCFB300B3644B00C06D5300BB695000BC6A4F00BC6A5100BC6A + 5100A35B4500B9886F00FCC8A800FCC9AA00FCCAAC00FCD0B600FDD6BC00FDD9 + C100FEDFCC0000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDEB + E000FDE2D300FCCFB300FBC8AA00FAC6A500FAC5A400FBC5A400FBC5A400FBC6 + A500FBC7A600FBC7A600FCC8A800FCC9AA00FCCAAC00FCD0B600FDD6BC00FDD9 + C100FEDFCC0000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000F4DA + CA00F2D2BD00ECBC9F00EAB59400E9B29000E8AF8D00E9AF8D00E9B08C00E9AF + 8D00E8AF8D00E9B08D00E8B08D00E8B18E00EAB28F00EAB79900EDBDA000EDC1 + A600F0C8B00000000000DDE6EA00DDE6EA0023232300BAEBFF00B3EAFF00B0E8 + FF00ACE7FF00A8E6FF00A5E6FF00A4E4FF009FE1FF009DE1FF009BE2FF0097E0 + FF0095DFFF0092DDFF008FDDFF008DDDFF008BDBFF0087D9FF0084D8FF0083D8 + FF007ED6FF007ED3FF0078D1FF00262626000000000000000000000000000000 + 0000FFFEFB00FFFEFA00FFFEF800FFFEF700FFFDF700FFFDF600FFFEF600FFFE + F700FFFFF700FFFFF800FFFFF900FFFFF900FFFFFA00FFFFFA00FFFFFB00FFFF + FC00FFFFFC00FFFFFC00FFFFFD00FFFFFE000000000000000000000000000000 + 000000000000000000000000000000000000E7A88300EBB69600EDC1A700F0C9 + B300F3D4C10000000000DDE6EA00DDE6EA002323230023232300232323002323 + 2300232323002323230023232300232323002323230023232300232323002323 + 2300232323002323230023232300232323002323230023232300232323002323 + 2300232323002323230023232300DDE6EA00DDE6EA00DDE6EA0000000000FDEA + DF00FCE1D000FBCCB000ED886800F38C6B00E8856500E9856600E9856600EB86 + 6600D97C5F00DCA18300FBC5A400FBC7A700FBC9AA00FCD3B800FDDAC400FDDF + CD00FEE7D80000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDEA + DF00FCE1D000FBCCB000FAC6A700F9C3A200FAC19F00FAC2A000FBC3A100FBC3 + A300FAC4A300FBC4A300FBC5A400FBC7A700FBC9AA00FCD3B800FDDAC400FDDF + CD00FEE7D80000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000F4D7 + C600F1CDB800EBB69600E8AE8C00E7AB8600E7A98200E6A88300E7A98300E7A8 + 8300E6A98200E7A88300E7A98300E7AA86000000000000000000000000000000 + 0000FFFDFA00FFFCF800FFFBF500FFFBF400FFFBF300FFFAF200FFFBF300FFFB + F300FFFCF400FFFCF400FFFDF500FFFEF500FFFDF500FFFEF600FFFEF600FFFF + F700FFFFF800FFFFF800FFFFF900FFFFF900FFFFFA00FFFFFB00FFFFFC00FFFF + FC0000000000000000000000000000000000F9BE9D00F8BF9E00F9C09E00F9C0 + 9F00F9C19F00F9C1A000F9C2A200F9C5A500F9C8AB00F9833C00FF985A00FFAC + 770000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000F1CF + BB00EEC5AB00E8AA8500E6A37B00E49F7400E39B7000E39C7100E49B7000E39C + 7100E39C7100E39B7000E39C7200E49F7500E5A37A00F9833C00FF985A00FFAC + 770000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00BAEEFC00B7ED + FD00B6ECFC00B2E9FB00B0E8FC00ADE8FB00AAE7FC00A7E6FC00A6E5FC003740 + 4500DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDE9 + DE00FCE0CF00FACAAD00FAC3A400F9C09E00F9BF9C00F9C09D00F9C09D00FAC1 + A000FAC1A000F9C1A100FAC3A200FAC5A500FBC7A900FCD4BC00FDDDCA00FDE4 + D500FEECE20000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDE9 + DE00FCE0CF00FACAAD00FAC3A400F9C09E000000000000000000000000000000 + 0000FFFCF800FFFBF600FFFAF200FFF9F000FFF8EF00FFF7EE00FFF9EE00FFF9 + EF00FFF9EF00FFF9F000FFFAF000FFFAF200FFFBF200FFFCF300FFFCF300FFFC + F400FFFCF400FFFDF500FFFEF500FFFFF600FFFFF700FFFFF700FFFFF700FFFF + FA0000000000000000000000000000000000DDE6EA00DDE6EA0000000000FCEA + DF00FBE2D200F9CEB400F8C8AB00F9C6A700F9C5A500F9C5A500F9C6A500F8C6 + A700F9C6A800F9C6A700F9C8A900FAC9AC00FACDB100FF9F6400FFB38100FFC8 + 9F00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FCEA + DF00FBE2D200F9CEB400F8C8AB00F9C6A700F9C5A500F9C5A500F9C6A500F8C6 + A700F9C6A800F9C6A700F9C8A900FAC9AC00FACDB100FF9F6400FFB38100FFC8 + 9F00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000F1CE + B900EEC4AB00E7AC8800E5A57F00E4A17900E49F7600E49F7600E49F7500E59F + 7600E49F7700E49F7600E49F7700E5A17900E5A57E00FF9F6400FFB38100FFC8 + 9F00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0023232300C1F1 + FD00BFEFFD00BAEEFC00B9EDFC00B6ECFC00B2EAFB00AFE9FB00ADE8FB00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000000000000000000000000000 + 0000FFFBF700FFFAF300FFF8EF00FFF6EC00FFF6EB00FFF5EB00FFF5EA00FFF6 + EB00FFF6EB00FFF7EB00FFF7ED00FFF8ED00FFF8EE00FFF9EE00FFF9F000FFFA + F000FFFAF000FFFAF200FFFBF200FFFBF200FFFCF300FFFCF300FFFDF400FFFD + F60000000000000000000000000000000000EEC3A90000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDEB + E200FCE5D700FAD5BF00F9D1B800F9CEB400F9CDB300F9CDB300F9CEB300F9CF + B500F9CFB500FACFB500F9D0B600FAD1B800FAD4BC00FFBA8B00FFCFA9000000 + 0000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDEB + E200FCE5D700FAD5BF00F9D1B800F9CEB400F9CDB300F9CDB300F9CEB300F9CF + B500F9CFB500FACFB500F9D0B600FAD1B800FAD4BC00FFBA8B00FFCFA9000000 + 0000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000F1CE + B900EEC6AE00E9B29200E7AD8800E6A98400E6A78100E7A88100E6A78100E7A7 + 8200E7A78200E6A78200E6A78200E6A984000000000000000000000000000000 + 0000FFFAF600FFF8F200FFF6ED00FFF4E900FFF4E600FFF3E600FFF3E600FFF4 + E700FFF4E700FFF5E800FFF5E800FFF5E900FFF5E900FFF5EB00FFF6EB00FFF7 + EB00FFF7EC00FFF8ED00FFF8EE00FFF8EE00FFF9EF00FFF9F000FFFAF000FFFA + F200000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDF1 + E900FDEEE500FCE8DC00FCE6D900FCE5D800FCE5D700FCE5D700FCE5D700FCE6 + D800FCE6D800FCE6D900FCE6D900FCE7DA00FCE8DC0000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FDF1 + E900FDEEE500FCE8DC00FCE6D900FCE5D8000000000000000000000000000000 + 0000FFFAF400FFF7F000FFF4EA00FFF2E600FFF1E300FFF0E200FFF0E200FFF1 + E200FFF2E300FFF2E400FFF2E500FFF3E500FFF3E500FFF4E600FFF5E700FFF4 + E700FFF5E800FFF5E900FFF5E900FFF5EA00FFF5EA00FFF6EB00FFF7ED00FFF8 + EF0000000000000000000000000000000000DDE6EA00DDE6EA00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000DDE6EA00DDE6EA00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000DDE6EA00DDE6EA000000000000000000000000000000 + 0000FFF9F300FFF6EE00FFF2E800FFF0E300FFEEE000FFEEDF00FFEEDE00FFEE + DF00FFEEE000FFEFE000FFEFE000FFEFE100FFF0E100FFF1E200FFF1E200FFF2 + E400FFF2E400FFF2E400FFF3E600FFF3E600FFF4E600FFF5E700FFF5E900FFF6 + EB0000000000000000000000000000000000FFFFF000FFFFF200FFFFF200FFFF + F400FFFFF500FFFFF500FFFFF60000000000DDE6EA00DDE6EA0000000000FFFC + F800FFFBF600FFF9F000FFF8EF00FFF7EE00FFF9EF00FFF9EF00FFF9F000FFFA + F200FFFBF200FFFCF300FFFCF400FFFCF400FFFDF500FFFFF600FFFFF700FFFF + F700FFFFFA0000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FFFD + FA00FFFCF800FFFBF400FFFBF300FFFAF200FFFBF300FFFCF400FFFCF400FFFE + F500FFFDF500FFFEF600FFFFF700FFFFF800FFFFF800FFFFF900FFFFFA00FFFF + FB00FFFFFC0000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA0000000000FFFD + FA00FFFCF800FFFBF400FFFBF300FFFAF200FFFBF300FFFCF400FFFCF400FFFE + F500FFFDF500FFFEF600FFFFF700FFFFF800FFFFF800FFFFF900FFFFFA00FFFF + FB00FFFFFC0000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFF800FFFEF600FFFFF400FFFF + F200FFFFF300FFFFF300FFFFF400FFFFF4000000000000000000000000000000 + 0000FFF8F200FFF5EC00FFF0E500FFEDDF00CD520800CD520800CD520800CD52 + 0800CD520800CD520800CD520800CD520800CD520800CD520800CD520800CD52 + 0800CD520800CD520800CD520800CD520800FFF1E300FFF2E300FFF2E400FFF3 + E60000000000000000000000000000000000DDE6EA00DDE6EA00DDE6EA000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000000000000000000000000000 + 0000FFF7F100FFF3EA00FFEEE300FFECDD00CD520800DA804A00DC7E4400E285 + 4C00EB956200F5AA7D00FEBE9700FFCCB000FFDCC800FFEFE300F7F8F800CEEA + FD0092CEF70060B8F3003CA3F000CD520800FFEEDF00FFEEDF00FFF0E100FFF0 + E30000000000000000000000000000000000DDE6EA00DDE6EA00DDE6EA000000 + 0000FFFEFB00FFFEFA00FFFEF800FFFEF700FFFDF700FFFDF600FFFEF600FFFE + F700FFFFF700FFFFF800FFFFF900FFFFF900FFFFFA00FFFFFA00FFFFFB00FFFF + FC00FFFFFC00FFFFFC00FFFFFD00FFFFFE00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA0000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000 + 0000BADDF900ABD5F80097CBF60089C4F5007EBFF40077BCF30076BBF30075BA + F30074BAF30075BAF20075BAF30075BAF30074BAF40075BBF40075BAF40074BB + F40074BAF40075BBF40075BAF40074BBF40074BBF40076BBF40078BCF4007EBF + F50000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000000000000000000000000000 + 0000FFF6EF00FFF1E900FFECDF00FFE9D900CD520800DD855200DB7C4000E282 + 4800EA925E00F4A77900FDBC9400FFCCAE00FFDCC700FFEFE400F7F8F900CDEA + FD008FCDF7005CB5F30038A1F000CD520800FFEBDB00FFECDC00FFEDDD00FFEF + E00000000000000000000000000000000000BBCCD500BBCCD500DDE6EA000000 + 0000FFFDFA00FFFCF800FFFBF500FFFBF400FFFBF300FFFAF200FFFBF300FFFB + F300FFFCF400FFFCF400FFFDF500FFFEF500FFFDF500FFFEF600FFFEF600FFFF + F700FFFFF800FFFFF800FFFFF900FFFFF900FFFFFA00FFFFFB00FFFFFC00FFFF + FC0000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000 + 0000C1DFF900B2D8F9009FCFF70091C8F60087C3F40080C0F4007FBFF4007EBF + F3007DBFF4007DBFF3007EBFF3007DBFF3007EBFF3007EBFF3007DBFF4007EBF + F4007EBFF4007DBFF4007DBEF3007EBFF4007DBEF3007EBFF40080C0F50086C2 + F60000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00214F4A00214F4A00214F + 4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F + 4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F + 4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F4A00214F + 4A00214F4A00214F4A00214F4A00DDE6EA000000000000000000000000000000 + 0000FFF5EE00FFF1E700FFEADD00FFE7D600CD520800DC855000DB7B4100E180 + 4700EA905C00F4A67800FDBC9400FFCBAE00FFDBC700FFEFE300F7F8F800CDEA + FD008FCDF7005BB5F40037A1EF00CD520800FFE9D700FFE9D700FFEAD900FFEC + DC0000000000000000000000000000000000DDE6EA00DDE6EA00DDE6EA000000 + 0000FFFCF800FFFBF60000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF7F100FFF3EA00FFF3EA00FFEEE300FFEEE300FFECDD00FFECDD00CD52 + 0800CD520800FBE6DA00FBE6DA00FBDED100FBDED100FBD0B900FBD0B900FBD3 + C000FBC4A300FBC4A300FBB99100FBB99100FBFAFB00FBFAFB00FBF6F600FBF6 + F600FBE6DA00FBE6DA00FB996400FB996400FBA87B00FBA87B00FB823F00FBDC + CB00FBDCCB00F7C2A500F7C2A500CD520800CD520800FFEEDF00FFEEDF00FFEE + DF00FFEEDF00FFF0E100FFF0E100FFF0E300FFF0E30000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500DDE6 + EA00BBCCD500BBCCD500BBCCD500BBCCD5000000000000000000000000000000 + 0000FFF4ED00FFEFE500FFE9DB00FFE5D300CD520800DC855000DB7C4100E181 + 4800EA905C00F4A67800FDBC9400FFCCAE00FFDCC700FFEFE300F7F8F800CDEA + FD008FCDF7005BB5F30037A1EF00CD520800FFE5D300FFE6D400FFE7D500FFE9 + D80000000000000000000000000000000000DDE6EA00DDE6EA00000000000000 + 0000FFF6EF00FFF1E900FFF1E900FFECDF00FFECDF00FFE9D900FFE9D900CD52 + 0800CD520800FEE6DB00FEE6DB00FEDBC800FEDBC800FED9C200FED9C200FED1 + B700FEAF8100FEAF8100FEF9F800FEF9F800FEF3EE00FEF3EE00FEFEFE00FEFE + FE00FEAB7B00FEAB7B00FEAB7A00FEAB7A00FE975F00FE975F00FE9C6200FEF3 + F100FEF3F100FBB08600FBB08600CD520800CD520800FFEBDB00FFEBDB00FFEC + DC00FFECDC00FFEDDD00FFEDDD00FFEFE000FFEFE00000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6 + EA00BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6EA00688DA200DDE6 + EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500688DA200688D + A200688DA200688DA200BBCCD500DDE6EA000000000000000000000000000000 + 0000FFF3EC00FFEEE300FFE7D800FFE3D000CD520800DC855000DB7C4000E281 + 4800EA905C00F4A67800FEBC9400FFCCAE00FFDCC700FFEFE300F7F8F800CDEA + FD008FCDF7005CB5F30037A1EF00CD520800FFE3CF00FFE3CF00FFE5D100FFE6 + D50000000000000000000000000000000000FEDBC800FED9C200FED9C200FED1 + B700FEAF8100FEAF8100FEF9F800FEF9F800FEF3EE00FEF3EE00FEFEFE00FEFE + FE00FEAB7B00FEAB7B00FEAB7A00FEAB7A00FE975F00FE975F00FE9C6200FEF3 + F100FEF3F100FBB08600FBB08600CD520800CD520800FFEBDB00FFEBDB00FFEC + DC00FFECDC00FFEDDD00FFEDDD00FFEFE000FFEFE00000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6 + EA00BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6EA00688DA200DDE6 + EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD500688DA200DDE6EA00BBCC + D500BBCCD500BBCCD500688DA200BBCCD500688DA200DDE6EA00BBCCD500BBCC + D500688DA200DDE6EA00688DA200DDE6EA00688DA200DDE6EA00BBCCD500BBCC + D500688DA200DDE6EA00688DA200DDE6EA000000000000000000000000000000 + 0000FFF2EA00FFEDE200FFE5D500FFE0CD00CD520800DC865100DB7C4000E281 + 4700EA905C00F4A67800FEBC9400FFCBAE00FFDCC700FFEFE300F7F8F800CDEA + FD008FCDF7005CB5F30036A1EF00CD520800FFE0CC00FFE0CC00FFE1CE00FFE3 + D10000000000000000000000000000000000FE823900FE823900FEDAC200FED8 + C300FED8C300FBA27300FBA27300CD520800CD520800FFE9D700FFE9D700FFE9 + D700FFE9D700FFEAD900FFEAD900FFECDC00FFECDC0000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6 + EA00BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6EA00688DA200DDE6 + EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD500688DA200DDE6EA00BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6EA00BBCCD500BBCC + D500688DA200DDE6EA00688DA200DDE6EA00688DA200DDE6EA00BBCCD500BBCC + D500688DA200DDE6EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD50053C7 + FF0051C6FF004FC5FF004CC4FF0049C4FF0047C2FF0044C1FF0042C0FF003FC0 + FF003DBDFF003AB9FF0038B6FF00214F4A000000000000000000000000000000 + 0000FFF1E900FFEBDF00FFE3D200FFDEC900CD520800DC865100DB7B4100E281 + 4800EB915C00F5A67800FEBB9400FFCCAE00FFDCC700FFEFE400F7F8F900CDEA + FD008FCDF7005CB5F40036A1EF00CD520800FFDDC700FFDEC800FFDFCB00FFE2 + CE0000000000000000000000000000000000FFE9D80000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00BBCCD500688DA200DDE6EA00688DA200DDE6 + EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD500688DA200DDE6EA00BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6EA00BBCCD500BBCC + D500688DA200DDE6EA00688DA200DDE6EA00688DA200DDE6EA00BBCCD500BBCC + D500688DA200DDE6EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD5008BDB + FF0082D9FF007BD7FF0077D5FF0073D4FF0071D2FF006ED1FF006AD0FF0068CF + FF0065CFFF0063CDFF0061CDFF005FCCFF005DCAFF005AC9FF0058C9FF0055C8 + FF0053C7FF0050C5FF0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000000000000000000000000000 + 0000FFF1E800FFEADE00FFE2D000FFDBC600CD520800DC855100DB7C4100E281 + 4800EB915C00F5A77800FDBC9400FFCBAE00FFDBC700FFEFE300F6F8F800CCEA + FD008FCDF7005BB6F30037A1EF00CD520800FFDBC300FFDBC400FFDDC700FFDF + CA0000000000000000000000000000000000BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200688D + A200688DA200688DA200BBCCD500BBCCD500688DA200DDE6EA00688DA200DDE6 + EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD500688DA200DDE6EA00BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500688DA200BBCCD500DDE6EA00DDE6 + EA00688DA200BBCCD500688DA200DDE6EA00688DA200BBCCD500DDE6EA00DDE6 + EA00688DA200BBCCD500688DA200DDE6EA00DDE6EA00BBCCD500DDE6EA00D9EB + FA00D9EAF900D9EAFA00D9EAFA00D9EAFA00D9EBFA00D9EBFA00DAEBF900DBEC + FA0000000000DDE6EA00DDE6EA00DDE6EA00232323009FE2FF0098E0FF008DDD + FF0084D9FF007ED6FF0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF4ED00FFEFE500FFEFE500FFE9DB00FFE9DB00FFE5D300FFE5D300CD52 + 0800CD520800FEE1CE00FEE1CE00FEE4D8000000000000000000000000000000 + 0000FFF0E700FFE9DC00FFE0CD00FED9C300CD520800DC855000DB7C4100E181 + 4700EA915C00F5A77800FEBB9400FFCCAE00FFDCC800FFEFE300F6F8F800CCEA + FD008FCDF7005BB5F30036A1EF00CD520800FFD7BF00FFD8C000FFDAC200FFDC + C70000000000000000000000000000000000688DA200BBCCD500688DA200DDE6 + EA00688DA200DDE6EA00BBCCD500BBCCD500BBCCD500688DA200DDE6EA00BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200688DA200688D + A200BBCCD500BBCCD500688DA200DDE6EA00BBCCD500688DA200688DA200688D + A200BBCCD500BBCCD500688DA200688DA200BBCCD500688DA200BBCCD5000000 + 0000F4F9FE00F1F8FD00EFF5FC00EBF5FC00EAF3FA00EAF2FA00E9F2FA007478 + 7D003A3C3F003A3D3F003A3D3F003A3D3F003A3D3F003A3D3F003A3D3F003A3D + 3F003A3D3F00E9F3FB0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF4ED00FFEFE500FFEFE500FFE9DB00FFE9DB00FFE5D300FFE5D300CD52 + 0800CD520800FEE1CE00FEE1CE00FEE4D800FEE4D800FEB89000FEB89000FECA + A900FEFEFE00FEFEFE00FEEBE100FEEBE100FEFDFE00FEFDFE00FEB78C00FEB7 + 8C00FEA16D00FEA16D00FE975C00FE975C000000000000000000000000000000 + 0000FFEFE500FFE8DA00FEDDCB00FDD7C000CD520800DD855100DB7B4000E181 + 4700EB915C00F5A67700FEBB9400FFCCAE00FFDBC700FFEFE400F6F8F900CCEA + FD008FCDF7005BB5F30036A1F000CD520800FFD5BB00FFD5BD00FFD8BF00FFDA + C20000000000000000000000000000000000BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500688DA200DDE6EA00BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500100F + 0E0000000000CFBEB000FFEAD900FFEBDB00FFEBDB00FFECDC00FFEDDD00FFEF + E00000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000 + 0000FCFDFE00FBFCFE0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF3EC00FFEEE300FFEEE300FFE7D800FFE7D800FFE3D000FFE3D000CD52 + 0800CD520800FEE4D300FEE4D300FEE1D100FEE1D100FEA67500FEA67500FEF6 + F100FEEFE900FEEFE900FEEBE200FEEBE200FEFBFA00FEFBFA00FE945900FE94 + 5900FEA97C00FEA97C00FE925000FE925000FEFEFE00FEFEFE00FEB98D00FEC3 + A100FEC3A100FBBC9200FBBC9200CD520800CD520800FFE3CF00FFE3CF00FFE3 + CF00FFE3CF00FFE5D100FFE5D100FFE6D5000000000000000000000000000000 + 0000FEEEE400FEE6D800FEDDC800FDD5BC00CD520800DD865200DB7C4200E183 + 4900EA925F00F4A77A00FDBD9500FFCCAE00FFDCC800FFEFE400F6F8F800CDEA + FD0090CDF7005DB6F30038A1F000CD520800FFD3B800FFD3BA00FFD6BC00FFD8 + C00000000000000000000000000000000000BBCCD500BBCCD500BBCCD5000000 + 0000FFF5EE00FFF1E700FFEADD00FFE7D600FFE4D100FFE2CF00FFE2CE00FFE2 + CF00CFB8A80040393400EFD6C300FFE5D100FFE5D200FFE5D200FFE5D300EFD8 + C700403A3500BFADA00000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF3EC00FFEEE300FFEEE300FFE7D800FFE7D800FFE3D000FFE3D000CD52 + 0800CD520800FEE4D300FEE4D300FEE1D100FEE1D100FEA67500FEA67500FEF6 + F100FEEFE900FEEFE900FEEBE200FEEBE200FEFBFA00FEFBFA00FE945900FE94 + 5900FEA97C00FEA97C00FE925000FE925000FEFEFE00FEFEFE00FEB98D00FEC3 + A100FEC3A100FBBC9200FBBC9200CD520800CD520800FFE3CF00FFE3CF00FFE3 + CF00FFE3CF00FFE5D100FFE5D100FFE6D500FFE6D50000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD5000000000000000000000000000000 + 0000FEEDE200FEE5D600FDDBC500FDD3BA00CD520800DD885600DD804800E388 + 5000EB976600F5AB8100FDBF9B00FFCEB200FFDECB00FFF0E400F6F8F800CFEB + FD0096D0F70064B9F30041A6F000CD520800FED2B700FED3BB00FED5BD00FED8 + C1000000000000000000000000000000000000000000FFFFFF00000000000000 + 0000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF2EA00FFEDE200FFEDE200FFE5D500FFE5D500FFE0CD00FFE0CD00CD52 + 0800CD520800FEEADD00FEEADD00FEC7A700FEC7A700FEC09B00FEC09B00FEFB + FB00FEEAE000FEEAE000FEEFE700FEEFE700FEF0EB00FEF0EB00FE844100FE84 + 4100FEA97800FEA97800FEC8AA00FEC8AA00FEFAFA00FEFAFA00FEAF7F00FEBD + 9A00FEBD9A00FBB07B00FBB07B00CD520800CD520800FFE0CC00FFE0CC00FFE0 + CC00FFE0CC00FFE1CE00FFE1CE00FFE3D100FFE3D10000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000000000000000000000000000 + 0000FEECE100FDE3D500FCD9C300FCD1B500CD520800DE8A5700DF885400E593 + 6000EEA17400F8B38D00FEC6A500FFD3BA00FFE1D000FFF2E700F7F8F900D4ED + FE00A0D5F80073C0F50054B0F100CD520800FED2B800FDD4BC00FDD7C000FEDA + C50000000000000000000000000000000000DDE6EA00DDE6EA00000000000000 + 0000FFF2EA00FFEDE200FFEDE200FFE5D500FFE5D500FFE0CD00FFE0CD00CD52 + 0800CD520800FEEADD00FEEADD00FEC7A700FEC7A700FEC09B00FEC09B00FEFB + FB00FEEAE000FEEAE000FEEFE700FEEFE700FEF0EB00FEF0EB00FE844100FE84 + 4100FEA97800FEA97800FEC8AA00FEC8AA00FEFAFA00FEFAFA00FEAF7F00FEBD + 9A00FEBD9A00FBB07B00FBB07B00CD520800CD520800FFE0CC00FFE0CC00FFE0 + CC00FFE0CC00FFE1CE00FFE1CE00FFE3D100FFE3D10000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200688D + A200688DA200688DA200688DA200BBCCD500688DA200BBCCD500688DA200BBCC + D500688DA200BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200688D + A200688DA200688DA200BBCCD500BBCCD5000000000000000000000000000000 + 0000FDEBE000FDE2D300FCD7C100FCCFB300CD520800E2966A00E3976800EA9F + 7000F1B28D00F8C1A100FED0B400FFD9C500FFE5D700FFF4EC00F8F6F600DBEC + F600B2DAF5008DC6EE0073BCEF00CD520800FDD6BC00FDD9C100FDDCC700FEDF + CC0000000000000000000000000000000000FEB08600FEDFCB00FEDFCB00FEF7 + F300FEE7DA00FEE7DA00FEF0EA00FEF0EA00FEEBE100FEEBE100FE813A00FE81 + 3A00FEAD7800FEAD7800FEE4D900FEE4D900FEE3DB00FEE3DB00FED1B000EFC5 + B400EFC5B400E99B7300E99B7300CD520800CD520800FFDDC700FFDDC700FFDE + C800FFDEC800FFDFCB00FFDFCB00FFE2CE00FFE2CE0000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD5000000000000000000000000000000 + 0000FDEADF00FCE1D000FBD5BE00FBCCB000CD520800CD520800CD520800CD52 + 0800CD520800CD520800CD520800CD520800CD520800CD520800CD520800CD52 + 0800CD520800CD520800CD520800CD520800FDDAC400FDDFCD00FDE3D300FEE7 + D80000000000000000000000000000000000FEE3DB00FEE3DB00FED1B000EFC5 + B400EFC5B400E99B7300E99B7300CD520800CD520800FFDDC700FFDDC700FFDE + C800FFDEC800FFDFCB00FFDFCB00FFE2CE00FFE2CE0000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD5000000 + 0000000000000000000000000000000000005BCAFF0058C9FF0056C7FF0053C7 + FF0051C4FF004DBFFF0049BBFF00214F4A000000000000000000000000000000 + 0000FDE9DE00FCE0CF00FAD4BB00FACAAD00FAC3A400F9C09E00F9BF9C00F9BF + 9C00F9C09D00F9C09D00FAC09F00FAC1A000FAC1A000F9C1A100F9C2A100FAC3 + A200FAC5A500FBC7A900FCCCB100FCD4BC00FDDDCA00FDE4D500FDE9DC00FEEC + E20000000000000000000000000000000000FFDFCA0000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD5000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000000000000000000000000000 + 0000FCE9DD00FBDFCD00FAD2BB00F9C9AB00F9C2A200F8BF9D00F8BE9A00F8BD + 9A00F8BE9B00F8BE9C00F9BF9D00F8C09D00F9C09E00F9C09F00F9C09F00F9C2 + A100FAC4A400FBC7A80000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500FFF7 + EB00FFF7EC00FFF8ED00FFF8EE00FFF8EE00FFF9EF00FFF9F000FFFAF000FFFA + F20000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000 + 0000FFFBF700FFFAF30000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF1E800FFEADE00FFEADE00FFE2D000FFE2D000FFDBC600FFDBC600CD52 + 0800CD520800FEE9DD00FEE9DD00FEA56E000000000000000000000000000000 + 0000FDE9DD00FCE0CF00FAD4BC00F8CAAD00F8C4A400F8C09F00F8BF9D00F9BE + 9D00F8BF9E00F9C09E00F9C09F00F9C09F00F9C19F00F9C1A000F9C1A000F9C2 + A200F9C5A500F9C8AB0000000000F9833C00FF985A00FFAC7700FFC195000000 + 000000000000000000000000000000000000BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD5000000 + 0000FFF7F100FFF3EA00FFEEE300FFECDD00CD520800FBE6DA00FBDED100FBD0 + B900FBD3C000FBC4A300FBB99100FBFAFB00FBF6F600FBE6DA00FB996400FBA8 + 7B00FB823F00FBDCCB0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF1E800FFEADE00FFEADE00FFE2D000FFE2D000FFDBC600FFDBC600CD52 + 0800CD520800FEE9DD00FEE9DD00FEA56E00FEA56E00FEE5D900FEE5D900FEF6 + F500FEE4D400FEE4D400FEEBE400FEEBE400FEEEE400FEEEE400FE7A3200FE7A + 3200FEAB7500FEAB7500FED1B800FED1B8000000000000000000000000000000 + 0000FCEADF00FBE2D200FAD6C100F9CEB400F8C8AB00F9C6A700F8C4A500F9C5 + A500F9C5A500F9C6A500F8C6A600F8C6A700F9C6A800F9C6A700F9C6A800F9C8 + A900FAC9AC00FACDB10000000000FF9F6400FFB38100FFC89F00000000000000 + 000000000000000000000000000000000000DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FEFA + FA00FEAF7F00FEBD9A00FBB07B00CD520800FFE0CC00FFE0CC00FFE1CE00FFE3 + D10000000000DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA000000 + 0000FFF3EC00FFEEE30000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF0E700FFE9DC00FFE9DC00FFE0CD00FFE0CD00FED9C300FED9C300CD52 + 0800CD520800FEE4D600FEE4D600FEA16D00FEA16D00FEE9E100FEE9E100FEF6 + F300FEEBDF00FEEBDF00FEF1EB00FEF1EB00FEF9FB00FEF9FB00FE824200FE82 + 4200FEA96F00FEA96F00FEBC8D00FEBC8D00FEFEFE00FEFEFE00FEFDFE00FEE2 + D500FEE2D500FBDED200FBDED200CD520800CD520800FFD7BF00FFD7BF00FFD8 + C000FFD8C000FFDAC200FFDAC200FFDCC7000000000000000000000000000000 + 0000FDEBE200FCE5D700FADCC900FAD5BF00F9D1B800F9CEB400F9CEB300F9CD + B300F9CDB300F9CEB300F9CEB400F9CFB500F9CFB500FACFB500FACFB500F9D0 + B600FAD1B800FAD4BC0000000000FFBA8B00FFCFA90000000000000000000000 + 000000000000000000000000000000000000BBCCD500BBCCD500BBCCD5000000 + 0000FFEFE500FFE8DA00FEDDCB00FDD7C000CD520800FEE4D700FE9F6600FEE9 + DD00FEF0E900FEE7DB00FEE7DF00FEFEFE00FEA37300FE8B3D00FEC69200FEE0 + D600FDFEFE00FEE2D30000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFF0E700FFE9DC00FFE9DC00FFE0CD00FFE0CD00FED9C300FED9C300CD52 + 0800CD520800FEE4D600FEE4D600FEA16D00FEA16D00FEE9E100FEE9E100FEF6 + F300FEEBDF00FEEBDF00FEF1EB00FEF1EB00FEF9FB00FEF9FB00FE824200FE82 + 4200FEA96F00FEA96F00FEBC8D00FEBC8D00FEFEFE00FEFEFE00FEFDFE00FEE2 + D500FEE2D500FBDED200FBDED200CD520800CD520800FFD7BF00FFD7BF00FFD8 + C000FFD8C000FFDAC200FFDAC200FFDCC700FFDCC70000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD5000000000000000000000000000000 + 0000FDEEE600FCEADF00FCE4D600FBE0CF00FBDDCB00FADBC800FADBC700FADB + C700FADBC800FADBC800FADBC800FADCC900FBDCC900FADCC900FADCC900FADC + CA00FBDDCB00FBE0CE0000000000FFD6B3000000000000000000000000000000 + 000000000000000000000000000000000000DDE6EA00DDE6EA00DDE6EA000000 + 0000FDEBE000FDE2D30000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00000000000000 + 0000FFEFE500FFE8DA00FFE8DA00FEDDCB00FEDDCB00FDD7C000FDD7C000CD52 + 0800CD520800FEE4D700FEE4D700FE9F6600FE9F6600FEE9DD00FEE9DD00FEF0 + E900FEE7DB00FEE7DB00FEE7DF00FEE7DF00FEFEFE00FEFEFE00FEA37300FEA3 + 7300FE8B3D00FE8B3D00FEC69200FEC69200FEE0D600FEE0D600FDFEFE00FEE2 + D300FEE2D300F1A98A00F1A98A00CD520800CD520800FFD5BB00FFD5BB00FFD5 + BD00FFD5BD00FFD8BF00FFD8BF00FFDAC200FFDAC20000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA200BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD5000000000000000000000000000000 + 0000FDF1E900FDEEE500FCEAE000FCE8DC00FCE6D900FCE5D800FCE5D700FCE5 + D700FCE5D700FCE5D700FCE5D800FCE6D800FCE6D800FCE6D900FCE6D900FCE6 + D900FCE7DA00FCE8DC0000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000DDE6EA00DDE6EA00000000000000 + 0000FFEFE500FFE8DA00FFE8DA00FEDDCB00FEDDCB00FDD7C000FDD7C000CD52 + 0800CD520800FEE4D700FEE4D700FE9F6600FE9F6600FEE9DD00FEE9DD00FEF0 + E900FEE7DB00FEE7DB00FEE7DF00FEE7DF00FEFEFE00FEFEFE00FEA37300FEA3 + 7300FE8B3D00FE8B3D00FEC69200FEC69200FEE0D600FEE0D600FDFEFE00FEE2 + D300FEE2D300F1A98A00F1A98A00CD520800CD520800FFD5BB00FFD5BB00FFD5 + BD00FFD5BD00FFD8BF00FFD8BF00FFDAC200FFDAC20000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA20000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FE9B6000FEDFCD00FEDFCD00FEF2 + EF00FEE3D900FEE3D900FEE0D300FEE0D300FEF8F800FEF8F800FEE8E300FEE8 + E300FE833B00FE833B00FEBB7300FEBB7300FEDFC000FEDFC000F9CEC200FED8 + CA00FED8CA00FBD2BF00FBD2BF00CD520800CD520800FFD3B800FFD3B800FFD3 + BA00FFD3BA00FFD6BC00FFD6BC00FFD8C000FFD8C00000000000DDE6EA00DDE6 + EA00DDE6EA00DDE6EA00DDE6EA00DDE6EA00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00BBCCD500DDE6EA00BBCCD500BBCCD500BBCCD500BBCCD500BBCC + D500BBCCD500BBCCD500BBCCD500BBCCD500BBCCD500688DA20000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00424D3E000000000000003E000000 + 2800000080000000200000000100010000000000000200000000000000000000 + 000000000000000000000000FFFFFF00E0000007000000000000000000000000 + E00000F7000000000000000000000000E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007FFFFFF00FFFFFF00FFFFFF00 + E00000070000000000000000FFFFFF00E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007FFFFFF00FFFFFF00FFFFFF00 + E00000070000000000000000FFFFFF00E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007000000000000000000000000 + E0000007000000000000000000000000E0000007FFFFFF00FFFFFF00FFFFFF00 + E00000070000000000000000FFFFFF00E0000007000000000000000000000000 + E0000007000000000000000000000000E000000F000000000000000000000000 + E000001F000000000000000000000000E000003F000000000000000000000000 + E000007F000000000000000000000000E00000FFFFFFFF00FFFFFF00FFFFFF00 + E00001FF10022F031F022F0320FFFF0000000000000000000000000000000000 + 000000000000} + end + object TooltipTimer: TTimer + OnTimer = TooltipTimerTimer + Left = 8 + Top = 52 + end +end diff --git a/Forms/Browser.pas b/Forms/Browser.pas new file mode 100644 index 0000000..bf09c1b --- /dev/null +++ b/Forms/Browser.pas @@ -0,0 +1,621 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Browser; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ExtCtrls, ComCtrls, ControlPoint, ToolWin, ImgList, StdCtrls, + Cmap, Menus, Global, Buttons, Translation, + RenderingInterface; + +const + PixelCountMax = 32768; + PaletteTooltipTimeout = 1500; + +type + TGradientBrowser = class(TForm) + SmallImages: TImageList; + pnlMain: TPanel; + PopupMenu: TPopupMenu; + DeleteItem: TMenuItem; + RenameItem: TMenuItem; + OpenDialog: TOpenDialog; + LargeImages: TImageList; + TooltipTimer: TTimer; + ListView: TListView; + pnlPreview: TPanel; + Image: TImage; + btnDefGradient: TSpeedButton; + procedure FormResize(Sender: TObject); + procedure ListViewChange(Sender: TObject; Item: TListItem; + Change: TItemChange); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure DeleteItemClick(Sender: TObject); + procedure RenameItemClick(Sender: TObject); + procedure ListViewEdited(Sender: TObject; Item: TListItem; + var S: string); + procedure btnDefGradientClick(Sender: TObject); + procedure SpeedButton1Click(Sender: TObject); + procedure ListViewKeyPress(Sender: TObject; var Key: Char); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure ListViewInfoTip(Sender: TObject; Item: TListItem; + var InfoTip: String); + procedure TooltipTimerTimer(Sender: TObject); + private + procedure DrawPalette; + procedure Apply; + public + PreviewDensity: double; + FlameIndex, GradientIndex: Integer; + Extension, Identifier, Filename: string; + cp: TControlPoint; + Palette: TColorMap; + zoom: double; + Center: array[0..1] of double; + Render: TRenderer; + procedure ListFileContents; + function LoadFractintMap(filen: string): TColorMap; + end; + +type + EFormatInvalid = class(Exception); + pRGBTripleArray = ^TRGBTripleArray; + TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple; + +var + GradientBrowser: TGradientBrowser; + FlameString: string; + +function CreatePalette(strng: string): TColorMap; + +implementation + +uses Main, Options, Editor, {Gradient,} Registry, Adjust, Mutate; + +{$R *.DFM} + + +procedure RGBBlend(a, b: integer; var Palette: TColorMap); +{ Linear blend between to indices of a palette } +var + c, v: real; + vrange, range: real; + i: integer; +begin + if a = b then + begin + Exit; + end; + range := b - a; + vrange := Palette[b mod 256][0] - Palette[a mod 256][0]; + c := Palette[a mod 256][0]; + v := vrange / range; + for i := (a + 1) to (b - 1) do + begin + c := c + v; + Palette[i mod 256][0] := Round(c); + end; + vrange := Palette[b mod 256][1] - Palette[a mod 256][1]; + c := Palette[a mod 256][1]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][1] := Round(c); + end; + vrange := Palette[b mod 256][2] - Palette[a mod 256][2]; + c := Palette[a mod 256][2]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][2] := Round(c); + end; +end; + +function GetVal(token: string): string; +var + p: integer; +begin + p := Pos('=', token); + Delete(Token, 1, p); + Result := Token; +end; + +function ReplaceTabs(str: string): string; +{Changes tab characters in a string to spaces} +var + i: integer; +begin + for i := 1 to Length(str) do + begin + if str[i] = #9 then + begin + Delete(str, i, 1); + Insert(#32, str, i); + end; + end; + Result := str; +end; + +function TGradientBrowser.LoadFractintMap(filen: string): TColorMap; +var + i: integer; + s: string; + pal: TColorMap; + MapFile: TextFile; +begin +{ Load a map file } + AssignFile(MapFile, Filen); + try + Reset(MapFile); + for i := 0 to 255 do + begin + Read(MapFile, Pal[i][0]); + Read(MapFile, Pal[i][1]); + Read(MapFile, Pal[i][2]); + Read(MapFile, s); + end; + CloseFile(MapFile); + Result := Pal; + except + on EInOutError do Application.MessageBox(PChar(Format(TextByKey('common-genericopenfailure'), [FileName])), PCHAR('Apophysis'), 16); + end; +end; + +function CreatePalette(strng: string): TColorMap; +{ Loads a palette from a gradient string } +var + Strings: TStringList; + index, i: integer; + Tokens: TStringList; + Indices, Colors: TStringList; + a, b: integer; +begin + Strings := TStringList.Create; + Tokens := TStringList.Create; + Indices := TStringList.Create; + Colors := TStringList.Create; + try + try + Strings.Text := strng; + if Pos('}', Strings.Text) = 0 then raise EFormatInvalid.Create('No closing brace'); + if Pos('{', Strings[0]) = 0 then raise EFormatInvalid.Create('No opening brace.'); + GetTokens(ReplaceTabs(strings.text), tokens); + Tokens.Text := Trim(Tokens.text); + i := 0; + while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do + begin + if Pos('index=', LowerCase(Tokens[i])) <> 0 then + Indices.Add(GetVal(Tokens[i])) + else if Pos('color=', LowerCase(Tokens[i])) <> 0 then + Colors.Add(GetVal(Tokens[i])); + inc(i) + end; + for i := 0 to 255 do + begin + Result[i][0] := 0; + Result[i][1] := 0; + Result[i][2] := 0; + end; + if Indices.Count = 0 then raise EFormatInvalid.Create('No color info'); + for i := 0 to Indices.Count - 1 do + begin + try + index := StrToInt(Indices[i]); + while index < 0 do inc(index, 400); + index := Round(Index * (255 / 399)); + indices[i] := IntToStr(index); + assert(index>=0); + assert(index<256); + Result[index][0] := StrToInt(Colors[i]) mod 256; + Result[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256; + Result[index][2] := trunc(StrToInt(Colors[i]) / 65536); + except + end; + end; + i := 1; + repeat + a := StrToInt(Trim(Indices[i - 1])); + b := StrToInt(Trim(Indices[i])); + RGBBlend(a, b, Result); + inc(i); + until i = Indices.Count; + if (Indices[0] <> '0') or (Indices[Indices.Count - 1] <> '255') then + begin + a := StrToInt(Trim(Indices[Indices.Count - 1])); + b := StrToInt(Trim(Indices[0])) + 256; + RGBBlend(a, b, Result); + end; + except on EFormatInvalid do + begin +// Result := False; + end; + end; + finally + Tokens.Free; + Strings.Free; + Indices.Free; + Colors.Free; + end; +end; + +procedure TGradientBrowser.DrawPalette; +var + i, j: integer; + Row: pRGBTripleArray; + BitMap: TBitMap; +begin + BitMap := TBitMap.Create; + try + Bitmap.PixelFormat := pf24bit; + BitMap.Width := 256; + BitMap.Height := 1; + for j := 0 to Bitmap.Height - 1 do + begin + Row := Bitmap.Scanline[j]; + for i := 0 to Bitmap.Width - 1 do + begin + with Row[i] do + begin + rgbtRed := Palette[i][0]; + rgbtGreen := Palette[i][1]; + rgbtBlue := Palette[i][2]; + end + end + end; + Image.Picture.Graphic := Bitmap; + Image.Refresh; + finally + BitMap.Free; + end; +end; + +procedure TGradientBrowser.ListFileContents; +{ List identifiers in file } +var + i, p: integer; + Title: string; + ListItem: TListItem; + FStrings: TStringList; +begin + FStrings := TStringList.Create; + FStrings.LoadFromFile(filename); + try + ListView.Items.BeginUpdate; + ListView.Items.Clear; + if Lowercase(ExtractFileExt(filename)) = '.map' then + begin + ListItem := ListView.Items.Add; + Listitem.Caption := Trim(filename); + end + else + if (Pos('{', FStrings.Text) <> 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos('{', FStrings[i]); + if (p <> 0) and (Pos('(3D)', FStrings[i]) = 0) then + begin + Title := Trim(Copy(FStrings[i], 1, p - 1)); + if Title <> '' then + begin { Otherwise bad format } + ListItem := ListView.Items.Add; + Listitem.Caption := Trim(Copy(FStrings[i], 1, p - 1)); + end; + end; + end; + end; + ListView.Items.EndUpdate; + ListView.Selected := ListView.Items[0]; + finally + FStrings.Free; + end; +end; + +procedure TGradientBrowser.ListViewChange(Sender: TObject; Item: TListItem; + Change: TItemChange); +var + Tokens, FStrings: TStringList; + EntryStrings: TStringList; + i: integer; +begin + Application.ProcessMessages; + FStrings := TStringList.Create; + EntryStrings := TStringList.Create; + Tokens := TStringList.Create; + try + if Lowercase(ExtractFileExt(filename)) = '.map' then + begin + Palette := LoadFractintMap(filename); + DrawPalette; + end + else + if (ListView.SelCount <> 0) and (ListView.Selected.Caption <> Identifier) then + begin + Identifier := ListView.Selected.Caption; + FStrings.LoadFromFile(Filename); + for i := 0 to FStrings.count - 1 do + if Pos(Lowercase(ListView.Selected.Caption) + ' ', Trim(Lowercase(FStrings[i]))) = 1 then break; + EntryStrings.Add(FStrings[i]); + repeat + inc(i); + EntryStrings.Add(FStrings[i]); + until Pos('}', FStrings[i]) <> 0; + Palette := CreatePalette(EntryStrings.Text); + DrawPalette; + end; + finally + EntryStrings.Free; + FStrings.Free; + Tokens.Free; + end; +end; + +procedure TGradientBrowser.FormCreate(Sender: TObject); +begin + self.Caption := TextByKey('gradientbrowser-title'); + btnDefGradient.Hint := TextByKey('common-browse'); + DeleteItem.Caption := TextByKey('common-delete'); + RenameItem.Caption := TextByKey('common-rename'); + PreviewDensity := prevMediumQuality; + cp := TControlPoint.Create; + cp.gamma := defGamma; + cp.brightness := defBrightness; + cp.vibrancy := defVibrancy; + cp.spatial_oversample := defOversample; + cp.spatial_filter_radius := defFilterRadius; + Render := TRenderer.Create; + FlameIndex := 0; + GradientIndex := 0; +end; + +procedure TGradientBrowser.FormDestroy(Sender: TObject); +begin + Render.Free; + cp.Free; +end; + +procedure TGradientBrowser.FormShow(Sender: TObject); +var + Registry: TRegistry; +begin + { Read posution from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Browser', False) then + begin + if Registry.ValueExists('Left') then + GradientBrowser.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + GradientBrowser.Top := Registry.ReadInteger('Top'); + if Registry.ValueExists('Width') then + GradientBrowser.Width := Registry.ReadInteger('Width'); + if Registry.ValueExists('Height') then + GradientBrowser.Height := Registry.ReadInteger('Height'); + end; + Registry.CloseKey; + finally + Registry.Free; + end; + if FileExists(filename) then ListFileContents; +end; + +procedure TGradientBrowser.DeleteItemClick(Sender: TObject); +var + c: boolean; +begin + if ListView.SelCount <> 0 then + begin + if ConfirmDelete then + c := Application.MessageBox( + PChar(Format(TextByKey('common-confirmdelete'), [ListView.Selected.Caption])), 'Apophysis', 36) = IDYES + else + c := True; + if c then + if ListView.Focused and (ListView.SelCount <> 0) then + begin + Application.ProcessMessages; + if DeleteEntry(ListView.Selected.Caption, Filename) then + begin + ListView.Items.Delete(ListView.Selected.Index); + ListView.Selected := ListView.ItemFocused; + end; + end; + end; +end; + +procedure TGradientBrowser.RenameItemClick(Sender: TObject); +begin + if ListView.SelCount <> 0 then + ListView.Items[ListView.Selected.Index].EditCaption; +end; + +procedure TGradientBrowser.ListViewEdited(Sender: TObject; Item: TListItem; + var S: string); +begin +// if s <> Item.Caption then +// if not RenameIFS(Item.Caption, s, Filename) then +// s := Item.Caption; +end; + +procedure TGradientBrowser.btnDefGradientClick(Sender: TObject); +var + fn:string; +begin + OpenDialog.InitialDir := BrowserPath; + OpenDialog.Filter := Format('%s|*.gradient;*.ugr|%s|*.map|%s|*.*', + [TextByKey('common-filter-gradientfiles'), + TextByKey('common-filter-fractintfiles'), + TextByKey('common-filter-allfiles')]); + OpenDialog.FileName := ''; + if OpenSaveFileDialog(GradientBrowser, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + Filename := fn; //OpenDialog.FileName; + GradientFile := Filename; + BrowserPath := ExtractFilePath(fn); //ExtractFilePath(OpenDialog.FileName); + ListFileContents; + end; +end; + +procedure TGradientBrowser.Apply; +begin + MainForm.StopThread; + MainForm.UpdateUndo; + MainCp.cmap := Palette; + MainCP.cmapindex := -1; + if EditForm.Visible then EditForm.UpdateDisplay; + if AdjustForm.Visible then AdjustForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + MainForm.RedrawTimer.enabled := true; +end; + +procedure TGradientBrowser.SpeedButton1Click(Sender: TObject); +begin + Apply; +end; + +procedure TGradientBrowser.ListViewKeyPress(Sender: TObject; + var Key: Char); +begin + if Key = #13 then Apply; +end; + +procedure TGradientBrowser.FormClose(Sender: TObject; + var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + { Defaults } + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Browser', True) then + begin + Registry.WriteInteger('Top', GradientBrowser.Top); + Registry.WriteInteger('Left', GradientBrowser.Left); + Registry.WriteInteger('Width', GradientBrowser.Width); + Registry.WriteInteger('Height', GradientBrowser.Height); + end; + finally + Registry.Free; + end; +end; + +procedure TGradientBrowser.ListViewInfoTip(Sender: TObject; + Item: TListItem; var InfoTip: String); +var + i, j: integer; + Row: pRGBTripleArray; + Bitmap: TBitmap; + pal: TColorMap; + EntryStrings, FStrings: TStringList; + rect: TRect; +begin + BitMap := TBitMap.create; + Bitmap.PixelFormat := pf24bit; + BitMap.Width := 256; + BitMap.Height := 100; + + FStrings := TStringList.Create; + EntryStrings := TStringList.Create; + try + if Lowercase(ExtractFileExt(filename)) = '.map' then + begin + pal := LoadFractintMap(filename); + end + else + begin + Identifier := Item.Caption; + FStrings.LoadFromFile(Filename); + for i := 0 to FStrings.count - 1 do + if Pos(Lowercase(Item.Caption) + ' ', Trim(Lowercase(FStrings[i]))) = 1 then break; + EntryStrings.Add(FStrings[i]); + repeat + inc(i); + EntryStrings.Add(FStrings[i]); + until Pos('}', FStrings[i]) <> 0; + pal := CreatePalette(EntryStrings.Text); + end; + finally + EntryStrings.Free; + FStrings.Free; + end; + + for j := 0 to Bitmap.Height - 1 do + begin + Row := Bitmap.Scanline[j]; + for i := 0 to Bitmap.Width - 1 do + begin + with Row[i] do + begin + rgbtRed := pal[i][0]; + rgbtGreen := pal[i][1]; + rgbtBlue := pal[i][2]; + end + end + end; + rect.TopLeft := Item.Position; + rect.BottomRight.X := rect.TopLeft.X + 100; + rect.BottomRight.Y := rect.TopLeft.Y + 16; + with ListView do + begin + Canvas.Rectangle(Rect); + //Canvas.TextOut(Rect.Left, Rect.Top, Item.Caption); + //Rect.Left := (Rect.Left + rect.Right) div 3; + Canvas.StretchDraw(Rect, Bitmap); + end; + BitMap.Free; + InfoTip := ''; + TooltipTimer.Interval := PaletteTooltipTimeout; + TooltipTimer.Enabled := true; +end; + +procedure TGradientBrowser.TooltipTimerTimer(Sender: TObject); +begin + ListView.Repaint; + TooltipTimer.Enabled := false; +end; + +procedure TGradientBrowser.FormResize(Sender: TObject); +begin + Listview.Width := self.ClientWidth - 4; + btnDefGradient.Left := self.ClientWidth - 2 - btnDefGradient.Width; + ListView.Height := self.ClientHeight - pnlPreview.Height - 6; + btnDefGradient.Top := self.ClientHeight - pnlPreview.Height - 2 + pnlPreview.Height div 2 - btnDefGradient.Height div 2; + ListView.Top := 2; + ListView.Left := 2; + pnlPreview.Top := self.ClientHeight - pnlPreview.Height - 2; + pnlPreview.Left := 2; + pnlPreview.Width := self.ClientWidth - btnDefGradient.Width - 6; +end; + +end. + diff --git a/Forms/Curves.dfm b/Forms/Curves.dfm new file mode 100644 index 0000000..1ba56af --- /dev/null +++ b/Forms/Curves.dfm @@ -0,0 +1,125 @@ +object CurvesForm: TCurvesForm + Left = 197 + Top = 111 + BorderStyle = bsDialog + Caption = 'Curves' + ClientHeight = 492 + ClientWidth = 489 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'System' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 16 + object Label1: TLabel + Left = 8 + Top = 16 + Width = 75 + Height = 13 + Caption = 'Selected curve:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + end + object CurvesPanel: TPanel + Left = 8 + Top = 68 + Width = 473 + Height = 414 + BevelOuter = bvNone + Color = clBlack + ParentBackground = False + TabOrder = 0 + end + object cbChannel: TComboBox + Left = 8 + Top = 35 + Width = 185 + Height = 21 + Style = csDropDownList + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ItemIndex = 0 + ParentFont = False + TabOrder = 1 + Text = 'Overall' + OnChange = cbChannelChange + Items.Strings = ( + 'Overall' + 'Red' + 'Green' + 'Blue') + end + object tbWeightLeft: TScrollBar + Left = 326 + Top = 8 + Width = 155 + Height = 21 + Max = 160 + PageSize = 0 + Position = 80 + TabOrder = 2 + OnChange = tbWeightChange + OnScroll = tbWeightScroll + end + object tbWeightRight: TScrollBar + Left = 326 + Top = 35 + Width = 155 + Height = 21 + Max = 160 + PageSize = 0 + Position = 80 + TabOrder = 3 + OnChange = tbWeightChange + OnScroll = tbWeightScroll + end + object Panel2: TPanel + Left = 199 + Top = 8 + Width = 121 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = ' First CP weight:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object Panel1: TPanel + Left = 199 + Top = 35 + Width = 121 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = ' Second CP weight:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end +end diff --git a/Forms/Curves.pas b/Forms/Curves.pas new file mode 100644 index 0000000..5e937c5 --- /dev/null +++ b/Forms/Curves.pas @@ -0,0 +1,123 @@ +unit Curves; + +interface + +uses Windows, Classes, Graphics, Forms, Controls, CurvesControl, Vcl.ExtCtrls, + Vcl.StdCtrls, Vcl.ComCtrls, ControlPoint, Registry, Global; + +type + TCurvesForm = class(TForm) + CurvesPanel: TPanel; + cbChannel: TComboBox; + tbWeightLeft: TScrollBar; + tbWeightRight: TScrollBar; + Panel2: TPanel; + Panel1: TPanel; + Label1: TLabel; + procedure FormShow(Sender: TObject); + procedure cbChannelChange(Sender: TObject); + procedure tbWeightChange(Sender: TObject); + procedure tbWeightScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); + procedure FormCreate(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + private + { Private declarations } + published + CurvesControl: TCurvesControl; + public + procedure SetCp(cp: TControlPoint); + end; + +var + CurvesForm: TCurvesForm; + +implementation + +uses Main; + +{$R *.DFM} + +procedure TCurvesForm.tbWeightScroll(Sender: TObject; ScrollCode: TScrollCode; + var ScrollPos: Integer); +begin + if ScrollCode = scEndScroll then + CurvesControl.UpdateFlame; +end; + +procedure TCurvesForm.SetCp(cp: TControlPoint); +begin + if CurvesControl = nil then Exit; + CurvesControl.SetCp(cp); +end; + +procedure TCurvesForm.cbChannelChange(Sender: TObject); +begin + if CurvesControl = nil then Exit; + CurvesControl.ActiveChannel := TCurvesChannel(cbChannel.ItemIndex); + tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10); + tbWeightRight.Position := Round(CurvesControl.WeightRight * 10); +end; + +procedure TCurvesForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Curves', True) then + begin + Registry.WriteInteger('Top', self.Top); + Registry.WriteInteger('Left', self.Left); + end; + finally + Registry.Free; + end; +// bStop := True; +end; + +procedure TCurvesForm.FormCreate(Sender: TObject); +begin + // +end; + +procedure TCurvesForm.FormShow(Sender: TObject); +var Registry: TRegistry; +begin + if not (assigned(curvesControl)) then + begin + CurvesControl := TCurvesControl.Create(self); + CurvesControl.Align := alClient; + CurvesControl.Parent := CurvesPanel; + end; + + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Curves', False) then + begin + if Registry.ValueExists('Left') then + self.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + self.Top := Registry.ReadInteger('Top'); + Registry.CloseKey; + end; + finally + Registry.Free; + end; + + tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10); + tbWeightRight.Position := Round(CurvesControl.WeightRight * 10); + + SetCp(MainCp); +end; + +procedure TCurvesForm.tbWeightChange(Sender: TObject); +begin + CurvesControl.WeightLeft := tbWeightLeft.Position / 10.0; + CurvesControl.WeightRight := tbWeightRight.Position / 10.0; +end; + +end. diff --git a/Forms/Editor.dfm b/Forms/Editor.dfm new file mode 100644 index 0000000..770c981 --- /dev/null +++ b/Forms/Editor.dfm @@ -0,0 +1,3543 @@ +object EditForm: TEditForm + Left = 509 + Top = 87 + Caption = 'Transform Editor' + ClientHeight = 772 + ClientWidth = 765 + Color = clBtnFace + Constraints.MinHeight = 400 + Constraints.MinWidth = 200 + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + Icon.Data = { + 0000010001001010000001002000680400001600000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000282728AC010101BC020202880000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000979697FA5E5B5E57010101EF02020286000000000000001E0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000005B5B5BBF010101F200000000131313DC0605 + 06D002000269010101E4020102F5090707E30000000000000000000000000000 + 000000000000000000000000000073737385020102FF02020281000000000000 + 00002B292BC0020102FF010101AC1212091D0000000000000000000000000000 + 000000000000000000000000000080808022504E50FF010101BF000000006059 + 5928575557A2242324FF010101EA000000000000000000000000000000000000 + 000000000000000000000000000000000000717171F2010101E9000000007B77 + 76D0919090EB565656832D2D2D7D010101DD010101C300000000000000000000 + 000000000000000000000000000000000000646464CC020102FF0000000D0000 + 0000747474216767673E00000000505050201717173700000000000000000000 + 0000000000000000000000000000000000006C6C6C95181718FF020202810000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000898887C7B1AFAEFF817F7EFF0E0B0AFF0A08 + 07F8000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000969496ED060506DA0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000009090908E646364FF0000 + 001D090606CF0A0707AB00000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000009D9C9DCB6E6B + 6BF50A0707F3070505BB00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008080 + 80224D4D4D3C0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000FFFF0000C7FF0000C2FF0000F2070000F1870000F10F0000F9030000F893 + 0000F8FF0000F07F0000FCFF0000FC1F0000FE1F0000FF3F0000FFFF0000} + KeyPreview = True + OldCreateOrder = True + OnActivate = FormActivate + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnKeyDown = EditKeyDown + OnKeyPress = EditKeyPress + OnResize = FormResize + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object StatusBar: TStatusBar + Left = 0 + Top = 757 + Width = 765 + Height = 15 + Panels = < + item + Width = 60 + end + item + Width = 60 + end + item + Width = 150 + end> + end + object topPnl: TPanel + Left = 0 + Top = 0 + Width = 765 + Height = 24 + Align = alTop + BevelOuter = bvSpace + Ctl3D = True + ParentCtl3D = False + TabOrder = 0 + object EditorToolBar: TToolBar + Left = 1 + Top = 1 + Width = 763 + Height = 22 + Align = alClient + ButtonHeight = 23 + Caption = 'EditorToolBar' + Color = clBtnFace + Images = EditorTB + ParentColor = False + TabOrder = 0 + object tbResetAll: TToolButton + Left = 0 + Top = 0 + Hint = 'New blank flame' + Caption = 'New blank flame' + ImageIndex = 0 + ParentShowHint = False + ShowHint = True + OnClick = mnuResetAllClick + end + object tbAdd: TToolButton + Left = 23 + Top = 0 + Hint = 'Adds a new triangle' + Caption = 'Add' + ImageIndex = 1 + ParentShowHint = False + ShowHint = True + OnClick = mnuAddClick + end + object tbDuplicate: TToolButton + Left = 46 + Top = 0 + Hint = 'Duplicates the selected triangle' + Caption = 'Duplicate' + ImageIndex = 2 + ParentShowHint = False + ShowHint = True + OnClick = mnuDupClick + end + object tbDelete: TToolButton + Left = 69 + Top = 0 + Hint = 'Deletes the selected triangle' + Caption = 'Delete' + ImageIndex = 3 + ParentShowHint = False + ShowHint = True + OnClick = mnuDeleteClick + end + object ToolButton4: TToolButton + Left = 92 + Top = 0 + Width = 8 + Caption = 'ToolButton4' + ImageIndex = 3 + Style = tbsSeparator + end + object tbUndo: TToolButton + Left = 100 + Top = 0 + Hint = 'Undo (Ctrl+Z)' + Caption = 'Undo' + ImageIndex = 4 + ParentShowHint = False + ShowHint = True + OnClick = mnuUndoClick + end + object tbRedo: TToolButton + Left = 123 + Top = 0 + Hint = 'Redo (Ctrl+Y)' + Caption = 'Redo' + ImageIndex = 5 + ParentShowHint = False + ShowHint = True + OnClick = mnuRedoClick + end + object ToolButton11: TToolButton + Left = 146 + Top = 0 + Width = 8 + Caption = 'ToolButton11' + ImageIndex = 32 + Style = tbsSeparator + end + object ToolButton9: TToolButton + Left = 154 + Top = 0 + Hint = 'Copy triangle' + Caption = 'ToolButton9' + ImageIndex = 26 + OnClick = btnCopyTriangleClick + end + object ToolButton10: TToolButton + Left = 177 + Top = 0 + Hint = 'Paste triangle' + Caption = 'ToolButton10' + ImageIndex = 27 + OnClick = btnPasteTriangleClick + end + object ToolButton1: TToolButton + Left = 200 + Top = 0 + Width = 8 + Caption = 'ToolButton1' + ImageIndex = 5 + Style = tbsSeparator + end + object tbSelect: TToolButton + Left = 208 + Top = 0 + Hint = 'Select mode' + Caption = 'Select' + Down = True + ImageIndex = 6 + ParentShowHint = False + ShowHint = True + OnClick = tbSelectClick + end + object tbMove: TToolButton + Left = 231 + Top = 0 + Hint = 'Move triangle' + Caption = 'Move' + Down = True + Grouped = True + ImageIndex = 7 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbEditModeClick + end + object tbRotate: TToolButton + Left = 254 + Top = 0 + Hint = 'Rotate triangle' + Caption = 'Rotate' + Grouped = True + ImageIndex = 8 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbEditModeClick + end + object tbScale: TToolButton + Left = 277 + Top = 0 + Hint = 'Scale triangle' + Caption = 'Scale' + Grouped = True + ImageIndex = 9 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbEditModeClick + end + object tbPivotMode: TToolButton + Left = 300 + Top = 0 + Hint = 'Toggle world pivot mode' + Caption = 'tbPivotMode' + ImageIndex = 15 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = btnPivotModeClick + end + object ToolButton6: TToolButton + Left = 323 + Top = 0 + Width = 8 + Caption = 'ToolButton6' + ImageIndex = 16 + Style = tbsSeparator + end + object tbRotate90CCW: TToolButton + Left = 331 + Top = 0 + Hint = 'Rotate triangle 90'#176' counter-clockwise' + Caption = 'tbRotate90CCW' + ImageIndex = 17 + ParentShowHint = False + ShowHint = True + OnClick = btTrgRotateLeft90Click + end + object tbRotate90CW: TToolButton + Left = 354 + Top = 0 + Hint = 'Rotate triangle 90'#176' clockwise' + Caption = 'tbRotate90CW' + ImageIndex = 18 + ParentShowHint = False + ShowHint = True + OnClick = btTrgRotateRight90Click + end + object tbFlipHorz: TToolButton + Left = 377 + Top = 0 + Hint = 'Flip triangle horizontal' + Caption = 'Flip Horizontal' + ImageIndex = 10 + ParentShowHint = False + ShowHint = True + OnClick = mnuFlipHorizontalClick + end + object tbFlipVert: TToolButton + Left = 400 + Top = 0 + Hint = 'Flip triangle vertical' + Caption = 'Flip Vertical' + ImageIndex = 11 + ParentShowHint = False + ShowHint = True + OnClick = mnuFlipVerticalClick + end + object ToolButton2: TToolButton + Left = 423 + Top = 0 + Width = 8 + Caption = 'ToolButton2' + ImageIndex = 14 + Style = tbsSeparator + end + object tbVarPreview: TToolButton + Left = 431 + Top = 0 + Hint = 'Show/hide variation preview' + Caption = 'Variation Preview' + ImageIndex = 14 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbVarPreviewClick + end + object ToolButton3: TToolButton + Left = 454 + Top = 0 + Width = 8 + Caption = 'ToolButton3' + ImageIndex = 16 + Style = tbsSeparator + end + object tbPostXswap: TToolButton + Left = 462 + Top = 0 + Hint = 'Enable post-triangle editing' + Caption = 'tbPostXswap' + ImageIndex = 29 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbPostXswapClick + end + object tbEnableFinalXform: TToolButton + Left = 485 + Top = 0 + Hint = 'Enable final transform' + Caption = 'Show Final Xform' + ImageIndex = 24 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbEnableFinalXformClick + end + object ToolButton8: TToolButton + Left = 508 + Top = 0 + Width = 8 + Caption = 'ToolButton8' + ImageIndex = 32 + Style = tbsSeparator + end + object ToolButton7: TToolButton + Left = 516 + Top = 0 + Hint = 'Adds a new linked triangle' + Caption = 'ToolButton7' + ImageIndex = 31 + ParentShowHint = False + ShowHint = True + OnClick = mnuLinkPostxformClick + end + object ToolButton5: TToolButton + Left = 539 + Top = 0 + Width = 8 + Caption = 'ToolButton5' + ImageIndex = 32 + Style = tbsSeparator + end + object ToolButton12: TToolButton + Left = 547 + Top = 0 + Caption = 'ToolButton12' + ImageIndex = 32 + Visible = False + OnClick = ToolButton12Click + end + object ToolButton13: TToolButton + Left = 570 + Top = 0 + Caption = 'ToolButton13' + ImageIndex = 33 + Visible = False + end + object ToolButton14: TToolButton + Left = 593 + Top = 0 + Caption = 'ToolButton14' + ImageIndex = 34 + Visible = False + end + end + end + object EditPnl: TPanel + Left = 0 + Top = 24 + Width = 765 + Height = 733 + Align = alClient + TabOrder = 2 + object Splitter1: TSplitter + Left = 454 + Top = 1 + Width = 10 + Height = 731 + Align = alRight + AutoSnap = False + Beveled = True + MinSize = 300 + OnMoved = splitterMoved + end + object GrphPnl: TPanel + Left = 1 + Top = 1 + Width = 453 + Height = 731 + Align = alClient + BevelOuter = bvNone + Color = clAppWorkSpace + TabOrder = 0 + object ImgTemp: TImage + Left = 0 + Top = 0 + Width = 273 + Height = 233 + Proportional = True + end + end + object RightPanel: TPanel + Left = 464 + Top = 1 + Width = 300 + Height = 731 + Align = alRight + Alignment = taLeftJustify + BevelOuter = bvNone + TabOrder = 1 + object Splitter2: TSplitter + Left = 0 + Top = 177 + Width = 300 + Height = 8 + Cursor = crVSplit + Align = alTop + AutoSnap = False + Beveled = True + MinSize = 177 + Visible = False + OnMoved = splitterMoved + end + object ControlPanel: TPanel + Left = 0 + Top = 185 + Width = 300 + Height = 546 + Align = alClient + TabOrder = 0 + OnResize = ControlPanelResize + DesignSize = ( + 300 + 546) + object PageControl: TPageControl + Left = 1 + Top = 71 + Width = 298 + Height = 466 + ActivePage = tabVariations + Anchors = [akLeft, akTop, akRight, akBottom] + MultiLine = True + TabOrder = 3 + TabStop = False + object TriangleTab: TTabSheet + Caption = 'Triangle' + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 + object TriangleScrollBox: TScrollBox + Left = 0 + Top = 0 + Width = 290 + Height = 420 + HorzScrollBar.Visible = False + VertScrollBar.Smooth = True + VertScrollBar.Style = ssFlat + VertScrollBar.Tracking = True + Align = alClient + BevelInner = bvNone + BevelOuter = bvNone + BorderStyle = bsNone + TabOrder = 0 + DesignSize = ( + 290 + 420) + object TrianglePanel: TPanel + Left = 1 + Top = 0 + Width = 284 + Height = 321 + Anchors = [akLeft, akTop, akRight] + BevelOuter = bvNone + TabOrder = 0 + OnResize = TrianglePanelResize + object ToolBar1: TToolBar + Left = 64 + Top = 218 + Width = 145 + Height = 28 + Align = alNone + ButtonWidth = 24 + Caption = 'ToolBar1' + EdgeInner = esNone + EdgeOuter = esNone + Images = EditorTB + TabOrder = 3 + object tbCopyTriangle: TToolButton + Left = 0 + Top = 0 + Hint = 'Copy triangle coordinates' + ImageIndex = 26 + ParentShowHint = False + ShowHint = True + OnClick = btnCopyTriangleClick + end + object tbPasteTriangle: TToolButton + Left = 24 + Top = 0 + Hint = 'Paste triangle coordinates' + ImageIndex = 27 + ParentShowHint = False + ShowHint = True + OnClick = btnPasteTriangleClick + end + object tbExtendedEdit: TToolButton + Left = 48 + Top = 0 + Hint = 'Enable extended edit mode' + Caption = 'tbExtendedEdit' + ImageIndex = 25 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbExtendedEditClick + end + object tbAxisLock: TToolButton + Left = 72 + Top = 0 + Hint = 'Lock transform axes' + Caption = 'tbAxisLock' + ImageIndex = 16 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbAxisLockClick + end + object tbAutoWeights: TToolButton + Left = 96 + Top = 0 + Hint = 'Auto-balance weights' + Caption = 'tbAutoWeights' + ImageIndex = 28 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + end + object tb2PostXswap: TToolButton + Left = 120 + Top = 0 + Hint = 'Enable post-triangle editing' + Caption = 'tb2PostXswap' + ImageIndex = 29 + ParentShowHint = False + ShowHint = True + Style = tbsCheck + OnClick = tbPostXswapClick + end + end + object GroupBox5: TGroupBox + Left = 20 + Top = 112 + Width = 177 + Height = 97 + TabOrder = 1 + object btTrgRotateLeft90: TSpeedButton + Left = 8 + Top = 17 + Width = 23 + Height = 24 + Hint = 'Rotate triangle 90'#176' counter-clockwise' + Flat = True + Glyph.Data = { + 36050000424D3605000000000000360400002800000010000000100000000100 + 08000000000000010000C40E0000C40E00000001000000000000000000000000 + 8000008000000080800080000000800080008080000080808000C0C0C0000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000003300 + 00006600000099000000CC000000FF0000000033000033330000663300009933 + 0000CC330000FF33000000660000336600006666000099660000CC660000FF66 + 000000990000339900006699000099990000CC990000FF99000000CC000033CC + 000066CC000099CC0000CCCC0000FFCC000000FF000033FF000066FF000099FF + 0000CCFF0000FFFF000000003300330033006600330099003300CC003300FF00 + 330000333300333333006633330099333300CC333300FF333300006633003366 + 33006666330099663300CC663300FF6633000099330033993300669933009999 + 3300CC993300FF99330000CC330033CC330066CC330099CC3300CCCC3300FFCC + 330000FF330033FF330066FF330099FF3300CCFF3300FFFF3300000066003300 + 66006600660099006600CC006600FF0066000033660033336600663366009933 + 6600CC336600FF33660000666600336666006666660099666600CC666600FF66 + 660000996600339966006699660099996600CC996600FF99660000CC660033CC + 660066CC660099CC6600CCCC6600FFCC660000FF660033FF660066FF660099FF + 6600CCFF6600FFFF660000009900330099006600990099009900CC009900FF00 + 990000339900333399006633990099339900CC339900FF339900006699003366 + 99006666990099669900CC669900FF6699000099990033999900669999009999 + 9900CC999900FF99990000CC990033CC990066CC990099CC9900CCCC9900FFCC + 990000FF990033FF990066FF990099FF9900CCFF9900FFFF99000000CC003300 + CC006600CC009900CC00CC00CC00FF00CC000033CC003333CC006633CC009933 + CC00CC33CC00FF33CC000066CC003366CC006666CC009966CC00CC66CC00FF66 + CC000099CC003399CC006699CC009999CC00CC99CC00FF99CC0000CCCC0033CC + CC0066CCCC0099CCCC00CCCCCC00FFCCCC0000FFCC0033FFCC0066FFCC0099FF + CC00CCFFCC00FFFFCC000000FF003300FF006600FF009900FF00CC00FF00FF00 + FF000033FF003333FF006633FF009933FF00CC33FF00FF33FF000066FF003366 + FF006666FF009966FF00CC66FF00FF66FF000099FF003399FF006699FF009999 + FF00CC99FF00FF99FF0000CCFF0033CCFF0066CCFF0099CCFF00CCCCFF00FFCC + FF0000FFFF0033FFFF0066FFFF0099FFFF00CCFFFF00FFFFFF000F0F0F0F0F0F + 0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F + 0F0F0F0F070000070F0F0F0F0F0F0F0F0F0F0F0F070000070F0F0F0F0F0F0F0F + 0F0F0F0F070000070F0F0F0F0F0F0FD40F0F0F0F070000070F0F0F0F0F0FD47E + 0F0F0F0F070000070F0F0F0F0FD453530F0F0F0F070000070F0F0F0FD4530053 + 0F0F0F0F070000070F0F0FD45300000007070707070000070F0F0F5300000000 + 00000000000000070F0F08070000000000000000000000070F0F0F0807000000 + 07070707070707070F0F0F0F080700000F0F0F0F0F0F0F0F0F0F0F0F0F080700 + 0F0F0F0F0F0F0F0F0F0F0F0F0F0F08000F0F0F0F0F0F0F0F0F0F} + ParentShowHint = False + ShowHint = True + OnClick = btTrgRotateLeft90Click + end + object btTrgRotateRight90: TSpeedButton + Left = 146 + Top = 17 + Width = 23 + Height = 24 + Hint = 'Rotate triangle 90'#176' clockwise' + Flat = True + Glyph.Data = { + 36050000424D3605000000000000360400002800000010000000100000000100 + 08000000000000010000C40E0000C40E00000001000000000000000000000000 + 8000008000000080800080000000800080008080000080808000C0C0C0000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000003300 + 00006600000099000000CC000000FF0000000033000033330000663300009933 + 0000CC330000FF33000000660000336600006666000099660000CC660000FF66 + 000000990000339900006699000099990000CC990000FF99000000CC000033CC + 000066CC000099CC0000CCCC0000FFCC000000FF000033FF000066FF000099FF + 0000CCFF0000FFFF000000003300330033006600330099003300CC003300FF00 + 330000333300333333006633330099333300CC333300FF333300006633003366 + 33006666330099663300CC663300FF6633000099330033993300669933009999 + 3300CC993300FF99330000CC330033CC330066CC330099CC3300CCCC3300FFCC + 330000FF330033FF330066FF330099FF3300CCFF3300FFFF3300000066003300 + 66006600660099006600CC006600FF0066000033660033336600663366009933 + 6600CC336600FF33660000666600336666006666660099666600CC666600FF66 + 660000996600339966006699660099996600CC996600FF99660000CC660033CC + 660066CC660099CC6600CCCC6600FFCC660000FF660033FF660066FF660099FF + 6600CCFF6600FFFF660000009900330099006600990099009900CC009900FF00 + 990000339900333399006633990099339900CC339900FF339900006699003366 + 99006666990099669900CC669900FF6699000099990033999900669999009999 + 9900CC999900FF99990000CC990033CC990066CC990099CC9900CCCC9900FFCC + 990000FF990033FF990066FF990099FF9900CCFF9900FFFF99000000CC003300 + CC006600CC009900CC00CC00CC00FF00CC000033CC003333CC006633CC009933 + CC00CC33CC00FF33CC000066CC003366CC006666CC009966CC00CC66CC00FF66 + CC000099CC003399CC006699CC009999CC00CC99CC00FF99CC0000CCCC0033CC + CC0066CCCC0099CCCC00CCCCCC00FFCCCC0000FFCC0033FFCC0066FFCC0099FF + CC00CCFFCC00FFFFCC000000FF003300FF006600FF009900FF00CC00FF00FF00 + FF000033FF003333FF006633FF009933FF00CC33FF00FF33FF000066FF003366 + FF006666FF009966FF00CC66FF00FF66FF000099FF003399FF006699FF009999 + FF00CC99FF00FF99FF0000CCFF0033CCFF0066CCFF0099CCFF00CCCCFF00FFCC + FF0000FFFF0033FFFF0066FFFF0099FFFF00CCFFFF00FFFFFF000F0F0F0F0F0F + 0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F07000007 + 0F0F0F0F0F0F0F0F0F0F0F0F070000070F0F0F0F0F0F0F0F0F0F0F0F07000007 + 0F0F0F0F0F0F0F0F0F0F0F0F070000070F0F0F0FD40F0F0F0F0F0F0F07000007 + 0F0F0F0F7ED40F0F0F0F0F0F070000070F0F0F0F5353D40F0F0F0F0F07000007 + 0F0F0F0F530053D40F0F0F0F070000070707070700000053D40F0F0F07000000 + 0000000000000000530F0F0F07000000000000000000000007080F0F07070707 + 0707070700000007080F0F0F0F0F0F0F0F0F0F0F000007080F0F0F0F0F0F0F0F + 0F0F0F0F0007080F0F0F0F0F0F0F0F0F0F0F0F0F00080F0F0F0F} + ParentShowHint = False + ShowHint = True + OnClick = btTrgRotateRight90Click + end + object btTrgScaleDown: TSpeedButton + Left = 32 + Top = 65 + Width = 23 + Height = 24 + Hint = 'Scale triangle down' + Flat = True + Glyph.Data = { + F6000000424DF600000000000000760000002800000010000000100000000100 + 0400000000008000000000000000000000001000000000000000000000000000 + 8000008000000080800080000000800080008080000080808000C0C0C0000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000 + 0FFFF000000000000FFFFF0000FFFFF00FFFFFF0000FFFF00FFFFFFFF000FFF0 + 0FFFFFFFFF000FF00FFFFFFFFFF000000FFFFFFFFFFF00000FFFFFFFFFFFFF00 + 0FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgScaleDownClick + end + object btTrgScaleUp: TSpeedButton + Left = 122 + Top = 65 + Width = 23 + Height = 24 + Hint = 'Scale triangle up' + Flat = True + Glyph.Data = { + F6000000424DF600000000000000760000002800000010000000100000000100 + 0400000000008000000000000000000000001000000000000000000000000000 + 8000008000000080800080000000800080008080000080808000C0C0C0000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FFFFFFFFFFFF + FFFFF00000000000000FF00000000000000FFF000FFFFFFFF00FFFF000FFFFFF + F00FFFFF000FFFFFF00FFFFFF000FFFFF00FFFFFFF000FFFF00FFFFFFFF000FF + F00FFFFFFFFF000FF00FFFFFFFFFF000F00FFFFFFFFFFF00000FFFFFFFFFFFF0 + 000FFFFFFFFFFFFF000FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgScaleUpClick + end + object btTrgMoveDown: TSpeedButton + Left = 32 + Top = 41 + Width = 23 + Height = 24 + Hint = 'Move triangle down' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000130B0000130B00000000000000000000FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF808080FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 + 0000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFF808080000000000000FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000 + 0000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFF808080000000000000000000000000FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 + 0000000000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF808080000000000000000000000000000000000000FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000 + 0000000000000000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFF808080000000808080808080000000000000C0C0C0404040000000FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF404040FFFFFFFFFFFF80808000 + 0000000000FFFFFFFFFFFFC0C0C0808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFF808080000000000000FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80808000 + 0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFF808080000000000000FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80808000 + 0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFF808080000000000000FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C000 + 0000404040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgMoveDownClick + end + object btTrgMoveLeft: TSpeedButton + Left = 122 + Top = 41 + Width = 23 + Height = 24 + Hint = 'Move triangle left' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000130B0000130B00000000000000000000FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF808080404040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFF808080000000000000FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80808000000000000000 + 0000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 8080800000000000000000000000000000008080808080808080808080808080 + 80808080808080C0C0C080808000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF808080 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000404040FFFFFFFFFFFFFFFFFF80808000000000000000000000 + 0000C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFF808080000000000000404040FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 + 8080000000C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF808080FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgMoveLeftClick + end + object btTrgMoveRight: TSpeedButton + Left = 146 + Top = 41 + Width = 23 + Height = 24 + Hint = 'Move triangle right' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000130B0000130B00000000000000000000FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40404080 + 8080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000808080FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 + 8080000000000000000000808080FFFFFFFFFFFFFFFFFFFFFFFFC0C0C0808080 + 8080808080808080808080808080808080800000000000000000000000000000 + 00808080FFFFFFFFFFFF00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000808080404040000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 + C0C0000000000000000000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF404040000000000000808080FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C000 + 0000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFF808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgMoveRightClick + end + object btTrgMoveUp: TSpeedButton + Left = 8 + Top = 41 + Width = 23 + Height = 24 + Hint = 'Move triangle up' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000130B0000130B00000000000000000000FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF404040000000C0C0C0FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 + 0000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000808080FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 + 0000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000808080FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 + 0000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFF808080C0C0C0FFFFFFFFFFFF000000000000808080FFFFFFFFFFFF4040 + 40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000404040C0C0C000 + 0000000000808080808080000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF808080000000000000000000000000000000000000000000FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 + 0000000000000000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFF808080000000000000000000000000000000FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000 + 0000000000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFF808080000000000000000000FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 + 0000000000808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF808080000000FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgMoveUpClick + end + object btTrgRotateLeft: TSpeedButton + Left = 32 + Top = 17 + Width = 23 + Height = 24 + Hint = 'Rotate triangle counter clockwise' + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000130B0000130B00000000000000000000FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFC0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF808080808080FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFF000000404040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0000000404040FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF404040000000404040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFF808080000000000000808080FFFFFFFFFFFF + FFFFFFFFFFFFE0E0E0606060FFFFFFFFFFFFFFFFFFFFFFFFE0E0E08080800000 + 00000000000000E0E0E0FFFFFFFFFFFFFFFFFFE0E0E0202020404040FFFFFFE0 + E0E0C0C0C0A0A0A0404040000000000000000000404040FFFFFFFFFFFFFFFFFF + E0E0E02020200000004040408080804040404040400000000000000000000000 + 00000000C0C0C0FFFFFFFFFFFFE0E0E020202000000000000000000000000000 + 0000000000000000000000000000404040404040FFFFFFFFFFFFFFFFFF202020 + 0000000000000000000000000000000000000000000000000000004040408080 + 80FFFFFFFFFFFFFFFFFFC0C0C080808000000000000000000000000000000000 + 0000000000404040808080808080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0 + 808080000000000000404040808080808080808080808080C0C0C0FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0808080000000202020808080C0 + C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFC0C0C0808080404040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0808080FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgRotateLeftClick + end + object btTrgRotateRight: TSpeedButton + Left = 122 + Top = 17 + Width = 23 + Height = 24 + Hint = 'Rotate triangle clockwise' + Flat = True + Glyph.Data = { + F6000000424DF600000000000000760000002800000010000000100000000100 + 04000000000080000000130B0000130B00001000000000000000000000000000 + 8000008000000080800080000000800080008080000080808000C0C0C0000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FFFFFFFFFFFF + FFFF77FFFFFFFFFFFFFF70FFFFFFFFFFFFFF708FFFFFFFFFFFFF707FFFFFFFFF + FFFF7007FFFFFFFFFFFFF0007FFFFF7FFFFFF7000788FF70FFFFF80000077770 + 0FFFFF770000000000FFFFF770000000000FFFFF777000000078FFFFF8777770 + 078FFFFFFFFF870078FFFFFFFFFFFF778FFFFFFFFFFFFF78FFFF} + ParentShowHint = False + ShowHint = True + OnClick = btTrgRotateRightClick + end + object txtTrgScaleValue: TComboBox + Left = 56 + Top = 66 + Width = 65 + Height = 21 + AutoComplete = False + ItemIndex = 1 + TabOrder = 2 + Text = '125' + OnExit = txtValidateValue + OnKeyPress = txtValKeyPress + OnSelect = txtValidateValue + Items.Strings = ( + '110' + '125' + '150' + '175' + '200') + end + object txtTrgRotateValue: TComboBox + Left = 56 + Top = 18 + Width = 65 + Height = 21 + AutoComplete = False + TabOrder = 0 + Text = '15' + OnExit = txtValidateValue + OnKeyPress = txtValKeyPress + OnSelect = txtValidateValue + Items.Strings = ( + '5' + '15' + '30' + '45' + '60' + '90' + '120' + '180') + end + object txtTrgMoveValue: TComboBox + Left = 56 + Top = 42 + Width = 65 + Height = 21 + AutoComplete = False + ItemIndex = 3 + TabOrder = 1 + Text = '0.1' + OnExit = txtValidateValue + OnKeyPress = txtValKeyPress + OnSelect = txtValidateValue + Items.Strings = ( + '1' + '0.5' + '0.25' + '0.1' + '0.05' + '0.025' + '0.01') + end + end + object GroupBox6: TGroupBox + Left = 6 + Top = 0 + Width = 209 + Height = 105 + Ctl3D = True + ParentCtl3D = False + TabOrder = 0 + DesignSize = ( + 209 + 105) + object LabelC: TLabel + Left = 8 + Top = 48 + Width = 10 + Height = 13 + Caption = 'Y:' + end + object LabelA: TLabel + Left = 8 + Top = 24 + Width = 10 + Height = 13 + Caption = 'X:' + end + object LabelB: TLabel + Left = 8 + Top = 72 + Width = 12 + Height = 13 + Caption = 'O:' + end + object txtAx: TEdit + Left = 28 + Top = 20 + Width = 83 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + Text = '0' + OnExit = CornerEditExit + OnKeyPress = CornerEditKeyPress + end + object txtAy: TEdit + Left = 117 + Top = 20 + Width = 86 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + Text = '0' + OnExit = CornerEditExit + OnKeyPress = CornerEditKeyPress + end + object txtBx: TEdit + Left = 28 + Top = 68 + Width = 83 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 4 + Text = '0' + OnExit = CornerEditExit + OnKeyPress = CornerEditKeyPress + end + object txtBy: TEdit + Left = 117 + Top = 68 + Width = 86 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 5 + Text = '0' + OnExit = CornerEditExit + OnKeyPress = CornerEditKeyPress + end + object txtCx: TEdit + Left = 28 + Top = 44 + Width = 83 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 2 + Text = '0' + OnExit = CornerEditExit + OnKeyPress = CornerEditKeyPress + end + object txtCy: TEdit + Left = 117 + Top = 44 + Width = 86 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 3 + Text = '0' + OnExit = CornerEditExit + OnKeyPress = CornerEditKeyPress + end + end + object GroupBox3: TGroupBox + Left = 6 + Top = 248 + Width = 209 + Height = 65 + Caption = 'Pivot Point' + TabOrder = 2 + object btnResetPivot: TSpeedButton + Left = 6 + Top = 40 + Width = 17 + Height = 17 + Hint = 'Reset pivot point to (0, 0)' + Caption = 'R' + ParentShowHint = False + ShowHint = True + OnClick = btnResetPivotClick + end + object btnPickPivot: TSpeedButton + Left = 184 + Top = 40 + Width = 16 + Height = 17 + Hint = 'Pick pivot point using mouse' + Caption = 'P' + ParentShowHint = False + ShowHint = True + OnClick = btnPickPivotClick + end + object btnPivotMode: TSpeedButton + Left = 24 + Top = 40 + Width = 160 + Height = 17 + Hint = 'Toggle pivot point mode' + Caption = 'Local Pivot' + ParentShowHint = False + ShowHint = True + OnClick = btnPivotModeClick + end + object editPivotY: TEdit + Left = 111 + Top = 13 + Width = 93 + Height = 21 + Hint = 'Pivot point coordinates in chosen coordinate system' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + Text = '0' + OnExit = PivotValidate + OnKeyPress = PivotKeyPress + end + object editPivotX: TEdit + Left = 6 + Top = 16 + Width = 99 + Height = 21 + Hint = 'Pivot point coordinates in chosen coordinate system' + ParentShowHint = False + ShowHint = True + TabOrder = 0 + Text = '0' + OnExit = PivotValidate + OnKeyPress = PivotKeyPress + end + end + end + end + end + object tabXForm: TTabSheet + Caption = 'Transform' + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 + object ScrollBox1: TScrollBox + Left = 0 + Top = 0 + Width = 290 + Height = 420 + HorzScrollBar.Visible = False + Align = alClient + BorderStyle = bsNone + TabOrder = 0 + OnResize = ScrollBox1Resize + DesignSize = ( + 290 + 420) + object GroupBox9: TGroupBox + Left = 8 + Top = 4 + Width = 225 + Height = 113 + TabOrder = 0 + object btnXcoefs: TSpeedButton + Left = 8 + Top = 12 + Width = 25 + Height = 21 + Hint = 'Reset vector X' + Caption = 'X' + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnXcoefsClick + end + object btnYcoefs: TSpeedButton + Left = 8 + Top = 36 + Width = 25 + Height = 21 + Hint = 'Reset vector Y' + Caption = 'Y' + ParentShowHint = False + ShowHint = True + OnClick = btnYcoefsClick + end + object btnOcoefs: TSpeedButton + Left = 8 + Top = 60 + Width = 25 + Height = 21 + Hint = 'Reset vector O' + Caption = 'O' + ParentShowHint = False + ShowHint = True + OnClick = btnOcoefsClick + end + object btnResetCoefs: TSpeedButton + Left = 8 + Top = 84 + Width = 209 + Height = 22 + Hint = 'Reset all vectors to default position' + Caption = 'Reset transform' + ParentShowHint = False + ShowHint = True + OnClick = btnResetCoefsClick + end + object txtA: TEdit + Left = 36 + Top = 12 + Width = 85 + Height = 21 + TabOrder = 0 + Text = '0' + OnExit = CoefValidate + OnKeyPress = CoefKeyPress + end + object txtB: TEdit + Left = 128 + Top = 12 + Width = 89 + Height = 21 + TabOrder = 1 + Text = '0' + OnExit = CoefValidate + OnKeyPress = CoefKeyPress + end + object txtC: TEdit + Left = 36 + Top = 36 + Width = 85 + Height = 21 + TabOrder = 2 + Text = '0' + OnExit = CoefValidate + OnKeyPress = CoefKeyPress + end + object txtD: TEdit + Left = 128 + Top = 36 + Width = 89 + Height = 21 + TabOrder = 3 + Text = '0' + OnExit = CoefValidate + OnKeyPress = CoefKeyPress + end + object txtE: TEdit + Left = 36 + Top = 60 + Width = 85 + Height = 21 + TabOrder = 4 + Text = '0' + OnExit = CoefValidate + OnKeyPress = CoefKeyPress + end + object txtF: TEdit + Left = 127 + Top = 63 + Width = 89 + Height = 21 + TabOrder = 5 + Text = '0' + OnExit = CoefValidate + OnKeyPress = CoefKeyPress + end + end + object GroupBox7: TGroupBox + Left = 8 + Top = 229 + Width = 225 + Height = 37 + TabOrder = 1 + object btnCoefsPolar: TSpeedButton + Left = 112 + Top = 12 + Width = 105 + Height = 17 + Hint = 'Show vectors in polar coordinates' + GroupIndex = 1 + Caption = 'Polar (deg)' + ParentShowHint = False + ShowHint = True + OnClick = btnCoefsModeClick + end + object btnCoefsRect: TSpeedButton + Left = 10 + Top = 12 + Width = 103 + Height = 17 + Hint = 'Show vectors in rectangular (cartesian) coordinates' + GroupIndex = 1 + Down = True + Caption = 'Rectangular' + ParentShowHint = False + ShowHint = True + OnClick = btnCoefsModeClick + end + end + object GroupBox8: TGroupBox + Left = 8 + Top = 116 + Width = 225 + Height = 113 + TabOrder = 2 + object btnXpost: TSpeedButton + Left = 8 + Top = 12 + Width = 25 + Height = 21 + Hint = 'Reset vector X' + Caption = 'X' + ParentShowHint = False + ShowHint = True + OnClick = btnXpostClick + end + object btnYpost: TSpeedButton + Left = 8 + Top = 36 + Width = 25 + Height = 21 + Hint = 'Reset vector Y' + Caption = 'Y' + ParentShowHint = False + ShowHint = True + OnClick = btnYpostClick + end + object btnOpost: TSpeedButton + Left = 8 + Top = 60 + Width = 25 + Height = 21 + Hint = 'Reset vector O' + Caption = 'O' + ParentShowHint = False + ShowHint = True + OnClick = btnOpostClick + end + object btnResetPostCoefs: TSpeedButton + Left = 8 + Top = 84 + Width = 213 + Height = 22 + Hint = 'Reset post-transform vectors to defaults' + Caption = 'Reset post-transform' + ParentShowHint = False + ShowHint = True + OnClick = btnResetPostCoefsClick + end + object txtPost00: TEdit + Left = 36 + Top = 12 + Width = 85 + Height = 21 + TabOrder = 0 + Text = '0' + OnExit = PostCoefValidate + OnKeyPress = PostCoefKeypress + end + object txtPost01: TEdit + Left = 128 + Top = 12 + Width = 89 + Height = 21 + TabOrder = 1 + Text = '0' + OnExit = PostCoefValidate + OnKeyPress = PostCoefKeypress + end + object txtPost10: TEdit + Left = 36 + Top = 36 + Width = 85 + Height = 21 + TabOrder = 2 + Text = '0' + OnExit = PostCoefValidate + OnKeyPress = PostCoefKeypress + end + object txtPost11: TEdit + Left = 128 + Top = 36 + Width = 89 + Height = 21 + TabOrder = 3 + Text = '0' + OnExit = PostCoefValidate + OnKeyPress = PostCoefKeypress + end + object txtPost20: TEdit + Left = 36 + Top = 60 + Width = 85 + Height = 21 + TabOrder = 4 + Text = '0' + OnExit = PostCoefValidate + OnKeyPress = PostCoefKeypress + end + object txtPost21: TEdit + Left = 128 + Top = 60 + Width = 89 + Height = 21 + TabOrder = 5 + Text = '0' + OnExit = PostCoefValidate + OnKeyPress = PostCoefKeypress + end + end + object chkAutoZscale: TCheckBox + Left = 8 + Top = 273 + Width = 275 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Auto calculate pre_zscale' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + OnClick = chkAutoZscaleClick + end + end + end + object tabColors: TTabSheet + Caption = 'Colors' + ImageIndex = 3 + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 + object GroupBox4: TGroupBox + Left = 8 + Top = 336 + Width = 225 + Height = 65 + Caption = 'Transform visibility' + TabOrder = 0 + Visible = False + object chkXformInvisible: TCheckBox + Left = 8 + Top = 32 + Width = 209 + Height = 17 + Caption = 'Invisible' + TabOrder = 0 + OnClick = chkPlotModeClick + end + end + object ScrollBox2: TScrollBox + Left = 0 + Top = 0 + Width = 290 + Height = 420 + HorzScrollBar.Visible = False + Align = alClient + BorderStyle = bsNone + TabOrder = 1 + OnResize = ScrollBox2Resize + DesignSize = ( + 290 + 420) + object GroupBox1: TGroupBox + Left = 6 + Top = 2 + Width = 281 + Height = 199 + Anchors = [akLeft, akTop, akRight] + Caption = 'Transform color' + TabOrder = 0 + DesignSize = ( + 281 + 199) + object pnlSymmetry: TPanel + Left = 8 + Top = 78 + Width = 97 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Color speed:' + ParentShowHint = False + ShowHint = True + TabOrder = 7 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlXFormColor: TPanel + Left = 8 + Top = 16 + Width = 73 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelInner = bvRaised + BevelOuter = bvLowered + BorderStyle = bsSingle + ParentShowHint = False + ShowHint = True + TabOrder = 6 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + object shColor: TShape + Left = -1 + Top = -1 + Width = 75 + Height = 25 + OnMouseDown = shColorMouseDown + OnMouseMove = shColorMouseMove + OnMouseUp = shColorMouseUp + end + end + object txtXFormColor: TEdit + Left = 80 + Top = 16 + Width = 192 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + OnExit = txtXFormColorExit + OnKeyPress = txtXFormColorKeyPress + end + object txtSymmetry: TEdit + Left = 104 + Top = 78 + Width = 168 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 2 + Text = '0' + OnExit = txtSymmetrySet + OnKeyPress = txtSymmetrKeyPress + end + object ColorBar: TPanel + Left = 8 + Top = 40 + Width = 264 + Height = 17 + Anchors = [akLeft, akTop, akRight] + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clAppWorkSpace + TabOrder = 8 + OnMouseUp = ColorBarMouseUp + object ColorBarPicture: TImage + Left = 1 + Top = 1 + Width = 258 + Height = 11 + Align = alClient + Stretch = True + OnMouseUp = ColorBarMouseUp + end + end + object scrlXFormColor: TScrollBar + Left = 9 + Top = 54 + Width = 263 + Height = 15 + Anchors = [akLeft, akTop, akRight] + LargeChange = 10 + Max = 1000 + PageSize = 0 + TabOrder = 1 + OnChange = scrlXFormColorChange + OnScroll = scrlXFormColorScroll + end + object pnlOpacity: TPanel + Left = 8 + Top = 108 + Width = 97 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Opacity:' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object txtOpacity: TEdit + Left = 104 + Top = 108 + Width = 168 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 3 + Text = '1' + OnExit = txtOpacitySet + OnKeyPress = txtOpacityKeyPress + end + object chkXformSolo: TCheckBox + Left = 8 + Top = 176 + Width = 264 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Solo' + TabOrder = 5 + OnClick = chkXformSoloClick + end + object pnlDC: TPanel + Left = 8 + Top = 140 + Width = 97 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Direct color:' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object txtDC: TEdit + Left = 104 + Top = 140 + Width = 168 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 4 + Text = '1' + OnExit = txtDCSet + OnKeyPress = txtDCKeyPress + end + end + object GroupBox2: TGroupBox + Left = 6 + Top = 207 + Width = 281 + Height = 121 + Anchors = [akLeft, akTop, akRight] + Caption = 'Variation preview' + TabOrder = 1 + DesignSize = ( + 281 + 121) + object Label1: TLabel + Left = 8 + Top = 24 + Width = 31 + Height = 13 + Caption = 'Range' + end + object Label2: TLabel + Left = 8 + Top = 56 + Width = 29 + Height = 13 + Caption = 'Depth' + end + object Label3: TLabel + Left = 8 + Top = 88 + Width = 36 + Height = 13 + Caption = 'Density' + end + object trkVarPreviewDensity: TTrackBar + Left = 88 + Top = 88 + Width = 184 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Max = 5 + Min = 1 + ParentShowHint = False + PageSize = 1 + Position = 2 + ShowHint = True + TabOrder = 2 + ThumbLength = 15 + OnChange = trkVarPreviewDensityChange + end + object trkVarPreviewRange: TTrackBar + Left = 88 + Top = 24 + Width = 184 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Max = 5 + Min = 1 + ParentShowHint = False + PageSize = 1 + Position = 2 + ShowHint = True + TabOrder = 0 + ThumbLength = 15 + OnChange = trkVarPreviewRangeChange + end + object trkVarPreviewDepth: TTrackBar + Left = 88 + Top = 56 + Width = 184 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Max = 5 + Min = 1 + ParentShowHint = False + PageSize = 1 + Position = 1 + ShowHint = True + TabOrder = 1 + ThumbLength = 15 + OnChange = trkVarPreviewDepthChange + end + end + end + end + object tabVariations: TTabSheet + Caption = 'Variations' + DesignSize = ( + 290 + 420) + object Label4: TLabel + Left = 2 + Top = 8 + Width = 37 + Height = 13 + Caption = 'Search:' + end + object SpeedButton1: TSpeedButton + Left = 268 + Top = 7 + Width = 17 + Height = 17 + Caption = 'r' + Flat = True + Font.Charset = SYMBOL_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Marlett' + Font.Style = [] + ParentFont = False + OnClick = btnResetSearchClick + end + object btnLoadVVAR: TButton + Left = 0 + Top = 392 + Width = 97 + Height = 25 + Anchors = [akLeft, akBottom] + Caption = 'Load variation...' + Enabled = False + TabOrder = 4 + Visible = False + OnClick = btnLoadVVARClick + end + object VEVars: TValueListEditor + Left = 0 + Top = 32 + Width = 290 + Height = 335 + Anchors = [akLeft, akTop, akRight, akBottom] + DefaultColWidth = 90 + ScrollBars = ssVertical + TabOrder = 1 + TitleCaptions.Strings = ( + 'Variation' + 'Value') + OnDblClick = VEVarsDblClick + OnDrawCell = VEVarsDrawCell + OnExit = VEVarsChange + OnKeyPress = VEVarsKeyPress + OnMouseDown = VEVarsMouseDown + OnMouseMove = VEVarsMouseMove + OnMouseUp = VEVarsMouseUp + OnValidate = VEVarsValidate + ColWidths = ( + 90 + 194) + end + object chkCollapseVariations: TCheckBox + Left = 1 + Top = 373 + Width = 291 + Height = 17 + Anchors = [akLeft, akRight, akBottom] + Caption = 'Hide non-used variations' + TabOrder = 2 + OnClick = chkCollapseVariationsClick + end + object bClear: TBitBtn + Left = 0 + Top = 392 + Width = 289 + Height = 25 + Anchors = [akLeft, akRight, akBottom] + Caption = 'Clear' + TabOrder = 3 + OnClick = bClearClick + end + object txtSearchBox: TEdit + Left = 45 + Top = 5 + Width = 217 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + OnChange = txtSearchBoxChange + end + end + object TabSheet4: TTabSheet + Caption = 'Variables' + ImageIndex = 4 + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 + DesignSize = ( + 290 + 420) + object vleVariables: TValueListEditor + Left = 0 + Top = 0 + Width = 290 + Height = 396 + Align = alTop + Anchors = [akLeft, akTop, akRight, akBottom] + ScrollBars = ssVertical + TabOrder = 0 + TitleCaptions.Strings = ( + 'Variable' + 'Value') + OnDblClick = VEVarsDblClick + OnExit = vleVariablesExit + OnKeyPress = vleVariablesKeyPress + OnMouseDown = VEVarsMouseDown + OnMouseMove = VEVarsMouseMove + OnMouseUp = VEVarsMouseUp + OnValidate = vleVariablesValidate + ColWidths = ( + 93 + 191) + end + object chkCollapseVariables: TCheckBox + Left = 0 + Top = 399 + Width = 291 + Height = 17 + Anchors = [akLeft, akRight, akBottom] + Caption = 'Show all variables' + TabOrder = 1 + OnClick = chkCollapseVariablesClick + end + end + object TabChaos: TTabSheet + Caption = 'Xaos' + ImageIndex = 5 + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 0 + ExplicitHeight = 0 + DesignSize = ( + 290 + 420) + object vleChaos: TValueListEditor + Left = 0 + Top = 0 + Width = 290 + Height = 375 + Align = alCustom + Anchors = [akLeft, akTop, akRight, akBottom] + PopupMenu = ChaosPopup + ScrollBars = ssVertical + TabOrder = 0 + TitleCaptions.Strings = ( + 'Path' + 'Weight modifier') + OnDblClick = VEVarsDblClick + OnDrawCell = VleChaosDrawCell + OnExit = vleChaosExit + OnKeyPress = vleChaosKeyPress + OnMouseDown = VEVarsMouseDown + OnMouseMove = VEVarsMouseMove + OnMouseUp = VEVarsMouseUp + OnValidate = vleChaosValidate + ColWidths = ( + 93 + 191) + end + object optFrom: TRadioButton + Left = 0 + Top = 398 + Width = 291 + Height = 17 + Anchors = [akLeft, akRight, akBottom] + Caption = 'View links as "from"' + TabOrder = 2 + TabStop = True + OnClick = mnuChaosViewFromClick + end + object optTo: TRadioButton + Left = 0 + Top = 382 + Width = 291 + Height = 17 + Anchors = [akLeft, akRight, akBottom] + Caption = 'View links as "to"' + Checked = True + TabOrder = 1 + TabStop = True + OnClick = mnuChaosViewToClick + end + end + end + object pnlWeight: TPanel + Left = 8 + Top = 47 + Width = 121 + Height = 21 + Cursor = crHandPoint + Hint = 'Click and drag to change value' + BevelOuter = bvLowered + Caption = ' Weight:' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object Panel1: TPanel + Left = 8 + Top = 6 + Width = 121 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = ' Transform:' + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object Panel2: TPanel + Left = 8 + Top = 26 + Width = 121 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = ' Name:' + ParentShowHint = False + ShowHint = True + TabOrder = 6 + end + object txtName: TEdit + Left = 128 + Top = 26 + Width = 163 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + OnExit = txtNameExit + OnKeyPress = txtNameKeyPress + end + object txtP: TEdit + Left = 128 + Top = 47 + Width = 163 + Height = 21 + Hint = '"Weight" is the probability of this transform to be applied' + Anchors = [akLeft, akTop, akRight] + TabOrder = 2 + Text = '0' + OnExit = txtPExit + OnKeyPress = txtPKeyPress + end + object cbTransforms: TComboBox + Left = 128 + Top = 6 + Width = 163 + Height = 19 + BevelEdges = [] + BevelOuter = bvNone + Style = csOwnerDrawFixed + Anchors = [akLeft, akTop, akRight] + Color = clBlack + Ctl3D = False + DropDownCount = 12 + ItemHeight = 13 + ParentCtl3D = False + TabOrder = 0 + OnChange = cbTransformsChange + OnDrawItem = cbTransformsDrawItem + end + end + object PrevPnl: TPanel + Left = 0 + Top = 0 + Width = 300 + Height = 177 + Align = alTop + BevelOuter = bvLowered + Color = clAppWorkSpace + TabOrder = 1 + Visible = False + object PreviewImage: TImage + Left = 1 + Top = 1 + Width = 298 + Height = 175 + PopupMenu = QualityPopup + Proportional = True + end + end + end + end + object EditPopup: TPopupMenu + Images = EditorTB + Left = 400 + Top = 112 + object mnuUndo: TMenuItem + Caption = 'Undo' + Enabled = False + Hint = 'Undo' + ImageIndex = 4 + ShortCut = 16474 + OnClick = mnuUndoClick + end + object mnuRedo: TMenuItem + Caption = 'Redo' + Enabled = False + Hint = 'Redo' + ImageIndex = 5 + ShortCut = 16473 + OnClick = mnuRedoClick + end + object N4: TMenuItem + Caption = '-' + end + object mnuAdd: TMenuItem + Caption = 'Add transform' + Hint = 'Add new triangle' + ImageIndex = 1 + OnClick = mnuAddClick + end + object N1: TMenuItem + Caption = '-' + end + object mnuAutoZoom: TMenuItem + Caption = 'Auto Zoom' + Hint = 'Zoom to fit all triangles' + ImageIndex = 19 + OnClick = mnuAutoZoomClick + end + object mnuShowVarPreview: TMenuItem + Caption = 'Show Variation Preview' + Hint = 'Show/hide variation preview' + ImageIndex = 14 + OnClick = tbVarPreviewClick + end + object N8: TMenuItem + Caption = '-' + end + object mnuSelectmode: TMenuItem + Caption = 'Select mode' + ImageIndex = 6 + OnClick = tbSelectClick + end + object mnuExtendedEdit: TMenuItem + Caption = 'Extended edit mode' + Hint = 'Toggle extended edit mode' + ImageIndex = 25 + OnClick = tbExtendedEditClick + end + object mnuAxisLock: TMenuItem + Caption = 'Lock transform axes' + ImageIndex = 16 + OnClick = tbAxisLockClick + end + object oggleposttriangleediting1: TMenuItem + Caption = 'Toggle post-triangle editing' + ImageIndex = 29 + OnClick = tbPostXswapClick + end + object N5: TMenuItem + Caption = '-' + end + object mnuFlipAllV: TMenuItem + Caption = 'Flip All Vertical ' + Hint = 'Flip all triangles vertical' + ImageIndex = 13 + OnClick = mnuFlipAllVClick + end + object mnuFlipAllH: TMenuItem + Caption = 'Flip All Horizontal' + Hint = 'Flip all triangles horizontal' + ImageIndex = 12 + OnClick = mnuFlipAllHClick + end + object N11: TMenuItem + Caption = '-' + end + object mnuEHighQuality: TMenuItem + Caption = 'High quality' + RadioItem = True + OnClick = mnuHighQualityClick + end + object mnuEMediumQuality: TMenuItem + Caption = 'Medium quality' + Checked = True + RadioItem = True + OnClick = mnuMediumQualityClick + end + object mnuELowQuality: TMenuItem + Caption = 'Low quality' + RadioItem = True + OnClick = mnuLowQualityClick + end + end + object QualityPopup: TPopupMenu + Images = MainForm.Buttons + Left = 384 + Top = 40 + object mnuLowQuality: TMenuItem + Caption = 'Low Quality' + RadioItem = True + OnClick = mnuLowQualityClick + end + object mnuMediumQuality: TMenuItem + Caption = 'Medium Quality' + Checked = True + RadioItem = True + OnClick = mnuMediumQualityClick + end + object mnuHighQuality: TMenuItem + Caption = 'High Quality' + RadioItem = True + OnClick = mnuHighQualityClick + end + object N3: TMenuItem + Caption = '-' + end + object mnuResetLoc: TMenuItem + Caption = 'Auto reset location' + OnClick = mnuResetLocClick + end + end + object EditorTB: TImageList + Left = 313 + Top = 40 + Bitmap = { + 494C010120003000240010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000009000000001002000000000000090 + 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 + 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 + 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 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000707070007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000707070007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000007070700070707000FED2B900FED1B800FDD0B700FCCF + B500FCCEB4007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000007070700070707000FED2B900FED1B800FDD0B700FCCF + B500FCCEB4007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000007070700070707000FED2B900FDD1B800FDD0 + B600FCCEB5007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000070707000707070007070 + 7000707070007070700070707000707070007070700070707000707070007070 + 7000FCCEB5007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000007070700070707000FED1B900FDD0 + B700FCCFB6007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000707070007070 + 7000707070007070700070707000707070007070700070707000707070007070 + 7000FCCFB6007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007070700070707000FDD1 + B800FDD0B7007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000007070 + 700070707000FEFEFE00FAF7F500F5EDE900EFE3DC00EAD9D100707070007070 + 7000FDD0B7007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000707070007070 + 7000FDD0B8007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00007070700070707000FDFCFB00F8F3F000F2E9E300EDDFD800707070007070 + 7000FDD0B8007070700070707000000000005A5A5A0000000000000000000000 + 00005A5A5A0000000000000000000000000000000000000000005A5A5A000000 + 000000000000000000005A5A5A000000000000000000B9530000000000000000 + 0000BA520200B9530000000000000000000000000000B9530000000000007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000007070700070707000FBF8F700F6EFEB00F0E5DF00707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B9530000000000000000 + 000000000000B95300000000000000000000B953000000000000000000000000 + 0000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000A5A5A5000000000000000000000000000000000000000000000000000000 + 000000000000000000007070700070707000F9F5F200F4EBE600707070007070 + 700070707000707070007070700000000000000000005A5A5A00000000005A5A + 5A00000000000000000000000000000000000000000000000000000000005A5A + 5A00000000005A5A5A00000000000000000000000000B9530000000000000000 + 00000000000000000000B9530000B95300000000000000000000000000000000 + 0000000000007070700070707000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000A5A5 + A5000000000000000000000000000000000000000000000000008E7A17006B53 + 17000000000000000000000000007070700070707000F7F1EE00707070007070 + 7000000000007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B9530000B9530000B953 + 0000B953000000000000B9530000B95300000000000000000000000000000000 + 0000000000000000000070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000A5A5A5000000 + 00000000000000000000000000000000000000000000000000008FBC49007E6D + 1200000000000000000000000000000000007070700070707000707070007070 + 70000000000000000000707070000000000000000000000000005A5A5A000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00005A5A5A0000000000000000000000000000000000B9530000000000000000 + 0000B9530000000000000000000000000000B953000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000A5A5A500000000000000 + 00000000000000000000000000000000000096C66200A6D17C00BBE1A20091C4 + 520089771400624D170000000000000000000000000070707000707070007070 + 7000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B9530000B9530000B953 + 0000B953000000000000000000000000000000000000B9530000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000A5A5A50000000000000000000000 + 000000000000000000000000000000000000B0D88900CFE9BB00D6EFCD00C0E4 + AA008FBE4B008E7D140000000000000000000000000000000000707070007070 + 7000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEE9BB00B1D7 + 8D00000000000000000000000000000000000000000000000000000000007070 + 7000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B1D98B00A0CD + 7500000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000707070007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000081685500262F3800262F3800262F3800262F3800262F + 3800262F3800262F3800262F3800262F38000000000000000000000000000000 + 0000000000007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000BA6E4700AA542900AA542900A25027009B4C25009648 + 23008F4622008A4321008641200000000000BCCCD200647E8E004F5E6F004552 + 610037414D00262F380089715E00E8DCD300B7A29300B7A29300B7A29300B7A2 + 9300B7A29300B7A29300B7A29300262F38000000000000000000000000000000 + 0000000000000000000070707000707070001FDC6F001EDB6E001EDA6C001DD8 + 6B001CD769007070700070707000000000000000000000000000000000000000 + 0000000000000000000042636300000000004263630000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C1795500FDF9F600CEB09C00CCAF9B00CAAD9A00C7AC + 9900C6AB9800C4A997008943210000000000717F8B0022B6EC00008FCD00008F + CD00008FCD00008FCD0091796600EFE6E100E8DBD300E0D0C600DAC6BC00D4BF + B200CFB9AB00CCB6A800B7A29300262F38000000000000000000000000000000 + 000000000000000000000000000070707000707070001FDB6E001EDA6D001DD9 + 6C001DD86A007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C9856400FFFFFF00DA8C5C00D1835100D1835100D183 + 5100D1835100C6AB98008E452200000000007584900068C8EA0010B5F00008AC + EB0003A4E3000096D4009A826F00F7F1EF00C3AE9E00C3AE9E00BDA89800B7A2 + 9300D4BFB200B7A29300B7A29300262F38000000000000000000000000000000 + 00000000000000000000000000000000000070707000707070001FDB6E001EDA + 6D001DD96B007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B7A2930063493500634935006349 + 35006349350063493500D1927300FFFFFF00FEFDFB00FBEFEA00F5DED300F0CE + BE00EDC3AF00C7AC990092472300000000007989940074D0ED0028BDF10011B5 + F00007ABEA00009DDC00A28A7800FDFBFA00F7F2EE00EFE6E100E8DBD300E0D0 + C600705A4A0061524600504842003F3D3E000000000000000000000000000000 + 0000000000000000000000000000000000000000000070707000707070001EDB + 6D001ED96C007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B7A29300F8F3F000EADFD700E6D9 + CF00E1D2C700DDCBBF00D89F8200FFFFFF00F3A77F00E7976E00DA8C5C00D183 + 5100D1835100CAAE9A00984A2500000000007E8E9A0083D9F00046C9F2002DBF + F20016B7F10000A0E200A9928000FFFFFF00C3AE9E00C3AE9E00BDA89900E8DC + D3007A604D00D4C5BA0061524700000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000707070007070 + 70001EDA6D007070700070707000000000000000000000000000426363000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000042636300000000000000000000000000B7A29300FBF8F700E5AE8100DEA1 + 7300DA9C6E00D5976800E0AA9000FFFFFF00FFFFFF00FFFFFF00FBF4F000F7E4 + DB00F2D3C500CCAE9A009D4D25000000000082949E0091E2F30066D5F4004CCB + F30032C2F20015AFE900B0998800FFFFFF00FFFFFF00FCFBF900F7F1EF00EFE7 + E100816856007A604D0000000000000000000000000000B93400000000000000 + 000002B8360000B9340000000000000000000000000000B93400000000007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000BBA69700FEFDFC00FBF6F500F6EF + EB00F1E6E000ECDED600E7B59C00FFFFFF00FCAE8A00FCAE8A00F1DBD200E78E + 6000B3572A00AC542900A4502700000000008699A2009FEAF60083E1F6006BD8 + F50053CEF4000EB3F000B6A08E00B0998800A9928000A28A78009A8270009179 + 670089715E000000000000000000000000000000000000B93400000000000000 + 00000000000000B93400000000000000000000B9340000000000000000000000 + 0000707070007070700070707000000000000000000000000000426363000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000042636300000000000000000000000000C1AB9C00FFFFFF00FAC59F00F0B8 + 8E00E5AE8100DEA17300ECBDA600FFFFFF00FFFFFF00FFFFFF00FFFFFF00EA9A + 7200F0C9B200B1572B00EDD7CD00000000008A9EA600A9F0F80099EAF80088E3 + F5006DD1EA0013A1D40013A1D40012A0D3000D97CF000791CA00008FCD00008F + CD00303944000000000000000000000000000000000000B93400000000000000 + 0000000000000000000000B9340000B934000000000000000000000000000000 + 0000000000007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C7B2A300FFFFFF00FFFFFF00FCFA + F900F8F2F000F3EAE600F0C4AE00FFFFFF00FFFFFF00FFFFFF00FFFFFF00EBA7 + 8500C5653500F1DBCF0000000000000000008DA1AA00AAF1F900A7F0F9005E7D + 8A0058737F00566D7A00526977004F6673004C617000445A6800236F9000008F + CD003E4A58000000000000000000000000000000000000B9340000B9340000B9 + 340000B934000000000000B9340000B934000000000000000000000000000000 + 0000000000000000000070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000CFB9A900FFFFFF00FFDABA00FFD0 + AE00F0DED200B7A29300F0C4AE00EFC2AB00EFC1AA00EFB9A000EDB09200EDB0 + 9200F9E4D9000000000000000000000000008FA4AC00AAF1F900A8F1F9005D86 + 96008CC6CF0093E4F0007AD5E70062C6DE004F9AB2003E5A67001C7DA500008F + CD004B5969000000000000000000000000000000000000B93400000000000000 + 00000000000000000000000000000000000000B9340000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000D4BEAF00FFFFFF00FFFFFF00FFFF + FF00FEFDFC00BBA69600D4C5BA008F725B00E2DDD90000000000000000000000 + 0000000000000000000000000000000000008FA4AC00ABF0F700AAF1F900A6EF + F7007397A200A1ECF500667D8A0078C5D6004C6C7C00346178005FC3E80022B6 + EC004E5E6F000000000000000000000000000000000000B9340000B9340000B9 + 340000B9340000B9340000000000000000000000000000B93400000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000042636300000000004263630000000000000000000000 + 000000000000000000000000000000000000D8C2B200FFFFFF00FFFFFF00FFFF + FF00FFFFFF00C7B1A200A5826600E2DDD9000000000000000000000000000000 + 000000000000000000000000000000000000B7CACF008FA4AC008FA4AC008FA4 + AC005B8D9F00A5E8EF009BE8F4008CD5E2004666760073858F007A8A95007585 + 9100BDCED3000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000D8C2B200D8C2B200D4BFAE00D4BF + AE00CEB8A900C8B2A300E9E2DE00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000086B3C30082ADBD00799FB000BCCED30000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000006300000000000000630000000000000063000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000063000000630000006300000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000630000000000 + 0000630000000000000063000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000006300 + 0000000000000000000000000000630000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000006300 + 0000630000006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000063000000630000006300000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000063000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000006300000063000000630000006300 + 0000630000006300000063000000FFFFFF006300000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000006300000063000000630000006300 + 0000630000006300000063000000630000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000005252 + 5200000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000063000000630000006300000000000000000000005252 + 5200000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000005252 + 5200000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000000000000000000005252 + 5200000000000000000063000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000525252000000 + 0000000000000000000000000000000000000000000000000000000000006300 + 0000000000000000000000000000000000000000000000000000525252000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000525252000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000000000000525252000000 + 0000000000006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000052525200000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000052525200000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000000000000000000000000000052525200000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000052525200000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000005252520000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000005252520000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000006300000000000000000000005252520000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000005252520000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000006300000063000000630000006300 + 0000630000006300000063000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000006300000000000000630000000000000063000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000630000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000063000000630000006300000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000630000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000063000000630000006300 + 0000630000006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000063000000FFFFFF00FFFF + FF00FFFFFF006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000063000000FFFFFF00FFFF + FF00FFFFFF0063000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000BE724D00C77B5500CC80 + 5B00D78B6500D68A650000000000000000000000000000000000D68A6500D78B + 6500CC805B00C77B5500BE724D00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000063000000FFFFFF00FFFF + FF00FFFFFF006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B0694700BC724E00BA66 + 3C00C47D5E00DE926C0000000000000000000000000000000000DE926C00FBC3 + A600FBC3A600FDBE9E00B0694700000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000063000000630000006300 + 0000630000006300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000D1B3CA0096492400000000000000000000000000A75F3C00BC724E00BA66 + 3C00C47D5E00DE926C0000000000000000000000000000000000DE926C00FBC3 + A600FBC3A600FDBE9E00A75F3C0000000000000000000000000096492400ECC5 + D700000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000D1B3 + CA009D4E28009D4D25000000000000000000000000009D543000BC724E00BA66 + 3C00C47D5E00E296700000000000000000000000000000000000E2967000FBC3 + A600FBC3A600FDBE9E009D5430000000000000000000000000009D4D25009D4E + 2800ECC5D7000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000052525200000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000D1B3CA00A050 + 2A00D2754700AB542900A24F27009A4B25009247230092472300BC724E00BA66 + 3C00C47D5E00E296700000000000000000000000000000000000E2967000FBC3 + A600FBC3A600FDBE9E0092472300924723009A4B2500A24F2700AB542900BF6A + 3F00A0502A00ECC5D70000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000005252520000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000D1B3CA00A2563100E186 + 5800F68F5B00E9865500D97B4D00C8704400B7653B00AA5B3300BD704A00B667 + 4000BE775500E296700000000000000000000000000000000000E2967000FBC3 + A600FBC3A600FDBE9E00FCB99700FDB08900F7905C00EC885600DE7F4F00D176 + 4800C46E4200A2563100ECC5D700000000000000000000000000000000000000 + 0000000000000000000000000000525252000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000E2956E00FBC0A100FFB3 + 8C00FF9E6D00F68F5B00E9865500D97B4D00C8704400C8704400CF7F5700CB79 + 5000C47A5700E296700000000000000000000000000000000000E2967000FBC3 + A600FBC3A600FDBE9E00FDBE9E00FCB99700FDA57800FC935E00F28C5900E584 + 5300D87B4C00C66E4100AE582B00000000000000000000000000000000000000 + 0000000000000000000052525200000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000E0BDCC00E89C7600FBC0 + A100FFB38B00FFB38D00F8A87F00EEA17A00E1987400E1987400E1987400D98B + 6500D1896500E296700000000000000000000000000000000000E2967000FBC3 + A600FBC3A600FBC3A600FBC3A600FDBE9E00FDBE9E00FEAE8500FFA87D00F89D + 6F00E5835100AE582B00F5CEE400000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000DFBFCF00E89C + 7600FBBFA000CE673300E7946C00E68E6200E5875800E28B5E00E28B6100E28F + 6500E2916800E296700000000000000000000000000000000000E2967000E296 + 7000E2967000E2967000E2967000E2967000DA8E6800D1855F00DB906A00F79A + 6B00AE582B00F5CEE40000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DFBF + CF00E79A7300D2703E0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000E5997300C576 + 4E00F4CFE2000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000DFBFCF00E79A730000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000E89C7600F9D3 + EB00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000B971 + 44000000000000000000AD6538000000000000000000A55C2E00000000000000 + 0000A1582A00000000000000000000000000000000000000000000000000BB74 + 460000000000000000000000000000000000000000000000000000000000A158 + 2A00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000BB75 + 48000000000000000000B16B3C000000000000000000A75F3200000000000000 + 0000A1582A00000000000000000000000000000000000000000000000000BB74 + 460000000000000000000000000000000000000000000000000000000000A158 + 2A00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000C7815400C37D5000BF79 + 4C00BD754800B9714200B56D4000B1693C00AE663700AB623400A85F3100A65B + 2E00A35A2C00A1582A00A1582A0000000000000000000000000000000000C079 + 4C0000000000000000000000000000000000000000000000000000000000A158 + 2A00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C37D + 52000000000000000000B97144000000000000000000AE663900000000000000 + 0000A55C2E00000000000000000000000000CD875A00CD875A00C9835600C57E + 5100C07A4C00BC754800B8714300B46C3F00B0683A00A9603300A65D2F00A35A + 2C00A1582A00A1582A00A1582A00000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C783 + 54000000000000000000BD7546000000000000000000B1693C00000000000000 + 0000A85F3100000000000000000000000000000000000000000000000000C983 + 560000000000000000000000000000000000000000000000000000000000A65E + 3000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000D48C5F00CF895C00CB85 + 5800C7815400C37D5000C1794C00BB754800B9714400B56B4000B2693B00AE65 + 3700AA623500A85F3100A55B3000000000000000000000000000000000003E39 + 370048403B0039322F0028231F001B171400070605000000000000000000AA61 + 3300000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CE8A + 5D000000000000000000C37D50000000000000000000B9714200000000000000 + 0000AD6738000000000000000000000000000000000000000000000000008976 + 6C00D1B9AC00CAAD9B00C8A89500C7A39000C7A08D000706050000000000B26A + 3C00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000008400840084008400840084008400 + 8400000000000000000084008400840084008400840084008400840084008400 + 840084008400840084008400840084008400000000000000000000000000D28E + 61000000000000000000C78154000000000000000000BB754800000000000000 + 0000B1693C000000000000000000000000008A4625000000000000000000897D + 7600F8E9E000F6E3D900F4DED100F2D9CC00C7A391001814120000000000B66F + 4100000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000DB976800D8946800D591 + 6400D28E6100CF895C00CB875800C7815400C37D5000C1794C00BD754600B770 + 4400B56D3E00B1693C00AE66390000000000975433008A462500000000008980 + 7900FAEEE700F8E8DF00F5E3D800F4DED100C8A89800231E1B0000000000BB74 + 4600000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000D894 + 67000000000000000000CF895C000000000000000000C47D5100000000000000 + 0000B97144000000000000000000000000009754330000000000000000008980 + 7C00FCF2EC00FAEDE600F8E9DF00F5E3D800CBAE9F00322C290000000000C079 + 4C00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DB95 + 6A000000000000000000D28E61000000000000000000C7835400000000000000 + 0000BB7548000000000000000000000000000000000000000000000000008880 + 7C00FCF4EE00FCF2EC00FAEFE800F9EAE100D6BFB3003F38350000000000C57E + 5100000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000DF9B6E00DF9B6E00DE98 + 6B00DB976800D8946700D5916400D28E6100CE8A5D00CB855800C9815400C57D + 5000C1794C00BD754800B771440000000000DF9B6E00DF9B6E00DF9B6E00887F + 7A0089807C0089807C0089807900887D770089766C0035312E00CD885B00C983 + 5600C57F5200C17A4D00C17A4D00000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DF9B + 6E000000000000000000D99366000000000000000000CF895C00000000000000 + 0000C57D5000000000000000000000000000000000000000000000000000DF9B + 6E0000000000000000000000000000000000000000000000000000000000CE88 + 5B00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DF9B + 6E000000000000000000DB976A000000000000000000D28E5F00000000000000 + 0000C9815400000000000000000000000000000000000000000000000000DF9B + 6E0000000000000000008A46250000000000000000000000000000000000D28D + 6000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008400840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DF9B + 6E000000000097543300975433008A462500000000000000000000000000D28D + 6000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000A27760006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 3500634935005C42300062483400000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000F0E1D900CB9E8700AE7050009956330099563300B1725200D1A28A00F4E5 + DE00000000000000000000000000000000000000000000000000A3786200EDED + ED00E0E0E000D9D9D900D1D1D100C9C9C900C2C2C200B9B9B900B4B4B400B1B1 + B100928884003A1C0E0060473300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000F8F1F100D5B2BB008A3C + 5A0078344C00000000000000000000000000000000000000000000000000E2C8 + BB00B5785700A7562D00B45C2E00B65C2E00B55C2D00B55C2D00BB5F3300D38D + 6A00F1D5C7000000000000000000000000000000000000000000A3796300EEEE + EE00EEEEEE00ECECEC00EBEBEB00E9E9E900E8E8E800E5E5E500DFDFDF00B6AB + A7002F160C0094888200634935000000000000000000B29E90007C6F63006D5D + 520068574A00635143005E4C3E000000000000000000C05D8000A94065008B2B + 5100872B4F0079254300701F3D00000000000000000000000000000000000000 + 0000000000000000000000000000F9F4F400D3B6BD008E445F008B445D008940 + 5B00853954000000000000000000000000000000000000000000F1E2DA00B778 + 5700B35B2E00DF835300F29A6C00F1996E00EE966900E78D5E00DC7D4D00D476 + 4800E09C7900F9EAE30000000000000000000000000000000000A37A6500EEEE + EE00EDEDED00EDEDED00EBEBEB00EAEAEA00EAEAEA0043211000BCB2AE002A14 + 0A00B5A9A300ADADAD00634935000000000000000000C1B3AA00D3D2D100BAB4 + B1009C948C0092877F00605042000000000000000000C2628300B9748900A44B + 68009F416200943758009D315800000000000000000000000000000000000000 + 000000000000F7EFEF00D8BCC30090466000924E6500A1607500A35D75009E54 + 6F0092405E000000000000000000000000000000000000000000CE9F8700AA57 + 2D00DF835300FBAD8700FECBB000FDE9DF00FBE7DD00F1BCA100DC885D00D87A + 4A00E58D5F00F3C4AD0000000000000000000000000000000000AE8A7700EDED + ED00EDEDED00ECECEC00EBEBEB00E9E9E900E9E9E900361A0D002D160B00BCB0 + A900DEDEDE00B1B1B10063493500000000000000000000000000BAA59600C7C3 + C100A69F9800988E8800604F42000000000000000000C4678600BD809200AD5D + 7600A54B6A00A3436600CE8F9B00000000000000000000000000FFFEFE00F3E6 + E800CEA8AF00A1597400A4647A00B9839400C18D9A00BD829300B7778A00AD6B + 80009B4564000000000000000000000000000000000000000000B5745300B85C + 2F00F0966800FDC8AE0000000000000000000000000000000000DCA58900CB6D + 3F00ED946500F4B29100000000000000000000000000A48F8000E4DBD5008871 + 5F00D2CCC800765D4B00D1CBC6006F564300CFC9C4003D241700381B0D004220 + 1000E2E2E200B8B8B800634935000000000000000000FEFEFE00C1B3AA00D1D0 + CE00B7B1AC00A0989100635244000000000000000000C66E8A00C28B9B00B570 + 8400AC5F7800A8436800F9F0F100000000000000000000000000E9D5DC00BC85 + 9700BF8C9A00D0A5AF00D5A9B600D3A8B300D2A3AF00CD9EAA00C692A000BC82 + 9300AF5072000000000000000000000000000000000000000000A0583400BA5E + 3100EC946600FBE7DC0000000000000000000000000000000000EFDAD000BF65 + 3600EE956600F3A9850000000000000000000000000000000000A38E80009680 + 6F0087705E007A614F006F56430069503D00674D3A00D2CDC900E9E9E900E8E8 + E800E5E5E500C1C1C10063493500000000000000000000000000FEFEFE00BAA5 + 9600C5C0BE00ADA6A30067554A000000000000000000C9748E00C7949F00BB7D + 8F00AB5B7600CE919A0000000000000000000000000000000000D3909F00D291 + A100D18FA000D0899B00CE819600CB7A9200C8738E00C56C8900C2638400C05C + 8000BE577C000000000000000000000000000000000000000000A0583400B65C + 2E00DE825300F7E3D80000000000D4886200FEFCFC0000000000EFDAD000BD60 + 3300ED956700F3AB8700000000000000000000000000B7A39600AE9A8C00F9F3 + EE00F2E5DC00F1E1D800EFDDD100EDD8CC006A513E006E554100EAEAEA00E9E9 + E900E8E8E800CBCBCB0063493500000000000000000000000000FEFEFE00C1B3 + AA00D1D0CF00C1BEBC006D5C50000000000000000000CB7B9100CB9DA900C38D + 9D00AA4C6E00F9F2F20000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B6765500B65C + 2E00CE6E3D00E5AE9100E9C2AE00DC926D000000000000000000CE997E00BF63 + 3500EF976C00F5B6940000000000000000000000000000000000B7A39600FCFD + FB00FCF8F600F7F2EC00F5E7DE00EFDED20070564300D5D0CC00EDEDED00ECEC + EC00EAEAEA00D0D0D0006349350000000000000000000000000000000000FEFE + FE00BAA59600C9C7C60075675D000000000000000000CE819500D4B0B900C177 + 9200D2949D000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000D5A58C00BE62 + 3300D06B3800DB7C4D00DE855600E8A17D000000000000000000A65E3A00CB6F + 4300F6A37800FACCB300000000000000000000000000C3B0A300BEAA9D00FDFE + FC00FCFDFB00FCFAF900F9F4EF00F0E1D70079604E00745C4900EEEEEE00EEEE + EE00ECECEC00DADADA006349350000000000000000000000000000000000FFFF + FF00C1B3AA00D2CFCE00807267000000000000000000D0889900D4AAB500C062 + 8400F5E9E9000000000000000000000000000000000000000000BFB2AB00A598 + 8E0091847A0084766B00796B61006D5C500067554A0063524400604F42006050 + 42005E4C3E000000000000000000000000000000000000000000F5E6DF00D48F + 6A00DB784600F18E5C00F69E7000F4AF8C000000000000000000BE7A5500E48F + 6500FDBC9E00FEEFE80000000000000000000000000000000000C3B0A300FDFE + FD00FDFEFD00FCFDFB00FCFBF900F2E5DD00856E5C00D6D1CC00EEEEEE00EEEE + EE00EEEEEE00E0E0E00063493500000000000000000000000000000000000000 + 000000000000BAA59600877A70000000000000000000D28D9C00CA849A00E1BA + BE00000000000000000000000000000000000000000000000000F9F8F700CEC3 + BC00BCA99C00CFCAC800C7C5C400C1BEBC00ADA6A300A0989100988E88009287 + 7F0063514300000000000000000000000000000000000000000000000000E2AF + 9400E68E6100FAA27600FFB08800FCB997000000000000000000FBF2ED00F6BF + A400FEE3D50000000000000000000000000000000000C9B7AB00C6B4A800FDFE + FD00FDFEFD00FDFEFD00FCFDFB00F7EEE900937D6D00866E5C00EEEEEE00EEEE + EE00EEEEEE00EDEDED0063493500000000000000000000000000000000000000 + 000000000000C1B3AA0092867C000000000000000000D4929F00D28B9E00FBF6 + F600000000000000000000000000000000000000000000000000000000000000 + 0000FAF9F900CEC3BC00BCA99C00CFCDCA00C5C0BE00B7B1AC00A69F98009C94 + 8C006A5A4D000000000000000000000000000000000000000000DA8F6A00E39A + 7600EDA78300F6B28F00FCB99700FCB997000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C9B7AB00C6B4 + A800C3B0A300BEAA9D00B6A39500AC988A00A18B7C00DED3CC00BCA19200A37A + 6500A3796300A3786200A2776000000000000000000000000000000000000000 + 000000000000FEFEFE00AC9D96000000000000000000D595A100E1BECB000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FEFEFE00F8F6F500CABEB600BCA99C00CFCDCB00C7C3C100BAB4 + B10075665B000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000CCBAAE0000000000C9B7 + AB0000000000C3B0A30000000000B6A2950000000000A08A7C00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000FEFEFD00F4F2F100D3C9C200BCA99C00D2CF + CE00817468000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FEFDFD00F4F1EF00CEC3 + BC00B2A195000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000745A4600694F3B00CAC2BB000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FBD7C500F8D5C3000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000F8D5C300FBD7C500000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000BBADA10081685400CAB2A400684E3A000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000F8DCCF00F38A5700E195 + 7100000000000000000000000000000000000000000000000000000000000000 + 0000E1957100F38A5700F8DCCF00000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000967C + 69000000000000000000000000008C735F00DFCABE00BDA79800705743000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000005A5A5A00000000005A5A5A0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000EECBBA00F085 + 5000DA865E00000000000000000000000000000000000000000000000000DA86 + 5E00F0855000EECBBA0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000009C83 + 70007F655200CEC6BF00CABEB50091796600E9D7CE007C634F00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CA80 + 5C00F0885500EAC8B70000000000000000000000000000000000EAC8B700F088 + 5500CA805C000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000A38A + 7700DCD1CB006D533F0091796600DDCEC500D6C5BB00856C5900000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E1CD + C300DB784700EF93670000000000000000000000000000000000EF936700DB78 + 4700E1CDC3000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000AA91 + 7F00F9F4F100DDD4CD00856C5800F3EAE500947C6900DCD4CE00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008A46 + 2500954C2800A4542E00B65F3400C7693A00D672400000000000000000000000 + 0000AE5C3600EC865200F2CFBD000000000000000000F2CFBD00EC865200AE5C + 3600000000000000000000000000D6724000C7693A00B65F3400A4542E00954C + 28008A462500000000000000000000000000000000000000000000000000B098 + 8600FCFAF900FBF7F600F9F5F200F7F2EE00896F5C00664C38006A503C00765C + 49000000000000000000000000000000000000000000000000005A5A5A000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00005A5A5A00000000000000000000000000000000000000000000000000954C + 2800DF733600EA824900F39A6A00F5B594000000000000000000000000000000 + 0000A3664800E9845200F7C2A7000000000000000000F7C2A700E9845200A366 + 480000000000000000000000000000000000F5B59400F39A6A00EA824900DF73 + 3600954C2800000000000000000000000000000000000000000000000000B79F + 8D00FFFFFE00FEFDFC00FDFBFA00FBF8F700FAF6F300DFD5CE00886E5B000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000A355 + 2E00EC824B00F38D5B00EC9C7600B6866F00E9D5CB0000000000000000000000 + 0000A9745900E1825400F7BE9E000000000000000000F7BE9E00E1825400A974 + 5900000000000000000000000000E9D5CB00B6866F00EC9C7600F38D5B00EC82 + 4B00A3552E00000000000000000000000000000000000000000000000000BDA6 + 9400FFFFFF00FFFFFF00FFFFFF00FEFDFD00E2DAD5009A826F00000000000000 + 00000000000000000000000000000000000000000000000000005A5A5A000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00005A5A5A00000000000000000000000000000000000000000000000000B55F + 3400F39A6A00F49C7100F29465009D533000AA613B00DAB8A70000000000F6C5 + AE009D644600DE805100F7BDA1000000000000000000F7BDA100DE8051009D64 + 4600F6C5AE0000000000DAB8A700AA613B009D533000F2946500F49C7100F39A + 6A00B55F3400000000000000000000000000000000000000000000000000C3AC + 9900FFFFFF00FFFFFF00FFFFFF00ECE7E300AB93810000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C769 + 3B00F7CAAE00FBDDCB00F4A37600F3946400B4623900B0643E00BF816200BB84 + 6000A15E3900EE8B5A00F6C8B0000000000000000000F6C8B000EE8B5A00A15E + 3900BB846000BF816200B0643E00B4623900F3946400F4A37600FBDDCB00F7CA + AE00C7693B00000000000000000000000000000000000000000000000000C8B0 + 9E00FFFFFF00FFFFFF00F6F2F000BDA593000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000D672 + 40000000000000000000FBDECF00F5A57E00F49D7200C9734700B7663C00B665 + 3D00E2815300F6BCA100F6CBB7000000000000000000F6CBB700F6BCA100E281 + 5300B6653D00B7663C00C9734700F49D7200F5A57E00FBDECF00000000000000 + 0000D6724000000000000000000000000000000000000000000000000000CBB4 + A200FFFFFF00F7F4F100CAB3A100000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000FBDACA00F5A67E00F6B69600F5B28F00F6B0 + 9100F6C1A800F6C5AE0000000000000000000000000000000000F6C5AE00F6C1 + A800F6B09100F5B28F00F6B69600F5A67E00FBDACA0000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CBB4 + A200F6F3F000CBB4A20000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000005A5A5A00000000005A5A5A0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FBE0D200F6C3A900F7CF + BB00F9DBCD00000000000000000000000000000000000000000000000000F9DB + CD00F7CFBB00F6C3A900FBE0D200000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CBB4 + A200CBB4A2000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CBB4 + A200000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A293006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 3500634935000000000000000000000000000000000000000000000000000000 + 0000707070007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000707070007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000707070007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000B7A29300FFFF + FF00B7A29300B7A29300B7A29300B7A29300B7A29300B7A29300B7A29300B7A2 + 9300634935000000000000000000000000000000000000000000000000000000 + 0000000000007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000007070700070707000707070007070700070707000707070007070 + 7000707070007070700070707000000000000000000000000000B7A29300FFFF + FF00FFFFFF00FCFAF900F7F1EE00F1E7E100ECDDD500E6D3C900E1CABD00B7A2 + 9300634935000000000000000000000000000000000000000000000000000000 + 000000000000000000007070700070707000FEFEFE00FAF7F500F5EDE900EFE3 + DC00EAD9D1007070700070707000000000000000000000000000000000000000 + 000000000000000000007070700070707000FEFEFE00FAF7F500F5EDE900EFE3 + DC00EAD9D1007070700070707000000000000000000000000000000000000000 + 000000000000000000007070700070707000FEFEFE00FAF7F500F5EDE900EFE3 + DC00EAD9D1007070700070707000000000000000000000000000B7A29300FFFF + FF00FFFFFF00F5F5F500F1EEEC00ECE4E000E6DBD400E1D1C900E4CFC400B7A2 + 9300634935000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000007070700070707000FDFCFB00F8F3F000F2E9 + E300EDDFD8007070700070707000000000000000000070707000707070007070 + 7000707070007070700070707000707070007070700070707000707070007070 + 7000EDDFD8007070700070707000000000000000000000000000000000000000 + 00000000000000000000000000007070700070707000FDFCFB00F8F3F000F2E9 + E300EDDFD8007070700070707000000000000000000000000000B7A29300FFFF + FF00C1C1C100ACACAC00ABAAA900A7A4A200A39D9900A0969200B4A69F00B7A2 + 9300634935000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000007070700070707000FBF8F700F6EF + EB00F0E5DF007070700070707000000000000000000000000000707070007070 + 7000707070007070700070707000707070007070700070707000707070007070 + 7000F0E5DF007070700070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000007070700070707000FBF8F700F6EF + EB00F0E5DF007070700070707000000000000000000000000000BAA59600FFFF + FF00B6B6B600ECECEC00FFFFFF00FBF8F700EEE7E4009C959100E8D8D000B7A2 + 9300634935000000000000000000000000000000000000000000000000000000 + 0000088A450008623200095B2E0000000000000000007070700070707000F9F5 + F200F4EBE6007070700070707000000000000000000000000000000000007070 + 700070707000FEFEFE00FAF7F500F5EDE900EFE3DC00EAD9D100707070007070 + 7000F4EBE60070707000707070000000000000000000000000005656FF000A0A + FF00000000000000000000000000000000007D7DFF009F9FFF0070707000F9F5 + F200F4EBE6007070700070707000000000000000000000000000BEA99A00FFFF + FF00B6B6B600ECECEC00FFFFFF00F8F7F600ACAAA700E7DEDA00EEE1DA00B7A2 + 9300634935000000000000000000000000000000000000000000000000000000 + 00000CA650000BB05600074D2600000000000000000000000000707070007070 + 7000F7F1EE007070700070707000000000000000000000000000000000000000 + 00007070700070707000FDFCFB00F8F3F000F2E9E300EDDFD800707070007070 + 7000F7F1EE0070707000707070000000000000000000000000006363FF000101 + 75004C4CFF0000000000000000008484FF003333FF0000000000707070007070 + 7000F7F1EE007070700070707000000000000000000000000000C3AE9E00FFFF + FF00B6B6B600ECECEC00FCFCFC00B9B9B900CCCBCA00F7F1EE00F1E7E100B7A2 + 9300634935000000000000000000000000000000000000000000000000000000 + 00000EC15D0048E8A800075B2D00000000000000000000000000000000007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 0000000000007070700070707000FBF8F700F6EFEB00F0E5DF00707070007070 + 7000707070007070700070707000000000000000000000000000000000000101 + DD000101C3008383FF009797FF001616FF007070FF0000000000000000007070 + 7000707070007070700070707000000000000000000000000000C8B2A300FFFF + FF00B5B5B500EDEDED00C1C1C100CBCBCB00FEFEFE00FAF7F500F5EDE900B7A2 + 930063493500000000000000000000000000000000000CD06A0016D66D001BD6 + 670027DB78006AEFC00010AF5600096B360008562C0007512B00000000000000 + 0000707070007070700070707000000000000000000000000000000000000000 + 000000000000000000007070700070707000F9F5F200F4EBE600707070007070 + 7000707070007070700070707000000000000000000000000000000000000000 + 00000101EB000101F8000101F5002323FF000000000000000000000000000000 + 0000707070007070700070707000000000000000000000000000CCB6A700FFFF + FF00B0B0B000C7C7C700C7C7C700FFFFFF00FFFFFF00FDFCFB00B7A29300B7A2 + 9300644A3600000000000000000000000000000000002DDB7F0082EDBC00C3FA + EC00A0F6DA008DF6D70070F0C50058EBB3000FB35600085D2E00000000000000 + 0000000000007070700070707000000000000000000000000000000000000000 + 00000000000000000000000000007070700070707000F7F1EE00707070007070 + 7000000000007070700070707000000000000000000000000000000000000000 + 00007979FF000101BC000101BC007C7CFF000000000000000000000000000000 + 0000000000007070700070707000000000000000000000000000D1BBAB00FFFF + FF00B6B6B600C1C1C100FFFFFF00FFFFFF00FFFFFF00B7A29300644A3600644A + 3600644A3600000000000000000000000000000000004ADF950066E4A50069E8 + A70062EAA8009CF6DB0039E088000EC55C000AA44F00098F4700000000000000 + 0000000000000000000070707000000000000000000000000000000000000000 + 0000000000000000000000000000000000007070700070707000707070007070 + 7000000000000000000070707000000000000000000000000000000000006868 + FF000000FF004747FF004F4FFF001515FF008787FF0000000000000000000000 + 0000000000000000000070707000000000000000000000000000D5BFAF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B9A49500D4C5BA00644A + 3600E1D5CD000000000000000000000000000000000000000000000000000000 + 000060E6A100C6FCEF003ADE8500000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000070707000707070007070 + 70000000000000000000000000000000000000000000000000004141FF000101 + D7005151FF0000000000000000006D6DFF003939FF006363FF00000000000000 + 0000000000000000000000000000000000000000000000000000D8C2B200FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00C0AB9C00644A3600E2D6 + CD00000000000000000000000000000000000000000000000000000000000000 + 000064E4A30089EDBF0032DD8400000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000707070007070 + 70000000000000000000000000000000000000000000000000002A2AFF006060 + FF00000000000000000000000000000000008787FF005656FF00000000000000 + 0000000000000000000000000000000000000000000000000000D8C2B200D8C2 + B200D8C2B200D8C2B200D8C2B200D4BEAE00CFB9A900C9B3A400E2D6CD000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000052E099002FDB7F0017D77200000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000007070 + 7000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000900000000100010000000000800400000000000000000000 + 000000000000000000000000FFFFFF0000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFF0012AA9F001 + F01FF8017EFDF801F83FFC01FEFFFC01FEFFFE017EFD80018EE3FF01FEFFC001 + 06C1FF817EFDE001FEFFFFC1FEFFF00176DDB3A10001F801FEFFBB71FEF3FC01 + AEEBBCF97EE5CE09FEFF84FDFECFCF0DDEF7B77F7E9D038FE00F87BFFE3F03CF + FEFFFFFF7E7DCFEFFFFFFFFF2AA9CFFFFFFFFFFFFFFFFFFFF0010EE1FFFFFC00 + F8017C7DFC010000FC01783DFC010000FE017EFDFC010000FF01FEFF00010000 + FF81DEF700010001FFC19EF300010003B3A1000100010007BB719EF300010007 + BCF9DEF70003000784FDFEFF00070007BF7F7EFD007F000783BF783D00FF0007 + FFFF7C7D01FFF87FFFFF0EE1FFFFFFFFFFFFFEFFFFF7FFFFFEFFFEFFFEF7FEFF + FFFFFEFFFFF7FFFFFEFFFABFFEF7FEFFFFFFFC7FFFD5FFFFFEFFEEFFFEE3FEFB + FFFFF47FFFF7FFFDAA020002AA02AA00FEE7F467FEE7FEE5FECFEECFFECFFECB + FE9FFE9FF69FFE9FFE3FFE3FFA3FFE3FFE7FFE7F007FFE7FFEFFFEFFFAFFFABF + FFFFFFFFF7FFFC7FFEFFFEFFFEFFFEFFFFFFFFFFFFFFFFFF83FFFFFFFFFFAAAB + 8001FFFFFFFFFFFD8001FF83C1FFBFFF8001FF83C1FFFFFD83FBF383C1CFB80F + C7F7E383C1C7FB9DC7EFC003C003BB3FC7DF8003C001FA7DC7BF8003C001B8FF + C77F8003C001F9FDC6FFC003C003BBFFC5FFE3FFFFC7FFFDC3FFF3FFFFCFBFFF + C7FFFFFFFFFFD555FFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFEDB7EFEF + FF7FFFFFEDB7EFEFE00FF3E78001EFEFE007E1E7EDB70001FF63C0E7EDB7EFEF + FF73F3E78001E02FFF73F3E7EDB7E02FFB730000EDB7602FF363F3E78001202F + E007F3E7EDB7602FE00FF1C7EDB7E02FF37FF80F80010001FB7FFC1FEDB7EFEF + FF7FFFFFEDB7EDEFFF7FFFFFFFFFE8EFFFFFFFFFFFFFFFFFFFFFC001FFFFFFFF + F00FC001FFFFFF87E007C0018181FE07C003C0018181F807C003C001C181C007 + C3C380018181C007C3C3C001C183C007C2438001C183FFFFC0C3C001E187FFFF + C0C38001E187C007C0C3C001F98FC007E0C78001F98FF007C0FFC001F99FF807 + FFFFAABFFFFFFE07FFFFFFFFFFFFFF87FFFFFFFFFFFFFFFFFFFFFFFFFF1FFEFF + FF9FF9FFFE1FFC7FFF8FF1FFEE1FF83FFFC7E3FFE03FFEFFFFE3C7FFE03FFEFF + FFE3C7FFE03FDEF7E0718E07E00F9EF3E0F18F07E01F0001E0718E07E03F9EF3 + E0218407E07FDEF7E0018007E0FFFEFFEC018037E1FFFEFFFE03C07FE3FFF83F + FF87E1FFE7FFFC7FFFFFFFFFEFFFFEFFFFFFFFFFFFFFFFFFC007F001F001F001 + C007F801F801F801C007FC01FC01FC01C007FE018001FE01C007FF01C001FF01 + C007F181E001CF01C007F1C1F001C641C007F1E1F801E061C0078031FC01F0F1 + C0078039FE09F0F9C007803DFF0DE07DC007F1FFFF8FC63FC00FF1FFFFCFCF3F + C01FF1FFFFEFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 + 000000000000} + end + object TrianglePopup: TPopupMenu + AutoPopup = False + Images = EditorTB + Left = 329 + Top = 129 + object mnuReset: TMenuItem + Caption = 'Reset triangle' + Hint = 'Reset triangle' + ImageIndex = 20 + OnClick = mnuResetTriangleClick + end + object N6: TMenuItem + Caption = '-' + end + object mnuDuplicate: TMenuItem + Caption = 'Duplicate' + Hint = 'Duplicate selected triangle' + ImageIndex = 2 + OnClick = mnuDupClick + end + object mnuDelete: TMenuItem + Caption = 'Delete' + Hint = 'Delete selected triangle' + ImageIndex = 3 + OnClick = mnuDeleteClick + end + object mnuAdd1: TMenuItem + Caption = 'Add' + Hint = 'Add new triangle' + ImageIndex = 1 + OnClick = mnuAddClick + end + object N21: TMenuItem + Caption = '-' + end + object mnuCopyTriangle: TMenuItem + Caption = 'Copy triangle coordinates' + ImageIndex = 26 + OnClick = btnCopyTriangleClick + end + object mnuPasteTriangle: TMenuItem + Caption = 'Paste triangle coordinates' + ImageIndex = 27 + OnClick = btnPasteTriangleClick + end + object N2: TMenuItem + Caption = '-' + end + object Rotatetriangle90CCW1: TMenuItem + Caption = 'Rotate triangle 90'#176' CCW' + ImageIndex = 17 + OnClick = btTrgRotateLeft90Click + end + object Rotatetriangle90CCW2: TMenuItem + Caption = 'Rotate triangle 90'#176' CW' + ImageIndex = 18 + OnClick = btTrgRotateRight90Click + end + object mnuFlipHorizontal: TMenuItem + Caption = 'Flip Horizontal' + Hint = 'Flip triangle horizontal' + ImageIndex = 10 + OnClick = mnuFlipHorizontalClick + end + object mnuFlipVertical: TMenuItem + Caption = 'Flip Vertical' + Hint = 'Flip triangle vertical' + ImageIndex = 11 + OnClick = mnuFlipVerticalClick + end + object N7: TMenuItem + Caption = '-' + end + object mnuResetTrgPosition: TMenuItem + Caption = 'Reset position' + ImageIndex = 21 + OnClick = btnOcoefsClick + end + object mnuResetTrgRotation: TMenuItem + Caption = 'Reset rotation' + ImageIndex = 22 + OnClick = mnuResetTrgRotationClick + end + object mnuResetTrgScale: TMenuItem + Caption = 'Reset scale' + ImageIndex = 23 + OnClick = mnuResetTrgScaleClick + end + end + object ChaosPopup: TPopupMenu + Left = 353 + Top = 241 + object mnuChaosViewTo: TMenuItem + Caption = 'View as "&to"' + Checked = True + RadioItem = True + OnClick = mnuChaosViewToClick + end + object mnuChaosViewFrom: TMenuItem + Caption = 'View as "&from"' + RadioItem = True + OnClick = mnuChaosViewFromClick + end + object mnuChaosRebuild: TMenuItem + Caption = 'Rebuild xaos links' + Checked = True + Hint = 'Rebuild xaos links when deleting transforms' + Visible = False + OnClick = mnuChaosRebuildClick + end + object N9: TMenuItem + Caption = '-' + end + object mnuChaosClearAll: TMenuItem + Caption = '&Clear all' + OnClick = mnuChaosClearAllClick + end + object mnuChaosSetAll: TMenuItem + Caption = '&Set all' + OnClick = mnuChaosSetAllClick + end + object N10: TMenuItem + Caption = '-' + end + object mnuLinkPostxform: TMenuItem + Caption = 'Add linked xform' + OnClick = mnuLinkPostxformClick + end + end +end diff --git a/Forms/Editor.pas b/Forms/Editor.pas new file mode 100644 index 0000000..1d446a4 --- /dev/null +++ b/Forms/Editor.pas @@ -0,0 +1,5995 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +//{$D-,L-,O+,Q-,R-,Y-,S-} + +unit Editor; + +//{$define VAR_STR} + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ExtCtrls, StdCtrls, ComCtrls, Math, Menus, ToolWin, Registry, + Grids, ValEdit, Buttons, ImgList, Types, StrUtils , Curves, + ControlPoint, XForm, cmap, CustomDrawControl, + RenderingInterface, Translation, RenderThread; + +type + TEditForm = class(TForm) + StatusBar: TStatusBar; + EditPopup: TPopupMenu; + mnuAdd: TMenuItem; + mnuAutoZoom: TMenuItem; + N1: TMenuItem; + mnuUndo: TMenuItem; + mnuRedo: TMenuItem; + QualityPopup: TPopupMenu; + mnuLowQuality: TMenuItem; + mnuMediumQuality: TMenuItem; + mnuHighQuality: TMenuItem; + N3: TMenuItem; + mnuResetLoc: TMenuItem; + N4: TMenuItem; + mnuFlipVertical: TMenuItem; + mnuFlipHorizontal: TMenuItem; + EditorToolBar: TToolBar; + tbAdd: TToolButton; + tbDuplicate: TToolButton; + tbDelete: TToolButton; + ToolButton4: TToolButton; + tbMove: TToolButton; + tbRotate: TToolButton; + ToolButton1: TToolButton; + tbUndo: TToolButton; + tbRedo: TToolButton; + tbScale: TToolButton; + tbFlipHorz: TToolButton; + tbFlipVert: TToolButton; + tbSelect: TToolButton; + EditorTB: TImageList; + tbResetAll: TToolButton; + ToolButton2: TToolButton; + tbVarPreview: TToolButton; + tbEnableFinalXform: TToolButton; + ToolButton3: TToolButton; + TrianglePopup: TPopupMenu; + mnuDuplicate: TMenuItem; + mnuDelete: TMenuItem; + mnuAdd1: TMenuItem; + N2: TMenuItem; + mnuShowVarPreview: TMenuItem; + mnuReset: TMenuItem; + N6: TMenuItem; + Rotatetriangle90CCW1: TMenuItem; + Rotatetriangle90CCW2: TMenuItem; + mnuResetTrgRotation: TMenuItem; + mnuResetTrgPosition: TMenuItem; + mnuResetTrgScale: TMenuItem; + N7: TMenuItem; + mnuExtendedEdit: TMenuItem; + N8: TMenuItem; + mnuAxisLock: TMenuItem; + mnuSelectmode: TMenuItem; + ToolButton6: TToolButton; + tbPivotMode: TToolButton; + tbRotate90CCW: TToolButton; + tbRotate90CW: TToolButton; + tbPostXswap: TToolButton; + oggleposttriangleediting1: TMenuItem; + mnuCopyTriangle: TMenuItem; + mnuPasteTriangle: TMenuItem; + ChaosPopup: TPopupMenu; + mnuChaosViewTo: TMenuItem; + mnuChaosViewFrom: TMenuItem; + N9: TMenuItem; + mnuChaosClearAll: TMenuItem; + mnuChaosSetAll: TMenuItem; + N10: TMenuItem; + mnuLinkPostxform: TMenuItem; + mnuChaosRebuild: TMenuItem; + ToolButton7: TToolButton; + ToolButton8: TToolButton; + ToolButton9: TToolButton; + ToolButton10: TToolButton; + ToolButton11: TToolButton; + EditPnl: TPanel; + Splitter1: TSplitter; + GrphPnl: TPanel; + RightPanel: TPanel; + Splitter2: TSplitter; + ControlPanel: TPanel; + cbTransforms: TComboBox; + PageControl: TPageControl; + TriangleTab: TTabSheet; + TriangleScrollBox: TScrollBox; + TrianglePanel: TPanel; + ToolBar1: TToolBar; + tbCopyTriangle: TToolButton; + tbPasteTriangle: TToolButton; + tbExtendedEdit: TToolButton; + tbAxisLock: TToolButton; + tbAutoWeights: TToolButton; + tb2PostXswap: TToolButton; + tabXForm: TTabSheet; + tabColors: TTabSheet; + GroupBox4: TGroupBox; + chkXformInvisible: TCheckBox; + tabVariations: TTabSheet; + btnLoadVVAR: TButton; + VEVars: TValueListEditor; + chkCollapseVariations: TCheckBox; + bClear: TBitBtn; + TabSheet4: TTabSheet; + vleVariables: TValueListEditor; + chkCollapseVariables: TCheckBox; + TabChaos: TTabSheet; + vleChaos: TValueListEditor; + optFrom: TRadioButton; + optTo: TRadioButton; + txtP: TEdit; + pnlWeight: TPanel; + Panel1: TPanel; + txtName: TEdit; + Panel2: TPanel; + PrevPnl: TPanel; + PreviewImage: TImage; + GroupBox5: TGroupBox; + btTrgRotateLeft90: TSpeedButton; + btTrgRotateRight90: TSpeedButton; + btTrgScaleDown: TSpeedButton; + btTrgScaleUp: TSpeedButton; + btTrgMoveDown: TSpeedButton; + btTrgMoveLeft: TSpeedButton; + btTrgMoveRight: TSpeedButton; + btTrgMoveUp: TSpeedButton; + btTrgRotateLeft: TSpeedButton; + btTrgRotateRight: TSpeedButton; + txtTrgScaleValue: TComboBox; + txtTrgRotateValue: TComboBox; + txtTrgMoveValue: TComboBox; + GroupBox6: TGroupBox; + LabelC: TLabel; + LabelA: TLabel; + LabelB: TLabel; + txtAx: TEdit; + txtAy: TEdit; + txtBx: TEdit; + txtBy: TEdit; + txtCx: TEdit; + txtCy: TEdit; + ScrollBox1: TScrollBox; + GroupBox9: TGroupBox; + btnXcoefs: TSpeedButton; + btnYcoefs: TSpeedButton; + btnOcoefs: TSpeedButton; + btnResetCoefs: TSpeedButton; + txtA: TEdit; + txtB: TEdit; + txtC: TEdit; + txtD: TEdit; + txtE: TEdit; + txtF: TEdit; + GroupBox7: TGroupBox; + btnCoefsPolar: TSpeedButton; + btnCoefsRect: TSpeedButton; + GroupBox8: TGroupBox; + btnXpost: TSpeedButton; + btnYpost: TSpeedButton; + btnOpost: TSpeedButton; + btnResetPostCoefs: TSpeedButton; + txtPost00: TEdit; + txtPost01: TEdit; + txtPost10: TEdit; + txtPost11: TEdit; + txtPost20: TEdit; + txtPost21: TEdit; + chkAutoZscale: TCheckBox; + ScrollBox2: TScrollBox; + GroupBox1: TGroupBox; + pnlSymmetry: TPanel; + pnlXFormColor: TPanel; + shColor: TShape; + txtXFormColor: TEdit; + txtSymmetry: TEdit; + ColorBar: TPanel; + ColorBarPicture: TImage; + scrlXFormColor: TScrollBar; + pnlOpacity: TPanel; + txtOpacity: TEdit; + chkXformSolo: TCheckBox; + pnlDC: TPanel; + txtDC: TEdit; + GroupBox2: TGroupBox; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + trkVarPreviewDensity: TTrackBar; + trkVarPreviewRange: TTrackBar; + trkVarPreviewDepth: TTrackBar; + ImgTemp: TImage; + N11: TMenuItem; + mnuEHighQuality: TMenuItem; + mnuEMediumQuality: TMenuItem; + mnuELowQuality: TMenuItem; + Label4: TLabel; + txtSearchBox: TEdit; + ToolButton5: TToolButton; + ToolButton12: TToolButton; + ToolButton13: TToolButton; + ToolButton14: TToolButton; + SpeedButton1: TSpeedButton; + GroupBox3: TGroupBox; + btnResetPivot: TSpeedButton; + btnPickPivot: TSpeedButton; + btnPivotMode: TSpeedButton; + editPivotY: TEdit; + editPivotX: TEdit; + procedure ToolButton12Click(Sender: TObject); + procedure btnResetSearchClick(Sender: TObject); + procedure txtSearchBoxKeyPress(Sender: TObject; var Key: Char); + procedure txtSearchBoxChange(Sender: TObject); + procedure FormActivate(Sender: TObject); + procedure ScrollBox1Resize(Sender: TObject); + procedure ScrollBox2Resize(Sender: TObject); + procedure ControlPanelResize(Sender: TObject); + procedure TrianglePanelResize(Sender: TObject); + + procedure ValidateVariable; + procedure vleVariablesValidate(Sender: TObject; ACol, ARow: Integer; const KeyName, KeyValue: string); + procedure vleVariablesKeyPress(Sender: TObject; var Key: Char); + procedure vleVariablesExit(Sender: TObject); + + procedure FormCreate(Sender: TObject); + + procedure TriangleViewMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: integer); + procedure TriangleViewMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: integer); + procedure TriangleViewMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: integer); + procedure TriangleViewMouseWheel(Sender: TObject; Shift: TShiftState; + WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); + procedure TriangleViewDblClick(Sender: TObject); + procedure TriangleViewKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure TriangleViewKeyUp(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure TriangleViewExit(Sender: TObject); + procedure TriangleViewMouseLeave(Sender: TObject); + procedure TriangleViewInvalidate(Sender: TObject); + + procedure SetGraphZoom(gz: double); + + procedure FormShow(Sender: TObject); + procedure mnuDeleteClick(Sender: TObject); + procedure mnuAddClick(Sender: TObject); + procedure mnuDupClick(Sender: TObject); + procedure mnuAutoZoomClick(Sender: TObject); + procedure btnCloseClick(Sender: TObject); + procedure FormResize(Sender: TObject); + procedure txtPKeyPress(Sender: TObject; var Key: Char); + procedure CornerEditKeyPress(Sender: TObject; var Key: Char); + procedure CornerEditExit(Sender: TObject); + procedure txtPExit(Sender: TObject); + procedure DrawPreview; + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure mnuUndoClick(Sender: TObject); + procedure mnuRedoClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure mnuLowQualityClick(Sender: TObject); + procedure mnuHighQualityClick(Sender: TObject); + procedure mnuMediumQualityClick(Sender: TObject); + procedure mnuResetLocClick(Sender: TObject); + procedure mnuFlipAllVClick(Sender: TObject); + procedure mnuFlipAllHClick(Sender: TObject); + procedure mnuFlipVerticalClick(Sender: TObject); + procedure mnuFlipHorizontalClick(Sender: TObject); + procedure cbTransformsChange(Sender: TObject); + procedure CoefKeyPress(Sender: TObject; var Key: Char); + procedure CoefValidate(Sender: TObject); + procedure scrlXFormColorScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); + procedure scrlXFormColorChange(Sender: TObject); +// procedure chkUseXFormColorClick(Sender: TObject); +// procedure chkHelpersClick(Sender: TObject); + procedure txtXFormColorExit(Sender: TObject); + procedure txtXFormColorKeyPress(Sender: TObject; var Key: Char); + procedure txtSymmetrySet(Sender: TObject); + procedure txtSymmetrKeyPress(Sender: TObject; var Key: Char); + procedure txtDCSet(Sender: TObject); + procedure txtDCKeyPress(Sender: TObject; var Key: Char); + procedure txtOpacitySet(Sender: TObject); + procedure txtOpacityKeyPress(Sender: TObject; var Key: Char); + + procedure btTrgRotateLeftClick(Sender: TObject); + procedure btTrgRotateRightClick(Sender: TObject); + procedure btTrgRotateLeft90Click(Sender: TObject); + procedure btTrgRotateRight90Click(Sender: TObject); + procedure TrgMove(dx, dy: double); + procedure btTrgMoveLeftClick(Sender: TObject); + procedure btTrgMoveRightClick(Sender: TObject); + procedure btTrgMoveUpClick(Sender: TObject); + procedure btTrgMoveDownClick(Sender: TObject); + procedure btTrgScaleUpClick(Sender: TObject); + procedure btTrgScaleDownClick(Sender: TObject); + procedure splitterMoved(Sender: TObject); + procedure tbSelectClick(Sender: TObject); + procedure EditKeyPress(Sender: TObject; var Key: Char); + procedure tbEditModeClick(Sender: TObject); + + procedure ValidateVariation; +// procedure ValidateValue(Sender: TObject); + procedure VEVarsKeyPress(Sender: TObject; var Key: Char); + procedure VEVarsChange(Sender: TObject); + procedure VEVarsValidate(Sender: TObject; ACol, ARow: Integer; + const KeyName, KeyValue: String); + procedure VEVarsMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure VEVarsMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure VEVarsMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure VEVarsDblClick(Sender: TObject); + + procedure cbTransformsDrawItem(Control: TWinControl; Index: Integer; + Rect: TRect; State: TOwnerDrawState); + + procedure tbFullViewClick(Sender: TObject); + + procedure EditKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure txtValidateValue(Sender: TObject); + procedure txtValKeyPress(Sender: TObject; var Key: Char); + procedure mnuResetTriangleClick(Sender: TObject); + procedure mnuResetAllClick(Sender: TObject); + procedure btnXcoefsClick(Sender: TObject); + procedure btnYcoefsClick(Sender: TObject); + procedure btnOcoefsClick(Sender: TObject); + procedure btnCoefsModeClick(Sender: TObject); + procedure tbVarPreviewClick(Sender: TObject); + procedure trkVarPreviewRangeChange(Sender: TObject); + procedure trkVarPreviewDensityChange(Sender: TObject); + procedure trkVarPreviewDepthChange(Sender: TObject); + procedure btnXpostClick(Sender: TObject); + procedure btnYpostClick(Sender: TObject); + procedure btnOpostClick(Sender: TObject); + procedure PostCoefValidate(Sender: TObject); + procedure PostCoefKeypress(Sender: TObject; var Key: Char); + procedure btnResetCoefsClick(Sender: TObject); + procedure btnResetPostCoefsClick(Sender: TObject); + procedure btnPivotModeClick(Sender: TObject); + procedure PivotValidate(Sender: TObject); + procedure PivotKeyPress(Sender: TObject; var Key: Char); + procedure btnResetPivotClick(Sender: TObject); + procedure btnPickPivotClick(Sender: TObject); + procedure VEVarsDrawCell(Sender: TObject; ACol, ARow: Integer; + Rect: TRect; State: TGridDrawState); + procedure tbEnableFinalXformClick(Sender: TObject); + procedure DragPanelMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure DragPanelMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure DragPanelMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure DragPanelDblClick(Sender: TObject); + procedure mnuResetTrgRotationClick(Sender: TObject); + procedure mnuResetTrgScaleClick(Sender: TObject); + procedure ResetAxisRotation(n: integer); + procedure ResetAxisScale(n: integer); + procedure tbExtendedEditClick(Sender: TObject); + procedure tbAxisLockClick(Sender: TObject); + procedure tbPostXswapClick(Sender: TObject); + procedure btnCopyTriangleClick(Sender: TObject); + procedure btnPasteTriangleClick(Sender: TObject); + procedure chkAutoZscaleClick(Sender: TObject); + procedure ValidateChaos; + procedure vleChaosExit(Sender: TObject); + procedure vleChaosKeyPress(Sender: TObject; var Key: Char); + procedure vleChaosValidate(Sender: TObject; ACol, ARow: Integer; + const KeyName, KeyValue: String); + procedure VleChaosDrawCell(Sender: TObject; ACol, ARow: Integer; + Rect: TRect; State: TGridDrawState); + procedure mnuChaosViewToClick(Sender: TObject); + procedure mnuChaosViewFromClick(Sender: TObject); + procedure chkPlotModeClick(Sender: TObject); + procedure mnuChaosClearAllClick(Sender: TObject); + procedure mnuChaosSetAllClick(Sender: TObject); + procedure mnuLinkPostxformClick(Sender: TObject); + procedure chkXformSoloClick(Sender: TObject); + procedure mnuChaosRebuildClick(Sender: TObject); + procedure chkCollapseVariationsClick(Sender: TObject); + procedure chkCollapseVariablesClick(Sender: TObject); + procedure shColorMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure shColorMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure shColorMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure bClearClick(Sender: TObject); + procedure ColorBarMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure btnLoadVVARClick(Sender: TObject); + procedure txtNameKeyPress(Sender: TObject; var Key: Char); + procedure txtNameExit(Sender: TObject); +// procedure btnInvisibleClick(Sender: TObject); +// procedure btnSoloClick(Sender: TObject); + + private + TriangleView: TCustomDrawControl; + cmap: TColorMap; + PreviewDensity: double; + + viewDragMode, viewDragged: boolean; + editMode, oldMode, widgetMode: (modeNone, modeMove, modeRotate, modeScale, modePick); + modeHack: boolean; // for mouseOverEdge... + modeKey: word; + key_handled: boolean; + updating: boolean; + + MousePos: TPoint; // in screen coordinates + mouseOverTriangle, mouseOverEdge, mouseOverCorner, mouseOverWidget: integer; + mouseOverPos: TSPoint; + + Widgets: array[0..3] of array [0..2] of TSPoint; + xx, xy, yx, yy: double; + + varDragMode: boolean; + varDragIndex: integer; + varDragValue: double; + varDragPos, varDragOld: integer; + varMM: boolean; //hack? + pDragValue: ^double; + + SelectMode, ExtendedEdit, AxisLock: boolean; + showVarPreview: boolean; + + GraphZoom: double; + TriangleCaught, CornerCaught, EdgeCaught: boolean; + LocalAxisLocked: boolean; +// SelectedTriangle: integer; // outside only for scripting + oldSelected: integer; + SelectedCorner: integer; + HasChanged: boolean; + + oldTriangle: TTriangle; + gCenterX: double; + gCenterY: double; + + MemTriangle: TTriangle; + + oldx, oldy, olddist: double; + Pivot: TSPoint; + + VarsCache: array[0..150] of double; // hack: to prevent slow valuelist redraw + // -JF- 64 wasn't big enough... buffer overrun + BackgroundBmp : TBitmap; + Renderer : TRenderThread; + + pnlDragMode: boolean; + pnlDragPos, pnlDragOld: integer; + pnlDragValue: double; + + LastFocus: TEdit; + + procedure UpdateFlameX; + procedure UpdateFlame(DrawMain: boolean); + procedure UpdateWidgets; + procedure UpdateXformsList; + + procedure DeleteTriangle(t: integer); + + function GetPivot: TSPoint; overload; + function GetPivot(n: integer): TSPoint; overload; + + procedure ShowSelectedInfo; + procedure Scale(var fx, fy: double; x, y: integer); + + procedure TriangleViewPaint(Sender: TObject); + procedure AutoZoom; + + procedure KeyInput(str: string); + public + cp: TControlPoint; + Render: TRenderer; + + // Accessible from scripter + SelectedTriangle: integer; + PivotMode: (pivotLocal, pivotWorld); + LocalPivot, WorldPivot: TSPoint; + + procedure UpdatePreview; + procedure UpdateDisplay(PreviewOnly: boolean = false); //(?) + + function GetTriangleColor(n: integer): TColor; + function LastTriangle: integer; + function InsideTriangle(x, y: double): integer; + + procedure ScriptGetPivot(var px, py: double); + procedure InvokeResetAll; + procedure UpdateColorBar; + + procedure PaintBackground; + end; + +const + {TrgColors: array[-1..13] of TColor = (clGray, + $0000ff, $00ffff, $00ff00, $ffff00, $ff0000, $ff00ff, $007fff, + $7f00ff, $55ffff, $ccffcc, $ffffaa, $ff7f7f, $ffaaff, $55ccff );} + TrgColors: array[-1..13] of TColor = (clGray, + $0000ff, $00cccc, $00cc00, $cccc00, $ff4040, $cc00cc, $0080cc, + $4f0080, $228080, $608060, $808050, $804f4f, $805080, $226080 ); + +var + EditForm: TEditForm; + +function ColorValToColor(c: TColorMap; index: double): TColor; +function FlipTriangleVertical(t: TTriangle): TTriangle; +function FlipTriangleHorizontal(t: TTriangle): TTriangle; +function RotateTriangle(t: TTriangle; rad: double): TTriangle; +function OffsetTriangle(t: TTriangle; range: double): TTriangle; +function ScaleTriangle(t: TTriangle; scale: double): TTriangle; +function RotateTriangleCenter(t: TTriangle; rad: double): TTriangle; +function RotateTrianglePoint(t: TTriangle; xr, yr: double; rad: double): TTriangle; +function Centroid(t: TTriangle): TSPoint; +function OffsetTriangleRandom(t: TTriangle): TTriangle; +function ScaleTriangleCenter(t: TTriangle; scale: double): TTriangle; +function ScaleTrianglePoint(t: TTriangle; x, y, scale: double): TTriangle; + +implementation + +uses + Main, Global, Adjust, Mutate, XformMan; + +{$R *.DFM} + +{ Triangle transformations } + +function OffsetTriangleRandom(t: TTriangle): TTriangle; +var + r: integer; +begin + r := random(3); + Result.x[r] := t.x[r] + random - 0.5; + Result.y[r] := t.y[r] + random - 0.5; +end; + +function FlipTriangleVertical(t: TTriangle): TTriangle; +begin + Result := t; + Result.y[0] := -t.y[0]; + Result.y[1] := -t.y[1]; + Result.y[2] := -t.y[2]; +end; + +function FlipTriangleHorizontal(t: TTriangle): TTriangle; +begin + Result := t; + Result.x[0] := -t.x[0]; + Result.x[1] := -t.x[1]; + Result.x[2] := -t.x[2]; +end; + +function ScaleTriangle(t: TTriangle; scale: double): TTriangle; +begin + Result.y[0] := scale * t.y[0]; + Result.y[1] := scale * t.y[1]; + Result.y[2] := scale * t.y[2]; + Result.x[0] := scale * t.x[0]; + Result.x[1] := scale * t.x[1]; + Result.x[2] := scale * t.x[2]; +end; + +function Centroid(t: TTriangle): TSPoint; +begin + Result.x := (t.x[0] + t.x[1] + t.x[2]) / 3; + Result.y := (t.y[0] + t.y[1] + t.y[2]) / 3; +end; + +function ScaleTriangleCenter(t: TTriangle; scale: double): TTriangle; +var + xr, yr: double; + z: TSPoint; +begin + assert(scale <> 0); + + z := Centroid(t); + xr := z.x; + yr := z.y; + Result.y[0] := scale * (t.y[0] - yr) + yr; + Result.y[1] := scale * (t.y[1] - yr) + yr; + Result.y[2] := scale * (t.y[2] - yr) + yr; + Result.x[0] := scale * (t.x[0] - xr) + xr; + Result.x[1] := scale * (t.x[1] - xr) + xr; + Result.x[2] := scale * (t.x[2] - xr) + xr; +end; + +function ScaleTrianglePoint(t: TTriangle; x, y, scale: double): TTriangle; +begin + //assert(scale <> 0); + if scale = 0 then scale := 1e-64; + + Result.y[0] := scale * (t.y[0] - y) + y; + Result.y[1] := scale * (t.y[1] - y) + y; + Result.y[2] := scale * (t.y[2] - y) + y; + Result.x[0] := scale * (t.x[0] - x) + x; + Result.x[1] := scale * (t.x[1] - x) + x; + Result.x[2] := scale * (t.x[2] - x) + x; +end; + +function RotateTriangle(t: TTriangle; rad: double): TTriangle; //rad in Radians +var + i: integer; +begin + for i := 0 to 2 do + begin + Result.x[i] := t.x[i] * cos(rad) - t.y[i] * sin(rad); + Result.y[i] := t.x[i] * sin(rad) + t.y[i] * cos(rad); + end; +end; + +function OffsetTriangle(t: TTriangle; range: double): TTriangle; +var + i: integer; + r: double; +begin + r := (random * 2 * range) - range; + for i := 0 to 2 do + begin + Result.x[i] := t.x[i] + r; + Result.y[i] := t.y[i] + r; + end; +end; + +function RotateTriangleCenter(t: TTriangle; rad: double): TTriangle; +var + i: integer; + xr, yr: double; + z: TSPoint; +begin + z := Centroid(t); + xr := z.x; + yr := z.y; + for i := 0 to 2 do + begin + Result.x[i] := xr + (t.x[i] - xr) * cos(rad) - (t.y[i] - yr) * sin(rad); + Result.y[i] := yr + (t.x[i] - xr) * sin(rad) + (t.y[i] - yr) * cos(rad); + end; +end; + +function RotateTrianglePoint(t: TTriangle; xr, yr: double; rad: double): TTriangle; +var + i: integer; +begin + for i := 0 to 2 do + begin + Result.x[i] := xr + (t.x[i] - xr) * cos(rad) - (t.y[i] - yr) * sin(rad); + Result.y[i] := yr + (t.x[i] - xr) * sin(rad) + (t.y[i] - yr) * cos(rad); + end; +end; + +function ColorValToColor(c: TColorMap; index: double): TColor; +var + i: integer; +begin + i := Trunc(Index * 255); + assert(i >= 0); + assert(i < 256); + result := c[i][2] shl 16 + c[i][1] shl 8 + c[i][0]; +end; + +procedure TEditForm.UpdatePreview; +var + pw, ph: integer; +begin + pw := PrevPnl.Width -2; + ph := PrevPnl.Height -2; + if (cp.width / cp.height) > (pw / ph) then + begin + PreviewImage.Width := pw; + assert(pw <> 0); + PreviewImage.Height := round(cp.height / cp.Width * pw); + PreviewImage.Left := 1; + PreviewImage.Top := (ph - PreviewImage.Height) div 2; + end + else begin + PreviewImage.Height := ph; + assert(ph <> 0); + PreviewImage.Width := round(cp.Width / cp.Height * ph); + PreviewImage.Top := 1; + PreviewImage.Left := (pw - PreviewImage.Width) div 2; + end; + cp.AdjustScale(PreviewImage.Width, PreviewImage.Height); + DrawPreview; + TriangleViewPaint(TriangleView); +end; + +procedure TEditForm.UpdateXformsList; +var + i, n: integer; + prefix: string; +begin + cbTransforms.Clear; + for i := 1 to Transforms do begin + + cbTransforms.Items.Add(IntToStr(i)); + end; + if EnableFinalXform or cp.HasFinalXForm then cbTransforms.Items.Add(TextByKey('editor-common-finalxformlistitem')); + cbTransforms.ItemIndex := SelectedTriangle; + + if mnuChaosViewTo.Checked then prefix := TextByKey('editor-common-toprefix') + else prefix := TextByKey('editor-common-fromprefix'); + n := Transforms + 1; + while vleChaos.RowCount > n do + vleChaos.DeleteRow(vleChaos.RowCount-1); + while vleChaos.RowCount < n do + vleChaos.InsertRow(Format(prefix, [vleChaos.RowCount]), '1', true); + + chkCollapseVariablesClick(nil); + chkCollapseVariationsClick(nil); +end; + +procedure TEditForm.UpdateDisplay(PreviewOnly: boolean = false); +begin + // currently EditForm does not really know if we select another + // flame in the Main Window - which is not good... + + cp.copy(MainCp); + + if SelectedTriangle > LastTriangle{???} then + begin + SelectedTriangle := cp.NumXForms-1; + mouseOverTriangle := -1; + end; + + EnableFinalXform := cp.finalXformEnabled; + tbEnableFinalXform.Down := EnableFinalXform; + + UpdatePreview; + + if PreviewOnly then exit; + + cp.cmap := MainCp.cmap; + cmap := MainCp.cmap; + + UpdateXformsList; + UpdateColorBar; + + // just in case: + SetCaptureControl(nil); + HasChanged := false; +// viewDragMode := false; + varDragMode := false; + pnlDragMode := false; + CornerCaught := false; + EdgeCaught := false; + TriangleCaught := false; + + cp.TrianglesFromCP(MainTriangles); + + ShowSelectedInfo; + if MainForm.UndoIndex = 0 then AutoZoom // auto-zoom only on 'new' flame + else TriangleView.Invalidate; +end; + +procedure TEditForm.DrawPreview; +begin + if EnableEditorPreview then exit; + + //Render.Stop; + cp.sample_density := PreviewDensity; + cp.spatial_oversample := defOversample; + cp.spatial_filter_radius := defFilterRadius; + if mnuResetLoc.checked then + begin + cp.zoom := 0; + cp.CalcBoundbox; +{ end + else + begin + cp.zoom := MainCp.zoom; + cp.center[0] := MainCp.Center[0]; + cp.center[1] := MainCp.Center[1]; +} + end; + + cp.cmap := MainCp.cmap; + Render.SetCP(cp); + Render.Render; + PreviewImage.Picture.Bitmap.Assign(Render.GetImage); + PreviewImage.refresh; +end; + +procedure TEditForm.ShowSelectedInfo; +var + i: integer; + v: double; + strval: string; + n : integer; +begin + updating := true; + + if (SelectedTriangle > LastTriangle) then + SelectedTriangle := LastTriangle; + for i:=0 to Transforms -1 do begin + if (i >= Transforms) then begin + if (cbTransforms.Items.Count > Transforms) then cbTransforms.Items[i] := TextByKey('editor-common-finalxformlistitem') + end else begin + n := i + 1; + if (cp.xform[i].TransformName <> '') then + cbTransforms.Items[i] := IntToStr(n) + ' - ' + cp.xform[i].TransformName + else + cbTransforms.Items[i] := IntToStr(n); + end; + end; + + cbTransforms.ItemIndex := SelectedTriangle; + cbTransforms.Refresh; + + with MainTriangles[SelectedTriangle] do + begin + txtAx.text := Format('%.6g', [x[0]]); + txtAy.text := Format('%.6g', [y[0]]); + txtBx.text := Format('%.6g', [x[1]]); + txtBy.text := Format('%.6g', [y[1]]); + txtCx.text := Format('%.6g', [x[2]]); + txtCy.text := Format('%.6g', [y[2]]); + end; + + with cp.xform[SelectedTriangle] do + begin + if btnCoefsRect.Down then begin + txtA.text := Format('%.6g', [ c[0][0]]); + txtB.text := Format('%.6g', [-c[0][1]]); + txtC.text := Format('%.6g', [-c[1][0]]); + txtD.text := Format('%.6g', [ c[1][1]]); + txtE.text := Format('%.6g', [ c[2][0]]); + txtF.text := Format('%.6g', [-c[2][1]]); + txtPost00.text := Format('%.6g', [ p[0][0]]); + txtPost01.text := Format('%.6g', [-p[0][1]]); + txtPost10.text := Format('%.6g', [-p[1][0]]); + txtPost11.text := Format('%.6g', [ p[1][1]]); + txtPost20.text := Format('%.6g', [ p[2][0]]); + txtPost21.text := Format('%.6g', [-p[2][1]]); + end + else begin + txtA.text := Format('%.6g', [Hypot(c[0][0], c[0][1])]); + txtB.text := Format('%.6g', [arctan2(-c[0][1], c[0][0])*180/PI]); + txtC.text := Format('%.6g', [Hypot(c[1][0], c[1][1])]); + txtD.text := Format('%.6g', [arctan2(c[1][1], -c[1][0])*180/PI]); + txtE.text := Format('%.6g', [Hypot(c[2][0], c[2][1])]); + txtF.text := Format('%.6g', [arctan2(-c[2][1], c[2][0])*180/PI]); + txtPost00.text := Format('%.6g', [Hypot(p[0][0], p[0][1])]); + txtPost01.text := Format('%.6g', [arctan2(-p[0][1], p[0][0])*180/PI]); + txtPost10.text := Format('%.6g', [Hypot(p[1][0], p[1][1])]); + txtPost11.text := Format('%.6g', [arctan2(p[1][1], -p[1][0])*180/PI]); + txtPost20.text := Format('%.6g', [Hypot(p[2][0], p[2][1])]); + txtPost21.text := Format('%.6g', [arctan2(-p[2][1], p[2][0])*180/PI]); + end; + + tbPostXswap.Down := postXswap; + tb2PostXswap.Down := postXswap; + + //GroupBox8.Visible := postXswap; + //GroupBox9.Visible := not postXswap; + + (*if postXswap then begin + GroupBox9.Top := 152; + GroupBox8.Top := 0; + end else begin + GroupBox8.Top := 152; + GroupBox9.Top := 0; + end; *) + + if postXswap then begin + btnXcoefs.Font.Style := []; + btnYcoefs.Font.Style := []; + btnOcoefs.Font.Style := []; + btnXpost.Font.Style := [fsBold]; + btnYpost.Font.Style := [fsBold]; + btnOpost.Font.Style := [fsBold]; + btnResetCoefs.Font.Style := []; + btnResetPostCoefs.Font.Style := [fsBold]; + end + else begin + btnXcoefs.Font.Style := [fsBold]; + btnYcoefs.Font.Style := [fsBold]; + btnOcoefs.Font.Style := [fsBold]; + btnXpost.Font.Style := []; + btnYpost.Font.Style := []; + btnOpost.Font.Style := []; + btnResetCoefs.Font.Style := [fsBold]; + btnResetPostCoefs.Font.Style := []; + end; + + chkAutoZscale.Checked := autoZscale; + + if SelectedTriangle < Transforms then + begin + txtP.text := Format('%.6g', [density]); + txtP.Enabled := true; + txtName.Enabled := true; + vleChaos.Enabled := true; + chkXformInvisible.Enabled := true; + chkXformInvisible.Checked := transOpacity = 0; + chkXformSolo.Enabled := true; + txtOpacity.Enabled := true; + txtDC.Enabled := true; + + if cp.soloXform >= 0 then begin + chkXformSolo.Checked := true; + chkXformSolo.Caption := Format(TextByKey('editor-tab-color-togglesoloformat'), [cp.soloXform + 1]); + end + else begin + chkXformSolo.Checked := false; + chkXformSolo.Caption := TextByKey('editor-tab-color-togglesolo'); + end; + end + else begin // disable controls for FinalXform + txtP.Enabled := false; + txtP.Text := 'n/a'; + txtName.Enabled := false; + vleChaos.Enabled := false; + chkXformInvisible.Enabled := false; + chkXformInvisible.Checked := false; + txtOpacity.Enabled := false; + chkXformSolo.Enabled := false; + end; + tbEnableFinalXform.Down := EnableFinalXform; + + txtSymmetry.text := Format('%.6g', [symmetry]); + txtOpacity.text := Format('%.6g', [transOpacity]); + txtDC.Text := Format('%.6g', [pluginColor]); + + pnlXFormColor.Color := ColorValToColor(cp.cmap, color); + shColor.Brush.Color := pnlXformColor.Color; + txtXFormColor.Text := Format('%1.3f', [color]); + scrlXFormcolor.Position := Trunc(color * scrlXFormColor.Max); + + for i := 0 to NRVAR-1 do begin + v := GetVariation(i); + if v <> VarsCache[i] then + begin + VarsCache[i]:=v; + VEVars.Values[VarNames(i)] := Format('%.6g', [v]); + end; + end; + + for i:= 0 to GetNrVariableNames - 1 do begin +{$ifndef VAR_STR} + GetVariable(GetVariableNameAt(i), v); + strval := Format('%.6g', [v]); +{$else} + strval := GetVariableStr(GetVariableNameAt(i)); +{$endif} + // kinda funny, but it really helped... + if vleVariables.Values[GetVariableNameAt(i)] <> strval then + vleVariables.Values[GetVariableNameAt(i)] := strval; + end; + + //Assert(vleChaos.RowCount = Transforms+1); + if SelectedTriangle < Transforms then begin + if mnuChaosViewTo.Checked then + // view as "to" values + for i := 1 to Transforms do begin + strval := Format('%.6g', [modWeights[i - 1]]); + if vleChaos.Cells[1, i] <> strval then + vleChaos.Cells[1, i] := strval; + end + else + // view as "from" values + for i := 1 to Transforms do begin + strval := Format('%.6g', [cp.xform[i - 1].modWeights[SelectedTriangle]]); + if vleChaos.Cells[1, i] <> strval then + vleChaos.Cells[1, i] := strval; + end; + end + else + for i := 1 to vleChaos.RowCount-1 do + vleChaos.Cells[1, i] := 'n/a'; + + txtName.Text := TransformName; + if (SelectedTriangle >= Transforms) then begin + txtName.Text := 'n/a'; + end; + end; + + if PivotMode = pivotLocal then begin + editPivotX.Text := Format('%.6g', [LocalPivot.x]); + editPivotY.Text := Format('%.6g', [LocalPivot.y]); + btnPivotMode.Caption := TextByKey('editor-tab-triangle-modelocal'); + tbPivotMode.Down := false; + end + else begin + editPivotX.Text := Format('%.6g', [WorldPivot.x]); + editPivotY.Text := Format('%.6g', [WorldPivot.y]); + btnPivotMode.Caption := TextByKey('editor-tab-triangle-modeworld'); + tbPivotMode.Down := true; + end; + PageControl.Refresh; + + updating := false; +end; + +procedure TEditForm.Scale(var fx, fy: double; x, y: integer); +var + sc: double; +begin + sc := 50 * GraphZoom; + fx := (x - (TriangleView.Width / 2)) / sc + gCenterX; + fy := -((y - (TriangleView.Height / 2)) / sc - gCentery); +end; + +procedure TEditForm.AutoZoom; +var + i, j: integer; + xminz, yminz, xmaxz, ymaxz: double; + gxlength, gylength: double; +begin + xminz := 0; + yminz := 0; + xmaxz := 0; + ymaxz := 0; + for i := -1 to LastTriangle do + begin + for j := 0 to 2 do + begin + if MainTriangles[i].x[j] < xminz then xminz := MainTriangles[i].x[j]; + if MainTriangles[i].y[j] < yminz then yminz := MainTriangles[i].y[j]; + if MainTriangles[i].x[j] > xmaxz then xmaxz := MainTriangles[i].x[j]; + if MainTriangles[i].y[j] > ymaxz then ymaxz := MainTriangles[i].y[j]; + end; + end; + gxlength := xmaxz - xminz; + gylength := ymaxz - yminz; + gCenterX := xminz + gxlength / 2; + gCentery := yminz + gylength / 2; + + if gxlength >= gylength then + GraphZoom := TriangleView.Width / 60 / gxlength + else + GraphZoom := TriangleView.Height / 60 / gylength; + EditForm.StatusBar.Panels[2].Text := Format(TextByKey('editor-status-zoomformat'), [GraphZoom]); + + TriangleView.Invalidate;//Refresh; +end; + +procedure TEditForm.UpdateFlameX; +begin + cp.GetFromTriangles(MainTriangles, Transforms); + + if tbAutoWeights.Down then cp.ComputeWeights(MainTriangles, Transforms); + DrawPreview; + ShowSelectedInfo; + TriangleView.Refresh; + + chkCollapseVariablesClick(nil); + chkCollapseVariationsClick(nil); +end; + +procedure TEditForm.UpdateFlame(DrawMain: boolean); +begin + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-zoomformat'), [GraphZoom]); + + cp.GetFromTriangles(MainTriangles, LastTriangle); + +// if not chkPreserve.Checked then ComputeWeights(cp, MainTriangles, transforms); + DrawPreview; + ShowSelectedInfo; + TriangleView.Refresh; + if DrawMain then begin + MainForm.StopThread; + + MainCp.Copy(cp, true); + + MainCp.cmap := cmap; + if mnuResetLoc.checked then begin + MainCp.zoom := 0; + MainForm.center[0] := cp.center[0]; + MainForm.center[1] := cp.center[1]; + end; + if AdjustForm.Visible then AdjustForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + if CurvesForm.Visible then CurvesForm.SetCp(MainCp); + MainForm.RedrawTimer.enabled := true; + end; + + chkCollapseVariablesClick(nil); + chkCollapseVariationsClick(nil); +end; + +procedure TEditForm.UpdateWidgets; + function Point(x, y: double): TSPoint; + begin + Result.x := x; + Result.y := y; + end; +begin + with mainTriangles[Selectedtriangle] do + begin + xx := x[0] - x[1]; + xy := y[0] - y[1]; + yx := x[2] - x[1]; + yy := y[2] - y[1]; + Widgets[0][0] := Point(x[1] + 0.8*xx + yx, y[1] + 0.8*xy + yy); + Widgets[0][1] := Point(x[1] + xx + yx, y[1] + xy + yy); + Widgets[0][2] := Point(x[1] + xx + 0.8*yx, y[1] + xy + 0.8*yy); + + Widgets[1][0] := Point(x[1] - 0.8*xx + yx, y[1] - 0.8*xy + yy); + Widgets[1][1] := Point(x[1] - xx + yx, y[1] - xy + yy); + Widgets[1][2] := Point(x[1] - xx + 0.8*yx, y[1] - xy + 0.8*yy); + + Widgets[2][0] := Point(x[1] - 0.8*xx - yx, y[1] - 0.8*xy - yy); + Widgets[2][1] := Point(x[1] - xx - yx, y[1] - xy - yy); + Widgets[2][2] := Point(x[1] - xx - 0.8*yx, y[1] - xy - 0.8*yy); + + Widgets[3][0] := Point(x[1] + 0.8*xx - yx, y[1] + 0.8*xy - yy); + Widgets[3][1] := Point(x[1] + xx - yx, y[1] + xy - yy); + Widgets[3][2] := Point(x[1] + xx - 0.8*yx, y[1] + xy - 0.8*yy); + end; +end; + +procedure TEditForm.DeleteTriangle(t: integer); +var + i, j, nmin, nmax: integer; +begin + if (t = Transforms) then + begin + assert(cp.HasFinalXForm or EnableFinalXform); + MainForm.UpdateUndo; + EnableFinalXform := false; + cp.finalXformEnabled := false; + cp.xform[Transforms].Clear; + cp.xform[Transforms].symmetry := 1; + assert(cp.HasFinalXForm = false); + MainTriangles[Transforms] := MainTriangles[-1]; + tbEnableFinalXform.Down := false; + if (SelectedTriangle = Transforms) then Dec(SelectedTriangle); + end + else + if (Transforms <= 1) then exit + else begin + MainForm.UpdateUndo; + + if RebuildXaosLinks then begin + // check for single "to" links + for i := 0 to Transforms-1 do + with cp.xform[i] do begin + nmin := NXFORMS; + nmax := -1; + for j := 0 to Transforms-1 do + if modWeights[j] <> 0 then begin + if j < nmin then nmin := j; + if j > nmax then nmax := j; + end; + if (nmin = nmax) and (nmin = t) then begin + for j := 0 to Transforms-1 do + modWeights[j] := cp.xform[t].modWeights[j]; + if (transOpacity = 0) then begin + transOpacity := cp.xform[t].transOpacity; + end; + end; + end; + // check for single "from" links + for i := 0 to Transforms-1 do + begin + if cp.xform[t].modWeights[i] = 0 then continue; + nmin := NXFORMS; + nmax := -1; + for j := 0 to Transforms-1 do + if cp.xform[j].modWeights[i] <> 0 then begin + if j < nmin then nmin := j; + if j > nmax then nmax := j; + end; + if (nmin = nmax) and (nmin = t) then begin + for j := 0 to Transforms-1 do + cp.xform[j].modWeights[i] := cp.xform[t].modWeights[i]; + end; + end; + end; + + // delete xform from all probability tables + for i := 0 to Transforms-1 do + with cp.xform[i] do begin + for j := t to Transforms-1 do + modWeights[j] := modWeights[j+1]; + modWeights[Transforms-1] := 1; + end; + + if t = (Transforms - 1) then + begin + MainTriangles[t] := MainTriangles[Transforms]; + cp.xform[t].Assign(cp.xform[Transforms]); + Dec(SelectedTriangle); + end + else begin + for i := t to Transforms-1 do // was: -2 + begin + { copy higher transforms down } + MainTriangles[i] := MainTriangles[i + 1]; + cp.xform[i].Assign(cp.xform[i + 1]); + end; + end; + + if cp.soloXform > t then Dec(cp.soloXform) + else if cp.soloXform = t then cp.soloXform := -1; + + Dec(Transforms); + assert(cp.xform[transforms].density = 0); // cp.xform[transforms].density := 0; + end; + UpdateXformsList; + UpdateFlame(True); +end; + +function TEditForm.InsideTriangle(x, y: double): integer; +var + i, j, k: integer; + inside: boolean; +begin +{ is x, y inside a triangle } + Result := -1; + inside := False; + j := 2; + for k := LastTriangle downto 0 do + begin + for i := 0 to 2 do + begin + if (((MainTriangles[k].y[i] <= y) and + (y < MainTriangles[k].y[j])) or + ((MainTriangles[k].y[j] <= y) and + (y < MainTriangles[k].y[i]))) and + (x < (MainTriangles[k].x[j] - MainTriangles[k].x[i]) * + (y - MainTriangles[k].y[i]) / + (MainTriangles[k].y[j] - MainTriangles[k].y[i]) + + MainTriangles[k].x[i]) then + Inside := not Inside; + j := i + end; + if inside then break; + end; + if inside then Result := k; +end; + +function TEditForm.GetTriangleColor(n: integer): TColor; +begin + if n = Transforms then Result := clWhite + else + if UseTransformColors then + Result := ColorValToColor(MainCp.cmap, cp.xform[n].color) + else Result := TrgColors[n mod 14]; +end; + +function TEditForm.LastTriangle: integer; +begin + if EnableFinalXform or cp.HasFinalXForm then Result := Transforms + else Result := Transforms-1; +end; + +procedure TEditForm.TriangleViewPaint(Sender: TObject); +const + foc_ofs = 4; + foc_size = 32; +var + ix, iy, sc: double; + + function ToScreen(fx, fy: double): TPoint; + begin + Result.x := integer(round(ix + (fx - gCenterX) * sc)); + Result.y := integer(round(iy - (fy - gCenterY) * sc)); + end; + + procedure ToUnit(p: TPoint; var fx, fy: double); + begin + fx := (p.x - ix) / sc + gCenterX; + fy := (p.y + iy) / sc + gCenterY; + end; + +var + dx, dy: double; + Width, Height: integer; + BitMap: TBitMap; + + procedure LineDxDy; + var + k: double; + begin + if (dx <> 0) and (dy <> 0) then with Bitmap.Canvas do + begin + k := dy / dx; + if abs(k) < 1 then begin + MoveTo(0, round(iy - sc*(Pivot.y - ( ix/sc-GCenterX+Pivot.x)*k - GCenterY))); + LineTo(Width, round(iy - sc*(Pivot.y - (-ix/sc-GCenterX+Pivot.x)*k - GCenterY))); + end + else begin + MoveTo(round(ix + sc*(Pivot.x - (-iy/sc-GCenterY+Pivot.y)/k - GCenterX)), 0); + LineTo(round(ix + sc*(Pivot.x - ( iy/sc-GCenterY+Pivot.y)/k - GCenterX)), Height); + end; + end; + end; + +var + a, b, c: TPoint; + e, f: TPoint; + + procedure DrawWidgets; + var + i: integer; + begin + with Bitmap.Canvas do + with MainTriangles[SelectedTriangle] do + begin + for i := 0 to 3 do + begin + a:=toscreen(Widgets[i][0].x, Widgets[i][0].y); + b:=toscreen(Widgets[i][1].x, Widgets[i][1].y); + c:=toscreen(Widgets[i][2].x, Widgets[i][2].y); + moveto(a.x, a.y); + lineto(b.x, b.y); + lineto(c.x, c.y); + end + end; + end; + +var + i, n, tc, tn: integer; + d, d1: double; + tx, ty: double; + + ax, ay: integer; + + gridX1, gridX2, gridY1, gridY2, gi, gstep: double; + gp: TRoundToRange; + + tps: TPenStyle; + tT: TTriangle; + txx, txy, tyx, tyy: double; + str, vvstr: string; + + bf: TBlendFunction; + RenderCP : TControlPoint; + Renderer : TRenderer; + bm : TBitmap; + q, p0, p1: integer; +label DrawCorner; +begin + if (SelectedTriangle < 0) then begin + assert(false, 'Selected triangle < 0'); + SelectedTriangle := 0; + end; + assert(TCustomDrawControl(Sender) = TriangleView); + if SelectedTriangle > LastTriangle then SelectedTriangle := LastTriangle; + + BitMap := TBitMap.Create; + Width := TriangleView.Width; + Height := TriangleView.Height; + Bitmap.Width := Width; + Bitmap.Height := Height; + ix := Width / 2; + iy := Height / 2; + sc := 50 * GraphZoom; + try + with Bitmap.Canvas do + begin + try // who knows... ;) + gp:=round(log10(max(Width, Height)/sc))-1; + gstep:=power(10.0, gp); + except + gp:=0; + gstep:=1.0; + end; + + a := ToScreen(MainTriangles[-1].x[0], MainTriangles[-1].y[0]); + b := ToScreen(MainTriangles[-1].x[1], MainTriangles[-1].y[1]); + c := ToScreen(MainTriangles[-1].x[2], MainTriangles[-1].y[2]); + + brush.Color := EditorBkgColor; + FillRect(Rect(0, 0, Width, Height)); + + if EnableEditorPreview then begin + q := 0; + if EditPrevQual = 2 then q := 1; + p0 := TriangleView.Width div (2 - q); + p1 := TriangleView.Height div (2 - q); + + RenderCp := cp.Clone; + RenderCp.Width := TriangleView.Width; + Rendercp.Height := TriangleView.Height; + RenderCp.pixels_per_unit := sc; + RenderCp.AdjustScale(p0, p1); + RenderCP.sample_density := PreviewDensity * 0.5; + RenderCP.spatial_oversample := 1; + RenderCP.spatial_filter_radius := 0.001; + RenderCp.center[0] := gCenterX ; + RenderCp.center[1] := -gCenterY ; + RenderCp.background[0] := EditorBkgColor and $ff; + RenderCp.background[1] := (EditorBkgColor and $ff00) shl 8; + RenderCp.background[2] := (EditorBkgColor and $ff0000) shl 16; + Render.SetCP(RenderCp); + Render.Render; + + bf.BlendOp := AC_SRC_OVER; + bf.BlendFlags := 0; + bf.SourceConstantAlpha := 255 - EditorPreviewTransparency; + bf.AlphaFormat := 0; + bm := TBitmap.Create; + bm.Width := p0; + bm.Height := p1; + bm.Assign(Render.GetImage); + + //Windows.BitBlt(Handle, 0, 0, + Windows.AlphaBlend(Handle, 0, 0, + TriangleView.Width, TriangleView.Height, + bm.Canvas.Handle, 0, 0, + //$CC0020); + bm.Width, bm.Height, bf); + + RenderCp.Destroy; + try + bm.Dormant; + bm.FreeImage; + finally + bm.Free; + end; + end; + + Pen.Style := psSolid; + Pen.Width := 1; + + // draw grid + Pen.Color := GridColor2; + gridX1:=gCenterX-ix/sc; + gridX2:=gCenterX+(Width-ix)/sc; + gridY1:=gCenterY-iy/sc; + gridY2:=gCenterY+(Height-iy)/sc; + + gi:=RoundTo(gridX1, gp); + while gi <= gridX2 do + begin + ax:=integer(round(ix + (gi - gCenterX)*sc)); + MoveTo(ax, 0); + LineTo(ax, Height); + gi:=gi+gstep; + end; + gi:=RoundTo(gridY1, gp); + while gi <= gridY2 do + begin + ay:=integer(round(iy - (gi - gCenterY)*sc)); + MoveTo(0, ay); + LineTo(Width, ay); + gi:=gi+gstep; + end; + // draw axis + Pen.Color := GridColor1; + ax := integer(round(ix - gCenterX*sc)); + ay := integer(round(iy + gCentery*sc)); + MoveTo(ax, 0); + LineTo(ax, Height-1); + MoveTo(0, ay); + LineTo(Width-1, ay); + + {Reference Triangle} + Pen.Style := psDot; + Pen.color := ReferenceTriangleColor; + brush.Color := gridColor1 shr 1 and $7f7f7f; + Polyline([a, b, c, a]); + + brush.Color := EditorBkgColor; + Font.color := Pen.color; + TextOut(c.x-9, c.y-12, 'Y'); + TextOut(a.x+2, a.y+1, 'X'); + TextOut(b.x-8, b.y+1, 'O'); + + Pen.Style := psSolid; + + // Draw Triangles + for i := 0 to LastTriangle do + begin + if i <> SelectedTriangle then Pen.Style := psDot; + + with cp.xform[i] do // draw post-triangle + if postXswap or + ((ShowAllXforms or (i = SelectedTriangle)) and ( + (p[0,0]<>1) or (p[0,1]<>0) or + (p[1,0]<>0) or (p[1,1]<>1) or + (p[2,0]<>0) or (p[2,1]<>0) )) then + begin + Pen.Color := GetTriangleColor(i) shr 1 and $7f7f7f; + tps := Pen.Style; + Pen.Style := psDot; + + cp.GetPostTriangle(tT, i); + txx := tT.x[0] - tT.x[1]; + txy := tT.y[0] - tT.y[1]; + tyx := tT.x[2] - tT.x[1]; + tyy := tT.y[2] - tT.y[1]; + a := ToScreen(tT.x[1] + txx + tyx, tT.y[1] + txy + tyy); + b := ToScreen(tT.x[1] - txx + tyx, tT.y[1] - txy + tyy); + e := ToScreen(tT.x[1] + txx - tyx, tT.y[1] + txy - tyy); + f := ToScreen(tT.x[1] - txx - tyx, tT.y[1] - txy - tyy); + Polyline([a, b, f, e, a]); + + pen.Style := psSolid; + a := ToScreen(tT.x[1] - txx, tT.y[1] - txy); + b := ToScreen(tT.x[1] + txx, tT.y[1] + txy); + e := ToScreen(tT.x[1] + tyx, tT.y[1] + tyy); + f := ToScreen(tT.x[1] - tyx, tT.y[1] - tyy); + Polyline([a, b, e, f]); + + if postXswap and ((i = SelectedTriangle) or ShowAllXforms) then + begin + Pen.Style := psDot; + cp.GetTriangle(tT, i); + + a:=toscreen(tT.x[0], tT.y[0]); + moveto(a.x, a.y); + b:=toscreen(tT.x[2], tT.y[2]); + lineto(b.x, b.y); + + pen.Style := psSolid; + b:=toscreen(tT.x[1], tT.y[1]); + lineto(b.x, b.y); + lineto(a.x, a.y); + end; + + Pen.Style := tps; + end; + + Pen.Color := GetTriangleColor(i); + a := ToScreen(MainTriangles[i].x[0], MainTriangles[i].y[0]); + b := ToScreen(MainTriangles[i].x[1], MainTriangles[i].y[1]); + c := ToScreen(MainTriangles[i].x[2], MainTriangles[i].y[2]); + if pen.Style <> psSolid then + Polyline([a, b, c, a]) + else begin + Polyline([a, b, c]); + Pen.Style := psDot; + brush.Color := pen.color shr 1 and $7f7f7f; + Polyline([c, a]); + brush.Color := EditorBkgColor; + end; + + Pen.Style := psSolid; + Ellipse(a.x - 4, a.y - 4, a.x + 4, a.y + 4); + Ellipse(b.x - 4, b.y - 4, b.x + 4, b.y + 4); + Ellipse(c.x - 4, c.y - 4, c.x + 4, c.y + 4); + + Font.color := Pen.color; + TextOut(c.x+2, c.y+1, 'Y'); + TextOut(a.x+2, a.y+1, 'X'); + TextOut(b.x+2, b.y+1, 'O'); + end; + + UpdateWidgets; + if ExtendedEdit then begin + n := GetTriangleColor(SelectedTriangle);// shr 1 and $7f7f7f; + if mouseOverTriangle <> SelectedTriangle then n := n shr 1 and $7f7f7f; + Pen.Color := n; + Pen.Mode := pmMerge; + DrawWidgets; + + if mouseOverWidget >= 0 then + begin + pen.Color := pen.Color shr 1 and $7f7f7f; + pen.Width := 4; + DrawWidgets; + pen.Width := 1; + end; + end; + + if showVarPreview then + begin + assert(trkVarPreviewRange.position > 0); + assert(trkVarPreviewDensity.position > 0); + + cp.xform[SelectedTriangle].Prepare; + + n := trkVarPreviewRange.position * trkVarPreviewDensity.position * 5; + d1 := trkVarPreviewDensity.position * 5; + tc := GetTriangleColor(SelectedTriangle); + for ax := -n to n do + for ay := -n to n do + try + tx := ax / d1; + ty := ay / d1; + for i := trkVarPreviewDepth.position downto 1 do + cp.xform[SelectedTriangle].NextPointXY(tx, ty); + a := toscreen(tx, -ty); + Pixels[a.x, a.y] := tc; + except + end; + end; + + if (TriangleCaught or CornerCaught) then // if dragging, draw pivot axis + begin + mouseOverTriangle := SelectedTriangle; + + if HelpersEnabled then + begin + pen.Color := HelpersColor; + pen.Mode := pmMerge; + pen.Style := psSolid; + a := ToScreen(Pivot.x, Pivot.y); + MoveTo(a.x, 0); + LineTo(a.x, Height); + MoveTo(0, a.y); + LineTo(Width, a.y); + + if (editMode = modeRotate) then // draw circle + begin + if CornerCaught then begin + dx := MainTriangles[SelectedTriangle].x[SelectedCorner] - Pivot.x; + dy := MainTriangles[SelectedTriangle].y[SelectedCorner] - Pivot.y; + d := Hypot(dx, dy); + end + else begin + dx := MainTriangles[SelectedTriangle].x[0] - Pivot.x; + dy := MainTriangles[SelectedTriangle].y[0] - Pivot.y; + d := Hypot(dx, dy); + for i := 1 to 2 do + begin + d1 := dist(Pivot.x, Pivot.y, MainTriangles[SelectedTriangle].x[i], MainTriangles[SelectedTriangle].y[i]); + if d1 > d then + begin + if d > 0 then begin + dx := dx/d*d1; + dy := dy/d*d1; + end; + d := d1; + end; + end; + end; + + i := integer(round(d * sc)); + if i > 4 then + begin + pen.Color := HelpersColor; + brush.Style := bsClear; + Ellipse(a.x - i, a.y - i, a.x + i, a.y + i); + + a := ToScreen(Pivot.x - dy, Pivot.y + dx); + b := ToScreen(Pivot.x + dy, Pivot.y - dx); + c := ToScreen(Pivot.x, Pivot.y); + MoveTo(a.x, a.y); + LineTo(c.X, c.y); + LineTo(b.X, b.y); + end; + + // rotated axis + LineDxDy; + end + else if (editMode = modeScale) then // draw lines + begin + if CornerCaught then begin + dx := MainTriangles[SelectedTriangle].x[SelectedCorner] - Pivot.x; + dy := MainTriangles[SelectedTriangle].y[SelectedCorner] - Pivot.y; + LineDxDy; + end + else begin // hmmm... + dx := MainTriangles[SelectedTriangle].x[0] - Pivot.x; + dy := MainTriangles[SelectedTriangle].y[0] - Pivot.y; + LineDxDy; + dx := MainTriangles[SelectedTriangle].x[1] - Pivot.x; + dy := MainTriangles[SelectedTriangle].y[1] - Pivot.y; + LineDxDy; + dx := MainTriangles[SelectedTriangle].x[2] - Pivot.x; + dy := MainTriangles[SelectedTriangle].y[2] - Pivot.y; + LineDxDy; + end; + end + else //if editMode = modeMove then // draw target axis + begin + Pen.Color := HelpersColor; + Pen.Mode := pmMerge;//Xor; + brush.Color := 0; + if CornerCaught then + a := ToScreen(MainTriangles[SelectedTriangle].x[SelectedCorner], + MainTriangles[SelectedTriangle].y[SelectedCorner]) + else + a := ToScreen(GetPivot.x, GetPivot.y); + MoveTo(a.x, 0); + LineTo(a.x, Height); + MoveTo(0, a.y); + LineTo(Width, a.y); + Pen.Mode := pmCopy; + end; + end; // endif HelpersEnabled + end; + + if (mouseOverTriangle >= 0) then // highlight triangle under cursor + begin + with MainTriangles[mouseOverTriangle] do begin + a := ToScreen(x[0], y[0]); + b := ToScreen(x[1], y[1]); + c := ToScreen(x[2], y[2]); + end; + + pen.Width:=2; + Pen.Color:=GetTriangleColor(mouseOverTriangle) shr 1 and $7f7f7f; + Pen.Mode:=pmMerge; + brush.Color:=Pen.Color shr 1 and $7f7f7f; + + if (SelectMode and (editMode <> modePick)) or (mouseOverTriangle = SelectedTriangle) then + Polygon([a, b, c]) + else + PolyLine([a, b, c, a]); + + pen.width:=4; + Ellipse(a.x - 3, a.y - 3, a.x + 3, a.y + 3); + Ellipse(b.x - 3, b.y - 3, b.x + 3, b.y + 3); + Ellipse(c.x - 3, c.y - 3, c.x + 3, c.y + 3); + pen.width:=1; + pen.mode:=pmCopy; + + if not (CornerCaught or TriangleCaught) then // show used variations + begin + font.Color := GetTriangleColor(mouseOverTriangle); + brush.Style := bsClear; + ay := Height-foc_ofs*2 + font.Height; // font.height < 0 + for i:= NRVAR - 1 downto 0 do + if cp.xform[mouseOverTriangle].GetVariation(i) <> 0 then + begin + vvstr := Varnames(i) + Format(' = %.6g', [cp.xform[mouseOverTriangle].GetVariation(i)]); + ax := Width-foc_ofs*2 - TextWidth(vvstr); + TextOut(ax, ay, vvstr); + Inc(ay, font.Height); + end; +// brush.Style := bsSolid; + end; + end; + + pen.color := clWhite; + if CornerCaught then // draw selected corner + begin + brush.Color:=clSilver; + a := ToScreen(MainTriangles[SelectedTriangle].x[SelectedCorner], MainTriangles[SelectedTriangle].y[SelectedCorner]); + Ellipse(a.x - 4, a.y - 4, a.x + 4, a.y + 4); + end + else if (mouseOverTriangle>=0) then + begin + if (mouseOverCorner >= 0) then // highlight corner under cursor + begin + case mouseOverCorner of + 0: brush.Color:=clRed; + 2: brush.Color:=clBlue; + else brush.Color:=clSilver; + end; + + a := ToScreen(MainTriangles[mouseOverTriangle].x[mouseOverCorner], MainTriangles[mouseOverTriangle].y[mouseOverCorner]); + Ellipse(a.x - 4, a.y - 4, a.x + 4, a.y + 4); + + // hmm... TODO: optimize + if HelpersEnabled then begin + pen.Color := HelpersColor; + pen.Mode := pmMerge; + pen.Style := psDot; + brush.Style := bsClear; + if (editMode = modeRotate) then + begin + i := integer(round(olddist * sc)); + if i > 4 then begin + a := ToScreen(pivot.x, pivot.y); + Ellipse(a.x - i, a.y - i, a.x + i, a.y + i); + end; + end + else if editMode = modeScale then + begin + dx := MainTriangles[mouseOverTriangle].x[mouseOverCorner] - Pivot.x; + dy := MainTriangles[mouseOverTriangle].y[mouseOverCorner] - Pivot.y; + LineDxDy; + end; + end; + end; + + if (mouseOverEdge >= 0) then // highlight edge under cursor + begin + i := (mouseOverEdge + 1) mod 3; + a := ToScreen(MainTriangles[mouseOverTriangle].x[mouseOverEdge], MainTriangles[mouseOverTriangle].y[mouseOverEdge]); + b := ToScreen(MainTriangles[mouseOverTriangle].x[i], MainTriangles[mouseOverTriangle].y[i]); + + pen.Width:=5; + Pen.Color:=GetTriangleColor(mouseOverTriangle) shr 1 and $7f7f7f; + Pen.Mode:=pmMerge; + + MoveTo(a.X, a.Y); + LineTo(b.X, b.Y); + pen.Mode:=pmCopy; + pen.Width:=1; + end; + end; + + // draw pivot point + a := ToScreen(GetPivot.x, GetPivot.y); + Pen.Style := psSolid; + pen.Color := clWhite; + brush.Color := clSilver; + if (pivotMode = pivotLocal) or EdgeCaught then i := 2 + else i := 3; + Ellipse(a.x - i, a.y - i, a.x + i, a.y + i); + + if editMode = modePick then begin // hmm... + a := ToScreen(mouseOverPos.x, mouseOverPos.y); + brush.Style := bsClear; + Ellipse(a.x - i, a.y - i, a.x + i, a.y + i); + end; + + if TWinControl(Sender).Focused then + begin + pen.Color := HelpersColor; + pen.Mode := pmXor; + MoveTo(foc_ofs, foc_size); + LineTo(foc_ofs, foc_ofs); + LineTo(foc_size, foc_ofs); + MoveTo(Width-1-foc_ofs, foc_size); + LineTo(Width-1-foc_ofs, foc_ofs); + LineTo(Width-1-foc_size, foc_ofs); + MoveTo(Width-1-foc_ofs, Height-1-foc_size); + LineTo(Width-1-foc_ofs, Height-1-foc_ofs); + LineTo(Width-1-foc_size, Height-1-foc_ofs); + MoveTo(foc_ofs, Height-1-foc_size); + LineTo(foc_ofs, Height-1-foc_ofs); + LineTo(foc_size, Height-1-foc_ofs); + end; + end; + TriangleView.Canvas.Draw(0, 0, Bitmap); + finally + BitMap.Free; + end; +end; + +procedure TEditForm.FormCreate(Sender: TObject); +var + i: integer; + vn: string; +begin + mnuELowQuality.Caption := TextByKey('common-lowquality'); + mnuEMediumQuality.Caption := TextByKey('common-mediumquality'); + mnuEHighQuality.Caption := TextByKey('common-highquality'); + mnuLowQuality.Caption := TextByKey('common-lowquality'); + mnuMediumQuality.Caption := TextByKey('common-mediumquality'); + mnuHighQuality.Caption := TextByKey('common-highquality'); + ToolButton9.Caption := TextByKey('common-copy'); + ToolButton9.Hint := TextByKey('common-copy'); + tbCopyTriangle.Hint := TextByKey('common-copy'); + ToolButton10.Caption := TextByKey('common-paste'); + ToolButton9.Hint := TextByKey('common-paste'); + tbPasteTriangle.Hint := TextByKey('common-paste'); + tbUndo.Caption := TextByKey('common-undo'); + tbUndo.Hint := TextByKey('common-undo'); + mnuUndo.Caption := TextByKey('common-undo'); + tbRedo.Caption := TextByKey('common-redo'); + tbRedo.Hint := TextByKey('common-redo'); + mnuRedo.Caption := TextByKey('common-redo'); + bClear.Caption := TextByKey('common-clear'); + pnlSymmetry.Hint := TextByKey('common-dragpanelhint'); + pnlOpacity.Hint := TextByKey('common-dragpanelhint'); + pnlDC.Hint := TextByKey('common-dragpanelhint'); + pnlWeight.Hint := TextByKey('common-dragpanelhint'); + self.Caption := TextByKey('editor-title'); + Panel1.Caption := TextByKey('editor-common-transform'); + Panel2.Caption := TextByKey('editor-common-name'); + pnlWeight.Caption := TextByKey('editor-common-weight'); + + tabVariations.Caption := TextByKey('editor-tab-variations-title'); + VEVars.TitleCaptions[0] := TextByKey('editor-tab-variations-name'); + VEVars.TitleCaptions[1] := TextByKey('editor-tab-variations-value'); + chkCollapseVariations.Caption := TextByKey('editor-tab-variations-togglehideunused'); + TabSheet4.Caption := TextByKey('editor-tab-variables-title'); + vleVariables.TitleCaptions[0] := TextByKey('editor-tab-variables-name'); + vleVariables.TitleCaptions[1] := TextByKey('editor-tab-variables-value'); + chkCollapseVariables.Caption := TextByKey('editor-tab-variables-toggleshowall'); + TabChaos.Caption := TextByKey('editor-tab-chaos-title'); + vleChaos.TitleCaptions[0] := TextByKey('editor-tab-chaos-path'); + vleChaos.TitleCaptions[1] := TextByKey('editor-tab-chaos-modifier'); + optTo.Caption := TextByKey('editor-tab-chaos-viewasto'); + mnuChaosViewTo.Caption := TextByKey('editor-tab-chaos-viewasto'); + optFrom.Caption := TextByKey('editor-tab-chaos-viewasfrom'); + mnuChaosViewFrom.Caption := TextByKey('editor-tab-chaos-viewasfrom'); + TriangleTab.Caption := TextByKey('editor-tab-triangle-title'); + GroupBox3.Caption := TextByKey('editor-tab-triangle-pivot'); + + btnResetPivot.Hint := TextByKey('editor-tab-triangle-resetpivot'); + btnPickPivot.Hint := TextByKey('editor-tab-triangle-pickpivot'); + btTrgRotateLeft.Hint := TextByKey('editor-tab-triangle-rotateleft'); + btTrgRotateRight.Hint := TextByKey('editor-tab-triangle-rotateright'); + btTrgMoveUp.Hint := TextByKey('editor-tab-triangle-moveup'); + btTrgMoveDown.Hint := TextByKey('editor-tab-triangle-movedown'); + btTrgMoveLeft.Hint := TextByKey('editor-tab-triangle-moveleft'); + btTrgMoveRight.Hint := TextByKey('editor-tab-triangle-moveright'); + btTrgScaleDown.Hint := TextByKey('editor-tab-triangle-scaledown'); + btTrgScaleUp.Hint := TextByKey('editor-tab-triangle-scaleup'); + tbAutoWeights.Hint := TextByKey('editor-tab-triangle-autoweight'); + tabXForm.Caption := TextByKey('editor-tab-transform-title'); + btnResetCoefs.Caption := TextByKey('editor-tab-transform-reset'); + btnResetCoefs.Hint := TextByKey('editor-tab-transform-resethint'); + btnCoefsRect.Caption := TextByKey('editor-tab-transform-rectangular'); + btnCoefsRect.Hint := TextByKey('editor-tab-transform-rectangularhint'); + btnCoefsPolar.Caption := TextByKey('editor-tab-transform-polar'); + btnCoefsPolar.Hint := TextByKey('editor-tab-transform-polarhint'); + btnResetPostCoefs.Caption := TextByKey('editor-tab-transform-resetpost'); + btnResetPostCoefs.Hint := TextByKey('editor-tab-transform-resetposthint'); + chkAutoZScale.Caption := TextByKey('editor-tab-transform-autozscale'); + btnXcoefs.Hint := TextByKey('editor-tab-transform-resetxhint'); + btnXpost.Hint := TextByKey('editor-tab-transform-resetxhint'); + btnYcoefs.Hint := TextByKey('editor-tab-transform-resetyhint'); + btnYpost.Hint := TextByKey('editor-tab-transform-resetyhint'); + btnOcoefs.Hint := TextByKey('editor-tab-transform-resetohint'); + btnOpost.Hint := TextByKey('editor-tab-transform-resetohint'); + tabColors.Caption := TextByKey('editor-tab-color-title'); + GroupBox1.Caption := TextByKey('editor-tab-color-transformcolor'); + pnlSymmetry.Caption := TextByKey('editor-tab-color-colorspeed'); + pnlOpacity.Caption := TextByKey('editor-tab-color-opacity'); + pnlDC.Caption := TextByKey('editor-tab-color-directcolor'); + chkXFormSolo.Caption := TextByKey('editor-tab-color-togglesolo'); + GroupBox2.Caption := TextByKey('editor-tab-color-varpreview'); + Label1.Caption := TextByKey('editor-tab-color-previewrange'); + Label2.Caption := TextByKey('editor-tab-color-previewdepth'); + Label3.Caption := TextByKey('editor-tab-color-previewdensity'); + tbResetAll.Caption := TextByKey('editor-toolbar-newflame'); + tbResetAll.Hint := TextByKey('editor-toolbar-newflame'); + tbAdd.Caption := TextByKey('editor-toolbar-newtransform'); + tbAdd.Hint := TextByKey('editor-toolbar-newtransform'); + mnuAdd.Caption := TextByKey('editor-toolbar-newtransform'); + mnuAdd1.Caption := TextByKey('editor-toolbar-newtransform'); + ToolButton7.Caption := TextByKey('editor-toolbar-addlinkedtransform'); + ToolButton7.Hint := TextByKey('editor-toolbar-addlinkedtransform'); + mnuLinkPostxform.Caption := TextByKey('editor-toolbar-addlinkedtransform'); + tbDuplicate.Caption := TextByKey('editor-toolbar-duplicatetransform'); + tbDuplicate.Hint := TextByKey('editor-toolbar-duplicatetransform'); + mnuDuplicate.Caption := TextByKey('editor-toolbar-duplicatetransform'); + tbDelete.Caption := TextByKey('editor-toolbar-removetransform'); + tbDelete.Hint := TextByKey('editor-toolbar-removetransform'); + mnuDelete.Caption := TextByKey('editor-toolbar-removetransform'); + tbSelect.Caption := TextByKey('editor-toolbar-modeselect'); + tbSelect.Hint := TextByKey('editor-toolbar-modeselect'); + mnuSelectMode.Caption := TextByKey('editor-toolbar-modeselect'); + tbMove.Caption := TextByKey('editor-toolbar-modemove'); + tbMove.Hint := TextByKey('editor-toolbar-modemove'); + tbRotate.Caption := TextByKey('editor-toolbar-moderotate'); + tbRotate.Hint := TextByKey('editor-toolbar-moderotate'); + tbScale.Caption := TextByKey('editor-toolbar-modescale'); + tbScale.Hint := TextByKey('editor-toolbar-modescale'); + tbPivotMode.Caption := TextByKey('editor-toolbar-toggleworldpivot'); + tbPivotMode.Hint := TextByKey('editor-toolbar-toggleworldpivot'); + tbRotate90CCW.Caption := TextByKey('editor-toolbar-rotate90ccw'); + tbRotate90CCW.Hint := TextByKey('editor-toolbar-rotate90ccw'); + btTrgRotateLeft90.Hint := TextByKey('editor-toolbar-rotate90ccw'); + RotateTriangle90CCW1.Caption := TextByKey('editor-toolbar-rotate90ccw'); + tbRotate90CW.Caption := TextByKey('editor-toolbar-rotate90cw'); + tbRotate90CW.Hint := TextByKey('editor-toolbar-rotate90cw'); + btTrgRotateRight90.Hint := TextByKey('editor-toolbar-rotate90cw'); + RotateTriangle90CCW2.Caption := TextByKey('editor-toolbar-rotate90cw'); + tbFlipHorz.Caption := TextByKey('editor-toolbar-fliph'); + tbFlipHorz.Hint := TextByKey('editor-toolbar-fliph'); + mnuFlipHorizontal.Caption := TextByKey('editor-toolbar-fliph'); + tbFlipVert.Caption := TextByKey('editor-toolbar-flipv'); + tbFlipVert.Hint := TextByKey('editor-toolbar-flipv'); + mnuFlipVertical.Caption := TextByKey('editor-toolbar-flipv'); + tbVarPreview.Caption := TextByKey('editor-toolbar-togglevarpreview'); + tbVarPreview.Hint := TextByKey('editor-toolbar-togglevarpreview'); + mnuShowVarPreview.Caption := TextByKey('editor-toolbar-togglevarpreview'); + tbPostXSwap.Caption := TextByKey('editor-toolbar-toggleposttransform'); + tbPostXSwap.Hint := TextByKey('editor-toolbar-toggleposttransform'); + tb2PostXSwap.Hint := TextByKey('editor-toolbar-toggleposttransform'); + oggleposttriangleediting1.Caption := TextByKey('editor-toolbar-toggleposttransform'); + tbEnableFinalxform.Caption := TextByKey('editor-toolbar-togglefinaltransform'); + tbEnableFinalxform.Hint := TextByKey('editor-toolbar-togglefinaltransform'); + mnuAutoZoom.Caption := TextByKey('editor-popup-panel-autozoom'); + tbExtendedEdit.Hint := TextByKey('editor-popup-panel-toggleextendededit'); + mnuExtendedEdit.Caption := TextByKey('editor-popup-panel-toggleextendededit'); + tbAxisLock.Hint := TextByKey('editor-popup-panel-locktransformaxes'); + mnuAxisLock.Caption := TextByKey('editor-popup-panel-locktransformaxes'); + + //mnuHorizintalFlipAll.Caption := TextByKey('editor-popup-panel-allfliph'); + //mnuVerticalFlipAll.Caption := TextByKey('editor-popup-panel-allflipv'); + mnuResetLoc.Caption := TextByKey('editor-popup-quality-autoreset'); + mnuResetTrgPosition.Caption := TextByKey('editor-popup-transform-resetposition'); + mnuResetTrgRotation.Caption := TextByKey('editor-popup-transform-resetrotation'); + mnuResetTrgScale.Caption := TextByKey('editor-popup-transform-resetscale'); + mnuCopyTriangle.Caption := TextByKey('editor-popup-transform-copycoords'); + mnuPasteTriangle.Caption := TextByKey('editor-popup-transform-pastecoords'); + mnuReset.Caption := TextByKey('editor-popup-transform-resetentiretriangle'); + mnuChaosRebuild.Caption := TextByKey('editor-popup-chaos-rebuildlinks'); + mnuChaosClearAll.Caption := TextByKey('editor-popup-chaos-clearall'); + mnuChaosSetAll.Caption := TextByKey('editor-popup-chaos-setall'); + btnPivotMode.Hint := TextByKey('editor-toolbar-toggleworldpivot'); + EditPopup.Items[13].Caption := TextByKey('editor-popup-panel-allflipv'); + EditPopup.Items[14].Caption := TextByKey('editor-popup-panel-allfliph'); + + // Custom control setup + TriangleView := TCustomDrawControl.Create(self); + TriangleView.TabStop := True; + TriangleView.TabOrder := 0; + TriangleView.Parent := GrphPnl; + TriangleView.Align := alClient; + TriangleView.Visible := True; + + TriangleView.OnPaint := TriangleViewPaint; + + TriangleView.OnDblClick := TriangleViewDblClick; + TriangleView.OnMouseDown := TriangleViewMouseDown; + TriangleView.OnMouseMove := TriangleViewMouseMove; + TriangleView.OnMouseUp := TriangleViewMouseUp; + TriangleView.OnMouseWheel := TriangleViewMouseWheel; + TriangleView.OnKeyDown := TriangleViewKeyDown; + TriangleView.OnKeyUp := TriangleViewKeyUp; + + TriangleView.OnEnter := TriangleViewInvalidate; + TriangleView.OnExit := TriangleViewExit; + TriangleView.OnMouseLeave := TriangleViewmouseLeave; + + for i:= 0 to NRVAR - 1 do begin + vn := Varnames(i); + VEVars.InsertRow(vn, '0', True); + end; + for i:= 0 to GetNrVariableNames - 1 do begin + vn := GetVariableNameAt(i); + vleVariables.InsertRow(vn, '0', True); + end; + + vleChaos.InsertRow(Format(TextByKey('editor-common-toprefix'), [1]), '1', true); + mnuChaosRebuild.Checked := RebuildXaosLinks; + + GraphZoom := 1; + + case EditPrevQual of + 0: begin + mnuLowQuality.Checked := true; + PreviewDensity := prevLowQuality; + end; + 1: begin + mnuMediumQuality.Checked := true; + PreviewDensity := prevMediumQuality; + end; + 2: begin + mnuHighQuality.Checked := true; + PreviewDensity := prevHighQuality; + end; + end; + cp := TControlPoint.Create; + Render := TRenderer.Create; + + SelectMode := true; + editMode := modeMove; + AxisLock := TransformAxisLock; + tbAxisLock.Down := AxisLock; + ExtendedEdit := ExtEditEnabled; +// tbExtendedEdit.Down := ExtendedEdit; + widgetMode := modeRotate; +// tbExtendedEdit.ImageIndex := imgExtMove; + + EdgeCaught := false; + CornerCaught := false; + TriangleCaught := false; + mouseOverTriangle := -1; + mouseOverCorner := -1; + mouseOverEdge := -1; + mouseOverWidget := -1; + oldSelected := -1; + + MemTriangle.x[0] := 1; + MemTriangle.y[0] := 0; + MemTriangle.x[1] := 0; + MemTriangle.y[1] := 0; + MemTriangle.x[2] := 0; + MemTriangle.y[2] := 1; + + for i := 0 to NRVAR-1 do + VarsCache[i] := MinDouble; + +end; + +procedure TEditForm.FormDestroy(Sender: TObject); +begin + cp.free; + Render.free; +end; + +procedure TEditForm.TriangleViewMouseMove(Sender: TObject; Shift: TShiftState; + X, Y: integer); +var + vx, vy, fx, fy: double; + mt, mc, me: integer; + a, t: double; + + i, j: integer; + d: double; + + i0, i1: integer; + + dx, dy, x1, y1: double; +label FoundCorner, Skip1, Skip2; +begin + Scale(fx, fy, x, y); + StatusBar.Panels[0].Text := Format(TextByKey('editor-status-xformat'), [fx]); + StatusBar.Panels[1].Text := Format(TextByKey('editor-status-yformat'), [fy]); + + if viewDragMode then // graph panning + begin + if (fx = oldx) and (fy = oldy) then exit; + viewDragged := true; + GcenterX := GcenterX - (fx - oldx); + GcenterY := GcenterY - (fy - oldy); + TriangleView.Refresh; + exit; + end; + + mt:=mouseOverTriangle; + mc:=MouseOverCorner; + me:=mouseOverEdge; + + if not (CornerCaught or TriangleCaught) then // look for a point under cursor + begin + mouseOverWidget := -1; + mouseOverEdge := -1; + mouseOverCorner:= -1; + mouseOverPos.x := fx; + mouseOverPos.y := fy; + + if SelectMode then + begin + i0:=0; + i1:=LastTriangle;//Transforms-1; + end + else begin + i0:=SelectedTriangle; + i1:=i0; + end; + + for i := i1 downto i0 do + begin + for j := 0 to 2 do // -- detect point hit first + begin + d := dist(fx, fy, MainTriangles[i].x[j], MainTriangles[i].y[j]); + if (d * GraphZoom * 50) < 4 then + begin + mouseOverTriangle := i; + mouseOverCorner := j; +// mouseOverEdge := -1; + +// -- from MouseDown -- for highlighting: +// TODO: optimize... + if (j = 1) then + begin + if PivotMode = pivotLocal then begin + Pivot.x := 0; + Pivot.y := 0; + end + else Pivot := GetPivot; + + LocalAxisLocked := true; + end + else begin + Pivot := GetPivot(mouseOverTriangle); + LocalAxisLocked := false; + end; + oldx := MainTriangles[mouseOverTriangle].x[j] - Pivot.X; + oldy := MainTriangles[mouseOverTriangle].y[j] - Pivot.Y; + olddist := Hypot(oldx, oldy); +// -- + +// -- for Pick Pivot + if editMode = modePick then + begin + mouseOverPos.x := MainTriangles[mouseOverTriangle].x[mouseOverCorner]; + mouseOverPos.y := MainTriangles[mouseOverTriangle].y[mouseOverCorner]; + end; +// --- + goto FoundCorner; + end; + end; + end; + + if ExtendedEdit then //and (oldMode = modeNone) then + begin + for i := 0 to 3 do // -- detect 'widget' hit + for j := 0 to 1 do begin + if abs(line_dist(fx, fy, Widgets[i][j].x, Widgets[i][j].y, + Widgets[i][j+1].x, Widgets[i][j+1].y) + ) * GraphZoom * 50 < 3 then + begin + mouseOverTriangle := SelectedTriangle; + mouseOverWidget := i; +// mouseOverEdge := -1; +// mouseOverCorner:= -1; + mouseOverPos.x := fx; + mouseOverPos.y := fy; + + goto FoundCorner; + end; + end; + + for i := i1 downto i0 do + begin + for j := 0 to 2 do // -- detect edge hit + begin + if abs(line_dist(fx, fy, MainTriangles[i].x[j], MainTriangles[i].y[j], + MainTriangles[i].x[(j+1) mod 3], MainTriangles[i].y[(j+1) mod 3]) + ) * GraphZoom * 50 < 3 then + begin + mouseOverTriangle:=i; + mouseOverEdge := j; +// mouseOverCorner:= -1; + mouseOverPos.x := fx; + mouseOverPos.y := fy; + + goto FoundCorner; + end; + end; + end; + end; + + i := InsideTriangle(fx, fy); + if i >= 0 then mouseOverTriangle:=i + else mouseOverTriangle:=-1; + +FoundCorner: + end; + + if (mouseOverTriangle >= 0) or (SelectMode = false) or (oldMode <> modeNone) then + begin + if (mouseOverWidget >= 0) and (oldMode = modeNone) then + TriangleView.Cursor := crEditRotate + else + if (mouseOverEdge >= 0) and (oldMode = modeNone) then begin // kinda hack, not good... + if mouseOverEdge = 2 then + TriangleView.Cursor := crEditScale + else + TriangleView.Cursor := crEditRotate; + end + else + case editMode of + modeMove: + TriangleView.Cursor := crEditMove; + modeRotate: + TriangleView.Cursor := crEditRotate; + modeScale: + TriangleView.Cursor := crEditScale; + modePick: + TriangleView.Cursor := crEditArrow; + end + end + else + TriangleView.Cursor := crEditArrow; //crDefault; + + Shift := Shift - [ssLeft]; + + if CornerCaught then // Modify a point /////////////////////////////////////// + begin + if (editMode = modeRotate) then // rotate point + begin // rotate point around pivot + d := dist(Pivot.X, Pivot.Y, fx, fy); + if d<>0 then begin + if ssShift in Shift then // angle snap + begin + try + t := StrToFloat(txtTrgRotateValue.Text)/180*PI; + //assert(t<>0); + except + t := 15.0*PI/180.0; + txtTrgRotateValue.Text := '15'; + end; + if t = 0 then goto Skip1; //? + + a := Round(arctan2(fy-Pivot.Y, fx-Pivot.X)/t)*t; + vx := olddist*cos(a); + vy := olddist*sin(a); + end + else begin +Skip1: + vx := (fx-Pivot.X)*olddist/d; + vy := (fy-Pivot.Y)*olddist/d; + a := arctan2(vy,vx) - arctan2(oldy,oldx); + end; + + if LocalAxisLocked then with MainTriangles[SelectedTriangle] do + begin + assert(SelectedCorner = 1); + x[0] := OldTriangle.x[0] + Pivot.X+vx - OldTriangle.x[1]; + y[0] := OldTriangle.y[0] + Pivot.Y+vy - OldTriangle.y[1]; + x[2] := OldTriangle.x[2] + Pivot.X+vx - OldTriangle.x[1]; + y[2] := OldTriangle.y[2] + Pivot.Y+vy - OldTriangle.y[1]; + end; + MainTriangles[SelectedTriangle].x[SelectedCorner] := Pivot.X+vx; + MainTriangles[SelectedTriangle].y[SelectedCorner] := Pivot.Y+vy; + end + else a := 0; + vy := abs( + arctan2(MainTriangles[SelectedTriangle].y[0]-MainTriangles[SelectedTriangle].y[1], + MainTriangles[SelectedTriangle].x[0]-MainTriangles[SelectedTriangle].x[1]) + -arctan2(MainTriangles[SelectedTriangle].y[2]-MainTriangles[SelectedTriangle].y[1], + MainTriangles[SelectedTriangle].x[2]-MainTriangles[SelectedTriangle].x[1]) + ); + if vy > PI then vy := 2*PI - vy; + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-rotateformat'), [a*180/PI, vy*180/PI]); + end + else if (editMode = modeScale) then + begin // move point along vector ("scale") + if olddist<>0 then begin + d := (oldx*(fx-Pivot.X) + oldy*(fy-Pivot.Y))/olddist; + + if ssShift in Shift then // 'snapped' scale + begin + try // use move-value for 'scaling' point: + t := abs(StrToFloat(txtTrgMoveValue.Text)); + //assert(t<>0); + except + t := 0.1; + txtTrgMoveValue.Text := '0.1'; + end; + if t <> 0 then d := Trunc(d/t)*t; + end; + vx := oldx*d/olddist; + vy := oldy*d/olddist; + + if LocalAxisLocked then with MainTriangles[SelectedTriangle] do + begin + assert(SelectedCorner = 1); + x[0] := OldTriangle.x[0] + Pivot.X+vx - OldTriangle.x[1]; + y[0] := OldTriangle.y[0] + Pivot.Y+vy - OldTriangle.y[1]; + x[2] := OldTriangle.x[2] + Pivot.X+vx - OldTriangle.x[1]; + y[2] := OldTriangle.y[2] + Pivot.Y+vy - OldTriangle.y[1]; + end; + MainTriangles[SelectedTriangle].x[SelectedCorner] := Pivot.X + vx; + MainTriangles[SelectedTriangle].y[SelectedCorner] := Pivot.Y + vy; + + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-scaleformat'), + [Hypot(vx, vy), d*100/olddist]); + end + else begin + MainTriangles[SelectedTriangle].x[SelectedCorner] := Pivot.X; + MainTriangles[SelectedTriangle].y[SelectedCorner] := Pivot.Y; + end; + end + else begin // snap/move + if ssShift in Shift then // snap to axis + begin + if abs(fx-Pivot.X) > abs(fy-Pivot.Y) then begin + vx := fx; + vy := Pivot.Y; + end + else begin + vx := Pivot.x; + vy := fy; + end; + end + else begin // just move + vx := fx; + vy := fy; + end; + if (SelectedCorner = 1) and AxisLock then with MainTriangles[SelectedTriangle] do + begin + x[0] := OldTriangle.x[0] + (vx - OldTriangle.x[1]); + y[0] := OldTriangle.y[0] + (vy - OldTriangle.y[1]); + x[2] := OldTriangle.x[2] + (vx - OldTriangle.x[1]); + y[2] := OldTriangle.y[2] + (vy - OldTriangle.y[1]); + end; + MainTriangles[SelectedTriangle].x[SelectedCorner] := vx; + MainTriangles[SelectedTriangle].y[SelectedCorner] := vy; + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-moveformat'), [vx-(Pivot.X+oldx), vy-(Pivot.Y+oldy)]); + end; + // -- + HasChanged := True; + UpdateFlameX; +// UpdateFlame(False); + StatusBar.Refresh; + exit; + end + else if TriangleCaught then // Modify a whole triangle /////////////////////// + begin + if (editMode = modeRotate) then // rotate triangle + begin + a := arctan2(fy-Pivot.Y, fx-Pivot.X) - arctan2(oldy, oldx); + if ssShift in Shift then // angle snap + begin + try + t := StrToFloat(txtTrgRotateValue.Text)/180*PI; + //assert(t<>0); + except + t := 15.0*PI/180.0; + txtTrgRotateValue.Text := '15'; + end; + if t = 0 then goto Skip2; + + a := Round(a/t)*t + end; +Skip2: + MainTriangles[SelectedTriangle] := + RotateTrianglePoint(OldTriangle, Pivot.X, Pivot.Y, a); + + vx := MainTriangles[SelectedTriangle].x[0]-MainTriangles[SelectedTriangle].x[1]; + vy := MainTriangles[SelectedTriangle].y[0]-MainTriangles[SelectedTriangle].y[1]; + if abs(vx*(MainTriangles[SelectedTriangle].x[2]-MainTriangles[SelectedTriangle].x[1])+ + vy*(MainTriangles[SelectedTriangle].y[2]-MainTriangles[SelectedTriangle].y[1])) < 0.001 + then + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-rotateformat2'), [a*180/PI, arctan2(vy, vx)*180/PI]) + else StatusBar.Panels[2].Text := Format(TextByKey('editor-status-rotateformat3'), [a*180/PI]); + end + else if (editMode = modeScale) then // scale + begin + if olddist<>0 then begin + vy := (oldx*(fx-Pivot.X) + oldy*(fy-Pivot.Y))/sqr(olddist); + + if ssShift in Shift then // 'snapped' scale + begin + try + t := abs(StrToFloat(txtTrgScaleValue.Text)/100.0 - 1.0); + //assert(t<>0); + except + t := 0.1; + txtTrgRotateValue.Text := '0.1'; + end; + if t <> 0 then vy := Trunc(vy/t)*t; + end; + + MainTriangles[SelectedTriangle] := + ScaleTrianglePoint(OldTriangle, Pivot.X, Pivot.Y, vy); + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-scaleformat2'), [vy*100]); + end + else MainTriangles[SelectedTriangle] := OldTriangle; + end + else begin // snap/move + vx := fx - (Pivot.x + oldx); + vy := fy - (Pivot.y + oldy); + if ssShift in Shift then // snap to axis + begin + if abs(vx) > abs(vy) then vy := 0 + else vx := 0; + end; + with MainTriangles[SelectedTriangle] do + begin + x[0] := OldTriangle.x[0] + vx; + y[0] := OldTriangle.y[0] + vy; + x[1] := OldTriangle.x[1] + vx; + y[1] := OldTriangle.y[1] + vy; + x[2] := OldTriangle.x[2] + vx; + y[2] := OldTriangle.y[2] + vy; + end; + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-moveformat2'), [vx, vy]); + end; + HasChanged := True; + UpdateFlameX; +// UpdateFlame(False); + StatusBar.Refresh; + exit; + end; + if ((mt <> mouseOverTriangle) or (mc <> MouseOverCorner) or (me <> MouseOverEdge)) then + begin + if (mouseOverTriangle >= 0) then + StatusBar.Panels[2].Text := Format(TextByKey('editor-status-transformformat'), [mouseOverTriangle+1]) + else StatusBar.Panels[2].Text := ''; + TriangleView.Refresh; + end + else if editMode = modePick then TriangleView.Refresh; // hmm... +end; + +procedure TEditForm.TriangleViewMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: integer); +var + d, fx, fy: double; + i, j: integer; + i0, i1: integer; +label + FoundTriangle; +begin + TWinControl(Sender).SetFocus; + + viewDragged := false; + + Scale(fx, fy, x, y); + + if Button = mbLeft then + begin + if editMode = modePick then + begin + if (mouseOverCorner >= 0) then // snap to point + begin + fx := MainTriangles[mouseOverTriangle].x[mouseOverCorner]; + fy := MainTriangles[mouseOverTriangle].y[mouseOverCorner]; + end; + if PivotMode = pivotLocal then + with MainTriangles[SelectedTriangle] do begin +// xx := x[0] - x[1]; +// xy := y[0] - y[1]; +// yx := x[2] - x[1]; +// yy := y[2] - y[1]; + d := (xx*yy - yx*xy); + if d <> 0 then + begin + LocalPivot.x := ( (fx - x[1]) * yy - (fy - y[1]) * yx) / d; + LocalPivot.y := (-(fx - x[1]) * xy + (fy - y[1]) * xx) / d; + end + end + else begin + WorldPivot.x := fx; + WorldPivot.y := fy; + end; + editMode := oldMode; + oldMode := modeNone; + btnPickPivot.Down := false; + ShowSelectedInfo; + TriangleView.Invalidate; + exit; + end; + + Shift := Shift - [ssLeft]; + if SelectMode then + begin + i0:=0; + i1:=LastTriangle; + end + else begin // Only check selected triangle + i0:=SelectedTriangle; + i1:=i0; + end; + oldSelected := SelectedTriangle; + + for i := i1 downto i0 do + begin + for j := 0 to 2 do // detect corner hit + begin + d := dist(fx, fy, MainTriangles[i].x[j], MainTriangles[i].y[j]); + if (d * GraphZoom * 50) < 4 then + begin + SelectedTriangle := i; + CornerCaught := True; + + SelectedCorner := j; +// Pivot := GetPivot; + if (j = 1) then //and ((rgPivot.ItemIndex = 1) or (rgPivot.ItemIndex = 4)) then + begin + if PivotMode = pivotLocal then begin + Pivot.x := 0; + Pivot.y := 0; + end + else Pivot := GetPivot; + + LocalAxisLocked := true; + end + else begin + Pivot := GetPivot; + LocalAxisLocked := false; + end; + OldTriangle := MainTriangles[SelectedTriangle]; + oldx := MainTriangles[SelectedTriangle].x[j] - Pivot.X; + oldy := MainTriangles[SelectedTriangle].y[j] - Pivot.Y; + olddist := sqrt(sqr(oldx) + sqr(oldy)); + + HasChanged := false; + ShowSelectedInfo; + TriangleView.Invalidate; + exit; + end; + end; + end; + + if ExtendedEdit then //and (oldMode = modeNone) then + begin + for i := 0 to 3 do // -- detect 'widget' hit + for j := 0 to 1 do + begin + if abs(line_dist(fx, fy, Widgets[i][j].x, Widgets[i][j].y, + Widgets[i][j+1].x, Widgets[i][j+1].y) + ) * GraphZoom * 50 < 3 then + begin +// modeHack := true; + if (oldMode = modeNone) then + begin + modeHack := true; + oldMode := editMode; + editMode := modeRotate; + end; + goto FoundTriangle; + end; + end; + + for i := i1 downto i0 do + begin + for j := 0 to 2 do // -- detect edge hit + begin + if abs(line_dist(fx, fy, MainTriangles[i].x[j], MainTriangles[i].y[j], + MainTriangles[i].x[(j+1) mod 3], MainTriangles[i].y[(j+1) mod 3]) + ) * GraphZoom * 50 < 3 then + begin + SelectedTriangle := i; + EdgeCaught := true; +// modeHack := true; + if (oldMode = modeNone) then + begin + modeHack := true; + oldMode := editMode; + if j = 2 then + editMode := modeScale + else + if AxisLock then editMode := modeRotate + else +begin + // hacky... + CornerCaught := True; + editMode := modeRotate; + if j = 1 then SelectedCorner := 2 + else SelectedCorner := 0; + Pivot := GetPivot; + LocalAxisLocked := false; + OldTriangle := MainTriangles[SelectedTriangle]; + oldx := MainTriangles[SelectedTriangle].x[SelectedCorner] - Pivot.X; + oldy := MainTriangles[SelectedTriangle].y[SelectedCorner] - Pivot.Y; + olddist := sqrt(sqr(oldx) + sqr(oldy)); + + HasChanged := false; + ShowSelectedInfo; + TriangleView.Invalidate; + exit; +end; + end; + goto FoundTriangle; + end; + end; + end; + end; + + // so user hasn't selected any corners, + // let's check for triangles then! + + if SelectMode then + begin + i := InsideTriangle(fx, fy); + if i >= 0 then SelectedTriangle := i + else + if (oldMode = modeNone) and not(ssShift in Shift) then exit; + end; +FoundTriangle: + TriangleCaught := True; + + OldTriangle := MainTriangles[SelectedTriangle]; + //MainForm.UpdateUndo; + HasChanged := false; + + Pivot := GetPivot; + oldx := fx-Pivot.X; + oldy := fy-Pivot.Y; + olddist := sqrt(oldx*oldx + oldy*oldy); + + ShowSelectedInfo; + TriangleView.Invalidate; + exit; + end + else if (Button = mbRight) and + not (TriangleCaught or CornerCaught) then // graph panning + begin + SetCaptureControl(TriangleView); + Screen.Cursor := crSizeAll; + + viewDragMode := true; + oldx := fx; + oldY := fy; + end; +end; + +procedure TEditForm.TriangleViewMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: integer); +begin + if Button = mbLeft then + begin + if modeHack then begin + assert(oldMode <> modeNone); + editMode := oldMode; + oldMode := modeNone; + + modeHack := false; + end; + + if HasChanged then + begin + MainForm.UpdateUndo; + UpdateFlame(true); + HasChanged := False; + end; + EdgeCaught := false; + CornerCaught := false; + TriangleCaught := false; + TriangleView.Invalidate; + end + else if (Button = mbRight) and viewDragMode then + begin + viewDragMode := false; + + Screen.Cursor := crDefault; + SetCaptureControl(nil); + + if viewDragged = false then // haven't dragged - popup menu then + begin + //GetCursorPos(mousepos); // hmmm + mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); + if mouseOverTriangle < 0 then + EditPopup.Popup(mousepos.x, mousepos.y) + else begin + SelectedTriangle := mouseOverTriangle; + cbTransforms.ItemIndex := SelectedTriangle; + TriangleView.Refresh; + TrianglePopup.Popup(mousepos.x, mousepos.y) + end; + end + else viewDragged := false; + end +end; + +procedure TEditForm.FormShow(Sender: TObject); +var + Registry: TRegistry; +begin + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Editor', False) then + begin + { Size and position } + if Registry.ValueExists('Left') then + EditForm.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + EditForm.Top := Registry.ReadInteger('Top'); + if Registry.ValueExists('Width') then + EditForm.Width := Registry.ReadInteger('Width'); + if Registry.ValueExists('Height') then + EditForm.Height := Registry.ReadInteger('Height'); + + if Registry.ValueExists('ResetLocation') then + mnuResetLoc.checked := Registry.ReadBool('ResetLocation') + else + mnuResetLoc.checked := false; + if Registry.ValueExists('HelpersEnabled') then + HelpersEnabled := Registry.ReadBool('HelpersEnabled') + else + HelpersEnabled := true; + + if Registry.ValueExists('VariationPreview') then + begin + showVarPreview := Registry.ReadBool('VariationPreview'); + tbVarPreview.Down := showVarPreview; + end + else begin + showVarPreview := false; + tbVarPreview.Down := false; + end; + + if Registry.ValueExists('VariationPreviewRange') then + trkVarPreviewRange.Position := Registry.ReadInteger('VariationPreviewRange'); + if Registry.ValueExists('VariationPreviewDensity') then + trkVarPreviewDensity.Position := Registry.ReadInteger('VariationPreviewDensity'); + if Registry.ValueExists('VariationPreviewDepth') then + trkVarPreviewDepth.Position := Registry.ReadInteger('VariationPreviewDepth'); + end + else begin + UseFlameBackground := False; + mnuResetLoc.checked := false; + end; + Registry.CloseKey; + finally + Registry.Free; + end; +// chkUseXFormColor.checked := UseTransformColors; +// chkHelpers.Checked := HelpersEnabled; + + if ExtendedEdit then tbExtendedEdit.Down := true + else tbMove.Down := true; + + UpdateDisplay; + TrianglePanelResize(nil); + ScrollBox1Resize(nil); +end; + +procedure TEditForm.mnuDeleteClick(Sender: TObject); +begin + if (SelectedTriangle >= 0) then DeleteTriangle(SelectedTriangle); +end; + +procedure TEditForm.mnuAddClick(Sender: TObject); +begin + if Transforms < NXFORMS then + begin + MainForm.UpdateUndo; + MainTriangles[Transforms+1] := MainTriangles[Transforms]; + cp.xform[Transforms+1].Assign(cp.xform[Transforms]); + MainTriangles[Transforms] := MainTriangles[-1]; + SelectedTriangle := Transforms; + cp.xform[Transforms].Clear; + cp.xform[Transforms].density := 0.5; + cp.xform[Transforms].SetVariation(0, 1); +// for i := 1 to NRVAR - 1 do cp.xform[Transforms].vars[i] := 0; + Inc(Transforms); + UpdateXformsList; + UpdateFlame(True); + end; +end; + +procedure TEditForm.mnuDupClick(Sender: TObject); +var + i: integer; +begin + if Transforms < NXFORMS then + begin + MainForm.UpdateUndo; + MainTriangles[Transforms+1] := MainTriangles[Transforms]; + cp.xform[Transforms+1].Assign(cp.xform[Transforms]); + if SelectedTriangle <> Transforms then + begin + MainTriangles[Transforms] := MainTriangles[SelectedTriangle]; + cp.xform[Transforms].Assign(cp.xform[SelectedTriangle]); + for i := 0 to Transforms-1 do + cp.xform[i].modWeights[Transforms] := cp.xform[i].modWeights[SelectedTriangle]; + cp.xform[Transforms].modWeights[Transforms] := cp.xform[SelectedTriangle].modWeights[SelectedTriangle]; + SelectedTriangle := Transforms; + end + else cp.xform[Transforms].density := 0.5; + Inc(Transforms); + UpdateXformsList; + UpdateFlame(True); + end; +end; + + +procedure TEditForm.mnuAutoZoomClick(Sender: TObject); +begin + AutoZoom; +end; + +procedure TEditForm.btnCloseClick(Sender: TObject); +begin + EditForm.Close; +end; + +procedure TEditForm.FormResize(Sender: TObject); +begin + AutoZoom; +end; + +procedure TEditForm.CornerEditExit(Sender: TObject); +var + Allow: boolean; + OldText: string; + Val: string; +begin + Allow := True; + if Sender = txtAx then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[0]]) + else if Sender = txtAy then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[0]]) + else if Sender = txtBx then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[1]]) + else if Sender = txtBy then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[1]]) + else if Sender = txtCx then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[2]]) + else if Sender = txtCy then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[2]]) + else if Sender = txtP then + if SelectedTriangle < Transforms then + val := Format('%.6f', [cp.xform[SelectedTriangle].density]); + OldText := Val; + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := OldText; + Allow := False; + end; + end; + { If it's not the same as the old value and it was valid } + if (val <> TEdit(Sender).Text) and Allow then + begin + if Sender = txtAx then + MainTriangles[SelectedTriangle].x[0] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtAy then + MainTriangles[SelectedTriangle].y[0] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtBx then + MainTriangles[SelectedTriangle].x[1] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtBy then + MainTriangles[SelectedTriangle].y[1] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtCx then + MainTriangles[SelectedTriangle].x[2] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtCy then + MainTriangles[SelectedTriangle].y[2] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtP then + begin + cp.xform[SelectedTriangle].density := StrToFloat(TEdit(Sender).Text); + TEdit(Sender).Text := Format('%.6g', [cp.xform[SelectedTriangle].density]); + end; + MainForm.UpdateUndo; + UpdateFlame(True); + end; + + self.LastFocus := TEdit(sender); +end; + +procedure TEditForm.CornerEditKeyPress(Sender: TObject; var Key: Char); +var + Allow: boolean; + OldText: string; + Val: string; +begin + if key = #13 then + begin + Allow := True; + if Sender = txtAx then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[0]]) + else if Sender = txtAy then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[0]]) + else if Sender = txtBx then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[1]]) + else if Sender = txtBy then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[1]]) + else if Sender = txtCx then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[2]]) + else if Sender = txtCy then + Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[2]]) + else if Sender = txtP then + val := Format('%.6f', [cp.xform[SelectedTriangle].density]); + OldText := Val; + { Stop the beep } + Key := #0; + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := OldText; + Allow := False; + end; + end; + { If it's not the same as the old value and it was valid } + if (val <> TEdit(Sender).Text) and Allow then + begin + if Sender = txtAx then + MainTriangles[SelectedTriangle].x[0] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtAy then + MainTriangles[SelectedTriangle].y[0] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtBx then + MainTriangles[SelectedTriangle].x[1] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtBy then + MainTriangles[SelectedTriangle].y[1] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtCx then + MainTriangles[SelectedTriangle].x[2] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtCy then + MainTriangles[SelectedTriangle].y[2] := StrToFloat(TEdit(Sender).Text) + else if Sender = txtP then + begin + cp.xform[SelectedTriangle].density := StrToFloat(TEdit(Sender).Text); + TEdit(Sender).Text := Format('%.6g', [cp.xform[SelectedTriangle].density]); + end; + MainForm.UpdateUndo; + UpdateFlame(True); + end; + end; +end; + +{ ************************* Probability input ******************************** } + +procedure TEditForm.txtPKeyPress(Sender: TObject; var Key: Char); +var + Allow: boolean; + NewVal, OldVal: double; +begin + if SelectedTriangle >= Transforms then key := #0; + if key = #13 then + begin + { Stop the beep } + Key := #0; + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].density); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < 0.000001 then NewVal := 0.000001; + if NewVal > MAX_WEIGHT then NewVal := MAX_WEIGHT; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].density := NewVal; + //ReadjustWeights(cp); + UpdateFlame(True); + end; + end; +end; + +procedure TEditForm.txtPExit(Sender: TObject); +var + Allow: boolean; + NewVal, OldVal: double; +begin + if SelectedTriangle >= Transforms then exit; + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].density); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < 0.000001 then NewVal := 0.000001; + if NewVal > MAX_WEIGHT then NewVal := MAX_WEIGHT; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].density := NewVal; + //ReadjustWeights(cp); + UpdateFlame(True); + end; + self.LastFocus := TEdit(sender); +end; + +{ **************************************************************************** } + +procedure TEditForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + { Defaults } + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Editor', True) then + begin + { Options } +// Registry.WriteBool('UseFlameBackground', UseFlameBackground); + Registry.WriteBool('ResetLocation', mnuResetLoc.checked); + Registry.WriteBool('VariationPreview', showVarPreview); + Registry.WriteBool('HelpersEnabled', HelpersEnabled); + Registry.WriteInteger('VariationPreviewRange', trkVarPreviewRange.Position); + Registry.WriteInteger('VariationPreviewDensity', trkVarPreviewDensity.Position); + Registry.WriteInteger('VariationPreviewDepth', trkVarPreviewDepth.Position); + { Size and position } + if EditForm.WindowState <> wsMaximized then begin + Registry.WriteInteger('Top', EditForm.Top); + Registry.WriteInteger('Left', EditForm.Left); + Registry.WriteInteger('Width', EditForm.Width); + Registry.WriteInteger('Height', EditForm.Height); + end; + end; + finally + Registry.Free; + end; +end; + +procedure TEditForm.mnuUndoClick(Sender: TObject); +begin + MainForm.Undo; +end; + +procedure TEditForm.mnuRedoClick(Sender: TObject); +begin + MainForm.Redo; +end; + +procedure TEditForm.mnuLowQualityClick(Sender: TObject); +begin + mnuLowQuality.Checked := True; + mnuELowQuality.Checked := True; + //tbLowQ.Down := true; + PreviewDensity := prevLowQuality; + EditPrevQual := 0; + DrawPreview; + TriangleViewPaint(TriangleView); +end; + +procedure TEditForm.mnuHighQualityClick(Sender: TObject); +begin + mnuHighQuality.Checked := True; + mnuEHighQuality.Checked := True; + //tbHiQ.Down := true; + PreviewDensity := prevHighQuality; + EditPrevQual := 2; + DrawPreview; + TriangleViewPaint(TriangleView); +end; + +procedure TEditForm.mnuMediumQualityClick(Sender: TObject); +begin + mnuMediumQuality.Checked := True; + mnuEMediumQuality.Checked := True; + //tbMedQ.Down := true; + PreviewDensity := prevMediumQuality; + EditPrevQual := 1; + DrawPreview; + TriangleViewPaint(TriangleView); +end; + +procedure TEditForm.mnuResetLocClick(Sender: TObject); +var + reset: boolean; +begin + reset:= not mnuResetLoc.Checked; + mnuResetLoc.Checked := reset; + //tbResetLoc.Down := reset; + if reset then + begin + cp.width := MainCp.width; + cp.height := MainCp.height; + cp.pixels_per_unit := MainCp.pixels_per_unit; + cp.AdjustScale(PreviewImage.width, PreviewImage.Height); + cp.zoom := MainCp.zoom; + cp.center[0] := MainCp.center[0]; + cp.center[1] := MainCp.center[1]; + end; + DrawPreview; +end; + +procedure TEditForm.mnuFlipAllVClick(Sender: TObject); +var + i: integer; +begin + MainForm.UpdateUndo; + for i := -1 to Transforms do + begin + MainTriangles[i] := FlipTriangleVertical(MainTriangles[i]); + end; + cp.GetFromTriangles(MainTriangles, Transforms); + cp.TrianglesFromCP(MainTriangles); + AutoZoom; + UpdateFlame(True); +end; + +procedure TEditForm.mnuFlipAllHClick(Sender: TObject); +var + i: integer; +begin + MainForm.UpdateUndo; + for i := -1 to Transforms do + begin + MainTriangles[i] := FlipTriangleHorizontal(MainTriangles[i]); + end; + cp.GetFromTriangles(MainTriangles, Transforms); + cp.TrianglesFromCP(MainTriangles); + AutoZoom; + UpdateFlame(True); +end; + +procedure TEditForm.mnuFlipVerticalClick(Sender: TObject); +var + p: double; +begin + MainForm.UpdateUndo; + with MainTriangles[SelectedTriangle] do + begin + p := GetPivot.y * 2; + y[0] := p - y[0]; + y[1] := p - y[1]; + y[2] := p - y[2]; + end; + //AutoZoom; + UpdateFlame(True); +end; + +procedure TEditForm.mnuFlipHorizontalClick(Sender: TObject); +var + p: double; +begin + MainForm.UpdateUndo; + with MainTriangles[SelectedTriangle] do + begin + p := GetPivot.x * 2; + x[0] := p - x[0]; + x[1] := p - x[1]; + x[2] := p - x[2]; + end; + //AutoZoom; + UpdateFlame(True); +end; + +procedure TEditForm.cbTransformsChange(Sender: TObject); +var + n: integer; +begin + n := cbTransforms.ItemIndex; + // We got a bug in the ComboBox-control :( + {if (EnableFinalXForm or cp.HasFinalXForm) and (SelectedTriangle = LastTriangle) then + begin + n := cbTransforms.Items.Count - 1; + end;} + // + + if (n <> SelectedTriangle) and (n >= 0) and (n <= LastTriangle) then + begin + SelectedTriangle := n; + ShowSelectedInfo; + TriangleView.Invalidate; + end; + chkCollapseVariablesClick(nil); + chkCollapseVariationsClick(nil); +end; + +procedure TEditForm.cbTransformsDrawItem(Control: TWinControl; + Index: Integer; Rect: TRect; State: TOwnerDrawState); +var + h: integer; + ax,ay,bx,by: integer; + TrgColor: TColor; +begin + assert(Index >= 0); + TrgColor := GetTriangleColor(Index); + with cbTransforms.Canvas do + begin + h := Rect.Bottom - Rect.Top; + + brush.Color:=clBlack; + FillRect(Rect); + + Font.Color := clWhite; + TextOut(Rect.Left+h+2, Rect.Top, cbTransforms.Items[Index]);//IntToStr(Index+1)); + + pen.Color := TrgColor; + brush.Color := pen.Color shr 1 and $7f7f7f; + + ax:=Rect.Left+h-2; + ay:=Rect.Top+1; + bx:=Rect.Left+2; + by:=Rect.Bottom-3; + Polygon([Point(ax, ay), Point(ax, by), Point(bx, by)]); + end; +end; + +procedure TEditForm.CoefKeyPress(Sender: TObject; var Key: Char); +begin + if key <> #13 then exit; + key := #0; + CoefValidate(Sender); +end; + +procedure TEditForm.CoefValidate(Sender: TObject); +var + NewVal: double; + x, y, r, a: double; // dumb... must optimize +begin + try + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + except on Exception do + begin + ShowSelectedInfo; //TEdit(Sender).Text := Format('%.6g', [pVal^]); + exit; + end; + end; + + //TEdit(Sender).Text := Format('%.6g', [NewVal]); + + MainForm.UpdateUndo; // TODO - prevent unnecessary UpdateUndo... + with cp.xform[SelectedTriangle] do + begin + if btnCoefsRect.Down = true then + begin + if Sender = txtA then c[0][0] := NewVal + else if Sender = txtB then c[0][1] := -NewVal + else if Sender = txtC then c[1][0] := -NewVal + else if Sender = txtD then c[1][1] := NewVal + else if Sender = txtE then c[2][0] := NewVal + else if Sender = txtF then c[2][1] := -NewVal; + end + else begin + if (Sender = txtA) or (Sender = txtB) then begin + x := c[0][0]; + y := -c[0][1]; + end else + if (Sender = txtC) or (Sender = txtD) then begin + x := -c[1][0]; + y := c[1][1]; + end else + {if (Sender = txtE) or (Sender = txtF) then} + begin + x := c[2][0]; + y := -c[2][1]; + end; + r := Hypot(x, y); + a := arctan2(y, x); + + if (Sender = txtA) or (Sender = txtC) or (Sender = txtE) then + r := NewVal + else + a := NewVal*PI/180; + + x := r * cos(a); + y := r * sin(a); + if (Sender = txtA) or (Sender = txtB) then begin + c[0][0] := x; + c[0][1] := -y; + end else + if (Sender = txtC) or (Sender = txtD) then begin + c[1][0] := -x; + c[1][1] := y; + end else + {if (Sender = txtE) or (Sender = txtF) then} + begin + c[2][0] := x; + c[2][1] := -y; + end; + end; + end; + + cp.TrianglesFromCP(MainTriangles); + + ShowSelectedInfo; + UpdateFlame(true); + + self.LastFocus := TEdit(sender); +end; + +procedure TEditForm.scrlXFormColorScroll(Sender: TObject; + ScrollCode: TScrollCode; var ScrollPos: Integer); +begin + if (ScrollCode = scEndScroll) and HasChanged then begin + MainForm.UpdateUndo; + UpdateFlame(True); + end; +end; + +procedure TEditForm.scrlXFormColorChange(Sender: TObject); +var + v: double; +begin + if updating then exit; + + v := (scrlXFormColor.Position) / scrlXFormColor.Max; + if v <> cp.xform[SelectedTriangle].color then + begin + cp.xform[SelectedTriangle].color := v; + pnlXFormColor.color := ColorValToColor(MainCp.cmap, v); + shColor.Brush.Color := pnlXFormColor.Color; + txtXFormColor.Text := Format('%1.3f', [v]); + txtXFormColor.Refresh; + + HasChanged := true; + DrawPreview; + end; +end; + +(* +procedure TEditForm.chkUseXFormColorClick(Sender: TObject); +begin + UseTransformColors := chkUseXFormColor.checked; + TriangleView.Invalidate; +end; + +procedure TEditForm.chkHelpersClick(Sender: TObject); +begin + HelpersEnabled := chkHelpers.checked; + TriangleView.Invalidate; +end; +*) + +procedure TEditForm.txtXFormColorExit(Sender: TObject); +var + v: double; +begin + try + v := StrToFloat(txtXFormColor.Text); + except on EConvertError do + begin + txtXformColor.text := Format('%1.3f', [cp.xform[SelectedTriangle].color]); + exit; + end; + end; + if v > 1 then v := 1; + if v < 0 then v := 0; + if v <> cp.xform[SelectedTriangle].color then + begin + updating := true; + scrlXFormColor.Position := round(v * scrlXFormColor.Max); + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].color := v; + updating := false; + UpdateFlame(true); + end; +end; + +procedure TEditForm.txtXFormColorKeyPress(Sender: TObject; var Key: Char); +begin + if key = #13 then + begin + key := #0; + txtXFormColorExit(Sender); + end; +end; + +procedure TEditForm.txtOpacitySet(Sender: TObject); +var + Allow: boolean; + NewVal, OldVal: double; +begin + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].transOpacity); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < 0 then NewVal := 0; + if NewVal > 1 then NewVal := 1; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].transOpacity := NewVal; + UpdateFlame(True); + end; +end; + +procedure TEditForm.txtDCSet(Sender: TObject); +var + Allow: boolean; + NewVal, OldVal: double; +begin + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].pluginColor); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < 0 then NewVal := 0; + if NewVal > 1 then NewVal := 1; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].pluginColor := NewVal; + UpdateFlame(True); + end; +end; + +procedure TEditForm.txtSymmetrySet(Sender: TObject); +var + Allow: boolean; + NewVal, OldVal: double; +begin + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].symmetry); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < -1 then NewVal := -1; + if NewVal > 1 then NewVal := 1; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].symmetry := NewVal; + UpdateFlame(True); + end; +end; + +procedure TEditForm.txtOpacityKeyPress(Sender: TObject; var Key: Char); +var + Allow: boolean; + NewVal, OldVal: double; +begin + if key = #13 then + begin + { Stop the beep } + Key := #0; + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].transOpacity); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < 0 then NewVal := 0; + if NewVal > 1 then NewVal := 1; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].transOpacity := NewVal; + UpdateFlame(True); + end; + end; +end; + +procedure TEditForm.txtDCKeyPress(Sender: TObject; var Key: Char); +var + Allow: boolean; + NewVal, OldVal: double; +begin + if key = #13 then + begin + { Stop the beep } + Key := #0; + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].pluginColor); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < 0 then NewVal := 0; + if NewVal > 1 then NewVal := 1; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].pluginColor := NewVal; + UpdateFlame(True); + end; + end; +end; + +procedure TEditForm.txtSymmetrKeyPress(Sender: TObject; var Key: Char); +var + Allow: boolean; + NewVal, OldVal: double; +begin + if key = #13 then + begin + { Stop the beep } + Key := #0; + Allow := True; + OldVal := Round6(cp.xform[SelectedTriangle].symmetry); + { Test that it's a valid floating point number } + try + StrToFloat(TEdit(Sender).Text); + except on Exception do + begin + { It's not, so we restore the old value } + TEdit(Sender).Text := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + if NewVal < -1 then NewVal := -1; + if NewVal > 1 then NewVal := 1; + { If it's not the same as the old value and it was valid } + TEdit(Sender).Text := Format('%.6g', [NewVal]); + if (OldVal <> NewVal) and Allow then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].symmetry := NewVal; + UpdateFlame(True); + end; + end; +end; + +// -- Variation List Editor ---------------------------------------------------- + +procedure TEditForm.ValidateVariation; +var + i: integer; + NewVal, OldVal: double; +begin + i := VEVars.Row - 1; + OldVal := Round6(cp.xform[SelectedTriangle].GetVariation(i)); + try + NewVal := Round6(StrToFloat(VEVars.Values[VarNames(i)])); + except + VEVars.Values[VarNames(i)] := Format('%.6g', [OldVal]); + exit; + end; + if (NewVal <> OldVal) then + begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].SetVariation(i, NewVal); + VEVars.Values[VarNames(i)] := Format('%.6g', [NewVal]); + ShowSelectedInfo; + UpdateFlame(True); + end; + chkCollapseVariationsClick(nil); + chkCollapseVariablesClick(nil); +end; + +(* + +// here's another way to do this - +// we could use it with variables value editor, +// only if we had an *array* of variables + +type + TDblArray = array of double; + PDblArray = ^TDblArray; + +procedure ValidateValue(Sender: TValueListEditor; values: PDblArray); +var + Allow: boolean; + i: integer; + NewVal, OldVal: double; +begin + Allow := True; + + i := Sender.Row - 1; + + OldVal := values^[i]; +{ Test that it's a valid floating point number } + try + StrToFloat(Sender.Values[VarNames(i)]); + except on Exception do + begin + { It's not, so we restore the old value } + Sender.Values[VarNames(i)] := Format('%.6g', [OldVal]); + Allow := False; + end; + end; + NewVal := Round6(StrToFloat(Sender.Values[VarNames(i)])); + Sender.Values[VarNames(i)] := Format('%.6g', [NewVal]); + +{ If it's not the same as the old value and it was valid } + if (NewVal <> OldVal) and Allow then + begin + MainForm.UpdateUndo; + values^[i] := NewVal; + Sender.Values[VarNames(i)] := Format('%.6g', [NewVal]); + EditForm.ShowSelectedInfo; + EditForm.UpdateFlame(True); + end; +end; +*) + +procedure TEditForm.VEVarsKeyPress(Sender: TObject; var Key: Char); +begin + if key = #13 then + begin + key := #0; + ValidateVariation; + end; +end; + +procedure TEditForm.VEVarsChange(Sender: TObject); +begin + ValidateVariation; +end; + +procedure TEditForm.VEVarsValidate(Sender: TObject; ACol, ARow: Integer; const KeyName, KeyValue: String); +begin + ValidateVariation; +end; + +// -- ValueList mouse stuff ---------------------------------------------------- + +procedure TEditForm.VEVarsMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +var + cell: TGridCoord; +begin + if Button = mbLeft then begin + varDragOld:=x; + cell := TValueListEditor(Sender).MouseCoord(x, y); + + varDragIndex := cell.Y-1; + + if (cell.y < 1) or (cell.y >= TValueListEditor(Sender).RowCount) or + (cell.x <> 0) then exit; + + TValueListEditor(Sender).Row := cell.Y; + + Screen.Cursor := crHSplit; + + //GetCursorPos(mousepos); // hmmm + mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); + + varDragMode:=true; + varDragPos:=0; + varMM := false; + SetCaptureControl(TValueListEditor(Sender)); + if Sender = VEVars then + varDragValue := cp.xform[SelectedTriangle].GetVariation(varDragIndex) + else if Sender = vleVariables then + cp.xform[SelectedTriangle].GetVariable(vleVariables.Keys[varDragIndex+1], varDragValue) + else if Sender = vleChaos then begin + if mnuChaosViewTo.Checked then + pDragValue := @cp.xform[SelectedTriangle].modWeights[varDragIndex] + else + pDragValue := @cp.xform[varDragIndex].modWeights[SelectedTriangle]; + varDragValue := pDragValue^; + end + else Assert(false); + + HasChanged := False; + end; +end; + +procedure TEditForm.VEVarsMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); +var + v: double; + cell: TGridCoord; +begin + cell := TValueListEditor(Sender).MouseCoord(x, y); + if (cell.Y > 0) and (cell.X = 0) then TValueListEditor(Sender).Cursor := crHandPoint + else TValueListEditor(Sender).Cursor := crDefault; + + if varMM then // hack: to skip MouseMove event + begin + varMM:=false; + end + else + if varDragMode and (x <> varDragOld) then + begin + Inc(varDragPos, x - varDragOld); + + if GetKeyState(VK_MENU) < 0 then v := 100000 + else if GetKeyState(VK_CONTROL) < 0 then v := 10000 + else if GetKeyState(VK_SHIFT) < 0 then v := 100 + else v := 1000; + + v := Round6(varDragValue + varDragPos/v); + + SetCursorPos(MousePos.x, MousePos.y); // hmmm + // this Delphi is WEIRD! + // why GetCursorPos deals with TPoint, + // and SetCursorPos - with two integers? :) + varMM:=true; + + //cp.xform[SelectedTriangle].vars[varDragIndex] := v; + if Sender = VEVars then + begin + cp.xform[SelectedTriangle].SetVariation(varDragIndex, v); + VEVars.Values[VarNames(varDragIndex)] := FloatToStr(v); //Format('%.6g', [v]); + end + else if Sender = vleVariables then begin + cp.xform[SelectedTriangle].SetVariable(vleVariables.Keys[varDragIndex+1], v); + vleVariables.Values[vleVariables.Keys[varDragIndex+1]] := FloatToStr(v); + end + else begin + if v < 0 then v := 0; + //cp.xform[SelectedTriangle].modWeights[varDragIndex] := v; + pDragValue^ := v; + vleChaos.Cells[1, varDragIndex+1] := FloatToStr(v); + end; + + HasChanged := True; + UpdateFlameX; + end; +end; + +procedure TEditForm.VEVarsMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + if Button <> mbLeft then exit; + SetCaptureControl(nil); + if varDragMode then + begin + varDragMode:=false; + Screen.Cursor := crDefault; + + if HasChanged then + begin + MainForm.UpdateUndo; + + UpdateFlame(true); + HasChanged := False; + end; + end; +end; + +procedure TEditForm.VEVarsDblClick(Sender: TObject); +var + n: integer; + v, v1: double; + changed: boolean; +begin + n := TValueListEditor(Sender).Row - 1; + assert(n >= 0); + assert(n < TValueListEditor(Sender).rowCount); + + //changed := false; + if (SelectedTriangle < 0) or (SelectedTriangle > High(cp.xform)) then + changed := false + else begin + if Sender = VEVars then + begin + if (n < 0) or (n > (cp.xform[SelectedTriangle].NumVariations - 1)) then + changed := false + else begin + v := cp.xform[SelectedTriangle].GetVariation(n); + cp.xform[SelectedTriangle].SetVariation(n, IfThen(v = 0, 1, 0)); + //VEVars.Values[VarNames(n)] := '0'; + changed := (cp.xform[SelectedTriangle].GetVariation(n) <> v); + end; + end + else if Sender = vleVariables then begin + (*if ((n + 1) < 0) or ((n + 1) > high(vleVariables.RowCount)) then + changed := false + else begin *) + cp.xform[SelectedTriangle].GetVariable(vleVariables.Keys[n + 1], v); + cp.xform[SelectedTriangle].ResetVariable(vleVariables.Keys[n + 1]); + //vleVariables.Values[vleVariables.Keys[varDragIndex+1]] := '0'; + cp.xform[SelectedTriangle].GetVariable(vleVariables.Keys[n + 1], v1); + changed := (v1 <> v); + //end; + end + else if Sender = vleChaos then begin + if ((varDragIndex) < 0) or ((varDragIndex) > high(cp.xform[SelectedTriangle].modWeights)) then + changed := false + else begin + if mnuChaosViewTo.Checked then + pDragValue := @cp.xform[SelectedTriangle].modWeights[varDragIndex] + else + pDragValue := @cp.xform[varDragIndex].modWeights[SelectedTriangle]; + v := pDragValue^; + //v := cp.xform[SelectedTriangle].modWeights[n]; + v := ifthen(v = 1, 0, 1); + //cp.xform[SelectedTriangle].modWeights[n] := v; + pDragValue^ := v; + vleChaos.Cells[1, n+1] := FloatToStr(v); + changed := true; + end + //else Assert(false); + end else changed := false; + end; + + if changed then MainForm.UpdateUndo; + UpdateFlame(true); +end; + +{ **************************************************************************** } + +function TEditForm.GetPivot: TSPoint; +begin + Result := GetPivot(SelectedTriangle); +end; + +function TEditForm.GetPivot(n: integer): TSPoint; +begin + if (PivotMode = pivotLocal) or {EdgeCaught} (mouseOverEdge >= 0) then // should be always local for edges (hmm...?) + with MainTriangles[n] do begin + Result.x := x[1] + (x[0] - x[1])*LocalPivot.x + (x[2] - x[1])*LocalPivot.y; + Result.y := y[1] + (y[0] - y[1])*LocalPivot.x + (y[2] - y[1])*LocalPivot.y; + end + else begin + Result.x := WorldPivot.x; + Result.y := WorldPivot.y; + end; +end; + +procedure TEditForm.ScriptGetPivot(var px, py: double); +begin + if (PivotMode = pivotLocal) then + with MainTriangles[SelectedTriangle] do begin + px := x[1] + (x[0] - x[1])*LocalPivot.x + (x[2] - x[1])*LocalPivot.y; + py := y[1] + (y[0] - y[1])*LocalPivot.x + (y[2] - y[1])*LocalPivot.y; + end + else begin + px := WorldPivot.x; + py := WorldPivot.y; + end; +end; + +procedure TEditForm.InvokeResetAll; +begin + mnuResetAllClick(nil); +end; + +procedure TEditForm.UpdateColorBar; +var + BitMap:TBitmap; + Row:pRGBTripleArray; + i:integer; +begin + BitMap := TBitMap.Create; + try + Bitmap.PixelFormat := pf24bit; + BitMap.Width := 256; + BitMap.Height := 1; + Row := Bitmap.Scanline[0]; + for i := 0 to 255 do + with Row[i] do + begin + rgbtRed := MainCP.cmap[i][0]; + rgbtGreen := MainCP.cmap[i][1]; + rgbtBlue := MainCP.cmap[i][2]; + end; + + EditForm.ColorBarPicture.Picture.Graphic := Bitmap; + EditForm.ColorBarPicture.Refresh; + finally + BitMap.Free; + end; +end; + +procedure TEditForm.btTrgRotateLeftClick(Sender: TObject); +var + angle: double; +begin + try + angle := StrToFloat(txtTrgRotateValue.Text); + except + txtTrgRotateValue.ItemIndex := 1; + exit; + end; + assert(angle <> 0); + + if GetKeyState(VK_CONTROL) < 0 then angle := angle/6.0 + else if GetKeyState(VK_SHIFT) < 0 then angle := angle*6.0; + + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := + RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, (PI/180)*angle); + HasChanged := True; + UpdateFlame(true); +end; + +procedure TEditForm.btTrgRotateLeft90Click(Sender: TObject); +begin + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := + RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, PI/2); + HasChanged := True; + UpdateFlame(true); +end; + +procedure TEditForm.btTrgRotateRightClick(Sender: TObject); +var + angle: double; +begin + try + angle := StrToFloat(txtTrgRotateValue.Text); + except + txtTrgRotateValue.ItemIndex := 1; + exit; + end; + assert(angle <> 0); + + if GetKeyState(VK_CONTROL) < 0 then angle := angle/6.0 + else if GetKeyState(VK_SHIFT) < 0 then angle := angle*6.0; + + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := + RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, -(PI/180)*angle); + HasChanged := True; + UpdateFlame(true); +end; + +procedure TEditForm.btTrgRotateRight90Click(Sender: TObject); +begin + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := + RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, -PI/2); + HasChanged := True; + UpdateFlame(true); +end; + +procedure TEditForm.PaintBackground; +begin + assert(false); + TriangleViewPaint(TriangleView); +end; + +procedure TEditForm.TrgMove(dx, dy: double); +var + i: integer; + offset: double; +begin + try + offset := StrToFloat(txtTrgMoveValue.Text); + assert(offset <> 0); + except + txtTrgMoveValue.ItemIndex := 1; + exit; + end; + + if GetKeyState(VK_CONTROL) < 0 then offset := offset/10.0 + else if GetKeyState(VK_SHIFT) < 0 then offset := offset*10.0; + + MainForm.UpdateUndo; + for i := 0 to 2 do begin + MainTriangles[SelectedTriangle].x[i] := + MainTriangles[SelectedTriangle].x[i] + dx*offset; + MainTriangles[SelectedTriangle].y[i] := + MainTriangles[SelectedTriangle].y[i] + dy*offset; + end; +// HasChanged := True; + UpdateFlame(true); +end; + +procedure TEditForm.btTrgMoveLeftClick(Sender: TObject); +begin + TrgMove(-1,0); +end; + +procedure TEditForm.btTrgMoveRightClick(Sender: TObject); +begin + TrgMove(1,0); +end; + +procedure TEditForm.btTrgMoveUpClick(Sender: TObject); +begin + TrgMove(0,1); +end; + +procedure TEditForm.btTrgMoveDownClick(Sender: TObject); +begin + TrgMove(0,-1); +end; + +{ +procedure TEditForm.btTrgMoveLUClick(Sender: TObject); +begin + TrgMove(-1,1); +end; + +procedure TEditForm.btTrgMoveLDClick(Sender: TObject); +begin + TrgMove(-1,-1); +end; + +procedure TEditForm.btTrgMoveRUClick(Sender: TObject); +begin + TrgMove(1,1); +end; + +procedure TEditForm.btTrgMoveRDClick(Sender: TObject); +begin + TrgMove(1,-1); +end; +} + +procedure TEditForm.btTrgScaleUpClick(Sender: TObject); +var + scale: double; +begin + try + scale := StrToFloat(txtTrgScaleValue.Text) / 100.0; + except + txtTrgScaleValue.ItemIndex := 1; + exit; + end; + if scale = 0 then scale := 1e-6; //assert(scale <> 0); + + if GetKeyState(VK_CONTROL) < 0 then scale := sqrt(scale) + else if GetKeyState(VK_SHIFT) < 0 then scale := scale*scale; + + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := + ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, scale); + HasChanged := True; + UpdateFlame(true); +end; + +procedure TEditForm.btTrgScaleDownClick(Sender: TObject); +var + scale: double; +begin + try + scale := 100.0 / StrToFloat(txtTrgScaleValue.Text); + except + txtTrgScaleValue.ItemIndex := 1; + exit; + end; + if scale = 0 then scale := 1e-6; //assert(scale <> 0); + + if GetKeyState(VK_CONTROL) < 0 then scale := sqrt(scale) + else if GetKeyState(VK_SHIFT) < 0 then scale := scale*scale; + + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := + ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, scale); + HasChanged := True; + UpdateFlame(true); +end; + +procedure TEditForm.TriangleViewKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +begin + if (oldMode = modeNone) and + (key in [{VK_SHIFT,} VK_MENU, VK_CONTROL]) then + begin + oldMode := editMode; + modeKey := key; + + if key = VK_MENU then + if editMode <> modeRotate then + begin + editMode := modeRotate; + TriangleView.Cursor := crEditRotate; + end + else begin + editMode := modeMove; + TriangleView.Cursor := crEditMove; + end + else {if key = VK_CONTROL then} + begin + if editMode <> modeScale then + begin + editMode := modeScale; + TriangleView.Cursor := crEditScale; + end + else begin + editMode := modeMove; + TriangleView.Cursor := crEditMove; + end + end; + end + else + case key of + VK_LEFT: + if Shift = [ssAlt] then btTrgRotateLeftClick(Sender) + else TrgMove(-1,0); + VK_RIGHT: + if Shift = [ssAlt] then btTrgRotateRightClick(Sender) + else TrgMove(1,0); + VK_UP: + if Shift = [ssAlt] then btTrgScaleUpClick(Sender) + else TrgMove(0,1); + VK_DOWN: + if Shift = [ssAlt] then btTrgScaleDownClick(Sender) + else TrgMove(0,-1); + VK_PRIOR: btTrgRotateLeftClick(Sender); + VK_NEXT: btTrgRotateRightClick(Sender); + VK_HOME: btTrgScaleUpClick(Sender); + VK_END: btTrgScaleDownClick(Sender); + VK_INSERT: mnuDupClick(Sender); + VK_DELETE: mnuDeleteClick(Sender); + + // can be changed in the future... + Ord('R'): btnResetPivotClick(Sender); + Ord('P'): btnPickPivotClick(Sender); + Ord('T'): tbPostXswapClick(Sender); + + Ord('I'): // Invisible + begin + //chkXformInvisible.Checked := not chkXformInvisible.Checked; + end; + Ord('S'): // Solo + begin + chkXformSolo.Checked := not chkXformSolo.Checked; + end; + + 189: // "-" + begin + GraphZoom := GraphZoom * 0.8; + EditForm.StatusBar.Panels[2].Text := Format(TextByKey('editor-status-zoomformat'), [GraphZoom]); + TriangleView.Invalidate; + end; + 187: // "+" + begin + GraphZoom := GraphZoom * 1.25; + EditForm.StatusBar.Panels[2].Text := Format(TextByKey('editor-status-zoomformat'), [GraphZoom]); + TriangleView.Invalidate; + end; + VK_ESCAPE: + begin + if TriangleCaught or CornerCaught or EdgeCaught then begin + if modeHack then begin + assert(oldMode <> modeNone); + editMode := oldMode; + oldMode := modeNone; + + modeHack := false; + end; + + if HasChanged then + begin + MainTriangles[SelectedTriangle] := OldTriangle; + HasChanged := False; + end; + EdgeCaught := false; + CornerCaught := false; + TriangleCaught := false; + TriangleView.Invalidate; + UpdateFlameX; + end; + end + end; +end; + +procedure TEditForm.TriangleViewKeyUp(Sender: TObject; var Key: Word; + Shift: TShiftState); +begin + if (oldMode <> modeNone) and (key = modeKey) then + begin + assert(key in [VK_MENU, VK_CONTROL]); + + editMode := oldMode; + oldMode := modeNone; +// tbMove.Down := (editMode = modeMove); +// tbRotate.Down := (editMode = modeRotate); +// tbScale.Down := (editMode = modeScale); + + // hack: to generate MouseMove event + GetCursorPos(MousePos); + SetCursorPos(MousePos.x, MousePos.y); + end; +end; + +procedure TEditForm.TriangleViewExit(Sender: TObject); +begin + if oldMode <> modeNone then + begin + editMode := oldMode; + oldMode := modeNone; +// tbMove.Down := (editMode = modeMove); +// tbRotate.Down := (editMode = modeRotate); +// tbScale.Down := (editMode = modeScale); + end; + + mouseOverTriangle := -1; + TriangleView.Invalidate; +end; + +procedure TEditForm.TriangleViewMouseLeave(Sender: TObject); +begin + if viewDragMode = false then + begin + mouseOverTriangle := -1; + TriangleView.Invalidate; + end; +end; + +procedure TEditForm.EditKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +begin + case key of + VK_ADD: + if SelectedTriangle < LastTriangle then begin + txtNameExit(Sender); // store name before re-filling name box by changing xform + Inc(SelectedTriangle); + TriangleView.Invalidate; + ShowSelectedInfo; + chkCollapseVariablesClick(nil); + chkCollapseVariationsClick(nil); + end; + VK_SUBTRACT: + if SelectedTriangle > 0 then begin + txtNameExit(Sender); // store name before re-filling name box by changing xform + Dec(SelectedTriangle); + TriangleView.Invalidate; + ShowSelectedInfo; + chkCollapseVariablesClick(nil); + chkCollapseVariationsClick(nil); + end; + VK_MULTIPLY: + SetGraphZoom(GraphZoom * 1.25); + VK_DIVIDE: + SetGraphZoom(GraphZoom * 0.8); + VK_SPACE: + if not txtName.Focused then + btnPivotModeClick(Sender); + + else + key_handled := false; + exit; + end; + key_handled := true; + key := 0; +end; + +procedure TEditForm.EditKeyPress(Sender: TObject; var Key: Char); +begin + if txtName.Focused then begin + if (key = '+') or (key='-') then begin + // nvm...code moved to EditKeyDown + key := #0; + end; + if (key='"') then key := #0; // we dont want that in "name" box -> XML mess! + exit; + end else if txtSearchBox.Focused then begin + exit; + end; +// kill alphanumeric keys generally + if key_handled or (CharInSet(key,['A'..'z'])) then key := #0; // hmmm... +end; + +procedure TEditForm.splitterMoved(Sender: TObject); +begin + UpdatePreview; +end; + +procedure TEditForm.tbSelectClick(Sender: TObject); +begin + SelectMode := not SelectMode; + tbSelect.Down := SelectMode; + + if SelectMode then + begin + StatusBar.Panels[2].Text := TextByKey('editor-status-selecton'); + end + else begin + mouseOverTriangle := SelectedTriangle; + StatusBar.Panels[2].Text := TextByKey('editor-status-selectoff');; + end; + + // hack: to generate MouseMove event + GetCursorPos(MousePos); + SetCursorPos(MousePos.x, MousePos.y); +end; + +procedure TEditForm.SetGraphZoom(gz: double); +var + fx, fy, sc: double; + p: TPoint; +begin + p := TriangleView.ScreenToClient(MousePos); + Scale(fx, fy, p.X, p.Y); + + GraphZoom := gz; + + EditForm.StatusBar.Panels[2].Text := Format(TextByKey('editor-status-zoomformat'), [GraphZoom]); + + if viewDragMode then begin + sc := GraphZoom * 50; + gCenterX := 0 - (p.X - TriangleView.Width/2) / sc; + gCenterY := 0 + (p.Y - TriangleView.Height/2) / sc; + end; + + TriangleView.Invalidate; +end; + +procedure TEditForm.TriangleViewMouseWheel(Sender: TObject; Shift: TShiftState; + WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); +var + fx, fy, sc: double; + p: TPoint; +begin + p := TriangleView.ScreenToClient(MousePos); + Scale(fx, fy, p.X, p.Y); + + if WheelDelta > 0 then SetGraphZoom(GraphZoom * 1.25) + else SetGraphZoom(GraphZoom * 0.8); + + Handled := true; +end; + +procedure TEditForm.TriangleViewDblClick(Sender: TObject); +begin + if mouseOverTriangle >= 0 then + begin + if mouseOverCorner >= 0 then begin + case mouseOverCorner of + 0: if editMode = modeRotate then ResetAxisRotation(0) else ResetAxisScale(0); + 1: if editMode = modeRotate then ResetAxisRotation(1) + else begin + if editMode = modeScale then + ResetAxisScale(1) + else begin + if cp.xform[SelectedTriangle].postXswap then + btnOpostClick(Sender) + else + btnOcoefsClick(Sender); + end; + end; + 2: if editMode = modeRotate then ResetAxisRotation(2) else ResetAxisScale(2); + end; + end + else if mouseOverEdge >= 0 then begin + if AxisLock then begin + if (editMode = modeScale) or (mouseOverEdge = 2)then + mnuResetTrgScaleClick(Sender) + else + mnuResetTrgRotationClick(Sender); + end + else case mouseOverEdge of + 0: if editMode = modeScale then ResetAxisScale(0) else ResetAxisRotation(0); + 1: if editMode = modeScale then ResetAxisScale(2) else ResetAxisRotation(2); + 2: mnuResetTrgScaleClick(Sender); + end; + end + else if mouseOverWidget >= 0 then begin + case editMode of + modeScale: mnuResetTrgScaleClick(Sender); + else mnuResetTrgRotationClick(Sender); + end; + end + else case editMode of + //modeMove: Do Nothing + modeScale: mnuResetTrgScaleClick(Sender); + modeRotate: mnuResetTrgRotationClick(Sender); + end; + end + else AutoZoom; +end; + +procedure TEditForm.TriangleViewInvalidate(Sender: TObject); +begin + TriangleView.Invalidate; +end; + +procedure TEditForm.tbEditModeClick(Sender: TObject); +begin +// ExtendedEdit := (Sender = tbExtendedEdit); + if Sender = tbRotate then + begin + editMode := modeRotate; + //tbRotate.Down := true; + end + else if Sender = tbScale then + begin + editMode := modeScale; + //tbScale.Down := true; + end + else begin + editMode := modeMove; + //tbMove.Down := true; + end; + TToolButton(Sender).Down := true; + TriangleView.Invalidate; +end; + +procedure TEditForm.tbExtendedEditClick(Sender: TObject); +begin + ExtendedEdit := not ExtendedEdit; + tbExtendedEdit.Down := ExtendedEdit; + TriangleView.Invalidate; +end; + +procedure TEditForm.tbAxisLockClick(Sender: TObject); +begin + {if Sender = chkAxisLock then AxisLock := chkAxisLock.Checked + else} AxisLock := not AxisLock; + tbAxisLock.Down := AxisLock; + //chkAxisLock.Checked := AxisLock; +end; + +procedure TEditForm.tbFullViewClick(Sender: TObject); +begin + MainForm.mnuFullScreenClick(Sender); +end; + +//-- Variable List ------------------------------------------------------------- + +procedure TEditForm.ValidateVariable; +var + i: integer; + NewVal, OldVal: double; + str, oldstr: string; +begin + i := vleVariables.Row; + +{$ifndef VAR_STR} + cp.xform[SelectedTriangle].GetVariable(vleVariables.Keys[i], OldVal); + { Test that it's a valid floating point number } + try + NewVal := Round6(StrToFloat(vleVariables.Values[vleVariables.Keys[i]])); + except + { It's not, so we restore the old value } + vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [OldVal]); +// cp.xform[SelectedTriangle].GetVariableStr(vleVariables.Keys[i]); + exit; + end; + { If it's not the same as the old value and it was valid } + if (NewVal <> OldVal) then + begin + vleVariables.Cells[1,i]; + MainForm.UpdateUndo; + + cp.xform[SelectedTriangle].SetVariable(vleVariables.Keys[i], NewVal); + vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [NewVal]); + + ShowSelectedInfo; + UpdateFlame(True); + end; +{$else} + oldstr := cp.xform[SelectedTriangle].GetVariableStr(vleVariables.Keys[i]); + str := vleVariables.Values[vleVariables.Keys[i]]; + cp.xform[SelectedTriangle].SetVariableStr(vleVariables.Keys[i], str); + + if str <> oldstr then + begin + MainForm.UpdateUndo; + + vleVariables.Values[vleVariables.Keys[i]] := str; + + ShowSelectedInfo; + UpdateFlame(True); + end; +{$endif} + + chkCollapseVariationsClick(nil); + chkCollapseVariablesClick(nil); +end; + +procedure TEditForm.vleVariablesExit(Sender: TObject); +begin + ValidateVariable; +end; + +procedure TEditForm.vleVariablesKeyPress(Sender: TObject; var Key: Char); +begin + if key <> #13 then Exit; + key := #0; + + ValidateVariable; +end; + +procedure TEditForm.vleVariablesValidate(Sender: TObject; ACol, ARow: Integer; const KeyName, KeyValue: string); +begin + ValidateVariable; +end; + +(* +procedure TEditForm.vleVariablesGetPickList(Sender: TObject; + const KeyName: String; Values: TStrings); +begin + if KeyName ='blur2_type' then + begin + Values.Add('gaussian'); + Values.Add('zoom'); + Values.Add('radial'); + Values.Add('defocus'); + end; +end; + +procedure TEditForm.vleVariablesStringsChange(Sender: TObject); +begin + if (vleVariables.ItemProps[vleVariables.Row - 1].ReadOnly) then ValidateVariable; +end; +*) + +// ----------------------------------------------------------------------------- + +procedure TEditForm.txtValidateValue(Sender: TObject); +var + t: double; +begin + try + t := StrToFloat(TComboBox(Sender).Text); + if t <> 0 then exit; + except + TComboBox(Sender).ItemIndex := 1; + end; +end; + +procedure TEditForm.txtValKeyPress(Sender: TObject; var Key: Char); +begin + if key <> #13 then exit; + key := #0; + txtValidateValue(Sender); +end; + +procedure TEditForm.mnuResetTriangleClick(Sender: TObject); +begin + if (MainTriangles[SelectedTriangle].x[0] = MainTriangles[-1].x[0]) and + (MainTriangles[SelectedTriangle].x[1] = MainTriangles[-1].x[1]) and + (MainTriangles[SelectedTriangle].x[2] = MainTriangles[-1].x[2]) and + (MainTriangles[SelectedTriangle].y[0] = MainTriangles[-1].y[0]) and + (MainTriangles[SelectedTriangle].y[1] = MainTriangles[-1].y[1]) and + (MainTriangles[SelectedTriangle].y[2] = MainTriangles[-1].y[2]) + then exit; + + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := MainTriangles[-1]; + UpdateFlame(True); +{ + with cp.xform[SelectedTriangle] do + begin + if (c[0,0]<>1) or (c[0,1]<>0) or(c[1,0]<>0) or (c[1,1]<>1) or (c[2,0]<>0) or (c[2,1]<>0) then + begin + MainForm.UpdateUndo; + c[0, 0] := 1; + c[0, 1] := 0; + c[1, 0] := 0; + c[1, 1] := 1; + c[2, 0] := 0; + c[2, 1] := 0; + ShowSelectedInfo; + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); + end; + end; +} +end; + +procedure TEditForm.mnuResetAllClick(Sender: TObject); +var + i: integer; +begin + MainForm.UpdateUndo; + for i := 0 to Transforms do cp.xform[i].Clear; + cp.xform[0].SetVariation(0, 1); + cp.xform[0].density := 0.5; + cp.xform[1].symmetry := 1; + + cp.center[0] := 0; + cp.center[1] := 0; + cp.zoom := 0; + cp.pixels_per_unit := PreviewImage.Width/4; + cp.FAngle := 0; + + Transforms := 1; + SelectedTriangle := 1; + MainTriangles[0] := MainTriangles[-1]; + MainTriangles[1] := MainTriangles[-1]; // kinda reset finalxform + + EnableFinalXform := false; + assert(cp.HasFinalXForm = false); + +// cbTransforms.clear; +// cbTransforms.Items.Add('1'); +// cbTransforms.Items.Add('2'); + UpdateXformsList; + AutoZoom; + + UpdateFlame(True); +end; + +// ----------------------------------------------------------------------------- + +procedure TEditForm.btnXcoefsClick(Sender: TObject); +begin + with cp.xform[SelectedTriangle] do + begin + if (c[0][0] = 1) and (c[0][1] = 0) then exit; + + MainForm.UpdateUndo; + c[0][0] := 1; + c[0][1] := 0; + end; + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); +end; + +procedure TEditForm.btnYcoefsClick(Sender: TObject); +begin + if (cp.xform[SelectedTriangle].c[1][0] = 0) and + (cp.xform[SelectedTriangle].c[1][1] = 1) then exit; + + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].c[1][0] := 0; + cp.xform[SelectedTriangle].c[1][1] := 1; + + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); +end; + +procedure TEditForm.btnOcoefsClick(Sender: TObject); +begin + if (sender = mnuResetTrgPosition) and cp.xform[SelectedTriangle].postXswap then + begin + btnOpostClick(Sender); + exit; + end; + + if (cp.xform[SelectedTriangle].c[2][0] = 0) and + (cp.xform[SelectedTriangle].c[2][1] = 0) then exit; + + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].c[2][0] := 0; + cp.xform[SelectedTriangle].c[2][1] := 0; + + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); +end; + +procedure TEditForm.btnCoefsModeClick(Sender: TObject); +begin + ShowSelectedInfo; +end; + +procedure TEditForm.tbVarPreviewClick(Sender: TObject); +begin + showVarPreview := not showVarPreview; + tbVarPreview.Down := showVarPreview; + TriangleView.Invalidate; +end; + +procedure TEditForm.trkVarPreviewRangeChange(Sender: TObject); +begin + trkVarPreviewRange.Hint := Format(TextByKey('editor-tab-color-previewrange') + ' %d', [trkVarPreviewRange.position*2]); + TriangleView.Invalidate; +end; + +procedure TEditForm.trkVarPreviewDensityChange(Sender: TObject); +begin + trkVarPreviewDensity.Hint := Format(TextByKey('editor-tab-color-previewdensity') + ' %d', [trkVarPreviewDensity.position]); + TriangleView.Invalidate; +end; + +procedure TEditForm.trkVarPreviewDepthChange(Sender: TObject); +begin + trkVarPreviewDepth.Hint := Format(TextByKey('editor-tab-color-previewdepth') + ' %d', [trkVarPreviewDepth.position]); + TriangleView.Invalidate; +end; + +procedure TEditForm.btnXpostClick(Sender: TObject); +begin + with cp.xform[SelectedTriangle] do + begin + if (p[0][0] = 1) and (p[0][1] = 0) then exit; + + MainForm.UpdateUndo; + p[0][0] := 1; + p[0][1] := 0; + end; + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); +end; + +procedure TEditForm.btnYpostClick(Sender: TObject); +begin + if (cp.xform[SelectedTriangle].p[1][0] = 0) and + (cp.xform[SelectedTriangle].p[1][1] = 1) then exit; + + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].p[1][0] := 0; + cp.xform[SelectedTriangle].p[1][1] := 1; + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); +end; + +procedure TEditForm.btnOpostClick(Sender: TObject); +begin + if (cp.xform[SelectedTriangle].p[2][0] = 0) and + (cp.xform[SelectedTriangle].p[2][1] = 0) then exit; + + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].p[2][0] := 0; + cp.xform[SelectedTriangle].p[2][1] := 0; + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); +end; + +// --Z-- copying functions is dumb... I am so lazy :-( + +procedure TEditForm.PostCoefKeypress(Sender: TObject; var Key: Char); +begin + if key <> #13 then exit; + key := #0; + PostCoefValidate(Sender); +end; + +procedure TEditForm.PostCoefValidate(Sender: TObject); +var + NewVal: double; + x, y, r, a: double; // dumb... must optimize +begin + try + NewVal := Round6(StrToFloat(TEdit(Sender).Text)); + except on Exception do + begin + ShowSelectedInfo; + exit; + end; + end; + + MainForm.UpdateUndo; // TODO - prevent unnecessary UpdateUndo... + with cp.xform[SelectedTriangle] do + begin + if btnCoefsRect.Down = true then + begin + if Sender = txtPost00 then p[0][0] := NewVal + else if Sender = txtPost01 then p[0][1] := -NewVal + else if Sender = txtPost10 then p[1][0] := -NewVal + else if Sender = txtPost11 then p[1][1] := NewVal + else if Sender = txtPost20 then p[2][0] := NewVal + else if Sender = txtPost21 then p[2][1] := -NewVal; + end + else begin + if (Sender = txtPost00) or (Sender = txtPost01) then begin + x := p[0][0]; + y := -p[0][1]; + end else + if (Sender = txtPost10) or (Sender = txtPost11) then begin + x := -p[1][0]; + y := p[1][1]; + end else + begin + x := p[2][0]; + y := -p[2][1]; + end; + r := Hypot(x, y); + a := arctan2(y, x); + + if (Sender = txtPost00) or (Sender = txtPost10) or (Sender = txtPost20) then + r := NewVal + else + a := NewVal*PI/180; + + x := r * cos(a); + y := r * sin(a); + if (Sender = txtPost00) or (Sender = txtPost01) then begin + p[0][0] := x; + p[0][1] := -y; + end else + if (Sender = txtPost10) or (Sender = txtPost11) then begin + p[1][0] := -x; + p[1][1] := y; + end else + begin + p[2][0] := x; + p[2][1] := -y; + end; + end; + end; + + cp.TrianglesFromCP(MainTriangles); + + ShowSelectedInfo; + UpdateFlame(true); + + self.LastFocus := TEdit(sender); +end; + +procedure TEditForm.btnResetCoefsClick(Sender: TObject); +begin + with cp.xform[SelectedTriangle] do + begin + if (c[0,0]<>1) or (c[0,1]<>0) or(c[1,0]<>0) or (c[1,1]<>1) or (c[2,0]<>0) or (c[2,1]<>0) then + begin + MainForm.UpdateUndo; + c[0, 0] := 1; + c[0, 1] := 0; + c[1, 0] := 0; + c[1, 1] := 1; + c[2, 0] := 0; + c[2, 1] := 0; + ShowSelectedInfo; + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); + end; + end; +end; + +procedure TEditForm.btnResetPostCoefsClick(Sender: TObject); +begin + with cp.xform[SelectedTriangle] do + begin + if (p[0,0]<>1) or (p[0,1]<>0) or(p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) then + begin + MainForm.UpdateUndo; + p[0, 0] := 1; + p[0, 1] := 0; + p[1, 0] := 0; + p[1, 1] := 1; + p[2, 0] := 0; + p[2, 1] := 0; + ShowSelectedInfo; + cp.TrianglesFromCP(MainTriangles); + UpdateFlame(True); + end; + end; +end; + +procedure TEditForm.btnPivotModeClick(Sender: TObject); +begin + if PivotMode <> pivotLocal then + // with MainTriangles[SelectedTriangle] do + begin + PivotMode := pivotLocal; +// btnPivotMode.Caption := 'Local Pivot'; +// tbPivotMode.Down := false; + end + else + // with MainTriangles[SelectedTriangle] do + begin + PivotMode := pivotWorld; +// btnPivotMode.Caption := 'World Pivot'; +// tbPivotMode.Down := true; + end; + + TriangleView.Invalidate; + ShowSelectedInfo; +end; + +procedure TEditForm.PivotValidate(Sender: TObject); +var + v: double; +begin + try + v := Round6(StrToFloat(TEdit(Sender).Text)); + except on Exception do + begin + ShowSelectedInfo; + exit; + end; + end; + + if Sender = editPivotX then + if v <> Round6(GetPivot.x) then begin + if PivotMode = pivotLocal then LocalPivot.x := v + else WorldPivot.x := v; + end + else exit + else + if v <> Round6(GetPivot.y) then begin + if PivotMode = pivotLocal then LocalPivot.y := v + else WorldPivot.y := v; + end + else exit; + + TriangleView.Invalidate; + ShowSelectedInfo; + + self.LastFocus := TEdit(sender); +end; + +procedure TEditForm.PivotKeyPress(Sender: TObject; var Key: Char); +begin + if key <> #13 then exit; + key := #0; + PivotValidate(Sender); +end; + +procedure TEditForm.btnResetPivotClick(Sender: TObject); +begin + if editMode = modePick then begin + editMode := oldMode; + oldMode := modeNone; + // hack: to generate MouseMove event + GetCursorPos(MousePos); + SetCursorPos(MousePos.x, MousePos.y); + // + end; + if PivotMode = pivotLocal then + begin + LocalPivot.x := 0; + LocalPivot.y := 0; + end + else begin + WorldPivot.x := 0; + WorldPivot.y := 0; + end; + TriangleView.Invalidate; + ShowSelectedInfo; +end; + +procedure TEditForm.btnPickPivotClick(Sender: TObject); +begin + if editMode = modePick then begin + editMode := oldMode; + oldMode := modeNone; + TriangleView.Invalidate; + // hack: to generate MouseMove event + GetCursorPos(MousePos); + SetCursorPos(MousePos.x, MousePos.y); + // + exit; + end; + if oldMode <> modeNone then exit; + oldMode := editMode; + editMode := modePick; + TriangleView.Invalidate; + btnPickPivot.Down := true; +end; + +procedure TEditForm.VEVarsDrawCell(Sender: TObject; ACol, ARow: Integer; + Rect: TRect; State: TGridDrawState); +var + supports3D, supportsDC : boolean; + col : TColor; frect : TRect; +begin + if (ARow > NRLOCVAR) and not (gdSelected in State) then + begin + if Arow > NumBuiltinVars then + col := $e0ffff + else + col := $ffe0e0; + VEVars.canvas.brush.Color := col; + VEVars.canvas.fillRect(Rect); + VEVars.canvas.TextOut(Rect.Left+2, Rect.Top+2, VEVars.Cells[ACol,ARow]); + end else col := VEVars.canvas.brush.color; + if (Acol = 0) and (Arow > 0) then begin + VEVars.Canvas.Font.Name := 'Arial'; + VEVars.Canvas.Font.Size := 5; + + VarSupports(Arow - 1, supports3D, supportsDC); + + frect.Left := Rect.Right - 12; + frect.Right := Rect.Right; + frect.Top := Rect.Top; + frect.Bottom := Rect.Bottom; + + if (supports3D or supportsDC) then begin + VEVars.canvas.brush.Color := col; + VEVars.canvas.fillRect(frect); + end; + + if (supports3D) then begin + VEVars.Canvas.Font.Color := $a00000; + VEVars.Canvas.TextOut(frect.Left, frect.Top + 2, '3D'); + end; + + if (supportsDC) then begin + VEVars.Canvas.Font.Color := $0000a0; + VEVars.Canvas.TextOut(frect.Left, frect.Top + 9, 'DC'); + end; + end; +end; + +procedure TEditForm.tbEnableFinalXformClick(Sender: TObject); +begin + MainForm.UpdateUndo; + EnableFinalXform := tbEnableFinalXform.Down; + if (cp.HasFinalXForm = false) then + begin + if (EnableFinalXform = true) then + begin + cbTransforms.Items.Add(TextByKey('editor-common-finalxformlistitem')); + SelectedTriangle := Transforms; + if (mouseOverTriangle > LastTriangle) then mouseOverTriangle := -1; + end + else begin + if cbTransforms.Items.Count = Transforms+1 then + cbTransforms.Items.Delete(Transforms); + if SelectedTriangle >= Transforms then SelectedTriangle := Transforms-1; + end; + end; + cp.finalXformEnabled := EnableFinalXform; + UpdateFlame(True); + TriangleView.Invalidate; +end; + +procedure TEditForm.DragPanelMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +var dont :boolean; +begin + if Button <> mbLeft then exit; + + // -X- why? its impossible! + assert(pnlDragMode = false); //? + if pnlDragMode = true then exit; + + dont := false; + if (Sender = pnlWeight) then + if SelectedTriangle < Transforms then + pnlDragValue := cp.xform[SelectedTriangle].density + else exit + else if (Sender = pnlSymmetry) then + pnlDragValue := cp.xform[SelectedTriangle].symmetry + else if (Sender = pnlXformColor) then + pnlDragValue := cp.xform[SelectedTriangle].color + else if (Sender = pnlOpacity) then begin + if (txtOpacity.Enabled) then begin + pnlDragValue := cp.xform[SelectedTriangle].transOpacity; + end else dont := true; + end else if (Sender = pnlDC) then begin + if (txtDC.Enabled) then begin + pnlDragValue := cp.xform[SelectedTriangle].pluginColor; + end else dont := true; + end else assert(false); + + if (not dont) then begin + pnlDragMode := true; + pnlDragPos := 0; + pnlDragOld := x; + varMM := false; + //SetCaptureControl(TControl(Sender)); + + Screen.Cursor := crHSplit; + //GetCursorPos(mousepos); // hmmm + mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); + HasChanged := false; + end; +end; + +procedure TEditForm.DragPanelMouseMove(Sender: TObject; Shift: TShiftState; + X, Y: Integer); +var + v: double; + pEdit: ^TEdit; +begin + if varMM then // hack: to skip MouseMove event + begin + varMM:=false; + end + else + if pnlDragMode and (x <> pnlDragOld) then + begin + Inc(pnlDragPos, x - pnlDragOld); + + if GetKeyState(VK_MENU) < 0 then v := 100000 + else if GetKeyState(VK_CONTROL) < 0 then v := 10000 + else if GetKeyState(VK_SHIFT) < 0 then v := 100 + else v := 1000; + + v := Round6(pnlDragValue + pnlDragPos / v); + + SetCursorPos(MousePos.x, MousePos.y); // hmmm + varMM:=true; + + if (Sender = pnlWeight) then + begin + if v <= 0.000001 then v := 0.000001 + else if v > MAX_WEIGHT then v := MAX_WEIGHT; + cp.xform[SelectedTriangle].density := v; + pEdit := @txtP; + end + else if (Sender = pnlSymmetry) then + begin + if v < -1 then v := -1 + else if v > 1 then v := 1; + cp.xform[SelectedTriangle].symmetry := v; + pEdit := @txtSymmetry; + end + else if (Sender = pnlOpacity) then + begin + if (txtOpacity.Enabled) then begin + if v < 0 then v := 0 + else if v > 1 then v := 1; + cp.xform[SelectedTriangle].transOpacity := v; + pEdit := @txtOpacity; + end else exit; + end + else if (Sender = pnlDC) then + begin + if (txtDC.Enabled) then begin + if v < 0 then v := 0 + else if v > 1 then v := 1; + cp.xform[SelectedTriangle].pluginColor := v; + pEdit := @txtDC; + end else exit; + end + else if (Sender = pnlXformColor) then + begin + if v < 0 then v := 0 + else if v > 1 then v := 1; + cp.xform[SelectedTriangle].color := v; + pnlXFormColor.Color := ColorValToColor(cp.cmap, v); + shColor.Brush.Color := pnlXformColor.Color; + updating := true; + scrlXformColor.Position := round(v*1000); + pEdit := @txtXformColor; + updating := false; + end + else begin + assert(false); + exit; + end; + pEdit^.Text := FloatToStr(v); + pEdit.Refresh; + HasChanged := True; + DrawPreview; + end; +end; + +procedure TEditForm.DragPanelMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + if Button <> mbLeft then exit; + + if pnlDragMode then + begin + //SetCaptureControl(nil); + + pnlDragMode := false; + Screen.Cursor := crDefault; + + if HasChanged then + begin + MainForm.UpdateUndo; + + UpdateFlame(true); + HasChanged := False; + end; + end; +end; + +procedure TEditForm.DragPanelDblClick(Sender: TObject); +var + pValue: ^double; + pEdit: ^TEdit; +begin + if (Sender = pnlWeight) then + begin + if SelectedTriangle >= Transforms then exit; // hmm + pValue := @cp.xform[SelectedTriangle].density; + if pValue^ = 0.5 then exit; + pValue^ := 0.5; + pEdit := @txtP; + end + else if (Sender = pnlSymmetry) then + begin + pValue := @cp.xform[SelectedTriangle].symmetry; + if SelectedTriangle = Transforms then begin + if pValue^ = 1 then exit; + pValue^ := 1; + end + else begin + if pValue^ = 0 then exit; + pValue^ := 0; + end; + pEdit := @txtSymmetry; + end + else if (Sender = pnlXformColor) then + begin + pValue := @cp.xform[SelectedTriangle].color; + if pValue^ = 0 then exit; + pValue^ := 0; + pEdit := @txtXformColor; + end + else if (Sender = pnlOpacity) then + begin + if SelectedTriangle >= Transforms then exit; // hmm + pValue := @cp.xform[SelectedTriangle].transOpacity; + if pValue^ = 1.0 then begin + pValue^ := 0.0; + end else begin + pValue^ := 1.0; + end; + pEdit := @txtOpacity; + end + else if (Sender = pnlDC) then + begin + if SelectedTriangle >= Transforms then exit; // hmm + pValue := @cp.xform[SelectedTriangle].pluginColor; + if pValue^ = 1.0 then begin + pValue^ := 0.0; + end else begin + pValue^ := 1.0; + end; + pEdit := @txtDC; + end + else begin + assert(false); + exit; + end; + + MainForm.UpdateUndo; + pEdit^.Text := FloatToStr(pValue^); + UpdateFlame(true); +end; + +procedure TEditForm.mnuResetTrgRotationClick(Sender: TObject); +var + dx, dy: double; + ax, ay, da: integer; + nx0, ny0, nx2, ny2: double; +begin + with MainTriangles[SelectedTriangle] do + begin +// xx := x[0] - x[1]; +// xy := y[0] - y[1]; +// yx := x[2] - x[1]; +// yy := y[2] - y[1]; + ax := round( arctan2(xy, xx) / (pi/2) ); + ay := round( arctan2(yy, yx) / (pi/2) ); + dx := Hypot(xx, xy); + dy := Hypot(yx, yy); + if xx*yy - yx*xy >= 0 then da := 1 else da := -1; + if ax = ay then ay := ay + da + else if abs(ax-ay) = 2 then ay := ay - da; + + nx0 := x[1] + dx*cos(ax*pi/2); + ny0 := y[1] + dx*sin(ax*pi/2); + nx2 := x[1] + dy*cos(ay*pi/2); + ny2 := y[1] + dy*sin(ay*pi/2); + if (x[0] = nx0) and (y[0] = ny0) and (x[2] = nx2) and (y[2] = ny2) then exit; + MainForm.UpdateUndo; + x[0] := nx0; + y[0] := ny0; + x[2] := nx2; + y[2] := ny2; + UpdateFlame(True); + end; +end; + +procedure TEditForm.mnuResetTrgScaleClick(Sender: TObject); +var + dx, dy: double; + nx0, ny0, nx2, ny2: double; +begin + with MainTriangles[SelectedTriangle] do + begin +// xx := x[0] - x[1]; +// xy := y[0] - y[1]; +// yx := x[2] - x[1]; +// yy := y[2] - y[1]; + dx := Hypot(xx, xy); + dy := Hypot(yx, yy); + if dx <> 0 then begin + nx0 := x[1] + (x[0] - x[1])/dx; + ny0 := y[1] + (y[0] - y[1])/dx; + end + else begin + nx0 := x[1] + 1; + ny0 := y[1]; + end; + if dx <> 0 then begin + nx2 := x[1] + (x[2] - x[1])/dy; + ny2 := y[1] + (y[2] - y[1])/dy; + end + else begin + nx2 := x[1]; + ny2 := y[1] + 1; + end; + if (x[0] = nx0) and (y[0] = ny0) and (x[2] = nx2) and (y[2] = ny2) then exit; + MainForm.UpdateUndo; + x[0] := nx0; + y[0] := ny0; + x[2] := nx2; + y[2] := ny2; + UpdateFlame(True); + end; +end; + +procedure TEditForm.ResetAxisRotation(n: integer); +var + dx, dy, d: double; + a: integer; + nx, ny: double; +begin + with MainTriangles[SelectedTriangle] do + begin + if n = 1 then + begin + d := Hypot(x[1], y[1]); + if d = 0 then exit; + a := round( arctan2(y[1], x[1]) / (pi/2) ); + nx := d*cos(a*pi/2); + ny := d*sin(a*pi/2); + if (x[1] = nx) and (y[1] = ny) then exit; + MainForm.UpdateUndo; + x[1] := nx; + y[1] := ny; + x[0] := x[1] + xx; + y[0] := y[1] + xy; + x[2] := x[1] + yx; + y[2] := y[1] + yy; + UpdateFlame(True); + end + else begin + dx := x[n] - x[1]; + dy := y[n] - y[1]; + a := round( arctan2(dy, dx) / (pi/2) ); + d := Hypot(dx, dy); + nx := x[1] + d*cos(a*pi/2); + ny := y[1] + d*sin(a*pi/2); + if (x[n] = nx) and (y[n] = ny) then exit; + MainForm.UpdateUndo; + x[n] := nx; + y[n] := ny; + UpdateFlame(True); + end; + end; +end; + +procedure TEditForm.ResetAxisScale(n: integer); +var + dx, dy, d: double; + nx, ny: double; +begin + with MainTriangles[SelectedTriangle] do + begin + if n = 1 then + begin + d := Hypot(x[1], y[1]); + if d = 0 then exit; + nx := x[1]/d; + ny := y[1]/d; + if (x[1] = nx) and (y[1] = ny) then exit; + MainForm.UpdateUndo; + x[1] := nx; + y[1] := ny; + x[0] := x[1] + xx; + y[0] := y[1] + xy; + x[2] := x[1] + yx; + y[2] := y[1] + yy; + UpdateFlame(True); + end + else begin + dx := x[n] - x[1]; + dy := y[n] - y[1]; + d := Hypot(dx, dy); + if d <> 0 then begin + nx := x[1] + dx / d; + ny := y[1] + dy / d; + end + else begin + nx := x[1] + ifthen(n=0, 1, 0); + ny := y[1] + ifthen(n=2, 1, 0); + end; + if (x[n] = nx) and (y[n] = ny) then exit; + MainForm.UpdateUndo; + x[n] := nx; + y[n] := ny; + UpdateFlame(True); + end; + end; +end; + +procedure TEditForm.tbPostXswapClick(Sender: TObject); +begin + cp.GetFromTriangles(MainTriangles, cp.NumXForms); + with cp.xform[SelectedTriangle] do begin +{ if sender = chkPostXswap then begin + postXswap := chkPostXswap.Checked; + tbPostXswap.Down := postXswap; + tb2PostXswap.Down := postXswap; + end + else begin + chkPostXswap.Checked := not postXswap; + exit; + end; +} + if (sender = tbPostXswap) then tb2PostXswap.down := tbPostXswap.Down; + if (sender = tb2PostXswap) then tbPostXswap.Down := tb2PostXSwap.Down; + + postXswap := TToolButton(sender).Down; + ShowSelectedInfo; + end; + cp.TrianglesFromCP(MainTriangles); + TriangleView.Refresh; +end; + +procedure TEditForm.btnCopyTriangleClick(Sender: TObject); +begin + MemTriangle := MainTriangles[SelectedTriangle]; +end; + +procedure TEditForm.btnPasteTriangleClick(Sender: TObject); +begin + if (MainTriangles[SelectedTriangle].x[0] <> MemTriangle.x[0]) or + (MainTriangles[SelectedTriangle].x[1] <> MemTriangle.x[1]) or + (MainTriangles[SelectedTriangle].x[2] <> MemTriangle.x[2]) or + (MainTriangles[SelectedTriangle].y[0] <> MemTriangle.y[0]) or + (MainTriangles[SelectedTriangle].y[1] <> MemTriangle.y[1]) or + (MainTriangles[SelectedTriangle].y[2] <> MemTriangle.y[2]) then + begin + MainForm.UpdateUndo; + MainTriangles[SelectedTriangle] := MemTriangle; + UpdateFlame(True); + end; +end; + +procedure TEditForm.chkAutoZscaleClick(Sender: TObject); +begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].autoZscale := chkAutoZscale.Checked; + UpdateFlame(True); +end; + +// --------------------------------------------------------------- Chaos Editor + +procedure TEditForm.ValidateChaos; +var + i: integer; + NewVal, OldVal: double; +begin + i := vleChaos.Row - 1; + + if mnuChaosViewTo.Checked then + OldVal := Round6(cp.xform[SelectedTriangle].modWeights[i]) + else + OldVal := Round6(cp.xform[i].modWeights[SelectedTriangle]); + + try + NewVal := Round6(StrToFloat(vleChaos.Cells[1, i+1])); + except + vleChaos.Cells[1, i+1] := Format('%.6g', [OldVal]); + exit; + end; + if (NewVal <> OldVal) then + begin + MainForm.UpdateUndo; + + if mnuChaosViewTo.Checked then + cp.xform[SelectedTriangle].modWeights[i] := NewVal + else + cp.xform[i].modWeights[SelectedTriangle] := NewVal; + + vleChaos.Cells[1, i+1] := Format('%.6g', [NewVal]); + ShowSelectedInfo; + UpdateFlame(True); + end; +end; + +procedure TEditForm.vleChaosExit(Sender: TObject); +begin + ValidateChaos; +end; + +procedure TEditForm.vleChaosKeyPress(Sender: TObject; var Key: Char); +begin + if key = #13 then + begin + key := #0; + ValidateChaos; + end; +end; + +procedure TEditForm.vleChaosValidate(Sender: TObject; ACol, ARow: Integer; + const KeyName, KeyValue: String); +begin + ValidateChaos; +end; + +procedure TEditForm.VleChaosDrawCell(Sender: TObject; ACol, ARow: Integer; + Rect: TRect; State: TGridDrawState); +var + h,ax,ay,bx,by: integer; + trgColor: TColor; +begin + if (ACol > 0) or (ARow = 0) then exit; + + trgColor := GetTriangleColor(ARow - 1); + with vleChaos.Canvas do begin + h := Rect.Bottom - Rect.Top - 2; +// TextOut(Rect.Left+h+2, Rect.Top+1, vleChaos.Cells[ACol, ARow]); + + ax:=Rect.Right-3; + ay:=Rect.Top+2; + bx:=Rect.Right-h; + by:=Rect.Bottom-3; + + pen.Color := clBlack; + Polyline([Point(ax+1, ay-2), Point(ax+1, by+1), Point(bx-2, by+1), Point(ax+1, ay-2)]); + + pen.Color := trgColor; + brush.Color := pen.Color shr 1 and $7f7f7f; + Polygon([Point(ax, ay), Point(ax, by), Point(bx, by)]); + end; +end; + +procedure TEditForm.mnuChaosViewToClick(Sender: TObject); +var + i: integer; +begin + mnuChaosViewTo.Checked := true; + for i := 1 to vleChaos.RowCount-1 do begin + vleChaos.Cells[0, i] := Format(TextByKey('editor-common-toprefix'), [i]); + vleChaos.Cells[1, i] := FloatToStr(cp.xform[SelectedTriangle].modWeights[i-1]); + end; + //ShowSelectedInfo; +end; + +procedure TEditForm.mnuChaosViewFromClick(Sender: TObject); +var + i: integer; +begin + mnuChaosViewFrom.Checked := true; + for i := 1 to vleChaos.RowCount-1 do begin + vleChaos.Cells[0, i] := Format(TextByKey('editor-common-fromprefix'), [i]); + vleChaos.Cells[1, i] := FloatToStr(cp.xform[i-1].modWeights[SelectedTriangle]); + end; + //ShowSelectedInfo; +end; + +procedure TEditForm.chkPlotModeClick(Sender: TObject); +var + newMode: boolean; +begin + (*if (SelectedTriangle < Transforms) then + begin + newMode := chkXformInvisible.Checked; + if cp.xform[SelectedTriangle].noPlot <> newMode then begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].noPlot := newMode; + UpdateFlame(true); + end; + end; *) +end; + +procedure TEditForm.mnuChaosClearAllClick(Sender: TObject); +var + i: integer; + noEdit: boolean; +begin + noEdit := true; + for i := 1 to cp.NumXForms do + if mnuChaosViewTo.Checked then begin + if cp.xform[SelectedTriangle].modWeights[i-1] <> 0 then begin + noEdit := false; + break; + end; + end + else begin + if cp.xform[i-1].modWeights[SelectedTriangle] <> 0 then begin + noEdit := false; + break; + end; + end; + if noEdit then exit; + + Mainform.UpdateUndo; + for i := 1 to cp.NumXForms do + if mnuChaosViewTo.Checked then + cp.xform[SelectedTriangle].modWeights[i-1] := 0 + else + cp.xform[i-1].modWeights[SelectedTriangle] := 0; + UpdateFlame(true); +end; + +procedure TEditForm.mnuChaosSetAllClick(Sender: TObject); +var + i: integer; + noEdit: boolean; +begin + noEdit := true; + for i := 1 to cp.NumXForms do + if mnuChaosViewTo.Checked then begin + if cp.xform[SelectedTriangle].modWeights[i-1] <> 1 then begin + noEdit := false; + break; + end; + end + else begin + if cp.xform[i-1].modWeights[SelectedTriangle] <> 1 then begin + noEdit := false; + break; + end; + end; + if noEdit then exit; + + Mainform.UpdateUndo; + for i := 1 to cp.NumXForms do + if mnuChaosViewTo.Checked then + cp.xform[SelectedTriangle].modWeights[i-1] := 1 + else + cp.xform[i-1].modWeights[SelectedTriangle] := 1; + UpdateFlame(true); +end; + +procedure TEditForm.mnuLinkPostxformClick(Sender: TObject); +var + i: integer; +begin + if (Transforms < NXFORMS) and (SelectedTriangle <> Transforms) then + begin + MainForm.UpdateUndo; + MainTriangles[Transforms+1] := MainTriangles[Transforms]; + cp.xform[Transforms+1].Assign(cp.xform[Transforms]); + + MainTriangles[Transforms] := MainTriangles[-1]; + cp.xform[Transforms].Clear; + cp.xform[Transforms].density := 0.5; + cp.xform[Transforms].SetVariation(0, 1); + + for i := 0 to Transforms-1 do begin + cp.xform[Transforms].modWeights[i] := cp.xform[SelectedTriangle].modWeights[i]; + cp.xform[SelectedTriangle].modWeights[i] := 0; + end; + + for i := 0 to Transforms do + cp.xform[i].modWeights[Transforms] := 0; + cp.xform[SelectedTriangle].modWeights[Transforms] := 1; + + cp.xform[Transforms].symmetry := 1; + cp.xform[Transforms].transOpacity := cp.xform[SelectedTriangle].transOpacity; + cp.xform[SelectedTriangle].transOpacity := 0; + + SelectedTriangle := Transforms; + + Inc(Transforms); + UpdateXformsList; + UpdateFlame(True); + end; +end; + +procedure TEditForm.chkXformSoloClick(Sender: TObject); +begin + if chkXformSolo.Checked <> (cp.soloXform >=0) then begin + if chkXformSolo.Checked then begin + if (SelectedTriangle < Transforms) then begin + cp.soloXform := SelectedTriangle; + UpdateFlame(true); + end; + end + else begin + cp.soloXform := -1; + UpdateFlame(true); + end; + end; +end; + +procedure TEditForm.mnuChaosRebuildClick(Sender: TObject); +begin + RebuildXaosLinks := not RebuildXaosLinks; + mnuChaosRebuild.Checked := RebuildXaosLinks; +end; + +procedure TEditForm.chkCollapseVariationsClick(Sender: TObject); +var + i:integer; + s:string; +begin + //txtSearchBox.Text := ''; + s:=Trim(txtSearchBox.Text); + for i:= 1 to VEVars.RowCount - 1 do begin + if (Length(s) = 0) then begin + if ((Assigned(cp)) and (VEVars.Cells[1,i]='0')) then + if chkCollapseVariations.Checked then VEVars.RowHeights[i] := -1 + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight; + end else begin + if (Length(s) > Length(VEVars.Cells[0, i])) then + VEVars.RowHeights[i] := -1 + else if Pos(s, VEVars.Cells[0, i]) > 0 then begin + if ((Assigned(cp)) and (VEVars.Cells[1,i]='0')) then + if chkCollapseVariations.Checked then VEVars.RowHeights[i] := -1 + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight; + end else VEVars.RowHeights[i] := -1; + end; + end; +end; + +procedure TEditForm.chkCollapseVariablesClick(Sender: TObject); +var + i, vari: integer; +begin + for i := 1 to vleVariables.RowCount - 1 do + begin + if chkCollapseVariables.Checked then + vleVariables.RowHeights[i] := vleVariables.DefaultRowHeight + else + begin + vari := GetVariationIndexFromVariableNameIndex(i-1); + if ( (vari = -1) or + ((Assigned(cp)) and (cp.xform[SelectedTriangle].GetVariation(vari) = 0)) ) then + vleVariables.RowHeights[i] := -1 + else + vleVariables.RowHeights[i] := vleVariables.DefaultRowHeight; + end; + end; +end; +procedure TEditForm.shColorMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + DragPanelMouseDown(pnlXFormColor, Button, Shift, X, Y); +end; + +procedure TEditForm.shColorMouseMove(Sender: TObject; Shift: TShiftState; + X, Y: Integer); +begin + DragPanelMouseMove(pnlXFormColor, Shift, X, Y); +end; + +procedure TEditForm.shColorMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + DragPanelMouseUp(pnlXFormColor, Button, Shift, X, Y); +end; + +procedure TEditForm.bClearClick(Sender: TObject); +var + i:integer; + changed:boolean; +begin + changed := false; + for i := 0 to VEVars.RowCount - 1 do begin + if (cp.xform[SelectedTriangle].GetVariation(i) <> 0) then changed := true; + cp.xform[SelectedTriangle].SetVariation(i, 0); + end; + + if changed then MainForm.UpdateUndo; + UpdateFlame(true); +end; + +procedure TEditForm.ColorBarMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +var + dx:Extended; +begin + dx := Round(100 * X / ColorBar.Width) / 100; + txtXFormColor.Text := FloatToStr(dx); + txtXFormColorExit(nil); +end; + +procedure TEditForm.btnLoadVVARClick(Sender: TObject); +var + fn:string; + i:integer; +begin + if OpenSaveFileDialog(EditForm, '.dll', 'Dynamic Link Libraries (*.dll)|*.dll', '.\Plugins', 'LoadPlugin...', fn, true, false, false, true) then begin + //if (fn <> '') then begin + {LoadPlugin(fn); + + VEVars.Strings.Clear; + vleVariables.Strings.Clear; + + for i:= 0 to NRVAR - 1 do begin + VEVars.InsertRow(Varnames(i), '0', True); + end; + for i:= 0 to GetNrVariableNames - 1 do begin + vleVariables.InsertRow(GetVariableNameAt(i), '0', True); + end; + + for i := 0 to Transforms - 1 do begin + cp.xform[i].InvokeAddRegVariations; + end; + end; } + end; +end; + +procedure TEditForm.txtNameKeyPress(Sender: TObject; var Key: Char); +begin + if SelectedTriangle >= Transforms then key := #0; + if key = #13 then + begin + { Stop the beep } + Key := #0; + txtNameExit(sender); + end; + +end; + +procedure TEditForm.txtNameExit(Sender: TObject); +var + n:integer; + oldval,newval:string; +begin + + oldval := cp.xform[SelectedTriangle].TransformName; + newval := txtName.Text; + + if (oldval <> newval) then begin + MainForm.UpdateUndo; + cp.xform[SelectedTriangle].TransformName := newval; + n := SelectedTriangle + 1; + if (cp.xform[SelectedTriangle].TransformName <> '') then + cbTransforms.Items[SelectedTriangle] := IntToStr(n) + ' - ' + cp.xform[SelectedTriangle].TransformName + else + cbTransforms.Items[SelectedTriangle] := IntToStr(n); + + //workaround.. + if (SelectedTriangle >= Transforms) then cbTransforms.Items[SelectedTriangle] := TextByKey('editor-common-finalxformlistitem'); + cbTransforms.ItemIndex := SelectedTriangle; + UpdateFlame(True); + end; +end; + +procedure TEditForm.TrianglePanelResize(Sender: TObject); +begin + GroupBox5.Left := TrianglePanel.CLientWidth div 2 - GroupBox5.Width div 2; + GroupBox6.Left := TrianglePanel.CLientWidth div 2 - GroupBox6.Width div 2; + GroupBox3.Left := TrianglePanel.CLientWidth div 2 - GroupBox3.Width div 2; + ToolBar1.Left := TrianglePanel.CLientWidth div 2 - Toolbar1.Width div 2; +end; + +procedure TEditForm.ControlPanelResize(Sender: TObject); +begin + cbTransforms.ItemHeight := Panel1.Height - 6; + cbTransforms.Height := Panel1.Height; + PageControl.Top := Panel1.Height + Panel2.Height + pnlWeight.Height + 12; + PageControl.Height := ControlPanel.Height - PageControl.Top; +end; + +procedure TEditForm.ScrollBox2Resize(Sender: TObject); +begin + // do +end; + +procedure TEditForm.ScrollBox1Resize(Sender: TObject); +begin + GroupBox7.Left := ScrollBox1.ClientWidth div 2 - GroupBox7.Width div 2; + GroupBox8.Left := ScrollBox1.ClientWidth div 2 - GroupBox8.Width div 2; + GroupBox9.Left := ScrollBox1.ClientWidth div 2 - GroupBox9.Width div 2; +end; + +procedure TEditForm.FormActivate(Sender: TObject); +begin + if EnableEditorPreview and PrevPnl.Visible then begin + Splitter2.Height := 1; + Splitter2.Visible := false; + PrevPnl.Height := 1; + PrevPnl.Visible := false; + end else if (not EnableEditorPreview) and (not PrevPnl.Visible) then begin + Splitter2.Height := 8; + Splitter2.Visible := true; + PrevPnl.Height := 177; + PrevPnl.Visible := true; + end; +end; + +procedure TEditForm.txtSearchBoxChange(Sender: TObject); +var + i:integer; + s:string; +begin + s:=Trim(txtSearchBox.Text); + for i:= 1 to VEVars.RowCount - 1 do begin + if (Length(s) = 0) then begin + if ((Assigned(cp)) and (VEVars.Cells[1,i]='0')) then + if chkCollapseVariations.Checked then VEVars.RowHeights[i] := -1 + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight; + end else begin + if (Length(s) > Length(VEVars.Cells[0, i])) then + VEVars.RowHeights[i] := -1 + else if Pos(s, VEVars.Cells[0, i]) > 0 then begin + if ((Assigned(cp)) and (VEVars.Cells[1,i]='0')) then + if chkCollapseVariations.Checked then VEVars.RowHeights[i] := -1 + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight + else VEVars.RowHeights[i] := VEVars.DefaultRowHeight; + end else VEVars.RowHeights[i] := -1; + end; + end; +end; + +procedure TEditForm.txtSearchBoxKeyPress(Sender: TObject; var Key: Char); +begin + txtSearchBoxChange(Sender); +end; + +procedure TEditForm.btnResetSearchClick(Sender: TObject); +begin + txtSearchBox.Text := ''; +end; + +procedure TEditForm.KeyInput(str:string); +var + Inp: TInput; + I: Integer; +begin + for I := 1 to Length(Str) do + begin + Inp.Itype := INPUT_KEYBOARD; + Inp.ki.wVk := Ord(UpCase(Str[i])); + Inp.ki.dwFlags := 0; + SendInput(1, Inp, SizeOf(Inp)); + Inp.Itype := INPUT_KEYBOARD; + Inp.ki.wVk := Ord(UpCase(Str[i])); + Inp.ki.dwFlags := KEYEVENTF_KEYUP; + SendInput(1, Inp, SizeOf(Inp)); + Application.ProcessMessages; + Sleep(1); + end; +end; + +procedure TEditForm.ToolButton12Click(Sender: TObject); +begin + KeyInput('3.141592'); +end; + +end. + diff --git a/Forms/FormExport.dfm b/Forms/FormExport.dfm new file mode 100644 index 0000000..f142a20 --- /dev/null +++ b/Forms/FormExport.dfm @@ -0,0 +1,553 @@ +object ExportDialog: TExportDialog + Left = 313 + Top = 276 + BorderStyle = bsDialog + Caption = 'Export Flame' + ClientHeight = 392 + ClientWidth = 496 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + OnShow = FormShow + DesignSize = ( + 496 + 392) + PixelsPerInch = 96 + TextHeight = 13 + object btnOK: TButton + Left = 398 + Top = 182 + Width = 89 + Height = 25 + Anchors = [akTop, akRight] + Caption = '&OK' + Default = True + ModalResult = 1 + TabOrder = 0 + OnClick = btnOKClick + end + object btnCancel: TButton + Left = 398 + Top = 210 + Width = 89 + Height = 25 + Anchors = [akTop, akRight] + Caption = 'Cancel' + ModalResult = 2 + TabOrder = 1 + end + object GroupBox1: TGroupBox + Left = 8 + Top = 5 + Width = 481 + Height = 57 + Anchors = [akLeft, akTop, akRight] + Caption = ' Destination ' + TabOrder = 2 + DesignSize = ( + 481 + 57) + object btnBrowse: TSpeedButton + Left = 448 + Top = 19 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnBrowseClick + end + object Label10: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'File name' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object txtFilename: TEdit + Left = 112 + Top = 20 + Width = 337 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + end + end + object GroupBox3: TGroupBox + Left = 256 + Top = 66 + Width = 233 + Height = 105 + Anchors = [akTop, akRight] + Caption = ' Quality ' + TabOrder = 3 + DesignSize = ( + 233 + 105) + object udOversample: TUpDown + Left = 212 + Top = 68 + Width = 12 + Height = 21 + Anchors = [akTop, akRight] + Associate = txtOversample + Min = 1 + Max = 4 + Position = 2 + TabOrder = 3 + end + object Label4: TPanel + Left = 8 + Top = 20 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Density' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object txtDensity: TEdit + Left = 120 + Top = 20 + Width = 105 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + OnChange = txtDensityChange + end + object Label5: TPanel + Left = 8 + Top = 44 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Filter radius' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object txtFilterRadius: TEdit + Left = 120 + Top = 44 + Width = 105 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + OnChange = txtFilterRadiusChange + end + object Label3: TPanel + Left = 8 + Top = 68 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Oversample' + ParentShowHint = False + ShowHint = True + TabOrder = 6 + end + object txtOversample: TEdit + Left = 120 + Top = 68 + Width = 92 + Height = 21 + Anchors = [akLeft, akTop, akRight] + ReadOnly = True + TabOrder = 2 + Text = '2' + OnChange = txtOversampleChange + end + end + object GroupBox2: TGroupBox + Left = 8 + Top = 66 + Width = 241 + Height = 105 + Anchors = [akLeft, akTop, akRight] + Caption = ' Size ' + TabOrder = 4 + DesignSize = ( + 241 + 105) + object Label13: TLabel + Left = 184 + Top = 36 + Width = 26 + Height = 13 + Anchors = [akLeft, akTop, akRight] + Caption = 'pixels' + Visible = False + end + object Label16: TLabel + Left = 168 + Top = 22 + Width = 15 + Height = 36 + Anchors = [akLeft, akTop, akRight] + Caption = '}' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -32 + Font.Name = 'Times New Roman' + Font.Style = [] + ParentFont = False + Visible = False + end + object chkMaintain: TCheckBox + Left = 8 + Top = 76 + Width = 225 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Maintain aspect ratio' + Checked = True + State = cbChecked + TabOrder = 0 + OnClick = chkMaintainClick + end + object Label1: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Width' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object Label2: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Height' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object cbHeight: TComboBox + Left = 112 + Top = 44 + Width = 121 + Height = 21 + Anchors = [akLeft, akTop, akRight] + ItemHeight = 13 + TabOrder = 2 + OnChange = txtHeightChange + Items.Strings = ( + '200' + '240' + '480' + '600' + '768' + '1024' + '1200' + '2048' + '2400') + end + object cbWidth: TComboBox + Left = 112 + Top = 20 + Width = 121 + Height = 21 + Anchors = [akLeft, akTop, akRight] + ItemHeight = 13 + TabOrder = 1 + OnChange = txtWidthChange + Items.Strings = ( + '320' + '640' + '800' + '1024' + '1280' + '1600' + '1920' + '2048' + '2560' + '3200') + end + end + object GroupBox4: TGroupBox + Left = 8 + Top = 176 + Width = 377 + Height = 113 + Anchors = [akLeft, akTop, akRight] + Caption = ' Parameters ' + TabOrder = 5 + DesignSize = ( + 377 + 113) + object udStrips: TUpDown + Left = 172 + Top = 52 + Width = 12 + Height = 21 + Associate = txtStrips + Min = 1 + Max = 512 + Position = 1 + TabOrder = 2 + end + object Label7: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Buffer depth' + ParentShowHint = False + ShowHint = True + TabOrder = 7 + end + object Label8: TPanel + Left = 8 + Top = 52 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Strips' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + end + object Label9: TPanel + Left = 8 + Top = 84 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'DE Radius' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + end + object txtEstimator: TEdit + Left = 112 + Top = 84 + Width = 73 + Height = 21 + TabOrder = 3 + Text = '5' + OnChange = txtEstimatorChange + end + object txtStrips: TEdit + Left = 112 + Top = 52 + Width = 60 + Height = 21 + TabOrder = 1 + Text = '1' + OnChange = txtBatchesChange + end + object cmbDepth: TComboBox + Left = 112 + Top = 20 + Width = 73 + Height = 21 + Style = csDropDownList + ItemHeight = 13 + TabOrder = 0 + OnChange = cmbDepthChange + Items.Strings = ( + '16-bit' + '32-bit' + '32-bit float' + '64-bit') + end + object Label14: TPanel + Left = 192 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Gamma threshold' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + end + object Label12: TPanel + Left = 192 + Top = 52 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'DE Curve' + ParentShowHint = False + ShowHint = True + TabOrder = 11 + end + object Label11: TPanel + Left = 192 + Top = 84 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'DE Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 12 + end + object txtGammaTreshold: TEdit + Left = 296 + Top = 20 + Width = 73 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 6 + Text = '0.01' + OnChange = txtGammaTresholdChange + end + object txtEstimatorCurve: TEdit + Left = 296 + Top = 52 + Width = 73 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 5 + Text = '0.6' + OnChange = txtEstimatorCurveChange + end + object txtEstimatorMin: TEdit + Left = 296 + Top = 84 + Width = 73 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 4 + Text = '0' + OnChange = txtEstimatorMinChange + end + end + object chkRender: TCheckBox + Left = 400 + Top = 246 + Width = 89 + Height = 43 + Anchors = [akTop, akRight] + Caption = 'Render' + Checked = True + State = cbChecked + TabOrder = 6 + end + object Panel1: TPanel + Left = 8 + Top = 296 + Width = 481 + Height = 89 + Anchors = [akLeft, akTop, akRight, akBottom] + BevelKind = bkSoft + BevelOuter = bvNone + Color = clInfoBk + TabOrder = 7 + OnResize = Panel1Resize + DesignSize = ( + 477 + 85) + object Label6: TLabel + Left = 8 + Top = 4 + Width = 453 + Height = 24 + Alignment = taCenter + Anchors = [akLeft, akTop, akRight] + AutoSize = False + Caption = 'WARNING!' + Font.Charset = DEFAULT_CHARSET + Font.Color = clInfoText + Font.Height = -19 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + end + object Label15: TLabel + Left = 8 + Top = 25 + Width = 447 + Height = 26 + Alignment = taCenter + Anchors = [akLeft, akRight] + Caption = + 'Fractals created with this version of Apophysis are not supporte' + + 'd by the external renderer! To render 2D-only fractals, download' + + ' the latest version of FLAM3 from http://www.flam3.com' + Color = clInfoBk + Font.Charset = DEFAULT_CHARSET + Font.Color = clInfoText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentColor = False + ParentFont = False + WordWrap = True + end + end + object SaveDialog: TSaveDialog + DefaultExt = 'jpg' + Filter = + 'JPEG Image (*.jpg)|*.jpg|PPM Image (*.ppm)|*.ppm|PNG Images (*.p' + + 'ng)|*.png' + Left = 464 + Top = 264 + end +end diff --git a/Forms/FormExport.pas b/Forms/FormExport.pas new file mode 100644 index 0000000..ff8741e --- /dev/null +++ b/Forms/FormExport.pas @@ -0,0 +1,346 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit FormExport; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, Buttons, ComCtrls, ExtCtrls, Translation; + +type + TExportDialog = class(TForm) + btnOK: TButton; + btnCancel: TButton; + GroupBox1: TGroupBox; + btnBrowse: TSpeedButton; + txtFilename: TEdit; + SaveDialog: TSaveDialog; + GroupBox3: TGroupBox; + txtOversample: TEdit; + txtFilterRadius: TEdit; + txtDensity: TEdit; + udOversample: TUpDown; + GroupBox2: TGroupBox; + chkMaintain: TCheckBox; + cbWidth: TComboBox; + cbHeight: TComboBox; + GroupBox4: TGroupBox; + cmbDepth: TComboBox; + chkRender: TCheckBox; + txtStrips: TEdit; + udStrips: TUpDown; + txtEstimator: TEdit; + txtEstimatorMin: TEdit; + txtEstimatorCurve: TEdit; + txtGammaTreshold: TEdit; + Panel1: TPanel; + Label6: TLabel; + Label15: TLabel; + Label13: TLabel; + Label16: TLabel; + Label4: TPanel; + Label5: TPanel; + Label3: TPanel; + Label1: TPanel; + Label2: TPanel; + Label7: TPanel; + Label8: TPanel; + Label9: TPanel; + Label14: TPanel; + Label12: TPanel; + Label11: TPanel; + Label10: TPanel; + procedure Panel1Resize(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure btnBrowseClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnOKClick(Sender: TObject); + procedure txtWidthChange(Sender: TObject); + procedure chkMaintainClick(Sender: TObject); + procedure txtHeightChange(Sender: TObject); + procedure txtDensityChange(Sender: TObject); + procedure txtFilterRadiusChange(Sender: TObject); + procedure txtOversampleChange(Sender: TObject); + procedure txtBatchesChange(Sender: TObject); + procedure cmbDepthChange(Sender: TObject); + procedure txtEstimatorChange(Sender: TObject); + procedure txtEstimatorMinChange(Sender: TObject); + procedure txtEstimatorCurveChange(Sender: TObject); + procedure txtJittersChange(Sender: TObject); + procedure txtGammaTresholdChange(Sender: TObject); + procedure lblFlam3LinkClick(Sender: TObject); + private + FloatFormatSettings: TFormatSettings; + public + Filename: string; + ImageWidth, ImageHeight, Oversample, Batches, Strips: Integer; + Sample_Density, Filter_Radius: double; + Estimator, EstimatorMin, EstimatorCurve: double; + GammaTreshold: double; + Jitters: integer; + end; + +var + ExportDialog: TExportDialog; + Ratio: double; + +implementation +uses Global, Main, ShellAPI; + +{$R *.DFM} + +procedure TExportDialog.btnBrowseClick(Sender: TObject); +begin + SaveDialog.InitialDir := ExtractFileDir(txtFilename.text); + SaveDialog.Filename := txtFilename.Text; + case ExportFileFormat of + 0: SaveDialog.DefaultExt := 'jpg'; + 1: SaveDialog.DefaultExt := 'ppm'; + end; + SaveDialog.filterIndex := ExportFileFormat; + SaveDialog.Filter := Format('Portable Pixmap (*.ppm)|*.ppm|%s|*.jpg;*.jpeg|%s|*.png|%s|*.*', + [TextByKey('common-filter-jpeg'), TextByKey('common-filter-png'), + TextByKey('common-filter-allfiles')]); + if SaveDialog.Execute then + begin + case SaveDialog.FilterIndex of + 1: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.jpg'); + 2: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.ppm'); + 3: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.png'); + end; + ExportFileFormat := SaveDialog.FilterIndex; + renderPath := ExtractFilePath(SaveDialog.Filename); + end; + +end; + +procedure TExportDialog.FormShow(Sender: TObject); +begin + txtFilename.Text := Filename; + cbWidth.Text := IntToStr(MainCp.Width); + cbHeight.Text := IntToStr(MainCp.Height); + ImageWidth := MainCp.Width; + ImageHeight := MainCp.Height; + txtDensity.text := FloatToStr(Sample_density); +// if cmbDepth.ItemIndex <> 2 then +// txtBatches.text := IntToStr(Round(Sample_density / 4)); + txtFilterRadius.text := FloatToStr(Filter_Radius); + txtOversample.text := IntToSTr(Oversample); + udOversample.Position := Oversample; + Ratio := ImageWidth / ImageHeight; + Batches := 1; + Estimator := 9.0; + EstimatorMin := 0.0; + EstimatorCurve := 0.4; + Jitters := 1; + GammaTreshold := MainCP.gamma_threshold; //0.01; + GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FloatFormatSettings); + txtEstimator.Text := FloatToStr(Estimator, FloatFormatSettings); + txtEstimatorMin.Text := FloatToStr(EstimatorMin, FloatFormatSettings); + txtEstimatorCurve.Text := FloatToStr(EstimatorCurve, FloatFormatSettings); +// txtJitters.Text := IntToStr(Jitters); + txtGammaTreshold.Text := FloatToStr(GammaTreshold, FloatFormatSettings); +end; + +procedure TExportDialog.btnOKClick(Sender: TObject); +begin + Filename := txtFilename.text; + ImageWidth := StrToInt(cbWidth.Text); + ImageHeight := StrToInt(cbHeight.Text); +end; + +procedure TExportDialog.txtWidthChange(Sender: TObject); +begin + try + ImageWidth := StrToInt(cbWidth.Text); + if chkMaintain.checked and cbWidth.Focused then + begin + ImageHeight := Round(ImageWidth / ratio); + cbHeight.Text := IntToStr(ImageHeight) + end; + except + end; +end; + +procedure TExportDialog.chkMaintainClick(Sender: TObject); +begin + Ratio := ImageWidth / ImageHeight; +end; + +procedure TExportDialog.txtHeightChange(Sender: TObject); +begin + try + ImageHeight := StrToInt(cbHeight.Text); + if chkMaintain.checked and cbHeight.Focused then + begin + ImageWidth := Round(ImageHeight * ratio); + cbWidth.Text := IntToStr(ImageWidth) + end; + except + end; +end; + +procedure TExportDialog.txtDensityChange(Sender: TObject); +begin + try + Sample_Density := StrToFloat(txtDensity.Text); +// if cmbDepth.ItemIndex <> 2 then +// txtBatches.text := IntToStr(Round(Sample_density / 4)); + except + end; +end; + +procedure TExportDialog.txtFilterRadiusChange(Sender: TObject); +begin + try + Filter_Radius := StrToFloat(txtFilterRadius.Text); + except + end; +end; + +procedure TExportDialog.txtOversampleChange(Sender: TObject); +begin + if StrToInt(txtOversample.Text) > udOversample.Max then + txtOversample.Text := IntToStr(udOversample.Max); + if StrToInt(txtOversample.Text) < udOversample.Min then + txtOversample.Text := IntToStr(udOversample.Min); + try + Oversample := StrToInt(txtOversample.Text); + except + end; +end; + +procedure TExportDialog.txtBatchesChange(Sender: TObject); +begin +{ + if StrToInt(txtBatches.Text) > udBatches.Max then + txtBatches.Text := IntToStr(udBatches.Max); + if StrToInt(txtBatches.Text) < udBatches.Min then + txtBatches.Text := IntToStr(udBatches.Min); + try + Batches := StrToInt(txtBatches.Text); + except + end; +} +end; + +procedure TExportDialog.cmbDepthChange(Sender: TObject); +begin +{ + if cmbDepth.ItemIndex <> 2 then + txtBatches.text := IntToStr(Round(Sample_density / 4)) + else + txtBatches.text := IntToStr(1); +} +end; + +procedure TExportDialog.txtEstimatorChange(Sender: TObject); +begin + Estimator := 0; + try + Estimator := StrToFloat(txtEstimator.Text, FloatFormatSettings); + except + end; +end; + +procedure TExportDialog.txtEstimatorMinChange(Sender: TObject); +begin + EstimatorMin := 0; + try + EstimatorMin := StrToFloat(txtEstimatorMin.Text, FloatFormatSettings); + except + end; +end; + +procedure TExportDialog.txtEstimatorCurveChange(Sender: TObject); +begin + EstimatorCurve := 0; + try + EstimatorCurve := StrToFloat(txtEstimatorCurve.Text, FloatFormatSettings); + except + end; +end; + +procedure TExportDialog.txtJittersChange(Sender: TObject); +begin +{ + Jitters := 0; + try + Jitters := StrToInt(txtJitters.Text); + except + end; +} +end; + +procedure TExportDialog.txtGammaTresholdChange(Sender: TObject); +begin + //GammaTreshold := 0.01; + try + GammaTreshold := StrToFloat(txtGammaTreshold.Text, FloatFormatSettings); + except + end; +end; + +procedure TExportDialog.lblFlam3LinkClick(Sender: TObject); +begin + ShellExecute(ValidParentForm(Self).Handle, 'open', PChar(TLabel(Sender).Hint), + nil, nil, SW_SHOWNORMAL); +end; + +procedure TExportDialog.FormCreate(Sender: TObject); +begin + btnOK.Caption := TextByKey('common-ok'); + btnCancel.Caption := TextByKey('common-cancel'); + Label1.Caption := TextByKey('common-width'); + Label2.Caption := TextByKey('common-height'); + GroupBox2.Caption := TextByKey('common-size'); + Label13.Caption := TextByKey('common-pixels'); + chkMaintain.Caption := TextByKey('common-keepaspect'); + GroupBox1.Caption := TextByKey('common-destination'); + Label10.Caption := TextByKey('common-filename'); + btnBrowse.Hint := TextByKey('common-browse'); + GroupBox3.Caption := TextByKey('common-quality'); + Label5.Caption := TextByKey('common-filterradius'); + Label4.Caption := TextByKey('common-density'); + Label3.Caption := TextByKey('common-oversample'); + Label14.Caption := TextByKey('common-gammathreshold'); + self.Caption := TextByKey('main-menu-file-exportflame'); + GroupBox4.Caption := TextByKey('export-paramoptions-title'); + Label7.Caption := TextByKey('export-paramoptions-bufferdepth'); + Label8.Caption := TextByKey('export-paramoptions-strips'); + Label9.Caption := TextByKey('export-paramoptions-estimatorradius'); + Label12.Caption := TextByKey('export-paramoptions-estimatorcurve'); + Label11.Caption := TextByKey('export-paramoptions-estimatormin'); + chkRender.Caption := TextByKey('export-paramoptions-dorender'); + Label6.Caption := TextByKey('export-paramoptions-warningtitle'); + Label15.Caption := TextByKey('export-paramoptions-warningtext'); +end; + +procedure TExportDialog.Panel1Resize(Sender: TObject); +begin + Label15.Top := (Panel1.Height - 30) div 2 - Label15.Height div 2 + 25; +end; + +end. + diff --git a/Forms/FormExportC.dfm b/Forms/FormExportC.dfm new file mode 100644 index 0000000..6514d3a --- /dev/null +++ b/Forms/FormExportC.dfm @@ -0,0 +1,553 @@ +object ExportCDialog: TExportCDialog + Left = 313 + Top = 276 + BorderStyle = bsDialog + Caption = 'Export Flame' + ClientHeight = 134 + ClientWidth = 496 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + OnShow = FormShow + DesignSize = ( + 496 + 134) + PixelsPerInch = 96 + TextHeight = 13 + object btnOK: TButton + Left = 254 + Top = 98 + Width = 115 + Height = 25 + Anchors = [akTop, akRight] + Caption = '&OK' + Default = True + ModalResult = 1 + TabOrder = 0 + OnClick = btnOKClick + end + object btnCancel: TButton + Left = 376 + Top = 98 + Width = 111 + Height = 25 + Anchors = [akTop, akRight] + Caption = 'Cancel' + ModalResult = 2 + TabOrder = 1 + end + object GroupBox1: TGroupBox + Left = 8 + Top = 237 + Width = 481 + Height = 57 + Anchors = [akLeft, akTop, akRight] + Caption = ' Destination ' + TabOrder = 2 + Visible = False + DesignSize = ( + 481 + 57) + object btnBrowse: TSpeedButton + Left = 448 + Top = 19 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnBrowseClick + end + object Label10: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'File name' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object txtFilename: TEdit + Left = 112 + Top = 20 + Width = 337 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + end + end + object GroupBox3: TGroupBox + Left = 256 + Top = 10 + Width = 233 + Height = 79 + Anchors = [akTop, akRight] + Caption = ' Quality ' + TabOrder = 3 + DesignSize = ( + 233 + 79) + object udOversample: TUpDown + Left = 212 + Top = 44 + Width = 12 + Height = 21 + Anchors = [akTop, akRight] + Associate = txtOversample + Min = 1 + Max = 4 + Position = 2 + TabOrder = 2 + end + object Label5: TPanel + Left = 8 + Top = 20 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Filter radius' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object txtFilterRadius: TEdit + Left = 120 + Top = 20 + Width = 105 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + OnChange = txtFilterRadiusChange + end + object Label3: TPanel + Left = 8 + Top = 44 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Oversample' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object txtOversample: TEdit + Left = 120 + Top = 44 + Width = 92 + Height = 21 + Anchors = [akLeft, akTop, akRight] + ReadOnly = True + TabOrder = 1 + Text = '2' + OnChange = txtOversampleChange + end + end + object GroupBox2: TGroupBox + Left = 8 + Top = 10 + Width = 241 + Height = 111 + Anchors = [akLeft, akTop, akRight] + Caption = ' Size ' + TabOrder = 4 + DesignSize = ( + 241 + 111) + object Label13: TLabel + Left = 184 + Top = 36 + Width = 26 + Height = 13 + Anchors = [akLeft, akTop, akRight] + Caption = 'pixels' + Visible = False + end + object Label16: TLabel + Left = 168 + Top = 22 + Width = 15 + Height = 36 + Anchors = [akLeft, akTop, akRight] + Caption = '}' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -32 + Font.Name = 'Times New Roman' + Font.Style = [] + ParentFont = False + Visible = False + end + object chkMaintain: TCheckBox + Left = 8 + Top = 76 + Width = 225 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Maintain aspect ratio' + Checked = True + State = cbChecked + TabOrder = 0 + OnClick = chkMaintainClick + end + object Label1: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Width' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object Label2: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Height' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object cbHeight: TComboBox + Left = 112 + Top = 44 + Width = 121 + Height = 21 + Anchors = [akLeft, akTop, akRight] + ItemHeight = 13 + TabOrder = 2 + OnChange = txtHeightChange + Items.Strings = ( + '200' + '240' + '480' + '600' + '768' + '1024' + '1200' + '2048' + '2400') + end + object cbWidth: TComboBox + Left = 112 + Top = 20 + Width = 121 + Height = 21 + Anchors = [akLeft, akTop, akRight] + ItemHeight = 13 + TabOrder = 1 + OnChange = txtWidthChange + Items.Strings = ( + '320' + '640' + '800' + '1024' + '1280' + '1600' + '1920' + '2048' + '2560' + '3200') + end + end + object GroupBox4: TGroupBox + Left = 8 + Top = 392 + Width = 377 + Height = 113 + Anchors = [akLeft, akTop, akRight] + Caption = ' Parameters ' + TabOrder = 5 + Visible = False + DesignSize = ( + 377 + 113) + object udStrips: TUpDown + Left = 172 + Top = 52 + Width = 12 + Height = 21 + Associate = txtStrips + Min = 1 + Max = 512 + Position = 1 + TabOrder = 2 + end + object Label7: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Buffer depth' + ParentShowHint = False + ShowHint = True + TabOrder = 7 + end + object Label8: TPanel + Left = 8 + Top = 52 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Strips' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + end + object Label9: TPanel + Left = 8 + Top = 84 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'DE Radius' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + end + object txtEstimator: TEdit + Left = 112 + Top = 84 + Width = 73 + Height = 21 + TabOrder = 3 + Text = '5' + end + object txtStrips: TEdit + Left = 112 + Top = 52 + Width = 60 + Height = 21 + TabOrder = 1 + Text = '1' + end + object cmbDepth: TComboBox + Left = 112 + Top = 20 + Width = 73 + Height = 21 + Style = csDropDownList + ItemHeight = 13 + TabOrder = 0 + Items.Strings = ( + '16-bit' + '32-bit' + '32-bit float' + '64-bit') + end + object Label14: TPanel + Left = 192 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Gamma threshold' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + end + object Label12: TPanel + Left = 192 + Top = 52 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'DE Curve' + ParentShowHint = False + ShowHint = True + TabOrder = 11 + end + object Label11: TPanel + Left = 192 + Top = 84 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'DE Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 12 + end + object txtGammaTreshold: TEdit + Left = 296 + Top = 20 + Width = 73 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 6 + Text = '0.01' + OnChange = txtGammaTresholdChange + end + object txtEstimatorCurve: TEdit + Left = 296 + Top = 52 + Width = 73 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 5 + Text = '0.6' + end + object txtEstimatorMin: TEdit + Left = 296 + Top = 84 + Width = 73 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 4 + Text = '0' + end + end + object chkRender: TCheckBox + Left = 392 + Top = 398 + Width = 89 + Height = 43 + Anchors = [akTop, akRight] + Caption = 'Render' + Checked = True + State = cbChecked + TabOrder = 6 + Visible = False + end + object Panel1: TPanel + Left = 8 + Top = 296 + Width = 481 + Height = 89 + Anchors = [akLeft, akTop, akRight] + BevelKind = bkSoft + BevelOuter = bvNone + Color = clInfoBk + TabOrder = 7 + Visible = False + DesignSize = ( + 477 + 85) + object Label6: TLabel + Left = 8 + Top = 4 + Width = 453 + Height = 24 + Alignment = taCenter + Anchors = [akLeft, akTop, akRight] + AutoSize = False + Caption = 'WARNING!' + Font.Charset = DEFAULT_CHARSET + Font.Color = clInfoText + Font.Height = -19 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + end + object Label15: TLabel + Left = 8 + Top = 25 + Width = 447 + Height = 26 + Alignment = taCenter + Anchors = [akLeft, akRight] + Caption = + 'Fractals created with this version of Apophysis are not supporte' + + 'd by the external renderer! To render 2D-only fractals, download' + + ' the latest version of FLAM3 from http://www.flam3.com' + Color = clInfoBk + Font.Charset = DEFAULT_CHARSET + Font.Color = clInfoText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentColor = False + ParentFont = False + WordWrap = True + end + end + object txtDensity: TEdit + Left = 120 + Top = 212 + Width = 105 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 8 + Visible = False + OnChange = txtDensityChange + end + object Label4: TPanel + Left = 8 + Top = 212 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Density' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + Visible = False + end + object SaveDialog: TSaveDialog + DefaultExt = 'jpg' + Filter = + 'JPEG Image (*.jpg)|*.jpg|PPM Image (*.ppm)|*.ppm|PNG Images (*.p' + + 'ng)|*.png' + Left = 464 + Top = 264 + end +end diff --git a/Forms/FormExportC.pas b/Forms/FormExportC.pas new file mode 100644 index 0000000..04e2f10 --- /dev/null +++ b/Forms/FormExportC.pas @@ -0,0 +1,257 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit FormExportC; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, Buttons, ComCtrls, ExtCtrls, Translation; + +type + TExportCDialog = class(TForm) + btnOK: TButton; + btnCancel: TButton; + GroupBox1: TGroupBox; + btnBrowse: TSpeedButton; + txtFilename: TEdit; + SaveDialog: TSaveDialog; + GroupBox3: TGroupBox; + txtOversample: TEdit; + txtFilterRadius: TEdit; + udOversample: TUpDown; + GroupBox2: TGroupBox; + chkMaintain: TCheckBox; + cbWidth: TComboBox; + cbHeight: TComboBox; + GroupBox4: TGroupBox; + cmbDepth: TComboBox; + chkRender: TCheckBox; + txtStrips: TEdit; + udStrips: TUpDown; + txtEstimator: TEdit; + txtEstimatorMin: TEdit; + txtEstimatorCurve: TEdit; + txtGammaTreshold: TEdit; + Panel1: TPanel; + Label6: TLabel; + Label15: TLabel; + Label13: TLabel; + Label16: TLabel; + Label5: TPanel; + Label3: TPanel; + Label1: TPanel; + Label2: TPanel; + Label7: TPanel; + Label8: TPanel; + Label9: TPanel; + Label14: TPanel; + Label12: TPanel; + Label11: TPanel; + Label10: TPanel; + txtDensity: TEdit; + Label4: TPanel; + procedure FormCreate(Sender: TObject); + procedure btnBrowseClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnOKClick(Sender: TObject); + procedure txtWidthChange(Sender: TObject); + procedure chkMaintainClick(Sender: TObject); + procedure txtHeightChange(Sender: TObject); + procedure txtDensityChange(Sender: TObject); + procedure txtFilterRadiusChange(Sender: TObject); + procedure txtOversampleChange(Sender: TObject); + procedure txtGammaTresholdChange(Sender: TObject); + private + FloatFormatSettings: TFormatSettings; + Estimator, EstimatorMin, EstimatorCurve: double; + Jitters, Batches, Strips: integer; + public + Filename: string; + ImageWidth, ImageHeight, Oversample: Integer; + Sample_Density, Filter_Radius: double; + GammaTreshold: double; + end; + +var + ExportCDialog: TExportCDialog; + Ratio: double; + +implementation +uses Global, Main, ShellAPI; + +{$R *.DFM} + +procedure TExportCDialog.btnBrowseClick(Sender: TObject); +begin + SaveDialog.InitialDir := ExtractFileDir(txtFilename.text); + SaveDialog.Filename := txtFilename.Text; + SaveDialog.DefaultExt := 'png'; + SaveDialog.filterIndex := ExportFileFormat; + SaveDialog.Filter := Format('%s|*.png|%s|*.*', + [TextByKey('common-filter-png'), + TextByKey('common-filter-allfiles')]); + if SaveDialog.Execute then + begin + ExportFileFormat := SaveDialog.FilterIndex; + renderPath := ExtractFilePath(SaveDialog.Filename); + end; + +end; + +procedure TExportCDialog.FormShow(Sender: TObject); +begin + txtFilename.Text := Filename; + cbWidth.Text := IntToStr(MainCp.Width); + cbHeight.Text := IntToStr(MainCp.Height); + ImageWidth := MainCp.Width; + ImageHeight := MainCp.Height; + txtDensity.text := FloatToStr(Sample_density); +// if cmbDepth.ItemIndex <> 2 then +// txtBatches.text := IntToStr(Round(Sample_density / 4)); + txtFilterRadius.text := FloatToStr(Filter_Radius); + txtOversample.text := IntToSTr(Oversample); + udOversample.Position := Oversample; + Ratio := ImageWidth / ImageHeight; + Batches := 1; + Estimator := 9.0; + EstimatorMin := 0.0; + EstimatorCurve := 0.4; + Jitters := 1; + GammaTreshold := MainCP.gamma_threshold; //0.01; + GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FloatFormatSettings); + txtEstimator.Text := FloatToStr(Estimator, FloatFormatSettings); + txtEstimatorMin.Text := FloatToStr(EstimatorMin, FloatFormatSettings); + txtEstimatorCurve.Text := FloatToStr(EstimatorCurve, FloatFormatSettings); +// txtJitters.Text := IntToStr(Jitters); + txtGammaTreshold.Text := FloatToStr(GammaTreshold, FloatFormatSettings); +end; + +procedure TExportCDialog.btnOKClick(Sender: TObject); +begin + Filename := txtFilename.text; + ImageWidth := StrToInt(cbWidth.Text); + ImageHeight := StrToInt(cbHeight.Text); +end; + +procedure TExportCDialog.txtWidthChange(Sender: TObject); +begin + try + ImageWidth := StrToInt(cbWidth.Text); + if chkMaintain.checked and cbWidth.Focused then + begin + ImageHeight := Round(ImageWidth / ratio); + cbHeight.Text := IntToStr(ImageHeight) + end; + except + end; +end; + +procedure TExportCDialog.chkMaintainClick(Sender: TObject); +begin + Ratio := ImageWidth / ImageHeight; +end; + +procedure TExportCDialog.txtHeightChange(Sender: TObject); +begin + try + ImageHeight := StrToInt(cbHeight.Text); + if chkMaintain.checked and cbHeight.Focused then + begin + ImageWidth := Round(ImageHeight * ratio); + cbWidth.Text := IntToStr(ImageWidth) + end; + except + end; +end; + +procedure TExportCDialog.txtDensityChange(Sender: TObject); +begin + try + Sample_Density := StrToFloat(txtDensity.Text); +// if cmbDepth.ItemIndex <> 2 then +// txtBatches.text := IntToStr(Round(Sample_density / 4)); + except + end; +end; + +procedure TExportCDialog.txtFilterRadiusChange(Sender: TObject); +begin + try + Filter_Radius := StrToFloat(txtFilterRadius.Text); + except + end; +end; + +procedure TExportCDialog.txtOversampleChange(Sender: TObject); +begin + if StrToInt(txtOversample.Text) > udOversample.Max then + txtOversample.Text := IntToStr(udOversample.Max); + if StrToInt(txtOversample.Text) < udOversample.Min then + txtOversample.Text := IntToStr(udOversample.Min); + try + Oversample := StrToInt(txtOversample.Text); + except + end; +end; + +procedure TExportCDialog.txtGammaTresholdChange(Sender: TObject); +begin + //GammaTreshold := 0.01; + try + GammaTreshold := StrToFloat(txtGammaTreshold.Text, FloatFormatSettings); + except + end; +end; + +procedure TExportCDialog.FormCreate(Sender: TObject); +begin + btnOK.Caption := TextByKey('common-ok'); + btnCancel.Caption := TextByKey('common-cancel'); + Label1.Caption := TextByKey('common-width'); + Label2.Caption := TextByKey('common-height'); + GroupBox2.Caption := TextByKey('common-size'); + Label13.Caption := TextByKey('common-pixels'); + chkMaintain.Caption := TextByKey('common-keepaspect'); + GroupBox1.Caption := TextByKey('common-destination'); + Label10.Caption := TextByKey('common-filename'); + btnBrowse.Hint := TextByKey('common-browse'); + GroupBox3.Caption := TextByKey('common-quality'); + Label5.Caption := TextByKey('common-filterradius'); + Label4.Caption := TextByKey('common-density'); + Label3.Caption := TextByKey('common-oversample'); + Label14.Caption := TextByKey('common-gammathreshold'); + self.Caption := TextByKey('main-menu-file-exportchaotica'); + GroupBox4.Caption := TextByKey('export-paramoptions-title'); + Label7.Caption := TextByKey('export-paramoptions-bufferdepth'); + Label8.Caption := TextByKey('export-paramoptions-strips'); + Label9.Caption := TextByKey('export-paramoptions-estimatorradius'); + Label12.Caption := TextByKey('export-paramoptions-estimatorcurve'); + Label11.Caption := TextByKey('export-paramoptions-estimatormin'); + chkRender.Caption := TextByKey('export-paramoptions-dorender'); + Label6.Caption := TextByKey('export-paramoptions-warningtitle'); + Label15.Caption := TextByKey('export-paramoptions-warningtext'); +end; + +end. + diff --git a/Forms/FormFavorites.dfm b/Forms/FormFavorites.dfm new file mode 100644 index 0000000..cba8df5 --- /dev/null +++ b/Forms/FormFavorites.dfm @@ -0,0 +1,115 @@ +object FavoritesForm: TFavoritesForm + Left = 493 + Top = 541 + BorderStyle = bsDialog + Caption = 'Favorite Scripts' + ClientHeight = 275 + ClientWidth = 352 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + DesignSize = ( + 352 + 275) + PixelsPerInch = 96 + TextHeight = 13 + object PageControl1: TPageControl + Left = 8 + Top = 8 + Width = 338 + Height = 231 + Anchors = [akLeft, akTop, akRight, akBottom] + TabOrder = 0 + end + object ListView: TListView + Left = 16 + Top = 16 + Width = 218 + Height = 215 + Anchors = [akLeft, akTop, akRight, akBottom] + Columns = < + item + AutoSize = True + Caption = 'Name' + end> + HideSelection = False + ReadOnly = True + RowSelect = True + ShowColumnHeaders = False + TabOrder = 1 + ViewStyle = vsReport + OnChange = ListViewChange + end + object btnAdd: TButton + Left = 241 + Top = 16 + Width = 99 + Height = 25 + Anchors = [akTop, akRight] + Caption = '&Add' + TabOrder = 2 + TabStop = False + OnClick = btnAddClick + end + object btnRemove: TButton + Left = 241 + Top = 48 + Width = 99 + Height = 25 + Anchors = [akTop, akRight] + Caption = '&Remove' + TabOrder = 3 + TabStop = False + OnClick = btnRemoveClick + end + object btnMoveUp: TButton + Left = 241 + Top = 80 + Width = 99 + Height = 25 + Anchors = [akTop, akRight] + Caption = 'Move &Up' + TabOrder = 4 + TabStop = False + OnClick = btnMoveUpClick + end + object btnMoveDown: TButton + Left = 241 + Top = 112 + Width = 99 + Height = 25 + Anchors = [akTop, akRight] + Caption = 'Move &Down' + TabOrder = 5 + TabStop = False + OnClick = btnMoveDownClick + end + object btnOK: TButton + Left = 193 + Top = 246 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = '&OK' + TabOrder = 6 + OnClick = btnOKClick + end + object btnCancel: TButton + Left = 273 + Top = 246 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = '&Cancel' + TabOrder = 7 + OnClick = btnCancelClick + end +end diff --git a/Forms/FormFavorites.pas b/Forms/FormFavorites.pas new file mode 100644 index 0000000..ed927f7 --- /dev/null +++ b/Forms/FormFavorites.pas @@ -0,0 +1,224 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit FormFavorites; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls, ComCtrls, Translation; + +type + TFavoritesForm = class(TForm) + PageControl1: TPageControl; + ListView: TListView; + btnAdd: TButton; + btnRemove: TButton; + btnMoveUp: TButton; + btnMoveDown: TButton; + btnOK: TButton; + btnCancel: TButton; + procedure FormShow(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure btnOKClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure btnAddClick(Sender: TObject); + procedure btnRemoveClick(Sender: TObject); + procedure ListViewChange(Sender: TObject; Item: TListItem; + Change: TItemChange); + procedure btnMoveUpClick(Sender: TObject); + procedure btnMoveDownClick(Sender: TObject); + private + { Private declarations } + public + Faves: TStringList; + { Public declarations } + end; + +var + FavoritesForm: TFavoritesForm; + +implementation + +uses Global, ScriptForm; +{$R *.DFM} + +procedure TFavoritesForm.FormShow(Sender: TObject); +var + ListItem: TListItem; + i: integer; + s: string; +begin + Faves.Text := Favorites.text; + ListView.Items.Clear; + for i := 0 to Favorites.Count - 1 do + begin + ListItem := ListView.Items.Add; + s := ExtractFileName(Favorites[i]); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + Listitem.Caption := s; + end; + if Favorites.Count <> 0 then ListView.Selected := ListView.Items[0] + else + btnRemove.Enabled := False; + if ListView.Items.Count <= 1 then + begin + btnMoveUp.Enabled := False; + btnMoveDown.Enabled := False; + end; +end; + +procedure TFavoritesForm.btnCancelClick(Sender: TObject); +begin + Close +end; + +procedure TFavoritesForm.btnOKClick(Sender: TObject); +begin + ModalResult := mrOK; + Faves.SaveToFile(AppPath + scriptFavsFilename); +end; + +procedure TFavoritesForm.FormCreate(Sender: TObject); +begin + btnOK.Caption := TextByKey('common-ok'); + btnCancel.Caption := TextByKey('common-cancel'); + self.Caption := TextByKey('favscripts-title'); + btnAdd.Caption := TextByKey('favscripts-add'); + btnRemove.Caption := TextByKey('favscripts-remove'); + btnMoveUp.Caption := TextByKey('favscripts-moveup'); + btnMoveDown.Caption := TextByKey('favscripts-movedown'); + + Faves := TStringList.Create; +end; + +procedure TFavoritesForm.FormDestroy(Sender: TObject); +begin + Faves.Free; +end; + +procedure TFavoritesForm.btnAddClick(Sender: TObject); +var + ListItem: TListItem; + i : integer; + s: string; +begin + ScriptEditor.MainOpenDialog.InitialDir := ScriptPath; + ScriptEditor.MainOpenDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*', + [TextByKey('common-filter-script'), + TextByKey('common-filter-allfiles')]); + if ScriptEditor.mainOpenDialog.Execute then + begin + for i := 0 to Faves.Count - 1 do + begin + if ScriptEditor.MainOpenDialog.Filename = Faves[i] then exit; + end; + + Faves.add(ScriptEditor.MainOpenDialog.Filename); + ListItem := ListView.Items.Add; + s := ExtractFileName(ScriptEditor.MainOpenDialog.Filename); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + Listitem.Caption := s; + ListView.Selected := ListView.Items[ListView.Items.Count - 1]; + btnRemove.Enabled := True; + end; + if ListView.Items.Count <= 1 then + begin + btnMoveUp.Enabled := False; + btnMoveDown.Enabled := False; + end; +end; + +procedure TFavoritesForm.btnRemoveClick(Sender: TObject); +var + i: integer; +begin + i := ListView.Selected.Index; + Faves.Delete(i); + ListView.Items[i].delete; + if ListView.Items.Count <> 0 then + if i < ListView.Items.Count then + ListView.Selected := ListView.Items[i] + else + ListView.Selected := ListView.Items[ListView.Items.Count - 1] + else + btnRemove.Enabled := False; + if ListView.Items.Count <= 1 then + begin + btnMoveUp.Enabled := False; + btnMoveDown.Enabled := False; + end; +end; + +procedure TFavoritesForm.ListViewChange(Sender: TObject; Item: TListItem; + Change: TItemChange); +begin + if (Item.Index = ListView.Items.Count - 1) then + btnMoveDown.Enabled := False + else + btnMoveDown.Enabled := True; + if (Item.Index = 0) then + btnMoveUp.Enabled := False + else + btnMoveUp.Enabled := True; + + if (ListView.Items.Count <= 1) then + begin + btnMoveDown.Enabled := False; + btnMoveUp.Enabled := False; + end; +end; + +procedure TFavoritesForm.btnMoveUpClick(Sender: TObject); +var + i: integer; + s: string; +begin + i := ListView.Selected.Index; + s := faves[i]; + Faves[i] := Faves[i - 1]; + Faves[i - 1] := s; + s := ListView.Selected.Caption; + ListView.Selected.Caption := Listview.Items[i - 1].Caption; + ListView.Items[i - 1].Caption := s; + ListView.Selected := ListView.Items[i - 1]; +end; + +procedure TFavoritesForm.btnMoveDownClick(Sender: TObject); +var + i: integer; + s: string; +begin + i := ListView.Selected.Index; + s := faves[i]; + Faves[i] := Faves[i + 1]; + Faves[i + 1] := s; + s := ListView.Selected.Caption; + ListView.Selected.Caption := Listview.Items[i + 1].Caption; + ListView.Items[i + 1].Caption := s; + ListView.Selected := ListView.Items[i + 1]; +end; + +end. + diff --git a/Forms/FormRender.dfm b/Forms/FormRender.dfm new file mode 100644 index 0000000..e15cdc7 --- /dev/null +++ b/Forms/FormRender.dfm @@ -0,0 +1,723 @@ +object RenderForm: TRenderForm + Left = 851 + Top = 205 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSingle + Caption = 'Render to Disk' + ClientHeight = 469 + ClientWidth = 497 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + DesignSize = ( + 497 + 469) + PixelsPerInch = 96 + TextHeight = 13 + object btnRender: TButton + Left = 256 + Top = 420 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Start' + Default = True + TabOrder = 0 + OnClick = btnRenderClick + end + object btnCancel: TButton + Left = 416 + Top = 420 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Close' + TabOrder = 1 + OnClick = btnCancelClick + end + object btnPause: TButton + Left = 336 + Top = 420 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Pause' + TabOrder = 2 + OnClick = btnPauseClick + end + object PageCtrl: TPageControl + Left = 8 + Top = 8 + Width = 481 + Height = 373 + ActivePage = TabSettings + Anchors = [akLeft, akTop, akRight, akBottom] + Images = MainForm.Buttons + TabOrder = 3 + object TabSettings: TTabSheet + Caption = 'Settings' + ImageIndex = 18 + DesignSize = ( + 473 + 344) + object btnBrowse: TSpeedButton + Left = 416 + Top = 11 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnBrowseClick + end + object btnGoTo: TSpeedButton + Left = 440 + Top = 11 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FF964924EADBD3FF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF9D + 4D259D4E28EADBD3FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFCF835D9247239A4B25A24F27AB5429BF6A3FA0502AEADBD3FF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD78B65FDB089F7905CEC8856DE + 7F4FD17648C46E42A25631EADBD3FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFDE926CFCB997FDA578FC935EF28C59E58453D87B4CC66E41AE582BFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFE49872FBC3A6FDBE9EFEAE85FF + A87DF89D6FE58351AE582BF4E7E1FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFE89C76E29670DA8E68D1855FDB906AF79A6BAE582BF4E7E1FF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFE5 + 9973C5764EF3E6DFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFE89C76F8EDE8FF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnGoToClick + end + object GroupBox5: TGroupBox + Left = 464 + Top = 16 + Width = 425 + Height = 57 + Caption = 'Preset' + TabOrder = 0 + Visible = False + object btnSavePreset: TSpeedButton + Left = 368 + Top = 18 + Width = 24 + Height = 24 + Hint = 'Save Preset' + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnSavePresetClick + end + object btnDeletePreset: TSpeedButton + Left = 392 + Top = 18 + Width = 24 + Height = 24 + Hint = 'Delete Preset' + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnDeletePresetClick + end + object cmbPreset: TComboBox + Left = 10 + Top = 20 + Width = 351 + Height = 21 + Style = csDropDownList + TabOrder = 0 + OnChange = cmbPresetChange + end + end + object GroupBox2: TGroupBox + Left = 8 + Top = 42 + Width = 233 + Height = 95 + Anchors = [akLeft, akTop, akRight] + Caption = 'Size' + TabOrder = 1 + DesignSize = ( + 233 + 95) + object Label6: TLabel + Left = 144 + Top = 22 + Width = 15 + Height = 36 + Caption = '}' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -32 + Font.Name = 'Times New Roman' + Font.Style = [] + ParentFont = False + Visible = False + end + object Label7: TLabel + Left = 160 + Top = 36 + Width = 26 + Height = 13 + Caption = 'pixels' + Visible = False + end + object chkMaintain: TCheckBox + Left = 8 + Top = 70 + Width = 217 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Keep aspect ratio' + Checked = True + State = cbChecked + TabOrder = 0 + OnClick = chkMaintainClick + end + object pnlWidth: TPanel + Left = 8 + Top = 20 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Width' + TabOrder = 3 + end + object pnlHeight: TPanel + Left = 8 + Top = 44 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Height' + TabOrder = 4 + end + object cbHeight: TComboBox + Left = 120 + Top = 44 + Width = 105 + Height = 21 + Anchors = [akLeft, akTop, akRight] + BiDiMode = bdLeftToRight + Enabled = False + ParentBiDiMode = False + TabOrder = 2 + OnChange = txtHeightChange + Items.Strings = ( + '200' + '240' + '480' + '600' + '768' + '1024' + '1200' + '1920' + '2048' + '2400') + end + object cbWidth: TComboBox + Left = 120 + Top = 20 + Width = 105 + Height = 21 + Anchors = [akLeft, akTop, akRight] + BiDiMode = bdLeftToRight + Enabled = False + ParentBiDiMode = False + TabOrder = 1 + OnChange = txtWidthChange + Items.Strings = ( + '320' + '640' + '800' + '1024' + '1280' + '1600' + '1920' + '2048' + '2560' + '3200') + end + end + object GroupBox3: TGroupBox + Left = 248 + Top = 42 + Width = 218 + Height = 95 + Anchors = [akTop, akRight] + Caption = 'Quality settings' + TabOrder = 2 + DesignSize = ( + 218 + 95) + object udOversample: TUpDown + Left = 196 + Top = 68 + Width = 13 + Height = 21 + Anchors = [akTop, akRight] + Associate = txtOversample + Min = 1 + Max = 16 + Position = 1 + TabOrder = 3 + end + object pnlDensity: TPanel + Left = 8 + Top = 20 + Width = 121 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Density' + TabOrder = 4 + end + object pnlFilter: TPanel + Left = 8 + Top = 44 + Width = 121 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Filter radius' + TabOrder = 5 + end + object pnlOversample: TPanel + Left = 8 + Top = 68 + Width = 121 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Oversample' + TabOrder = 6 + end + object txtDensity: TComboBox + Left = 128 + Top = 20 + Width = 82 + Height = 21 + AutoComplete = False + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + OnChange = txtDensityChange + OnCloseUp = txtDensityChange + Items.Strings = ( + '200' + '500' + '1000' + '2000' + '4000') + end + object txtFilterRadius: TEdit + Left = 128 + Top = 44 + Width = 82 + Height = 21 + Anchors = [akLeft, akTop, akRight] + BiDiMode = bdRightToLeft + ParentBiDiMode = False + TabOrder = 1 + Text = '0.1' + OnChange = txtFilterRadiusChange + end + object txtOversample: TEdit + Left = 128 + Top = 68 + Width = 68 + Height = 21 + Anchors = [akLeft, akTop, akRight] + BiDiMode = bdRightToLeft + Enabled = False + ParentBiDiMode = False + ReadOnly = True + TabOrder = 2 + Text = '1' + OnChange = txtOversampleChange + end + end + object GroupBox4: TGroupBox + Left = 8 + Top = 142 + Width = 458 + Height = 99 + Anchors = [akLeft, akTop, akRight] + Caption = 'Resource usage' + TabOrder = 3 + DesignSize = ( + 458 + 99) + object lblApproxMem: TLabel + Left = 439 + Top = 100 + Width = 42 + Height = 13 + Alignment = taRightJustify + Caption = '0000 Mb' + Visible = False + end + object lblPhysical: TLabel + Left = 439 + Top = 96 + Width = 42 + Height = 13 + Alignment = taRightJustify + Caption = '0000 Mb' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + Visible = False + end + object lblMaxbits: TLabel + Left = 440 + Top = 116 + Width = 33 + Height = 13 + Hint = '- No render stats -' + Alignment = taRightJustify + Caption = '99.999' + ParentShowHint = False + ShowHint = True + Visible = False + end + object Label9: TLabel + Left = 440 + Top = 108 + Width = 96 + Height = 13 + Hint = '- No render stats -' + Caption = 'Max bits per sample:' + ParentShowHint = False + ShowHint = True + Visible = False + end + object lblMemory: TLabel + Left = 11 + Top = 18 + Width = 442 + Height = 24 + Anchors = [akLeft, akTop, akRight] + AutoSize = False + Caption = + 'The render process will use 0000 Mb of 0000MB available physical' + + ' memory' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + Layout = tlCenter + WordWrap = True + end + object lblCPUCores: TLabel + Left = 11 + Top = 43 + Width = 442 + Height = 14 + Anchors = [akLeft, akTop, akRight] + AutoSize = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + Layout = tlCenter + WordWrap = True + end + object chkLimitMem: TCheckBox + Left = 444 + Top = 134 + Width = 125 + Height = 17 + Caption = 'Limit memory usage to:' + TabOrder = 0 + Visible = False + end + object pnlLimit: TPanel + Left = 8 + Top = 68 + Width = 121 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Memory limit' + TabOrder = 2 + end + object cbMaxMemory: TComboBox + Left = 128 + Top = 68 + Width = 97 + Height = 21 + Style = csDropDownList + BiDiMode = bdLeftToRight + ItemIndex = 0 + ParentBiDiMode = False + TabOrder = 1 + Text = 'No limit' + OnChange = cbMaxMemoryChange + Items.Strings = ( + 'No limit' + '32' + '64' + '128' + '256' + '512' + '1024' + '1536') + end + object PBMem: TProgressBar + Left = 232 + Top = 68 + Width = 217 + Height = 21 + TabOrder = 3 + end + end + object GroupBox1: TGroupBox + Left = 8 + Top = 253 + Width = 217 + Height = 81 + Caption = 'Output options' + TabOrder = 5 + DesignSize = ( + 217 + 81) + object chkSave: TCheckBox + Left = 8 + Top = 24 + Width = 201 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Save parameters' + Checked = True + State = cbChecked + TabOrder = 0 + end + object chkSaveIncompleteRenders: TCheckBox + Left = 8 + Top = 48 + Width = 201 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Save incomplete renders' + TabOrder = 1 + OnClick = chkSaveIncompleteRendersClick + end + end + object GroupBox6: TGroupBox + Left = 232 + Top = 253 + Width = 234 + Height = 81 + Anchors = [akLeft, akTop, akRight] + Caption = 'Completion options' + TabOrder = 6 + DesignSize = ( + 234 + 81) + object chkPostProcess: TCheckBox + Left = 8 + Top = 24 + Width = 217 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Post-process after completion' + TabOrder = 0 + end + object chkShutdown: TCheckBox + Left = 8 + Top = 48 + Width = 217 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Shut down computer when complete' + TabOrder = 1 + end + end + object pnlTarget: TPanel + Left = 8 + Top = 12 + Width = 121 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Destination' + TabOrder = 7 + end + object txtFilename: TEdit + Left = 128 + Top = 12 + Width = 288 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 4 + OnChange = txtFilenameChange + end + object chkBinary: TCheckBox + Left = 8 + Top = 349 + Width = 457 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = + 'Write raw data (WARNING: this is experimental and slows down the' + + ' rendering!!!)' + Enabled = False + TabOrder = 8 + Visible = False + end + end + object TabOutput: TTabSheet + Caption = 'Output' + ImageIndex = 38 + object Output: TMemo + Left = 0 + Top = 0 + Width = 473 + Height = 344 + Align = alClient + BorderStyle = bsNone + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clBtnText + Font.Height = -11 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 0 + end + end + end + object StatusBar: TStatusBar + Left = 0 + Top = 450 + Width = 497 + Height = 19 + Panels = < + item + Width = 161 + end + item + Width = 150 + end + item + Width = 50 + end> + end + object btnSaveLog: TButton + Left = 8 + Top = 419 + Width = 73 + Height = 25 + Anchors = [akLeft, akBottom] + Caption = 'Save log' + Enabled = False + TabOrder = 5 + Visible = False + OnClick = btnSaveLogClick + end + object ProgressBar2: TProgressBar + Left = 8 + Top = 388 + Width = 481 + Height = 25 + Anchors = [akLeft, akRight, akBottom] + TabOrder = 6 + end + object SaveDialog: TSaveDialog + Left = 168 + Top = 464 + end +end diff --git a/Forms/FormRender.pas b/Forms/FormRender.pas new file mode 100644 index 0000000..7719e53 --- /dev/null +++ b/Forms/FormRender.pas @@ -0,0 +1,1311 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit FormRender; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ComCtrls, Math, Buttons, Registry, ExtCtrls, MMSystem, Windows7, + ControlPoint, RenderThread, cmap, RenderingCommon, RenderingInterface, + ShellAPI, Translation, ActiveX, ComObj; + +type + TRenderForm = class(TForm) + btnRender: TButton; + btnCancel: TButton; + SaveDialog: TSaveDialog; + btnPause: TButton; + StatusBar: TStatusBar; + PageCtrl: TPageControl; + TabSettings: TTabSheet; + TabOutput: TTabSheet; + GroupBox5: TGroupBox; + btnSavePreset: TSpeedButton; + btnDeletePreset: TSpeedButton; + cmbPreset: TComboBox; + GroupBox2: TGroupBox; + chkMaintain: TCheckBox; + cbWidth: TComboBox; + cbHeight: TComboBox; + GroupBox3: TGroupBox; + txtOversample: TEdit; + txtFilterRadius: TEdit; + udOversample: TUpDown; + txtDensity: TComboBox; + GroupBox4: TGroupBox; + lblApproxMem: TLabel; + lblPhysical: TLabel; + lblMaxbits: TLabel; + Label9: TLabel; + cbMaxMemory: TComboBox; + chkLimitMem: TCheckBox; + Output: TMemo; + lblMemory: TLabel; + btnBrowse: TSpeedButton; + txtFilename: TEdit; + GroupBox1: TGroupBox; + chkSave: TCheckBox; + GroupBox6: TGroupBox; + chkPostProcess: TCheckBox; + chkShutdown: TCheckBox; + Label6: TLabel; + Label7: TLabel; + btnGoTo: TSpeedButton; + pnlWidth: TPanel; + pnlHeight: TPanel; + pnlDensity: TPanel; + pnlFilter: TPanel; + pnlOversample: TPanel; + pnlLimit: TPanel; + pnlTarget: TPanel; + btnSaveLog: TButton; + chkBinary: TCheckBox; + ProgressBar2: TProgressBar; + PBMem: TProgressBar; + chkSaveIncompleteRenders: TCheckBox; + lblCPUCores: TLabel; + procedure btnSaveLogClick(Sender: TObject); + procedure cbMaxMemoryChange(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure btnRenderClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure txtWidthChange(Sender: TObject); + procedure txtHeightChange(Sender: TObject); + procedure txtOversampleChange(Sender: TObject); + procedure txtFilenameChange(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure txtDensityChange(Sender: TObject); + procedure txtFilterRadiusChange(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure btnPauseClick(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure btnSavePresetClick(Sender: TObject); + procedure btnBrowseClick(Sender: TObject); + procedure btnDeletePresetClick(Sender: TObject); + procedure cmbPresetChange(Sender: TObject); + procedure chkMaintainClick(Sender: TObject); + procedure chkSaveIncompleteRendersClick(Sender: TObject); + procedure btnGoToClick(Sender: TObject); + private + StartTime, EndTime, oldElapsed, edt: TDateTime; + oldProg: double; + + ApproxSamples: int64; + + procedure DoPostProcess; + + procedure HandleThreadCompletion(var Message: TMessage); + message WM_THREAD_COMPLETE; + procedure HandleThreadTermination(var Message: TMessage); + message WM_THREAD_TERMINATE; + procedure ListPresets; + function WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean; + procedure Save(const str:string); + function IsLimitingMemory():boolean; + + public + Renderer: TRenderThread; + PhysicalMemory, ApproxMemory, TotalPhysicalMemory: int64; + ColorMap: TColorMap; + cp: TControlPoint; + Filename: string; + ImageWidth, ImageHeight, Oversample: Integer; + BitsPerSample: integer; + zoom, Sample_Density, Brightness, Gamma, Vibrancy, Filter_Radius: double; + center: array[0..1] of double; + MaxMemory: integer; + bRenderAll: boolean; + + procedure OnProgress(prog: double); + procedure ShowMemoryStatus; + procedure ResetControls; + end; + +var + RenderForm: TRenderForm; + Ratio: double; + +implementation + +uses + Main, Global, SavePreset, formPostProcess, PngImage, ImageMaker,Tracer; + +{$R *.DFM} + +function TRenderForm.IsLimitingMemory():boolean; +begin + Result := (cbMaxMemory.ItemIndex > 0); +end; + +procedure TRenderForm.ResetControls; +begin + txtFilename.Enabled := true; + btnBrowse.Enabled := true; + cbWidth.Enabled := true; + cbHeight.Enabled := true; + txtDensity.Enabled := true; + txtFilterRadius.enabled := true; + txtOversample.Enabled := true; + //chkLimitMem.Enabled := true; + cbMaxMemory.enabled := true; + //cbBitsPerSample.Enabled := true; + chkPostProcess.Enabled := not IsLimitingMemory; + chkSaveIncompleteRenders.Enabled := not IsLimitingMemory; + btnRender.Enabled := true; + cmbPreset.enabled := true; + btnSaveLog.Enabled := false; + chkSave.enabled := true; + chkPostProcess.enabled := true; + chkShutdown.enabled := true; + btnSavePreset.enabled := true; + btnDeletePreset.enabled := true; + btnCancel.Caption := TextByKey('common-close'); + btnPause.enabled := false; + ProgressBar2.Position := 0; + chkMaintain.Enabled := true; + + SetTaskbarProgressValue( + ProgressBar2.Position - ProgressBar2.Min, + ProgressBar2.Max - ProgressBar2.Min); + SetTaskbarProgressState(tbpsNone); + + pnlWidth.Enabled := true; + pnlHeight.Enabled := true; + pnlDensity.Enabled := true; + pnlFilter.Enabled := true; + pnlOversample.Enabled := true; + pnlLimit.Enabled := true; + pnlTarget.Enabled := true; + //pnlBufferDepth.Enabled := true; + + pnlWidth.Font.Color := clWindowText; + pnlHeight.Font.Color := clWindowText; + pnlDensity.Font.Color := clWindowText; + pnlFilter.Font.Color := clWindowText; + pnlOversample.Font.Color := clWindowText; + pnlLimit.Font.Color := clWindowText; + pnlTarget.Font.Color := clWindowText; + //pnlBufferDepth.Font.Color := clWindowText; + ShowMemoryStatus; +end; + +procedure WinShellExecute(const Operation, AssociatedFile: string); +var + a1: string; +begin + a1 := Operation; + if a1 = '' then + a1 := 'open'; + ShellExecute( + application.handle + , pchar(a1) + , pchar(AssociatedFile) + , '' + , '' + , SW_SHOWNORMAL + ); +end; + +function GetCpuCount: integer; +var + si: TSystemInfo; +begin; + GetSystemInfo(si); + Result := si.dwNumberOfProcessors; +end; + +procedure TRenderForm.ShowMemoryStatus; +var + GlobalMemoryInfo: TMemoryStatus; // holds the global memory status information +begin + GlobalMemoryInfo.dwLength := SizeOf(GlobalMemoryInfo); + GlobalMemoryStatus(GlobalMemoryInfo); + PhysicalMemory := GlobalMemoryInfo.dwAvailPhys div 1048576; + TotalPhysicalMemory := GlobalMemoryInfo.dwTotalPhys div 1048576; + //TotalPhysicalMemory := TotalPhysicalMemory * 9 div 10; // assume that OS will take 10% of RAM ;) + + if SingleBuffer then + ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 16 div 1048576 + else + ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 32 div 1048576; + + +// lblPhysical.Caption := Format('%u', [PhysicalMemory]) + ' Mb'; +// lblApproxMem.Caption := Format('%u', [ApproxMemory]) + ' Mb'; + lblMemory.Caption := Format(TextByKey('render-resourceusage-infotext'), [ApproxMemory, PhysicalMemory]); + lblCPUCores.Caption := Format(TextByKey('render-resourceusage-infotext2'), [NrTreads, GetCpuCount]); + PBMem.Position := round(100 * (ApproxMemory / PhysicalMemory)); + + if ApproxMemory > PhysicalMemory then //lblPhysical.Font.Color := clRed + lblMemory.Font.Color := clRed + else //lblPhysical.Font.Color := clWindowText; + lblMemory.Font.Color := clWindowText; + + if NrTreads > GetCpuCount then + lblCpuCores.Font.Color := clRed + else + lblCpuCores.Font.Color := clWindowText; + + + //btnRender.Enabled := (ApproxMemory <= PhysicalMemory) or (cbMaxMemory.ItemIndex > 0); + + if ApproxMemory > 0 then + lblMaxbits.caption := format('%2.3f', [8 + log2( + sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) + )]); +end; + +procedure Trace2(const str: string); +begin + if TraceLevel >= 2 then + RenderForm.Output.Lines.Add('. . ' + str); +end; + +procedure TRenderForm.Save(const str:string); +begin + Renderer.SaveImage(FileName); +end; + +procedure TRenderForm.HandleThreadCompletion(var Message: TMessage); +var + tryAgain: boolean; +begin + Trace2(MsgComplete + IntToStr(message.LParam)); + if not assigned(Renderer) then begin + Trace2(MsgNotAssigned); + exit; + end; + if Renderer.ThreadID <> message.LParam then begin + Trace2(MsgAnotherRunning); + exit; + end; + + EndTime := Now; + + repeat + tryAgain := false; + try + Save(FileName); + except + on e: Exception do begin + Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log')); + tryAgain := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message + + #13#10 + TextByKey('render-status-saveerror-message2')), 'Apophysis', MB_RETRYCANCEL or MB_ICONERROR) = IDRETRY); + SetTaskbarProgressState(tbpsError); + end; + end; + until tryAgain = false; + + if PlaySoundOnRenderComplete then + if RenderCompleteSoundFile <> '' then + sndPlaySound(PChar(RenderCompleteSoundFile), SND_FILENAME or SND_NOSTOP or SND_ASYNC) + else + sndPlaySound(pchar(SND_ALIAS_SYSTEMASTERISK), SND_ALIAS_ID or SND_NOSTOP or SND_ASYNC); + + PageCtrl.TabIndex := 1; + if ShowRenderStats then + Renderer.ShowBigStats + else + Renderer.ShowSmallStats; + Output.Lines.Add(' ' + TextByKey('render-status-totaltime') + TimeToString(EndTime - StartTime)); + Output.Lines.Add(''); + + SetTaskbarProgressState(tbpsNone); + + if not IsLimitingMemory and chkPostProcess.checked then + DoPostProcess; + + Renderer.Free; + Renderer := nil; + if not bRenderAll then ResetControls; + + btnSaveLog.Enabled := true; + + if chkShutdown.Checked and not bRenderAll then + WindowsExit; +end; + +procedure TRenderForm.HandleThreadTermination(var Message: TMessage); +begin + Trace2(MsgTerminated + IntToStr(message.LParam)); + if not assigned(Renderer) then begin + Trace2(MsgNotAssigned); + exit; + end; + if Renderer.ThreadID <> message.LParam then begin + Trace2(MsgAnotherRunning); + exit; + end; + + if Renderer.GetRenderer.Hibernated then + Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-renderhibernated')) + else + Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-renderterminated')); + + Output.Lines.Add(''); + SetTaskbarProgressState(tbpsNone); + sndPlaySound(pchar(SND_ALIAS_SYSTEMEXCLAMATION), SND_ALIAS_ID or SND_NOSTOP or SND_ASYNC); + + Renderer.Free; + Renderer := nil; + ResetControls; + + btnSaveLog.Enabled := true; +end; + +procedure TRenderForm.OnProgress(prog: double); +var + Elapsed, Remaining, dt: TDateTime; +begin + Elapsed := Now - StartTime; + dt := Elapsed - oldElapsed; + if (prog = 1.0) then begin + StatusBar.Panels[0].text := Format(TextByKey('render-status-elapsed') + ': %2.2d:%2.2d:%2.2d.%2.2d', + [Trunc(Elapsed * 24), + Trunc(Elapsed * 24 * 60) mod 60, + Trunc(Elapsed * 24 * 60 * 60) mod 60, + Trunc(Elapsed * 24 * 60 * 60 * 100) mod 100]); + StatusBar.Panels[1].text := TextByKey('render-status-remaining') + ': 00:00:00.00'; + exit; + end; + + //if (dt < 1/24/60/60/10) then exit; + if (dt < 1/24/60/60) then exit; // PB: too much time consuming... was every 1/10th seconds! + oldElapsed := Elapsed; + + prog := (Renderer.Slice + Prog) / Renderer.NrSlices; + if ShowProgress then ProgressBar2.Position := round(100 * prog); + + StatusBar.Panels[0].text := Format(TextByKey('render-status-elapsed') + ': %2.2d:%2.2d:%2.2d.%2.2d', + [Trunc(Elapsed * 24), + Trunc(Elapsed * 24 * 60) mod 60, + Trunc(Elapsed * 24 * 60 * 60) mod 60, + Trunc(Elapsed * 24 * 60 * 60 * 100) mod 100]); + + edt := edt + dt; + if (edt > 1/24/60/60/2) and (prog > 0) then + begin + Remaining := (1 - prog) * edt / (prog - oldProg); + edt := 0; + oldProg := prog; + + StatusBar.Panels[1].text := Format(TextByKey('render-status-remaining') + ': %2.2d:%2.2d:%2.2d.%2.2d', + [Trunc(Remaining * 24), + Trunc(Remaining * 24 * 60) mod 60, + Trunc(Remaining * 24 * 60 * 60) mod 60, + Trunc(Remaining * 24 * 60 * 60 * 100) mod 100]); + end; + StatusBar.Panels[2].text := Format(TextByKey('render-status-slicestatus'), [(Renderer.Slice + 1), (Renderer.nrSlices)]); + //'Slice ' + IntToStr(Renderer.Slice + 1) + ' of ' + IntToStr(Renderer.nrSlices); + Application.ProcessMessages; +end; + +procedure TRenderForm.FormCreate(Sender: TObject); +begin +{$ifdef Apo7X64} + cbMaxMemory.Items.Add('2048'); + cbMaxMemory.Items.Add('3072'); + cbMaxMemory.Items.Add('4096'); +{$endif} + + pnlWidth.Caption := TextByKey('common-width'); + pnlHeight.Caption := TextByKey('common-height'); + GroupBox2.Caption := TextByKey('common-size'); + chkMaintain.Caption := TextByKey('common-keepaspect'); + pnlTarget.Caption := TextByKey('common-destination'); + btnBrowse.Hint := TextByKey('common-browse'); + GroupBox3.Caption := TextByKey('common-quality'); + pnlFilter.Caption := TextByKey('common-filterradius'); + pnlDensity.Caption := TextByKey('common-density'); + pnlOversample.Caption := TextByKey('common-oversample'); + btnRender.Caption := TextByKey('common-start'); + btnPause.Caption := TextByKey('common-pause'); + btnCancel.Caption := TextByKey('common-close'); + self.Caption := TextByKey('render-title'); + TabSettings.Caption := TextByKey('render-tab-settings-title'); + TabOutput.Caption := TextByKey('render-tab-output-title'); + btnGoTo.Hint := TextByKey('render-common-gotofolder'); + GroupBox4.Caption := TextByKey('render-resourceusage-title'); + pnlLimit.Caption := TextByKey('render-resourceusage-limit'); + //pnlBufferDepth.Caption := TextByKey('render-resourceusage-bufferdepth'); + chkSave.Caption := TextByKey('render-output-saveparams'); + GroupBox6.Caption := TextByKey('render-completion-title'); + chkPostProcess.Caption := TextByKey('render-completion-postprocess'); + chkShutdown.Caption := TextByKey('render-completion-shutdown'); + chkSaveIncompleteRenders.Caption := TextByKey('render-completion-saveincomplete'); + cbMaxMemory.Items[0] := TextByKey('render-resourceusage-nolimit') ; + Groupbox1.Caption := TextByKey('render-tab-output-title'); + + cp := TControlPoint.Create; + cbMaxMemory.ItemIndex := 0; + //cbBitsPerSample.ItemIndex := 0; + BitsPerSample := 0; + MainForm.Buttons.GetBitmap(2, btnSavePreset.Glyph); + MainForm.Buttons.GetBitmap(9, btnDeletePreset.Glyph); + bRenderAll := false; + ListPresets; +end; + +procedure TRenderForm.FormDestroy(Sender: TObject); +begin + if assigned(Renderer) then begin + Renderer.Terminate; + Renderer.WaitFor; + Renderer.Free; + end; + cp.free; +end; + +procedure TRenderForm.btnRenderClick(Sender: TObject); +var + t: string; + iCurrFlame: integer; + path, ext: string; + lim:integer; + ilm:boolean; + sl: TStringList; + tryAgain: boolean; + cancel: boolean; + result: integer; +begin + // overwrite target with 0b file + // this to test writability in output directory + {sl := TStringList.Create; + sl.Text := ''; + repeat + tryAgain := false; + cancel := false; + try + sl.SaveToFile(txtFileName.Text); + except + on e: Exception do begin + Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log')); + result := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message + + #13#10 + TextByKey('render-status-saveerror-message2')), 'Apophysis', MB_RETRYCANCEL or MB_ICONERROR)); + tryAgain := (result = IDRETRY); + cancel := (result = IDCANCEL); + ProgressBar2.ProgressBarState := pbstError; + end; + end; + until (tryAgain = false) or (cancel = true); + sl.Destroy; } + + //if (cancel) then Exit; + Output.Text := ''; + SetTaskbarProgressValue( + ProgressBar2.Position - ProgressBar2.Min, + ProgressBar2.Max - ProgressBar2.Min); + SetTaskbarProgressState(tbpsNormal); + + ImageWidth := StrToInt(cbWidth.text); + ImageHeight := StrToInt(cbHeight.text); + + ilm := IsLimitingMemory; + if (IsLimitingMemory) then begin + lim := StrToInt(cbMaxMemory.text); + MaxMemory := lim; + end + else lim := PhysicalMemory + 1; + + if not ilm then begin + if (ApproxMemory > {Total}PhysicalMemory) then + begin + if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory1')), 'Apophysis', MB_ICONWARNING or MB_YESNO) then + exit; + end; +{ + if (ApproxMemory > PhysicalMemory) then + begin + if Application.MessageBox('There is not enough memory for this render. ' + #13 + + 'You can use memory limiting, or - if you are sure that your system *should* ' + #13 + + 'have the required amount of free RAM, you can try to allocate memory anyway. ' + #13#13 + + 'Dou you want to try? (SLOW AND UNSTABLE - USE AT YOUR OWN RISK!!!)', 'Apophysis', + MB_ICONWARNING or MB_YESNO) <> IDYES then exit; + end; +} + end + else if (PhysicalMemory < lim) and (Approxmemory > PhysicalMemory) then begin + if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory2')), 'Apophysis', MB_ICONWARNING or MB_YESNO) then + exit; + end; + + t := txtFilename.Text; + if t = '' then + begin + Application.MessageBox(PChar(TextByKey('render-status-nofilename')), 'Apophysis', 48); + Exit; + end; + if FileExists(t) then + if Application.MessageBox(PChar(Format(TextByKey('render-status-fileexists-message1'), [t]) + #13#10 + TextByKey('render-status-fileexists-message2')), + 'Apophysis', 52) = ID_NO then exit; + if not DirectoryExists(ExtractFileDir(t)) then + begin + Application.MessageBox(PChar(TextByKey('render-status-pathdoesnotexist')), 'Apophyis', 16); + exit; + end; + {Check for invalid values } + if sample_density <= 0 then + begin + Application.MessageBox(PChar(TextByKey('render-status-invaliddensity')), 'Apophysis', 16); + exit; + end; + if filter_radius <= 0 then + begin + Application.MessageBox(PChar(TextByKey('render-status-invalidfilterradius')), 'Apophysis', 16); + exit; + end; + if Oversample < 1 then + begin + Application.MessageBox(PChar(TextByKey('render-status-invalidoversample')), 'Apophysis', 16); + exit; + end; + if ImageWidth < 1 then + begin + Application.MessageBox(PChar(TextByKey('render-status-invalidwidth')), 'Apophysis', 16); + exit; + end; + if ImageHeight < 1 then + begin + Application.MessageBox(PChar(TextByKey('render-status-invalidheight')), 'Apophysis', 16); + exit; + end; + if (ilm) then + if lim * 1024*1024 < ImageWidth * (int64(ImageHeight) * 4 + oversample) then begin + // Must be enough memory to hold the final image (RGBA) + if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-maxmemorytoosmall')), 'Apophysis', MB_ICONERROR or MB_YESNO) then + exit; + end; + + txtFilename.Enabled := false; + btnBrowse.Enabled := false; + cbWidth.Enabled := False; + cbHeight.Enabled := false; + txtDensity.Enabled := false; + txtFilterRadius.enabled := false; + txtOversample.Enabled := false; + //chkLimitMem.Enabled := true; + cbMaxMemory.Enabled := false; + //cbBitsPerSample.Enabled := false; + cmbPreset.enabled := false; + chkSave.enabled := false; + chkPostProcess.enabled := false; + chkShutdown.enabled := false; + btnSavePreset.enabled := false; + btnDeletePreset.enabled := false; + btnRender.Enabled := false; + btnSaveLog.Enabled := false; + btnPause.enabled := true; + btnCancel.Caption := TextByKey('common-cancel'); + chkMaintain.Enabled := false; + StartTime := Now; + + SetTaskbarProgressValue( + ProgressBar2.Position - ProgressBar2.Min, + ProgressBar2.Max - ProgressBar2.Min); + SetTaskbarProgressState(tbpsNormal); + + pnlWidth.Enabled := false; + pnlHeight.Enabled := false; + pnlDensity.Enabled := false; + pnlFilter.Enabled := false; + pnlOversample.Enabled := false; + pnlLimit.Enabled := false; + pnlTarget.Enabled := false; + //pnlBufferDepth.Enabled := false; + + pnlWidth.Font.Color := clGrayText; + pnlHeight.Font.Color := clGrayText; + pnlDensity.Font.Color := clGrayText; + pnlFilter.Font.Color := clGrayText; + pnlOversample.Font.Color := clGrayText; + pnlLimit.Font.Color := clGrayText; + pnlTarget.Font.Color := clGrayText; + //pnlBufferDepth.Font.Color := clGrayText; + + PageCtrl.TabIndex := 1; + + if Output.Lines.Count >= 1000 then Output.Lines.Clear; + + if bRenderAll then + begin + path := ExtractFilePath(FileName); + ext := ExtractFileExt(FileName); + + if Assigned(Renderer) then begin + Output.Lines.Add(TimeToStr(Now) + TextByKey('render-status-shuttingdownrender')); + Renderer.Terminate; + Renderer.WaitFor; + Renderer.Free; + Renderer := nil; + end; + + for iCurrFlame := 0 to MainForm.ListView1.Items.Count-1 do + begin + MainForm.ListView1.ItemIndex := iCurrFlame; + cp.Free; + cp := TControlPoint.Create; + cp.Copy(MainCP); + cp.cmap := maincp.cmap; + zoom := maincp.zoom; + Center[0] := MainForm.center[0]; + Center[1] := MainForm.center[1]; + FileName := path + cp.name + ext; + Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + ' ---'); + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight])); + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density])); + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius])); + if SingleBuffer then + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32 bit float'])) + else + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64 bit float'])); + + if (ilm) then + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [MaxMemory])) + else + if (UpperCase(ExtractFileExt(FileName)) = '.PNG') and + (ImageWidth * ImageHeight >= 20000000) then + begin + Output.Lines.Add(TextByKey('render-status-log-largepng-message1')); + Output.Lines.Add(TextByKey('render-status-log-largepng-message2')); + Output.Lines.Add(TextByKey('render-status-log-largepng-message3')); + end; + + if not Assigned(Renderer) then + begin + // disable screensaver + SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0); + + cp.sample_density := Sample_density; + cp.spatial_oversample := Oversample; + cp.spatial_filter_radius := Filter_Radius; + cp.AdjustScale(ImageWidth, ImageHeight); + cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(FileName)) = '.PNG'); + renderPath := ExtractFilePath(Filename); + if chkSave.checked then + MainForm.SaveXMLFlame(cp, ExtractFileName(FileName), renderPath + 'renders7X.flame'); + + oldProg:=0; + oldElapsed:=0; + edt:=0; + ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) ); + + try + + if not bRenderAll then exit; + if iCurrFlame = MainForm.ListView1.Items.Count-1 then bRenderAll := false; + + Renderer := TRenderThread.Create; + assert(Renderer <> nil); +{ + if chkThreadPriority.Checked then + Renderer.SetPriority(tpLower) + else + Renderer.SetPriority(tpNormal); +} + Renderer.ExportBuffer := chkBinary.Checked; + Renderer.BitsPerSample := BitsPerSample; + if (ilm) then + Renderer.MaxMem := lim;//StrToInt(cbMaxMemory.text); + Renderer.OnProgress := OnProgress; + Renderer.TargetHandle := self.Handle; + Renderer.SetCP(cp); + Renderer.Priority := tpLower; + Renderer.NrThreads := NrTreads; + Renderer.Output := Output.Lines; + Renderer.Resume; + if bRenderAll then Renderer.WaitFor; + while Renderer <> nil do Application.ProcessMessages; // wait for HandleThreadCompletion + + except + Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log')); + //Application.MessageBox('Error while rendering!', 'Apophysis', 48); + end; + end; + end; + end else + begin + Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + '" ---'); + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight])); + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density])); + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius])); + + if SingleBuffer then + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32 bit float'])) + else + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64 bit float'])); + + if (ilm) then + Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [lim])) + else + if (UpperCase(ExtractFileExt(FileName)) = '.PNG') and + (ImageWidth * ImageHeight >= 20000000) then + begin + Output.Lines.Add(TextByKey('render-status-log-largepng-message1')); + Output.Lines.Add(TextByKey('render-status-log-largepng-message2')); + Output.Lines.Add(TextByKey('render-status-log-largepng-message3')); + end; + + if Assigned(Renderer) then begin + Output.Lines.Add(TimeToStr(Now) + TextByKey('render-status-shuttingdownrender')); + Renderer.Terminate; + Renderer.WaitFor; + Renderer.Free; + Renderer := nil; + end; + + if not Assigned(Renderer) then + begin + // disable screensaver + SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0); + + cp.sample_density := Sample_density; + cp.spatial_oversample := Oversample; + cp.spatial_filter_radius := Filter_Radius; + cp.AdjustScale(ImageWidth, ImageHeight); + cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(FileName)) = '.PNG'); + renderPath := ExtractFilePath(Filename); + if chkSave.checked then + MainForm.SaveXMLFlame(cp, ExtractFileName(FileName), renderPath + 'renders7X.flame'); + + oldProg:=0; + oldElapsed:=0; + edt:=0; + ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) ); + + try + + Renderer := TRenderThread.Create; + assert(Renderer <> nil); +{ + if chkThreadPriority.Checked then + Renderer.SetPriority(tpLower) + else + Renderer.SetPriority(tpNormal); +} + Renderer.BitsPerSample := BitsPerSample; + if (ilm) then + Renderer.MaxMem := lim;//StrToInt(cbMaxMemory.text); + Renderer.ExportBuffer := chkBinary.Checked; + Renderer.OnProgress := OnProgress; + Renderer.TargetHandle := self.Handle; + // Renderer.Output := Output.Lines; + // Renderer.Compatibility := compatibility; + Renderer.SetCP(cp); + Renderer.Priority := tpLower; + Renderer.NrThreads := NrTreads; + + Renderer.Output := Output.Lines; + Renderer.Resume; + + except + Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log')); + Application.MessageBox(PChar(TextByKey('render-status-rendererror-message')), 'Apophysis', 48); + end; + end; + end; + // enable screensaver + SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0); +end; + +procedure TRenderForm.FormShow(Sender: TObject); +var + Registry: TRegistry; +begin + { Read position from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Render', False) then + begin + if Registry.ValueExists('Left') then + self.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + self.Top := Registry.ReadInteger('Top'); + end; + Registry.CloseKey; + finally + Registry.Free; + end; + + SaveDialog.FileName := Filename; + case renderFileFormat of + 1: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.bmp'); + 2: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.png'); + 3: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.jpg'); + end; + txtOversample.Text := IntToStr(renderOversample); + txtFilterRadius.Text := FloatToStr(renderFilterRadius); + cbWidth.Text := IntToStr(cp.Width); + cbHeight.Text := IntToStr(cp.Height); + ImageWidth := StrToInt(cbWidth.Text); + ImageHeight := StrToInt(cbHeight.Text); + sample_density := renderDensity; + txtDensity.Text := FloatToStr(sample_density); + BitsPerSample := renderBitsPerSample; + ShowMemoryStatus; + Ratio := ImageWidth / ImageHeight; + chkSaveIncompleteRenders.Checked := SaveIncompleteRenders; +end; + +procedure TRenderForm.txtWidthChange(Sender: TObject); +begin + try + ImageWidth := StrToInt(cbWidth.Text); + if chkMaintain.checked and cbWidth.Focused then + begin + ImageHeight := Round(ImageWidth / ratio); + cbHeight.Text := IntToStr(ImageHeight) + end; + except + end; + ShowMemoryStatus; +end; + +procedure TRenderForm.txtHeightChange(Sender: TObject); +begin + try + ImageHeight := StrToInt(cbHeight.Text); + if chkMaintain.checked and cbHeight.Focused then + begin + ImageWidth := Round(ImageHeight * ratio); + cbWidth.Text := IntToStr(ImageWidth) + end; + except + end; + ShowMemoryStatus; +end; + +procedure TRenderForm.txtOversampleChange(Sender: TObject); +var + o: integer; +begin + try + o := StrToInt(txtOversample.Text); + except + txtOversample.Text := IntToStr(Oversample); + exit; + end; + if o > udOversample.Max then + begin + o := udOversample.Max; + txtOversample.Text := IntToStr(o); + end + else if o < udOversample.Min then + begin + o := udOversample.Min; + txtOversample.Text := IntToStr(o); + end; + Oversample := o; + ShowMemoryStatus; +end; + +procedure TRenderForm.txtFilenameChange(Sender: TObject); +var + ext : string; +begin + filename := txtFilename.text; + ext := LowerCase(ExtractFileExt(filename)); +end; + +procedure TRenderForm.btnCancelClick(Sender: TObject); +begin + if Assigned(Renderer) or bRenderAll then + begin + if Assigned(Renderer) then + if Renderer.Suspended then begin + Renderer.Resume; + btnPause.caption := TextByKey('common-pause'); + end; + + if ConfirmStopRender then begin + if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then exit; + end; + + bRenderAll := false; + if Assigned(Renderer) then + if SaveIncompleteRenders and (not IsLimitingMemory) then + begin + Renderer.BreakRender; + Renderer.WaitFor; //? + end else + begin + Renderer.Terminate; + Renderer.WaitFor; //? + PageCtrl.TabIndex := 0; + end; + SetTaskbarProgressValue( + ProgressBar2.Position - ProgressBar2.Min, + ProgressBar2.Max - ProgressBar2.Min); + SetTaskbarProgressState(tbpsNone); + end else + Close; +end; + +procedure TRenderForm.txtDensityChange(Sender: TObject); +var + t: double; +begin + if TryStrToFloat(txtDensity.Text, t) then + Sample_Density := t; + if Sample_Density > 0 then ShowMemoryStatus; +end; + +procedure TRenderForm.txtFilterRadiusChange(Sender: TObject); +begin + try + Filter_Radius := StrToFloat(txtFilterRadius.Text); + except + end; +end; + +procedure TRenderForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Ext: string; + Registry: TRegistry; +begin + Ext := ExtractFileExt(txtFileName.Text); + if Ext = '.bmp' then renderFileFormat := 1; + if Ext = '.png' then renderFileFormat := 2; + if (Ext = '.jpg') or (Ext = '.jpeg') then renderFileFormat := 3; + renderFilterRadius := Filter_Radius; + renderWidth := ImageWidth; + renderHeight := ImageHeight; + renderDensity := Sample_density; + renderOversample := Oversample; + renderBitsPerSample := BitsPerSample; + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Render', True) then + begin + Registry.WriteInteger('Top', Top); + Registry.WriteInteger('Left', Left); + end; + finally + Registry.Free; + end; +end; + +procedure TRenderForm.btnPauseClick(Sender: TObject); +begin + if Assigned(Renderer) then + if Renderer.Suspended = false then begin + renderer.Suspend; + btnPause.caption := TextByKey('common-resume'); + SetTaskbarProgressState(tbpsPaused); + end else begin + renderer.Resume; + btnPause.caption := TextByKey('common-pause'); + SetTaskbarProgressState(tbpsNormal); + end; +end; + +procedure TRenderForm.FormCloseQuery(Sender: TObject; + var CanClose: Boolean); +begin + if Assigned(Renderer) then + if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then + CanClose := False + else + begin + if Assigned(Renderer) then begin + Renderer.Terminate; + Renderer.WaitFor; + end; + end; +end; + +procedure TRenderForm.btnSavePresetClick(Sender: TObject); +var + IFile: TextFile; + Title, Filename: string; +begin + SavePresetForm.txtPresetName.Text := cmbPreset.Text; + if SavePresetForm.ShowModal = mrOK then + begin + Title := Trim(SavePresetForm.txtPresetName.Text); + Filename := AppPath + 'render presets'; + try + AssignFile(IFile, FileName); + if FileExists(FileName) then + begin + if EntryExists(Title, FileName) then DeleteEntry(Title, FileName); + Append(IFile); + end + else + ReWrite(IFile); + WriteLn(IFile, Title + ' {'); + WriteLn(IFile, Trim(cbWidth.text)); + WriteLn(IFile, Trim(cbHeight.text)); + WriteLn(IFile, Trim(txtDensity.text)); + WriteLn(IFile, Trim(txtFilterRadius.text)); + WriteLn(IFile, Trim(txtOversample.text)); + WriteLn(IFile, ExtractFileExt(txtFileName.Text)); + if (not IsLimitingMemory) then + WriteLn(IFile, 'true') + else + WriteLn(IFile, 'false'); + WriteLn(IFile, IntToStr(cbMaxMemory.ItemIndex)); + WriteLn(IFile, cbMaxMemory.Text); + WriteLn(IFile, '}'); + WriteLn(IFile, ''); + CloseFile(IFile); + except on EInOutError do + begin + Application.MessageBox('Cannot save preset.', 'Apophysis', 16); + Exit; + end; + end; + ListPresets; + cmbPreset.ItemIndex := cmbPreset.Items.count - 1; + end; +end; + +procedure TRenderForm.btnBrowseClick(Sender: TObject); +var + fn:string; + ext:string; + sl:TStringList; +begin + SaveDialog.Filename := Filename; + case renderFileFormat of + 1: SaveDialog.DefaultExt := 'bmp'; + 2: SaveDialog.DefaultExt := 'png'; + 3: SaveDialog.DefaultExt := 'jpg'; + end; + SaveDialog.filterIndex := renderFileFormat; + SaveDialog.Filter := Format('%s|*.bmp;*.dib;*.jpg;*.jpeg|%s|*.bmp;*.dib|%s|*.jpg;*.jpeg|%s|*.png|%s|*.*', + [TextByKey('common-filter-allimages'), TextByKey('common-filter-bitmap'), + TextByKey('common-filter-jpeg'), TextByKey('common-filter-png'), + TextByKey('common-filter-allfiles')]); + if OpenSaveFileDialog(RenderForm, SaveDialog.DefaultExt, SaveDialog.Filter, SaveDialog.InitialDir, TextByKey('common-browse'), fn, false, true, false, false) then + //if SaveDialog.Execute then + begin + SaveDialog.FileName := fn; + ext := LowerCase(ExtractFileExt(fn)); + if (ext = '.bmp') then renderFileFormat := 1; + if (ext = '.png') then renderFileFormat := 2; + if ((ext = '.jpg') or (ext = '.jpeg')) then renderFileFormat := 3; + {case SaveDialog.FilterIndex of + 1: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.bmp'); + 2: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.png'); + 3: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.jpg'); + end; } + txtFileName.Text := ChangeFileExt(fn, ext); + //renderFileFormat := SaveDialog.FilterIndex; + renderPath := ExtractFilePath(SaveDialog.Filename); + + end; +end; + +procedure TRenderForm.ListPresets; +{ List identifiers in file } +var + i, p: integer; + Title: string; + FStrings: TStringList; + f: textfile; +begin + FStrings := TStringList.Create; + try + if fileExists(AppPath + 'render presets') then begin + FStrings.LoadFromFile(AppPath + 'render presets'); + cmbPreset.Clear; + if (Pos('{', FStrings.Text) <> 0) then begin + for i := 0 to FStrings.Count - 1 do begin + p := Pos('{', FStrings[i]); + if (p <> 0) then begin + Title := Trim(Copy(FStrings[i], 1, p - 1)); + if Title <> '' then begin + cmbPreset.Items.add(Copy(FStrings[i], 1, p - 1)); + end; + end; + end; + end; + end; + finally + FStrings.Free; + end; +end; + +procedure TRenderForm.btnDeletePresetClick(Sender: TObject); +var + Title, Filename: string; +begin + Title := Trim(cmbPreset.Text); + if Title = '' then exit; + Filename := AppPath + 'render presets'; + if EntryExists(Title, FileName) then DeleteEntry(Title, FileName); + ListPresets; +end; + +procedure TRenderForm.cmbPresetChange(Sender: TObject); +var + chk: boolean; + i, j: integer; + FStrings: TStringList; + Title, Filename: string; +begin + Title := Trim(cmbPreset.Text); + Filename := AppPath + 'render presets'; + if Title = '' then exit; + if EntryExists(Title, FileName) then + begin + // Load preset + FStrings := TStringList.Create; + try + FStrings.LoadFromFile(Filename); + for i := 0 to FStrings.Count - 1 do + if Pos(LowerCase(Title) + ' {', Lowercase(FStrings[i])) <> 0 then + begin + chk := chkMaintain.checked; + chkMaintain.Checked := False; + j := i + 1; + cbWidth.Text := FStrings[j]; + inc(j); + cbHeight.text := FStrings[j]; + chkMaintain.Checked := chk; + inc(j); + txtDensity.text := FStrings[j]; + inc(j); + txtFilterRadius.text := FStrings[j]; + inc(j); + txtOversample.text := FStrings[j]; + inc(j); + txtFileName.Text := ChangeFileExt(txtFileName.Text, FStrings[j]); + inc(j); + //if Fstrings[j] = 'true' then (not IsLimitingMemory) else chkLimitMem.checked := false; + inc(j); + cbMaxMemory.ItemIndex := StrToInt(Fstrings[j]); + //cbMaxMemory.enabled := chkLimitMem.checked; + inc(j); + cbMaxMemory.Text := Fstrings[j]; + break; + end; + finally + FStrings.Free; + end + end; + ImageWidth := StrToInt(cbWidth.Text); + ImageHeight := StrToInt(cbHeight.Text); + Sample_Density := StrToFloat(txtDensity.Text); + ShowMemoryStatus; +end; + +procedure TRenderForm.chkMaintainClick(Sender: TObject); +begin + Ratio := ImageWidth / ImageHeight; +end; + +procedure TRenderForm.DoPostProcess; +begin + frmPostProcess.cp := cp; + frmPostProcess.SetRenderer(Renderer.GetRenderer); + frmPostProcess.SetControlPoint(CP); + frmPostProcess.SetImageName(FileName); + frmPostProcess.Show; +end; + +function TRenderForm.WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean; +var + TTokenHd: THandle; + TTokenPvg: TTokenPrivileges; + cbtpPrevious: DWORD; + rTTokenPvg: TTokenPrivileges; + pcbtpPreviousRequired: DWORD; + tpResult: Boolean; +const + SE_SHUTDOWN_NAME = 'SeShutdownPrivilege'; +begin + if ((GetWinVersion = wvWinNT) or + (GetWinVersion = wvWin2000) or + (GetWinVersion = wvWinXP) or + (GetWinVersion = wvWinVista) or + (GetWinVersion = wvWin7) or + (GetWinVersion = wvWinFutureFromOuterSpace)) then + begin + tpResult := OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, + TTokenHd); + if tpResult then + begin + tpResult := LookupPrivilegeValue(nil, + SE_SHUTDOWN_NAME, + TTokenPvg.Privileges[0].Luid); + TTokenPvg.PrivilegeCount := 1; + TTokenPvg.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; + cbtpPrevious := SizeOf(rTTokenPvg); + pcbtpPreviousRequired := 0; + if tpResult then + Windows.AdjustTokenPrivileges(TTokenHd, + False, + TTokenPvg, + cbtpPrevious, + rTTokenPvg, + pcbtpPreviousRequired); + end; + end; + Result := ExitWindowsEx(RebootParam, 0); +end; + +procedure TRenderForm.chkSaveIncompleteRendersClick(Sender: TObject); +begin + SaveIncompleteRenders := chkSaveIncompleteRenders.Checked; +end; + +procedure TRenderForm.btnGoToClick(Sender: TObject); +var + path:string; +begin + path := ExtractFilePath(txtFilename.Text); + if (path <> '') then WinShellExecute('open', path); +end; + + +procedure TRenderForm.cbMaxMemoryChange(Sender: TObject); +begin + //cbMaxMemory.enabled := IsLimitingMemory; + chkPostProcess.Enabled := not IsLimitingMemory; + chkSaveIncompleteRenders.Enabled := not IsLimitingMemory; + //btnRender.Enabled := (ApproxMemory <= PhysicalMemory) or (cbMaxMemory.ItemIndex > 0); +end; + +procedure TRenderForm.btnSaveLogClick(Sender: TObject); +var fn: string; sl: TStringList; +begin + if OpenSaveFileDialog(RenderForm, '.log', + Format('Render-Log (*.txt;*.log)|*.txt;*.log|%s|*.*', [TextByKey('common-filter-allfiles')]), + SaveDialog.InitialDir, TextByKey('common-browse'), fn, false, true, false, false) + then begin + sl := TStringList.Create; + sl.Text := Output.Text; + sl.SaveToFile(fn); + sl.Destroy; + end; +end; + +end. + diff --git a/Forms/Fullscreen.dfm b/Forms/Fullscreen.dfm new file mode 100644 index 0000000..d21c90d --- /dev/null +++ b/Forms/Fullscreen.dfm @@ -0,0 +1,59 @@ +object FullscreenForm: TFullscreenForm + Left = 439 + Top = 325 + BorderStyle = bsNone + Caption = 'FullscreenForm' + ClientHeight = 131 + ClientWidth = 186 + Color = clBlack + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + PopupMenu = FullscreenPopup + OnClose = FormClose + OnCreate = FormCreate + OnDblClick = ImageDblClick + OnDestroy = FormDestroy + OnKeyPress = FormKeyPress + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Image: TImage + Left = 0 + Top = 0 + Width = 186 + Height = 131 + PopupMenu = FullscreenPopup + OnDblClick = ImageDblClick + end + object Timelimiter: TTimer + Enabled = False + Interval = 2000 + OnTimer = TimelimiterOnTimer + Left = 8 + Top = 8 + end + object FullscreenPopup: TPopupMenu + Left = 40 + Top = 8 + object RenderStop: TMenuItem + Caption = '&Stop Render' + OnClick = RenderStopClick + end + object RenderMore: TMenuItem + Caption = 'Render &More' + ShortCut = 114 + OnClick = RenderMoreClick + end + object N1: TMenuItem + Caption = '-' + end + object Exit1: TMenuItem + Caption = '&Close' + OnClick = ImageDblClick + end + end +end diff --git a/Forms/Fullscreen.pas b/Forms/Fullscreen.pas new file mode 100644 index 0000000..ea34c56 --- /dev/null +++ b/Forms/Fullscreen.pas @@ -0,0 +1,343 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Fullscreen; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + Menus, ExtCtrls, ControlPoint, RenderThread, Translation; + +type + TFullscreenForm = class(TForm) + Image: TImage; + Timelimiter: TTimer; + FullscreenPopup: TPopupMenu; + RenderStop: TMenuItem; + N1: TMenuItem; + Exit1: TMenuItem; + RenderMore: TMenuItem; + procedure FormShow(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormKeyPress(Sender: TObject; var Key: Char); + procedure ImageDblClick(Sender: TObject); + procedure TimelimiterOnTimer(Sender: TObject); + procedure RenderStopClick(Sender: TObject); + procedure RenderMoreClick(Sender: TObject); + + private + Remainder, StartTime, t: double; + imgLeft, imgTop, + imgWidth, imgHeight: integer; + Closing: boolean; + + Renderer: TRenderThread; + + procedure showTaskbar; + procedure hideTaskbar; + procedure DrawFlame; + procedure OnProgress(prog: double); + procedure HandleThreadCompletion(var Message: TMessage); + message WM_THREAD_COMPLETE; + procedure HandleThreadTermination(var Message: TMessage); + message WM_THREAD_TERMINATE; + + public + Calculate : boolean; + cp: TControlPoint; + Zoom: double; + center: array[0..1] of double; + + ActiveForm: TForm; + end; + +var + FullscreenForm: TFullscreenForm; + +implementation + +uses + Main, Math, Global, + Tracer; + +{$R *.DFM} + +procedure Trace1(const str: string); +begin + if TraceLevel >= 1 then + TraceForm.FullscreenTrace.Lines.Add('. ' + str); +end; + +procedure Trace2(const str: string); +begin + if TraceLevel >= 2 then + TraceForm.FullscreenTrace.Lines.Add('. . ' + str); +end; + +procedure TFullscreenForm.DrawFlame; +var + r: double; +begin + if (cp.width / cp.height) > (ClientWidth / ClientHeight) then + begin + imgWidth := ClientWidth; + r := cp.width / imgWidth; + imgHeight := round(cp.height / r); + imgLeft := 1; + imgTop := (ClientHeight - imgHeight) div 2; + end + else begin + imgHeight := ClientHeight; + r := cp.height / imgHeight; + imgWidth := round(cp.Width / r); + imgTop := 1; + imgLeft := (ClientWidth - ImgWidth) div 2; + end; + cp.AdjustScale(imgWidth, imgHeight); + +// cp.Zoom := MainForm.Zoom; +// cp.center[0] := MainForm.center[0]; +// cp.center[1] := MainForm.center[1]; + cp.sample_density := defSampleDensity; + StartTime := Now; + t := now; + Remainder := 1; + + if Assigned(Renderer) then begin // hmm... + Trace2('Killing previous RenderThread #' + inttostr(Renderer.ThreadID)); + Renderer.Terminate; + Renderer.WaitFor; + + while Renderer <> nil do + Application.ProcessMessages; // HandleThreadTermination kinda should be called here...(?) + end; + + assert(not assigned(renderer), 'Render thread is still running!?'); + + Renderer := TRenderThread.Create; // Hmm... Why do we use RenderThread here, anyway? :-\ + Renderer.TargetHandle := Handle; + Renderer.OnProgress := OnProgress; + Renderer.NrThreads := NrTreads; + if TraceLevel > 0 then Renderer.Output := TraceForm.FullscreenTrace.Lines; + Renderer.SetCP(cp); + + Renderer.WaitForMore := true; + RenderStop.Enabled := true; + RenderMore.Enabled := false; + + Renderer.Resume; +end; + +procedure TFullscreenForm.HandleThreadCompletion(var Message: TMessage); +var + bm: TBitmap; +begin + Trace2(MsgComplete + IntToStr(message.LParam)); + if not Assigned(Renderer) then begin + Trace2(MsgNotAssigned); + exit; + end; + if Renderer.ThreadID <> message.LParam then begin + Trace2(MsgAnotherRunning); + exit; + end; + + if Assigned(Renderer) then + begin + bm := TBitmap.Create; + bm.assign(Renderer.GetImage); + Image.SetBounds(imgLeft, imgTop, imgWidth, imgHeight); + Image.Picture.Graphic := bm; + bm.Free; + end; + + RenderStop.Enabled := false; + RenderMore.Enabled := true; + + TimeLimiter.Enabled := false; +end; + +procedure TFullscreenForm.HandleThreadTermination(var Message: TMessage); +var + bm: TBitmap; +begin + Trace2(MsgTerminated + IntToStr(message.LParam)); + if not Assigned(Renderer) then begin + Trace2(MsgNotAssigned); + exit; + end; + if Renderer.ThreadID <> message.LParam then begin + Trace2(MsgAnotherRunning); + exit; + end; + + RenderStop.Enabled := false; + RenderMore.Enabled := false; + + TimeLimiter.Enabled := false; +end; + +procedure TFullscreenForm.OnProgress(prog: double); +begin + prog := (Renderer.Slice + Prog) / Renderer.NrSlices; + Canvas.Lock; + try + if prog >= 1 then + begin + Canvas.Brush.Color := clBlack; + Canvas.FillRect(Rect(5, ClientHeight - 15, ClientWidth - 5, ClientHeight - 5)); + end + else if prog >= 0 then begin + Canvas.Brush.Color := clTeal; + Canvas.FrameRect(Rect(5, ClientHeight - 15, ClientWidth - 5, ClientHeight - 5)); + Canvas.Brush.Color := clTeal; + Canvas.Fillrect(Rect(7, ClientHeight - 13, 7 + Round(prog * (ClientWidth - 14)), ClientHeight - 7)); + Canvas.Brush.Color := clBlack; + Canvas.Fillrect(Rect(7 + Round(prog * (ClientWidth - 14)), ClientHeight - 13, ClientWidth - 7, ClientHeight - 7)); + end; + finally + Canvas.Unlock; + end; + //Application.ProcessMessages; +end; + +procedure TFullscreenForm.hideTaskbar; +var wndHandle: THandle; + wndClass: array[0..50] of Char; +begin + StrPCopy(@wndClass[0], 'Shell_TrayWnd'); + wndHandle := FindWindow(@wndClass[0], nil); + ShowWindow(wndHandle, SW_HIDE); +end; + +procedure TFullscreenForm.showTaskbar; +var wndHandle: THandle; + wndClass: array[0..50] of Char; +begin + StrPCopy(@wndClass[0], 'Shell_TrayWnd'); + wndHandle := FindWindow(@wndClass[0], nil); + ShowWindow(wndHandle, SW_RESTORE); +end; + +procedure TFullscreenForm.FormShow(Sender: TObject); +begin + Trace1('--- Opening Fullscreen View ---'); + + if Image.Width < ClientWidth then + Image.Left := (ClientWidth - Image.Width) div 2; + if Image.Height < ClientHeight then + Image.Top := (ClientHeight - Image.Height) div 2; + + Closing := false; + TimeLimiter.Enabled := false; + + RenderStop.Enabled := false; + RenderMore.Enabled := false; + + MainForm.mnuFullScreen.enabled := true; + HideTaskbar; + + if calculate then + DrawFlame; +end; + +procedure TFullscreenForm.FormClose(Sender: TObject; + var Action: TCloseAction); +begin + Closing := true; + if Assigned(Renderer) then begin + if Renderer.Suspended then begin + Renderer.WaitForMore := false; + Renderer.Resume; + end; + Trace2('Form closing: killing RenderThread #' + inttostr(Renderer.ThreadID)); + Renderer.Terminate; + Renderer.WaitFor; + + Trace2('Destroying RenderThread #' + IntToStr(Renderer.ThreadID)); + Renderer.Free; + Renderer := nil; + end; + Trace1('--- Closing Fullscreen View ---'); + Trace1(''); + ShowTaskbar; + + ActiveForm.SetFocus; +end; + +procedure TFullscreenForm.FormCreate(Sender: TObject); +begin + Exit1.Caption := TextByKey('common-close'); + RenderMore.Caption := TextByKey('fullscreen-popup-rendermore'); + RenderStop.Caption := TextByKey('fullscreen-popup-stoprender'); + cp := TControlPoint.Create; +end; + +procedure TFullscreenForm.FormDestroy(Sender: TObject); +begin + if assigned(Renderer) then begin + Renderer.Terminate; + Renderer.WaitFor; + Renderer.Free; + end; + cp.Free; +end; + +procedure TFullscreenForm.FormKeyPress(Sender: TObject; var Key: Char); +begin + if key = ' ' then begin + if RenderStop.Enabled then RenderStop.Click + else if RenderMore.Enabled then RenderMore.Click; + end + else Close; +end; + +procedure TFullscreenForm.ImageDblClick(Sender: TObject); +begin + Close; +end; + +procedure TFullscreenForm.TimelimiterOnTimer(Sender: TObject); +begin + //if assigned(Renderer) then Renderer.Break; + TimeLimiter.Enabled := false; +end; + +procedure TFullscreenForm.RenderStopClick(Sender: TObject); +begin + if assigned(Renderer) then Renderer.BreakRender; +end; + +procedure TFullscreenForm.RenderMoreClick(Sender: TObject); +begin + if assigned(Renderer) and Renderer.Suspended then begin + Renderer.Resume; + RenderStop.Enabled := true; + RenderMore.Enabled := false; + end; +end; + +end. + diff --git a/Forms/ImageColoring.dfm b/Forms/ImageColoring.dfm new file mode 100644 index 0000000..4942671 --- /dev/null +++ b/Forms/ImageColoring.dfm @@ -0,0 +1,315 @@ +object frmImageColoring: TfrmImageColoring + Left = 419 + Top = 408 + Width = 581 + Height = 365 + Caption = 'Image coloring' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + PixelsPerInch = 96 + TextHeight = 13 + object Label1: TLabel + Left = 16 + Top = 40 + Width = 54 + Height = 13 + Caption = 'First Palete' + end + object Label2: TLabel + Left = 16 + Top = 168 + Width = 72 + Height = 13 + Caption = 'Second palette' + end + object Label3: TLabel + Left = 296 + Top = 36 + Width = 30 + Height = 13 + Caption = 'Image' + end + object Label4: TLabel + Left = 16 + Top = 107 + Width = 57 + Height = 13 + Alignment = taCenter + AutoSize = False + Caption = 'Preset' + end + object Label5: TLabel + Left = 16 + Top = 235 + Width = 57 + Height = 13 + Alignment = taCenter + AutoSize = False + Caption = 'Preset' + end + object cbEnable: TCheckBox + Left = 16 + Top = 8 + Width = 133 + Height = 17 + Caption = 'Enable image coloring' + TabOrder = 0 + end + object Panel1: TPanel + Left = 16 + Top = 56 + Width = 258 + Height = 40 + BevelOuter = bvLowered + TabOrder = 1 + object imgPal1: TImage + Left = 1 + Top = 1 + Width = 256 + Height = 38 + Align = alClient + Stretch = True + end + end + object Panel2: TPanel + Left = 16 + Top = 188 + Width = 258 + Height = 40 + BevelOuter = bvLowered + TabOrder = 2 + object imgpal2: TImage + Left = 1 + Top = 1 + Width = 256 + Height = 38 + Align = alClient + Stretch = True + end + end + object Panel3: TPanel + Left = 292 + Top = 60 + Width = 258 + Height = 258 + BevelOuter = bvLowered + TabOrder = 3 + end + object cmbPalette1: TComboBox + Left = 80 + Top = 106 + Width = 177 + Height = 19 + Style = csOwnerDrawFixed + Color = clBlack + DropDownCount = 20 + Font.Charset = ANSI_CHARSET + Font.Color = clWhite + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ItemHeight = 13 + ParentFont = False + ParentShowHint = False + ShowHint = False + TabOrder = 4 + OnChange = cmbPalette1Change + OnDrawItem = cmbPalette1DrawItem + Items.Strings = ( + 'south-sea-bather' + 'sky-flesh' + 'blue-bather' + 'no-name' + 'pillows' + 'mauve-splat' + 'facial-treescape 6' + 'fasion-bug' + 'leafy-face' + 'mouldy-sun' + 'sunny-harvest' + 'peach-tree' + 'fire-dragon' + 'ice-dragon' + 'german-landscape' + 'no-name' + 'living-mud-bomb' + 'cars' + 'unhealthy-tan' + 'daffodil' + 'rose' + 'healthy-skin' + 'orange' + 'white-ivy' + 'summer-makeup' + 'glow-buzz' + 'deep-water' + 'afternoon-beach' + 'dim-beach' + 'cloudy-brick' + 'burning-wood' + 'aquatic-garden' + 'no-name' + 'fall-quilt' + 'night-blue-sky' + 'shadow-iris' + 'solid-sky' + 'misty-field' + 'wooden-highlight' + 'jet-tundra' + 'pastel-lime' + 'hell' + 'indian-coast' + 'dentist-decor' + 'greenland' + 'purple-dress' + 'no-name' + 'spring-flora' + 'andi' + 'gig-o835' + 'rie02' + 'rie05' + 'rie11' + 'etretat.ppm' + 'the-hollow-needle-at-etretat.ppm' + 'rouen-cathedral-sunset.ppm' + 'the-houses-of-parliament.ppm' + 'starry-night.ppm' + 'water-lilies-sunset.ppm' + 'gogh.chambre-arles.ppm' + 'gogh.entrance.ppm' + 'gogh.the-night-cafe.ppm' + 'gogh.vegetable-montmartre.ppm' + 'matisse.bonheur-vivre.ppm' + 'matisse.flowers.ppm' + 'matisse.lecon-musique.ppm' + 'modigliani.nude-caryatid.ppm' + 'braque.instruments.ppm' + 'calcoast09.ppm' + 'dodge102.ppm' + 'ernst.anti-pope.ppm' + 'ernst.ubu-imperator.ppm' + 'fighting-forms.ppm' + 'fog25.ppm' + 'geyser27.ppm' + 'gris.josette.ppm' + 'gris.landscape-ceret.ppm' + 'kandinsky.comp-9.ppm' + 'kandinsky.yellow-red-blue.ppm' + 'klee.insula-dulcamara.ppm' + 'nile.ppm' + 'picasso.jfille-chevre.ppm' + 'pollock.lavender-mist.ppm' + 'yngpaint.ppm') + end + object cmbPalette2: TComboBox + Left = 80 + Top = 234 + Width = 177 + Height = 19 + Style = csOwnerDrawFixed + Color = clBlack + DropDownCount = 20 + Font.Charset = ANSI_CHARSET + Font.Color = clWhite + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ItemHeight = 13 + ParentFont = False + ParentShowHint = False + ShowHint = False + TabOrder = 5 + OnChange = cmbPalette2Change + OnDrawItem = cmbPalette1DrawItem + Items.Strings = ( + 'south-sea-bather' + 'sky-flesh' + 'blue-bather' + 'no-name' + 'pillows' + 'mauve-splat' + 'facial-treescape 6' + 'fasion-bug' + 'leafy-face' + 'mouldy-sun' + 'sunny-harvest' + 'peach-tree' + 'fire-dragon' + 'ice-dragon' + 'german-landscape' + 'no-name' + 'living-mud-bomb' + 'cars' + 'unhealthy-tan' + 'daffodil' + 'rose' + 'healthy-skin' + 'orange' + 'white-ivy' + 'summer-makeup' + 'glow-buzz' + 'deep-water' + 'afternoon-beach' + 'dim-beach' + 'cloudy-brick' + 'burning-wood' + 'aquatic-garden' + 'no-name' + 'fall-quilt' + 'night-blue-sky' + 'shadow-iris' + 'solid-sky' + 'misty-field' + 'wooden-highlight' + 'jet-tundra' + 'pastel-lime' + 'hell' + 'indian-coast' + 'dentist-decor' + 'greenland' + 'purple-dress' + 'no-name' + 'spring-flora' + 'andi' + 'gig-o835' + 'rie02' + 'rie05' + 'rie11' + 'etretat.ppm' + 'the-hollow-needle-at-etretat.ppm' + 'rouen-cathedral-sunset.ppm' + 'the-houses-of-parliament.ppm' + 'starry-night.ppm' + 'water-lilies-sunset.ppm' + 'gogh.chambre-arles.ppm' + 'gogh.entrance.ppm' + 'gogh.the-night-cafe.ppm' + 'gogh.vegetable-montmartre.ppm' + 'matisse.bonheur-vivre.ppm' + 'matisse.flowers.ppm' + 'matisse.lecon-musique.ppm' + 'modigliani.nude-caryatid.ppm' + 'braque.instruments.ppm' + 'calcoast09.ppm' + 'dodge102.ppm' + 'ernst.anti-pope.ppm' + 'ernst.ubu-imperator.ppm' + 'fighting-forms.ppm' + 'fog25.ppm' + 'geyser27.ppm' + 'gris.josette.ppm' + 'gris.landscape-ceret.ppm' + 'kandinsky.comp-9.ppm' + 'kandinsky.yellow-red-blue.ppm' + 'klee.insula-dulcamara.ppm' + 'nile.ppm' + 'picasso.jfille-chevre.ppm' + 'pollock.lavender-mist.ppm' + 'yngpaint.ppm') + end +end diff --git a/Forms/ImageColoring.pas b/Forms/ImageColoring.pas new file mode 100644 index 0000000..40f34f5 --- /dev/null +++ b/Forms/ImageColoring.pas @@ -0,0 +1,161 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit ImageColoring; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, ExtCtrls, StdCtrls, cmap; + +type + TfrmImageColoring = class(TForm) + cbEnable: TCheckBox; + Panel1: TPanel; + Panel2: TPanel; + Panel3: TPanel; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + cmbPalette1: TComboBox; + Label4: TLabel; + imgPal1: TImage; + imgpal2: TImage; + Label5: TLabel; + cmbPalette2: TComboBox; + procedure cmbPalette2Change(Sender: TObject); + procedure cmbPalette1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); + procedure cmbPalette1Change(Sender: TObject); + private + FPal1: TColorMap; + FPal2: TColorMap; + FBkuPal1: TColorMap; + FBkuPal2: TColorMap; + Index1: integer; + Index2: integer; + + procedure DrawPalette1; + procedure DrawPalette2; + + procedure Apply; + public + procedure Update; override; + end; + +var + frmImageColoring: TfrmImageColoring; + +implementation + +{$R *.dfm} + +uses + Main, Editor, Mutate, GradientHlpr; + +{ TfrmImageColoring } + +procedure TfrmImageColoring.Update; +begin +// FPal1 := MainCP.Pal; + FBkuPal1 := FPal1; +end; + +procedure TfrmImageColoring.cmbPalette1Change(Sender: TObject); +begin + Index1 := cmbPalette1.ItemIndex; + GetCmap(Index1, 1, FPal1); + FBkuPal1 := FPal1; +// ScrollBar.Position := 0; + DrawPalette1; + Apply; +end; + +procedure TfrmImageColoring.Apply; +begin + MainForm.StopThread; + MainForm.UpdateUndo; + + MainCp.CmapIndex := cmbPalette1.ItemIndex; + MainCp.cmap := FPal1; + + if EditForm.visible then EditForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + + MainForm.RedrawTimer.enabled := true; +end; + +procedure TfrmImageColoring.cmbPalette1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); +var + Bitmap: TBitmap; + PalName: string; +begin + BitMap := GradientHelper.GetGradientBitmap(Index, 1); + + GetCmapName(index, PalName); + + with Control as TComboBox do begin + Canvas.Rectangle(Rect); + + Canvas.TextOut(4, Rect.Top, PalName); + Rect.Left := (Rect.Left + rect.Right) div 2; + Canvas.StretchDraw(Rect, Bitmap); + end; + BitMap.Free; +end; + +procedure TfrmImageColoring.DrawPalette1; +var + Bitmap: TBitmap; +begin + BitMap := GradientHelper.GetGradientBitmap(Index1, 1); + + imgPal1.Picture.Graphic := Bitmap; + imgPal1.Refresh; + + BitMap.Free; +end; + +procedure TfrmImageColoring.DrawPalette2; +var + Bitmap: TBitmap; +begin + BitMap := GradientHelper.GetGradientBitmap(Index2, 1); + + imgPal2.Picture.Graphic := Bitmap; + imgPal2.Refresh; + + BitMap.Free; +end; + +procedure TfrmImageColoring.cmbPalette2Change(Sender: TObject); +begin + Index2 := cmbPalette2.ItemIndex; + GetCmap(Index2, 1, FPal2); + FBkuPal2 := FPal2; +// ScrollBar.Position := 0; + DrawPalette2; + Apply; +end; + +end. diff --git a/Forms/LoadTracker.dfm b/Forms/LoadTracker.dfm new file mode 100644 index 0000000..b208e6f --- /dev/null +++ b/Forms/LoadTracker.dfm @@ -0,0 +1,120 @@ +object LoadForm: TLoadForm + Left = 443 + Top = 274 + ActiveControl = Button1 + Anchors = [akLeft, akTop, akRight, akBottom] + Caption = 'Messages' + ClientHeight = 388 + ClientWidth = 662 + Color = clBtnFace + Constraints.MinHeight = 275 + Constraints.MinWidth = 550 + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + FormStyle = fsStayOnTop + Icon.Data = { + 0000010001001010000001002000680400001600000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000006349 + 35146349352E927A69FF8C7563FF87705EFF6349352E7F6654FF7A624FFF755D + 4AFF6349352E6E5441FF6A513EFF674E3AFF6349352E00000000000000006349 + 352EAE9888FFEFE3DDFFF2E7E1FFEDDFD7FF836B59FFB79B8BFFDBBDADFFD9B7 + A6FF725946FFAE8B77FFD0A692FFCC9E87FF654B38FF6349352E00000000B7A2 + 93FFFBF8F7FFF9F4F2FFF7F0ECFFF4EBE6FFF1E5DFFF7F6754FF7A624FFF765D + 4AFF735946FF6E5542FF6B523EFF674E3AFF654B38FF634935FF00000000B7A2 + 93FFFDFCFBFFFBF9F7FFFAF5F2FFF7EFEDFFF4EAE6FFF2E5DFFFDDDCD7FFDFD7 + CEFFDECDC0FFDEC5B6FFDEBFACFFDBBAA6FFD8B5A3FF634935FF00000000B7A2 + 93FFFFFFFFFFB47F65FFB47F64FFEDDDD5FFB37E63FFF4EBE6FFF1E5DFFFEFDF + D7FFEBD9D1FFE8D3C9FFE5CDC1FFE1C6B9FFD6B3A1FF634A35FF00000000B9A4 + 95FFFFFFFFFFFFFFFFFFFDFCFCFFFCF9F7FFFAF4F2FFF6F0ECFFF4EBE5FFF2E5 + DFFFEEDFD8FFEBD9D0FFE8D3C8FFE5CCC1FFDBBDADFF634A36FF00000000BDA7 + 98FFFFFFFFFF968E88FFEEDED7FF968E87FFEDDDD6FF968D86FF958C85FFF4EB + E6FFF2E5DFFFEFDFD8FFECD9D0FFE8D3C9FFE0C7BAFF634A35FF00000000C1AB + 9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFCFFFBF8F7FFFAF4F2FFF7F0 + ECFFF4EAE6FFF1E5DFFFEEDFD7FFEBD9D0FFE6D1C6FF634A35FF00000000C5AF + A0FFFFFFFFFFB48065FFB48065FF968E88FFC2B0A3FF968E87FF968E86FFF9F4 + F2FFF7EFECFFF4EBE6FFF2E5DFFFEFDFD8FFEADBD1FF634936FF00000000C8B2 + A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFCFFFCF8 + F7FFF9F5F2FFF7F0ECFFF4EBE6FFF1E5DFFFEEE2DAFF644A36FF00000000C9B4 + A5FFFFFFFFFFFFFFFFFF66A365FF66A365FF66A365FFC0B4ADFF66A365FF66A3 + 65FF66A264FFFAF5F2FFF7F0ECFFF4EBE6FFEEE2DAFF644A36FF00000000C8B2 + A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFEFCFBFFFBF9F7FFFAF4F2FFF7F0EDFFF3EAE4FF644A36FF00000000C8B2 + A3FFCAB4A5FFCBB5A6FFCAB4A5FFC9B3A4FFC7B2A3FFC6B0A1FFC3AE9FFFC1AC + 9DFFBFAA9BFFBDA899FFBBA697FFB9A495FFB8A394FFB7A293FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000FFFF00000003000000010000000100000001000000010000000100000001 + 0000000100000001000000010000000100000001000000010000FFFF0000} + OldCreateOrder = False + OnCreate = FormCreate + OnResize = FormResize + DesignSize = ( + 662 + 388) + PixelsPerInch = 96 + TextHeight = 13 + object Bevel1: TBevel + Left = 7 + Top = 7 + Width = 533 + Height = 308 + Anchors = [akLeft, akTop, akRight, akBottom] + Style = bsRaised + end + object Button1: TButton + Left = 527 + Top = 359 + Width = 112 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Close' + TabOrder = 0 + OnClick = Button1Click + end + object CheckBox1: TCheckBox + Left = 8 + Top = 360 + Width = 384 + Height = 24 + Anchors = [akLeft, akRight, akBottom] + Caption = 'Automatically open this window when loading flame' + TabOrder = 1 + WordWrap = True + OnClick = CheckBox1Click + end + object Button2: TButton + Left = 406 + Top = 359 + Width = 113 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Clear' + TabOrder = 2 + OnClick = Button2Click + end + object Output: TMemo + Left = 8 + Top = 8 + Width = 528 + Height = 303 + BevelOuter = bvRaised + BorderStyle = bsNone + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clBtnText + Font.Height = -12 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 3 + end +end diff --git a/Forms/LoadTracker.pas b/Forms/LoadTracker.pas new file mode 100644 index 0000000..8468131 --- /dev/null +++ b/Forms/LoadTracker.pas @@ -0,0 +1,104 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit LoadTracker; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, Global, Settings, ExtCtrls, Translation; + +type + TLoadForm = class(TForm) + Button1: TButton; + CheckBox1: TCheckBox; + Button2: TButton; + Bevel1: TBevel; + Output: TMemo; + procedure FormResize(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure CheckBox1Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure Button2Click(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + LoadForm: TLoadForm; + +implementation + +{$R *.dfm} + +procedure TLoadForm.Button1Click(Sender: TObject); +begin + Close; +end; + +procedure TLoadForm.CheckBox1Click(Sender: TObject); +begin + AutoOpenLog := CheckBox1.Checked; +end; + +procedure TLoadForm.FormCreate(Sender: TObject); +begin + Button2.Caption := TextByKey('common-clear'); + Button1.Caption := TextByKey('common-close'); + self.Caption := TextByKey('messages-title'); + CheckBox1.Caption := TextByKey('messages-openautomatically'); + CheckBox1.Checked := AutoOpenLog; +end; + +procedure TLoadForm.Button2Click(Sender: TObject); +begin + Output.Text := ''; +end; + +procedure TLoadForm.FormResize(Sender: TObject); +begin + CheckBox1.Left := 2; + Checkbox1.Top := self.ClientHeight - Checkbox1.Height - 2; + CheckBox1.Width := self.ClientWidth - button1.Width - button2.Width - 8; + + Button1.Left := self.ClientWidth - button1.Width - button2.Width - 4; + Button1.Top := self.ClientHeight - Checkbox1.Height - 2 + Checkbox1.Height div 2 - Button1.Height div 2; + + Button2.Left := self.ClientWidth - button2.Width - 2; + Button2.Top := Button1.Top; + + Bevel1.Left := 2; + Bevel1.Top := 2; + Bevel1.Width := self.ClientWidth - 4; + Bevel1.Height := self.ClientHeight - 6 - checkbox1.Height; + + Output.Left := Bevel1.Left + 2; + Output.Top := Bevel1.Top + 2; + Output.Width := Bevel1.Width - 4; + Output.Height := Bevel1.Height -4; +end; + +end. diff --git a/Forms/Main.dfm b/Forms/Main.dfm new file mode 100644 index 0000000..85b3cb7 --- /dev/null +++ b/Forms/Main.dfm @@ -0,0 +1,5974 @@ +object MainForm: TMainForm + Left = 265 + Top = 172 + Caption = 'Apophysis 7X' + ClientHeight = 791 + ClientWidth = 1000 + Color = clBtnFace + Constraints.MinHeight = 240 + Constraints.MinWidth = 320 + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + Icon.Data = { + 000001000F00404000000100080028160000F60000003030000001000800A80E + 00001E1700002020000001000800A8080000C62500001818000001000800C806 + 00006E2E00001010000001000800680500003635000040400000010018002832 + 00009E3A00003030000001001800A81C0000C66C00002020000001001800A80C + 00006E8900001818000001001800480700001696000010100000010018006803 + 00005E9D0000404000000100200028420000C6A000003030000001002000A825 + 0000EEE200002020000001002000A81000009608010018180000010020008809 + 00003E190100101000000100200068040000C622010028000000400000008000 + 0000010008000000000000100000000000000000000000010000000100000000 + 00003E3E3E0042424200494949004E4E4E005A5A5A005C5C5C00626262006565 + 6500696969006D6D6D007171710075757500787878007D7D7D005C23CF005E25 + D1006027D300642FD0006229D500642BD700672EDA006631D2006833D4006B35 + D6006C3BD0006930DC006C33DF00723DDD006F36E2007138E400743BE700773E + EA007140D5007749D300794CD5007947DC007D53D1007E51DA007A45E5007B42 + EE007E45F1008154DD00875DDB008A64D7008D67DA00987AD6009876DD009B7D + D900844FEF008150E5008759E3008957ED008148F400844BF700874EFA008C5B + F0008C57F8008A51FD008F57FF008F5AFA00925CFF008F61EB00936DE0009369 + E7009264EE009670E2009F7CE4009C76E9009260F500986AF4009561FF009A68 + FF009C6AFF009D6DFE00A47EF000A274FE00A477FE00A57BF900A579FE00A77C + FE00A87DFE008282820085858500898989008C8C8C0092929200969696009999 + 99009D9D9D00A1A1A100A5A5A500A9A9A900ADADAD00B1B1B100B5B5B500B9B9 + B900BDBDBD009E83D300A186D600A489D900A992D700AE9BD400AA8FE000AD93 + E300B39CE100B092EE00B499EA00B79CED00AF8DF400AB85F800AA80FE00AD85 + FD00AF88FE00B089FD00B28DFD00B48FFD00B391F800B490FC00B794FC00B896 + FC00BD9EFB00B998FC00BC9BFD00BD9EFC00BBA8E200BDA6EB00BCA1F200BEA4 + F400C7BFD600C1B1DF00C9BEE000C5AEF300C1A4FA00C4A9FA00C7ADFA00C6AC + FC00C7B1F500CEBBF400CAB2F900CBB5F900C9B0FC00D1BDF900C1C1C100C6C6 + C600C9C9C900CDCDCD00D3CFDA00D0D0D000D5D5D500D7D3DE00D9D9D900DDDD + DD00CFC0EE00D2CAE100D4C9EB00D9D2E900DDD6EC00D5C6F300D4C2F700D5C4 + F700D8C9F600DACCF600D4C1FA00D7C4FD00D8C6F900DDCEFC00DDD1F500DED0 + F800E2DEEA00E0D5F700E1D9F000E3DAF700E7DFF600E4DAF900E6DBFD00E1E1 + E100E5E5E500E9E9E900EDEDED00E8E2F400EDEAF300EEEBF400ECE5FA00EDE5 + FC00F0EDF800F1F1F100F5F5F500F4F0FB00F6F2FD00F9F9F900FDFDFD000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF005305 + 0302020202020202020202020202020202020202020202020202020202020202 + 0202020202020202020202020202020202020202020202020202020201035A5A + 530E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E + 0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0D08035D90 + 615F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F + 5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5D54055D92 + 9290909090909090909090909090909090909090909090909090909090909090 + 9090909090909090909090909090909090909090909090909090906157085F92 + 9290929092909290929092909290929092909290929092909290929092909290 + 9290929092909290929092909290929092909290929092909290906157085D92 + 9290929092909290929092909290929092909290929092909290929092909290 + 9290929092909290929092909290929092909290929092909290926157085F92 + 9292909290929092909290929092909290929092909290929092909290929092 + 909290929092909290929092909290929092909290929092909290615A055D92 + 9292929292929292929292929292929292929292929292929292929292929292 + 9292929292929292929292929292929292929292929292929292926157085F92 + 9292909290929092909290929092909290929092909290929092909290929092 + 9092909290929092909290929092909290929092909290929092909057085F92 + 9292929292929292929292929292929292929292929292929292929292929292 + 929292929292929292929292929292929292929292929292929292615A055F92 + 9492929292929292929292929292929292929292929292929292929292929292 + 929292929292929292929292929292929292929292929292929292615A085F94 + 9492929292929292929292929292929292929292929292929292929292929292 + 9292929292929292929292929292929292929292929292929292929057085F94 + 9492949294929492949294929492949294929492949294929492949294929492 + 949294929492949294929492949294929492949294929492949292905A085F94 + 9494949494949494949494949494949494949494949494949494949494949494 + 9494949494949494949494949494949494949494949494949494929057085F94 + 949494949494925F5D5D5D619294949494949494949494949494949492905D5D + 5D5F90929494949494949494949494949492615D5D5D5F90929494905A085F94 + 979494949494949494945D576194949494949494949494949494949494949494 + 945D5A909494949494949494949494949492949494925D5F949494905A085F97 + 94979497949721101010625A5A92949497949497949497949497949466101010 + 0F81575F92949794979497949794979494250F100F128190949494925A085F97 + 97949794979765101010129354619497949794979497949794979497972E1010 + 102261549094949794979497949794976510101010639092949794905A085F97 + 9794979497949726101111305D5A929497949794979497949794979497972112 + 1011645D5A9294979497949794979496171111112C929294979497925A085F97 + 9797949797979782121112139A57619497979497979794979797949797978314 + 1213119A5A5D9497979497979794973F1211121A9A929497949794925A086194 + 97979797949797B12B1413142F5D5A949497979794979797949797979797B167 + 13141426905490949797979497977D141414146992949797979794925A096197 + 97979797979797979C141A141A9C5A5F979797979797979797979797979497B1 + 32141414685F5A929497979797B127141A143F9494979797979797925A095F97 + 9797979797979797B1431A1A1A3F615A929497979797979797979797979797B1 + 9C1A1B1A1A9B5A5F94979797B1431A1A1A1C9C9497979797979797925A096197 + B197979797979797B0AC1B1B1B1A995A5F979797979797979797979797979797 + B36B1A1B1B339457909497B1991B1B1B1B7E979797979797979797925A096197 + 979797979797979797B36B1E1B1C40925A929797979797979797979797B09797 + 97BA401B1E1B6B5F5A9497BA321B1E1B4497949797979797979797945C096197 + B197B19797B197B097B0B9271C1E1B9F5A5F9797B197B197B197B197B19797B0 + 97B1AD271C1F1CA85A61B16A1C1E1C28B99797B197B097B197B097945A0961B1 + 979797B19797B097B097B37F1F1F1F40975792979797B1979797B19797B097B0 + 97B0B3841F1F1F41975FAA1F1F1F1F8A9797B097B097B097B09797945D096197 + B1B197B197B197B197B1B0BE341F2020875E5F97B19797B1B19797B197B197B1 + 97B097BB4B1F201F8597401F20204BB195B097B197B097B197B197945D0961B1 + 97B197B197B197B0B097B0B38D29292038B1579297B1B19797B1B197B197B197 + B197B1B1BB362929286D20292936BB97B0B0B097B1B0B097B197B1945C0961B1 + 97B197B1B197B1B0B0B0B0B0BE413529298D5F5F97B097B1B197B197B1B0B0B0 + B0B0B0B0BAA329292929352929A3B0B0B0B0B0B0B0B0B0B0B0B197955C0961B1 + B1B1B197B1B1B0B0B0B0B0B0B3A635363641BB5792B0B197B1B1B0B197B1B0B0 + B0B0B0B0B0BA7535353535356EB094B0B0B0B0B0B0B0B0B0B0B0B1945D0961B1 + 97B1B1B197B1B0B1B0B0B0B1B1BA5036363686605F97B1B1B0B197B1B1B1B0B1 + B0B1B0B1B0B1AD3636363639BB5C92B0B0B0B0B0B0B0B0B0B0B0B0955D0961B1 + B1B1B1B1B1B1B1B0B1B1B1B0B1B3AF3636363BBB5792B1B1B1B1B1B1B1B1B1B0 + B1B1B1B1B1B37A3936363736888F5C95B1B1B1B1B1B1B1B1B1B1B1955D0990B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1BA7A39373987605D97B1B1B1B1B1B1B1B1B1 + B1B1B1B1B2A339373937393737B85D61B0B1B1B1B1B1B1B1B1B1B1955D0A90B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B3AD3B3B3B47AD5A92B1B1B1B1B1B1B1B1B1 + B1B1B1B1BB49393B3B4D3B3B3B4D975792B1B1B1B1B1B1B1B1B1B1975D0990B1 + B1B3B1B1B3B1B1B3B1B1B3B1B1B3B1BA8D473B477A615D97B2B1B2B1B2B1B2B1 + B2B1B1B57547473B50B37647474788615A97B1B1B1B1B1B1B2B1B1975E0A90B1 + B3B1B3B1B1B3B1B1B3B1B1B3B1B1B3B3B949474747AD5A92B1B3B1B3B1B3B1B3 + B1B3B3A347474747AF97AD49474747AF5F61B1B1B3B1B3B1B2B2B2975E0990B1 + B3B1B1B3B1B3B1B3B1B3B1B1B3B1B2B2BA8847474786605C97B3B1B2B2B2B2B2 + B2B2B9494747478697B2BA8E4747474DB05A92B1B2B2B1B3B2B2B2975E0B90B1 + B3B3B3B1B3B1B3B3B1B3B3B3B1B3B3B2B3BA50494747AF5A92B1B3B2B2B3B2B3 + B2B37A49494950B3B1B2B3BA7A474947885F5A97B2B3B2B2B2B2B2975E0990B3 + B3B1B3B3B3B3B3B1B3B3B1B3B3B3B2B3B3BA8E494D4975925A97B3B3B2B2B3B2 + B3A549494949AC97B3B2B3BAB44D494949A85E61B0B3B3B3B3B3B3B05E0D90B3 + B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B2B3B3BA7649494DA65D92B3B3B3B3B2B3 + B54D494D498797B2B3B3B2B3BA8E4D494D50BA5A91B1B3B2B3B2B2B05D0990B1 + B3B3B3B1926161616161616161618F8F618F94AA4D4D4D759490B3B3B3B3B3B2 + 7A4D4D4D6EB5B1B3B3B3B3B3B3BA794D4D4D86605A97B3B3B3B3B3B05F0B90B3 + B3B3B3B3BABABABABABABABABABABABABABABABA7A4D4D4DBA8FB3B3B3B3B3A1 + 4D4D4D4DA897B3B3B3B3B3B3B3BAB4504D4D4D9F5F60B1B3B3B3B3B05E0B90B3 + BAB3BA765050505050505050505050505050504D504D5050BA90B3B3BAB3B56E + 50504D8797B3B3B3BAB3BAB3BAB3BAA14D4D5050B55A92B3B3B5B3B15F0A90B3 + BABABA765050505050505050505050505050505050505050BA90B3BAB3B3864D + 505076B4B1B3BABABABABABABABABABA79505050868F5A94BABAB3B15F0D90BA + BABABA7650506E506E506E506E506E506E506E506E506E50BA92BABABAA15050 + 6E50A1B0B3BABABABABABABABABABABAB476506E509F9094BABAB3B15E0B92B3 + BABABA766E6E506E506E506E506E506E506E507050705070BAB2BABAB476506E + 508DB2B3BABABABABABABABABABABABABAA5506F6E70B4B3BABABAB15F0D90BA + BABBBABABBBABBBABBBABBBABBBABBBABBBABBBABBBABBBABABABABABABABABB + BBBABABABABABABABABABABABABABABABABABBBBBABBBABABABABAB15F0D92BA + BBBABEBABBBBBABEBABBBBBBBABBBBBBBABBBBBBBABBBBBBBBBABEBABEBABEBA + BBBBBBBBBABEBABEBABEBABEBABEBABEBABBBBBABBBBBBBABBBABAB35F0D92BA + BEBABEBBBBBEBABEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBEBABEBABE + BABBBBBBBBBBBEBABEBABEBABEBABEBABEBBBBBBBBBBBBBBBBBBBBB25F0D92BA + BEBEBABEBBBEBEBABEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBEBABEBEBEBA + BEBBBBBBBBBEBABEBEBEBABEBEBEBABEBBBBBBBBBBBBBBBBBBBBBBB25F0D92BA + BEBEBEBBBEBABEBEBBBEBBBEBBBEBBBEBBBEBBBEBBBEBBBEBBBEBEBEBEBABEBE + BBBEBEBEBBBEBEBEBABEBEBEBABEBEBBBEBBBEBBBEBBBEBBBEBEBBB35F0D92BA + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBBB35F0D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBBB3610D92BA + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB35F0D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB3610D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB3610D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBA610D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBA610D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBA610D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBA610D92BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE945394BE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE + BEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBE5D9494 + 9494949494949494949494949494949494949494949494949494949494949494 + 9494949494949494949494949494949494949494949494949494949494940000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002800 + 0000300000006000000001000800000000000009000000000000000000000001 + 000000010000000000004B4B4B00515151005C5C5C00616161006E6E6E007171 + 710075757500797979007D7D7D005C23CF005E25D100652FD2006128D400642B + D700652DD500642BD800662ED900682FDB006833D2006935D2006D3CD1006A32 + D9006B32DE006E38DB00723FD900733EDF006F36E2007037E2007139E2007239 + E500763DE900783FE9007345D100784AD4007847DA007948DD007E55D1007E4B + E7007941E9007B42EE007E49EA007F46F2008156D7008257DA00977DC9008761 + D5008965D1008860D800926DDD009471D9009976DE00824FE700824CEF008250 + E7008351E8008656E8008859E800834AF600854DF600874EFA008A55F3008D57 + FA008C53FD008C54FE00915AFE008E64E3009166E700996FEE009A76E1009A75 + E5009B78E2009A73E9009161F1009261F4009565F700976AF200996DF2009460 + FE009865FE009B6AFE009C6AFE009E6DFE009F72FB009F70FF00A07CEB00A279 + F500A172FE00A275FE00A477FE00A57AFB00A579FE00A87DFE00818181008585 + 8500888888008C8C8C009696960099999900A09FA400A3A3A300A1A0A400A4A4 + A500A9A9A900ADADAD00A8A0BA00ABA1BF00B0AFB200B1AEB900B2B2B200B6B6 + B600B4B1BB00B5B4B900B9B9B900BDBDBD009D81D3009C80D4009E81DB00A58F + D100AE9AD700AD97D800AEA3C600B9B5C000BAB3C700B4A6D200B9AAD700BBAC + D800BFB6D000A384E200A481EC00A988EB00AC91E200AE90E900B298E700B092 + EC00AF8CF300AC85FB00AA80FE00AD85FD00AF88FC00B18CFC00B699F100B89B + F300B99AF600B490FB00B695F900B592FC00B795FC00B998FB00BC9CFA00B998 + FC00BEADE000BFA7F000C2BEC800C4BFCE00C2B9D400C5BDD500C2B6D900C6BC + DA00C9BFDC00C0AAEB00C0ABED00C6B8E300C7B8E400C9BCE400C5B2EB00C7B3 + EF00C8B5ED00C9B9E800CAB8ED00CCBBEE00CEBFED00C2A6F800C4A9F900C6AD + F900C8AFFB00CAB6F200C8B1F600CEBAF700CAB3F800CBB5F800CDB6F900CEB9 + F800C1C1C100C5C5C500C7C6CA00C6C2CE00C9C9C900CDCDCD00CCC9D200C9C2 + D800CEC9D800D0CADB00D0C9DF00D1D1D100D5D5D500D5D0DF00D8D6DB00D8D6 + DD00D9D9D900DBDADC00DDDDDD00D3CDE200D4C9E900D9D3E500DDDBE100DFDD + E300DBD4E800DDD6ED00D7CAF100D9CEF000D8CAF400D3C0FA00D5C4F800DCCD + F900DFD7F100DDD2F500DFD4F400E1DFE500E2DDEC00E0D6F200E1D6F600E4DD + F200E2D8F400E5DEF500E0E0E000E2E1E500E4E2E700E5E5E500E5E3E800E6E5 + E900E6E2ED00E9E6ED00E9E9E900EAE8ED00ECEBEF00EDEDED00E6E1F000EAE4 + F400EDEAF300EEECF100EDEAF400F0EFF200F1F1F100F5F5F500F9F9F900FDFD + FD00000000000000000000000000000000000000000000000000000000000000 + 0000FFFFFF005E04020202020202020202020202020202020202020202020202 + 0202020202020202020202020202020202020202010167676262626262626262 + 6262626262626262626262626262626262626262626262626262626262626262 + 626262615E036EBBB8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B87264056EBBBBB8BBB8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8670572BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB867056EBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBB670672C2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2 + BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBB670672BBC2BBBBC2BBBBC2BB + BBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2BBBBC2 + BBBBC2BB670672C2BBC2C2BBC2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BB + C2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2BB6E0672C2C2C2C2C2C2C2BBC2 + C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BBC2C2BB + C2C2BBBB670672C2C2C2C2C2BBB872B8BBC2C2C2C2C2C2C2C2C2C2C2C2BBB872 + B8BBC2C2C2C2C2C2C2C2C2C2C2B87272B8BBC2C26E0672C2C2C2C2C2BBBBBB64 + 6EBBC2C2C2C2C2C2C2C2C2C2C2BBBBBB6E6EBBC2C2C2C2C2C2C2C2C2BBBBBBB8 + 6EB8C2BB6E0672C2C2C2C2C7210B0A2D6472C2C2C2C2C2C2C2C2C2C2BE2B0A0A + 74646EC2C2C2C2C2C2C2C2BD2F0B0A15BABBC2C26E0672C7C2C7C2C2770C0B22 + 6967C2C2C7C2C7C2C7C2C7C2C29E0C0B136964B8C2C7C2C7C2C7C277150B1376 + BBC2C7BB6E0672C7C7C2C7C7C1300C0C7465B8C7C2C7C2C7C2C7C2C7C2C7750C + 0D2E6C6EC2C2C7C2C7C2C12B0C0D32BEC2C7C2C27206B8C2C7C7C2C7C7971910 + 237967C2C7C7C7C7C7C7C7C7C7C7C1311016736572C7C7C7C7C73310102B9CC2 + C7C7C7C26E06B8C7C7C7C7C7C7CD451210806772C2C7C7C7C7C7C7C7C7C7C7A4 + 2416237C67BBC7C7C7A416161697C2C7C7C7C7C2720872C7C7C7C7C7C7C7CB17 + 171A7F67C2C7C7C7C7C7C7C7C7C7C7E2851717427267C2C7CF43161748C7C7C7 + C7C7C7C27206B8C7C7C7C7C7C7C7E2861A17477272C7C7C7C7C7C7C7C7C7C7C7 + E9481A17836EB7CE841A1E43C1C3C7C7C7C7C7C77208B8E2C7E2C7E1C7E2C9D2 + 381F347D67C7C7E2C7E1C7E2C7E1C7E1C7D2381F347D6EAB341A29A5C7CDC7E1 + C7E1C7C77206B8E1C7E1C7E2C7E1C7E88D201F816CB8C7E1C7E2C7E1C7E2C7E2 + C7E598292055BF441F1F82C7CDC7E2C7E1C7E1C77208B8E2E1E1E1E1E1E1E1E2 + CF4D292AAB64C2E1E1E1E1E1E1E1E1E1E2E2E98728294D29284AE8C7E2E1E1E1 + E1E1C7C77208B8E1E1E1E1E1E1E1E1E1E9AE282A56B972C7E2E1E1E1E1E1E1E1 + E1E1E2E04A28282A3CA7C7E2E1E1E1E1E1E2E2C7B808B8E2E1E1E2E1E1E2E1E2 + E2F04F2A3CAB6EC2E1E2E1E1E1E1E1E1E1E2E1E2B33C2A3C9199C2E2E1E1E2E1 + E1E1E2E17208BBE2E2E4E2E2E2E2E2E2E2E9D43E3C5A9972E2E2E2E2E2E2E2E2 + E2E2E4E85A3C3C3C539E6EC7E2E2E2E2E2E2E1E1B808BBE9E4E4E4E9E4E9E4E4 + E4E4E88B3F4EA06BC3E9E2E9E4E9E4E9E4E4E9AE3F3F4E3F3F9672B7E1E9E4E9 + E4E9E4E1B808BBE9E4E4E4E4E9E1E9E4E9E4E9D4514E8A7BB7E1E9E4E4E4E9E1 + E9E9D25A3F4FB05A4E4EA26DC2E2E9E1E9E1E9E1B808BBE9E9E9E9E9E9E9E9E4 + E9E9E9E9964F4EB367C2E9E9E9E9E9E9E4DB8A4E4FACCED6514F5A9F6EE1E9E9 + E9E9E9E1B85DBBE9E9E9E9E9E9E9E9E9E9E9E9E9E04F4F5CB972E1E9E9E9E9E9 + E9AE4F4F8ACFE2EAAE4F4F8F6EB8E1E9E9E4E9E4B808BBE9E9E9E9E9E9E9E9E9 + E9E9E9E9F3965151A072C2E9E9E9E9E9DB5A4F51D2E2E9E9E08C515AA06EC2E9 + E9E9E9E9B85DC2E9F3E9E9E2E1E1E1E1E1E1E1E1E1DB8A538A9BB8E9E9E9E9E8 + 8C525AACCEE9E9F3E9D95A515CC16EC7E9ECE9E9B85DC2E9F3E9E4C7C7C7C7C7 + C7C7C7C7C7E2B35A5AA6B9E9F3ECE9AE5C5A8CDBE8E9ECF3E9F3AE5B5A8F70B8 + E9ECECE9B85DC2F3F3E896969696968F8F968F9696968C5B5AB3BBF3ECF3D98A + 5A5CA7E2F3F3F3E9F3F3E0915A5CA76EC7E9ECE9BB5EC2F3F2D98C5C8A5C5C5C + 5C5C5C5C5C5C5C5C5CB6C2F3F3E8915C5CAEE8E9ECF3F3F3F3F3F3D88C5C8C9D + 6EE2ECECBB5EC2F3F3E08A8A5C8A5C8A8A5C8A5C8A5C8A5C8AB3E2F3F0B65C8A + 8CDBE9F3F3F3F3F3F3F3F3F0B38A5C96C7E2F3ECC25DC2F3F3F0D9D9D9D9D9DD + DDD9D9D9D9D9D9D9DDEAF2F3F3E0D9D9EAF2F3F3F3F3F3F3F3F3F3F3F0DDD9E0 + F2F3F3ECC25DC2F3F5F3F5F3F5F3F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F3F5F3 + F5F2F3F5F3F5F3F3F5F3F5F3F3F5F3F3F3F5F3F3C25EC2F5F3F5F3F5F3F5F3F5 + F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5F3F5 + F3F5F5ECC25EC2F5F5F5F5F3F5F5F5F5F5F5F5F3F5F5F5F3F5F5F5F5F5F3F5F5 + F5F5F5F3F5F5F5F3F5F5F5F3F5F5F5F5F5F3F5F3C25EC7F3F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F3C25EC2F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F3C25FC7F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5C25FC7F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5C25FC7F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5C25FC7F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5C75FC7F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5C75FC7F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F367C2C7C7E2C7C7E1C7C7E2 + C7C7E1C7C7E2C7C7E1C7C7E2C7C7E1C7C7E2C7C7E1C7C7E2C7C7E1C7C7E2C7C7 + E1C7C7E2C7BB0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000002800000020000000400000000100080000000000000400000000 + 00000000000000010000000100000000000041414100454545004B4B4B004C4C + 4C00555555005E5E5E006262620066666600696969006D6D6D00717171007575 + 7500787878007C7C7C005E25D1006229D500662DD9006B36D6006F3ED3006B32 + DE006F3ADA00743FDF007138E400763DE9007C4FD8007A45E5007D4CE1007C43 + EF007F4AEA008056D4008153DD00916FD600997BD7008857EC008C5FE8008249 + F5008D5CF1008950FC009059FF008F65E400956BEA009C79E1009B6DF7009560 + FF009764FF009B69FF009E6FFE00A37DF000A071FE00A477FF00A77CFE00A87D + FE00868686008B8B8B00969696009A9A9A009E9E9E00A1A1A100A5A5A500A9A9 + A900AEAEAE00B1B1B100B5B5B500B9B9B900BEBEBE00A287D700A88DDE00A586 + E200AA8CE800B092EE00B499E900A882F400AB81FE00AD85FD00AF88FE00B08A + FD00B99BF600B591FD00BC9CFC00B9A6E000BFA1FB00BFA1FC00C2B3E100CBBF + E200C8B9E700C6B3EC00C3ACF100C1A4FB00C4A7FC00C5AAFB00C9AFFD00CCB9 + F200CBB5FA00CDB6FA00D2BEF900C1C1C100C5C5C500C9C9C900CDCDCD00D0D0 + D000D5D5D500D4D0DB00D9D9D900DDDDDD00DCD8E400D3C0F900D7C6F800D9CA + F800DECFFD00DFD4F600DED1F900E3DFEB00E2D7F900E5DAFA00E6DBFC00E0E0 + E000E5E5E500E9E9E900EDEDED00EAE6F200E9E3F500EEEBF400EFECF500F0ED + F800F1F1F100F5F5F500F4F0FB00F4F0FC00F9F9F900FEFEFE00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000FFFFFF00360603020202020202020202020202020202 + 02020202020202020202020202053A39350E0E0E0E0E0E0E0E0E0E0E0E0E0E0E + 0E0E0E0E0E0E0E0E0E0E0E0C07033D62413F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3D35063F6262626262626262626262626262626262 + 62626262626262626262624137073F6464626264626264626264626264626264 + 62626462626462626462626039073F6464646462646462646462646462646462 + 64646264646264646264626039073F6464646260606064646464646464646060 + 60626464646464626260604139073F6467646764603F62646464646464646762 + 4160646464646464676260413907416467671310424141646764676467210F1E + 603F6264676467210F13664139093F676774501012693D626767646767741910 + 436041646767541010536462390941676767761F104460606467676767745510 + 1670416067761F112A6764623A0941676767745614167A3F6467676767677646 + 1128673F7447141B7A6767623A0941677467747D29174664606767746774747D + 231757627C1A175C746767643A0C41747474677671171D806062747474677476 + 6C17257C30173076677474643A094174747474747D4A1C486760677474747474 + 7D4F1C251C258074747467643D09607474747474767324247360647474747474 + 76812B24245E6767747474673D09607476767676747D58264C74607476767674 + 767D3226266D6462747674673D0C6076767476767676802D2773626476747676 + 7D5B272D272B7D61677476673D0960767676767676767D582C4E676274767676 + 732D27734F2D4F66617476673D0C60767676767676767680342B71636776767D + 4A2B5A767C342B6D646476673D0C627676746767646764765B324B76647D7D5E + 32347D747D6A324A766167673F0C627D7D7D817D817D817D814C327A6776794A + 326C767D7D7D4F325A6762673F0C627D5B4A3434343434343434347A677D4F33 + 5876767D7D7D7A4A346E67643F0C627D6A344A344A4A344A4A344A7C7D6A4A4C + 7A7A7D7D7D7D7D6C4A4C7C743F0C627D7D7D807E7D807E7D807D817D807D817D + 7D817E817D817D807D817D74410C627D81818181818181818181818181818181 + 817E818181818181818181763F0C628181818181818181818181818181818181 + 818181818181818181818176410C647D81818181818181818181818181818181 + 818181818181818181818176410C648181818181818181818181818181818181 + 81818181818181818181817D410E648181818181818181818181818181818181 + 8181818181818181818181816236628181818181818181818181818181818181 + 818181818181818181818181813D676464646464646464646464646464646464 + 6464646464646464646464646464000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000280000001800000030000000010008000000 + 00004002000000000000000000000001000000010000000000004C4C4C005151 + 5100555555005D5D5D00636363006F6F6F007373730075757500797979007D7D + 7D006A36D3006C37D800713ED800723CDE007546D400794BD500794DD4007747 + D9007A48DE007D49E7007F4CE700926DDD009571DD008254E0008451ED00824A + F300834BF4008F5DF5008B53FC008F65E200956FE3009266EA009163EF009368 + E9009866FC009A69FC009C6CFE009F70FE00A173FE00A97EFE00818181008585 + 8500888888008E8E8E009696960098989800A5A5A500AAAAAA00ADADAD00B3B3 + B300B6B6B600B7B5BA00B9B9B900BDBDBD009C82D100B29FD900B8AFCA00BAA9 + DC00A687E600AA8FE000B196E800A681F100AA88F000AE89F700AA80FF00AD86 + FD00AF88FD00B18DFB00B08AFD00B18DFC00B48FFD00B799F500B896FC00BC9E + F900BA99FC00BC9CFC00B8A4E100BCA5E900BFA0FD00C0B5D700C1B6D800C7B8 + E500C8B5EE00CBBAEE00C5ADF600C4A9F900C7AFF900C8B0FA00CBB4F900CDB8 + F900D1BEF800C1C1C100C4C4C400C9C9C900CAC8CE00CCCBCD00CCCCCC00CFCD + D300D4CFDE00D1D1D100D5D5D500D6D4DB00D7D4DD00D9D9D900DDDDDD00CEC4 + E300CEC2E700D2C5EB00D8D1E500D9D1E800D2C3F200D5C6F300D5C5F600DCCE + F700DFD7F000DED3F400DFD4F500E0D5F500E2DAF200E5DFF200E1D6F800E1E1 + E100E4E2E700E5E5E500E5E4E900E5E1EC00E7E4ED00EAE7EF00E9E9E900EAE8 + EF00EDEDED00E6E0F100E9E5F300E9E2F400EBE9F000EDEBF000F1F1F100F5F5 + F500F9F9F900FEFEFE0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FFFFFF002B050303030303030303 + 030303030303030303030303010130302E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E + 2E2E2E2E2904355E5D5D5D5D5D355D5D5D355D5D5D355D5D5D355D352F06355E + 645E5E5E5E645E5E5E645E5E5E645E5E5E645E5E30063564645E5E5E645E6464 + 5E645E5E5E645E64645E5E5D3006356464645E355E64646464645E5D5D5E6464 + 64645E5D30295D68681110395D64646468380C37345E6864510F106230063568 + 684D0C3C355E6868647A160F515D6468170D3A6433295D68686E1E116E5D6568 + 68686B181F5E5E540E3B676433065D7A687A54153D5E64687A687A53144E6E1F + 206E686835295D7A7A7A7F3E216A5E687A7A7A7F3F213E15717A7A6835295E7A + 7A7A7A721B485E687A7A7A7A861C1B4069687A7A35295E7A7A817F814F246C5E + 7A7A817A85241D4F64677A7A5D295E818181818179264F64688181854F244724 + 6C64687A5D296481818181818556276E647A8172275684474767647A5D295E89 + 817A687A7A6E474F6881774747818179285562685D2964845B5A5A545B5A4749 + 7F815A28718189895A426C645D296479472828282828284F8174425881898989 + 864F497F5E296489898B898B898B89898B898A898B8A898A8A898989642B688B + 8B8B8B8B8B8B8B8B8B8B8B8B8A8B8B8B8B8B8B89642B648B8B8B8B8B8B8B8B8B + 8B8B8B8B8B8B8B8B8B8B8B89642B688B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B + 8B8B8B8B682B688B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B89306468 + 687A68687A68687A687A68687A68687A68687A68686400000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000028000000100000002000 + 0000010008000000000000010000000000000000000000010000000100000000 + 00004141410047474700494949004E4E4E0050505000585858005F5F5F006363 + 6300646464006A6A6A006D6D6D007171710076767600797979007C7C7C006229 + D500723DDE007240D5007A48DD00987AD6008B5DE7008249F5008853F4009268 + E6009662FD009B69FF00A07DE500A97FFE00858585008A8A8A009A9A9A009287 + A900A0A0A000A5A5A500A9A9A900ADADAD00B1B1B100B9B9B900BEBEBE00A085 + D600A68CDC00AF9CD600B1A9C200B6A7D500BEAFDD00BFB3D600A788E400AD88 + F700AB83FB00AB81FF00AE87FD00B08CFA00B392F500B694F800BD9FFA00C4AF + EE00C8B9E700C0A6F600C2A7F900CCB7F600C2C2C200C5C5C500CACACA00CDCD + CD00CBC4DB00D3CFDA00D0D0D000D5D5D500D9D9D900DDDDDD00CEC3E500D5CE + E500DBD3E900DBD4EA00DBCDF700DFD4F500E0DAEE00E5DCF500E1E1E100E6E6 + E600E9E9E900EDEDED00EAE7F000F2F2F200F6F6F600F9F9F900000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF001E07 + 040402040204020402040202020622221D0E0E0E0E0E0E0E0E0E0E0E0704253F + 3D26262626262626262626251E07264444444444444444444444443D1F0B2645 + 12284444442E102A44442C10200B26452D1141454545291342421314220B264F + 4F181B454F454F152F2F153F220C3D4F4F3916484F4F4F4817164744220C3D4F + 524F3436524F524919194945250C3D5252524D1A4D525234363A3145250C3F52 + 5254523B37523C1C53533138250C3F3731313131314E314B54544C312B0E3F54 + 565555555555555555565652260E43545656565656565656565656563F1D4456 + 565656565656565656565656562544444343444343444343444343443F440000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002800 + 0000400000008000000001001800000000000030000000000000000000000000 + 0000000000008585855A5A5A4848484343434343434343434343434343434343 + 4343434343434343434343434343434343434343434343434343434343434343 + 4343434343434343434343434343434343434343434343434343434343434343 + 4343434343434343434343434343434343434343434343434343434343434343 + 4343434343434343434343434343434343434343434343434343434343434343 + 4343434343434343434343434343434343434343434343434343434343424242 + 3E3E3E4E4E4EA0A0A09F9F9F8585857E7E7E7D7D7D7D7D7D7D7D7D7D7D7D7D7D + 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D + 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D + 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D + 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D + 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D777777 + 6464644B4B4BADADADC8C8C8BEBEBEB6B6B6B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B4B4B4ABABAB + 8989895C5C5CAFAFAFCCCCCCCACACAC7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C6C6C6BBBBBB + 969696626262B0B0B0CDCDCDCBCBCBC9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C8C8C8BEBEBE + 979797626262B0B0B0CDCDCDCBCBCBC9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C8C8C8BEBEBE + 979797626262B0B0B0CECECECCCCCCCACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACAC9C9C9BFBFBF + 989898626262B1B1B1CFCFCFCDCDCDCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCACACAC0C0C0 + 989898626262B1B1B1D0D0D0CECECECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBC1C1C1 + 999999636363B1B1B1D0D0D0CECECECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBC1C1C1 + 999999636363B2B2B2D1D1D1CFCFCFCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCCCCCCC2C2C2 + 9A9A9A646464B2B2B2D2D2D2D0D0D0CECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECDCDCDC3C3C3 + 9B9B9B646464B2B2B2D3D3D3D1D1D1CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCECECEC4C4C4 + 9B9B9B656565B3B3B3D3D3D3D2D2D2D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFC5C5C5 + 9C9C9C656565B4B4B4D4D4D4D3D3D3D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1C9C9 + C9B6B6B6ABABABAAAAAAAFAFAFBEBEBECDCDCDD1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + CECECEC1C1C1B0B0B0AAAAAAAAAAAAB3B3B3C5C5C5D0D0D0D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1CA + CACAB9B9B9ACACACAAAAAAAAAAAAB3B3B3C6C6C6D0D0D0D1D1D1D0D0D0C6C6C6 + 9D9D9D666666B4B4B4D5D5D5D4D4D4D2D2D2D2D2D2D2D2D2D2D2D2D3D3D3D1D1 + D1D4D4D4D4D4D4D4D4D4A7A7A7939393BEBEBED1D1D1D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D0D0D0D4D4D4D4D4D4D4D4D4D4D4D4AAAAAAA0A0A0C7C7C7D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1CB + CBCBD4D4D4D4D4D4D4D4D4CCCCCCAEAEAEB6B6B6D0D0D0D2D2D2D1D1D1C6C6C6 + 9E9E9E666666B4B4B4D6D6D6D5D5D5D3D3D3D3D3D3D3D3D3D3D3D3D6D6D66C3B + D05C23CF5C23CF5C23CF9E83D39F9F9FA5A5A5CCCCCCD3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D4D4D4 + AE9BD45C23CF5C23CF5C23CF5C23CFC7BFD6999999AFAFAFCFCFCFD3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D2D2D2D1D1D17D + 53D15C23CF5C23CF5C23CF642FD0C7BFD6C1C1C1D2D2D2D3D3D3D2D2D2C7C7C7 + 9F9F9F666666B5B5B5D7D7D7D6D6D6D4D4D4D4D4D4D4D4D4D4D4D4D7D7D7A992 + D75E25D15E25D15E25D16631D2D3CFDA8C8C8CBDBDBDD3D3D3D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D8D8D8987AD65E25D15E25D15E25D17749D3BFBFBF8C8C8CBEBEBED3D3D3D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4A992D75E + 25D15E25D15E25D15E25D1A186D6C8C8C8D0D0D0D4D4D4D4D4D4D3D3D3C8C8C8 + 9F9F9F666666B6B6B6D8D8D8D7D7D7D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5DDDD + DD794CD56027D36027D36027D39B7DD9AAAAAAA0A0A0CDCDCDD5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D6D6D6DEDEDE7140D56027D36027D36027D3A489D9AAAAAA9D9D9DCACACAD5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D7D3DE6833D460 + 27D36027D36027D38A64D7CBCBCBCDCDCDD5D5D5D5D5D5D5D5D5D4D4D4C9C9C9 + A0A0A0676767B7B7B7D9D9D9D8D8D8D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6DBDB + DBC1B1DF6229D56229D56229D56229D5D2CAE1919191BCBCBCD5D5D5D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6DCDCDCC9BEE06229D56229D56229D56229D5D2CAE19E9E9EB2B2B2D2D2 + D2D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D5D5D5D9D9D98D67DA6229D562 + 29D56229D56B35D6D2CAE1CACACAD5D5D5D6D6D6D6D6D6D6D6D6D5D5D5CACACA + A1A1A1676767B8B8B8D9D9D9D9D9D9D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7E3E3E3875DDB642BD7642BD7642BD79876DDB0B0B0A0A0A0CECECED7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7E0E0E0AA8FE0642BD7642BD7642BD77E51DAC8C8C88D8D8DBFBF + BFD5D5D5D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7DADADABBA8E2642BD7642BD764 + 2BD7642BD7B39CE1D0D0D0D4D4D4D7D7D7D7D7D7D7D7D7D7D7D7D6D6D6CBCBCB + A2A2A2686868B8B8B8DADADADADADAD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8DEDEDED9D2E9672EDA672EDA672EDA672EDAD9D2E9989898BABABAD5D5D5D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D9D9D9E7E7E78154DD672EDA672EDA672EDAAD93E3B1B1B19D9D + 9DCCCCCCD8D8D8D8D8D8D8D8D8D8D8D8D9D9D9E2DEEA7947DC672EDA672EDA67 + 2EDA936DE0D3D3D3CFCFCFD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D7D7D7CCCCCC + A2A2A2696969B8B8B8DBDBDBDBDBDBD9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9E6E6E69F7CE46930DC6930DC6930DC9670E2BDBDBD9A9A9ACCCCCCD9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9E2E2E2DDD6EC6930DC6930DC6930DC6930DCD4C9EBA3A3 + A3B3B3B3D5D5D5D9D9D9D9D9D9D9D9D9E1E1E19F7CE46930DC6930DC6930DC72 + 3DDDDDD6ECD0D0D0D8D8D8D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D8D8D8CDCDCD + A3A3A3696969B9B9B9DCDCDCDCDCDCDADADADADADADADADADADADADADADADADA + DADADADADFDFDFE1D9F06C33DF6C33DF6C33DF6C33DFCFC0EE9F9F9FB9B9B9D7 + D7D7DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADAE9E9E9B499EA6C33DF6C33DF6C33DF8759E3D2D2 + D2909090C2C2C2D8D8D8DADADAE2E2E2CFC0EE6C33DF6C33DF6C33DF6C33DFBD + A6EBD8D8D8D7D7D7DADADADADADADADADADADADADADADADADADAD9D9D9CECECE + A4A4A46A6A6ABABABADDDDDDDDDDDDDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBEBEBEBB79CED6F36E26F36E26F36E29369E7CCCCCC9A9A9ACD + CDCDDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDCDCDCEFEFEF9369E76F36E26F36E26F36E2B79C + EDB7B7B79F9F9FCFCFCFDDDDDDEFEFEF8150E56F36E26F36E26F36E29C76E9DC + DCDCD2D2D2DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDADADACFCFCF + A5A5A56A6A6ABBBBBBDEDEDEDEDEDEDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDEDEDEF0ECF87A45E57138E47138E47138E4D5C6F3A8A8A8B7 + B7B7D9D9D9DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCE5E5E5E7DFF67A45E57138E47138E47138 + E4DED2F5A8A8A8B5B5B5E6E6E6B092EE7138E47138E47138E47A45E5F0ECF8D6 + D6D6DBDBDBDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDBDBDBD0D0D0 + A5A5A56A6A6ABBBBBBDFDFDFDEDEDEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDEDEDEDBCA1F2743BE7743BE7743BE78F61EBDADADA93 + 9393CCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEDEDEDC5AEF3743BE7743BE7743B + E78F61EBD9D9D9B4B4B4E0D5F7743BE7743BE7743BE7743BE7CEBBF4DDDDDDDA + DADADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCD1D1D1 + A6A6A66A6A6ABCBCBCE0E0E0DFDFDFDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEE0E0E0F9F9F98957ED773EEA773EEA773EEAC7B1F5B0 + B0B0B5B5B5DBDBDBDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEF3F3F3A47EF0773EEA773E + EA773EEABEA4F4DBDBDB9264EE773EEA773EEA773EEAA47EF0E2E2E2D5D5D5DE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDD2D2D2 + A7A7A76B6B6BBCBCBCE0E0E0E0E0E0DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFEDEDEDCAB3F87B42EE7B42EE7B42EE8C5BF0E7 + E7E7939393CCCCCCDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFE7E7E7F5F1FD844FEF7B42 + EE7B42EE7B42EEAF8DF47B42EE7B42EE7B42EE844FEFF5F1FDD9D9D9DEDEDEDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDED3D3D3 + A8A8A86B6B6BBDBDBDE1E1E1E1E1E1E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0F9F9F9986AF47E45F17E45F17E45F1CB + B5F9B0B0B0B2B2B2DADADAE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0F0F0F0D4C1FA7E45 + F17E45F17E45F17E45F17E45F17E45F17E45F1D4C1FAE0E0E0DCDCDCE0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0DFDFDFD4D4D4 + A8A8A86C6C6CBDBDBDE2E2E2E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EDEDEDDDCEFC8148F48148F48148F492 + 60F5F7F3FE969696CBCBCBE0E0E0E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1F3F3F3B391 + F88148F48148F48148F48148F48148F4AB85F8DFDFDFD4D4D4E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E0E0E0D5D5D5 + A9A9A96D6D6DBEBEBEE3E3E3E3E3E3E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2F7F7F7A57BF9844BF7844BF784 + 4BF7C6ABFBB8B8B8B2B2B2DCDCDCE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E4E4E4EFE7 + FE844BF7844BF7844BF7844BF78C57F8F7F3FEA9A9A9CACACAE1E1E1E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E1E1E1D6D6D6 + AAAAAA6D6D6DC0C0C0E5E5E5E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4ECECECE6DBFD874EFA874EFA87 + 4EFA8F5AFAF6F2FE979797CDCDCDE3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3ECECECB794 + FC874EFA874EFA874EFA874EFA874EFAC6ACFCBFBFBFA8A8A8D8D8D8E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3D7D7D7 + ABABAB6D6D6DC1C1C1E6E6E6E6E6E6E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F3F3F3B896FD8A51FD8A + 51FD8A51FDC7ADFDB6B6B6AEAEAEDCDCDCE5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5EBEBEBD7C4FD8A51 + FD8A51FD8A51FD8A51FD8A51FD8A51FD8A51FDEEE6FDADADADBEBEBEE1E1E1E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E4E4E4D8D8D8 + ACACAC6D6D6DC1C1C1E6E6E6E7E7E7E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6EAEAEAEDE5FC8F57FF8F + 57FF8F57FF9662FFEDE5FC9E9E9ECACACAE5E5E5E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E8E8E8F4F0FB9D6DFE8F57 + FF8F57FF8F57FFA578FE8F57FF8F57FF8F57FFA578FEDADADA979797CDCDCDE4 + E4E4E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E5E5E5D9D9D9 + ADADAD6D6D6DC2C2C2E7E7E7E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7F2F2F2C9B0FC92 + 5CFF925CFF925CFFBC9BFDBEBEBEADADADDEDEDEE7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E6E6E6EDEDEDB591FD925CFF925C + FF925CFFA77CFEE9E9E9B591FD925CFF925CFF925CFFC9B0FCBCBCBCA6A6A6D9 + D9D9E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E6E6E6DADADA + AEAEAE6E6E6EC3C3C3E8E8E8E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E9E9E9F2EFF99C + 6AFF9560FF9560FF9560FFECE5FA9D9D9DCACACAE6E6E6E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8EDEDEDD8C6FB9560FF9560FF9560 + FF9560FFE5DAFADFDFDFECE5FA9C6AFF9560FF9560FF9560FFE5DAFAB2B2B2BC + BCBCE2E2E2E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E7E7E7DBDBDB + AFAFAF6E6E6EC3C3C3E9E9E9EAEAEAE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9F0F0F0CA + B2FB9763FF9763FF9763FFBD9EFCBBBBBBA9A9A9DDDDDDE9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9EAEAEAF1EDF89D6DFE9763FF9763FF9763 + FFC4A8FBDFDFDFE3E3E3F0F0F0D1BCFA9763FF9763FF9763FFA477FEE1E1E19C + 9C9CCDCDCDE6E6E6E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E8E8E8DCDCDC + AFAFAF6F6F6FC3C3C3EAEAEAEBEBEBEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEBEBEBF4 + F4F4A67BFE9A68FF9A68FF9A68FFE4DAF8A6A6A6C7C7C7E7E7E7EAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAE9E9E9ECECECB997FC9A68FF9A68FF9A68FFA67B + FEEBEBEBDFDFDFEAEAEAEAEAEAF2F2F2B997FC9A68FF9A68FF9A68FFC5AAFBB9 + B9B9A4A4A4D9D9D9E9E9E9EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE9E9E9DDDDDD + AFAFAF6F6F6FC3C3C3EBEBEBECECECEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBF0 + F0F0D2BEF99D6CFF9D6CFF9D6CFFB491FCCDCDCDA6A6A6DDDDDDEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBECECECD8C7F89D6CFF9D6CFF9D6CFF9D6CFFE3DA + F7E0E0E0E9E9E9EBEBEBEBEBEBEEEEEEE9E3F6A375FE9D6CFF9D6CFF9D6CFFDE + D0F8AFAFAFBABABAE3E3E3EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEAEAEADEDEDE + B0B0B0707070C4C4C4ECECECEDEDEDECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECF2F2F2B08AFD9F6FFF9F6FFF9F6FFFDDD1F7A7A7A7CDCDCDECECECECECEC + ECECECECECECECECECEBEBEBEEEBF5A578FE9F6FFF9F6FFF9F6FFFC7ADFADDDD + DDE5E5E5ECECECECECECECECECECECECF0F0F0D2BFF89F6FFF9F6FFF9F6FFFAA + 81FEEEEBF5A0A0A0CCCCCCE8E8E8ECECECECECECECECECECECECEBEBEBDFDFDF + B1B1B1707070C5C5C5ECECECEEEEEEEDEDEDEDEDEDE4E4E4CECECEC2C2C2C0C0 + C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0 + C0C0D4D4D4DDD1F6A274FFA274FFA274FFB896FCD0D0D0C3C3C3EDEDEDEDEDED + EDEDEDEDEDEDECECECEAEAEABD9EFBA274FFA274FFA274FFAD85FDEEEBF4DFDF + DFECECECEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF1F1F1BD9EFBA274FFA274FFA2 + 74FFC2A7FAB8B8B8A1A1A1D9D9D9ECECECEDEDEDEDEDEDEDEDEDECECECE0E0E0 + B1B1B1707070C6C6C6EDEDEDEFEFEFEEEEEEF0F0F0EEEEEEF2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2B998FCA477FFA477FFA477FFF2F2F2C1C1C1EEEEEEEEEEEE + EEEEEEEEEEEEECECECD8C9F6A477FFA477FFA477FFA477FFDDD1F5DEDEDEEBEB + EBEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFEFEFE8E2F4A97FFEA477FFA4 + 77FFA477FFD8C9F6B4B4B4B8B8B8E5E5E5EEEEEEEEEEEEEEEEEEEDEDEDE1E1E1 + B2B2B2717171C6C6C6EEEEEEF0F0F0EFEFEFF2F2F2B08AFDA67AFFA67AFFA67A + FFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFA6 + 7AFFA67AFFA67AFFA67AFFA67AFFA67AFFA67AFFF2F2F2C2C2C2EFEFEFEFEFEF + EFEFEFEDEDEDEDEAF3AB82FEA67AFFA67AFFA67AFFC4AAFADCDCDCE7E7E7EFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFF1F1F1D4C2F7A67AFFA6 + 7AFFA67AFFAB82FEEDEAF3A4A4A4CBCBCBEBEBEBEFEFEFEFEFEFEEEEEEE2E2E2 + B3B3B3717171C7C7C7EFEFEFF1F1F1F0F0F0F2F2F2B28DFDA87DFFA87DFFA87D + FFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA8 + 7DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFF2F2F2C3C3C3F0F0F0F0F0F0 + EFEFEFEAEAEAC1A4FBA87DFFA87DFFA87DFFB28DFDEDEAF3E1E1E1EFEFEFF0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F1F1F1C1A4FBA8 + 7DFFA87DFFA87DFFC1A4FBC0C0C09E9E9ED9D9D9EFEFEFF0F0F0EFEFEFE3E3E3 + B4B4B4727272C7C7C7F0F0F0F2F2F2F1F1F1F2F2F2B48FFDAA80FFAA80FFAA80 + FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA + 80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFF2F2F2CFCFCFF1F1F1F1F1F1 + F0F0F0DACCF6AA80FFAA80FFAA80FFAA80FFDACCF6E0E0E0EDEDEDF1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1E8E3F4AF + 88FEAA80FFAA80FFAA80FFD5C4F7C7C7C7D1D1D1EEEEEEF1F1F1F0F0F0E4E4E4 + B4B4B4727272C8C8C8F1F1F1F3F3F3F2F2F2F2F2F2B490FDAB81FFAB81FFAB81 + FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB + 81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFF2F2F2E7E7E7F2F2F2F2F2F2 + E9E3F4B089FEAB81FFAB81FFAB81FFC7AEFAE8E8E8EBEBEBF2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2D6 + C5F7AB81FFAB81FFAB81FFB089FEE9E3F4E7E7E7F1F1F1F2F2F2F1F1F1E5E5E5 + B5B5B5737373C9C9C9F2F2F2F4F4F4F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F2F2F2E6E6E6 + B6B6B6737373C9C9C9F3F3F3F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F3F3F3E7E7E7 + B7B7B7747474CACACAF3F3F3F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F4F4F4E8E8E8 + B7B7B7747474CACACAF4F4F4F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F5F5F5E8E8E8 + B8B8B8747474CBCBCBF4F4F4F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6E9E9E9 + B9B9B9757575CCCCCCF5F5F5F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F7F7F7EAEAEA + BABABA757575CCCCCCF6F6F6F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F8F8F8EBEBEB + BABABA767676CCCCCCF6F6F6F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F8F8F8EBEBEB + BABABA767676CDCDCDF7F7F7FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF9F9F9ECECEC + BBBBBB767676CECECEF8F8F8FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFAFAFAEDEDED + BCBCBC777777CECECEF8F8F8FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFBFBFBEEEEEE + BDBDBD777777CECECEF8F8F8FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFBFBFBEEEEEE + BDBDBD777777CECECEF9F9F9FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFCFCFCEFEFEF + BDBDBD787878CECECEF9F9F9FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF0F0F0 + BEBEBE787878CFCFCFFAFAFAFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + D0D0D0828282CECECEFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBA7A7A7D4D4D4D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D4D4D40000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000002800000030000000600000000100180000000000001B00000000 + 0000000000000000000000000000838383616161535353515151515151515151 + 5151515151515151515151515151515151515151515151515151515151515151 + 5151515151515151515151515151515151515151515151515151515151515151 + 5151515151515151515151515151515151515151515151515151515151515151 + 5151515151515151515151515151515151515151515151514B4B4B4B4B4BA9A9 + A9AAAAAA9B9B9B99999999999999999999999999999999999999999999999999 + 9999999999999999999999999999999999999999999999999999999999999999 + 9999999999999999999999999999999999999999999999999999999999999999 + 9999999999999999999999999999999999999999999999999999999999999999 + 99999999999696968383835C5C5CB5B5B5C8C8C8C3C3C3C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2BEBEBEA4A4A46D6D6DB7B7 + B7CCCCCCC9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C5C5C5AAAAAA6F6F6FB7B7B7CCCCCCC9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C5C5C5AAAAAA6F6F6FB8B8 + B8CDCDCDCBCBCBCACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACAC7C7C7ABABAB6F6F6FB9B9B9CFCFCFCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8C8C8ADADAD707070B9B9 + B9CFCFCFCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCC8C8C8ADADAD707070BABABAD0D0D0CECECECDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCACACAAEAEAE717171BABA + BAD2D2D2CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCBCBCBAFAFAF727272BBBBBBD2D2D2D0D0D0D0D0D0D0D0D0D0D0D0 + CACACAC0C0C0BDBDBDC1C1C1CACACAD0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFCACACABFBFBFBCBCBCC0C0C0CC + CCCCD0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + CECECEC2C2C2BDBDBDBDBDBDC3C3C3CDCDCDD0D0D0CCCCCCB0B0B0737373BCBC + BCD4D4D4D2D2D2D2D2D2D1D1D1D2D2D2CECECECBCBCBC9C9C9A6A6A6AFAFAFCD + CDCDD1D1D1D1D1D1D1D1D1D2D2D2D1D1D1D1D1D1D2D2D2D1D1D1D1D1D1D2D2D2 + D0D0D0CFCFCFCACACAC9C9C9B3B3B3B1B1B1CDCDCDD1D1D1D2D2D2D1D1D1D2D2 + D2D1D1D1D1D1D1D2D2D2D1D1D1D1D1D1CCCCCCCCCCCCC9C9C9C5C5C5B2B2B2C5 + C5C5D1D1D1CECECEB1B1B1747474BCBCBCD5D5D5D3D3D3D3D3D3D3D3D3D5D5D5 + 7345D15C23CF5C23CF977DC9A5A4A6BEBEBED3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3C6BFD47E55D15C23CF5C23CF9D81D3A3 + A3A3B8B8B8D0D0D0D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3CCC9D2 + 8965D15C23CF5C23CF6D3CD1C6C2CFCBCBCBD3D3D3CFCFCFB3B3B3747474BEBE + BED6D6D6D4D4D4D4D4D4D4D4D4D5D5D5AD97D8652FD25E25D1784AD4A8A0BAA9 + A9A9D1D1D1D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D5D5D5C2B6D9652FD25E25D16833D2ABA1BFA4A4A4C6C6C6D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D5AE9AD76935D35E25D16935D2A58FD1CCCCCCD3 + D3D3D4D4D4D0D0D0B3B3B3747474BFBFBFD8D8D8D6D6D6D5D5D5D5D5D5D5D5D5 + D0CADB8860D86128D4652DD59C80D4A1A0A4C5C5C5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5DADADA9E81DB6128D46128D487 + 61D5B2AFB8B1B1B1D3D3D3D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5C9C2D88156D7 + 6229D4632AD49471D9C7C3CFD3D3D3D5D5D5D5D5D5D1D1D1B5B5B5757575C0C0 + C0D9D9D9D7D7D7D7D7D7D7D7D7D7D7D7DADADABEAEE0723FD9642BD87847DAAE + A3C6A8A8A8CFCFCFD7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D5D0DF926DDD662ED86932D89C81D4A09FA4BDBDBDD5D5D5D7D7 + D7D7D7D7D7D7D7DBDADC9976DE642BD7642BD88257DAC5BCD6D3D3D3D7D7D7D7 + D7D7D7D7D7D3D3D3B6B6B6767676C0C0C0DADADAD8D8D8D8D8D8D8D8D8D8D8D8 + D9D9D9DDDBE19A76E1682FDB672EDAA384E2AAAAAABDBDBDD6D6D6D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8DCDCDCC9BCE47948DD68 + 2FDB7948DDB4A6D2A8A8A8CACACAD8D8D8D8D8D8DADADAC7B8E46E38DB672EDA + 6B33DBBEADE0D2D2D2D7D7D7D8D8D8D8D8D8D8D8D8D4D4D4B7B7B7777777C1C1 + C1DBDBDBDADADAD9D9D9D9D9D9D9D9D9D9D9D9DDDDDDD4C9E96B32DE6B32DE73 + 3EDFBFB6D0ADADADD1D1D1D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9DADADAE0E0E2B298E76B32DE6B32DE8E64E3BABABAAFAFAFD4D4 + D4DBDBDBD9D3E58F65E36B32DE6B32DE9A75E5D8D6DBD7D7D7D9D9D9D9D9D9D9 + D9D9D9D9D9D5D5D5B8B8B8787878C3C3C3DDDDDDDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBE4E4E4B092EC7038E26F36E29B78E2B5B4B9BDBDBDDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBE8E8E89A + 73E97038E26F36E2AC91E2B1AFB3BEBEBEDFDDE3AE90E9733BE37037E29166E7 + D0C9DFD6D6D6DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBD7D7D7BABABA787878C4C4 + C4DEDEDEDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDDDDDDD9CEF08656E872 + 39E58250E7B9AAD7ABABABD5D5D5DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDFDFDFD7CAF08859E87239E58351E8BBACD8B7B7 + B7CEBFED824FE77239E57E4BE7C5B2EBDBDBDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCD8D8D8BABABA787878C4C4C4DFDFDFDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDE5E3E8B699F17941E9773FE9A481ECB1ADBAC3C3C3DCDC + DCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE3 + E1E6BFA7F07E49EA783FE9A07CEBCEC9D8996FEE763DE9763DE9A988EBD9D7DE + DBDBDBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD9D9D9BCBCBC797979C5C5 + C5E0E0E0DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFE2E2E2DFD7F197 + 6AF27B42EE824CEFCAB9ECA5A5A5D1D1D1DEDEDEDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFE1E1E1ECEBEFAF8CF37B42EF7B42EE996D + F27B42EE7B42EE9161F1EAE8EEDCDCDCDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDBDBDBBDBDBD7A7A7AC6C6C6E1E1E1E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E9E9E9C8B1F67F46F27F46F2A279F5C7C6CABBBB + BBDCDCDCE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E4E4E4E4DDF29261F47F46F27F46F27F46F28A55F3C8B5EEDBDBDBDFDFDF + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0DCDCDCBEBEBE7B7B7BC7C7 + C7E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E3E3E3ED + EAF39565F7834AF6864EF6C9B9E8B3B3B3D3D3D3E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E6E6E6C8AFFB834AF6834A + F6844CF6B695F9C2BEC8D1D1D1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1DDDDDDBFBFBF7C7C7CC9C9C9E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E9E9E9D3C0FA8D57FA874EFAA57AFBC4BF + CEBBBBBBE2E2E2E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E6E2EDA276FC874EFA874EFB874EFA9F72FBC6BCDAB3B3B3DADADA + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E0E0E0C1C1C17C7C7CCACA + CAE6E6E6E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E7E2F1AF88FD8C53FD9560FEC0AAEBB0AFB2D7D7D7E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5EAE9ECC7ADFA8C54FE8C53FD9460 + FD8C53FD8C53FDBA98FDBDBDBDC0C0C0E1E1E1E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E1E1E1C2C2C27C7C7CCBCBCBE7E7E7E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E9E9EAD5C4F89B6AFE915BFFAD85 + FDBAB3C7BFBFBFE3E3E3E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7 + E7E7D8CAF4A072FE915AFF9966FECAB6F2A478FD915AFE9561FEC6B8E3B1B1B1 + D0D0D0E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E2E2E2C3C3C37D7D7DCCCC + CCE8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8EDECF0BA98FC9560FF9560FFCDB6FBACACACD2D2D2E7E7E7E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E5DDF3AF88FD9560FF9865FFC2A6F8E1DF + E5DCCDF99F6FFE9560FFA579FEC9BFDCB6B6B6DFDFDFE8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E4E4E4C5C5C57E7E7ECCCCCCE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9EBEBEBE2D9F49D6CFE9865 + FEA67BFDC5C1CDBCBCBCE2E2E2E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9EAEAEAC6 + ACFB9967FE9865FEAC85FBDBD4E8E4E4E4EAE7EFC4A9F99C6BFE9A67FEB99AF6 + B4B1BBC2C2C2E4E4E4E9E9E9E9E9E9E9E9E9E9E9E9E5E5E5C5C5C57E7E7ECDCD + CDEBEBEBEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEFEFEFBC9CFB9C6AFE9C6AFEC0ABEDB8B8B8D3D3D3EAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAE0D6F2A273FE9C6AFE9C6AFED7CAF3E4E4E4E9E9 + E9EBEBEBE5DFF3AF89FC9C6AFEA173FEC9B6EDB1B1B1D3D3D3E9E9E9EAEAEAEA + EAEAEAEAEAE6E6E6C6C6C67F7F7FCECECEECECECECECECECECECE7E7E7E2E2E2 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1DED7EFAD86 + FD9F70FFAD84FDC2B9D4C4C4C4ECECECECECECECECECECECECE6E1F0B38FFC9F + 70FFA172FEC5AAFAE0E0E0E9E9E9ECECECECECECEDEDEDDFD4F4A478FE9F70FF + A67AFED3CDE2B3B3B3DBDBDBECECECECECECECECECE8E8E8C8C8C8808080CFCF + CFEDEDEDEDEDEDEDEDEDE4E4E4DBDBDBD9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9E4E2E7CAB3F8A579FEA579FEC7B3EFC9C9C9EDEDED + EDEDEDEDEDEDE9E7EDC8B1F6A67AFEA375FFB490FBDDD6ECE7E7E7EDEDEDEDED + EDEDEDEDEDEDEDEFEFEFC7AEF9A477FEA375FFB89BF3B9B5C0C1C1C1E9E9E9ED + EDEDEDEDEDE9E9E9C8C8C8808080D0D0D0EEEEEEEFEFEFE5DEF3BC9DFAB998FB + B998FCB998FBB998FBB998FCB998FBB998FCB998FBB998FBB998FBB998FCB18C + FDA67BFEA579FFCBB5F8CDCDCDEFEFEFEEEEEEEDEDEDDFD5F4AD86FDA579FFAB + 82FECCBBEEE2E2E4EEEEEEEEEEEEEFEFEFEEEEEEEEEEEEEFEFEFE5DEF3B795FC + A579FFA97FFECAB8EFB6B6B7D8D8D8EDEDEDEFEFEFEAEAEACACACA818181D1D1 + D1F0F0F0F0F0F0E2D8F4AD85FDA87DFEA87DFFA87DFEA87DFEA87DFFA87DFEA8 + 7DFFA87DFEA87DFEA87DFEA87DFFA87DFEA87DFEA87DFFCDB7F8D0D0D0F0F0F0 + EFEFEFE8E5EDB693FCA87DFEA87DFEC7AFF8E6E5E9ECECECF0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0DDD2F5B28CFDA87DFEB18CFDC2B7D9B3B3B3E2 + E2E2F0F0F0ECECECCBCBCB828282D1D1D1F1F1F1F1F1F1E2D9F4AF87FDAA80FE + AA80FFAA80FEAA80FEAA80FFAA80FEAA80FFAA80FEAA80FEAA80FEAA80FFAA80 + FEAA80FEAA80FFCEB9F8E0E0E0F1F1F1EEEDF1CEBAF7AA80FFAA80FEB491FDE2 + DDECEAEAEAF0F0F0F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1EFEDF2 + CDB7F8AA80FEAA80FEBC9DFBD8D6DDE5E5E5F1F1F1EDEDEDCCCCCC828282D3D3 + D3F2F2F2F3F3F3EFECF3E2D8F5E1D6F6E1D6F6E1D6F6E1D6F6E1D6F6E1D6F6E1 + D6F6E1D6F6E1D6F6E1D6F6E1D6F6E1D6F6E1D6F6E1D6F6EAE4F4F0F0F0F3F3F3 + F1F1F3E5DEF5E1D6F6E1D6F6E6DFF5F0F0F0F2F2F2F2F2F2F3F3F3F2F2F2F3F3 + F3F2F2F2F2F2F2F3F3F3F2F2F2F2F2F2EDEAF4E1D6F6E1D6F6E2D8F6F0EFF2F1 + F1F1F3F3F3EEEEEECDCDCD838383D3D3D3F3F3F3F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F0F0F0CFCFCF848484D4D4 + D4F4F4F4F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F1F1F1CFCFCF848484D5D5D5F5F5F5F6F6F6F7F7F7F6F6F6F6F6F6 + F7F7F7F6F6F6F6F6F6F7F7F7F6F6F6F7F7F7F6F6F6F6F6F6F6F6F6F7F7F7F6F6 + F6F6F6F6F7F7F7F6F6F6F6F6F6F7F7F7F6F6F6F6F6F6F7F7F7F6F6F6F6F6F6F7 + F7F7F6F6F6F6F6F6F7F7F7F6F6F6F7F7F7F6F6F6F6F6F6F7F7F7F6F6F6F6F6F6 + F7F7F7F6F6F6F6F6F6F7F7F7F6F6F6F6F6F6F7F7F7F2F2F2D0D0D0858585D6D6 + D6F6F6F6F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F3F3F3D2D2D2868686D6D6D6F7F7F7F8F8F8F9F9F9F8F8F8F8F8F8 + F9F9F9F8F8F8F8F8F8F9F9F9F8F8F8F9F9F9F8F8F8F8F8F8F8F8F8F9F9F9F8F8 + F8F8F8F8F9F9F9F8F8F8F8F8F8F9F9F9F8F8F8F8F8F8F9F9F9F8F8F8F8F8F8F9 + F9F9F8F8F8F8F8F8F9F9F9F8F8F8F9F9F9F8F8F8F8F8F8F9F9F9F8F8F8F8F8F8 + F9F9F9F8F8F8F8F8F8F9F9F9F8F8F8F8F8F8F9F9F9F4F4F4D2D2D2868686D7D7 + D7F8F8F8F9F9F9FAFAFAF9F9F9F9F9F9FAFAFAF9F9F9F9F9F9FAFAFAF9F9F9FA + FAFAF9F9F9F9F9F9F9F9F9FAFAFAF9F9F9F9F9F9FAFAFAF9F9F9F9F9F9FAFAFA + F9F9F9F9F9F9FAFAFAF9F9F9F9F9F9FAFAFAF9F9F9F9F9F9FAFAFAF9F9F9FAFA + FAF9F9F9F9F9F9FAFAFAF9F9F9F9F9F9FAFAFAF9F9F9F9F9F9FAFAFAF9F9F9F9 + F9F9FAFAFAF5F5F5D3D3D3878787D8D8D8F9F9F9FBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF6F6F6D4D4D4888888D8D8 + D8F9F9F9FBFBFBFCFCFCFBFBFBFBFBFBFCFCFCFBFBFBFBFBFBFCFCFCFBFBFBFC + FCFCFBFBFBFBFBFBFBFBFBFCFCFCFBFBFBFBFBFBFCFCFCFBFBFBFBFBFBFCFCFC + FBFBFBFBFBFBFCFCFCFBFBFBFBFBFBFCFCFCFBFBFBFBFBFBFCFCFCFBFBFBFCFC + FCFBFBFBFBFBFBFCFCFCFBFBFBFBFBFBFCFCFCFBFBFBFBFBFBFCFCFCFBFBFBFB + FBFBFCFCFCF7F7F7D5D5D5888888D9D9D9FAFAFAFCFCFCFDFDFDFCFCFCFCFCFC + FDFDFDFCFCFCFCFCFCFDFDFDFCFCFCFDFDFDFCFCFCFCFCFCFCFCFCFDFDFDFCFC + FCFCFCFCFDFDFDFCFCFCFCFCFCFDFDFDFCFCFCFCFCFCFDFDFDFCFCFCFCFCFCFD + FDFDFCFCFCFCFCFCFDFDFDFCFCFCFDFDFDFCFCFCFCFCFCFDFDFDFCFCFCFCFCFC + FDFDFDFCFCFCFCFCFCFDFDFDFCFCFCFCFCFCFDFDFDF8F8F8D6D6D6898989D9D9 + D9FBFBFBFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFAFAFADADADA8C8C8CD9D9D9FBFBFBFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF0F0F0A8A8A8D4D4 + D4DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADACDCDCD000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000280000002000000040000000010018000000 + 0000000C0000000000000000000000000000000000008B8B8B5D5D5D4B4B4B46 + 4646454545454545454545454545454545454545454545454545454545454545 + 4545454545454545454545454545454545454545454545454545454545454545 + 45454545454545454545454545444444414141555555A2A2A29F9F9F8686867D + 7D7D7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C + 7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C + 7C7C7C7C7C7C7C7C7C7C7C7C7C7676766262624C4C4CAFAFAFC8C8C8BFBFBFB5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5AAAAAA8787875F5F5FB2B2B2CECECECDCDCDCA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACAC9C9C9BEBEBE969696656565B3B3B3CFCFCFCECECECC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCBCBCBBFBFBF979797676767B4B4B4D1D1D1D0D0D0CE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECDCDCDC1C1C1999999676767B5B5B5D2D2D2D2D2D2D0 + D0D0CBCBCBC1C1C1BFBFBFC6C6C6CECECED0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0CDCDCDC5C5C5BFBFBFC3C3C3CCCCCCD0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0CDCDCDC5C5C5BEBEBEC0C0C0BEBEBE9A9A9A676767B7B7B7D4D4D4D4D4D4D4 + D4D4D4D4D4D6D6D6BFBFBFB1B1B1C7C7C7D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D3D3D3D2D2D2D6D6D6C8C8C8B6B6B6C0C0C0D0D0D0D2D2D2D2D2D2D2D2D2D2D2 + D2CFCFCFD6D6D6CECECEBEBEBEBABABA9B9B9B686868B7B7B7D6D6D6D6D6D6DC + DCDC6F3ED35E25D1A287D7BCBCBCBBBBBBD1D1D1D4D4D4D4D4D4D4D4D4D4D4D4 + D9D9D9916FD65E25D18056D4C9C9C9AFAFAFC9C9C9D4D4D4D4D4D4D4D4D4D6D6 + D6997BD75E25D16F3ED3D4D0DBC0C0C09D9D9D686868B8B8B8D8D8D8D8D8D8DD + DDDDB9A6E06229D56B36D6DCD8E4B1B1B1CACACAD6D6D6D6D6D6D6D6D6D6D6D6 + D9D9D9E2E2E27C4FD86229D5A88DDEC2C2C2BBBBBBD1D1D1D6D6D6DADADACBBF + E26229D56229D5C2B3E1D4D4D4C7C7C79F9F9F696969B9B9B9D9D9D9DADADAD8 + D8D8E8E8E88153DD662DD9A586E2C6C6C6BFBFBFD5D5D5D8D8D8D8D8D8D8D8D8 + D8D8D8E0E0E0C8B9E7662DD96F3ADAE3DFEBBDBDBDC6C6C6D6D6D6E6E6E68153 + DD662DD99C79E1DADADAD3D3D3CACACAA0A0A06A6A6ABABABADBDBDBDCDCDCDA + DADAE4E4E4C6B3EC6B32DE743FDFEAE6F2B6B6B6CECECEDADADADADADADADADA + DADADADADADAE9E9E9AA8CE86B32DE8F65E4DBDBDBB3B3B3E0E0E0B499E96B32 + DE7D4CE1EAE6F2D7D7D7D9D9D9CCCCCCA2A2A26B6B6BBCBCBCDDDDDDDEDEDEDC + DCDCDCDCDCF1F1F1956BEA7138E4B092EECFCFCFC0C0C0D8D8D8DCDCDCDCDCDC + DCDCDCDCDCDCE0E0E0F3F3F38C5FE87138E4C3ACF1C8C8C8F0ECF87A45E57138 + E4CCB9F2E0E0E0DADADADBDBDBCECECEA4A4A46C6C6CBDBDBDDFDFDFDFDFDFDE + DEDEDEDEDEE8E8E8E2D7F9763DE97F4AEAF4F0FCC1C1C1CECECEDDDDDDDEDEDE + DEDEDEDEDEDEDEDEDEEAEAEAD9CAF8763DE98857ECF4F0FCA37DF0763DE9A37D + F0EAEAEADADADADEDEDEDDDDDDD0D0D0A5A5A56D6D6DBFBFBFE0E0E0E1E1E1E0 + E0E0E0E0E0E0E0E0F5F5F5A882F47C43EFA882F4DEDEDEBFBFBFDADADAE0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0F2F2F2B99BF67C43EF8D5CF17C43EF8D5CF1F6F2 + FEE0E0E0E0E0E0E0E0E0DFDFDFD2D2D2A7A7A76D6D6DC0C0C0E2E2E2E3E3E3E2 + E2E2E2E2E2E2E2E2E9E9E9E6DBFD8249F58249F5E6DBFDC3C3C3D1D1D1E1E1E1 + E2E2E2E2E2E2E2E2E2E2E2E2E6E6E6F9F9F99B6DF78249F58249F5CDB6FBD8D8 + D8D7D7D7E2E2E2E2E2E2E1E1E1D4D4D4A8A8A86E6E6EC2C2C2E5E5E5E6E6E6E5 + E5E5E5E5E5E5E5E5E5E5E5F3F3F3BFA1FC8950FCB08AFCDFDFDFC4C4C4DFDFDF + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F6F6F6A073FC8950FC8950FCDECFFDD0D0 + D0CDCDCDE1E1E1E5E5E5E4E4E4D7D7D7AAAAAA707070C3C3C3E6E6E6E8E8E8E7 + E7E7E7E7E7E7E7E7E7E7E7E9E9E9F4F0FB9764FF9059FFE6DBFCC5C5C5D5D5D5 + E5E5E5E7E7E7E7E7E7E7E7E7F0F0F0C9AFFD9059FF9764FF9059FF9E6FFEEFEF + EFC3C3C3D7D7D7E5E5E5E6E6E6D9D9D9ACACAC717171C4C4C4E8E8E8EAEAEAE9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9F2F2F2C4A7FC9560FFB693FDDDDDDDC4C4C4 + E2E2E2E9E9E9E9E9E9EDEDEDE5DAFA9560FF9560FFE5DAFABD9DFD9560FFBD9D + FDD7D7D7C4C4C4E1E1E1E8E8E8DADADAADADAD727272C4C4C4EAEAEAECECECEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBECECECF1EEF8A77CFE9B69FFDED1F9CDCDCD + D9D9D9EBEBEBEBEBEBF2F2F2AD85FD9B69FFC6ABFBE8E8E8F1EEF8A77CFE9B69 + FFDED1F9CFCFCFD2D2D2E6E6E6DCDCDCAFAFAF737373C6C6C6EBEBEBEAEAEAE1 + E1E1D9D9D9D5D5D5D5D5D5D5D5D5D5D5D5E4E4E4CDB7FAA071FFB18BFDE6E6E6 + D4D4D4ECECECEEEEEECDB7FAA071FFAB83FEEFEFEFE6E6E6F1F1F1D3C0F9A071 + FFAB83FEEAEAEAC6C6C6DBDBDBDCDCDCB0B0B0747474C7C7C7EEEEEEEFEFEFF4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4AF88FEA477FFEFECF5 + D6D6D6EDEDEDE9E3F5A97FFEA477FFD9CAF8E7E7E7EDEDEDEFEFEFF2F2F2BFA1 + FBA477FFC4A9FBD6D6D6C8C8C8D7D7D7B2B2B2757575C8C8C8F1F1F1CBB5FAA8 + 7DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFA87DFFEEEBF4 + DEDEDEF1F1F1BC9CFCA87DFFC1A4FBEAEAEAECECECF1F1F1F1F1F1F2F2F2EEEB + F4AD85FEA87DFFDFD4F6D9D9D9D6D6D6B2B2B2757575CACACAF2F2F2CEB7FAAB + 81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFEFECF5 + F0F0F0D2BEF9AB81FFB089FEEFECF5EEEEEEF3F3F3F3F3F3F3F3F3F3F3F3F4F4 + F4D7C6F8AB81FFB590FEEEEBF4DFDFDFB5B5B5757575CBCBCBF2F2F2F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F4F4F4E6E6E6B6B6B6777777CCCCCCF3F3F3F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F6F6F6E8E8E8B8B8B8787878CDCDCDF5F5F5F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F8F8F8E9E9E9B9B9B9787878CECECEF6F6F6FAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAF9F9F9EAEAEABABABA787878CFCFCFF7F7F7FCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCEEEEEEBDBDBD7A7A7AD0D0D0F8F8F8FDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDCECECE868686CFCFCFFAFAFAF9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFAFAA7A7A7D5D5D5D0D0D0D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0D0D0D5D5D500000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000028000000180000003000 + 00000100180000000000C0060000000000000000000000000000000000008888 + 8863636355555552525252525252525252525252525252525252525252525252 + 5252525252525252525252525252525252525252525252525252525252525252 + 4C4C4C505050ABABABABABAB9B9B9B9898989898989898989898989898989898 + 9898989898989898989898989898989898989898989898989898989898989898 + 98989898989696968282825D5D5DB8B8B8CACACAC5C5C5C4C4C4C4C4C4C4C4C4 + C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4 + C4C4C4C4C4C4C4C4C4C4C4C4C4C1C1C1A5A5A56F6F6FBABABACFCFCFCDCDCDCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8C8C8ABABAB737373BBBB + BBD1D1D1CFCFCFCBCBCBC6C6C6C9C9C9CECECECECECECECECECFCFCFCECECECE + CECEC8C8C8C7C7C7CBCBCBCFCFCFCECECECECECECECECECBCBCBC6C6C6C4C4C4 + ACACAC737373BDBDBDD3D3D3D3D3D3D1D1D1C7C7C7B8B8B8CBCBCBD1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1CECECEBFBFBFC0C0C0D0D0D0D1D1D1D1D1D1D0D0D0D0 + D0D0CBCBCBBDBDBDAAAAAA747474BFBFBFD6D6D6DADADA794BD5794CD4B8AFCA + BEBEBED2D2D2D4D4D4D4D4D4D6D6D6B29FD96A36D39C82D1B7B5BAC9C9C9D4D4 + D4D5D5D5C1B6D87546D47A4ED5CFCDD3AFAFAF757575C0C0C0D8D8D8DADADAB8 + A4E16C37D8AA8FE0BDBDBDCCCCCCD6D6D6D7D7D7D7D7D7DEDEDF926DDD7747D9 + C0B5D7C0C0C0D0D0D0DDDDDD9571DD713ED8BAA9DCD0D0D0B3B3B3767676C2C2 + C2DADADAD9D9D9D9D2E58F65E27A48DED6D4DBC3C3C3D7D7D7D9D9D9D9D9D9DB + DBDBCEC2E78254E0956FE3CCCCCCCACACAC7B8E5723CDEA687E6D7D4DDD4D4D4 + B6B6B6787878C4C4C4DEDEDEDDDDDDE1E1E1CBBAEE7F4CE7B196E8CCCBCDD0D0 + D0DCDCDCDCDCDCDCDCDCE3E3E3C8B5EE7D49E7BCA5E9D8D1E59266EA9368E9D9 + D2E7DCDCDCD8D8D8B9B9B97A7A7AC6C6C6DFDFDFDFDFDFE0E0E0E7E4EDA681F0 + 9163EFCEC4E3C8C8C8DCDCDCDEDEDEDFDFDFE0E0E0E5E1ECAA88F09163EFA782 + F28451EDD2C3F2E0E0E0DEDEDEDADADABBBBBB7B7B7BC8C8C8E2E2E2E1E1E1E1 + E1E1E6E6E6DCCEF7834BF4B799F5CAC8CED6D6D6E1E1E1E1E1E1E1E1E1E5E5E5 + E9E3F48F5DF5824AF3AE89F7DEDDDFDDDDDDE1E1E1DDDDDDBDBDBD7C7C7CCBCB + CBE5E5E5E5E5E5E5E5E5E5E5E5EDEDEDBC9CFC9A69FCD2C5EBCACACAE0E0E0E5 + E5E5E5E5E5E6E6E6E9E5F39866FC8B53FCBD9DFDD4D4D4D4D4D4E3E3E3E1E1E1 + C0C0C07E7E7ECCCCCCE7E7E7E8E8E8E8E8E8E7E7E7E8E8E8E1D6F89F70FEBFA0 + FDD0D0D0D7D7D7E7E7E7E8E8E8EAE7EFBD9EFB9D6DFEB28DFD9C6CFED3C7EBCD + CDCDDDDDDDE3E3E3C2C2C2808080CDCDCDEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EBE9F0C4A8FBA173FED9D1E8D2D2D2E6E6E6ECECECD5C5F6A173FEC5ABF8E5DF + F2B28EFCB18DFBD4CFDED3D3D3E3E3E3C4C4C4818181CFCFCFEBEBEBE7E7E7DF + DFDFDCDCDCDCDCDCDFDFDFDFD7F0B08AFDBC9EF8DEDEDFE6E6E6E2DAF2B28DFD + B18CFDECECECECECECE0D5F5A87DFEC5ADF6CFCED3D7D7D7C5C5C5838383D1D1 + D1E6E0F1D1BEF8CEB8F9CDB8F9CDB8F9CEB8F9CDB8F9B48FFDB896FCE4E2E7E9 + E9E9C7AFF9AD85FDD5C6F3EBEBEBEFEFEFF1F1F1CBB4F9AF88FDD1C4EBD2D2D2 + C4C4C4848484D3D3D3DFD4F5B28DFDAA80FFAA7FFEAA7FFEAA80FFAA7FFEAA7F + FEBB9BFCEDEBF0DED3F4AE87FEC8B0FAEAE8EFF1F1F1F2F2F2F2F2F2E9E2F5BB + 9AFCBA98FCE5E4E9C8C8C8848484D5D5D5F4F4F4F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F1F1F1CECECE878787D6D6D6F5F5F5F7F7F7F8 + F8F8F7F7F7F7F7F7F8F8F8F7F7F7F7F7F7F8F8F8F7F7F7F8F8F8F7F7F7F7F7F7 + F7F7F7F8F8F8F7F7F7F7F7F7F8F8F8F7F7F7F7F7F7F3F3F3D0D0D0888888D7D7 + D7F7F7F7F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F5F5F5 + D1D1D1888888D9D9D9F9F9F9FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCF9F9F9D9D9D98E8E8EDADADAF9F9F9FAFAFAFBFBFBFAFAFAFAFAFA + FBFBFBFAFAFAFAFAFAFBFBFBFAFAFAFBFBFBFAFAFAFAFAFAFAFAFAFBFBFBFAFA + FAFAFAFAFBFBFBFAFAFAFAFAFAFBFBFBEFEFEFA9A9A9D5D5D5DADADADADADADB + DBDBDADADADADADADBDBDBDADADADADADADBDBDBDADADADBDBDBDADADADADADA + DADADADBDBDBDADADADADADADBDBDBDADADADADADADBDBDBDADADACDCDCD0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002800 + 0000100000002000000001001800000000000003000000000000000000000000 + 0000000000008B8B8B5F5F5F4E4E4E4949494949494949494949494949494949 + 49494949494949494949494949474747414141585858A5A5A5A0A0A08686867D + 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7C7C7C777777 + 636363505050B3B3B3CDCDCDC3C3C3BABABAB9B9B9B9B9B9B9B9B9B9B9B9B9B9 + B9B9B9B9B9B9B9B9B9B9B8B8B8AEAEAE8A8A8A646464B8B8B8D4D4D4D4D4D4D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0D0D0C4C4C4 + 9A9A9A6A6A6ABABABAD8D8D87240D5A085D6D6D6D6D6D6D6D6D6D6BFB3D66229 + D5AF9CD6D6D6D6D6D6D6B6A7D56229D59287A96C6C6CBBBBBBDADADABEAFDD72 + 3DDECBC4DBDADADADADADADADADAA68CDC7A48DDD3CFDAD3CFDA7A48DD987AD6 + A1A1A16F6F6FBEBEBEDEDEDEE0E0E09268E6A07DE5DEDEDEDEDEDEDEDEDEDEDE + DE8B5DE7A788E4A788E48B5DE7D0D0D0A4A4A4707070C0C0C0E1E1E1E3E3E3C8 + B9E78249F5D5CEE5E2E2E2E2E2E2E2E2E2D5CEE58853F48249F5CEC3E5D4D4D4 + A7A7A7717171C3C3C3E5E5E5E8E8E8E7E7E7AD88F7B392F5E7E7E7E7E7E7E7E7 + E7DBD4EA9662FD9662FDDBD3E9D9D9D9AAAAAA737373C5C5C5E9E9E9ECECECEB + EBEBE0DAEE9B69FFE0DAEEEBEBEBEBEBEBB08CFAB694F8C0A6F6AB83FBDCDCDC + ADADAD757575C7C7C7ECECECF0F0F0EFEFEFEFEFEFC2A7F9BD9FFAEFEFEFCCB7 + F6A97FFEEAE7F0EAE7F0AE87FDC4AFEEB0B0B0767676CACACABD9FFBAB81FFAB + 81FFAB81FFAB81FFAB81FFE5DCF5AB81FFDBCDF7F3F3F3F3F3F3DFD4F5AB81FF + B1A9C2787878CCCCCCF3F3F3F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7E9E9E9B8B8B87B7B7BCECECEF6F6F6FBFBFBFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + CCCCCC858585CFCFCFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F8F8F8F8F8F8A8A8A8D6D6D6D1D1D1D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D1D1D1D6D6D60000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000002800000040000000800000000100200000000000004200000000 + 0000000000000000000000000000858585FF5A5A5AFF484848FF434343FF4343 + 43FF434343FF434343FF434343FF434343FF434343FF434343FF434343FF4343 + 43FF434343FF434343FF434343FF434343FF434343FF434343FF434343FF4343 + 43FF434343FF434343FF434343FF434343FF434343FF434343FF434343FF4343 + 43FF434343FF434343FF434343FF434343FF434343FF434343FF434343FF4343 + 43FF434343FF434343FF434343FF434343FF434343FF434343FF434343FF4343 + 43FF434343FF434343FF434343FF434343FF434343FF434343FF434343FF4343 + 43FF434343FF434343FF434343FF434343FF434343FF434343FF434343FF4343 + 43FF424242FF3E3E3EFF4E4E4EFFA0A0A0FF9F9F9FFF858585FF7E7E7EFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D + 7DFF777777FF646464FF4B4B4BFFADADADFFC8C8C8FFBEBEBEFFB6B6B6FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB4B4 + B4FFABABABFF898989FF5C5C5CFFAFAFAFFFCCCCCCFFCACACAFFC7C7C7FFC7C7 + C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7 + C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7 + C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7 + C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7 + C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7 + C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7 + C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC7C7C7FFC6C6 + C6FFBBBBBBFF969696FF626262FFB0B0B0FFCDCDCDFFCBCBCBFFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC8C8 + C8FFBEBEBEFF979797FF626262FFB0B0B0FFCDCDCDFFCBCBCBFFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC8C8 + C8FFBEBEBEFF979797FF626262FFB0B0B0FFCECECEFFCCCCCCFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFC9C9 + C9FFBFBFBFFF989898FF626262FFB1B1B1FFCFCFCFFFCDCDCDFFCBCBCBFFCBCB + CBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCB + CBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCB + CBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCB + CBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCB + CBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCB + CBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCB + CBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCBCBCBFFCACA + CAFFC0C0C0FF989898FF626262FFB1B1B1FFD0D0D0FFCECECEFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCBCB + CBFFC1C1C1FF999999FF636363FFB1B1B1FFD0D0D0FFCECECEFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCBCB + CBFFC1C1C1FF999999FF636363FFB2B2B2FFD1D1D1FFCFCFCFFFCDCDCDFFCDCD + CDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCD + CDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCD + CDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCD + CDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCD + CDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCD + CDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCD + CDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCDCDCDFFCCCC + CCFFC2C2C2FF9A9A9AFF646464FFB2B2B2FFD2D2D2FFD0D0D0FFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCDCD + CDFFC3C3C3FF9B9B9BFF646464FFB2B2B2FFD3D3D3FFD1D1D1FFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCECE + CEFFC4C4C4FF9B9B9BFF656565FFB3B3B3FFD3D3D3FFD2D2D2FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFCFCF + CFFFC5C5C5FF9C9C9CFF656565FFB4B4B4FFD4D4D4FFD3D3D3FFD1D1D1FFD1D1 + D1FFD1D1D1FFD1D1D1FFD1D1D1FFC9C9C9FFB6B6B6FFABABABFFAAAAAAFFAFAF + AFFFBEBEBEFFCDCDCDFFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1 + D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1 + D1FFD1D1D1FFCECECEFFC1C1C1FFB0B0B0FFAAAAAAFFAAAAAAFFB3B3B3FFC5C5 + C5FFD0D0D0FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1 + D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFCACACAFFB9B9 + B9FFACACACFFAAAAAAFFAAAAAAFFB3B3B3FFC6C6C6FFD0D0D0FFD1D1D1FFD0D0 + D0FFC6C6C6FF9D9D9DFF666666FFB4B4B4FFD5D5D5FFD4D4D4FFD2D2D2FFD2D2 + D2FFD2D2D2FFD2D2D2FFD3D3D3FFD1D1D1FFD4D4D4FFD4D4D4FFD4D4D4FFA7A7 + A7FF939393FFBEBEBEFFD1D1D1FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2 + D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2 + D2FFD2D2D2FFD0D0D0FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFAAAAAAFFA0A0 + A0FFC7C7C7FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2 + D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD1D1D1FFCBCBCBFFD4D4 + D4FFD4D4D4FFD4D4D4FFCCCCCCFFAEAEAEFFB6B6B6FFD0D0D0FFD2D2D2FFD1D1 + D1FFC6C6C6FF9E9E9EFF666666FFB4B4B4FFD6D6D6FFD5D5D5FFD3D3D3FFD3D3 + D3FFD3D3D3FFD3D3D3FFD6D6D6FF6C3BD0FF5C23CFFF5C23CFFF5C23CFFF9E83 + D3FF9F9F9FFFA5A5A5FFCCCCCCFFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3 + D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3 + D3FFD4D4D4FFAE9BD4FF5C23CFFF5C23CFFF5C23CFFF5C23CFFFC7BFD6FF9999 + 99FFAFAFAFFFCFCFCFFFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3 + D3FFD3D3D3FFD3D3D3FFD3D3D3FFD3D3D3FFD2D2D2FFD1D1D1FF7D53D1FF5C23 + CFFF5C23CFFF5C23CFFF642FD0FFC7BFD6FFC1C1C1FFD2D2D2FFD3D3D3FFD2D2 + D2FFC7C7C7FF9F9F9FFF666666FFB5B5B5FFD7D7D7FFD6D6D6FFD4D4D4FFD4D4 + D4FFD4D4D4FFD4D4D4FFD7D7D7FFA992D7FF5E25D1FF5E25D1FF5E25D1FF6631 + D2FFD3CFDAFF8C8C8CFFBDBDBDFFD3D3D3FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4 + D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4 + D4FFD4D4D4FFD8D8D8FF987AD6FF5E25D1FF5E25D1FF5E25D1FF7749D3FFBFBF + BFFF8C8C8CFFBEBEBEFFD3D3D3FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4 + D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFA992D7FF5E25D1FF5E25 + D1FF5E25D1FF5E25D1FFA186D6FFC8C8C8FFD0D0D0FFD4D4D4FFD4D4D4FFD3D3 + D3FFC8C8C8FF9F9F9FFF666666FFB6B6B6FFD8D8D8FFD7D7D7FFD5D5D5FFD5D5 + D5FFD5D5D5FFD5D5D5FFD5D5D5FFDDDDDDFF794CD5FF6027D3FF6027D3FF6027 + D3FF9B7DD9FFAAAAAAFFA0A0A0FFCDCDCDFFD5D5D5FFD5D5D5FFD5D5D5FFD5D5 + D5FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5 + D5FFD5D5D5FFD6D6D6FFDEDEDEFF7140D5FF6027D3FF6027D3FF6027D3FFA489 + D9FFAAAAAAFF9D9D9DFFCACACAFFD5D5D5FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5 + D5FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5D5FFD7D3DEFF6833D4FF6027D3FF6027 + D3FF6027D3FF8A64D7FFCBCBCBFFCDCDCDFFD5D5D5FFD5D5D5FFD5D5D5FFD4D4 + D4FFC9C9C9FFA0A0A0FF676767FFB7B7B7FFD9D9D9FFD8D8D8FFD6D6D6FFD6D6 + D6FFD6D6D6FFD6D6D6FFD6D6D6FFDBDBDBFFC1B1DFFF6229D5FF6229D5FF6229 + D5FF6229D5FFD2CAE1FF919191FFBCBCBCFFD5D5D5FFD6D6D6FFD6D6D6FFD6D6 + D6FFD6D6D6FFD6D6D6FFD6D6D6FFD6D6D6FFD6D6D6FFD6D6D6FFD6D6D6FFD6D6 + D6FFD6D6D6FFD6D6D6FFDCDCDCFFC9BEE0FF6229D5FF6229D5FF6229D5FF6229 + D5FFD2CAE1FF9E9E9EFFB2B2B2FFD2D2D2FFD6D6D6FFD6D6D6FFD6D6D6FFD6D6 + D6FFD6D6D6FFD6D6D6FFD5D5D5FFD9D9D9FF8D67DAFF6229D5FF6229D5FF6229 + D5FF6B35D6FFD2CAE1FFCACACAFFD5D5D5FFD6D6D6FFD6D6D6FFD6D6D6FFD5D5 + D5FFCACACAFFA1A1A1FF676767FFB8B8B8FFD9D9D9FFD9D9D9FFD7D7D7FFD7D7 + D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFE3E3E3FF875DDBFF642BD7FF642B + D7FF642BD7FF9876DDFFB0B0B0FFA0A0A0FFCECECEFFD7D7D7FFD7D7D7FFD7D7 + D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7 + D7FFD7D7D7FFD7D7D7FFD7D7D7FFE0E0E0FFAA8FE0FF642BD7FF642BD7FF642B + D7FF7E51DAFFC8C8C8FF8D8D8DFFBFBFBFFFD5D5D5FFD7D7D7FFD7D7D7FFD7D7 + D7FFD7D7D7FFD7D7D7FFDADADAFFBBA8E2FF642BD7FF642BD7FF642BD7FF642B + D7FFB39CE1FFD0D0D0FFD4D4D4FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD6D6 + D6FFCBCBCBFFA2A2A2FF686868FFB8B8B8FFDADADAFFDADADAFFD8D8D8FFD8D8 + D8FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFDEDEDEFFD9D2E9FF672EDAFF672E + DAFF672EDAFF672EDAFFD9D2E9FF989898FFBABABAFFD5D5D5FFD8D8D8FFD8D8 + D8FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8 + D8FFD8D8D8FFD8D8D8FFD8D8D8FFD9D9D9FFE7E7E7FF8154DDFF672EDAFF672E + DAFF672EDAFFAD93E3FFB1B1B1FF9D9D9DFFCCCCCCFFD8D8D8FFD8D8D8FFD8D8 + D8FFD8D8D8FFD9D9D9FFE2DEEAFF7947DCFF672EDAFF672EDAFF672EDAFF936D + E0FFD3D3D3FFCFCFCFFFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFD7D7 + D7FFCCCCCCFFA2A2A2FF696969FFB8B8B8FFDBDBDBFFDBDBDBFFD9D9D9FFD9D9 + D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFE6E6E6FF9F7CE4FF6930 + DCFF6930DCFF6930DCFF9670E2FFBDBDBDFF9A9A9AFFCCCCCCFFD9D9D9FFD9D9 + D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9 + D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFE2E2E2FFDDD6ECFF6930DCFF6930 + DCFF6930DCFF6930DCFFD4C9EBFFA3A3A3FFB3B3B3FFD5D5D5FFD9D9D9FFD9D9 + D9FFD9D9D9FFE1E1E1FF9F7CE4FF6930DCFF6930DCFF6930DCFF723DDDFFDDD6 + ECFFD0D0D0FFD8D8D8FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFD9D9D9FFD8D8 + D8FFCDCDCDFFA3A3A3FF696969FFB9B9B9FFDCDCDCFFDCDCDCFFDADADAFFDADA + DAFFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFDFDFDFFFE1D9F0FF6C33 + DFFF6C33DFFF6C33DFFF6C33DFFFCFC0EEFF9F9F9FFFB9B9B9FFD7D7D7FFDADA + DAFFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFDADA + DAFFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFE9E9E9FFB499EAFF6C33 + DFFF6C33DFFF6C33DFFF8759E3FFD2D2D2FF909090FFC2C2C2FFD8D8D8FFDADA + DAFFE2E2E2FFCFC0EEFF6C33DFFF6C33DFFF6C33DFFF6C33DFFFBDA6EBFFD8D8 + D8FFD7D7D7FFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFD9D9 + D9FFCECECEFFA4A4A4FF6A6A6AFFBABABAFFDDDDDDFFDDDDDDFFDBDBDBFFDBDB + DBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFEBEBEBFFB79C + EDFF6F36E2FF6F36E2FF6F36E2FF9369E7FFCCCCCCFF9A9A9AFFCDCDCDFFDBDB + DBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDB + DBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDCDCDCFFEFEFEFFF9369 + E7FF6F36E2FF6F36E2FF6F36E2FFB79CEDFFB7B7B7FF9F9F9FFFCFCFCFFFDDDD + DDFFEFEFEFFF8150E5FF6F36E2FF6F36E2FF6F36E2FF9C76E9FFDCDCDCFFD2D2 + D2FFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDADA + DAFFCFCFCFFFA5A5A5FF6A6A6AFFBBBBBBFFDEDEDEFFDEDEDEFFDCDCDCFFDCDC + DCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDEDEDEFFF0EC + F8FF7A45E5FF7138E4FF7138E4FF7138E4FFD5C6F3FFA8A8A8FFB7B7B7FFD9D9 + D9FFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDC + DCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFE5E5E5FFE7DF + F6FF7A45E5FF7138E4FF7138E4FF7138E4FFDED2F5FFA8A8A8FFB5B5B5FFE6E6 + E6FFB092EEFF7138E4FF7138E4FF7138E4FF7A45E5FFF0ECF8FFD6D6D6FFDBDB + DBFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDBDB + DBFFD0D0D0FFA5A5A5FF6A6A6AFFBBBBBBFFDFDFDFFFDEDEDEFFDDDDDDFFDDDD + DDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFEDED + EDFFBCA1F2FF743BE7FF743BE7FF743BE7FF8F61EBFFDADADAFF939393FFCCCC + CCFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDD + DDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFEDED + EDFFC5AEF3FF743BE7FF743BE7FF743BE7FF8F61EBFFD9D9D9FFB4B4B4FFE0D5 + F7FF743BE7FF743BE7FF743BE7FF743BE7FFCEBBF4FFDDDDDDFFDADADAFFDDDD + DDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDDDDDDFFDCDC + DCFFD1D1D1FFA6A6A6FF6A6A6AFFBCBCBCFFE0E0E0FFDFDFDFFFDEDEDEFFDEDE + DEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFE0E0 + E0FFF9F9F9FF8957EDFF773EEAFF773EEAFF773EEAFFC7B1F5FFB0B0B0FFB5B5 + B5FFDBDBDBFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDE + DEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDE + DEFFF3F3F3FFA47EF0FF773EEAFF773EEAFF773EEAFFBEA4F4FFDBDBDBFF9264 + EEFF773EEAFF773EEAFF773EEAFFA47EF0FFE2E2E2FFD5D5D5FFDEDEDEFFDEDE + DEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDDDD + DDFFD2D2D2FFA7A7A7FF6B6B6BFFBCBCBCFFE0E0E0FFE0E0E0FFDFDFDFFFDFDF + DFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDF + DFFFEDEDEDFFCAB3F8FF7B42EEFF7B42EEFF7B42EEFF8C5BF0FFE7E7E7FF9393 + 93FFCCCCCCFFDEDEDEFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDF + DFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDF + DFFFE7E7E7FFF5F1FDFF844FEFFF7B42EEFF7B42EEFF7B42EEFFAF8DF4FF7B42 + EEFF7B42EEFF7B42EEFF844FEFFFF5F1FDFFD9D9D9FFDEDEDEFFDFDFDFFFDFDF + DFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDEDE + DEFFD3D3D3FFA8A8A8FF6B6B6BFFBDBDBDFFE1E1E1FFE1E1E1FFE0E0E0FFE0E0 + E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0 + E0FFE0E0E0FFF9F9F9FF986AF4FF7E45F1FF7E45F1FF7E45F1FFCBB5F9FFB0B0 + B0FFB2B2B2FFDADADAFFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0 + E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0 + E0FFE0E0E0FFF0F0F0FFD4C1FAFF7E45F1FF7E45F1FF7E45F1FF7E45F1FF7E45 + F1FF7E45F1FF7E45F1FFD4C1FAFFE0E0E0FFDCDCDCFFE0E0E0FFE0E0E0FFE0E0 + E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFE0E0E0FFDFDF + DFFFD4D4D4FFA8A8A8FF6C6C6CFFBDBDBDFFE2E2E2FFE2E2E2FFE1E1E1FFE1E1 + E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1 + E1FFE1E1E1FFEDEDEDFFDDCEFCFF8148F4FF8148F4FF8148F4FF9260F5FFF7F3 + FEFF969696FFCBCBCBFFE0E0E0FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1 + E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1 + E1FFE1E1E1FFE1E1E1FFF3F3F3FFB391F8FF8148F4FF8148F4FF8148F4FF8148 + F4FF8148F4FFAB85F8FFDFDFDFFFD4D4D4FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1 + E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE0E0 + E0FFD5D5D5FFA9A9A9FF6D6D6DFFBEBEBEFFE3E3E3FFE3E3E3FFE2E2E2FFE2E2 + E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2 + E2FFE2E2E2FFE2E2E2FFF7F7F7FFA57BF9FF844BF7FF844BF7FF844BF7FFC6AB + FBFFB8B8B8FFB2B2B2FFDCDCDCFFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2 + E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2 + E2FFE2E2E2FFE2E2E2FFE4E4E4FFEFE7FEFF844BF7FF844BF7FF844BF7FF844B + F7FF8C57F8FFF7F3FEFFA9A9A9FFCACACAFFE1E1E1FFE2E2E2FFE2E2E2FFE2E2 + E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE1E1 + E1FFD6D6D6FFAAAAAAFF6D6D6DFFC0C0C0FFE5E5E5FFE5E5E5FFE4E4E4FFE4E4 + E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4 + E4FFE4E4E4FFE4E4E4FFECECECFFE6DBFDFF874EFAFF874EFAFF874EFAFF8F5A + FAFFF6F2FEFF979797FFCDCDCDFFE3E3E3FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4 + E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4 + E4FFE4E4E4FFE3E3E3FFECECECFFB794FCFF874EFAFF874EFAFF874EFAFF874E + FAFF874EFAFFC6ACFCFFBFBFBFFFA8A8A8FFD8D8D8FFE4E4E4FFE4E4E4FFE4E4 + E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE3E3 + E3FFD7D7D7FFABABABFF6D6D6DFFC1C1C1FFE6E6E6FFE6E6E6FFE5E5E5FFE5E5 + E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5 + E5FFE5E5E5FFE5E5E5FFE5E5E5FFF3F3F3FFB896FDFF8A51FDFF8A51FDFF8A51 + FDFFC7ADFDFFB6B6B6FFAEAEAEFFDCDCDCFFE5E5E5FFE5E5E5FFE5E5E5FFE5E5 + E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5 + E5FFE5E5E5FFEBEBEBFFD7C4FDFF8A51FDFF8A51FDFF8A51FDFF8A51FDFF8A51 + FDFF8A51FDFF8A51FDFFEEE6FDFFADADADFFBEBEBEFFE1E1E1FFE5E5E5FFE5E5 + E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFE4E4 + E4FFD8D8D8FFACACACFF6D6D6DFFC1C1C1FFE6E6E6FFE7E7E7FFE6E6E6FFE6E6 + E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6 + E6FFE6E6E6FFE6E6E6FFE6E6E6FFEAEAEAFFEDE5FCFF8F57FFFF8F57FFFF8F57 + FFFF9662FFFFEDE5FCFF9E9E9EFFCACACAFFE5E5E5FFE6E6E6FFE6E6E6FFE6E6 + E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6 + E6FFE8E8E8FFF4F0FBFF9D6DFEFF8F57FFFF8F57FFFF8F57FFFFA578FEFF8F57 + FFFF8F57FFFF8F57FFFFA578FEFFDADADAFF979797FFCDCDCDFFE4E4E4FFE6E6 + E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE5E5 + E5FFD9D9D9FFADADADFF6D6D6DFFC2C2C2FFE7E7E7FFE8E8E8FFE7E7E7FFE7E7 + E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7 + E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFF2F2F2FFC9B0FCFF925CFFFF925C + FFFF925CFFFFBC9BFDFFBEBEBEFFADADADFFDEDEDEFFE7E7E7FFE7E7E7FFE7E7 + E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE6E6 + E6FFEDEDEDFFB591FDFF925CFFFF925CFFFF925CFFFFA77CFEFFE9E9E9FFB591 + FDFF925CFFFF925CFFFF925CFFFFC9B0FCFFBCBCBCFFA6A6A6FFD9D9D9FFE7E7 + E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE6E6 + E6FFDADADAFFAEAEAEFF6E6E6EFFC3C3C3FFE8E8E8FFE9E9E9FFE8E8E8FFE8E8 + E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8 + E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE9E9E9FFF2EFF9FF9C6AFFFF9560 + FFFF9560FFFF9560FFFFECE5FAFF9D9D9DFFCACACAFFE6E6E6FFE8E8E8FFE8E8 + E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFEDED + EDFFD8C6FBFF9560FFFF9560FFFF9560FFFF9560FFFFE5DAFAFFDFDFDFFFECE5 + FAFF9C6AFFFF9560FFFF9560FFFF9560FFFFE5DAFAFFB2B2B2FFBCBCBCFFE2E2 + E2FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE7E7 + E7FFDBDBDBFFAFAFAFFF6E6E6EFFC3C3C3FFE9E9E9FFEAEAEAFFE9E9E9FFE9E9 + E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9 + E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFF0F0F0FFCAB2FBFF9763 + FFFF9763FFFF9763FFFFBD9EFCFFBBBBBBFFA9A9A9FFDDDDDDFFE9E9E9FFE9E9 + E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFEAEAEAFFF1ED + F8FF9D6DFEFF9763FFFF9763FFFF9763FFFFC4A8FBFFDFDFDFFFE3E3E3FFF0F0 + F0FFD1BCFAFF9763FFFF9763FFFF9763FFFFA477FEFFE1E1E1FF9C9C9CFFCDCD + CDFFE6E6E6FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE8E8 + E8FFDCDCDCFFAFAFAFFF6F6F6FFFC3C3C3FFEAEAEAFFEBEBEBFFEAEAEAFFEAEA + EAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEA + EAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEBEBEBFFF4F4F4FFA67B + FEFF9A68FFFF9A68FFFF9A68FFFFE4DAF8FFA6A6A6FFC7C7C7FFE7E7E7FFEAEA + EAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFE9E9E9FFECECECFFB997 + FCFF9A68FFFF9A68FFFF9A68FFFFA67BFEFFEBEBEBFFDFDFDFFFEAEAEAFFEAEA + EAFFF2F2F2FFB997FCFF9A68FFFF9A68FFFF9A68FFFFC5AAFBFFB9B9B9FFA4A4 + A4FFD9D9D9FFE9E9E9FFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFE9E9 + E9FFDDDDDDFFAFAFAFFF6F6F6FFFC3C3C3FFEBEBEBFFECECECFFEBEBEBFFEBEB + EBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEB + EBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFF0F0F0FFD2BE + F9FF9D6CFFFF9D6CFFFF9D6CFFFFB491FCFFCDCDCDFFA6A6A6FFDDDDDDFFEBEB + EBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFECECECFFD8C7F8FF9D6C + FFFF9D6CFFFF9D6CFFFF9D6CFFFFE3DAF7FFE0E0E0FFE9E9E9FFEBEBEBFFEBEB + EBFFEEEEEEFFE9E3F6FFA375FEFF9D6CFFFF9D6CFFFF9D6CFFFFDED0F8FFAFAF + AFFFBABABAFFE3E3E3FFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEAEA + EAFFDEDEDEFFB0B0B0FF707070FFC4C4C4FFECECECFFEDEDEDFFECECECFFECEC + ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC + ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFF2F2 + F2FFB08AFDFF9F6FFFFF9F6FFFFF9F6FFFFFDDD1F7FFA7A7A7FFCDCDCDFFECEC + ECFFECECECFFECECECFFECECECFFECECECFFEBEBEBFFEEEBF5FFA578FEFF9F6F + FFFF9F6FFFFF9F6FFFFFC7ADFAFFDDDDDDFFE5E5E5FFECECECFFECECECFFECEC + ECFFECECECFFF0F0F0FFD2BFF8FF9F6FFFFF9F6FFFFF9F6FFFFFAA81FEFFEEEB + F5FFA0A0A0FFCCCCCCFFE8E8E8FFECECECFFECECECFFECECECFFECECECFFEBEB + EBFFDFDFDFFFB1B1B1FF707070FFC5C5C5FFECECECFFEEEEEEFFEDEDEDFFEDED + EDFFE4E4E4FFCECECEFFC2C2C2FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0 + C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFD4D4 + D4FFDDD1F6FFA274FFFFA274FFFFA274FFFFB896FCFFD0D0D0FFC3C3C3FFEDED + EDFFEDEDEDFFEDEDEDFFEDEDEDFFECECECFFEAEAEAFFBD9EFBFFA274FFFFA274 + FFFFA274FFFFAD85FDFFEEEBF4FFDFDFDFFFECECECFFEDEDEDFFEDEDEDFFEDED + EDFFEDEDEDFFEDEDEDFFF1F1F1FFBD9EFBFFA274FFFFA274FFFFA274FFFFC2A7 + FAFFB8B8B8FFA1A1A1FFD9D9D9FFECECECFFEDEDEDFFEDEDEDFFEDEDEDFFECEC + ECFFE0E0E0FFB1B1B1FF707070FFC6C6C6FFEDEDEDFFEFEFEFFFEEEEEEFFF0F0 + F0FFEEEEEEFFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2 + F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2 + F2FFF2F2F2FFB998FCFFA477FFFFA477FFFFA477FFFFF2F2F2FFC1C1C1FFEEEE + EEFFEEEEEEFFEEEEEEFFEEEEEEFFECECECFFD8C9F6FFA477FFFFA477FFFFA477 + FFFFA477FFFFDDD1F5FFDEDEDEFFEBEBEBFFEEEEEEFFEEEEEEFFEEEEEEFFEEEE + EEFFEEEEEEFFEEEEEEFFEFEFEFFFE8E2F4FFA97FFEFFA477FFFFA477FFFFA477 + FFFFD8C9F6FFB4B4B4FFB8B8B8FFE5E5E5FFEEEEEEFFEEEEEEFFEEEEEEFFEDED + EDFFE1E1E1FFB2B2B2FF717171FFC6C6C6FFEEEEEEFFF0F0F0FFEFEFEFFFF2F2 + F2FFB08AFDFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67A + FFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67A + FFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFA67AFFFFF2F2F2FFC2C2C2FFEFEF + EFFFEFEFEFFFEFEFEFFFEDEDEDFFEDEAF3FFAB82FEFFA67AFFFFA67AFFFFA67A + FFFFC4AAFAFFDCDCDCFFE7E7E7FFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEF + EFFFEFEFEFFFEFEFEFFFEFEFEFFFF1F1F1FFD4C2F7FFA67AFFFFA67AFFFFA67A + FFFFAB82FEFFEDEAF3FFA4A4A4FFCBCBCBFFEBEBEBFFEFEFEFFFEFEFEFFFEEEE + EEFFE2E2E2FFB3B3B3FF717171FFC7C7C7FFEFEFEFFFF1F1F1FFF0F0F0FFF2F2 + F2FFB28DFDFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87D + FFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87D + FFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFF2F2F2FFC3C3C3FFF0F0 + F0FFF0F0F0FFEFEFEFFFEAEAEAFFC1A4FBFFA87DFFFFA87DFFFFA87DFFFFB28D + FDFFEDEAF3FFE1E1E1FFEFEFEFFFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0 + F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF1F1F1FFC1A4FBFFA87DFFFFA87D + FFFFA87DFFFFC1A4FBFFC0C0C0FF9E9E9EFFD9D9D9FFEFEFEFFFF0F0F0FFEFEF + EFFFE3E3E3FFB4B4B4FF727272FFC7C7C7FFF0F0F0FFF2F2F2FFF1F1F1FFF2F2 + F2FFB48FFDFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80 + FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80 + FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFAA80FFFFF2F2F2FFCFCFCFFFF1F1 + F1FFF1F1F1FFF0F0F0FFDACCF6FFAA80FFFFAA80FFFFAA80FFFFAA80FFFFDACC + F6FFE0E0E0FFEDEDEDFFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1 + F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFE8E3F4FFAF88FEFFAA80 + FFFFAA80FFFFAA80FFFFD5C4F7FFC7C7C7FFD1D1D1FFEEEEEEFFF1F1F1FFF0F0 + F0FFE4E4E4FFB4B4B4FF727272FFC8C8C8FFF1F1F1FFF3F3F3FFF2F2F2FFF2F2 + F2FFB490FDFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81 + FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81 + FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFF2F2F2FFE7E7E7FFF2F2 + F2FFF2F2F2FFE9E3F4FFB089FEFFAB81FFFFAB81FFFFAB81FFFFC7AEFAFFE8E8 + E8FFEBEBEBFFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2 + F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFD6C5F7FFAB81 + FFFFAB81FFFFAB81FFFFB089FEFFE9E3F4FFE7E7E7FFF1F1F1FFF2F2F2FFF1F1 + F1FFE5E5E5FFB5B5B5FF737373FFC9C9C9FFF2F2F2FFF4F4F4FFF3F3F3FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF2F2 + F2FFE6E6E6FFB6B6B6FF737373FFC9C9C9FFF3F3F3FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3 + F3FFE7E7E7FFB7B7B7FF747474FFCACACAFFF3F3F3FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4 + F4FFE8E8E8FFB7B7B7FF747474FFCACACAFFF4F4F4FFF6F6F6FFF6F6F6FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5 + F5FFE8E8E8FFB8B8B8FF747474FFCBCBCBFFF4F4F4FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6 + F6FFE9E9E9FFB9B9B9FF757575FFCCCCCCFFF5F5F5FFF8F8F8FFF8F8F8FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7 + F7FFEAEAEAFFBABABAFF757575FFCCCCCCFFF6F6F6FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF8F8 + F8FFEBEBEBFFBABABAFF767676FFCCCCCCFFF6F6F6FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF8F8 + F8FFEBEBEBFFBABABAFF767676FFCDCDCDFFF7F7F7FFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFF9F9 + F9FFECECECFFBBBBBBFF767676FFCECECEFFF8F8F8FFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFAFA + FAFFEDEDEDFFBCBCBCFF777777FFCECECEFFF8F8F8FFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFBFB + FBFFEEEEEEFFBDBDBDFF777777FFCECECEFFF8F8F8FFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFBFB + FBFFEEEEEEFFBDBDBDFF777777FFCECECEFFF9F9F9FFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFCFC + FCFFEFEFEFFFBDBDBDFF787878FFCECECEFFF9F9F9FFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFF0F0F0FFBEBEBEFF787878FFCFCFCFFFFAFAFAFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFD0D0D0FF828282FFCECECEFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFA7A7A7FFD4D4D4FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD4D4D4FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000280000003000000060000000010020000000 + 00008025000000000000000000000000000000000000838383FF616161FF5353 + 53FF515151FF515151FF515151FF515151FF515151FF515151FF515151FF5151 + 51FF515151FF515151FF515151FF515151FF515151FF515151FF515151FF5151 + 51FF515151FF515151FF515151FF515151FF515151FF515151FF515151FF5151 + 51FF515151FF515151FF515151FF515151FF515151FF515151FF515151FF5151 + 51FF515151FF515151FF515151FF515151FF515151FF515151FF515151FF5151 + 51FF515151FF515151FF515151FF4B4B4BFF4B4B4BFFA9A9A9FFAAAAAAFE9B9B + 9BFE999999FF999999FE999999FE999999FF999999FE999999FE999999FF9999 + 99FE999999FF999999FE999999FE999999FE999999FF999999FE999999FE9999 + 99FF999999FE999999FE999999FF999999FE999999FE999999FF999999FE9999 + 99FE999999FF999999FE999999FE999999FF999999FE999999FF999999FE9999 + 99FE999999FF999999FE999999FE999999FF999999FE999999FE999999FF9999 + 99FE999999FE999999FF969696FE838383FE5C5C5CFEB5B5B5FFC8C8C8FEC3C3 + C3FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2C2FFC2C2 + C2FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2C2FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2 + C2FFC2C2C2FEC2C2C2FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2C2FFC2C2C2FEC2C2 + C2FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2C2FFC2C2C2FEC2C2C2FFC2C2C2FEC2C2 + C2FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2C2FFC2C2C2FEC2C2C2FEC2C2C2FFC2C2 + C2FEC2C2C2FEC2C2C2FFBEBEBEFEA4A4A4FE6D6D6DFEB7B7B7FFCCCCCCFFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9 + C9FFC9C9C9FFC9C9C9FFC5C5C5FFAAAAAAFF6F6F6FFFB7B7B7FFCCCCCCFEC9C9 + C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9C9FFC9C9 + C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9 + C9FFC9C9C9FEC9C9C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9C9FFC9C9C9FEC9C9 + C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9C9FFC9C9C9FEC9C9C9FFC9C9C9FEC9C9 + C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9C9FFC9C9C9FEC9C9C9FEC9C9C9FFC9C9 + C9FEC9C9C9FEC9C9C9FFC5C5C5FEAAAAAAFE6F6F6FFEB8B8B8FFCDCDCDFECBCB + CBFECACACAFFCACACAFECACACAFECACACAFFCACACAFECACACAFECACACAFFCACA + CAFECACACAFFCACACAFECACACAFECACACAFECACACAFFCACACAFECACACAFECACA + CAFFCACACAFECACACAFECACACAFFCACACAFECACACAFECACACAFFCACACAFECACA + CAFECACACAFFCACACAFECACACAFECACACAFFCACACAFECACACAFFCACACAFECACA + CAFECACACAFFCACACAFECACACAFECACACAFFCACACAFECACACAFECACACAFFCACA + CAFECACACAFECACACAFFC7C7C7FEABABABFE6F6F6FFEB9B9B9FFCFCFCFFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFC8C8C8FFADADADFF707070FFB9B9B9FFCFCFCFFECCCC + CCFECCCCCCFFCCCCCCFECCCCCCFECCCCCCFFCCCCCCFECCCCCCFECCCCCCFFCCCC + CCFECCCCCCFFCCCCCCFECCCCCCFECCCCCCFECCCCCCFFCCCCCCFECCCCCCFECCCC + CCFFCCCCCCFECCCCCCFECCCCCCFFCCCCCCFECCCCCCFECCCCCCFFCCCCCCFECCCC + CCFECCCCCCFFCCCCCCFECCCCCCFECCCCCCFFCCCCCCFECCCCCCFFCCCCCCFECCCC + CCFECCCCCCFFCCCCCCFECCCCCCFECCCCCCFFCCCCCCFECCCCCCFECCCCCCFFCCCC + CCFECCCCCCFECCCCCCFFC8C8C8FEADADADFE707070FEBABABAFFD0D0D0FECECE + CEFECDCDCDFFCDCDCDFECDCDCDFECDCDCDFFCDCDCDFECDCDCDFECDCDCDFFCDCD + CDFECDCDCDFFCDCDCDFECDCDCDFECDCDCDFECDCDCDFFCDCDCDFECDCDCDFECDCD + CDFFCDCDCDFECDCDCDFECDCDCDFFCDCDCDFECDCDCDFECDCDCDFFCDCDCDFECDCD + CDFECDCDCDFFCDCDCDFECDCDCDFECDCDCDFFCDCDCDFECDCDCDFFCDCDCDFECDCD + CDFECDCDCDFFCDCDCDFECDCDCDFECDCDCDFFCDCDCDFECDCDCDFECDCDCDFFCDCD + CDFECDCDCDFECDCDCDFFCACACAFEAEAEAEFE717171FEBABABAFFD2D2D2FFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF + CFFFCFCFCFFFCFCFCFFFCBCBCBFFAFAFAFFF727272FFBBBBBBFFD2D2D2FED0D0 + D0FED0D0D0FFD0D0D0FED0D0D0FECACACAFFC0C0C0FEBDBDBDFEC1C1C1FFCACA + CAFED0D0D0FFD0D0D0FED0D0D0FED0D0D0FED0D0D0FFD0D0D0FED0D0D0FED0D0 + D0FFD0D0D0FED0D0D0FED0D0D0FFCFCFCFFECACACAFEBFBFBFFFBCBCBCFEC0C0 + C0FECCCCCCFFD0D0D0FED0D0D0FED0D0D0FFD0D0D0FED0D0D0FFD0D0D0FED0D0 + D0FED0D0D0FFD0D0D0FED0D0D0FECECECEFFC2C2C2FEBDBDBDFEBDBDBDFFC3C3 + C3FECDCDCDFED0D0D0FFCCCCCCFEB0B0B0FE737373FEBCBCBCFFD4D4D4FFD2D2 + D2FFD2D2D2FFD1D1D1FFD2D2D2FFCECECEFFCBCBCBFFC9C9C9FFA6A6A6FFAFAF + AFFFCDCDCDFFD1D1D1FFD1D1D1FFD1D1D1FFD2D2D2FFD1D1D1FFD1D1D1FFD2D2 + D2FFD1D1D1FFD1D1D1FFD2D2D2FFD0D0D0FFCFCFCFFFCACACAFFC9C9C9FFB3B3 + B3FFB1B1B1FFCDCDCDFFD1D1D1FFD2D2D2FFD1D1D1FFD2D2D2FFD1D1D1FFD1D1 + D1FFD2D2D2FFD1D1D1FFD1D1D1FFCCCCCCFFCCCCCCFFC9C9C9FFC5C5C5FFB2B2 + B2FFC5C5C5FFD1D1D1FFCECECEFFB1B1B1FF747474FFBCBCBCFFD5D5D5FED3D3 + D3FED3D3D3FFD3D3D3FED5D5D5FE7345D1FF5C23CFFE5C23CFFE977DC9FFA5A4 + A6FEBEBEBEFFD3D3D3FED3D3D3FED3D3D3FED3D3D3FFD3D3D3FED3D3D3FED3D3 + D3FFD3D3D3FED3D3D3FED3D3D3FFC6BFD4FE7E55D1FE5C23CFFF5C23CFFE9D81 + D3FEA3A3A3FFB8B8B8FED0D0D0FED3D3D3FFD3D3D3FED3D3D3FFD3D3D3FED3D3 + D3FED3D3D3FFD3D3D3FECCC9D2FE8965D1FF5C23CFFE5C23CFFE6D3CD1FFC6C2 + CFFECBCBCBFED3D3D3FFCFCFCFFEB3B3B3FE747474FEBEBEBEFFD6D6D6FED4D4 + D4FED4D4D4FFD4D4D4FED5D5D5FEAD97D8FF652FD2FE5E25D1FE784AD4FFA8A0 + BAFEA9A9A9FFD1D1D1FED4D4D4FED4D4D4FED4D4D4FFD4D4D4FED4D4D4FED4D4 + D4FFD4D4D4FED4D4D4FED4D4D4FFD5D5D5FEC2B6D9FE652FD2FF5E25D1FE6833 + D2FEABA1BFFFA4A4A4FEC6C6C6FED4D4D4FFD4D4D4FED4D4D4FFD4D4D4FED4D4 + D4FED4D4D4FFD4D4D5FEAE9AD7FE6935D3FF5E25D1FE6935D2FEA58FD1FFCCCC + CCFED3D3D3FED4D4D4FFD0D0D0FEB3B3B3FE747474FEBFBFBFFFD8D8D8FED6D6 + D6FED5D5D5FFD5D5D5FED5D5D5FED0CADBFF8860D8FE6128D4FE652DD5FF9C80 + D4FEA1A0A4FFC5C5C5FED5D5D5FED5D5D5FED5D5D5FFD5D5D5FED5D5D5FED5D5 + D5FFD5D5D5FED5D5D5FED5D5D5FFD5D5D5FEDADADAFE9E81DBFF6128D4FE6128 + D4FE8761D5FFB2AFB8FEB1B1B1FED3D3D3FFD5D5D5FED5D5D5FFD5D5D5FED5D5 + D5FED5D5D5FFC9C2D8FE8156D7FE6229D4FF632AD4FE9471D9FEC7C3CFFFD3D3 + D3FED5D5D5FED5D5D5FFD1D1D1FEB5B5B5FE757575FEC0C0C0FFD9D9D9FFD7D7 + D7FFD7D7D7FFD7D7D7FFD7D7D7FFDADADAFFBEAEE0FF723FD9FF642BD8FF7847 + DAFFAEA3C6FFA8A8A8FFCFCFCFFFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7 + D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD5D0DFFF926DDDFF662E + D8FF6932D8FF9C81D4FFA09FA4FFBDBDBDFFD5D5D5FFD7D7D7FFD7D7D7FFD7D7 + D7FFDBDADCFF9976DEFF642BD7FF642BD8FF8257DAFFC5BCD6FFD3D3D3FFD7D7 + D7FFD7D7D7FFD7D7D7FFD3D3D3FFB6B6B6FF767676FFC0C0C0FFDADADAFED8D8 + D8FED8D8D8FFD8D8D8FED8D8D8FED9D9D9FFDDDBE1FE9A76E1FE682FDBFF672E + DAFEA384E2FFAAAAAAFEBDBDBDFED6D6D6FED8D8D8FFD8D8D8FED8D8D8FED8D8 + D8FFD8D8D8FED8D8D8FED8D8D8FFD8D8D8FED8D8D8FEDCDCDCFFC9BCE4FE7948 + DDFE682FDBFF7948DDFEB4A6D2FEA8A8A8FFCACACAFED8D8D8FFD8D8D8FEDADA + DAFEC7B8E4FF6E38DBFE672EDAFE6B33DBFFBEADE0FED2D2D2FED7D7D7FFD8D8 + D8FED8D8D8FED8D8D8FFD4D4D4FEB7B7B7FE777777FEC1C1C1FFDBDBDBFEDADA + DAFED9D9D9FFD9D9D9FED9D9D9FED9D9D9FFDDDDDDFED4C9E9FE6B32DEFF6B32 + DEFE733EDFFFBFB6D0FEADADADFED1D1D1FED9D9D9FFD9D9D9FED9D9D9FED9D9 + D9FFD9D9D9FED9D9D9FED9D9D9FFD9D9D9FED9D9D9FEDADADAFFE0E0E2FEB298 + E7FE6B32DEFF6B32DEFE8E64E3FEBABABAFFAFAFAFFED4D4D4FFDBDBDBFED9D3 + E5FE8F65E3FF6B32DEFE6B32DEFE9A75E5FFD8D6DBFED7D7D7FED9D9D9FFD9D9 + D9FED9D9D9FED9D9D9FFD5D5D5FEB8B8B8FE787878FEC3C3C3FFDDDDDDFFDBDB + DBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFE4E4E4FFB092ECFF7038 + E2FF6F36E2FF9B78E2FFB5B4B9FFBDBDBDFFDBDBDBFFDBDBDBFFDBDBDBFFDBDB + DBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFE8E8 + E8FF9A73E9FF7038E2FF6F36E2FFAC91E2FFB1AFB3FFBEBEBEFFDFDDE3FFAE90 + E9FF733BE3FF7037E2FF9166E7FFD0C9DFFFD6D6D6FFDBDBDBFFDBDBDBFFDBDB + DBFFDBDBDBFFDBDBDBFFD7D7D7FFBABABAFF787878FFC4C4C4FFDEDEDEFEDCDC + DCFEDCDCDCFFDCDCDCFEDCDCDCFEDCDCDCFFDCDCDCFEDDDDDDFED9CEF0FF8656 + E8FE7239E5FF8250E7FEB9AAD7FEABABABFED5D5D5FFDCDCDCFEDCDCDCFEDCDC + DCFFDCDCDCFEDCDCDCFEDCDCDCFFDCDCDCFEDCDCDCFEDCDCDCFFDCDCDCFEDFDF + DFFED7CAF0FF8859E8FE7239E5FE8351E8FFBBACD8FEB7B7B7FFCEBFEDFE824F + E7FE7239E5FF7E4BE7FEC5B2EBFEDBDBDCFFDCDCDCFEDCDCDCFEDCDCDCFFDCDC + DCFEDCDCDCFEDCDCDCFFD8D8D8FEBABABAFE787878FEC4C4C4FFDFDFDFFEDDDD + DDFEDDDDDDFFDDDDDDFEDDDDDDFEDDDDDDFFDDDDDDFEDDDDDDFEE5E3E8FFB699 + F1FE7941E9FF773FE9FEA481ECFEB1ADBAFEC3C3C3FFDCDCDCFEDDDDDDFEDDDD + DDFFDDDDDDFEDDDDDDFEDDDDDDFFDDDDDDFEDDDDDDFEDDDDDDFFDDDDDDFEDDDD + DDFEE3E1E6FFBFA7F0FE7E49EAFE783FE9FFA07CEBFECEC9D8FF996FEEFE763D + E9FE763DE9FFA988EBFED9D7DEFEDBDBDBFFDDDDDDFEDDDDDDFEDDDDDDFFDDDD + DDFEDDDDDDFEDDDDDDFFD9D9D9FEBCBCBCFE797979FEC5C5C5FFE0E0E0FFDFDF + DFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFE2E2E2FFDFD7 + F1FF976AF2FF7B42EEFF824CEFFFCAB9ECFFA5A5A5FFD1D1D1FFDEDEDEFFDFDF + DFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDF + DFFFE1E1E1FFECEBEFFFAF8CF3FF7B42EFFF7B42EEFF996DF2FF7B42EEFF7B42 + EEFF9161F1FFEAE8EEFFDCDCDCFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDF + DFFFDFDFDFFFDFDFDFFFDBDBDBFFBDBDBDFF7A7A7AFFC6C6C6FFE1E1E1FEE0E0 + E0FEE0E0E0FFE0E0E0FEE0E0E0FEE0E0E0FFE0E0E0FEE0E0E0FEE0E0E0FFE9E9 + E9FEC8B1F6FF7F46F2FE7F46F2FEA279F5FEC7C6CAFFBBBBBBFEDCDCDCFEE0E0 + E0FFE0E0E0FEE0E0E0FEE0E0E0FFE0E0E0FEE0E0E0FEE0E0E0FFE0E0E0FEE0E0 + E0FEE0E0E0FFE4E4E4FEE4DDF2FE9261F4FF7F46F2FE7F46F2FF7F46F2FE8A55 + F3FEC8B5EEFFDBDBDBFEDFDFDFFEE0E0E0FFE0E0E0FEE0E0E0FEE0E0E0FFE0E0 + E0FEE0E0E0FEE0E0E0FFDCDCDCFEBEBEBEFE7B7B7BFEC7C7C7FFE2E2E2FEE1E1 + E1FEE1E1E1FFE1E1E1FEE1E1E1FEE1E1E1FFE1E1E1FEE1E1E1FEE1E1E1FFE3E3 + E3FEEDEAF3FF9565F7FE834AF6FE864EF6FEC9B9E8FFB3B3B3FED3D3D3FEE1E1 + E1FFE1E1E1FEE1E1E1FEE1E1E1FFE1E1E1FEE1E1E1FEE1E1E1FFE1E1E1FEE1E1 + E1FEE1E1E1FFE1E1E1FEE6E6E6FEC8AFFBFF834AF6FE834AF6FF844CF6FEB695 + F9FEC2BEC8FFD1D1D1FEE1E1E1FEE1E1E1FFE1E1E1FEE1E1E1FEE1E1E1FFE1E1 + E1FEE1E1E1FEE1E1E1FFDDDDDDFEBFBFBFFE7C7C7CFEC9C9C9FFE5E5E5FFE4E4 + E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4 + E4FFE9E9E9FFD3C0FAFF8D57FAFF874EFAFFA57AFBFFC4BFCEFFBBBBBBFFE2E2 + E2FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4 + E4FFE4E4E4FFE4E4E4FFE6E2EDFFA276FCFF874EFAFF874EFBFF874EFAFF9F72 + FBFFC6BCDAFFB3B3B3FFDADADAFFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4 + E4FFE4E4E4FFE4E4E4FFE0E0E0FFC1C1C1FF7C7C7CFFCACACAFFE6E6E6FEE5E5 + E5FEE5E5E5FFE5E5E5FEE5E5E5FEE5E5E5FFE5E5E5FEE5E5E5FEE5E5E5FFE5E5 + E5FEE5E5E5FFE7E2F1FEAF88FDFE8C53FDFE9560FEFFC0AAEBFEB0AFB2FED7D7 + D7FFE5E5E5FEE5E5E5FEE5E5E5FFE5E5E5FEE5E5E5FEE5E5E5FFE5E5E5FEE5E5 + E5FEE5E5E5FFEAE9ECFEC7ADFAFE8C54FEFF8C53FDFE9460FDFF8C53FDFE8C53 + FDFEBA98FDFFBDBDBDFEC0C0C0FEE1E1E1FFE5E5E5FEE5E5E5FEE5E5E5FFE5E5 + E5FEE5E5E5FEE5E5E5FFE1E1E1FEC2C2C2FE7C7C7CFECBCBCBFFE7E7E7FEE6E6 + E6FEE6E6E6FFE6E6E6FEE6E6E6FEE6E6E6FFE6E6E6FEE6E6E6FEE6E6E6FFE6E6 + E6FEE6E6E6FFE9E9EAFED5C4F8FE9B6AFEFE915BFFFFAD85FDFEBAB3C7FEBFBF + BFFFE3E3E3FEE6E6E6FEE6E6E6FFE6E6E6FEE6E6E6FEE6E6E6FFE6E6E6FEE6E6 + E6FEE7E7E7FFD8CAF4FEA072FEFE915AFFFF9966FEFECAB6F2FFA478FDFE915A + FEFE9561FEFFC6B8E3FEB1B1B1FED0D0D0FFE6E6E6FEE6E6E6FEE6E6E6FFE6E6 + E6FEE6E6E6FEE6E6E6FFE2E2E2FEC3C3C3FE7D7D7DFECCCCCCFFE8E8E8FFE8E8 + E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8 + E8FFE8E8E8FFE8E8E8FFEDECF0FFBA98FCFF9560FFFF9560FFFFCDB6FBFFACAC + ACFFD2D2D2FFE7E7E7FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8 + E8FFE5DDF3FFAF88FDFF9560FFFF9865FFFFC2A6F8FFE1DFE5FFDCCDF9FF9F6F + FEFF9560FFFFA579FEFFC9BFDCFFB6B6B6FFDFDFDFFFE8E8E8FFE8E8E8FFE8E8 + E8FFE8E8E8FFE8E8E8FFE4E4E4FFC5C5C5FF7E7E7EFFCCCCCCFFE9E9E9FEE9E9 + E9FEE9E9E9FFE9E9E9FEE9E9E9FEE9E9E9FFE9E9E9FEE9E9E9FEE9E9E9FFE9E9 + E9FEE9E9E9FFE9E9E9FEEBEBEBFEE2D9F4FE9D6CFEFF9865FEFEA67BFDFEC5C1 + CDFFBCBCBCFEE2E2E2FEE9E9E9FFE9E9E9FEE9E9E9FEE9E9E9FFE9E9E9FEEAEA + EAFEC6ACFBFF9967FEFE9865FEFEAC85FBFFDBD4E8FEE4E4E4FFEAE7EFFEC4A9 + F9FE9C6BFEFF9A67FEFEB99AF6FEB4B1BBFFC2C2C2FEE4E4E4FEE9E9E9FFE9E9 + E9FEE9E9E9FEE9E9E9FFE5E5E5FEC5C5C5FE7E7E7EFECDCDCDFFEBEBEBFEEAEA + EAFEEAEAEAFFEAEAEAFEEAEAEAFEEAEAEAFFEAEAEAFEEAEAEAFEEAEAEAFFEAEA + EAFEEAEAEAFFEAEAEAFEEAEAEAFEEFEFEFFEBC9CFBFF9C6AFEFE9C6AFEFEC0AB + EDFFB8B8B8FED3D3D3FEEAEAEAFFEAEAEAFEEAEAEAFEEAEAEAFFEAEAEAFEE0D6 + F2FEA273FEFF9C6AFEFE9C6AFEFED7CAF3FFE4E4E4FEE9E9E9FFEBEBEBFEE5DF + F3FEAF89FCFF9C6AFEFEA173FEFEC9B6EDFFB1B1B1FED3D3D3FEE9E9E9FFEAEA + EAFEEAEAEAFEEAEAEAFFE6E6E6FEC6C6C6FE7F7F7FFECECECEFFECECECFFECEC + ECFFECECECFFE7E7E7FFE2E2E2FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1 + E1FFE1E1E1FFE1E1E1FFE1E1E1FFE1E1E1FFDED7EFFFAD86FDFF9F70FFFFAD84 + FDFFC2B9D4FFC4C4C4FFECECECFFECECECFFECECECFFECECECFFE6E1F0FFB38F + FCFF9F70FFFFA172FEFFC5AAFAFFE0E0E0FFE9E9E9FFECECECFFECECECFFEDED + EDFFDFD4F4FFA478FEFF9F70FFFFA67AFEFFD3CDE2FFB3B3B3FFDBDBDBFFECEC + ECFFECECECFFECECECFFE8E8E8FFC8C8C8FF808080FFCFCFCFFFEDEDEDFEEDED + EDFEEDEDEDFFE4E4E4FEDBDBDBFED9D9D9FFD9D9D9FED9D9D9FED9D9D9FFD9D9 + D9FED9D9D9FFD9D9D9FED9D9D9FED9D9D9FEE4E2E7FFCAB3F8FEA579FEFEA579 + FEFFC7B3EFFEC9C9C9FEEDEDEDFFEDEDEDFEEDEDEDFEE9E7EDFFC8B1F6FEA67A + FEFEA375FFFFB490FBFEDDD6ECFEE7E7E7FFEDEDEDFEEDEDEDFFEDEDEDFEEDED + EDFEEFEFEFFFC7AEF9FEA477FEFEA375FFFFB89BF3FEB9B5C0FEC1C1C1FFE9E9 + E9FEEDEDEDFEEDEDEDFFE9E9E9FEC8C8C8FE808080FED0D0D0FFEEEEEEFFEFEF + EFFFE5DEF3FFBC9DFAFFB998FBFFB998FCFFB998FBFFB998FBFFB998FCFFB998 + FBFFB998FCFFB998FBFFB998FBFFB998FBFFB998FCFFB18CFDFFA67BFEFFA579 + FFFFCBB5F8FFCDCDCDFFEFEFEFFFEEEEEEFFEDEDEDFFDFD5F4FFAD86FDFFA579 + FFFFAB82FEFFCCBBEEFFE2E2E4FFEEEEEEFFEEEEEEFFEFEFEFFFEEEEEEFFEEEE + EEFFEFEFEFFFE5DEF3FFB795FCFFA579FFFFA97FFEFFCAB8EFFFB6B6B7FFD8D8 + D8FFEDEDEDFFEFEFEFFFEAEAEAFFCACACAFF818181FFD1D1D1FFF0F0F0FEF0F0 + F0FEE2D8F4FFAD85FDFEA87DFEFEA87DFFFFA87DFEFEA87DFEFEA87DFFFFA87D + FEFEA87DFFFFA87DFEFEA87DFEFEA87DFEFEA87DFFFFA87DFEFEA87DFEFEA87D + FFFFCDB7F8FED0D0D0FEF0F0F0FFEFEFEFFEE8E5EDFEB693FCFFA87DFEFEA87D + FEFEC7AFF8FFE6E5E9FEECECECFEF0F0F0FFF0F0F0FEF0F0F0FFF0F0F0FEF0F0 + F0FEF0F0F0FFF0F0F0FEDDD2F5FEB28CFDFFA87DFEFEB18CFDFEC2B7D9FFB3B3 + B3FEE2E2E2FEF0F0F0FFECECECFECBCBCBFE828282FED1D1D1FFF1F1F1FEF1F1 + F1FEE2D9F4FFAF87FDFEAA80FEFEAA80FFFFAA80FEFEAA80FEFEAA80FFFFAA80 + FEFEAA80FFFFAA80FEFEAA80FEFEAA80FEFEAA80FFFFAA80FEFEAA80FEFEAA80 + FFFFCEB9F8FEE0E0E0FEF1F1F1FFEEEDF1FECEBAF7FEAA80FFFFAA80FEFEB491 + FDFEE2DDECFFEAEAEAFEF0F0F0FEF1F1F1FFF1F1F1FEF1F1F1FFF1F1F1FEF1F1 + F1FEF1F1F1FFF1F1F1FEEFEDF2FECDB7F8FFAA80FEFEAA80FEFEBC9DFBFFD8D6 + DDFEE5E5E5FEF1F1F1FFEDEDEDFECCCCCCFE828282FED3D3D3FFF2F2F2FFF3F3 + F3FFEFECF3FFE2D8F5FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6 + F6FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6F6FFE1D6 + F6FFEAE4F4FFF0F0F0FFF3F3F3FFF1F1F3FFE5DEF5FFE1D6F6FFE1D6F6FFE6DF + F5FFF0F0F0FFF2F2F2FFF2F2F2FFF3F3F3FFF2F2F2FFF3F3F3FFF2F2F2FFF2F2 + F2FFF3F3F3FFF2F2F2FFF2F2F2FFEDEAF4FFE1D6F6FFE1D6F6FFE2D8F6FFF0EF + F2FFF1F1F1FFF3F3F3FFEEEEEEFFCDCDCDFF838383FFD3D3D3FFF3F3F3FEF4F4 + F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4F4FFF4F4 + F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4 + F4FFF4F4F4FEF4F4F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4F4FFF4F4F4FEF4F4 + F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4F4FFF4F4F4FEF4F4F4FFF4F4F4FEF4F4 + F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4F4FFF4F4F4FEF4F4F4FEF4F4F4FFF4F4 + F4FEF4F4F4FEF4F4F4FFF0F0F0FECFCFCFFE848484FED4D4D4FFF4F4F4FEF5F5 + F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5F5FFF5F5 + F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5 + F5FFF5F5F5FEF5F5F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5F5FFF5F5F5FEF5F5 + F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5F5FFF5F5F5FEF5F5F5FFF5F5F5FEF5F5 + F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5F5FFF5F5F5FEF5F5F5FEF5F5F5FFF5F5 + F5FEF5F5F5FEF5F5F5FFF1F1F1FECFCFCFFE848484FED5D5D5FFF5F5F5FFF6F6 + F6FFF7F7F7FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6 + F6FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6F6FFF6F6F6FFF7F7 + F7FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6F6FFF6F6 + F6FFF7F7F7FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6F6FFF7F7F7FFF6F6F6FFF6F6 + F6FFF7F7F7FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6F6FFF6F6F6FFF7F7F7FFF6F6 + F6FFF6F6F6FFF7F7F7FFF2F2F2FFD0D0D0FF858585FFD6D6D6FFF6F6F6FEF8F8 + F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8F8FFF8F8 + F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8 + F8FFF8F8F8FEF8F8F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8F8FFF8F8F8FEF8F8 + F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8F8FFF8F8F8FEF8F8F8FFF8F8F8FEF8F8 + F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8F8FFF8F8F8FEF8F8F8FEF8F8F8FFF8F8 + F8FEF8F8F8FEF8F8F8FFF3F3F3FED2D2D2FE868686FED6D6D6FFF7F7F7FEF8F8 + F8FEF9F9F9FFF8F8F8FEF8F8F8FEF9F9F9FFF8F8F8FEF8F8F8FEF9F9F9FFF8F8 + F8FEF9F9F9FFF8F8F8FEF8F8F8FEF8F8F8FEF9F9F9FFF8F8F8FEF8F8F8FEF9F9 + F9FFF8F8F8FEF8F8F8FEF9F9F9FFF8F8F8FEF8F8F8FEF9F9F9FFF8F8F8FEF8F8 + F8FEF9F9F9FFF8F8F8FEF8F8F8FEF9F9F9FFF8F8F8FEF9F9F9FFF8F8F8FEF8F8 + F8FEF9F9F9FFF8F8F8FEF8F8F8FEF9F9F9FFF8F8F8FEF8F8F8FEF9F9F9FFF8F8 + F8FEF8F8F8FEF9F9F9FFF4F4F4FED2D2D2FE868686FED7D7D7FFF8F8F8FFF9F9 + F9FFFAFAFAFFF9F9F9FFF9F9F9FFFAFAFAFFF9F9F9FFF9F9F9FFFAFAFAFFF9F9 + F9FFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFFAFAFAFFF9F9F9FFF9F9F9FFFAFA + FAFFF9F9F9FFF9F9F9FFFAFAFAFFF9F9F9FFF9F9F9FFFAFAFAFFF9F9F9FFF9F9 + F9FFFAFAFAFFF9F9F9FFF9F9F9FFFAFAFAFFF9F9F9FFFAFAFAFFF9F9F9FFF9F9 + F9FFFAFAFAFFF9F9F9FFF9F9F9FFFAFAFAFFF9F9F9FFF9F9F9FFFAFAFAFFF9F9 + F9FFF9F9F9FFFAFAFAFFF5F5F5FFD3D3D3FF878787FFD8D8D8FFF9F9F9FEFBFB + FBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFBFBFFFBFB + FBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFBFBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFB + FBFFFBFBFBFEFBFBFBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFBFBFFFBFBFBFEFBFB + FBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFBFBFFFBFBFBFEFBFBFBFFFBFBFBFEFBFB + FBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFBFBFFFBFBFBFEFBFBFBFEFBFBFBFFFBFB + FBFEFBFBFBFEFBFBFBFFF6F6F6FED4D4D4FE888888FED8D8D8FFF9F9F9FEFBFB + FBFEFCFCFCFFFBFBFBFEFBFBFBFEFCFCFCFFFBFBFBFEFBFBFBFEFCFCFCFFFBFB + FBFEFCFCFCFFFBFBFBFEFBFBFBFEFBFBFBFEFCFCFCFFFBFBFBFEFBFBFBFEFCFC + FCFFFBFBFBFEFBFBFBFEFCFCFCFFFBFBFBFEFBFBFBFEFCFCFCFFFBFBFBFEFBFB + FBFEFCFCFCFFFBFBFBFEFBFBFBFEFCFCFCFFFBFBFBFEFCFCFCFFFBFBFBFEFBFB + FBFEFCFCFCFFFBFBFBFEFBFBFBFEFCFCFCFFFBFBFBFEFBFBFBFEFCFCFCFFFBFB + FBFEFBFBFBFEFCFCFCFFF7F7F7FED5D5D5FE888888FED9D9D9FFFAFAFAFFFCFC + FCFFFDFDFDFFFCFCFCFFFCFCFCFFFDFDFDFFFCFCFCFFFCFCFCFFFDFDFDFFFCFC + FCFFFDFDFDFFFCFCFCFFFCFCFCFFFCFCFCFFFDFDFDFFFCFCFCFFFCFCFCFFFDFD + FDFFFCFCFCFFFCFCFCFFFDFDFDFFFCFCFCFFFCFCFCFFFDFDFDFFFCFCFCFFFCFC + FCFFFDFDFDFFFCFCFCFFFCFCFCFFFDFDFDFFFCFCFCFFFDFDFDFFFCFCFCFFFCFC + FCFFFDFDFDFFFCFCFCFFFCFCFCFFFDFDFDFFFCFCFCFFFCFCFCFFFDFDFDFFFCFC + FCFFFCFCFCFFFDFDFDFFF8F8F8FFD6D6D6FF898989FFD9D9D9FFFBFBFBFEFDFD + FDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFDFDFFFDFD + FDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFDFDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFD + FDFFFDFDFDFEFDFDFDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFDFDFFFDFDFDFEFDFD + FDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFDFDFFFDFDFDFEFDFDFDFFFDFDFDFEFDFD + FDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFDFDFFFDFDFDFEFDFDFDFEFDFDFDFFFDFD + FDFEFDFDFDFEFDFDFDFFFAFAFAFEDADADAFE8C8C8CFED9D9D9FFFBFBFBFEFCFC + FCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFCFCFFFCFC + FCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFCFCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFC + FCFFFCFCFCFEFCFCFCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFCFCFFFCFCFCFEFCFC + FCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFCFCFFFCFCFCFEFCFCFCFFFCFCFCFEFCFC + FCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFCFCFFFCFCFCFEFCFCFCFEFCFCFCFFFCFC + FCFEFCFCFCFEFCFCFCFFFCFCFCFEF0F0F0FEA8A8A8FED4D4D4FFDADADAFEDADA + DAFEDADADAFFDADADAFEDADADAFEDADADAFFDADADAFEDADADAFEDADADAFFDADA + DAFEDADADAFFDADADAFEDADADAFEDADADAFEDADADAFFDADADAFEDADADAFEDADA + DAFFDADADAFEDADADAFEDADADAFFDADADAFEDADADAFEDADADAFFDADADAFEDADA + DAFEDADADAFFDADADAFEDADADAFEDADADAFFDADADAFEDADADAFFDADADAFEDADA + DAFEDADADAFFDADADAFEDADADAFEDADADAFFDADADAFEDADADAFEDADADAFFDADA + DAFEDADADAFEDADADAFFDADADAFEDADADAFECDCDCDFE00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000028000000200000004000 + 0000010020000000000080100000000000000000000000000000000000008B8B + 8BFF5D5D5DFF4B4B4BFF464646FF454545FF454545FF454545FF454545FF4545 + 45FF454545FF454545FF454545FF454545FF454545FF454545FF454545FF4545 + 45FF454545FF454545FF454545FF454545FF454545FF454545FF454545FF4545 + 45FF454545FF454545FF454545FF454545FF444444FF414141FF555555FFA2A2 + A2FF9F9F9FFF868686FF7D7D7DFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C + 7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C + 7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C + 7CFF7C7C7CFF7C7C7CFF7C7C7CFF7C7C7CFF767676FF626262FF4C4C4CFFAFAF + AFFFC8C8C8FFBFBFBFFFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5 + B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFAAAAAAFF878787FF5F5F5FFFB2B2 + B2FFCECECEFFCDCDCDFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACACAFFCACA + CAFFCACACAFFCACACAFFCACACAFFC9C9C9FFBEBEBEFF969696FF656565FFB3B3 + B3FFCFCFCFFFCECECEFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCBCBCBFFBFBFBFFF979797FF676767FFB4B4 + B4FFD1D1D1FFD0D0D0FFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE + CEFFCECECEFFCECECEFFCECECEFFCDCDCDFFC1C1C1FF999999FF676767FFB5B5 + B5FFD2D2D2FFD2D2D2FFD0D0D0FFCBCBCBFFC1C1C1FFBFBFBFFFC6C6C6FFCECE + CEFFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFCDCDCDFFC5C5 + C5FFBFBFBFFFC3C3C3FFCCCCCCFFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFCDCDCDFFC5C5C5FFBEBEBEFFC0C0C0FFBEBEBEFF9A9A9AFF676767FFB7B7 + B7FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD6D6D6FFBFBFBFFFB1B1B1FFC7C7 + C7FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD3D3D3FFD2D2D2FFD6D6 + D6FFC8C8C8FFB6B6B6FFC0C0C0FFD0D0D0FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2 + D2FFCFCFCFFFD6D6D6FFCECECEFFBEBEBEFFBABABAFF9B9B9BFF686868FFB7B7 + B7FFD6D6D6FFD6D6D6FFDCDCDCFF6F3ED3FF5E25D1FFA287D7FFBCBCBCFFBBBB + BBFFD1D1D1FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD9D9D9FF916FD6FF5E25 + D1FF8056D4FFC9C9C9FFAFAFAFFFC9C9C9FFD4D4D4FFD4D4D4FFD4D4D4FFD6D6 + D6FF997BD7FF5E25D1FF6F3ED3FFD4D0DBFFC0C0C0FF9D9D9DFF686868FFB8B8 + B8FFD8D8D8FFD8D8D8FFDDDDDDFFB9A6E0FF6229D5FF6B36D6FFDCD8E4FFB1B1 + B1FFCACACAFFD6D6D6FFD6D6D6FFD6D6D6FFD6D6D6FFD9D9D9FFE2E2E2FF7C4F + D8FF6229D5FFA88DDEFFC2C2C2FFBBBBBBFFD1D1D1FFD6D6D6FFDADADAFFCBBF + E2FF6229D5FF6229D5FFC2B3E1FFD4D4D4FFC7C7C7FF9F9F9FFF696969FFB9B9 + B9FFD9D9D9FFDADADAFFD8D8D8FFE8E8E8FF8153DDFF662DD9FFA586E2FFC6C6 + C6FFBFBFBFFFD5D5D5FFD8D8D8FFD8D8D8FFD8D8D8FFD8D8D8FFE0E0E0FFC8B9 + E7FF662DD9FF6F3ADAFFE3DFEBFFBDBDBDFFC6C6C6FFD6D6D6FFE6E6E6FF8153 + DDFF662DD9FF9C79E1FFDADADAFFD3D3D3FFCACACAFFA0A0A0FF6A6A6AFFBABA + BAFFDBDBDBFFDCDCDCFFDADADAFFE4E4E4FFC6B3ECFF6B32DEFF743FDFFFEAE6 + F2FFB6B6B6FFCECECEFFDADADAFFDADADAFFDADADAFFDADADAFFDADADAFFE9E9 + E9FFAA8CE8FF6B32DEFF8F65E4FFDBDBDBFFB3B3B3FFE0E0E0FFB499E9FF6B32 + DEFF7D4CE1FFEAE6F2FFD7D7D7FFD9D9D9FFCCCCCCFFA2A2A2FF6B6B6BFFBCBC + BCFFDDDDDDFFDEDEDEFFDCDCDCFFDCDCDCFFF1F1F1FF956BEAFF7138E4FFB092 + EEFFCFCFCFFFC0C0C0FFD8D8D8FFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFE0E0 + E0FFF3F3F3FF8C5FE8FF7138E4FFC3ACF1FFC8C8C8FFF0ECF8FF7A45E5FF7138 + E4FFCCB9F2FFE0E0E0FFDADADAFFDBDBDBFFCECECEFFA4A4A4FF6C6C6CFFBDBD + BDFFDFDFDFFFDFDFDFFFDEDEDEFFDEDEDEFFE8E8E8FFE2D7F9FF763DE9FF7F4A + EAFFF4F0FCFFC1C1C1FFCECECEFFDDDDDDFFDEDEDEFFDEDEDEFFDEDEDEFFDEDE + DEFFEAEAEAFFD9CAF8FF763DE9FF8857ECFFF4F0FCFFA37DF0FF763DE9FFA37D + F0FFEAEAEAFFDADADAFFDEDEDEFFDDDDDDFFD0D0D0FFA5A5A5FF6D6D6DFFBFBF + BFFFE0E0E0FFE1E1E1FFE0E0E0FFE0E0E0FFE0E0E0FFF5F5F5FFA882F4FF7C43 + EFFFA882F4FFDEDEDEFFBFBFBFFFDADADAFFE0E0E0FFE0E0E0FFE0E0E0FFE0E0 + E0FFE0E0E0FFF2F2F2FFB99BF6FF7C43EFFF8D5CF1FF7C43EFFF8D5CF1FFF6F2 + FEFFE0E0E0FFE0E0E0FFE0E0E0FFDFDFDFFFD2D2D2FFA7A7A7FF6D6D6DFFC0C0 + C0FFE2E2E2FFE3E3E3FFE2E2E2FFE2E2E2FFE2E2E2FFE9E9E9FFE6DBFDFF8249 + F5FF8249F5FFE6DBFDFFC3C3C3FFD1D1D1FFE1E1E1FFE2E2E2FFE2E2E2FFE2E2 + E2FFE2E2E2FFE6E6E6FFF9F9F9FF9B6DF7FF8249F5FF8249F5FFCDB6FBFFD8D8 + D8FFD7D7D7FFE2E2E2FFE2E2E2FFE1E1E1FFD4D4D4FFA8A8A8FF6E6E6EFFC2C2 + C2FFE5E5E5FFE6E6E6FFE5E5E5FFE5E5E5FFE5E5E5FFE5E5E5FFF3F3F3FFBFA1 + FCFF8950FCFFB08AFCFFDFDFDFFFC4C4C4FFDFDFDFFFE5E5E5FFE5E5E5FFE5E5 + E5FFE5E5E5FFE5E5E5FFF6F6F6FFA073FCFF8950FCFF8950FCFFDECFFDFFD0D0 + D0FFCDCDCDFFE1E1E1FFE5E5E5FFE4E4E4FFD7D7D7FFAAAAAAFF707070FFC3C3 + C3FFE6E6E6FFE8E8E8FFE7E7E7FFE7E7E7FFE7E7E7FFE7E7E7FFE9E9E9FFF4F0 + FBFF9764FFFF9059FFFFE6DBFCFFC5C5C5FFD5D5D5FFE5E5E5FFE7E7E7FFE7E7 + E7FFE7E7E7FFF0F0F0FFC9AFFDFF9059FFFF9764FFFF9059FFFF9E6FFEFFEFEF + EFFFC3C3C3FFD7D7D7FFE5E5E5FFE6E6E6FFD9D9D9FFACACACFF717171FFC4C4 + C4FFE8E8E8FFEAEAEAFFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFF2F2 + F2FFC4A7FCFF9560FFFFB693FDFFDDDDDDFFC4C4C4FFE2E2E2FFE9E9E9FFE9E9 + E9FFEDEDEDFFE5DAFAFF9560FFFF9560FFFFE5DAFAFFBD9DFDFF9560FFFFBD9D + FDFFD7D7D7FFC4C4C4FFE1E1E1FFE8E8E8FFDADADAFFADADADFF727272FFC4C4 + C4FFEAEAEAFFECECECFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFECEC + ECFFF1EEF8FFA77CFEFF9B69FFFFDED1F9FFCDCDCDFFD9D9D9FFEBEBEBFFEBEB + EBFFF2F2F2FFAD85FDFF9B69FFFFC6ABFBFFE8E8E8FFF1EEF8FFA77CFEFF9B69 + FFFFDED1F9FFCFCFCFFFD2D2D2FFE6E6E6FFDCDCDCFFAFAFAFFF737373FFC6C6 + C6FFEBEBEBFFEAEAEAFFE1E1E1FFD9D9D9FFD5D5D5FFD5D5D5FFD5D5D5FFD5D5 + D5FFE4E4E4FFCDB7FAFFA071FFFFB18BFDFFE6E6E6FFD4D4D4FFECECECFFEEEE + EEFFCDB7FAFFA071FFFFAB83FEFFEFEFEFFFE6E6E6FFF1F1F1FFD3C0F9FFA071 + FFFFAB83FEFFEAEAEAFFC6C6C6FFDBDBDBFFDCDCDCFFB0B0B0FF747474FFC7C7 + C7FFEEEEEEFFEFEFEFFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFF4F4F4FFAF88FEFFA477FFFFEFECF5FFD6D6D6FFEDEDEDFFE9E3 + F5FFA97FFEFFA477FFFFD9CAF8FFE7E7E7FFEDEDEDFFEFEFEFFFF2F2F2FFBFA1 + FBFFA477FFFFC4A9FBFFD6D6D6FFC8C8C8FFD7D7D7FFB2B2B2FF757575FFC8C8 + C8FFF1F1F1FFCBB5FAFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFA87D + FFFFA87DFFFFA87DFFFFA87DFFFFA87DFFFFEEEBF4FFDEDEDEFFF1F1F1FFBC9C + FCFFA87DFFFFC1A4FBFFEAEAEAFFECECECFFF1F1F1FFF1F1F1FFF2F2F2FFEEEB + F4FFAD85FEFFA87DFFFFDFD4F6FFD9D9D9FFD6D6D6FFB2B2B2FF757575FFCACA + CAFFF2F2F2FFCEB7FAFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFAB81 + FFFFAB81FFFFAB81FFFFAB81FFFFAB81FFFFEFECF5FFF0F0F0FFD2BEF9FFAB81 + FFFFB089FEFFEFECF5FFEEEEEEFFF3F3F3FFF3F3F3FFF3F3F3FFF3F3F3FFF4F4 + F4FFD7C6F8FFAB81FFFFB590FEFFEEEBF4FFDFDFDFFFB5B5B5FF757575FFCBCB + CBFFF2F2F2FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFE6E6E6FFB6B6B6FF777777FFCCCC + CCFFF3F3F3FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFE8E8E8FFB8B8B8FF787878FFCDCD + CDFFF5F5F5FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF8F8F8FFE9E9E9FFB9B9B9FF787878FFCECE + CEFFF6F6F6FFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFF9F9F9FFEAEAEAFFBABABAFF787878FFCFCF + CFFFF7F7F7FFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFEEEEEEFFBDBDBDFF7A7A7AFFD0D0 + D0FFF8F8F8FFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFCECECEFF868686FFCFCF + CFFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFFAFAFAFFA7A7A7FFD5D5 + D5FFD0D0D0FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1 + D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1 + D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1 + D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD0D0D0FFD5D5D5FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002800 + 0000180000003000000001002000000000006009000000000000000000000000 + 000000000000888888FF636363FF555555FF525252FF525252FF525252FF5252 + 52FF525252FF525252FF525252FF525252FF525252FF525252FF525252FF5252 + 52FF525252FF525252FF525252FF525252FF525252FF525252FF525252FF4C4C + 4CFF505050FFABABABFFABABABFE9B9B9BFE989898FF989898FE989898FE9898 + 98FF989898FE989898FE989898FF989898FE989898FF989898FE989898FE9898 + 98FE989898FF989898FE989898FE989898FF989898FE989898FE969696FF8282 + 82FE5D5D5DFEB8B8B8FFCACACAFEC5C5C5FEC4C4C4FFC4C4C4FEC4C4C4FEC4C4 + C4FFC4C4C4FEC4C4C4FEC4C4C4FFC4C4C4FEC4C4C4FFC4C4C4FEC4C4C4FEC4C4 + C4FEC4C4C4FFC4C4C4FEC4C4C4FEC4C4C4FFC4C4C4FEC4C4C4FEC1C1C1FFA5A5 + A5FE6F6F6FFEBABABAFFCFCFCFFFCDCDCDFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFC8C8C8FFABAB + ABFF737373FFBBBBBBFFD1D1D1FECFCFCFFECBCBCBFFC6C6C6FEC9C9C9FECECE + CEFFCECECEFECECECEFECFCFCFFFCECECEFECECECEFFC8C8C8FEC7C7C7FECBCB + CBFECFCFCFFFCECECEFECECECEFECECECEFFCBCBCBFEC6C6C6FEC4C4C4FFACAC + ACFE737373FEBDBDBDFFD3D3D3FED3D3D3FED1D1D1FFC7C7C7FEB8B8B8FECBCB + CBFFD1D1D1FED1D1D1FED1D1D1FFD1D1D1FED1D1D1FFCECECEFEBFBFBFFEC0C0 + C0FED0D0D0FFD1D1D1FED1D1D1FED0D0D0FFD0D0D0FECBCBCBFEBDBDBDFFAAAA + AAFE747474FEBFBFBFFFD6D6D6FFDADADAFF794BD5FF794CD4FFB8AFCAFFBEBE + BEFFD2D2D2FFD4D4D4FFD4D4D4FFD6D6D6FFB29FD9FF6A36D3FF9C82D1FFB7B5 + BAFFC9C9C9FFD4D4D4FFD5D5D5FFC1B6D8FF7546D4FF7A4ED5FFCFCDD3FFAFAF + AFFF757575FFC0C0C0FFD8D8D8FEDADADAFEB8A4E1FF6C37D8FEAA8FE0FEBDBD + BDFFCCCCCCFED6D6D6FED7D7D7FFD7D7D7FEDEDEDFFF926DDDFE7747D9FEC0B5 + D7FEC0C0C0FFD0D0D0FEDDDDDDFE9571DDFF713ED8FEBAA9DCFED0D0D0FFB3B3 + B3FE767676FEC2C2C2FFDADADAFED9D9D9FED9D2E5FF8F65E2FE7A48DEFED6D4 + DBFFC3C3C3FED7D7D7FED9D9D9FFD9D9D9FEDBDBDBFFCEC2E7FE8254E0FE956F + E3FECCCCCCFFCACACAFEC7B8E5FE723CDEFFA687E6FED7D4DDFED4D4D4FFB6B6 + B6FE787878FEC4C4C4FFDEDEDEFFDDDDDDFFE1E1E1FFCBBAEEFF7F4CE7FFB196 + E8FFCCCBCDFFD0D0D0FFDCDCDCFFDCDCDCFFDCDCDCFFE3E3E3FFC8B5EEFF7D49 + E7FFBCA5E9FFD8D1E5FF9266EAFF9368E9FFD9D2E7FFDCDCDCFFD8D8D8FFB9B9 + B9FF7A7A7AFFC6C6C6FFDFDFDFFEDFDFDFFEE0E0E0FFE7E4EDFEA681F0FE9163 + EFFFCEC4E3FEC8C8C8FEDCDCDCFFDEDEDEFEDFDFDFFFE0E0E0FEE5E1ECFEAA88 + F0FE9163EFFFA782F2FE8451EDFED2C3F2FFE0E0E0FEDEDEDEFEDADADAFFBBBB + BBFE7B7B7BFEC8C8C8FFE2E2E2FFE1E1E1FFE1E1E1FFE6E6E6FFDCCEF7FF834B + F4FFB799F5FFCAC8CEFFD6D6D6FFE1E1E1FFE1E1E1FFE1E1E1FFE5E5E5FFE9E3 + F4FF8F5DF5FF824AF3FFAE89F7FFDEDDDFFFDDDDDDFFE1E1E1FFDDDDDDFFBDBD + BDFF7C7C7CFFCBCBCBFFE5E5E5FEE5E5E5FEE5E5E5FFE5E5E5FEEDEDEDFEBC9C + FCFF9A69FCFED2C5EBFECACACAFFE0E0E0FEE5E5E5FFE5E5E5FEE6E6E6FEE9E5 + F3FE9866FCFF8B53FCFEBD9DFDFED4D4D4FFD4D4D4FEE3E3E3FEE1E1E1FFC0C0 + C0FE7E7E7EFECCCCCCFFE7E7E7FEE8E8E8FEE8E8E8FFE7E7E7FEE8E8E8FEE1D6 + F8FF9F70FEFEBFA0FDFED0D0D0FFD7D7D7FEE7E7E7FFE8E8E8FEEAE7EFFEBD9E + FBFE9D6DFEFFB28DFDFE9C6CFEFED3C7EBFFCDCDCDFEDDDDDDFEE3E3E3FFC2C2 + C2FE808080FECDCDCDFFEAEAEAFEEAEAEAFEEAEAEAFFEAEAEAFEEAEAEAFEEBE9 + F0FFC4A8FBFEA173FEFED9D1E8FFD2D2D2FEE6E6E6FFECECECFED5C5F6FEA173 + FEFEC5ABF8FFE5DFF2FEB28EFCFEB18DFBFFD4CFDEFED3D3D3FEE3E3E3FFC4C4 + C4FE818181FECFCFCFFFEBEBEBFFE7E7E7FFDFDFDFFFDCDCDCFFDCDCDCFFDFDF + DFFFDFD7F0FFB08AFDFFBC9EF8FFDEDEDFFFE6E6E6FFE2DAF2FFB28DFDFFB18C + FDFFECECECFFECECECFFE0D5F5FFA87DFEFFC5ADF6FFCFCED3FFD7D7D7FFC5C5 + C5FF838383FFD1D1D1FFE6E0F1FED1BEF8FECEB8F9FFCDB8F9FECDB8F9FECEB8 + F9FFCDB8F9FEB48FFDFEB896FCFFE4E2E7FEE9E9E9FFC7AFF9FEAD85FDFED5C6 + F3FEEBEBEBFFEFEFEFFEF1F1F1FECBB4F9FFAF88FDFED1C4EBFED2D2D2FFC4C4 + C4FE848484FED3D3D3FFDFD4F5FEB28DFDFEAA80FFFFAA7FFEFEAA7FFEFEAA80 + FFFFAA7FFEFEAA7FFEFEBB9BFCFFEDEBF0FEDED3F4FFAE87FEFEC8B0FAFEEAE8 + EFFEF1F1F1FFF2F2F2FEF2F2F2FEE9E2F5FFBB9AFCFEBA98FCFEE5E4E9FFC8C8 + C8FE848484FED5D5D5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF1F1F1FFCECE + CEFF878787FFD6D6D6FFF5F5F5FEF7F7F7FEF8F8F8FFF7F7F7FEF7F7F7FEF8F8 + F8FFF7F7F7FEF7F7F7FEF8F8F8FFF7F7F7FEF8F8F8FFF7F7F7FEF7F7F7FEF7F7 + F7FEF8F8F8FFF7F7F7FEF7F7F7FEF8F8F8FFF7F7F7FEF7F7F7FEF3F3F3FFD0D0 + D0FE888888FED7D7D7FFF7F7F7FEF9F9F9FEF9F9F9FFF9F9F9FEF9F9F9FEF9F9 + F9FFF9F9F9FEF9F9F9FEF9F9F9FFF9F9F9FEF9F9F9FFF9F9F9FEF9F9F9FEF9F9 + F9FEF9F9F9FFF9F9F9FEF9F9F9FEF9F9F9FFF9F9F9FEF9F9F9FEF5F5F5FFD1D1 + D1FE888888FED9D9D9FFF9F9F9FFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFF9F9F9FFD9D9 + D9FF8E8E8EFFDADADAFFF9F9F9FEFAFAFAFEFBFBFBFFFAFAFAFEFAFAFAFEFBFB + FBFFFAFAFAFEFAFAFAFEFBFBFBFFFAFAFAFEFBFBFBFFFAFAFAFEFAFAFAFEFAFA + FAFEFBFBFBFFFAFAFAFEFAFAFAFEFBFBFBFFFAFAFAFEFAFAFAFEFBFBFBFFEFEF + EFFEA9A9A9FED5D5D5FFDADADAFEDADADAFEDBDBDBFFDADADAFEDADADAFEDBDB + DBFFDADADAFEDADADAFEDBDBDBFFDADADAFEDBDBDBFFDADADAFEDADADAFEDADA + DAFEDBDBDBFFDADADAFEDADADAFEDBDBDBFFDADADAFEDADADAFEDBDBDBFFDADA + DAFECDCDCDFE0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000002800000010000000200000000100200000000000400400000000 + 00000000000000000000000000008B8B8BFF5F5F5FFF4E4E4EFF494949FF4949 + 49FF494949FF494949FF494949FF494949FF494949FF494949FF494949FF4949 + 49FF474747FF414141FF585858FFA5A5A5FFA0A0A0FF868686FF7D7D7DFF7D7D + 7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7D7D7DFF7C7C + 7CFF777777FF636363FF505050FFB3B3B3FFCDCDCDFFC3C3C3FFBABABAFFB9B9 + B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB8B8 + B8FFAEAEAEFF8A8A8AFF646464FFB8B8B8FFD4D4D4FFD4D4D4FFD1D1D1FFD1D1 + D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD1D1D1FFD0D0 + D0FFC4C4C4FF9A9A9AFF6A6A6AFFBABABAFFD8D8D8FF7240D5FFA085D6FFD6D6 + D6FFD6D6D6FFD6D6D6FFBFB3D6FF6229D5FFAF9CD6FFD6D6D6FFD6D6D6FFB6A7 + D5FF6229D5FF9287A9FF6C6C6CFFBBBBBBFFDADADAFFBEAFDDFF723DDEFFCBC4 + DBFFDADADAFFDADADAFFDADADAFFA68CDCFF7A48DDFFD3CFDAFFD3CFDAFF7A48 + DDFF987AD6FFA1A1A1FF6F6F6FFFBEBEBEFFDEDEDEFFE0E0E0FF9268E6FFA07D + E5FFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFF8B5DE7FFA788E4FFA788E4FF8B5D + E7FFD0D0D0FFA4A4A4FF707070FFC0C0C0FFE1E1E1FFE3E3E3FFC8B9E7FF8249 + F5FFD5CEE5FFE2E2E2FFE2E2E2FFE2E2E2FFD5CEE5FF8853F4FF8249F5FFCEC3 + E5FFD4D4D4FFA7A7A7FF717171FFC3C3C3FFE5E5E5FFE8E8E8FFE7E7E7FFAD88 + F7FFB392F5FFE7E7E7FFE7E7E7FFE7E7E7FFDBD4EAFF9662FDFF9662FDFFDBD3 + E9FFD9D9D9FFAAAAAAFF737373FFC5C5C5FFE9E9E9FFECECECFFEBEBEBFFE0DA + EEFF9B69FFFFE0DAEEFFEBEBEBFFEBEBEBFFB08CFAFFB694F8FFC0A6F6FFAB83 + FBFFDCDCDCFFADADADFF757575FFC7C7C7FFECECECFFF0F0F0FFEFEFEFFFEFEF + EFFFC2A7F9FFBD9FFAFFEFEFEFFFCCB7F6FFA97FFEFFEAE7F0FFEAE7F0FFAE87 + FDFFC4AFEEFFB0B0B0FF767676FFCACACAFFBD9FFBFFAB81FFFFAB81FFFFAB81 + FFFFAB81FFFFAB81FFFFE5DCF5FFAB81FFFFDBCDF7FFF3F3F3FFF3F3F3FFDFD4 + F5FFAB81FFFFB1A9C2FF787878FFCCCCCCFFF3F3F3FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFE9E9E9FFB8B8B8FF7B7B7BFFCECECEFFF6F6F6FFFBFBFBFFFAFAFAFFFAFA + FAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFCCCCCCFF858585FFCFCFCFFFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF8F8F8FFF8F8F8FFA8A8A8FFD6D6D6FFD1D1D1FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0 + D0FFD0D0D0FFD1D1D1FFD6D6D6FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000} + KeyPreview = True + Menu = MainMenu + OldCreateOrder = True + OnActivate = FormActivate + OnClose = FormClose + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnDestroy = FormDestroy + OnDeactivate = FormDeactivate + OnKeyDown = FormKeyUpDown + OnKeyPress = FormKeyPress + OnKeyUp = FormKeyUpDown + OnResize = FormResize + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Image1: TImage + Left = 48 + Top = 104 + Width = 105 + Height = 105 + end + object Splitter: TSplitter + Left = 161 + Top = 22 + Width = 4 + Height = 750 + end + object BackPanel: TPanel + Left = 165 + Top = 22 + Width = 835 + Height = 750 + Align = alClient + BevelInner = bvLowered + BevelOuter = bvNone + Color = clAppWorkSpace + TabOrder = 0 + OnResize = BackPanelResize + object Image: TImage + Left = 1 + Top = 1 + Width = 833 + Height = 748 + Align = alClient + Anchors = [] + Center = True + PopupMenu = DisplayPopup + Proportional = True + OnDblClick = ImageDblClick + OnMouseDown = ImageMouseDown + OnMouseMove = ImageMouseMove + OnMouseUp = ImageMouseUp + end + end + object ListBackPanel: TPanel + Left = 0 + Top = 22 + Width = 161 + Height = 750 + Align = alLeft + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + Color = clWindow + Ctl3D = True + ParentCtl3D = False + TabOrder = 1 + object Shape1: TShape + Left = 1 + Top = 1 + Width = 159 + Height = 748 + Align = alClient + Brush.Color = clWindow + Pen.Color = clWindow + end + object ListView1: TListView + Left = 1 + Top = 1 + Width = 159 + Height = 748 + Align = alClient + BorderStyle = bsNone + Columns = < + item + Caption = 'Title' + Width = 160 + end> + FlatScrollBars = True + LargeImages = Thumbnails + PopupMenu = ListPopUp + TabOrder = 1 + OnChange = ListViewChange + OnEdited = ListViewEdited + OnInfoTip = ListViewInfoTip + end + object ListView: TListView + Left = 23 + Top = 94 + Width = 33 + Height = 33 + Columns = <> + TabOrder = 0 + Visible = False + end + end + object cbMain: TCoolBar + Left = 0 + Top = 0 + Width = 1000 + Height = 22 + AutoSize = True + BandBorderStyle = bsNone + Bands = < + item + Control = ToolBar + FixedBackground = False + ImageIndex = -1 + MinHeight = 22 + MinWidth = 100 + Width = 998 + end> + Color = clBtnFace + Ctl3D = False + EdgeBorders = [] + EdgeInner = esNone + EdgeOuter = esNone + FixedSize = True + FixedOrder = True + ParentColor = False + object ToolBar: TToolBar + Left = 2 + Top = 0 + Width = 998 + Height = 22 + Align = alClient + ButtonHeight = 23 + Images = Buttons + ParentShowHint = False + ShowHint = True + TabOrder = 0 + object ToolButton8: TToolButton + Left = 0 + Top = 0 + Hint = 'New Flame' + Caption = 'ToolButton8' + ImageIndex = 65 + OnClick = ToolButton8Click + end + object btnOpen: TToolButton + Left = 23 + Top = 0 + Hint = 'Open (Ctrl+O)|Open a parameter file for browsing' + Caption = 'btnOpen' + ImageIndex = 1 + OnClick = mnuOpenClick + end + object btnSave: TToolButton + Left = 46 + Top = 0 + Hint = 'Save Parameters (Ctrl+S)|Save parameters to file' + Caption = 'btnSave' + ImageIndex = 3 + OnClick = mnuSaveAsClick + end + object ToolButton10: TToolButton + Left = 69 + Top = 0 + Width = 8 + Caption = 'ToolButton10' + ImageIndex = 39 + Style = tbsSeparator + end + object btnRender: TToolButton + Left = 77 + Top = 0 + Hint = 'Render (Ctrl+R)|Render flame to disk' + Caption = 'btnRender' + ImageIndex = 35 + OnClick = mnuRenderClick + end + object tbRenderAll: TToolButton + Left = 100 + Top = 0 + Hint = 'Render all' + Caption = 'tbRenderAll' + ImageIndex = 64 + OnClick = mnuRenderAllClick + end + object ToolButton9: TToolButton + Left = 123 + Top = 0 + Width = 8 + ImageIndex = 8 + Style = tbsSeparator + end + object btnViewList: TToolButton + Left = 131 + Top = 0 + Hint = 'Change flame list view to report' + Caption = 'Flame list view' + ImageIndex = 54 + OnClick = btnViewListClick + end + object btnViewIcons: TToolButton + Left = 154 + Top = 0 + Hint = 'Change flame list view to icons' + Caption = 'Flame icon view' + ImageIndex = 55 + OnClick = btnViewIconsClick + end + object ToolButton2: TToolButton + Left = 177 + Top = 0 + Width = 8 + Caption = 'ToolButton2' + ImageIndex = 39 + Style = tbsSeparator + end + object btnUndo: TToolButton + Left = 185 + Top = 0 + Hint = 'Undo (Ctrl+Z)|Undo the last action' + Caption = 'btnUndo' + ImageIndex = 4 + OnClick = mnuUndoClick + end + object btnRedo: TToolButton + Left = 208 + Top = 0 + Hint = 'Redo (Ctrl+Y)|Redo the last action' + Caption = 'btnRedo' + ImageIndex = 5 + OnClick = mnuRedoClick + end + object ToolButton1: TToolButton + Left = 231 + Top = 0 + Width = 8 + ImageIndex = 18 + Style = tbsSeparator + end + object btnReset: TToolButton + Left = 239 + Top = 0 + Hint = 'Reset Location (F12)' + Caption = 'btnReset' + ImageIndex = 12 + OnClick = mnuResetLocationClick + end + object btnFullScreen: TToolButton + Left = 262 + Top = 0 + Hint = 'Fullscreen View (F3)|Show full-screen view of the flame' + Caption = 'btnFullScreen' + ImageIndex = 52 + OnClick = mnuFullScreenClick + end + object ToolButton3: TToolButton + Left = 285 + Top = 0 + Width = 8 + Caption = 'ToolButton3' + ImageIndex = 54 + Style = tbsSeparator + end + object tbQualityBox: TComboBoxEx + Left = 293 + Top = 0 + Width = 69 + Height = 22 + ItemsEx = < + item + Caption = '5' + end + item + Caption = '10' + end + item + Caption = '15' + end + item + Caption = '25' + end + item + Caption = '50' + end + item + Caption = '100' + end + item + Caption = '150' + end + item + Caption = '250' + end + item + Caption = '500' + end + item + Caption = '1000' + end> + TabOrder = 0 + OnExit = tbQualityBoxSet + OnKeyPress = tbQualityBoxKeyPress + OnSelect = tbQualityBoxSet + end + object ToolButton4: TToolButton + Left = 362 + Top = 0 + Width = 8 + Caption = 'ToolButton4' + ImageIndex = 55 + Style = tbsSeparator + end + object ToolButton5: TToolButton + Left = 370 + Top = 0 + Hint = 'Editor' + Caption = 'ToolButton5' + ImageIndex = 19 + OnClick = mnuEditorClick + end + object ToolButton6: TToolButton + Left = 393 + Top = 0 + Hint = 'Adjust' + Caption = 'ToolButton6' + ImageIndex = 18 + OnClick = mnuAdjustClick + end + object ToolButton7: TToolButton + Left = 416 + Top = 0 + Hint = 'Gradient' + Caption = 'ToolButton7' + ImageIndex = 11 + OnClick = mnuGradClick + end + object ToolButton19: TToolButton + Left = 439 + Top = 0 + Hint = 'Curves' + Caption = 'Curves' + ImageIndex = 69 + OnClick = ToolButton19Click + end + object ToolButton11: TToolButton + Left = 462 + Top = 0 + Hint = 'Mutate' + Caption = 'ToolButton11' + ImageIndex = 17 + OnClick = mnuMutateClick + end + object ToolButton12: TToolButton + Left = 485 + Top = 0 + Hint = 'Image size' + Caption = 'ToolButton12' + ImageIndex = 51 + OnClick = mnuImageSizeClick + end + object ToolButton13: TToolButton + Left = 508 + Top = 0 + Hint = 'Messages' + Caption = 'ToolButton13' + ImageIndex = 63 + OnClick = ToolButton7Click + end + object ToolButton14: TToolButton + Left = 531 + Top = 0 + Hint = 'Options' + Caption = 'ToolButton14' + ImageIndex = 13 + OnClick = mnuOptionsClick + end + object ToolButton15: TToolButton + Left = 554 + Top = 0 + Width = 8 + Caption = 'ToolButton15' + ImageIndex = 62 + Style = tbsSeparator + end + object tbShowAlpha: TToolButton + Left = 562 + Top = 0 + Hint = 'Show transparency' + Caption = 'Show Alpha' + ImageIndex = 53 + Style = tbsCheck + OnClick = tbShowAlphaClick + end + object tbGuides: TToolButton + Left = 585 + Top = 0 + Caption = 'Show guides' + Down = True + ImageIndex = 68 + Style = tbsCheck + OnClick = tbGuidesClick + end + object ToolButton16: TToolButton + Left = 608 + Top = 0 + Width = 8 + Caption = 'ToolButton16' + ImageIndex = 54 + Style = tbsSeparator + end + object ToolButton17: TToolButton + Left = 616 + Top = 0 + Hint = 'Edit script' + Caption = 'ToolButton17' + ImageIndex = 42 + OnClick = mnuEditScriptClick + end + object btnRunScript: TToolButton + Left = 639 + Top = 0 + Hint = 'Run script' + Caption = 'btnRunScript' + ImageIndex = 43 + OnClick = btnRunClick + end + object btnStopScript: TToolButton + Left = 662 + Top = 0 + Hint = 'Stop script' + Caption = 'btnStopScript' + ImageIndex = 36 + OnClick = mnuStopClick + end + object ToolButton18: TToolButton + Left = 685 + Top = 0 + Width = 8 + Caption = 'ToolButton18' + ImageIndex = 37 + Style = tbsSeparator + end + object tbDraw: TToolButton + Left = 693 + Top = 0 + Caption = 'tbDraw' + Grouped = True + ImageIndex = 48 + Style = tbsCheck + OnClick = tbDragClick + end + object ToolButton20: TToolButton + Left = 716 + Top = 0 + Caption = 'ToolButton20' + Grouped = True + ImageIndex = 41 + Style = tbsCheck + OnClick = tbRotateClick + end + object ToolButton21: TToolButton + Left = 739 + Top = 0 + Caption = 'ToolButton21' + Grouped = True + ImageIndex = 50 + Style = tbsCheck + OnClick = tbzoomwindowClick + end + object ToolButton22: TToolButton + Left = 762 + Top = 0 + Caption = 'ToolButton22' + Grouped = True + ImageIndex = 49 + Style = tbsCheck + OnClick = tbzoomoutwindowClick + end + end + end + object BottomDock: TPanel + Left = 0 + Top = 772 + Width = 1000 + Height = 19 + Align = alBottom + BevelOuter = bvNone + TabOrder = 3 + object StatusBar: TStatusBar + Left = 0 + Top = 0 + Width = 803 + Height = 19 + Align = alClient + Panels = < + item + Width = 200 + end + item + Width = 161 + end + item + Width = 150 + end + item + Width = 50 + end> + end + object pnlLSPFrame: TPanel + Left = 803 + Top = 0 + Width = 197 + Height = 19 + Align = alRight + BevelOuter = bvNone + TabOrder = 1 + object LoadSaveProgress: TProgressBar + Left = 2 + Top = 0 + Width = 194 + Height = 21 + Align = alCustom + Anchors = [akLeft, akTop, akRight, akBottom] + Smooth = True + TabOrder = 0 + end + end + end + object Buttons: TImageList + Left = 104 + Top = 280 + Bitmap = { + 494C0101460050005C0010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000002001000001002000000000000020 + 0100000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B7A2930063493500634935006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 35006349350063493500634935006349350000000000BBA697FF875C44FF875C + 44FF875C44FF875C44FF875C44FF875C44FF875C44FF875C44FF875C44FF875C + 44FF875C44FF875C44FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B7A29300C0C0C000FFFFFF008000 + 8000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0 + C00080008000C0C0C000FFFFFF006349350000000000BCA798FFFC8E54FFEF81 + 47FFEA763AFFE77136FFE56F2FFFDE6A2AFFD96123FFD45A1EFFC95617FFC350 + 15FFBC4C14FFB84B15FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B7A29300FFFFFF00C0C0C0008000 + 8000C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFF + FF0080008000FFFFFF00C0C0C0006349350000000000BDA899FFFC945EFFFE8C + 51FFFF8344FFFE7B39FFF97530FFF4712BFFEF6A26FFE96120FFE25E1DFFDA5B + 16FFD25415FFBE4C13FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B7A2930080008000800080008000 + 8000800080008000800080008000800080008000800080008000800080008000 + 80008000800080008000800080006349350000000000BEAA9AFFFC9A69FFFD91 + 57FFFF8749FFFF7B3BFFFA7831FFF5742BFFF06B27FFEB6321FFE55E1DFFE05D + 17FFD95515FFC14E13FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B7A29300FFFFFF00C0C0C0008000 + 8000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0080008000FFFFFF00C0C0C0006349350000000000C0AB9BFFFCA374FFFE99 + 62FFFF8E50FFFE8343FFFB7936FFF6752CFFF16C27FFEC6422FFE75F1EFFE55D + 18FFDE5614FFC74F13FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000BAA59600C0C0C000FFFFFF008000 + 8000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0080008000C0C0C000FFFFFF006349350000000000C2AC9DFF57D546FF47D0 + 32FF34CC1EFF2EC617FF26C310FF1FC00AFF1BB904FF18B401FF19AA00FF16A0 + 00FF159700FF117200FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000BEA99A00FFFFFF00C0C0C0008000 + 8000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0080008000FFFFFF00C0C0C0006349350000000000C4AE9FFF6AD75AFF57D3 + 46FF41D02DFF32C71DFF2AC313FF1FC00AFF1BBC03FF19B601FF18AC00FF16A3 + 00FF149B00FF107800FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C3AE9E00C0C0C000FFFFFF008000 + 8000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0080008000C0C0C000FFFFFF006349350000000000C6AFA1FF7CDA6FFF67D6 + 58FF51D240FF3DCC2AFF30C41BFF22C10EFF1CBB05FF17B801FF16AE00FF14A4 + 00FF149D00FF107B00FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C8B2A300FFFFFF00C0C0C0008000 + 8000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0080008000FFFFFF00C0C0C0006349350000000000C7B1A2FF8FDD84FF79DA + 6DFF62D554FF4ECD3DFF3BC728FF2AC213FF1FBD08FF17B801FF17B000FF16A6 + 00FF15A000FF107D00FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000BEA99A0080008000800080008000 + 8000800080008000800080008000800080008000800080008000800080008000 + 80008000800080008000800080006349350000000000C9B2A3FF7A85E6FF6F78 + E5FF636DE6FF5360E2FF4653DFFF394ADCFF3141D7FF2535D3FF1E2DCFFF182A + CCFF1528C7FF111FB0FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C3AE9E00C0C0C000FFFFFF008000 + 8000C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFF + FF0080008000FFFFFF00C0C0C0006349350000000000CAB4A5FF838DE5FF7983 + E4FF6D76E5FF606CE2FF4F5ADFFF4250DBFF3746D7FF2C3AD4FF2130CFFF1A29 + CBFF1427CAFF101EB2FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C8B2A300FFFFFF00C0C0C0008000 + 8000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0C000FFFFFF00C0C0 + C00080008000C0C0C000FFFFFF006349350000000000CBB5A6FF8D95E5FF828D + E4FF777FE3FF6B75E1FF5C6AE0FF4A57DEFF3D4DD8FF313FD5FF2533D1FF1C2A + CDFF1426CAFF0E1FBAFF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000EAAA8B00EAAA8B00EAAA8B00EAAA + 8B00E9A58400E99F7A00E7976E00E68E6200E5865600E37D4A00E3764000E272 + 3900E2723900E2723900E2723900C8622F0000000000CCB6A7FF959DE4FF8C95 + E4FF818AE2FF757EE3FF6775E0FF5763DDFF4857D8FF3A48D4FF2D3BD1FF2432 + CDFF1629CBFF1020C6FF875C44FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000EAAA8B00FFC2A200FFC2A200FEC0 + 9F00FDBD9A00FCB99600FBB59000FAB08B00F9AB8400F8A77D00F6A27700F59D + 7100F5996A00F3956500F3956500CD65310000000000CCB6A7FFCCB6A6FFCAB5 + A5FFC9B3A4FFC8B2A3FFC6B1A2FFC5AFA1FFC3AE9FFFC2AC9DFFC1AB9CFFBFA9 + 9BFFBEA89AFFBDA899FFBCA698FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000EAAA8B00EAAA8B00EAAA8B00EAAA + 8B00EAAA8B00EAA68600E9A17F00E89B7600E7946C00E68E6200E5875800E481 + 4E00E47B4600E3763E00E3763E00E27239000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000A5795F0080472800804728007F4425007E4121007C3E1C007B3A18007936 + 130078330E0077300B00762E0800000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A293006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 3500634935000000000000000000000000000000000000000000000000000000 + 0000EAE2DE00C8B6AB00A88E7D008E6F5A00886A57009A837300B9AAA000E1DC + D700000000000000000000000000000000000000000000000000000000000000 + 0000A97E6600FEF1EA00FEF1EA00FCECE300FAE4D900F6DBCC00F3D1C000F0C9 + B400EEC1A900ECBCA20077300A00000000000000000000000000965C5B009558 + 5700FFFFFF00C897920095525300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A29300FFFF + FF00B7A29300B7A29300B7A29300B7A29300B7A29300B7A29300B7A29300B7A2 + 930063493500000000000000000000000000000000000000000000000000D7C8 + BF00A5857200927049006B65450093664400B2663E00965D3D0079533B008169 + 5900C3B8B0000000000000000000000000000000000000000000A5795F008047 + 2800804728007F4425007E4121007C3E1C007B3A18007936130078330E007730 + 0B00762E0800EEC1A80077320D00000000000000000000000000904F4E00B162 + 6600703C3C0095525300703C3C00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A29300FFFF + FF00FFFFFF00FCFAF900F7F1EE00F1E7E100ECDDD500E6D3C900E1CABD00B7A2 + 9300634935000000000000000000000000000000000000000000DACAC100A67D + 6500C57E580087742E005C74240053613E0088623C00BB663D00B6633B008B56 + 38006F544100C3B8B00000000000000000000000000000000000A97E6600FEF1 + EA00FEF1EA00FCECE300FAE4D900F6DBCC00F3D1C000F0C9B400EEC1A900ECBC + A20077300A00F0C7B10078341000000000009857550081464600C06E6A00BB61 + 5E00BE655D00DA706F00C4636300A66D69006D35360000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A29300FFFF + FF00FFFFFF00F5F5F500F1EEEC00ECE4E000E6DBD400E1D1C900E4CFC400B7A2 + 93006349350000000000000000000000000000000000EDE5E000B08E7C00CE86 + 6200E8895900CB8147005D8B1F00348822005A6737006F644100B6673D00B562 + 3A008B56380081695900E1DCD70000000000A5795F0080472800804728007F44 + 25007E4121007C3E1C007B3A18007936130078330E0077300B00762E0800EEC1 + A80077320D00F2CEBB007A37140000000000DC878600C0757700DC8786008E56 + 5700C1A4A500C6898800C4636300B1565700B156570000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A29300FFFF + FF00C1C1C100ACACAC00ABAAA900A7A4A200A39D9900A0969200B4A69F00B7A2 + 93006349350000000000000000000000000000000000D4C0B400C1886B00F594 + 6400EE906100C5845A00547E3F003B9B24003C8B28006D6C3C00B46B42008760 + 3C005D5F3E0061594400B9AAA00000000000A97E6600FBEFEB00CFA89500C799 + 8300BA928000A783710096746300856557004A372B00574B3F0077300A00F0C7 + B10078341000F5D7C6007B3A180000000000FEFAFA00D3878600E08F8D007341 + 4100DDD1D100DAC1C300CD6E6E00B1565700FBF3F30000000000000000000000 + 0000000000000000000000000000000000000000000000000000BAA59600FFFF + FF00B6B6B600ECECEC00FFFFFF00FBF8F700EEE7E4009C959100E8D8D000B7A2 + 93006349350000000000000000000000000000000000C0A19000DE967100F99C + 6E00DD9269006E7A520055A438004FA6300080952D00CD7A4C006D6D3F004B65 + 4200317B1600626A33009A83730000000000AE856D00FFFFFF00F3DFD500DCAF + 9800D39F8700CA9B8500C1978200523928009F85740039342F0077320D00F2CE + BB007A371400F8DFD2007C3D1B0000000000DD908E00E5A4A600F0A8A800AA6B + 6E008457570093606000C26C6D00B15657006D353600965C5B00955857000000 + 0000C89792009552530000000000000000000000000000000000BEA99A00FFFF + FF00B6B6B600ECECEC00FFFFFF00F8F7F600ACAAA700E7DEDA00EEE1DA00B7A2 + 93006349350000000000000000000000000000000000B38D7800F7B49200EBA4 + 7B0065795F00639B4C0060AF400096A23E00DF895D00D4805400516E48003B84 + 2C002B8D15003C7D1C00886A570000000000B28B7400B4A39600FEFBFA00F1DF + D500DFB19B00C9A79700715B4C00C7B4AA0070655D004B423F0078341000F5D7 + C6007B3A1800FBE6DB007D401F0000000000ECBDBD00DB929300F6B8B800EDA9 + A800DD898600D67D7700C26C6D00C0727200BD727300904F4E00B1626600703C + 3C0095525300703C3C0000000000000000000000000000000000C3AE9E00FFFF + FF00B6B6B600ECECEC00FCFCFC00B9B9B900CCCBCA00F7F1EE00F1E7E100B7A2 + 93006349350000000000000000000000000000000000B68F7A00F8BA9B009B9B + 800047A74E005AB64B0091955E00E5976E00E6916600DC895C0064A12B003F9D + 240040961D0045881F008E6F5A0000000000B7927B00ECE5E100AE9A8A00FCF5 + F200F0DDD2006D5646009D8A7F009D8E86004C342900ECBCA2007A371400F8DF + D2007C3D1B00FCEDE4007E432300000000000000000000000000E4A7AA00DB9F + 9E00D0827E00CE7E7A00B96F70009857550081464600C06E6A00BB615E00BE65 + 5D00DA706F00C4636300A66D69006D3536000000000000000000C8B2A300FFFF + FF00B5B5B500EDEDED00C1C1C100CBCBCB00FEFEFE00FAF7F500F5EDE900B7A2 + 93006349350000000000000000000000000000000000C4A69500E1B4990090B6 + 85004FC96C004DCB710079A17300B9A26E00D2996800E48F6400A5963C004DA5 + 2B00439F2300528A2C00A88E7D0000000000BC988200FFFFFF00E2D8D200AF99 + 89009E897C00C5A89800BAABA300BBA79D00FDDAC800EDC3AC007B3A1800FBE6 + DB007D401F00FEF1EA007F452500000000000000000000000000DD9C9B00E4AB + A900FEF9F900CE7E7A00BD727300DC878600C0757700DC8786008E565700C1A4 + A500C6898800C4636300B1565700B15657000000000000000000CCB6A700FFFF + FF00B0B0B000C7C7C700C7C7C700FFFFFF00FFFFFF00FDFCFB00B7A29300B7A2 + 9300644A360000000000000000000000000000000000D8C4B900B6A283008BCF + 980077DD960093E2A10087E4A200A2D29700ABA66B00ED996900E08D5B0053A7 + 2E004CA529006F844000C8B6AB0000000000C09D8800FFFFFF00FFFFFF00E6DC + D600E9DACD00E2E2F2005568CC003554CF00D0C3D400EECAB8007C3D1B00FCED + E4007E432300A2745A009E6F5400000000000000000000000000000000000000 + 0000000000000000000000000000FEFAFA00D3878600E08F8D0073414100DDD1 + D100DAC1C300CD6E6E00B1565700FBF3F3000000000000000000D1BBAB00FFFF + FF00B6B6B600C1C1C100FFFFFF00FFFFFF00FFFFFF00B7A29300644A3600644A + 3600644A360000000000000000000000000000000000EFE7E200BEA18E0092CB + 9900A1E8B700CBEEC000D5F4CD00EBF7D700B3E5AB0087986700D6984700B093 + 390065963A00A0877000EAE2DE0000000000C4A38E00FFFFFF00FFFDFC00FFFF + FF00FFFFFB006572C9004BA0ED002374CB002A4AC100EED3C5007D401F00FEF1 + EA007F4525000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000DD908E00E5A4A600F0A8A800AA6B6E008457 + 570093606000C26C6D00B15657006D3536000000000000000000D5BFAF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B9A49500D4C5BA00644A + 3600E1D5CD000000000000000000000000000000000000000000E0D0C700B9A5 + 8A00B5D5AD00D4F2CE00E6F8D70086B075007DDB90004EB16A008B874200C885 + 5B00A27F6100D7C8BF000000000000000000C7A79200FFFFFF00FFFBFA00FFFB + FA00FFFFFD008D97D20093C3E8004EA5EF00656CBA00EFDBD1007E432300A274 + 5A009E6F54000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000ECBDBD00DB929300F6B8B800EDA9A800DD89 + 8600D67D7700C26C6D00C0727200BD7273000000000000000000D8C2B200FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00C0AB9C00644A3600E2D6 + CD0000000000000000000000000000000000000000000000000000000000E0D0 + C700C0A29000C3C2A200CDDCBB00B7E4B60081DDA20067B670009F855600B08E + 7C00DACAC100000000000000000000000000E2BDA600FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E2E5F5009BA5DD008D96D300ECE9F100FEF1EA007F4525000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000E4A7AA00DB9F9E00D082 + 7E00CE7E7A00B96F700000000000000000000000000000000000D8C2B200D8C2 + B200D8C2B200D8C2B200D8C2B200D4BEAE00CFB9A900C9B3A400E2D6CD000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000EFE7E200D9C5BA00C6A89900BB998500BD9D8B00C5A79700D4C0B500EDE5 + E00000000000000000000000000000000000E2BDA600E2BDA600C1A08A00C1A0 + 8A00BD998300B7927B00B28A7200AC826A00A77B6200A2745A009E6F54000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000DD9C9B00E4ABA900FEF9 + F900CE7E7A00BD72730000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C3646500AA55 + 5600A45253009F4F50009A4D4D00944A4A008F4747008944440083414100783B + 3C00783B3C00723939006E363700000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A293006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 350063493500000000000000000000000000B7A2930060463200634935006349 + 350063493500634935006349350063493500634935006349350063493500684E + 3A000000000000000000000000000000000000000000CF6B6C00F6ABAC00ECA1 + A200C0745D0047322100D3C7C100D5CDC700D8D1CD00DBD6D300564D4800B770 + 6800B66F6A00B36C660072393900000000000000000000000000C7C7C700B8B8 + B800CCCCCC000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A29300FFFF + FF00B7A29300B09E950077789C00B19E9500B7A29300B7A29300B7A29300B7A2 + 930063493500000000000000000000000000BDA89900FDFEFD00F0EFEE00F0EC + E900EFE9E400EEE5DE00EEE0D700EDDDD200EDDACD00ECD8CA00DBC9BD00684E + 3A000000000000000000000000000000000000000000D16F7000FFB3B400F1A5 + A600ECA1A200715B4B00776E6900AB9B8F00F2E8E200F5EDE8008F7F7300BB72 + 6900BA736E00B66F6900783B3C00000000000000000000000000D8D8D800EAEA + EA00A4A4A400CCCCCC0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000B7A29300FFFF + FF00EDAF8C003153C1001639B300697ECB00C9815700CE825000E1CABD00B7A2 + 930063493500000000000000000000000000C6B0A100FDFEFD00E6D9D200E5D7 + D000E3D4CC00FCF5EF00E0CEC500DECCC200DECCC200F9E8DC00DBC9BD00684E + 3A000000000000000000000000000000000000000000D4757600FFB8B900F8AD + AD00F1A5A600715B4B0042424200776E6900EFE3DB00F1E6DF0085746700C37A + 7400C0787400BB736E007D3E3E00000000000000000000000000000000000000 + 0000D0D0D000A3A3A30000000000B1B1B100B1B1B100D7D7D700A9A9A900A2A2 + A200ABABAB000000000000000000000000000000000000000000B7A29300DBE1 + F400294DC2002854ED00234BE2001238B5009D9FCC00EAD9D100E4CFC400B7A2 + 930063493500000000000000000000000000CCB6A700FDFEFD00FDFEFD00FDFE + FD00FCFCFA00FCF9F50075716E005754510000000000E2D8D000DECEC300684E + 3A000000000000000000000000000000000000000000D77B7C00FFBFC000FCB8 + B900F8AFB000715B4B00715B4B00715B4B00715B4B00766252007D6A5B00CC82 + 8000C67D7A00C078740083414100000000000000000000000000000000000000 + 0000E3E3E3009E9E9E00CECECE000000000000000000C2C2C2009E9E9E000000 + 0000000000000000000000000000000000000000000000000000B7A293001E44 + BF002A57F4006183FB005477F8003D63EA002040B400B77A5E00E7D5CB00B7A2 + 930063493500000000000000000000000000CCB6A700FDFEFD00E8DDD700E7DC + D500E6D9D200FCFCFA00A39D9800FEFEFE0090BAC8000E121600D2CDC7007860 + 4D000000000000000000000000000000000000000000DB838400FFC7C700FFC2 + C300FDBBBC00F7ABAC00F1A5A600ECA1A200E79C9C00E1969600DD919200D187 + 8600CC828000C67D7A0089444400000000000000000000000000000000000000 + 000000000000BCBCBC00B7B7B700000000000000000000000000ABABAB00A6A6 + A600000000000000000000000000000000000000000000000000BAA5960087A2 + FC007895FB007C94FC00E0E5FD00819AF8004262E2003F57B200E7D8D200B7A2 + 930063493500000000000000000000000000CCB6A700FDFEFD00FDFEFD00FDFE + FD00FDFEFD00FDFEFD00A39D9800B3D1DB00A6E0EC008BBECE000E1216007C72 + 66000000000000000000000000000000000000000000DF8A8B00FFCDCD00FFC9 + CA00C9636000C45E5600BE584B00B8523F00B34D3400AD472800A7411C00A13B + 1100D1878600CC8280008F474700000000000000000000000000000000000000 + 000000000000CCCCCC00A7A7A70000000000D5D5D500D8D8D800DEDEDE00D8D8 + D800ABABAB00B5B5B50000000000000000000000000000000000BEA99A00E8EB + FF00C1CDFE00F0BCA500EBAE8C00D19781007D95F6002E54DD005668B100B6A2 + 930063493500000000000000000000000000CCB6A700FDFEFD00E8DDD700E8DD + D700E8DDD700FDFEFD00D7D2CF004D9CB300B5EBF4009BD6E5008BBECE000E12 + 16000000000000000000000000000000000000000000E2919200FFCECF00CC66 + 6700FFFFFF00FFFFFF00FCFAF800F8F2EF00F4ECE700EFE4DE00ECDDD500E9D8 + CE00A13B1100D2878600944A4A00000000000000000000000000000000000000 + 000000000000D0D0D0009E9E9E00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C3AE9E00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F1F1F800748EF500264CD7006C6E + 950062493600000000000000000000000000CCB6A700FDFEFD00FDFEFD00FDFE + FD00FDFEFD00FDFEFD00FCFBF700E4E0DC0057A0B500B5EBF4009BD6E5008BBE + CE000E12160000000000000000000000000000000000E5979800FFCECF00D36D + 6E00FFFFFF00FFFFFF00FFFFFF00FCFAF800F8F2EF00F4ECE700EFE4DE00ECDD + D500A7411C00D98E8E009A4D4D00000000000000000000000000000000000000 + 000000000000DEDEDE00A7A7A700CECECE000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C8B2A300FFFF + FF00F7D0BB00F5C8B200EDBC9E00E6AD8C00DFA07B00DB9A72007F96F200244A + D700433E5900000000000000000000000000EBAC8D00F2C9B500F2C8B400F1C4 + AD00F0BEA400EFB79B00EEB29400EFB99D00DFC8BB0065A6B700B5EBF4009BD6 + E5008BBECE000E121600000000000000000000000000E99E9F00FFCECF00DC76 + 7700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FCFAF800F8F2EF00F4ECE700EFE4 + DE00AD472800E19696009F4F5000000000000000000000000000000000000000 + 0000DCDCDC00E1E1E100CECECE00A2A2A200A4A4A40000000000000000000000 + 0000000000000000000000000000000000000000000000000000CCB6A700FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FDFCFB00B7A293007B8D + D800274DD700000000000000000000000000EBAC8D00FFD9C400FED6C000FDD4 + BD00FCD0B900FCCDB500FBC9B000FBC6AB00F7C6AE00E2CDC10073ACB900B5EB + F400A1D9E700ACB2B200353590000000000000000000EDA6A700FFCECF00E680 + 8100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FCFAF800F8F2EF00F4EC + E700B34D3400E79C9C00A4525300000000000000000000000000000000000000 + 00000000000000000000D9D9D900AEAEAE000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000D1BBAB00FFFF + FF00F7D0BB00F5C8B200EDBC9E00E6AD8C00DFA07B00DB9A7200644A3600644A + 3600644A3600000000000000000000000000EBAC8D00EAAA8B00EAAA8B00EAA8 + 8900E9A28100E89C7700E7946B00E68C6000E5865500E68D5F00CA997F007DB0 + BB00DDD2CA00A6B1E20098A1CB003535900000000000F0ACAD00FFCECF00EF89 + 8A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FCFAF800F8F2 + EF00B8523F008E686800AA555600000000000000000000000000000000000000 + 00000000000000000000E7E7E700C4C4C40000000000B2B2B200C0C0C0000000 + 0000000000000000000000000000000000000000000000000000D5BFAF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B9A49500D4C5BA00644A + 3600E1D5CD000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00005E6CAD00A4B7EB0098A7E1005E6CAD0000000000F3B2B300FFCECF00F892 + 9300FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FCFA + F800BE584B00C4838400B0585900000000000000000000000000000000000000 + 0000000000000000000000000000E1E1E100C9C9C900A5A5A500B9B9B9000000 + 0000000000000000000000000000000000000000000000000000D8C2B200FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00C0AB9C00644A3600E2D6 + CD00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000005E6CAD005E6CAD000000000000000000F5B6B700F5B6B700F3B2 + B300F1ADAE00EEA7A800EAA1A200E79A9B00E4939400E08E8F00DD878800DA80 + 8100D67A7B00D3747500D16F7000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000D8C2B200D8C2 + B200D8C2B200D8C2B200D8C2B200D4BEAE00CFB9A900C9B3A400E2D6CD000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000747474003E3E3E00424242003434340000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000081685500262F3800262F3800262F3800262F3800262F + 3800262F3800262F3800262F3800262F38000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000464646003E3E + 3E000000000046464600BEBEBE00C7C7C7003333330000000000000000003535 + 3500828282000000000000000000000000000000000000000000000000000000 + 00000000000000000000BA6E4700AA542900AA542900A25027009B4C25009648 + 23008F4622008A432100864120000000000000000000647E8E004F5E6F004552 + 610037414D00262F380089715E00F2EBE500D5C9C000D5C9C000D5C9C000D5C9 + C000D5C9C000D5C9C000D5C9C000262F380000000000000000003E3937004840 + 3B0039322F0028231F001B17140000000000000000003E39370048403B003932 + 2F0028231F001B17140000000000000000000000000054545400CECECE00D0D0 + D0003131310037373700C9C9C900C9C9C9004D4D4D002B2B2B003F3F3F00C1C1 + C100B6B6B6006B6B6B0000000000000000000000000000000000000000000000 + 00000000000000000000C1795500FDF9F600CEB09C00CCAF9B00CAAD9A00C7AC + 9900C6AB9800C4A997008943210000000000717F8B007FD5F4006BBEE2006BBE + E2006BBEE2006BBEE20091796600F6F0EE00F2EAE500EDE4DE00EADED800E6DA + D200E3D6CE00E1D5CD00D5C9C000262F3800000000000000000089766C00FCF7 + F300FBECDD00E5D7C800D3C5B600181412000000000089766C00FCF7F300FBEC + DD00E5D7C800D3C5B60018141200000000000000000066666600D9D9D900D7D7 + D700D0D0D000CECECE00CFCFCF00CCCCCC00C9C9C900C1C1C100C3C3C300C5C5 + C500C4C4C4003D3D3D0000000000000000000000000000000000000000000000 + 00000000000000000000C9856400FFFFFF00DA8C5C00D1835100D1835100D183 + 5100D1835100C6AB98008E4522000000000075849000A7DFF30074D4F60070CF + F3006DCAEF006BC2E6009A826F00FAF7F600DCD0C700DCD0C700D9CDC300D5C9 + C000E6DAD200D5C9C000D5C9C000262F3800000000000000000089807900FCF7 + F300E2723900C8622F00E5D7C800231E1B000000000089807900FCF7F300E272 + 3900C8622F00E5D7C800231E1B000000000000000000000000007D7D7D00D9D9 + D900D7D7D700D5D5D500D2D2D200CFCFCF00CCCCCC00C9C9C900C7C7C700C5C5 + C5003F3F3F00000000000000000000000000B7A2930063493500634935006349 + 35006349350063493500D1927300FFFFFF00FEFDFB00FBEFEA00F5DED300F0CE + BE00EDC3AF00C7AC9900924723000000000079899400AEE4F50082D9F70075D4 + F6006FCEF3006BC6EB00A28A7800FEFDFC00FAF7F500F6F0EE00F2EAE500EDE4 + DE00705A4A0061524600504842003F3D3E00000000000000000089807C00FEFB + FA00F5825000CD653100FBECDD00322C29000000000089807C00FEFBFA00F582 + 5000CD653100FBECDD00322C290000000000000000000000000073737300DBDB + DB00D9D9D900CECECE006868680064646400C9C9C900CCCCCC00C9C9C900C1C1 + C10038383800000000000000000000000000B7A29300F8F3F000EADFD700E6D9 + CF00E1D2C700DDCBBF00D89F8200FFFFFF00F3A77F00E7976E00DA8C5C00D183 + 5100D1835100CAAE9A00984A2500000000007E8E9A00B7E9F60094E0F70085DA + F70078D5F7006BC8EE00A9928000FFFFFF00DCD0C700DCD0C700D9CDC400F2EB + E5007A604D00E6DDD7006152470000000000000000000000000088807C00FFFF + FF00FDFBFA00FCF7F300FCF7F3003F3835000000000088807C00FFFFFF00FDFB + FA00FCF7F300FCF7F3003F38350000000000656565006262620066666600DFDF + DF00CFCFCF0059595900000000000000000092929200C8C8C800CCCCCC00C9C9 + C900444444003E3E3E003C3C3C0000000000B7A29300FBF8F700E5AE8100DEA1 + 7300DA9C6E00D5976800E0AA9000FFFFFF00FFFFFF00FFFFFF00FBF4F000F7E4 + DB00F2D3C500CCAE9A009D4D25000000000082949E00BFEEF800A6E7F90097E1 + F80088DCF70077D1F200B0998800FFFFFF00FFFFFF00FDFDFC00FAF7F600F6F1 + EE00816856007A604D0000000000000000000000000000000000887F7A008980 + 7C0089807C008980790089766C0035312E0000000000887F7A0089807C008980 + 7C008980790089766C0035312E00000000008F8F8F00E6E6E600E4E4E400E2E2 + E20044444400000000000000000000000000000000005F5F5F00CFCFCF00CCCC + CC00C9C9C900C7C7C7004444440000000000BBA69700FEFDFC00FBF6F500F6EF + EB00F1E6E000ECDED600E7B59C00FFFFFF00FCAE8A00FCAE8A00F1DBD200E78E + 6000B3572A00AC542900A4502700000000008699A200C7F3FA00B7EEFA00A9E8 + F9009BE3F90073D3F600B6A08E00B0998800A9928000A28A78009A8270009179 + 670089715E000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000090909000EAEAEA00E6E6E600E4E4 + E40051515100000000000000000000000000000000005F5F5F00D2D2D200CFCF + CF00CACACA00C0C0C0004747470000000000C1AB9C00FFFFFF00FAC59F00F0B8 + 8E00E5AE8100DEA17300ECBDA600FFFFFF00FFFFFF00FFFFFF00FFFFFF00EA9A + 7200F0C9B200B1572B00EDD7CD00000000008A9EA600CDF6FB00C4F3FB00BAEF + F900AAE4F30076C8E60076C8E60075C8E50073C3E3006FBFE0006BBEE2006BBE + E2003039440000000000000000000000000000000000000000003E3937004840 + 3B0039322F0028231F001B17140000000000000000003E39370048403B003932 + 2F0028231F001B171400000000000000000090909000979797009E9E9E00E5E5 + E500D9D9D9006F6F6F0000000000000000007D7D7D00CDCDCD00D4D4D400D0D0 + D00063636300616161005959590000000000C7B2A300FFFFFF00FFFFFF00FCFA + F900F8F2F000F3EAE600F0C4AE00FFFFFF00FFFFFF00FFFFFF00FFFFFF00EBA7 + 8500C5653500F1DBCF0000000000000000008DA1AA00CEF7FC00CCF6FC005E7D + 8A0058737F00566D7A00526977004F6673004C617000445A68007FABBF006BBE + E2003E4A5800000000000000000000000000000000000000000089766C00FCF7 + F300FBECDD00E5D7C800D3C5B600181412000000000089766C00FCF7F300FBEC + DD00E5D7C800D3C5B6001814120000000000000000000000000069696900E6E6 + E600E7E7E700D7D7D700505050004E4E4E00D4D4D400D9D9D900D7D7D700CECE + CE0031313100000000000000000000000000CFB9A900FFFFFF00FFDABA00FFD0 + AE00F0DED200B7A29300F0C4AE00EFC2AB00EFC1AA00EFB9A000EDB09200EDB0 + 9200F9E4D9000000000000000000000000008FA4AC00CEF7FC00CDF7FC005D86 + 9600BCDEE300C0EFF600B2E7F100A4DEEC0099C4D2003E5A67007BB4CB006BBE + E2004B596900000000000000000000000000000000000000000089807900FCF7 + F300E2723900C8622F00E5D7C800231E1B000000000089807900FCF7F300E272 + 3900C8622F00E5D7C800231E1B0000000000000000005A5A5A00E5E5E500E8E8 + E800E7E7E700E7E7E700E4E4E400E2E2E200DFDFDF00DBDBDB00D9D9D900D7D7 + D700CCCCCC00393939000000000000000000D4BEAF00FFFFFF00FFFFFF00FFFF + FF00FEFDFC00BBA69600D4C5BA008F725B00E2DDD90000000000000000000000 + 0000000000000000000000000000000000008FA4AC00CEF6FA00CEF7FC00CBF6 + FA007397A200C8F4F900667D8A00B1DDE7004C6C7C0034617800A2DCF2007FD5 + F4004E5E6F00000000000000000000000000000000000000000089807C00FEFB + FA00F5825000CD653100FBECDD00322C29000000000089807C00FEFBFA00F582 + 5000CD653100FBECDD00322C290000000000000000009B9B9B00E6E6E600E7E7 + E700828282007D7D7D00E6E6E600E4E4E40082828200686868007B7B7B00D9D9 + D900CFCFCF005B5B5B000000000000000000D8C2B200FFFFFF00FFFFFF00FFFF + FF00FFFFFF00C7B1A200A5826600E2DDD9000000000000000000000000000000 + 000000000000000000000000000000000000000000008FA4AC008FA4AC008FA4 + AC005B8D9F00CBF2F600C5F2F900BCE7EE004666760073858F007A8A95007585 + 910000000000000000000000000000000000000000000000000088807C00FFFF + FF00FDFBFA00FCF7F300FCF7F3003F3835000000000088807C00FFFFFF00FDFB + FA00FCF7F300FCF7F3003F383500000000000000000000000000A8A8A8009898 + 9800000000008C8C8C00E8E8E800E6E6E6006060600000000000000000007070 + 700067676700000000000000000000000000D8C2B200D8C2B200D4BFAE00D4BF + AE00CEB8A900C8B2A300E9E2DE00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000086B3C30082ADBD00799FB0000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000887F7A008980 + 7C0089807C008980790089766C0035312E0000000000887F7A0089807C008980 + 7C008980790089766C0035312E00000000000000000000000000000000000000 + 00000000000090909000989898008A8A8A008484840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B9A39500634935006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 350063493500634935006349350000000000B7A2930063493500634935006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 3500634935006349350063493500634935000000000063493500634935006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 3500634935006349350000000000000000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5A5A500A5A5A500A5A5A500A5A5 + A500A5A5A500A5A5A500000000000000000000000000B9A39500FEFDF200DEDB + D500DAD2CB00D7CBC200D3C2B700CEBAAD00C7B0A300C1A99C00BAA19300B297 + 8900AB908100A5897A006349350000000000B7A29300FBF6F000E4E1DC00E0DD + D700DFD7CE00DFD3C800E0D0C100E0CCBE00E3C8B600E3C7B300E3C4AE00E3C3 + AC00E3C3AC00E3C3AC00E3C3AC0063493500BEA99A00FEF0E800FEEFE600FEED + E300FEEBE000FEE9DD00FEE7DB00FFE6D800FFE4D600FFE2D400FFE1D200FFE0 + D000FFDFCE00FFDECD0063493500000000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5A5A500A5A5A500A5A5A500A5A5 + A500A5A5A500A5A5A500000000000000000000000000B9A39500FFFFF600B3D0 + DD00337085009DA7AB00FADCC600F9D2B800F4C6AA00EFBDA000E7B39500DDA7 + 8900D39C7D00AB9081006349350000000000B7A29300FCF8F400AF8D7A00A37A + 65008C5D440076452C006F3E2500FAEEE400AF8D7A00A37A65008C5D44007645 + 2C006F3E2500F9E6D900E3C5AF0063493500C0AA9B00FEF2EB00CB977D00DB9D + 7F00EAA38000E99D7700E8976D00E7906300E6885900E5824F00E47C4600E478 + 3F00E57E4A00FFDFCE0063493500000000000000000000000000FFFFFF00FFFF + FF00A5A5A500A5A5A500A5A5A500A5A5A500FFFFFF00FFFFFF00FFFFFF00FFFF + FF00A5A5A500A5A5A500000000000000000000000000B9A39500FFFFF60000AF + FC00C1FDFF002D677F00FBE4D200B7A39900B49F9200B69B8E00AF948500AD8F + 7F00DDA78900B29789006349350000000000B7A29300FCFAF600C8AD9B00E5D2 + C700D0A69100A984780084523700FAEFE500C8AD9B00E5D2C700D0A69100A984 + 780084523700F9E7DA00E2C8B40063493500C1AC9D00FEF4EE00C7907400FCBF + 9E00F3AD8800F3A77F00F09D7300EC956A00E58C6200DE825A00D6795300CD70 + 4B00E2733A00FFE0D00063493500000000000000000000000000FFFFFF00FFFF + FF00A5A5A500A5A5A500A5A5A500A5A5A500FFFFFF00FFFFFF00FFFFFF00FFFF + FF00A5A5A500A5A5A500000000000000000000000000BAA59600FFFFF600B6DD + EF0000AFFC00B2D2DC00FCEDDD00FBE2CE00F9D7C000F8CDB200F4C3A600EFBD + A000E7B39500BAA193006349350000000000B7A29300FDFCF900CEB6A700B9E4 + FF00AFBFFF004E87FF00A3765F00FAF0E700CEB6A700B9E4FF00AFBFFF004E87 + FF00A3765F00F9E8DB00E1CBB90063493500C3AD9E00FEF6F000C68E7200FDC5 + A800FFE7D900FFE4D600FFE1D100FFDDCC00FFDBC800FFD5C200FFD0BC00D679 + 5300E2723900FFE1D20063493500000000000000000000000000FFFFFF00FFFF + FF00A5A5A500A5A5A500A5A5A500A5A5A500FFFFFF00FFFFFF00FFFFFF00FFFF + FF00A5A5A500A5A5A500000000000000000000000000BCA69800FFFFF600FFFF + F600FFFFF600FEFCF200FEF5E800FCEAD900FBDFCB00F9D4BC00F8CCB000F4C3 + A600EFBDA000C1A99C006349350000000000BAA59600FDFDFB00D4BEB200D1BB + AB00CBB09E00C1A38F00B2917A00FAF1EA00D4BEB200D1BBAB00CBB09E00C1A3 + 8F00B2917A00F9E9DD00E0CEBF0063493500C4AE9F00FDF7F300C68E7200FDCC + B100FDC5A700FCBE9D00F9B38F00F6AA8300F3A17800ED986F00E68E6600DE82 + 5A00E2723900FFE2D40063493500000000000000000000000000FFFFFF00FFFF + FF00A5A5A500A5A5A500A5A5A500A5A5A500FFFFFF00FFFFFF00FFFFFF00FFFF + FF00A5A5A500A5A5A500000000000000000000000000BEA89900FFFFF60095A3 + FF002E3BA5008F96CD00FEFAF000FDF2E400FCE8D500FADCC600F9D2B800F8CA + AE00F4C3A600C7B0A3006349350000000000BEA99A00FEFEFD00FDFDFB00FDFB + F900FCFAF600FCF8F300FCF6F000FBF3ED00FAF2E900FAEFE600FAEEE400FAEC + E200FAEBE000FAEADE00E0D2C50063493500C5B0A100FDF9F500C68E7200FED2 + B900FFECE100FFE9DD00FFE7D900FFE4D500FFE1D100FFDDCC00FFDBC800E58C + 6200E3733900FFE4D60063493500000000000000000000000000A5A5A500A5A5 + A500FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5A5A500A5A5A500A5A5A500A5A5 + A500FFFFFF00FFFFFF00000000000000000000000000C0AA9C00FFFFF6004360 + FF0095B3FF002F39AD00FFFFF600B9A79E00B6A29700B49D9100B2998B00B096 + 8800F7C8AC00CCB6A9006349350000000000BEA99A00FFFEFE00AF8D7A00A37A + 65008C5D440076452C006F3E2500FCF5EF00AF8D7A00A37A65008C5D44007645 + 2C006F3E2500FAEBDF00DFD5CB0063493500C7B1A200FDFBF700C68E7200FFD7 + C200FED1B800FDCBAF00FDC4A600FCBD9C00FBB59100F7AB8400F2A07700EC94 + 6A00E3733900FFE6D80063493500000000000000000000000000A5A5A500A5A5 + A500FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5A5A500A5A5A500A5A5A500A5A5 + A500FFFFFF00FFFFFF00000000000000000000000000C3AE9E00FFFFF60096A3 + FF004661FF0094A1FF00FFFFF600FFFEF500FEF7EA00FCEDDD00FBE2CE00F9D7 + BF00F8CDB200CEB8AB006349350000000000C3AE9E00FFFFFE00C8AD9B00E5D2 + C700D0A69100A984780084523700FCF8F300C8AD9B00E5D2C700D0A69100A984 + 780084523700FAECE100DED8D00063493500C8B2A300FDFCF900C68E7200FFDC + C900FFF0E800FFEEE500FFECE000FDC3A500FCBD9B00FBB69100FAAF8800F09C + 7200E3743A00FEE7DB0063493500000000000000000000000000A5A5A500A5A5 + A500FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5A5A500A5A5A500A5A5A500A5A5 + A500FFFFFF00FFFFFF00000000000000000000000000C5B0A000FFFFF600FFFF + F600FFFFF600FFFFF600FFFFF600FFFFF600FFFDF300FEF4E700FCEAD900FADE + CA00F9D4BC00D0BBB0006349350000000000C8B2A300FFFFFF00CEB6A700B9E4 + FF00AFBFFF004E87FF00A3765F00FCFAF700CEB6A700B9E4FF00AFBFFF004E87 + FF00A3765F00FAEDE200DEDBD50063493500C9B3A400FDFDFB00C78F7400FFDF + CE00FFDBC800FFD6C000FED1B700FDCAAE00FDC3A500FCBD9B00FBB69100FAAF + 8700E4784000FEE9DD0063493500000000000000000000000000A5A5A500A5A5 + A500FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5A5A500A5A5A500A5A5A500A5A5 + A500FFFFFF00FFFFFF00000000000000000000000000C7B1A200FFFFF600FF9B + 9900B8303000FF8D6A00FFFFF600FFFFF600FFFFF600FEFAF000FDF1E400FCE7 + D500FADCC700D3C1B6006349350000000000CCB6A700FFFFFF00D4BEB200D1BB + AB00CBB09E00C1A38F00B2917A00FDFCF900D4BEB200D1BBAB00CBB09E00C1A3 + 8F00B2917A00FAEFE600E2E1DB00644A3600CAB4A500FDFEFD00CE9F8700C893 + 7800C78C6F00C88B6D00C8866600C67E5A00C4774F00C3714700C36B3F00C467 + 3900CC744500FEEBE00063493500000000000000000000000000A5A5A500A5A5 + A500A5A5A500A5A5A500A5A5A500A5A5A500FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00000000000000000000000000C9B3A500FFFFF600FF83 + 7E00FFC3C400B7252500FFFFF600BAAAA100B8A69C00B6A29600B39D9000B198 + 8B00FBE4D200D6C7BD006349350000000000CCB6A700FFFFFF00FFFFFF00FFFF + FF00FFFFFE00FFFEFE00FEFDFD00FEFDFB00FDFBF900FDFAF700FCF8F300FCF5 + EF00FBF4EC00FBF1E900FAEFE600644A3600CBB5A600FDFFFE00FDFEFD00FDFD + FB00FDFCF900FDFBF700FDF9F500FDF7F300FEF6F000FEF4EE00FEF2EB00FEF0 + E800FEEFE600FEEDE30063493500000000000000000000000000A5A5A500A5A5 + A500A5A5A500A5A5A500A5A5A500A5A5A500FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00000000000000000000000000CBB5A600FFFFF600FFA9 + A900FF827F00FF989300FFFFF600FFFFF600FFFFF600FFFFF600FFFEF400FDF7 + EB00FCEDDD00D7CCC3006349350000000000EAAA8B00EAAA8B00E9A78700E9A2 + 8000E99D7700E7976D00E6906500E6895B00E4825100E37B4800E3764100E273 + 3A00E2723800E2723900E2723900C8622F0000000000CBB5A600CAB4A500C9B3 + A400C8B2A300C7B1A200C5B0A100C4AE9F00C3AD9E00C1AC9D00C0AA9B00BEA9 + 9A00BDA89900BCA7980000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000CBB5A600FFFFF600FFFF + F600FFFFF600FFFFF600FFFFF600FFFFF600FFFFF600FFFFF600FFFFF600FEFC + F300FDF4E700FCEADA006349350000000000EAAA8B00FFC2A200FEBF9D00FCBB + 9800FCB89400FBB59000FAB18C00F9AD8700F9A98100F8A67C00F6A27800F59F + 7300F59B6D00F4986800F3956500CD6531000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000CCB6A700CCB6A700CAB5 + A600CAB3A400C8B2A300C5AFA100C3AD9E00C0AB9C00BEA99A00BCA69700BAA4 + 9600B8A39400B8A39400B8A3940000000000EAAA8B00EAAA8B00EAAA8C00EAA9 + 8900EAA58400E9A17F00E89D7800E7977000E7926800E68D6000E5885900E483 + 5100E47E4A00E4794300E3763E00E27239000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000091877D00525050005954510058524D0058504900584E + 4700574C4400564A4000584C42004B413A000000000000000000000000000000 + 000000000000000000000000000000000000745A4600694F3B00CAC2BB000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000D7D7D70072747400C6C7C7000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000D7D7D70072747400C6C7C7000000000000000000000000000000 + 00000000000000000000AC9A8D00FFFFFF00FDFFFF00FFFDF700FFF8ED00FEF1 + E000FDEAD500FCE5CC00FFEACF00574B41000000000000000000000000000000 + 0000000000000000000000000000BBADA10081685400CAB2A400684E3A000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000C6C7C6004D504F00328DB300436674000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000C6C7C6004D504F00328DB300436674000000000000000000000000000000 + 00000000000000000000AC989000FFFFFE00FFFFFF00FEF8F400FFF2ED00FCEB + E300FCE6D900FCE0CE00FFE2CF00574B4100000000000000000000000000967C + 69000000000000000000000000008C735F00DFCABE00BDA79800705743000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C6C7 + C6004D504F002B97C60087D8EF006493A5000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C6C7 + C6004D504F002B97C60087D8EF006493A5000000000000000000000000000000 + 00000000000000000000AA9A8D00FFFFFF00FFFFFF00FFFBF900FEF6F200FCF1 + EC00FCECE200F9E3D600FEE7D500574B41000000000000000000000000009C83 + 70007F655200CEC6BF00CABEB50091796600E9D7CE007C634F00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C6C7C6004D50 + 4F002B97C60087D8EF006493A500000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C6C7C6004D50 + 4F002B97C60087D8EF006493A500000000000000000000000000000000009187 + 7D005250500059545100AB998C00FFFEFF00FFFFFF00FFFEFD00FFF9F800FCF3 + F000FCEDE600FDE8DD00FFEDDF00574B4100000000000000000000000000A38A + 7700DCD1CB006D533F0091796600DDCEC500D6C5BB00856C5900000000000000 + 000000000000000000000000000000000000000000000000000000000000E8E2 + DE00CDBAAD00937C6B0077584400775843009C7D6B00ABADAC002D3442002B97 + C60087D8EF006493A5000000000000000000000000000000000000000000E8E2 + DE00CDBAAD00937C6B0077584400775843009C7D6B00ABADAC002D3442002B97 + C60087D8EF006493A5000000000000000000000000000000000000000000AC9A + 8D00FFFFFF00FDFFFF00AB9B8E00FEFEFE00FFFEFF00FFFFFF00FFFFFF00FFFF + FE00FFFEF900FCF9F000FEFDF100574B4100000000000000000000000000AA91 + 7F00F9F4F100DDD4CD00856C5800F3EAE500947C6900DCD4CE00000000000000 + 0000000000000000000000000000000000000000000000000000DED6D0008668 + 54009D816500BFA27E00D0AD8700B4957300937559006E5440004F80910087D8 + EF006493A5000000000000000000000000000000000000000000DED6D0008668 + 54009D816500BFA27E00D0AD8700B4957300937559006E5440004F80910087D8 + EF006493A500000000000000000000000000000000000000000000000000AC98 + 9000FFFFFE00FFFFFF00AA998F00FBAC8500ED916500E2825600DF7D4F00DB74 + 4600D96E4000D4693800D9693600574B4100000000000000000000000000B098 + 8600FCFAF900FBF7F600F9F5F200F7F2EE00896F5C00664C38006A503C00765C + 49000000000000000000000000000000000000000000F7F5F300896E5C00C1AB + 8B00ECD1AA00EED2AE00ECCFA700E7C79E00D8B28A00A1816200725642006493 + A5000000000000000000000000000000000000000000F7F5F300896E5C00C1AB + 8B00ECD1AA0010708800114A5D0012445600D8B28A00A1816200725642006493 + A50000000000000000000000000000000000000000000000000000000000AA9A + 8D00FFFFFF00FFFFFF00C59F9400AA9B8C00B1907900C1795A00AE704F00AA63 + 470099583E0098583B009A5A3C007A4E3B00000000000000000000000000B79F + 8D00FFFFFE00FEFDFC00FDFBFA00FBF8F700FAF6F300DFD5CE00886E5B000000 + 00000000000000000000000000000000000000000000C5B7AE00B0998100F2DF + BA00F3E1C100F2E1C100F0DEBB00EDD8B200E7CBA300D3AD8700927357006D66 + 5D000000000000000000000000000000000000000000C5B7AE00B0998100F2DF + BA00F3E1C10021889A0020B8D3000C242A00E7CBA300D3AD8700927357006D66 + 5D000000000000000000000000000000000091877D005250500059545100AB99 + 8C00FFFEFF00FFFFFF00FFFEFD00FFF9F800FCF3F000FCEDE600FDE8DD00FFED + DF00574B4100000000000000000000000000000000000000000000000000BDA6 + 9400FFFFFF00FFFFFF00FFFFFF00FEFDFD00E2DAD5009A826F00000000000000 + 00000000000000000000000000000000000000000000B19E9100CDBCA400139A + C6001E98B6001E92AD001A809A000F5267000D313E000E3C4F00B5947200886E + 5E000000000000000000000000000000000000000000B19E9100CDBCA400139A + C6001E98B6001E92AD003DD4EE000F5267000D313E000E3C4F00B5947200886E + 5E0000000000000000000000000000000000AC9A8D00FFFFFF00FDFFFF00AB9B + 8E00FEFEFE00FFFEFF00FFFFFF00FFFFFF00FFFFFE00FFFEF900FCF9F000FEFD + F100574B4100000000000000000000000000000000000000000000000000C3AC + 9900FFFFFF00FFFFFF00FFFFFF00ECE7E300AB93810000000000000000000000 + 0000000000000000000000000000000000000000000097817100E3DAC40039AF + D000A4F0FC008BEBF90062EBFB0043D8F10030BED60010475500CCA682007254 + 3F00000000000000000000000000000000000000000097817100E3DAC40039AF + D000A4F0FC008BEBF90062EBFB0043D8F10030BED60010475500CCA682007254 + 3F0000000000000000000000000000000000AC989000FFFFFE00FFFFFF00AA99 + 8F00FBAC8500ED916500E2825600DF7D4F00DB744600D96E4000D4693800D969 + 3600574B4100000000000000000000000000000000000000000000000000C8B0 + 9E00FFFFFF00FFFFFF00F6F2F000BDA593000000000000000000000000000000 + 00000000000000000000000000000000000000000000BFB0A600CFC4B60057BA + DE0068C2DD0045C0CF0045C0CF0029A1B6001682900012768D00C0A27D00795C + 48000000000000000000000000000000000000000000BFB0A600CFC4B60057BA + DE0068C2DD0045C0CF0082ECFB0029A1B6001682900012768D00C0A27D00795C + 480000000000000000000000000000000000AA9A8D00FFFFFF00FFFFFF00C59F + 9400AA9B8C00B1907900C1795A00AE704F00AA63470099583E0098583B009A5A + 3C007A4E3B00000000000000000000000000000000000000000000000000CBB4 + A200FFFFFF00F7F4F100CAB3A100000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000E1DAD600C1B4A800F0EB + E300FBFAF400FBF9F100FAF5EA00F5EDD700F1DFBF00E6CBA4009E856800B6A7 + 9C000000000000000000000000000000000000000000E1DAD600C1B4A800F0EB + E300FBFAF40062BDDA00ABF4FC002FA8C600F1DFBF00E6CBA4009E856800B6A7 + 9C0000000000000000000000000000000000AB998C00FFFEFF00FFFFFF00FFFE + FD00FFF9F800FCF3F000FCEDE600FDE8DD00FFEDDF00574B4100000000000000 + 000000000000000000000000000000000000000000000000000000000000CBB4 + A200F6F3F000CBB4A20000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000F3F0EE00C1B3A900D1C6 + BE00F6F4EA00F9F6E600F6F2DE00F4EACE00E5D4B200B59E80007A5E4A00EBE7 + E5000000000000000000000000000000000000000000F3F0EE00C1B3A900D1C6 + BE00F6F4EA0061BDE0003DAFD00021A4CA00E5D4B200B59E80007A5E4A00EBE7 + E50000000000000000000000000000000000AB9B8E00FEFEFE00FFFEFF00FFFF + FF00FFFFFF00FFFFFE00FFFEF900FCF9F000FEFDF100574B4100000000000000 + 000000000000000000000000000000000000000000000000000000000000CBB4 + A200CBB4A2000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000E7E0DC00C0B2 + A900CABFB300D6CBBB00DED4BB00C3B29800A59076008D735F00D4CAC2000000 + 0000000000000000000000000000000000000000000000000000E7E0DC00C0B2 + A900CABFB300D6CBBB00DED4BB00C3B29800A59076008D735F00D4CAC2000000 + 000000000000000000000000000000000000AA998F00FBAC8500ED916500E282 + 5600DF7D4F00DB744600D96E4000D4693800D9693600574B4100000000000000 + 000000000000000000000000000000000000000000000000000000000000CBB4 + A200000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000F7F5 + F400E0D9D300C7B9AF00B7A69A00A4918200BAAA9D00F2E7E200000000000000 + 000000000000000000000000000000000000000000000000000000000000F7F5 + F400E0D9D300C7B9AF00B7A69A00A4918200BAAA9D00F2E7E200000000000000 + 000000000000000000000000000000000000C59F9400AA9B8C00B1907900C179 + 5A00AE704F00AA63470099583E0098583B009A5A3C007A4E3B00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001010100010101000101010001010 + 1000101010001010100010101000101010001010100010101000101010001010 + 1000101010001010100010101000101010000000000000000000000000000000 + 0000A5795F0080472800804728007F4425007E4121007C3E1C007B3A18007936 + 130078330E0077300B00762E0800000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001010100010101000101010001010 + 1000101010001010100010101000101010001010100010101000101010001010 + 1000101010001010100010101000101010000000000000000000000000000000 + 0000A97E6600FEF1EA00FEF1EA00FCECE300FAE4D900F6DBCC00F3D1C000F0C9 + B400EEC1A900ECBCA20077300A000000000010428C0010216B0010216B001021 + 6B0010216B0010216B0010216B0010216B0010216B0010216B0010216B001021 + 6B0010216B0010216B0010216B00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001010100000000000000000000808 + 0800101010000800000000000000000000000000000000000000000000000000 + 0000000000000000000000000000101010000000000000000000A5795F008047 + 2800804728007F4425007E4121007C3E1C007B3A18007936130078330E007730 + 0B00762E0800EEC1A80077320D000000000010428C0000000000000000001031 + 7B0010397B005A9CC60010216B00000000000000000008185A00000000000000 + 0000000000000000000010216B00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001010100000000000000000001818 + 1800101010000000000000000000000000000000000018182100311831000000 + 0000000000000000000000000000101010000000000000000000A97E6600FEF1 + EA00FEF1EA00FCECE300FAE4D900F6DBCC00F3D1C000F0C9B400EEC1A900ECBC + A20077300A00F0C7B100783410000000000010428C0000000000081052001029 + 73003973AD003973B5006BA5CE0010317B004A8CBD0018529C00000010000818 + 5A00000000000000000010216B00000000000000000000000000000000000000 + 000000000000000000000000000096492400EADBD30000000000000000000000 + 0000000000000000000000000000000000001010100000000000000000002931 + 2900182121000000000000000000080808001821290063527B008C4A94003929 + 4A0010101000000000000000000010101000A5795F0080472800804728007F44 + 25007E4121007C3E1C007B3A18007936130078330E0077300B00762E0800EEC1 + A80077320D00F2CEBB007A3714000000000010428C0000000000104A94001852 + 9C00296BAD004A8CBD00528CBD002163A500215A9C004284B500081039000000 + 1000000000000000000010216B00000000000000000000000000000000000000 + 00000000000000000000000000009D4D25009D4E2800EADBD300000000000000 + 0000000000000000000000000000000000001010100000000000080808004A42 + 4A004A4A4A001818180008080000393942006B6B94009473AD00B563BD00BD94 + C6008C949400292921000000000010101000A97E6600FBEFEB00CFA89500C799 + 8300BA928000A783710096746300856557004A372B00574B3F0077300A00F0C7 + B10078341000F5D7C6007B3A18000000000010428C0000000000215AA5003173 + AD002163A5004284BD004284B5004284B50010428C0018529C0010428C00296B + A500081863000000100010216B0000000000000000000000000000000000CF83 + 5D00924723009A4B2500A24F2700AB542900BF6A3F00A0502A00EADBD3000000 + 0000000000000000000000000000000000001010100000000000000000005242 + 4A008C738C00847B8400636363004A425200948CB5009CA5CE007B5A8C008463 + 8400636B6B00293129000808080010101000AE856D00FFFFFF00F3DFD500DCAF + 9800D39F8700CA9B8500C1978200523928009F85740039342F0077320D00F2CE + BB007A371400F8DFD2007C3D1B000000000010428C0008186300397BB5003973 + B5002163A5003173AD0018529C00215A9C0010428C004A8CBD0018529C002963 + A5003973AD000810390010216B0000000000000000000000000000000000D78B + 6500FDB08900F7905C00EC885600DE7F4F00D1764800C46E4200A2563100EADB + D300000000000000000000000000000000001010100021182100292929004A42 + 4200948C9400B59CB500B5A5B5006B636B0084738C00ADB5DE005A5A7B001008 + 080008000000000000001008100010101000B28B7400B4A39600FEFBFA00F1DF + D500DFB19B00C9A79700715B4C00C7B4AA0070655D004B423F0078341000F5D7 + C6007B3A1800FBE6DB007D401F000000000010428C00103984004A8CBD00397B + B500427BB5002963A5003173AD0010428C0010428C0018529C00104A94000821 + 630010397B000810520010216B0000000000000000000000000000000000DE92 + 6C00FCB99700FDA57800FC935E00F28C5900E5845300D87B4C00C66E4100AE58 + 2B000000000000000000000000000000000010101000291831007B6373007363 + 6B008C7384009C8CA500A594A500946B7B006B5263008484A500636B84000000 + 000000000000000000000000000010101000B7927B00ECE5E100AE9A8A00FCF5 + F200F0DDD2006D5646009D8A7F009D8E86004C342900ECBCA2007A371400F8DF + D2007C3D1B00FCEDE4007E4323000000000010428C0063A5CE004A8CBD003973 + B5003173AD001039840008185A000008210008185A00104A940063A5CE008CBD + DE00102973000810390010216B0000000000000000000000000000000000E498 + 7200FBC3A600FDBE9E00FEAE8500FFA87D00F89D6F00E5835100AE582B00F4E7 + E10000000000000000000000000000000000101010001010100094848C00C6B5 + C6009C8C940084738400736B7B005A4A5A00423142004A39520052526B001010 + 180000000000000000000000000010101000BC988200FFFFFF00E2D8D200AF99 + 89009E897C00C5A89800BAABA300BBA79D00FDDAC800EDC3AC007B3A1800FBE6 + DB007D401F00FEF1EA007F4525000000000010428C0008185A00397BB5003973 + AD0018529C0010428C002963A50010317B00639CCE003973B5005A9CC6004A84 + BD00081052000810520010216B0000000000000000000000000000000000E89C + 7600E2967000DA8E6800D1855F00DB906A00F79A6B00AE582B00F4E7E1000000 + 00000000000000000000000000000000000010101000000800007B7B8400EFDE + E700BDA5B500AD94A50073636B00212129000808080021101800293139001010 + 180000000000000000000000000010101000C09D8800FFFFFF00FFFFFF00E6DC + D600E9DACD00E2E2F2005568CC003554CF00D0C3D400EECAB8007C3D1B00FCED + E4007E432300A2745A009E6F54000000000010428C000000000008216300427B + B5002963A5003173AD00427BB5003973AD00639CCE004A84BD003973B50073AD + D600104A94000810390010216B00000000000000000000000000000000000000 + 0000000000000000000000000000E5997300C5764E00F3E6DF00000000000000 + 0000000000000000000000000000000000001010100008000800313939006B6B + 6B005A4A520063525A006B5A6300211821000000000000000000101821001010 + 210008000000000000000000000010101000C4A38E00FFFFFF00FFFDFC00FFFF + FF00FFFFFB006572C9004BA0ED002374CB002A4AC100EED3C5007D401F00FEF1 + EA007F45250000000000000000000000000010428C0000000000000000001042 + 8C005294C600427BB5003973B5007BB5D600397BB500215AA5009CC6DE0073AD + D600082163001039840010216B00000000000000000000000000000000000000 + 0000000000000000000000000000E89C7600F8EDE80000000000000000000000 + 0000000000000000000000000000000000001010100000000800000000000000 + 0000000000000808080031313100101810000000000000000000081018001010 + 290008080800000000000000000010101000C7A79200FFFFFF00FFFBFA00FFFB + FA00FFFFFD008D97D20093C3E8004EA5EF00656CBA00EFDBD1007E432300A274 + 5A009E6F540000000000000000000000000010428C0000000000000000000000 + 00000008310010296B004A8CBD007BADD6004284BD007BADD600B5D6EF001852 + 9C00081052000008310010216B00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001010100000000000000000000000 + 0000000000000000000010081000080000000000000000000000000000000808 + 080000000000000000000000000010101000E2BDA600FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E2E5F5009BA5DD008D96D300ECE9F100FEF1EA007F4525000000 + 00000000000000000000000000000000000010428C0000000000000000000000 + 0000081052000000000008216300081863002963A50008185A00081052000810 + 390010216B0008185A0010216B00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001010100010101000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000001010100010101000E2BDA600E2BDA600C1A08A00C1A0 + 8A00BD998300B7927B00B28A7200AC826A00A77B6200A2745A009E6F54000000 + 00000000000000000000000000000000000010428C0000000000000000000000 + 000000000000000000000000000008185A000810520000082100000831000008 + 3100000831000008210010216B00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001010100010101000101010001010 + 1000101010001010100010101000101010001010100010101000101010001010 + 1000101010001010100010101000101010000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000010428C0010428C0010428C001042 + 8C0010428C0010428C0010428C0010428C0010428C0010428C0010428C001042 + 8C0010428C0010428C0010428C00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008442 + 3100844231000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008442 + 3100844231000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008C42 + 39008C4239000000000000000000000000000000000000000000000000000000 + 0000F0E1D900CB9E8700AE7050009956330099563300B1725200D1A28A00F4E5 + DE0000000000000000000000000000000000F3F1EF00E3DEDB00927A69008C75 + 630087705E00E3DEDB007F6654007A624F00755D4A00E3DEDB006E5441006A51 + 3E00674E3A00E3DEDB0000000000000000000000000000000000000000000000 + 000000000000DEEAE00000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000A552 + 4200A5524200A5524200A54A42009C4A42009C4A42009C4A3900944A39009442 + 39008C4A39008C4239008C4239008C423900000000000000000000000000E2C8 + BB00B5785700A7562D00B45C2E00B65C2E00B55C2D00B55C2D00BB5F3300D38D + 6A00F1D5C700000000000000000000000000E3DEDB00AE988800EFE3DD00F2E7 + E100EDDFD700836B5900B79B8B00DBBDAD00D9B7A60072594600AE8B7700D0A6 + 9200CC9E8700654B3800E3DEDB00000000000000000000000000000000000000 + 00000000000009631400DEEAE000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000B55A + 4200AD524200AD524200A5524200A5524200A5524200A55242009C4A42009C4A + 42009C4A3900944A3900944A39008C4A39000000000000000000F1E2DA00B778 + 5700B35B2E00DF835300F29A6C00F1996E00EE966900E78D5E00DC7D4D00D476 + 4800E09C7900F9EAE3000000000000000000B7A29300FBF8F700F9F4F200F7F0 + EC00F4EBE600F1E5DF007F6754007A624F00765D4A00735946006E5542006B52 + 3E00674E3A00654B380063493500000000000000000000000000000000000000 + 00000000000011681B0004600F00DEEAE0000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000B55A + 4A00B55A4A00B5524A000000000000000000000000000000000000000000A552 + 42009C4A42000000000000000000000000000000000000000000CE9F8700AA57 + 2D00DF835300FBAD8700FECBB000FDE9DF00FBE7DD00F1BCA100DC885D00D87A + 4A00E58D5F00F3C4AD000000000000000000B7A29300FDFCFB00FBF9F700FAF5 + F200F7EFED00F4EAE600F2E5DF00DDDCD700DFD7CE00DECDC000DEC5B600DEBF + AC00DBBAA600D8B5A30063493500000000000000000000000000000000000000 + 0000000000001A6F240020732C0004600F00DEEAE00000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C65A + 4A00BD5A4A0000000000B55A4A0000000000000000000000000000000000AD52 + 4200A55242000000000000000000000000000000000000000000B5745300B85C + 2F00F0966800FDC8AE0000000000000000000000000000000000DCA58900CB6D + 3F00ED946500F4B291000000000000000000B7A29300FFFFFF00B47F6500B47F + 6400EDDDD500B37E6300F4EBE600F1E5DF00EFDFD700EBD9D100E8D3C900E5CD + C100E1C6B900D6B3A100634A3500000000000000000000000000000000000000 + 00000000000023752E002F833D0020732C0004600F00DEEAE000000000000000 + 000000000000000000000000000000000000000000000000000000000000C663 + 4A00C6634A000000000000000000BD5A4A00000000000000000000000000B552 + 4200AD5242000000000000000000000000000000000000000000A0583400BA5E + 3100EC946600FBE7DC0000000000000000000000000000000000EFDAD000BF65 + 3600EE956600F3A985000000000000000000B9A49500FFFFFF00FFFFFF00FDFC + FC00FCF9F700FAF4F200F6F0EC00F4EBE500F2E5DF00EEDFD800EBD9D000E8D3 + C800E5CCC100DBBDAD00634A3600000000000000000000000000000000000000 + 0000000000002E7C370050A25A002F833D0020732C0004600F00DEEAE0000000 + 000000000000000000000000000000000000000000000000000000000000D663 + 5200CE635200000000000000000000000000C65A4A000000000000000000BD5A + 4A00B55A4A000000000000000000000000000000000000000000A0583400B65C + 2E00DE825300F7E3D80000000000D4886200FEFCFC0000000000EFDAD000BD60 + 3300ED956700F3AB87000000000000000000BDA79800FFFFFF00968E8800EEDE + D700968E8700EDDDD600968D8600958C8500F4EBE600F2E5DF00EFDFD800ECD9 + D000E8D3C900E0C7BA00634A3500000000000000000000000000000000000000 + 000000000000388341005DB0680050A25A002F833D0020732C000B661800DEEA + E00000000000000000000000000000000000000000000000000000000000D66B + 5200D663520000000000000000000000000000000000C65A4A0000000000C65A + 4A00BD5A4A000000000000000000000000000000000000000000B6765500B65C + 2E00CE6E3D00E5AE9100E9C2AE00DC926D000000000000000000CE997E00BF63 + 3500EF976C00F5B694000000000000000000C1AB9C00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FDFCFC00FBF8F700FAF4F200F7F0EC00F4EAE600F1E5DF00EEDF + D700EBD9D000E6D1C600634A3500000000000000000000000000000000000000 + 000000000000438A4C006BBF76006BBF760050A25A002F763900D6EDD9000000 + 000000000000000000000000000000000000000000000000000000000000DE6B + 5200DE6B52000000000000000000000000000000000000000000CE635200CE63 + 5200C6634A000000000000000000000000000000000000000000D5A58C00BE62 + 3300D06B3800DB7C4D00DE855600E8A17D000000000000000000A65E3A00CB6F + 4300F6A37800FACCB3000000000000000000C5AFA000FFFFFF00B4806500B480 + 6500968E8800C2B0A300968E8700968E8600F9F4F200F7EFEC00F4EBE600F2E5 + DF00EFDFD800EADBD10063493600000000000000000000000000000000000000 + 0000000000004B9053006BBF7600A3DAB0002F763900D6EDD900000000000000 + 000000000000000000000000000000000000E76B5A00E76B5A00E76B5A00E76B + 5A00E76B5A00E76B5200DE6B5200DE6B5200DE635200D66B5200D6635200D663 + 5200CE6352000000000000000000000000000000000000000000F5E6DF00D48F + 6A00DB784600F18E5C00F69E7000F4AF8C000000000000000000BE7A5500E48F + 6500FDBC9E00FEEFE8000000000000000000C8B2A300FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FDFCFC00FCF8F700F9F5F200F7F0EC00F4EB + E600F1E5DF00EEE2DA00644A3600000000000000000000000000000000000000 + 00000000000052945A00A3DAB0002F763900D6EDD90000000000000000000000 + 000000000000000000000000000000000000E76B5A00E76B5A00E76B5A00E76B + 5A00E76B5A00E76B5A00E76B5A00E76B5A00E76B5200DE6B5200DE635200D66B + 5200D66B5200000000000000000000000000000000000000000000000000E2AF + 9400E68E6100FAA27600FFB08800FCB997000000000000000000FBF2ED00F6BF + A400FEE3D500000000000000000000000000C9B4A500FFFFFF00FFFFFF0066A3 + 650066A3650066A36500C0B4AD0066A3650066A3650066A26400FAF5F200F7F0 + EC00F4EBE600EEE2DA00644A3600000000000000000000000000000000000000 + 000000000000589860002F763900D6EDD9000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E76B + 5A00E76B5A000000000000000000000000000000000000000000000000000000 + 000000000000DE6B520000000000000000000000000000000000DA8F6A00E39A + 7600EDA78300F6B28F00FCB99700FCB997000000000000000000000000000000 + 000000000000000000000000000000000000C8B2A300FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FEFCFB00FBF9F700FAF4 + F200F7F0ED00F3EAE400644A3600000000000000000000000000000000000000 + 00000000000058986000D6EDD900000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E76B + 5A00E76B5A000000000000000000000000000000000000000000000000000000 + 00000000000000000000DE6B5200000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C8B2A300CAB4A500CBB5A600CAB4 + A500C9B3A400C7B2A300C6B0A100C3AE9F00C1AC9D00BFAA9B00BDA89900BBA6 + 9700B9A49500B8A39400B7A29300000000000000000000000000000000000000 + 000000000000D6EDD90000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E76B + 5A00E76B5A000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000F7E7E700FFEF + E700FFEFE700FFEFE700FFEFE700FFEFEF00F7EFE70000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000F3F1EF00E3DEDB00927A69008C75 + 630087705E00E3DEDB007F6654007A624F00755D4A00E3DEDB006E5441006A51 + 3E00674E3A00E3DEDB0000000000000000000000000000000000FFF7E700FFEF + DE00FFEFDE00FFEFDE00FFEFE700FFEFE700FFEFE70000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000007B7B7B00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF000000000000000000E3DEDB00AE988800EFE3DD00F2E7 + E100EDDFD700836B5900B79B8B00DBBDAD00D9B7A60072594600AE8B7700D0A6 + 9200CC9E8700654B3800E3DEDB00000000000000000000000000FFEFE700FFE7 + D600FFE7D600FFE7D600FFE7D600FFEFDE00FFE7DE0000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E39A + 7500B6623900B05C3300A7532A009D482000923E160089340D00822D0600812C + 05000000000000000000000000000000000000000000000000007B7B7B000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFF000000000000000000B7A29300FBF8F700F9F4F200F7F0 + EC00F4EBE600F1E5DF007F6754007A624F00765D4A00735946006E5542006B52 + 3E00674E3A00654B380063493500000000000000000000000000FFE7DE00FFDE + CE00FFDEC600FFDECE00FFDECE00FFE7D600FFDED60000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E397 + 7000F3BCA000D7A18300CE8D6D00C17C5900AF6B4800A76240009B583700812C + 05000000000000000000000000000000000000000000000000007B7B7B000000 + 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0000000000FFFFFF000000000000000000B7A29300FDFCFB00FBF9F700FAF5 + F200F7EFED00F4EAE600F2E5DF00DDDCD700DFD7CE00DECDC000DEC5B600DEBF + AC00DBBAA600D8B5A30063493500000000000000000000000000FFE7D600FFD6 + BD00FFD6BD00FFD6BD00FFDEC600FFE7CE00FFE7D60000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E79B + 7400F9C9AF00F5B59400EDA37E00E6956C00DA855900CE794E00AC6543008530 + 09000000000000000000000000000000000000000000000000007B7B7B000000 + 0000FFFFFF00FFFFFF00FFFFFF00FF000000FF000000FFFFFF00FFFFFF00FFFF + FF0000000000FFFFFF000000000000000000B7A29300FFFFFF00B47F6500B47F + 6400EDDDD500B37E6300F4EBE600F1E5DF00EFDFD700EBD9D100E8D3C900E5CD + C100E1C6B900D6B3A100634A3500000000000000000000000000FFDECE00FFD6 + B500FFCEAD00FFD6B500F7CEB500EFD6C600EFD6C60000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000EA9E + 7800F9D0BB00F8BDA100F4B09000EF9F7900E6926800DC845900B46B48008B36 + 0F000000000000000000000000000000000000000000000000007B7B7B000000 + 0000FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF00FF000000FFFFFF00FFFF + FF0000000000FFFFFF000000000000000000B9A49500FFFFFF00FFFFFF00FDFC + FC00FCF9F700FAF4F200F6F0EC00F4EBE500F2E5DF00EEDFD800EBD9D000E8D3 + C800E5CCC100DBBDAD00634A3600000000000000000000000000FFDEC600FFCE + AD00FFC6A500FFD6B50000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000EFA3 + 7D00FBD7C800F8C7AD00F7B79800F2AB8800ED9F7A00E6946D00BE775500923E + 16000000000000000000000000000000000000000000000000007B7B7B000000 + 0000FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF00FF000000FFFFFF00FFFF + FF0000000000FFFFFF000000000000000000BDA79800FFFFFF00968E8800EEDE + D700968E8700EDDDD600968D8600958C8500F4EBE600F2E5DF00EFDFD800ECD9 + D000E8D3C900E0C7BA00634A3500000000000000000000000000FFDEC600FFCE + AD00FFC6A500FFD6B50000000000F7A57B000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000F3A8 + 8100FBE1D300F9CEBA00F8BFA500F3B39400F2A88500EB9F7A00D08D6C009A46 + 1E000000000000000000000000000000000000000000000000007B7B7B000000 + 0000FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF00FF000000FFFFFF00FFFF + FF0000000000FFFFFF000000000000000000C1AB9C00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FDFCFC00FBF8F700FAF4F200F7F0EC00F4EAE600F1E5DF00EEDF + D700EBD9D000E6D1C600634A3500000000000000000000000000FFE7D600FFDE + C600FFDEC600FFE7CE0039292900000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000F6AD + 8600FBE5DA00FBDACA00F9CAB300F8C2A800F6B69800F3B39100DCA38700A24E + 25000000000000000000000000000000000000000000000000007B7B7B000000 + 0000FFFFFF00FFFFFF00FFFFFF00FF000000FF000000FFFFFF00FFFFFF00FFFF + FF0000000000FFFFFF000000000000000000C5AFA000FFFFFF00B4806500B480 + 6500968E8800C2B0A300968E8700968E8600F9F4F200F7EFEC00F4EBE600F2E5 + DF00EFDFD800EADBD10063493600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FAB0 + 8A00FCE1D500FBE2D400FAD8C600F9CDB900F9CAB300F9C6AC00F5BB9D00AA55 + 2D000000000000000000000000000000000000000000000000007B7B7B000000 + 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0000000000FFFFFF000000000000000000C8B2A300FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FDFCFC00FCF8F700F9F5F200F7F0EC00F4EB + E600F1E5DF00EEE2DA00644A3600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FDB3 + 8D00FAB08A00F6AD8600F3A88100EFA37D00EA9E7800E79B7400E3977000E39A + 75000000000000000000000000000000000000000000000000007B7B7B000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFF000000000000000000C9B4A500FFFFFF00FFFFFF0066A3 + 650066A3650066A36500C0B4AD0066A3650066A3650066A26400FAF5F200F7F0 + EC00F4EBE600EEE2DA00644A3600000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000737B8400293131002931 + 31000808080029313100293131004A525A000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000007B7B7B007B7B + 7B007B7B7B007B7B7B007B7B7B007B7B7B007B7B7B007B7B7B007B7B7B007B7B + 7B007B7B7B007B7B7B000000000000000000C8B2A300FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FEFCFB00FBF9F700FAF4 + F200F7F0ED00F3EAE400644A3600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C8B2A300CAB4A500CBB5A600CAB4 + A500C9B3A400C7B2A300C6B0A100C3AE9F00C1AC9D00BFAA9B00BDA89900BBA6 + 9700B9A49500B8A39400B7A29300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000063493500634935006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 3500634935006349350063493500634935000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000BD4A0000BD4A0000BD4A0000BD4A0000BD4A0000BD4A0000BD4A0800BD4A + 0800BD4A0000BD4A0000BD4A0000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000BFAA9B00FEF0E800FEEFE600FEED + E300FEECE100FEEADF00FEE9DD00FEE7DB00FFE6D900FFE5D700FFE3D500FFE2 + D300FFE1D200FFE0D000FFDFCF00634935000000000000000000000000000000 + 00000000000000000000B4A2A20073383800763B3C00602E2F00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000B5420000FFFFFF00FFFFFF00A5A5A500A5A5A500FFFFFF00FFFF + FF00A5A5A500A5A5A500AD42000000000000000000005A636300182121001821 + 21005A6363000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C0AB9C00FEF1EA002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FFE0D000634935000000000000000000000000008C63 + 64007A4444008F4243008E7A7A008E4B4B00C4616000602D2D0000000000B560 + 60006E343500CBABAB0000000000000000000000000000000000000000000000 + 00000000000000000000A5420000FFFFFF00A5A5A500A5A5A500FFFFFF00FFFF + FF00A5A5A500A5A5A500A5420000000000005A6363003984B500399CE700218C + D6002173A5002121290000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C1AB9C00FEF3EC002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FFE1D2006349350000000000ECDADB009D676800C176 + 7700C97B7B00642E2E006D353600BB666700C867660090454500562B2C007338 + 3900A851510076383900BA959500000000000000000094390000000000000000 + 000000000000000000000000000094390000FFFFFF00FFFFFF00A5A5A500A5A5 + A500FFFFFF00FFFFFF009439000000000000182121007BC6FF0073C6FF004AAD + EF003194DE001010100000000000000000000000000000000000000000005A63 + 630018212100182121005A63630000000000C2AC9D00FEF4EE002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FFE2D3006349350000000000E0BFC000A65E5E00E493 + 9300E08C8C00CB7C7C00C5757400D1757500CC6E6E00C8676700A3535300B458 + 5700C15D5C00BA5A590070383900000000000000000084310000843100000000 + 00000000000000000000000000000000000084310000FFFFFF00A5A5A500A5A5 + A500FFFFFF00FFFFFF0084310000000000001010100084D6FF009CE7FF0073C6 + FF005AB5EF0018212100000000000000000000000000000000005A6363003984 + B500399CE700218CD6002173A50021212900C2AD9E00FEF6F0002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FFE3D5006349350000000000E6CBCC00CA8D8D00BC75 + 7500E5939300E08C8C00DC858500D67D7D00D1767500CC6E6D00C8676600C361 + 6100BE5C5B00753A3B00DCC3C300000000000000000073290000CE5208007329 + 0000000000000000000000000000000000007329000073290000FFFFFF00FFFF + FF00A5A5A500A5A5A50073290000000000002121210073ADCE009CDEFF009CDE + FF0073A5CE005A63630000000000000000000000000000000000182121007BC6 + FF0073C6FF004AADEF003194DE0010101000C3AE9F00FDF7F2002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FFE5D700634935000000000000000000AA8E8F00B36A + 6C00E5979800E5939300C2747500A4606100A05C5D00B9686800CC6E6D00C767 + 6600A55353006430310000000000000000000000000063290000CE520800E77B + 420063290000000000000000000063290000632900006329000063290000FFFF + FF00A5A5A500A5A5A5006329000000000000000000005A636300182121000000 + 00005A63630000000000000000000000000000000000000000001010100084D6 + FF009CE7FF0073C6FF005AB5EF0018212100C5AFA000FDF8F4002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FFE6D90063493500D8C9CA00B75A5B00AC595A00B45C + 5D00EFA2A300C178790087515100E8CDCD00DBB7B800BE858600B8676700CC6E + 6D00C86766008D3B3B00703839006E3637000000000052210000CE520800E77B + 4200F7AD7B005A2100005A2100005A2100005A21000000000000000000005A21 + 0000FFFFFF00FFFFFF005A210000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000002121210073AD + CE009CDEFF009CDEFF0073A5CE005A636300C6B0A100FDFAF6002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FEE7DB0063493500C6B1B100DD858600FCB6B800F9B1 + B200F4AAAB007D3D3D00B1717000CDADAF00E6D4D500B17675009B575800D175 + 7500CC6E6D00C7676600C46161007D3D3E00000000004A180000CE520800E77B + 4200F7AD7B00FFCEB5004A1800004A1800000000000000000000000000000000 + 00004A180000FFFFFF004A180000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000005A63 + 630018212100182121005A63630000000000C7B1A200FDFBF8002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FEE9DD0063493500C5B0B100DE868600FDC0C100FBB5 + B600F8B1B20090494900DA939400824445008E555600C27E7F0099575800D67E + 7D00D1767500C5696A009E515200804041000000000039180000CE520800E77B + 4200F7AD7B00FFD6B500FFF7EF00391800000000000000000000000000000000 + 0000000000003910000039180000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C7B2A300FDFCF9002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FEEADF006349350000000000E5999A00E2A3A400E095 + 9600FAB4B600DB929300A96E6F00E7A4A500E49F9F00B0797900C0737400DB85 + 8400CE787800A35D5D00AE787800A67272000000000029100000CE520800E77B + 4200F7AD7B00FFD6B500FFF7EF00BDE7FF002910000000000000000000000000 + 0000000000000000000029100000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C8B3A400FDFDFB002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FEECE10063493500000000000000000000000000BB60 + 6100FBB6B700FDB7B800D78E8F008B48490088474800D1868700E4939300E08C + 8C00C37575006533340000000000000000000000000018080000CE520800E77B + 4200F7AD7B00FFCEB500FFF7EF00BDE7FF004AADF70018080000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C9B3A400FDFEFC002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FEEDE300634935000000000000000000BC515100F8B2 + B300FFBBBC00FDB9BA00FCB7B800F9B1B200F4AAAB00EEA3A300E8999900E593 + 9400E08C8C00BE7172007A484800000000000000000008000000CE520800E77B + 4200F7AD7B00FFCEB500FFF7EF00BDE7FF004AADF7000884EF00080000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000CAB4A500FDFEFD002C2C2C003C3C + 3C004E4E4E006161610076767600898989009E9E9E00B1B1B100C3C3C300D3D3 + D300E2E2E200EEEEEE00FEEFE600634935000000000000000000E5949300FAB5 + B600FEB9BA00CA7A7A00C3747500FCB6B800F9B1B200C07A7B00A2626300B873 + 7400E5939300C3787800A5656600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000CBB5A600FDFFFE00FDFEFD00FDFE + FC00FDFDFB00FDFCF900FDFBF800FDFAF600FDF8F400FDF7F200FEF6F000FEF4 + EE00FEF3EC00FEF1EA00FEF0E80063493500000000000000000000000000E8A2 + A200DE8F900000000000CF8A8D00FFBBBC00FCB6B700A0575A0000000000DAAF + B000A9696800AA696A0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000CBB5A600CBB5A600CAB4A500C9B3 + A400C8B3A400C7B2A300C7B1A200C6B0A100C5AFA000C3AE9F00C2AD9E00C2AC + 9D00C1AB9C00C0AB9C00BFAA9B00000000000000000000000000000000000000 + 00000000000000000000CE888900D7909100CD818200CD7B7C00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000002929290000000000293131000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000E77B42000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000D7D7D70072747400C6C7C7000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000DE733100DE733100DE7331000000 + 00000000000000000000E77B3900E77B3900E77B420000000000000000000000 + 0000E7844A00E7844A00E7844A000000000000000000DCD5C900E1BB9B00E6A5 + 7200EA935100EC883800EF832D00ED8B3900EA975200E7A97200E2BD9B00DCD6 + C900000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000C6C7C6004D504F00328DB300436674000000000000000000000000000000 + 0000ADEFFF0084DEFF0084DEFF000000000000000000084273001894FF000000 + 0000C6A5F700AD7BF700AD7BF70000000000DE6B2900DE6B2900000000000000 + 000000000000DE733100DE733900DE7B3900E77B3900E77B3900000000000000 + 000000000000E7844A00E7844A000000000000000000E7A66B00F0852B008269 + 57007B614F00F0862B00F0862B00F0872B00F0862B00F0862B00F0862B00E7A6 + 6B00000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C6C7 + C6004D504F002B97C60087D8EF006493A5000000000000000000000000000000 + 0000ADEFFF0084DEFF0084DEFF0000000000000000001894FF001894FF000000 + 0000C6A5F700AD7BF700AD7BF70000000000DE6B210000000000DE6B29000000 + 0000000000000000000000000000DE7331000000000000000000000000000000 + 0000E77B420000000000E78442000000000000000000DCD7C900E2BF9B00B9A6 + 9800FFFFFF007259450063483300EE8D3900EB9A5200E7AA7200E2BF9B00DCD6 + C900000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C6C7C6004D50 + 4F002B97C60087D8EF006493A500000000000000000000000000000000000000 + 0000ADEFFF00ADEFFF0031424A0000000000105A7B0021BDFF0021BDFF000000 + 0000C6A5F700C6A5F700C6A5F70000000000000000000000000000000000DE6B + 2900000000000000000000000000DE733100000000000000000000000000DE7B + 3900000000000000000000000000000000000000000000000000000000000000 + 0000B9A69800E5DEDB00B59C8F00715642000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E8E2 + DE00CDBAAD00937C6B0077584400775843009C7D6B00ABADAC002D3442002B97 + C60087D8EF006493A50000000000000000000000000000000000000000003110 + 0000180800001808000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000BD4A0800BD4A + 0800BD4A0800BD4A0000C64A0000C64A0800C64A0000C64A0800C64A0000C64A + 0800C64A08000000000000000000000000000000000000000000000000000000 + 0000B9A69800FFFFFF00E7DCD800B59C8F007055410000000000000000000000 + 0000000000000000000000000000000000000000000000000000DED6D0008668 + 54009D816500BFA27E00D0AD8700B4957300937559006E5440004F80910087D8 + EF006493A50000000000000000000000000000000000846B5A0029080000B57B + 5A00EFE7DE00E7CEC600AD735200290800006B73730052BDFF0052BDFF000000 + 0000EF842100DE631800DE6318000000000000000000B54200007B5AA5001810 + E7006B296B00B54A00008CBD8C0031EFA5007B944200BD4A0800E78C7300F76B + 6300D6522900BD4A000000000000000000000000000000000000000000000000 + 000000000000B9A69800FFFFFF00E7DDD700B59C8F0070554100000000000000 + 00000000000000000000000000000000000000000000F7F5F300896E5C00C1AB + 8B00ECD1AA00EED2AE00ECCFA700E7C79E00D8B28A00A1816200725642006493 + A500000000000000000000000000000000000000000031080000EFDECE00EFE7 + D600FFEFE700F7EFE700FFF7EF00E7D6CE0039100800637B940052BDFF000000 + 0000EF842100DE631800DE6318000000000000000000A54200003129F7000000 + FF002108CE00AD4200004AF7E70018FFBD0031D68400AD420000FFADAD00FF6B + 6B00EF524A00B542000000000000000000000000000000000000000000000000 + 00000000000000000000B9A69800FFFFFF00E6DCD600B59C8F00725844000000 + 00000000000000000000000000000000000000000000C5B7AE00B0998100F2DF + BA00F3E1C100F2E1C100F0DEBB00EDD8B200E7CBA300D3AD8700927357006D66 + 5D000000000000000000000000000000000039292100D6AD9400FFEFD600CEAD + 9C00EFD6C600EFDECE00F7E7D600EFE7D600D6B5A500181810006BD6FF000000 + 0000EF842100EF842100EF84210000000000000000009C3900003129F7000000 + FF002110CE009C3900004AF7E70021FFDE0031DE9400A5420000FFADAD00FF94 + 9400EF635200AD42000000000000000000000000000000000000000000000000 + 0000000000000000000000000000B9A69800FFFFFF00DED0CA00B59C8F007258 + 4400BCCBCE007A848500000000000000000000000000B19E9100CDBCA400F4E8 + CC00F6EED700F7EFDA00F4EAD200F2E2C500ECD5B300E3C39D00B5947200886E + 5E000000000000000000000000000000000000000000F7E7D600F7CEB500AD7B + 6300A5735A00A57B6300B5947B00DEC6AD00FFF7DE0000000000000000000000 + 00000000000000000000000000000000000000000000943900007352A5002121 + FF007352A5009439000084B58C0042FFEF0084B58C009C390000DE847300FFB5 + B500DE8473009C39000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B9A69800FFFFFF00DED0CA00CAB7 + AD001E1B17000504020000000000000000000000000097817100E3DAC400F7F1 + DE00FAF6EB00FBF8EE00F9F3E600F4E9D300EFDCBE00E7CAA500CCA682007254 + 3F000000000000000000000000000000000000000000FFEFDE00EFB59C009C5A + 4200E7A58C00EFAD9400EFBD9C00CEA58C00FFEFD60008080000FFFFFF000000 + 0000FFDEC600FFCEAD00FFCEAD00000000000000000000000000843100008431 + 00008C3100008C3100008C3100008C3900008C3900008C3900008C3900009439 + 0000943900000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B9A69800BBC8C800392E + 2400413831000D090700000000000000000000000000BFB0A600CFC4B600F9F5 + EA00FCFAF300FCFBF400FBF6EE00F6EDDA00F0DEC100ECCFA900C0A27D00795C + 48000000000000000000000000000000000000000000FFE7D600F7B59C00A552 + 3100E7948400E79C8400EFAD8C00D69C8400EFCEB50008080800FFFFFF000000 + 0000FFDEC600FFCEAD00FFCEAD0000000000000000000000000000000000CE52 + 0800000000000000000000000000D65A1000000000000000000000000000D663 + 1800000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000C1CFD1003E3228004138 + 3100484846003A38360041444400909B9D0000000000E1DAD600C1B4A800F0EB + E300FBFAF400FBF9F100FAF5EA00F5EDD700F1DFBF00E6CBA4009E856800B6A7 + 9C000000000000000000000000000000000063525200B57B5A00FFCEBD00CE84 + 6B00F79C7B00F79C8400F7B59400EFB59400945239007B635A00FFFFFF000000 + 0000FFDEC600FFDEC600FFDEC60000000000CE52080000000000CE5208000000 + 0000000000000000000000000000CE5208000000000000000000000000000000 + 0000D65A180000000000D6631800000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007D838200251A12004846 + 4400635D58007E7875005B56540035393A0000000000F3F0EE00C1B3A900D1C6 + BE00F6F4EA00F9F6E600F6F2DE00F4EACE00E5D4B200B59E80007A5E4A00EBE7 + E500000000000000000000000000000000000000000063423900BD8C7300FFDE + C600F7CEB500EFB59C00F7BDA5008C4A31000800000000000000000000000000 + 000000000000000000000000000000000000CE520800CE520800000000000000 + 000000000000CE520800CE520800CE520800CE520800CE520800000000000000 + 000000000000D65A1000D65A1800000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000BBC9CB00A1AC + AD0063636200CDCDCD008E8A8800383A39000000000000000000E7E0DC00C0B2 + A900CABFB300D6CBBB00DED4BB00C3B29800A59076008D735F00D4CAC2000000 + 0000000000000000000000000000000000000000000000000000524242000000 + 00005A3921004229180000000000423931000000000000000000000000000000 + 000000000000000000000000000000000000CE520800CE520800CE5208000000 + 00000000000000000000CE520800CE520800CE52080000000000000000000000 + 0000CE520800D65A1000D65A1000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000909C9E00363A3A00353A3A00909B9D00000000000000000000000000F7F5 + F400E0D9D300C7B9AF00B7A69A00A4918200BAAA9D00F2E7E200000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000CE5208000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFF7F700FFF7 + EF00FFEFE700FFEFE700FFF7E700FFF7EF00FFF7EF00FFF7EF00FFF7EF00FFF7 + EF00FFF7F7000000000000000000000000000000000000000000FFF7F700FFF7 + EF00FFEFE700FFEFE700FFF7E700FFF7EF00FFF7EF00FFF7EF00FFF7EF00FFF7 + EF00FFF7F7000000000000000000000000000000000000000000CEE7FF0094C6 + F7006BB5EF0063ADEF0063ADEF0063ADEF0063ADEF0063ADEF0063ADEF0063AD + EF006BB5EF000000000000000000000000000000000000000000000000000000 + 0000FFF7EF00FFF7E700FFF7EF00FFF7EF00FFF7EF00FFF7F700FFFFF7000000 + 0000000000000000000000000000000000000000000000000000FFF7EF00FFEF + E700FFEFDE00FFEFDE00FFEFE700FFEFE700FFEFE700FFEFE700FFEFE700FFEF + E700FFF7EF000000000000000000000000000000000000000000FFF7EF00FFEF + E700FFEFDE00FFEFDE00FFEFE700FFEFE700FFEFE700FFEFE700FFEFE700FFEF + E700FFF7EF000000000000000000000000000000000000000000D6EFFF009CCE + F7007BBDEF006BB5EF006BB5EF006BB5EF006BB5EF006BB5EF006BB5EF006BB5 + EF007BBDEF000000000000000000000000000000000000000000000000000000 + 0000FFF7E700FFE7D60063848C00A5A5A500FFEFE700FFF7E700FFF7EF000000 + 0000521800005218000052180000521800000000000000000000FFF7EF00FFEF + DE00FFE7DE00F7DED60063737B007B7B7B00FFEFDE00FFEFDE00FFEFDE00FFEF + E700FFEFE7000000000000000000000000000000000000000000FFF7EF00FFEF + DE00AD9C9400000000000000000000000000000000000000000000000000DECE + C600FFEFE7000000000000000000000000000000000000000000DEEFFF00B5D6 + F700638CA5000000000000000000000000000000000000000000000000007BAD + CE0094CEEF000000000000000000000000000000000000000000000000000000 + 0000FFEFE7006BBDD60000B5E7001094B500EFD6C600F7DED600FFEFDE000000 + 0000FFF7EF00FFF7F700FFFFF700521800000000000000000000FFEFE700FFE7 + DE00E7D6CE005A9CB5000094D6000073A5007B949C00FFE7D600FFE7D600FFE7 + D600FFEFDE000000000000000000000000000000000000000000FFEFE700FFE7 + DE00FFE7D6007B736B00BDAD9C00FFE7D600FFE7D600FFE7D60063525200AD9C + 9400FFEFDE000000000000000000000000000000000000000000EFF7FF00D6E7 + F700C6DEEF005A6B73008CA5B500BDDEEF00BDDEEF00BDDEEF0042525A008494 + A500C6DEF7000000000000000000000000008C4221008C4221008C4221000000 + 0000FFE7DE0010DEFF0000DEFF0000BDF70084A5B5006B529400FFE7D6000000 + 0000CE733900C65A2100FFF7EF00521800000000000000000000FFEFE700FFE7 + D60000B5E70000C6FF0000DEFF0000DEFF00007BB500DECEBD00FFE7D6009C84 + AD00FFE7D6000000000000000000000000000000000000000000FFEFE700FFE7 + D600FFDECE00FFDECE0063524A00DEC6B500FFE7CE00FFE7D600EFD6C600BDAD + 9C00FFE7D6000000000000000000000000000000000000000000FFFFFF00F7F7 + F700EFEFEF00EFEFEF005A5A5A00CECED600EFEFEF00EFEFF700DEDEE700ADB5 + B500EFEFF7000000000000000000000000008C422100FFF7EF00FFF7E7000000 + 0000FFE7D600A5EFDE0008EFFF0000EFFF004A73AD0010089400FFE7CE000000 + 0000BDFFFF008C7B7B00FFEFDE00521800000000000000000000FFEFDE00FFE7 + CE0000FFFF0000D6FF0000CEFF0000D6FF0000ADEF006B9C9C008C63AD000000 + 6B00FFE7D6000000000000000000000000000000000000000000FFEFDE00FFE7 + CE00FFDEC600FFDEC600EFCEBD0063524A00EFCEBD00FFDECE00FFDECE00FFDE + CE00FFE7D6000000000000000000000000000000000000000000FFFFFF00FFF7 + EF00FFEFE700FFEFE700EFDED600635A5200EFDED600FFEFE700FFEFE700FFEF + E700FFEFE7000000000000000000000000008C422100FFF7E700D66321000000 + 0000FFDECE00F7D6BD004AD6BD0010848C000000B5001008BD00FFDECE000000 + 0000BDF7FF008C7B7300FFE7D600521800000000000000000000FFEFDE00FFDE + CE00CEEFDE005AF7E70000DEFF0000E7FF0000E7FF008C9CB50000009C000000 + 9400FFDECE000000000000000000000000000000000000000000FFEFDE00FFDE + CE00FFD6C600FFD6BD00FFD6BD007B6B5A00735A5200FFDEC600FFDEC600FFDE + CE00FFDECE000000000000000000000000000000000000000000FFF7F700FFEF + DE00FFE7CE00FFDECE00FFDECE007B6B630073635A00FFDECE00FFE7CE00FFE7 + D600FFE7D6000000000000000000000000008C422100FFEFE700E7A57B000000 + 0000FFDEC600B55A4200941000007B1808000000000000000000000000000000 + 0000BDF7FF008C7B7300FFE7CE00521800000000000000000000FFE7DE00FFDE + C600FFD6BD00B5D6C60000FFFF0000FFFF00217B8C0000008C000000A5000000 + 9400FFE7D6000000000000000000000000000000000000000000FFE7DE00FFDE + C600FFD6BD00FFD6B500CEAD940000000000BDA58C00FFDEC600FFDEC600FFDE + CE00FFE7D6000000000000000000000000000000000000000000FFF7EF00FFDE + CE00FFD6BD00FFCEB500CEA5940000000000BD9C8C00FFD6BD00FFDEC600FFDE + CE00FFE7D6000000000000000000000000008C422100FFE7DE00E7945A000000 + 0000FFDEC600DE5A3900DE4A2900D673520000000000F7A57B0000000000FFD6 + B500C6FFFF009C847B00FFDECE00521800000000000000000000FFE7D600FFD6 + BD00E7A58C00E7A58C00843110008C290000210039000000FF000000FF000000 + B500FFEFDE000000000000000000000000000000000000000000FFE7D600FFD6 + BD00FFCEB500EFC6A500211810007B635A00FFD6B500FFDEC600BDAD9C00FFE7 + DE00FFEFDE000000000000000000000000000000000000000000FFEFE700FFD6 + BD00FFC6A500EFB59400211810007B5A4A00FFC6A500FFCEB500BDAD9C00FFEF + DE00FFEFE7000000000000000000000000008C422100FFE7D600E78442000000 + 0000FFE7D600FFDEC600FFD6C600FFD6C6000000000000000000FF945A00FFF7 + DE00521800005218000052180000521800000000000000000000FFE7D600FFD6 + BD009429100084180000841000008C180000AD6B5A0000000000080818001810 + 5A00000000000000000000000000000000000000000000000000FFE7D600FFD6 + BD00FFCEAD004231290042312900FFCEAD00FFCEB50000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFEFDE00FFCE + AD00F7B58C003929210039292100F7AD8400F7B58C0000000000000000000000 + 0000000000000000000000000000000000008C422100FFDECE00E78439000000 + 00000000000000000000000000000000000000000000D65A1000D6631800E773 + 310052180000F7A57B0052180000000000000000000000000000FFE7CE00FFD6 + BD00F76B4A00EF633900EF633900F7633900E79C7B0000000000E77B4200EF94 + 5A00000000000000000000000000000000000000000000000000FFE7CE00FFD6 + BD00AD8C730042312900735A4A007B6352007B6352000000000063311800EF94 + 5A00000000000000000000000000000000000000000000000000FFE7D600F7C6 + A500A5735200392918006B423100735239007B5242000000000063311800EF94 + 5A00000000000000000000000000000000008C422100FFDEC600E78C4200FFFF + FF00FFFFF7008C4221008C42210052180000FFE7D600FFDEC600FFD6C600FFD6 + C600521800005218000000000000000000000000000000000000FFE7D600FFD6 + BD00FFD6B500FFCEB500FFCEB500FFD6B500FFD6BD0000000000F7A57B000000 + 0000000000000000000000000000000000000000000000000000FFE7D600FFD6 + BD00FFD6B500FFCEB500FFCEB500FFD6B500FFD6BD0000000000F7A57B000000 + 0000000000000000000000000000000000000000000000000000FFE7DE00F7CE + AD00EFB59400EFAD8C00EFAD8C00EFAD8C00EFB5940000000000F7A57B000000 + 0000000000000000000000000000000000008C422100FFDEC600D6631800D673 + 3900E77B39008C422100F7A57B00521800005218000052180000521800005218 + 0000521800000000000000000000000000000000000000000000FFE7DE00FFE7 + D600FFDECE00FFDECE00FFDECE00FFDECE00FFDECE0000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFE7DE00FFE7 + D600FFDECE00FFDECE00FFDECE00FFDECE00FFDECE0000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFF7EF00F7E7 + D600F7DECE00F7D6C600F7D6C600F7D6C600F7DECE0000000000000000000000 + 0000000000000000000000000000000000008C422100FFE7D600FFDEC600FFD6 + C600FFD6C600000000008C422100000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008C4221008C4221008C4221008C42 + 21008C4221008C42210000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000008F796900664B3700674D3800684E3A00694F3B006A50 + 3D006A503D00644A360000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFF7F700FFF7 + EF00FFEFE700FFEFE700FFF7E700FFF7EF00FFF7EF00FFF7EF00FFF7EF00FFF7 + EF00FFF7F7000000000000000000000000000000000000000000000000000000 + 00000000000000000000D6CCC400BBAA9E00AA948500AC978700AC968600AE98 + 8A00998271006A503D0000000000000000000000000000000000FFF7F700FFF7 + EF00FFEFE700FFEFE700FFF7E700FFF7EF00FFF7EF00FFF7EF00FFF7EF00FFF7 + EF00FFF7F7000000000000000000000000000000000000000000FFF7EF00FFF7 + E700FFF7EF00FFF7EF00FFF7EF00FFF7F700FFFFF70000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFF7EF00FFEF + E700FFEFDE00FFEFDE00FFEFE700FFEFE700FFEFE700FFEFE700FFEFE700FFEF + E700FFF7EF000000000000000000000000000000000000000000000000000000 + 0000B19C8D007B655400E5DED800FFFFFF00FCF8F600F5ECE700EEE0D800E9D4 + CA00A690800069503C0000000000000000000000000000000000FFF7EF00FFEF + E700FFEFDE00FFEFDE00FFEFE700FFEFE700FFEFE700FFEFE700FFEFE700FFEF + E700FFF7EF000000000000000000000000000000000000000000FFF7E700D663 + 2100D6733100D6733100D6631000D6632100FFF7EF0000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFF7EF00CE52 + 0800CE520800CE520800CE520800CE520800CE520800CE520800CE520800CE52 + 0800FFEFE7000000000000000000000000000000000000000000000000000000 + 0000C7B7AA00FBF8F700E2DAD400FFFFFF00FEFDFC00F7F2EF00F1E6E000EADA + D100A48E7E00694F3C0000000000000000000000000000000000FFF7EF00CE52 + 0800CE520800CE520800CE520800CE520800CE520800CE520800CE520800CE52 + 0800FFEFE7000000000000000000000000000000000000000000FFEFE700E7A5 + 7B00FFFFE7000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFEFE700CE52 + 0800FFFFFF00FFCE9C00FFFFFF00FFFFFF00FF8C3900FF944A00FFFFF700CE52 + 0800FFEFDE000000000000000000000000000000000000000000BCA99C00C6BB + B200BFADA000FFFFFF00E4DCD600FFFFFF00FFFFFF00FBF9F800F5EDE900EEE1 + D900A48E7E00694F3B0000000000000000000000000000000000FFEFE700CE52 + 0800E7631800EF7B3100FFA57300FFD6B500FFF7EF00C6EFFF0042ADF700CE52 + 0800FFEFDE000000000000000000000000000000000000000000FFE7DE00E794 + 5A00FFF7EF0000000000FFF7EF00FFF7E700FFF7EF00FFF7EF00FFF7EF00FFF7 + F700FFFFF7000000000000000000000000000000000000000000FFEFE700CE52 + 0800FFFFEF00FFBD9400FFFFFF00FFF7E700FF8C4200FFB57B00FFF7DE00CE52 + 0800FFE7D6000000000000000000000000000000000000000000C1AEA100F7F3 + F000C9B8AB00FFFFFF00E7DED800FFFFFF00FFFFFF00FEFEFE00F9F5F300F5EB + E600A48E7E00684E3A0000000000000000000000000000000000FFEFE700CE52 + 0800E7631800EF7B3100FFA57300FFD6B500FFF7EF00C6EFFF0042ADF700CE52 + 0800FFE7D6000000000000000000000000000000000000000000FFE7D600E784 + 4200FFFFFF0000000000FFF7E700D6632100D6733100D6733100D6631000D663 + 2100FFF7EF000000000000000000000000000000000000000000FFEFDE00CE52 + 0800FFDEAD00FFF7E700FFF7F700FFC6AD00FF945200FFFFFF00FFB57B00CE52 + 0800FFE7D6000000000000000000000000000000000000000000BFAC9E00EFEA + E600CCBCB000FFFFFF00E9E0DA00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F1E8 + E200A99383006A503C0000000000000000000000000000000000FFEFDE00CE52 + 0800E7631800EF7B3100FFA57300FFD6B500FFF7EF00C6EFFF0042ADF700CE52 + 0800FFE7D6000000000000000000000000000000000000000000FFDECE00E784 + 3900FFFFF70000000000FFEFE700E7A57B00FFFFE700FFF7E700FFAD6B00E7AD + 8400FFEFDE000000000000000000000000000000000000000000FFEFDE00CE52 + 0800FFC68C00FFFFFF00FFEFEF00FFBD9400FF9C5200FFFFFF00FFC6A500CE52 + 0800FFDECE000000000000000000000000000000000000000000C3B0A300EFEA + E700D1C1B400FFFFFF00EBE3DC00FFFFFF00FFFFFF00FFFFFF00EBE5E0009179 + 6700806754006146320000000000000000000000000000000000FFEFDE00CE52 + 0800E7631800EF7B3100FFA57300FFD6B500FFF7EF00C6EFFF0042ADF700CE52 + 0800FFDECE000000000000000000000000000000000000000000FFDEC600E78C + 4200FFFFFF0000000000FFE7DE00E7945A00FFF7EF00FFCEAD00FFCEAD00E78C + 4A00FFE7D6000000000000000000000000000000000000000000FFE7DE00CE52 + 0800FFBD8400FFFFFF00FFEFEF00FFD6C600FF7B2100FFF7E700FFFFFF00CE52 + 0800FFE7D6000000000000000000000000000000000000000000C8B6A700F1EC + E900D6C4B900FFFFFF00EEE6DF00FFFFFF00FFFFFF00FFFFFF00CFC1B7009D87 + 770072594700AD9C8F0000000000000000000000000000000000FFE7DE00CE52 + 0800E7631800EF7B3100FFA57300FFD6B500FFF7EF00C6EFFF0042ADF700CE52 + 0800FFE7D6000000000000000000000000000000000000000000FFDEC600D663 + 1800D673390000000000FFE7D600E7844200FFFFFF00FFB59400FFE7CE00E78C + 5200FFE7CE000000000000000000000000000000000000000000FFE7D600CE52 + 0800FFBD7300FFFFFF00FFDECE00FFFFFF00FF6B1000FFCE8C00FFFFFF00CE52 + 0800FFEFDE000000000000000000000000000000000000000000CEBAAD00F2ED + EA00DACABC00FFFFFF00ECE2DB00FBF8F600FBF8F600FAF8F600D7C8BF008E76 + 6400D7CAC0000000000000000000000000000000000000000000FFE7D600CE52 + 0800E7631800EF7B3900FFAD7300FFD6B500FFF7EF00C6EFFF0042ADF700CE52 + 0800FFEFDE000000000000000000000000000000000000000000FFE7D600FFDE + C600FFD6C60000000000FFDECE00E7843900FFFFF700FFC69C00FFD6A500F7B5 + 8C00FFDECE000000000000000000000000000000000000000000FFE7D600CE52 + 0800FFDE9C00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 + 0000000000000000000000000000000000000000000000000000D2BFB100F3EE + EB00DFCEC100FFFFFF00DECCBF00E0CEC100DFCDC000D3BFB100C6B0A100D0C0 + B500000000000000000000000000000000000000000000000000FFE7D600CE52 + 0800EF7B3100FF945200FFBD8C00FFE7C600FFFFFF0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000FFDEC600E78C4200FFFFFF00FFFFF700000000000000 + 0000000000000000000000000000000000000000000000000000FFE7CE00CE52 + 0800CE520800CE520800CE520800CE520800CE52080000000000E77B4200EF94 + 5A00000000000000000000000000000000000000000000000000D8C4B600F5F0 + ED00DBC7B800EADFD600EADFD600E9DDD500E3D5CB00AD978700CCBFB4000000 + 0000000000000000000000000000000000000000000000000000FFE7CE00CE52 + 0800CE520800CE520800CE520800CE520800CE52080000000000E77B4200EF94 + 5A00000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000FFDEC600D6631800D6733900E77B390000000000F7A5 + 7B00000000000000000000000000000000000000000000000000FFE7D600FFD6 + BD00FFD6B500FFCEB500FFCEB500FFD6B500FFD6BD0000000000F7A57B000000 + 0000000000000000000000000000000000000000000000000000DBC8B900F6F1 + ED00FFFFFF00FFFFFF00FFFFFF00C7B6A900907A6A00D6C9C000000000000000 + 0000000000000000000000000000000000000000000000000000FFE7D600FFD6 + BD00FFD6B500FFCEB500FFCEB500FFD6B500FFD6BD0000000000F7A57B000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000FFE7D600FFDEC600FFD6C600FFD6C600000000000000 + 0000000000000000000000000000000000000000000000000000FFE7DE00FFE7 + D600FFDECE00FFDECE00FFDECE00FFDECE00FFDECE0000000000000000000000 + 0000000000000000000000000000000000000000000000000000D9C3B300DBC7 + B800DCC8BA00DBC8B900D6C2B400CAB4A500D3C6BB0000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFE7DE00FFE7 + D600FFDECE00FFDECE00FFDECE00FFDECE00FFDECE0000000000000000000000 + 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 + 000000000000000000000000000000000000000000004C4846004B4745004B47 + 44004B4743004B4742004B4641004B4540004A443F004A443E004A433D004A42 + 3B004A423B004A413A004A413A00564C450000000000000000003E3937004840 + 3B0039322F0028231F001B17140000000000000000003E39370048403B003932 + 2F0028231F001B1714000000000000000000B7A2930060463200634935006349 + 350063493500634935006349350063493500634935006349350063493500684E + 3A000000000000000000000000000000000000000000000000006E6D6E004444 + 4400787878000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B8A89D00FFFFFF00FFFFFF00FFFF + FC00FFFBF800FFF7F200FFF3EC00FFEFE500FEEBDF00FCE6D900FCE2D200FBDE + CC00FADAC600F9D7C100EACBB5002E282200000000000000000089766C00FCF7 + F300FBECDD00E5D7C800D3C5B600181412000000000089766C00FCF7F300FBEC + DD00E5D7C800D3C5B6001814120000000000BDA89900FCFEFC00E7E6E400E7E2 + DC00E6DCD400E5D6CB00E4CFC100E3CAB800E3C5B100E2C2AC00C7AA9800684E + 3A0000000000000000000000000000000000000000000000000099989900C8C7 + C800111111007A7A7A0000000000E1E1E1000000000000000000000000000000 + 000000000000000000000000000000000000B8A89E00FFFFFF00FFFFFE00FFFD + FB00FEFAF800FEF7F200FCF3EC00FBEFE700FBEBE000FAE6DA00F9E2D400F8DE + CD00F7DAC700F6D6C200EACBB500312B2600000000000000000089807900FCF7 + F300E2723900C8622F00E5D7C800231E1B000000000089807900FCF7F300E272 + 3900C8622F00E5D7C800231E1B0000000000C6B0A100FCFEFC00D8C4B900D6C0 + B500D3BCAF00FAEFE600CFB3A500CCAF9F00CCAF9F00F6DBC800C7AA9800684E + 3A00000000000000000000000000000000000000000000000000000000000000 + 0000848484000E0E0E00000000003333330034333400979697001C1C1C000C0B + 0C0024222200000000000000000000000000B8A89E00FFFFFF00FFFFFF00FFFE + FE00FFFCFA00FEF8F600FDF6F000FCF2EB00FCEEE500FAE9DF00FAE5D800F8E1 + D100F8DDCB00F7D8C600EACDB900312B2700000000000000000089807C00FEFB + FA00F5825000CD653100FBECDD00322C29000000000089807C00FEFBFA00F582 + 5000CD653100FBECDD00322C290000000000CCB6A700FCFEFC00FCFEFC00FCFE + FC00FBFAF700FBF5EF0075716E005754510000000000D2C2B500CBB2A100684E + 3A00000000000000000000000000000000000000000000000000000000000000 + 0000B6B6B600020102007F7F7F0000000000000000005F5E5F00020102005454 + 5400E4E4E300000000000000000000000000B8A89E00FFFFFF00FFFFFF00FFFF + FF00FFFEFD00FEFBF900FDF8F500FDF4EF00FCF0E900FBECE300FAE8DC00FAE4 + D600F9DFD000F8DCC900EACEBD00312B2700000000000000000088807C00FFFF + FF00FDFBFA00FCF7F300FCF7F3003F3835000000000088807C00FFFFFF00FDFB + FA00FCF7F300FCF7F3003F38350000000000CCB6A700FCFEFC00DBCAC000DAC8 + BD00D8C4B900FBFAF700A39D9800FDFEFE005193A9000E121600B8B1A8007860 + 4D00000000000000000000000000000000000000000000000000000000000000 + 0000EEEEEE00504E50004141410000000000E6E5E50094939400242324001616 + 160000000000000000000000000000000000B8A89E00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFDFC00FEFAF800FEF7F300FCF2ED00FCEFE700FBEBE100FAE7 + DA00F9E2D400F8DECD00EAD1C000322B27000000000000000000887F7A008980 + 7C0089807C008980790089766C0035312E0000000000887F7A0089807C008980 + 7C008980790089766C0035312E0000000000CCB6A700FCFEFC00FCFEFC00FCFE + FC00FCFEFC00FCFEFC00A39D980088B7C70074CEE200499AB2000E1216007C72 + 6600000000000000000000000000000000000000000000000000000000000000 + 00000000000078787800171717000000000093908F009A999900A8A8A8009898 + 9800232323003D3D3D000000000000000000B8A89E00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFEFF00FEFCFA00FEF9F500FDF6F100FCF2EB00FCEEE500FAEA + DF00FAE5D800F9E0D200EAD4C300322B27000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000CCB6A700FCFEFC00DBCAC000DBCA + C000DBCAC000FCFEFC00C1B9B4004D9CB3008CE0EE0062BFD700499AB2000E12 + 1600CEDBDF000000000000000000000000000000000000000000000000000000 + 0000000000008383830002010200F2F2F20000000000EDEDED00DADADA000000 + 0000E9E9E900CDCDCD000000000000000000B8A89E00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFEFD00FEFAF900FEF8F500FDF4EF00FCF1E900FBEC + E300FAE8DD00F9E4D600EAD6C800322C270000000000000000003E3937004840 + 3B0039322F0028231F001B17140000000000000000003E39370048403B003932 + 2F0028231F001B1714000000000000000000CCB6A700FCFEFC00FCFEFC00FCFE + FC00FCFEFC00FCFEFC00FBF8F300D5CEC80057A0B5008CE0EE0062BFD700499A + B2000E121600CEDBDF0000000000000000000000000000000000000000000000 + 000000000000A9A9A900181718007F7F7F000000000000000000000000000000 + 000000000000000000000000000000000000B8A89E00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFDFC00FEFAF800FDF7F300FCF3ED00FCEF + E700FAEBE100FAE7DB00EAD9CB00322C2700000000000000000089766C00FCF7 + F300FBECDD00E5D7C800D3C5B600181412000000000089766C00FCF7F300FBEC + DD00E5D7C800D3C5B6001814120000000000EBAC8D00EAAA8C00EAA98900E9A2 + 7E00E8997100E68F6300E5875800E6926500CDA9950065A6B7008CE0EE0062BF + D700499AB2000E121600D7DFE200000000000000000000000000000000000000 + 0000A3A2A100B1AFAE00817F7E000E0B0A00110F0E0000000000000000000000 + 000000000000000000000000000000000000AB998E00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFEFE00FFFBFA00FEF8F500FDF5 + EF00FCF1E800FBECE200EADFD400322C2700000000000000000089807900FCF7 + F300E2723900C8622F00E5D7C800231E1B000000000089807900FCF7F300E272 + 3900C8622F00E5D7C800231E1B0000000000EBAC8D00FFC3A200FEBF9D00FCBB + 9800FBB69200FAB08B00F8AB8400F8A67C00F3A68000D2B09E0073ACB9008CE0 + EE006CC4D9007D86860035359000BFC2D9000000000000000000000000000000 + 000000000000000000009D9C9D002A292A000000000000000000000000000000 + 000000000000000000000000000000000000AC9A8E00F7F0EC00FCF6F400FCF6 + F300FBF5F200FAF4F100FAF4F000FAF2EE00FAF2EE00FAF0EA00F9EDE600F9EA + E100F8E6DC00F8E3D600E6D6C90035302A00000000000000000089807C00FEFB + FA00F5825000CD653100FBECDD00322C29000000000089807C00FEFBFA00F582 + 5000CD653100FBECDD00322C290000000000EBAC8D00EAAA8B00EAAA8B00EAA8 + 8900E9A28100E89C7700E7946B00E68C6000E5865500E68D5F00CA997F007DB0 + BB00CAB8AC007385D1005E6CAD00353590000000000000000000000000000000 + 00000000000000000000C1C1C10064636400E2E2E200373535005B5959000000 + 000000000000000000000000000000000000CEA58F00F0B19200F4B29100E89F + 7A00E1906800DD885D00DC875B00DA835700D87F5200D77C4E00D6794B00D578 + 4900D4774700D4764600CA70410047312400000000000000000088807C00FFFF + FF00FDFBFA00FCF7F300FCF7F3003F3835000000000088807C00FFFFFF00FDFB + FA00FCF7F300FCF7F3003F383500000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DCE5 + E8005E6CAD00708FDF005E76D0005E6CAD000000000000000000000000000000 + 0000000000000000000000000000B1B0B1007471710016131300494848000000 + 000000000000000000000000000000000000D8AA9200FCC0A000FCBD9B00F9B6 + 9400F5B08B00F1A98500EEA47F00ECA07900EB9C7200E7956B00E48F6500E18B + 5E00DF865900DD825400CE774C0038281E000000000000000000887F7A008980 + 7C0089807C008980790089766C0035312E0000000000887F7A0089807C008980 + 7C008980790089766C0035312E00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000D4DAEE005E6CAD005E6CAD00E2E6F2000000000000000000000000000000 + 000000000000000000000000000000000000EEEEEE00D5D5D500000000000000 + 000000000000000000000000000000000000CEAB9A00DCAE9800D5A58E00D3A0 + 8600CE9B8100C88B6D00CA856400C57F5D00B6755600AD705200A76B4E00A76B + 4E00A76B4E00A76B4E00A66A4D00795847000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000091877D00525050005954510058524D0058504900584E + 4700574C4400564A4000584C42004B413A000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000007C7573004E4B4B00544F4D00544F + 4D00544F4D0056514D0053504C00524F4B00524F4C00524F4B00514E4B00544E + 4600000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000AC9A8D00FFFFFF00FDFFFF00FFFDF700FFF8ED00FEF1 + E000FDEAD500FCE5CC00FFEACF00574B410000000000A3887700634935006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 3500634935006349350000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000D9CFC800FFFFFF00FBFDFF00FBFD + FF00FFFFF600FFFFF600FFFFF600FFF9EC00FFF0E100FFEAD500FFEAD200544E + 4600000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000AC989000FFFFFE00FFFFFF00FEF8F400FFF2ED00FCEB + E300FCE6D900FCE0CE00FFE2CF00574B410000000000AD938300FEFBFA00FDF9 + F600FCF5F200FBF2ED00FAEEE800F9E9E200F7E5DC00F6E1D700F5DDD100F3D8 + CB00F3D4C600634935000000000000000000000000000000000000000000E39A + 7500B6623900B6623900B05C3300A7532A009D482000923E160089340D00822D + 0600812C0500000000000000000000000000D2C8C100FFFFFF00C4AFA200C4AF + A200FFFBF900C4AFA200C4AFA200C4AFA200C4AFA200C4AFA200FDDECB00544E + 4600000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000AA9A8D00FFFFFF00FFFFFF00FFFBF900FEF6F200FCF1 + EC00FCECE200F9E3D600FEE7D500574B410000000000B4998A00FEFDFC00FDFA + F900FCF7F500FCF4F100FBF0EC00F9ECE600F8E8E100F6E4DB00F5DFD500F5DB + D000F3D7CA00634935000000000000000000000000000000000000000000E39A + 7500E58C5E00E2845500E17E4C00DF774200DE713B00DC6B3400FFFFFF00DA62 + 2700812C0500000000000000000000000000D2C8C100FFFFFF00FBFDFF00FBFD + FF00FFFEFC00FDFAF800FBF4EF00FBEEE600FAE9DE00F8E2D200FFE2D000544E + 4600000000000000000000000000000000000000000000000000000000009187 + 7D005250500059545100AB998C00FFFEFF00FFFFFF00FFFEFD00FFF9F800FCF3 + F000FCEDE600FDE8DD00FFEDDF00574B410000000000BAA09300FFFFFE00FFFC + FB00FDF9F700FCF6F400FCF3EF00FAEFEA00F9EBE400F7E7DF00F7E2D900F5DE + D300F4DACD00634935000000000000000000000000000000000000000000E397 + 7000E7946B00E58D6100E3865700D0AE9C00DF784500DE733C00FFFFFF00DA68 + 2E00812C0500000000000000000000000000D3C9C200FFFFFF00C4AFA200C4AF + A200FFFFFE00C4AFA200C4AFA200C4AFA200C4AFA200C4AFA200FFE5D600544E + 460000000000000000000000000000000000000000000000000000000000AC9A + 8D00FFFFFF00FDFFFF00AB9B8E00FEFEFE00FFFEFF00FFFFFF00FFFFFF00FFFF + FE00FFFEF900FCF9F000FEFDF100574B410000000000EAAA8B00EAAA8B00E9A5 + 8400E99F7A00E7976E00E68E6200E5865600E37D4A00E3764000E2723900E272 + 3900E2723900E27239000000000000000000000000000000000000000000E79B + 7400EA9E7700E7966C00DDC4B900FFFFFF00E2805000E07A4600FFFFFF00DD6E + 360085300900000000000000000000000000D1C7C000FFFFFF00FBFDFF00FBFD + FF00FFFFFF00FEFEFD00FEFBF800FDF6F200FCF0E800FCF0E800FFE9DC00544E + 460000000000000000000000000000000000000000000000000000000000AC98 + 9000FFFFFE00FFFFFF00AA998F00FBAC8500ED916500E2825600DF7D4F00DB74 + 4600D96E4000D4693800D9693600574B410000000000EAAA8B00FFFFFE00FFC2 + A200FCB99600FBB59000FAB08B00F9AB8400F8A77D00F6A27700F59D7100F599 + 6A00F3956500E27239000000000000000000000000000000000000000000EA9E + 7800ECA68300E9D4CA00FFFFFF00FFFFFF00E4895B00E2825100FFFFFF00DF75 + 40008B360F00000000000000000000000000D1C8C100FFFFFF00FBFDFF00FBFD + FF00FFFFFF00FFFFFF00FEFEFC00B0ADAC00415C7200E3D9D300FFEDE300544E + 460000000000000000000000000000000000000000000000000000000000AA9A + 8D00FFFFFF00FFFFFF00C59F9400AA9B8C00B1907900C1795A00AE704F00AA63 + 470099583E0098583B009A5A3C007A4E3B0000000000EAAA8B00EAAA8B00EAAA + 8B00EAA68600E9A17F00E89B7600E7946C00E68E6200E5875800E4814E00E47B + 4600E3763E00E27239000000000000000000000000000000000000000000EFA3 + 7D00F3E2D900FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00ECD3C600E17D + 4A00923E1600000000000000000000000000D1C8C100FFFFFF00E2E9E9005E75 + 8400DFE4E500FFFFFF00C2CACE004A6170002EA9D6000B101B005D5C6000A49D + 9600000000000000000093B699001C66290091877D005250500059545100AB99 + 8C00FFFEFF00FFFFFF00FFFEFD00FFF9F800FCF3F000FCEDE600FDE8DD00FFED + DF00574B410000000000000000000000000000000000A3887700634935006349 + 3500634935006349350063493500634935006349350063493500634935006349 + 350063493500634935000000000000000000000000000000000000000000F3A8 + 8100F2B89C00F8E9E100FFFFFF00FFFFFF00E99B7400E7946A00E58D6000E385 + 56009A461E00000000000000000000000000DF9D7D00F1CAB7008FA4AC0086D3 + E5004B617000A79289004A61700061C1DE00574D59001FD0FF00152733001007 + 0A0002212E004F56650059785B00188C3200AC9A8D00FFFFFF00FDFFFF00AB9B + 8E00FEFEFE00FFFEFF00FFFFFF00FFFFFF00FFFFFE00FFFEF900FCF9F000FEFD + F100574B410000000000000000000000000000000000AD938300FEFBFA00FDF9 + F600FCF5F200FBF2ED00FAEEE800F9E9E200F7E5DC00F6E1D700F5DDD100F3D8 + CB00F3D4C600634935000000000000000000000000000000000000000000F6AD + 8600F4C1A800F2BA9E00FAE4DA00FFFFFF00ECA48000E99D7500E7956C00E68D + 6200A24E2500000000000000000000000000DF9D7D00FFC5A400E5C9B9008FA4 + AC0083E1F6004B6170007ACDE2005260670068EDFF00413D500032B2DF001D99 + C8001593C40014628E004066510029973F00AC989000FFFFFE00FFFFFF00AA99 + 8F00FBAC8500ED916500E2825600DF7D4F00DB744600D96E4000D4693800D969 + 3600574B410000000000000000000000000000000000B4998A00FEFDFC00FDFA + F900FCF7F500FCF4F100FBF0EC00F9ECE600F8E8E100F6E4DB00F5DFD500F5DB + D000F3D7CA00634935000000000000000000000000000000000000000000FAB0 + 8A00F6C9B200F4C2A900F2BCA000F9E0D300EEAD8D00ECA58300EA9E7800E897 + 6E00AA552D00000000000000000000000000DF9D7D00DF9D7D00DF9D7D00DABA + AA008FA4AC007FE3F9005384950068EDFF00303A4F0069DBF60058D2F30040C3 + ED0031BBEA0011A8EC0050908C00329E4100AA9A8D00FFFFFF00FFFFFF00C59F + 9400AA9B8C00B1907900C1795A00AE704F00AA63470099583E0098583B009A5A + 3C007A4E3B0000000000000000000000000000000000BAA09300FFFFFE00FFFC + FB00FDF9F700FCF6F400FCF3EF00FAEFEA00F9EBE400F7E7DF00F7E2D900F5DE + D300F4DACD00634935000000000000000000000000000000000000000000FDB3 + 8D00FDB38D00FDB38D00F6AD8600F3A88100EFA37D00EA9E7800E79B7400E397 + 7000E39A75000000000000000000000000000000000000000000000000000000 + 000000000000576B800068EDFF005898AE006EEBFF0072E1F9006ADDF70056CF + F2004BC7ED0022BAFA005FA2A60041AC5300AB998C00FFFEFF00FFFFFF00FFFE + FD00FFF9F800FCF3F000FCEDE600FDE8DD00FFEDDF00574B4100000000000000 + 00000000000000000000000000000000000000000000EAAA8B00EAAA8B00E9A5 + 8400E99F7A00E7976E00E68E6200E5865600E37D4A00E3764000E2723900E272 + 3900E2723900E272390000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000C2C8D000B0EBFA005B6D7F006EEBFF006EEBFF006EEBFF0072E2FA0067D7 + F40054BDDC0051728B00699C890085CC8500AB9B8E00FEFEFE00FFFEFF00FFFF + FF00FFFFFF00FFFFFE00FFFEF900FCF9F000FEFDF100574B4100000000000000 + 00000000000000000000000000000000000000000000EAAA8B00FFFFFE00FFC2 + A200FCB99600FBB59000FAB08B00F9AB8400F8A77D00F6A27700F59D7100F599 + 6A00F3956500E272390000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000A3ACB80095B8C400D4D9DD0081A6B5008097A3008096A0007A8F99007385 + 93005C718000BFC8CD009AD3A40070C17D00AA998F00FBAC8500ED916500E282 + 5600DF7D4F00DB744600D96E4000D4693800D9693600574B4100000000000000 + 00000000000000000000000000000000000000000000EAAA8B00EAAA8B00EAAA + 8B00EAA68600E9A17F00E89B7600E7946C00E68E6200E5875800E4814E00E47B + 4600E3763E00E272390000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C59F9400AA9B8C00B1907900C179 + 5A00AE704F00AA63470099583E0098583B009A5A3C007A4E3B00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000081685500262F3800262F3800262F3800262F3800262F + 3800262F3800262F3800262F3800262F38000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000BCCCD200647E8E004F5E6F004552 + 610037414D00262F380089715E00E8DCD300B7A29300B7A29300B7A29300B7A2 + 9300B7A29300B7A29300B7A29300262F38000000000000000000A1A09F005656 + 550091919100B6B6B60000000000000000000000000000000000000000000000 + 0000BCBCBC00B8B8B80000000000000000000000000000000000FFFFFF00FFEF + DE00FFE7D600FFD6B500FFCEAD00FFFFFF00FFFFFF00FFDECE00FF9C6B00FF94 + 5A00FFC6A500FFEFE7000000000000000000FEFEFE00FEFEFE00FEFEFE00FEFE + FE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFE + FE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00717F8B0022B6EC00008FCD00008F + CD00008FCD00008FCD0091796600EFE6E100E8DBD300E0D0C600DAC6BC00D4BF + B200CFB9AB00CCB6A800B7A29300262F380000000000BBBBBB00676666001713 + 12004D4B4A00A5A4A400BEBEBE0000000000000000000000000000000000BDBD + BD00727070009A9A9A00BEBEBE00000000000000000000000000FFF7EF00FFDE + C600FFCEAD00FFB58C00FFF7EF00FFF7EF00FFFFF700FF8C4A00FFA56B00FF8C + 4A00FFDECE00FFC6AD000000000000000000FEFEFE003E36F500332CF2002B22 + EE00241CED00FEFEFE00C100A100BF009900BF009400BE008F00FEFEFE00F3C8 + 2E00F2C51B00F3C20B00F3BF0000FEFEFE007584900068C8EA0010B5F00008AC + EB0003A4E3000096D4009A826F00F7F1EF00C3AE9E00C3AE9E00BDA89800B7A2 + 9300D4BFB200B7A29300B7A29300262F3800000000000000000090908F002018 + 16002B262500706F6E00B8B8B800000000000000000000000000BEBEBE00AAAA + A90038373700AAAAAA00BEBEBE00000000000000000000000000FFEFE700FFD6 + C600FFB58400FFDECE00FFF7EF00FFFFFF00FFCEA500FF8C4A00FF945200FFB5 + 8C00FFE7DE00FFB58C000000000000000000FEFEFE004E47FA00443CF7003830 + F3002E26F000FEFEFE00C100AB00C100A300BF009C00BF009500FEFEFE00F2CE + 4B00F3CA3800F3C62500F3C21300FEFEFE007989940074D0ED0028BDF10011B5 + F00007ABEA00009DDC00A28A7800FDFBFA00F7F2EE00EFE6E100E8DBD300E0D0 + C600705A4A0061524600504842003F3D3E000000000000000000BBBBBB005E5A + 590029242100403C3B00A8A7A7000000000000000000BABABA00B6B5B5004D4B + 490064626000BEBEBE0000000000000000000000000000000000FFF7E700FFCE + AD00FFBD9400FFF7F700FFEFDE00FFFFFF00FF945A00FF9C6B00FF9C6300FFEF + DE00FFBD9C00FFC6A5000000000000000000FEFEFE005A53FE00524CFB004942 + F8003E36F500FEFEFE00C300B600C200AE00C100A600C0009E00FEFEFE00F2D2 + 6100F2CF5400F2CC4100F3C82E00FEFEFE007E8E9A0083D9F00046C9F2002DBF + F20016B7F10000A0E200A9928000FFFFFF00C3AE9E00C3AE9E00BDA89900E8DC + D3007A604D00D4C5BA006152470000000000000000000000000000000000B2B1 + B10043413E0025211E0053505000B4B4B400B8B8B800B8B8B800646260003936 + 3600AFAEAE000000000000000000000000000000000000000000FFF7EF00FFBD + 9400FFD6BD00FFF7F700FFEFE700FFFFF700FF7B3100FFAD7300FFD6BD00FFE7 + CE00FFAD7B00FFC694000000000000000000FEFEFE005D56FF005D56FF00574F + FD004E46FA00FEFEFE00C400BF00C300B800C200B000C200A900FEFEFE00F2D3 + 6600F2D36600F2D15B00F2CD4B00FEFEFE0082949E0091E2F30066D5F4004CCB + F30032C2F20015AFE900B0998800FFFFFF00FFFFFF00FCFBF900F7F1EF00EFE7 + E100816856007A604D0000000000000000000000000000000000000000000000 + 0000AFAEAE0043413F002D2827005B5A59009D9D9C00504D4C00333130008281 + 8000000000000000000000000000000000000000000000000000FFF7E700FFB5 + 8C00FFEFE700FFEFE700FFEFE700FFF7EF00FF7B2900FFB57B00FFEFE700FFDE + C600F7CEAD00EFAD8C000000000000000000FEFEFE005D56FF005D56FF005D56 + FF005A54FE00FEFEFE00C500C500C400C000C400BA00C300B300FEFEFE00F2D3 + 6600F2D36600F2D36600F2D26100FEFEFE008699A2009FEAF60083E1F6006BD8 + F50053CEF4000EB3F000B6A08E00B0998800A9928000A28A78009A8270009179 + 670089715E000000000000000000000000000000000000000000000000000000 + 000000000000AEAEAE0046424100312E2D0034302F003835340042403F000000 + 0000000000000000000000000000000000000000000000000000FFEFDE00FFAD + 7B00FFF7F700FFEFDE00FFE7DE00FFF7F700FF732100FFAD7300FFDECE00FFEF + DE00FFBD9C00EFDED6000000000000000000FEFEFE00FEFEFE00FEFEFE00FEFE + FE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFE + FE00FEFEFE00FEFEFE00FEFEFE00FEFEFE008A9EA600A9F0F80099EAF80088E3 + F5006DD1EA0013A1D40013A1D40012A0D3000D97CF000791CA00008FCD00008F + CD00303944000000000000000000000000000000000000000000000000000000 + 000000000000000000009C9B9B00373231003D3A390044414000B5B4B4000000 + 0000000000000000000000000000000000000000000000000000FFE7D600FFAD + 7B00FFF7F700FFEFE700FFEFE700FFFFFF00FF7B3900FFA55A00FFCEA500FFFF + FF00FFF7F700FFE7DE000000000000000000FEFEFE0000B0FF0000AAFF0000A5 + FF0000A2FF00FEFEFE0000B7340000B1310000AB2E0000A52C00FEFEFE00CE28 + 2F00C21F2600B6161D00AB0D1500FEFEFE008DA1AA00AAF1F900A7F0F9005E7D + 8A0058737F00566D7A00526977004F6673004C617000445A6800236F9000008F + CD003E4A58000000000000000000000000000000000000000000000000000000 + 0000BFBFBF00ABABAB00595756003B3736003A3736003A3B39005B595600BABA + BA00000000000000000000000000000000000000000000000000FFE7D600FFA5 + 7300FFF7EF00FFEFDE00FFDED600FFFFFF00FFBD9C00FF7B2100FFCE9C00FFE7 + DE00FFE7DE00FFC6B5000000000000000000FEFEFE0000B8FF0000B2FF0000AC + FF0000A7FF00FEFEFE0000BF380000B9350000B2320000AD3000FEFEFE00DD34 + 3B00D12A3300C5212800B9171F00FEFEFE008FA4AC00AAF1F900A8F1F9005D86 + 96008CC6CF0093E4F0007AD5E70062C6DE004F9AB2003E5A67001C7DA500008F + CD004B596900000000000000000000000000000000000000000000000000BDBD + BD008988880044424100423E3E0075757400A8A7A700757272003C3C3D006F6D + 6B00B7B7B6000000000000000000000000000000000000000000FFEFDE00FF9C + 6300FFEFE700FFEFE700FFDECE00FFEFEF00FFFFFF00FF945A00FFB57300F7CE + B500FFDED600FFF7F7000000000000000000FEFEFE0000C0FF0000BAFF0000B4 + FF0000AEFF00FEFEFE0000C63C0000C0390000BB360000B53300FEFEFE00EB3F + 4600E0363E00D42D3400C7232B00FEFEFE008FA4AC00ABF0F700AAF1F900A6EF + F7007397A200A1ECF500667D8A0078C5D6004C6C7C00346178005FC3E80022B6 + EC004E5E6F0000000000000000000000000000000000B3B3B300A4A4A4006765 + 64003F3C3A00403F3E006E707100BABBBB0000000000BBBBBB00717170004341 + 3F0075747400B9B9B80000000000000000000000000000000000FFEFDE00FF9C + 6300FFDEC600FFF7EF00FFE7D600FFDED600FFFFFF00FFD6C600FFD6C600F7D6 + CE00F7B59400FFEFDE000000000000000000FEFEFE0000C7FF0000C2FF0000BD + FF0000B6FF00FEFEFE0000CD3E0000C83B0000C2390000BD3600FEFEFE00F748 + 5000ED404800E3394000D7303700FEFEFE00B7CACF008FA4AC008FA4AC008FA4 + AC005B8D9F00A5E8EF009BE8F4008CD5E2004666760073858F007A8A95007585 + 9100BDCED300000000000000000000000000BEBEBE00908F8F00666363003D39 + 37004541400087868600BEBEBE00000000000000000000000000BBBBBB009F9E + 9D004D4D4E007271710000000000000000000000000000000000FFFFFF00FFC6 + 9400FFCEAD00FFFFFF00FFFFF700FFF7EF00FFFFFF00FFFFFF00FFDECE00FFDE + C600FFBDA500FFEFE7000000000000000000FEFEFE0000CCFF0000C8FF0000C4 + FF0000BFFF00FEFEFE0000D1400000CD3E0000CA3C0000C43A00FEFEFE00FF4E + 5600F9495100F0434A00E63B4200FEFEFE000000000000000000000000000000 + 00000000000086B3C30082ADBD00799FB000BCCED30000000000000000000000 + 000000000000000000000000000000000000BEBEBE008E8D8D00444141004747 + 46009A9A9A00BEBEBE000000000000000000000000000000000000000000BDBD + BD00B1B1B1008B8B8B0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FEFEFE00FEFEFE00FEFEFE00FEFE + FE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFE + FE00FEFEFE00FEFEFE00FEFEFE00FEFEFE000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C0C0C000A9A9A90068696700A1A1 + A000BFBFBF000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000BBA1 + 9400975F450063423200A28D8200000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FBD7C500F8D5C3000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000F8D5C300FBD7C500000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CD86 + 6300AB623F008A50330062453700BDBDBE00B99F9200664334005E3F3000A891 + 8600000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000BA6E4700AA542900AA542900A25027009B4C25009648 + 23008F4622008A43210086412000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000F8DCCF00F38A5700E195 + 7100000000000000000000000000000000000000000000000000000000000000 + 0000E1957100F38A5700F8DCCF00000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DD83 + 5500C3B2AA00B89C8E00854E3300C0C0C000C5826100AA623E00633C29002F25 + 2300000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C1795500FDF9F600CEB09C00CCAF9B00CAAD9A00C7AC + 9900C6AB9800C4A9970089432100000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000EECBBA00F085 + 5000DA865E00000000000000000000000000000000000000000000000000DA86 + 5E00F0855000EECBBA0000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E185 + 5700C5B3AA00BDAEA8008C523500BCB8B600D47C5200C2B2AA00AE9486006B42 + 2D00000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C9856400FFFFFF00DA8C5C00D1835100D1835100D183 + 5100D1835100C6AB98008E452200000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CA80 + 5C00F0885500EAC8B70000000000000000000000000000000000EAC8B700F088 + 5500CA805C000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000DA98 + 7600E5865600B06641008F5538009C725D00C9754D00C1B9B500BA9E90008F55 + 360000000000000000000000000000000000B7A2930063493500634935006349 + 35006349350063493500D1927300FFFFFF00FEFDFB00FBEFEA00F5DED300F0CE + BE00EDC3AF00C7AC990092472300000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000E1CD + C300DB784700EF93670000000000000000000000000000000000EF936700DB78 + 4700E1CDC3000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C8B5 + AC00EB8E5D00DB8256009F5F400094604700BE744F00D57B4F00B96B4500AD87 + 740000000000000000000000000000000000B7A29300F8F3F000EADFD700E6D9 + CF00E1D2C700DDCBBF00D89F8200FFFFFF00F3A77F00E7976E00DA8C5C00D183 + 5100D1835100CAAE9A00984A2500000000000000000000000000000000008A46 + 2500954C2800A4542E00B65F3400C7693A00D672400000000000000000000000 + 0000AE5C3600EC865200F2CFBD000000000000000000F2CFBD00EC865200AE5C + 3600000000000000000000000000D6724000C7693A00B65F3400A4542E00954C + 28008A4625000000000000000000000000000000000000000000000000000000 + 0000C8B6AE00DE997600DF845600C68D7000CC784D00D27C5100C6917700BDA7 + 9C0000000000000000000000000000000000B7A29300FBF8F700E5AE8100DEA1 + 7300DA9C6E00D5976800E0AA9000FFFFFF00FFFFFF00FFFFFF00FBF4F000F7E4 + DB00F2D3C500CCAE9A009D4D250000000000000000000000000000000000954C + 2800DF733600EA824900F39A6A00F5B594000000000000000000000000000000 + 0000A3664800E9845200F7C2A7000000000000000000F7C2A700E9845200A366 + 480000000000000000000000000000000000F5B59400F39A6A00EA824900DF73 + 3600954C28000000000000000000000000000000000000000000000000000000 + 00000000000000000000887366007160560086675500AB9E9900000000000000 + 000000000000000000000000000000000000BBA69700FEFDFC00FBF6F500F6EF + EB00F1E6E000ECDED600E7B59C00FFFFFF00FCAE8A00FCAE8A00F1DBD200E78E + 6000B3572A00AC542900A450270000000000000000000000000000000000A355 + 2E00EC824B00F38D5B00EC9C7600B6866F00E9D5CB0000000000000000000000 + 0000A9745900E1825400F7BE9E000000000000000000F7BE9E00E1825400A974 + 5900000000000000000000000000E9D5CB00B6866F00EC9C7600F38D5B00EC82 + 4B00A3552E000000000000000000000000000000000000000000000000000000 + 000000000000B8B4B1008E8074007E6E6300695D550076726E00000000000000 + 000000000000000000000000000000000000C1AB9C00FFFFFF00FAC59F00F0B8 + 8E00E5AE8100DEA17300ECBDA600FFFFFF00FFFFFF00FFFFFF00FFFFFF00EA9A + 7200F0C9B200B1572B00EDD7CD0000000000000000000000000000000000B55F + 3400F39A6A00F49C7100F29465009D533000AA613B00DAB8A70000000000F6C5 + AE009D644600DE805100F7BDA1000000000000000000F7BDA100DE8051009D64 + 4600F6C5AE0000000000DAB8A700AA613B009D533000F2946500F49C7100F39A + 6A00B55F34000000000000000000000000000000000000000000000000000000 + 000000000000BAB0AA00A2948B00A8A099008E817700635B5500000000000000 + 000000000000000000000000000000000000C7B2A300FFFFFF00FFFFFF00FCFA + F900F8F2F000F3EAE600F0C4AE00FFFFFF00FFFFFF00FFFFFF00FFFFFF00EBA7 + 8500C5653500F1DBCF000000000000000000000000000000000000000000C769 + 3B00F7CAAE00FBDDCB00F4A37600F3946400B4623900B0643E00BF816200BB84 + 6000A15E3900EE8B5A00F6C8B0000000000000000000F6C8B000EE8B5A00A15E + 3900BB846000BF816200B0643E00B4623900F3946400F4A37600FBDDCB00F7CA + AE00C7693B000000000000000000000000000000000000000000000000000000 + 000000000000BEB1AA00A1948B00C8C6C400CDC5C0006B5F5600ADADAE000000 + 000000000000000000000000000000000000CFB9A900FFFFFF00FFDABA00FFD0 + AE00F0DED200B7A29300F0C4AE00EFC2AB00EFC1AA00EFB9A000EDB09200EDB0 + 9200F9E4D900000000000000000000000000000000000000000000000000D672 + 40000000000000000000FBDECF00F5A57E00F49D7200C9734700B7663C00B665 + 3D00E2815300F6BCA100F6CBB7000000000000000000F6CBB700F6BCA100E281 + 5300B6653D00B7663C00C9734700F49D7200F5A57E00FBDECF00000000000000 + 0000D67240000000000000000000000000000000000000000000000000000000 + 000000000000A99B9200B2A8A300C3C3C300E8E4E2007C6F6600A8A9AA000000 + 000000000000000000000000000000000000D4BEAF00FFFFFF00FFFFFF00FFFF + FF00FEFDFC00BBA69600D4C5BA008F725B00E2DDD90000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000FBDACA00F5A67E00F6B69600F5B28F00F6B0 + 9100F6C1A800F6C5AE0000000000000000000000000000000000F6C5AE00F6C1 + A800F6B09100F5B28F00F6B69600F5A67E00FBDACA0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000BBB8B600A3968C00BCBAB90000000000DDDCDC00BCB2AB00A6A19E000000 + 000000000000000000000000000000000000D8C2B200FFFFFF00FFFFFF00FFFF + FF00FFFFFF00C7B1A200A5826600E2DDD9000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FBE0D200F6C3A900F7CF + BB00F9DBCD00000000000000000000000000000000000000000000000000F9DB + CD00F7CFBB00F6C3A900FBE0D200000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000BFB8B300B3A89E000000000000000000CBCBCB00E2DDDA00A19790000000 + 000000000000000000000000000000000000D8C2B200D8C2B200D4BFAE00D4BF + AE00CEB8A900C8B2A300E9E2DE00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00009E8D80006349350063493500634935006349350063493500634935006349 + 3500634935006349350000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000EFCECF00C3646500AA55 + 5600A45253009F4F50009A4D4D00944A4A008F4747008944440083414100783B + 3C00783B3C00723939006E3637000000000000000000EFCECF00C3646500AA55 + 5600A45253009F4F50009A4D4D00944A4A008F4747008944440083414100783B + 3C00783B3C00723939006E363700000000000000000000000000000000000000 + 00009B8A7D00FCFAF800D9C0AE00D5BCAB00CFB7A600C8B1A000C1AB9B00BBA6 + 9600B7A2930063493500000000000000000075848F0066808F0060798700576E + 7B004E626F0044566100394852002E3A4300252E35001B22290014191E000E12 + 16000E13180000000000000000000000000000000000CF6B6C00F38E8F00E680 + 8100AA44240047322100C3B4AB00C6BBB300CAC1BC00CEC8C400564D48009E3E + 33009C3D360098393100723939000000000000000000CF6B6C00F38E8F00E680 + 8100AA44240047322100C3B4AB00C6BBB300CAC1BC00CEC8C400564D48009E3E + 33009C3D36009839310072393900000000000000000000000000000000000000 + 00009B8A7D00FEFEFE00FBF8F700F6F1ED00F1E8E100EBDED600E5D5C900E1CD + BE00BCA596006349350000000000000000007787920089A1AB006AB2D400008F + CD00008FCD00008FCD00048CC7000888BE000F82B400157CA9001B779F001F72 + 9600224B5C0087A2AB00000000000000000000000000D16F7000FF999A00EC86 + 8700E6808100715B4B00473C34008D786800EDE0D800F1E7E0008F7F7300A341 + 3500A2423C009C3D3500783B3C000000000000000000D16F7000FF999A00EC86 + 8700E6808100715B4B00473C34008D786800EDE0D800F1E7E0008F7F7300A341 + 3500A2423C009C3D3500783B3C00000000000000000000000000000000000000 + 00009E8D8000FFFFFF00FEFDFD00FAF7F500F5EFEA00F0E6DF00EBDDD300E5D4 + C700C1AA9B006349350000000000000000007A8A95007EBED3008AA4AE007EDC + FF005FCFFF0055CBFF004CC4FA0041BCF50037B3F0002EAAEB0024A0E500138C + D400236780005E696D00000000000000000000000000D4757600FF9FA000F590 + 9100EC868700715B4B0000000000473C3400E9D9CE00ECDDD40085746700AE4B + 4300AA494400A3423C007D3E3E000000000000000000D4757600FF9FA000F590 + 9100EC868700715B4B0000000000473C3400E9D9CE00ECDDD40085746700AE4B + 4300AA494400A3423C007D3E3E00000000000000000000000000000000000000 + 0000A2918400FFFFFF00FFFFFF00FDFDFB00F9F5F300F4EDE800EFE4DC00E9DB + D000C8B1A1006349350000000000000000007D8E980079D2EC008BA4AD0089C2 + CE0071D8FF0065D3FF005CCEFF0051C9FE0049C1FA003FB9F50034B0EE0029A8 + E9001085CD00224B5B0098B2BA000000000000000000D77B7C00FFA9AA00FB9F + A000F5939400715B4B00715B4B00715B4B00715B4B00766252007D6A5B00BA56 + 5400B24F4C00AA494400834141000000000000000000D77B7C00FFA9AA00FB9F + A000F5939400715B4B00715B4B00715B4B00715B4B00766252007D6A5B00BA56 + 5400B24F4C00AA49440083414100000000000000000000000000000000000000 + 0000A7958800FFFFFF00FFFFFF00FFFFFF00FCFBFA00F9F4F100F3ECE600EDE3 + DA00CFB7A60063493500000000000000000080919C0081D7EF007DC5E0008CA6 + B00080DDFE0068D3FF0067D4FF0062D1FF0058CDFF004EC7FC0046BEF7003BB6 + F20031ACEC00256981007A95A1000000000000000000DB838400FFB3B400FFAD + AE00FCA3A400F48E8F00EC868700E6808100DF797A00D7717200D16B6C00C15D + 5C00BA565400B2504C00894444000000000000000000DB838400FFB3B400FFAD + AE00FCA3A400F48E8F00EC868700E6808100DF797A00D7717200D16B6C00C15D + 5C00BA565400B2504C0089444400000000000000000000000000000000000000 + 0000AB9A8C00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FCFAF800F7F3EF00F2EA + E400D5BCAB0063493500000000000000000083959F0089DCF1008CE2FF008DA8 + B1008CBAC70074D8FF0067D4FF0067D4FF0067D4FF005FD0FF0054CDFF004BC5 + FC0041BBF7002EA2DB005167740098B2BA0000000000DF8A8B00FFBBBC00FFB6 + B700C9636000C45E5600BE584B00B8523F00B34D3400AD472800A7411C00A13B + 1100C15D5C00BA5654008F4747000000000000000000DF8A8B00FFBBBC00FFB6 + B700C9636000C45E5600BE584B00B8523F00B34D3400AD472800A7411C00A13B + 1100C15D5C00BA5654008F474700000000000000000000000000000000000000 + 0000B09E9000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFEFE00FBF9F700F6F1 + ED00D9C0AE00634935000000000000000000869AA30092E1F20098E8FD0080C4 + DE008EA7B00081DEFD0084E0FF0084E0FF0084E0FF0084E0FF0081DFFF007BDD + FF0074D8FF006BD6FF0056A9D1008F9BA40000000000E2919200FFBDBE00CC66 + 6700FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5DE00EADBD200E5D1C600E1CA + BD00A13B1100C25D5C00944A4A000000000000000000E2919200FFBDBE00CC66 + 6700FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5DE00EADBD200E5D1C600E1CA + BD00A13B1100C25D5C00944A4A00000000000000000070C7E10081D8EE0086E6 + FA0039BEE50099D8DF0091E1F60081D0E900FFFFFF00FFFFFF00FEFEFD00C4AD + 9D00C3AB9C00644A36000000000000000000889CA5009AE6F3009FEBFB0098E8 + FE008BACB9008BACB9008AAAB70088A6B30086A3AF00839FAA00819AA6007F95 + A1007C919D007A8E9900798B95007788930000000000E5979800FFBDBE00D36D + 6E00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5DE00EADBD200E5D1 + C600A7411C00CC6767009A4D4D000000000000000000E5979800FFBDBE00D36D + 6E00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5DE00EADBD200E5D1 + C600A7411C00CC6767009A4D4D00000000000000000098E2F30031B7DF007DE9 + FD005DC6E60093F0FF002FB6DF00A0E8F900FFFFFF00FFFFFF00A9988A00644A + 3600644A3600644A360000000000000000008BA0A800A0EAF600A6EEF9009FEB + FB0098E8FE007ADAFF0067D4FF0067D4FF0067D4FF0067D4FF0067D4FF0067D4 + FF007788930000000000000000000000000000000000E99E9F00FFBDBE00DC76 + 7700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5DE00EADB + D200AD472800D77172009F4F50000000000000000000E99E9F00FFBDBE00DC76 + 7700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5DE00EADB + D200AD472800D77172009F4F5000000000000000000094EAFA0093F1FF00BFF8 + FF00AFE8F400C7FBFF0093F1FF009FF0FF00FFFFFF00FFFFFF00AE9C8E00D4C5 + BA00644A3600D0CBC40000000000000000008EA2AB00A7EEF600ABF0F700A6EE + F9009FEBFB0098E8FD0071D4FB00899EA7008699A30082949F007E909A007A8C + 97007788930000000000000000000000000000000000EDA6A700FFBDBE00E680 + 8100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5 + DE00B34D3400DF797A00A45253000000000000000000EDA6A700FFBDBE00E680 + 8100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EEEA00F0E5 + DE00B34D3400DF797A00A4525300000000000000000022ABD90053BFE100AFE8 + F400F0FFFD00B4EBF60053BFE10036BBE500FFFFFF00FFFFFF00B2A09200644A + 3600D0CCC5000000000000000000000000008FA4AC00A0D2DA00ABF0F700ABF0 + F700A6EEF9009FEBFB008DA1AA00B5CBD0000000000000000000000000000000 + 00000000000000000000000000000000000000000000F0ACAD00FFBDBE00EF89 + 8A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EE + EA00B8523F0067333300AA5556000000000000000000F0ACAD00FFBDBE00EF89 + 8A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8F600F6EE + EA00B8523F0067333300AA555600000000000000000094EAFA0096F3FF00C7FB + FF00ADE5F300C3FBFF0096F3FF008BD7E200B6A49600B6A49600B5A39500D0CC + C50000000000000000000000000000000000BDCED4008FA4AC008FA4AC008FA4 + AC008FA4AC008FA4AC00B5CBD000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000F3B2B300FFBDBE00F892 + 9300FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8 + F600BE584B00B0585900B05859000000000000000000F3B2B300FFBDBE00F892 + 9300FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FBF8 + F600BE584B00B0585900B0585900000000000000000096E1F30032B8E0008CF1 + FF0058C2E30090F1FF002FB6DF008DDDF0000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000F5B6B700F5B6B700F3B2 + B300F1ADAE00EEA7A800EAA1A200E79A9B00E4939400E08E8F00DD878800DA80 + 8100D67A7B00D3747500D16F70000000000000000000F5B6B700F5B6B700F3B2 + B300F1ADAE00EEA7A800EAA1A200E79A9B00E4939400E08E8F00DD878800DA80 + 8100D67A7B00D3747500D16F7000000000000000000066C3E00081D8EE0094EA + FA0026AFDB008CE8FA008EDEF10081CCE3000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000200100000100010000000000000900000000000000000000 + 000000000000000000000000FFFFFF00FFFF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000FFFFFFFFFFFFF001FFFFC007F00FF001 + C1FFC007E007C001C1FFC007C003C001007FC00780010001007FC00780010001 + 007FC007800100010013C007800100010003C00780010001C000C00780010001 + C000C00780010001FE00C00780010007FE00C007C0030007FE00C00FE007001F + FF83C01FF00F001FFF83FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC001FFFFC007 + 000F8001C7FFC007000F8001C3FFC007000F8001F207C007000F8001F19FC007 + 000F8001F9CFC007000F8001F903C007000F8001F9FFC00700078001F8FFC007 + 00038001F07FC00700018001FCFFC00700008001FC9FC007FFF08001FE1FC00F + FFF98001FFFFC01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87FFFFFFC00FFFF + C867FC018000C0818003FC010000C0818003FC010000C081C00700010000C081 + C00700010001C081030100010003C081078100010007FFFF078100010007C081 + 030100030007C081C00700070007C0818003007F0007C081800300FF800FC081 + C86701FFF8FFC081F87FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800180010000 + 8003800180010000000180018001000000018001800100000001800180010000 + 0001800180010000000180018001000000018001800100000001800180010000 + 0001800180010000000180018001000000018001800100000001800180010000 + 8003800180010000FFFFFFFF80010000FFFFFFFFFFFFFC00FF1FFFF8FFF8FC00 + FE1FFFF0FFF0FC00EE1FFFE0FFE0FC00E03FFFC1FFC1E000E03FE003E003E000 + E03FC007C007E000E00F800F800FE000E01F800F800F0007E03F800F800F0007 + E07F800F800F0007E0FF800F800F0007E1FF800F800F003FE3FF800F800F003F + E7FFC01FC01F003FEFFFE03FE03F003FFFFF0000F001FFFFFFFF0000F0010001 + FFFF0000C0010001FFFF0000C0010001FE7F000000010001FE3F000000010001 + E01F000000010001E00F000000010001E00F000000010001E00F000000010001 + E01F000000010001FE3F000000070001FE7F000000070001FFFF0000001F0001 + FFFF0000001F0001FFFF0000FFFF0001FFE7FFFFFFFFFFFFFFE7FFFFFFFFFFFF + FFE7F00F0003FBFFE000E0070001F9FFE000C0030001F8FFE3E7C0030001F87F + E5E7C3C30001F83FE6E7C3C30001F81FE767C2430001F80FE7A7C0C30001F81F + E7C7C0C30001F83F0007C0C30001F87F0007E0C70001F8FFE7FBC0FF0001F9FF + E7FDFFFF0001FBFFE7FFFFFFFFFFFFFFFFFFFFFFFFFF803FFFFFFFFFFFFF803F + FFFFFFFF0003803FFFFFC0030001803FE00FCFFB0001803FE00FC00B0001803F + E00FC00B0001803FE00FC00B0001803FE00FC00B0001807FE00FC00B000180FF + E00FC00B000181FFE00FC00B0001FFFFE00FC0030001FF80FFFFC0030001FFFF + FFFFFFFF0001FFFFFFFFFFFFFFFFFFFFFFFFDFFF8000FFFFF001DFFB0000FC3F + F80187FB0000E023FC0103FB00008001BE0103E1000080019F0103C000008001 + 8F0103C00000C003860187C0000000008061EFC00000000080F1EFE100000000 + 80F9EFF700008000807DF7EF0000E003803FF7EF0000C001801FFBDF0000C001 + 800FFC3F0000E423FFFFFFFF0001FC3FFFFFFF1FFEFFFFFFFFF8E0001C71800F + FFF0E0003839800FFFE0E0005EF5800FFFC1E000EEEFF0FFE003E000C007F07F + C00780008003F83F800F80008003FC1F800F00008003FE03800F00008003FF03 + 800F0000C007FF83800F0000EEEFFF80800F00005EF5FF80800F80003839FFC0 + C01FC0FF1C71FFF0E03FFFFFFEFFFFFFFFFFFFFFFFFFFFFF800380038003E00F + 800380038003E00F800380038003E000800380038003E0008003800380030000 + 8003800380030000800380038003000080038003800300008003800380030000 + 800380038003000080038003800300018007800780070003800F800F800F0007 + 801F801F801F01FF803F803F803F03FFFFFFFFFFFFFFFFFF8003FC038003803F + 8003FC038003803F8003F0038003803F8003F003800380038003C00380038003 + 8003C003800380038003C003800380038003C003800380038003C00380038003 + 8003C007800380038003C00F800380038007C01F8007F807800FC03F800FF80F + 801FC07F801FF81F803FFFFF803FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 8000C081000FC7FF0000C081000FC2FF0000C081000FF2070000C081000FF187 + 0000C081000FF10F0000C081000FF9030000FFFF0007F8930000C0810003F8FF + 0000C0810001F07F0000C0810000FCFF0000C0810000FC1F0000C081FFE0FE1F + 0000C081FFF0FF3F0000FFFFFFFFFFFFFFFFFFFFFC00FFFFFFFF000FFC008003 + FFFF000FFC008003E007000FFC008003E007000FE0008003E007000FE0008003 + E007000FE0008003E007000FE0008003E007000C00078003E007000000078003 + E007000000078003E007000000078003E007F800003F8003FFFFF000003F8003 + FFFFF000003F8003FFFFFFFF003FFFFFFFFFFFFFFFFFFFFFFC00FFFF8001FFFF + 0000C3F380010000000081E1800100000000C1C1800100000000C18380010000 + 0001E007800100000003F00F800100000007F81F800100000007FC1F80010000 + 0007F00F800100000007E007800100000007808380010000000701C380010000 + F87F03E380010000FFFF07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1FFFFFF + FF9FF9FFE00FFC01FF8FF1FFE00FFC01FFC7E3FFE00FFC01FFE3C7FFE00F0001 + FFE3C7FFE00F0001E0718E07F00F0001E0F18F07FC3F0001E0718E07F83F0001 + E0218407F83F0003E0018007F81F0007EC018037F81F007FFE03C07FF11F00FF + FF87E1FFF31F01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003FFFF80018001 + F003000780018001F003000380018001F003000380018001F003000180018001 + F003000180018001F003000080018001F0030000800180018003000080018001 + 80030007800180018003000780018001800700FF80018001800F01FF80018001 + 80FFFFFF8001800180FFFFFFFFFFFFFF00000000000000000000000000000000 + 000000000000} + end + object SmallImages: TImageList + Left = 24 + Top = 224 + Bitmap = { + 494C010101004400500010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000001000000001002000000000000010 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEF + FF00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEF + FF00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEF + FF00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00296BAD00296BAD00296BAD00296BAD00296BAD00296BAD00296BAD00296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF000000000008297B005A9CBD000000000008185A000000000000000000296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF0000000000184A9C004A8CBD00185A9C00397BAD000000080000000000296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF0008185A00396BAD00296BAD00185A9C004A8CBD00295A9C0000000000296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF005A9CCE00396BAD0008397B0000081800084A8C008CBDDE00296BAD00296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF0000000000397BAD00296BAD00396BAD004A7BBD006BADCE0008083900296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00000000000000000008296B007BADCE007BADCE00184A9C0000082900296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF0000000000000000000000000008185A00000818000008290000081800296B + AD00CEEFFF00CEEFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF000000 + 0000ADCEEF000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CEEFFF00CEEF + FF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF00CEEFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000100000000100010000000000800000000000000000000000 + 000000000000000000000000FFFFFF0080010000000000008001000000000000 + 8001000000000000800100000000000080010000000000008001000000000000 + 8001000000000000800100000000000080010000000000008001000000000000 + 8001000000000000800100000000000080010000000000008003000000000000 + 8007000000000000800F00000000000000000000000000000000000000000000 + 000000000000} + end + object MainMenu: TMainMenu + Images = Buttons + Left = 24 + Top = 168 + object MainFile: TMenuItem + Caption = '&File' + OnClick = MainFileClick + object New1: TMenuItem + Caption = 'New...' + ShortCut = 16462 + OnClick = ToolButton8Click + end + object mnuOpen: TMenuItem + Caption = '&Open...' + Hint = 'Open parameter file for browsing' + ImageIndex = 1 + ShortCut = 16463 + OnClick = mnuOpenClick + end + object Restorelastautosave1: TMenuItem + Caption = 'Restore last autosave' + ShortCut = 49217 + OnClick = Restorelastautosave1Click + end + object N3: TMenuItem + Caption = '-' + end + object mnuSaveAs: TMenuItem + Caption = '&Save Parameters...' + Hint = 'Save parameters to file' + ImageIndex = 3 + ShortCut = 16467 + OnClick = mnuSaveAsClick + end + object mnuSaveAllAs: TMenuItem + Caption = 'Save &All Parameters' + Hint = 'Save all parameters to file' + ShortCut = 24659 + OnClick = mnuSaveAllAsClick + end + object N9: TMenuItem + Caption = '-' + end + object mnuSmoothGradient: TMenuItem + Caption = 'Smooth Palette...' + Hint = 'Create a smooth gradient from an image' + ImageIndex = 34 + OnClick = mnuSmoothGradientClick + end + object mnuOpenGradient: TMenuItem + Caption = 'Gradient Browser...' + Hint = 'Show the gradient browser' + ImageIndex = 22 + OnClick = mnuOpenGradientClick + end + object N18: TMenuItem + Caption = '-' + end + object mnuSaveUPR: TMenuItem + Caption = 'Export &UPR...' + Hint = + 'Save the flame in UltraFractal parameter format *** OUTDATED ***' + + ' USE AT YOUR OWN RISK!' + OnClick = mnuSaveUPRClick + end + object mnuExportFLame: TMenuItem + Caption = 'Export Flame...' + Hint = 'Disabled in this "3D hack" version' + ShortCut = 16472 + OnClick = mnuExportFLameClick + end + object mnuImportGimp: TMenuItem + Caption = 'Import Gimp Parameters' + Hint = 'Import Gimp parameters' + OnClick = mnuImportGimpClick + end + object N1: TMenuItem + Caption = '-' + end + object mnuPostSheep: TMenuItem + Caption = 'Post Sheep...' + Enabled = False + ImageIndex = 45 + ShortCut = 16456 + Visible = False + end + object N21: TMenuItem + Caption = '-' + Visible = False + end + object mnuRandomBatch: TMenuItem + Caption = '&Random Batch' + Hint = 'Create and load a file containing random flame parameters' + ShortCut = 16450 + OnClick = mnuRandomBatchClick + end + object FileExitSep: TMenuItem + Caption = '-' + end + object mnuExit: TMenuItem + Caption = 'E&xit' + Hint = 'Quit Apophysis' + OnClick = mnuExitClick + end + end + object MainEdit: TMenuItem + Caption = '&Edit' + object mnuUndo: TMenuItem + Caption = '&Undo' + Enabled = False + Hint = 'Undo last action' + ImageIndex = 4 + ShortCut = 16474 + OnClick = mnuUndoClick + end + object mnuRedo: TMenuItem + Caption = '&Redo' + Enabled = False + Hint = 'Redo last action' + ImageIndex = 5 + ShortCut = 16473 + OnClick = mnuRedoClick + end + object mnuSaveUndo: TMenuItem + Caption = 'Save Undo...' + Enabled = False + Hint = 'Save undo list to a parameter file' + ShortCut = 49237 + Visible = False + end + object N13: TMenuItem + Caption = '-' + end + object mnuCopy: TMenuItem + Caption = 'Copy' + Hint = 'Copy |Copies a flame to the clipboard' + ImageIndex = 7 + ShortCut = 16451 + OnClick = mnuCopyClick + end + object mnuPaste: TMenuItem + Caption = 'Paste' + ImageIndex = 8 + ShortCut = 16470 + OnClick = mnuPasteClick + end + object N20: TMenuItem + Caption = '-' + end + object mnuCopyUPR: TMenuItem + Caption = 'Copy as U&PR' + Hint = 'Copy a UPR to the clipboard' + ImageIndex = 23 + ShortCut = 16469 + OnClick = mnuCopyUPRClick + end + end + object View1: TMenuItem + Caption = '&View' + object mnuFullScreen: TMenuItem + Caption = 'Full Screen' + Hint = 'Show the flame in fullscreen mode' + ImageIndex = 52 + ShortCut = 114 + OnClick = mnuFullScreenClick + end + object N4: TMenuItem + Caption = '-' + end + object mnuEditor: TMenuItem + Caption = '&Editor' + Hint = 'Show the Transform Editor' + ImageIndex = 19 + ShortCut = 115 + OnClick = mnuEditorClick + end + object mnuAdjust: TMenuItem + Caption = 'Adjust' + Hint = 'Show the Adjust window' + ImageIndex = 18 + ShortCut = 116 + OnClick = mnuAdjustClick + end + object mnuGrad: TMenuItem + Caption = 'Gradient' + Hint = 'Show the Gradient window' + ImageIndex = 11 + ShortCut = 117 + OnClick = mnuGradClick + end + object mnuMutate: TMenuItem + Caption = 'Mutation' + Hint = 'Show the Mutation window' + ImageIndex = 17 + ShortCut = 118 + OnClick = mnuMutateClick + end + object mnuCurves: TMenuItem + Caption = 'Curves' + ImageIndex = 69 + ShortCut = 119 + OnClick = ToolButton19Click + end + object N5: TMenuItem + Caption = '-' + end + object mnuImageSize: TMenuItem + Caption = 'Image Size' + ImageIndex = 51 + OnClick = mnuImageSizeClick + end + object mnuMessages: TMenuItem + Caption = 'Messages' + OnClick = ToolButton7Click + end + object mnuimage: TMenuItem + Caption = 'Image ' + Visible = False + OnClick = mnuimageClick + end + end + object F1: TMenuItem + Caption = 'Flame' + object mnuResetLocation: TMenuItem + Caption = 'Reset Location' + Hint = 'Recalculate flame location' + ImageIndex = 12 + ShortCut = 123 + OnClick = mnuResetLocationClick + end + object N19: TMenuItem + Caption = '-' + end + object mnuRandom: TMenuItem + Caption = '&Randomize' + Hint = 'Randomize flame parameters' + OnClick = mnuRandomClick + end + object mnuRWeights: TMenuItem + Caption = 'Random &Weights' + Hint = 'Randomize transform weights' + OnClick = mnuRWeightsClick + end + object mnuEqualize: TMenuItem + Caption = '&Equalize Weights' + Hint = 'Set all weights to the same value' + OnClick = mnuEqualizeClick + end + object mnuNormalWeights: TMenuItem + Caption = 'Compute Weights' + Hint = 'Compute weights from triangle areas' + OnClick = mnuNormalWeightsClick + end + object N7: TMenuItem + Caption = '-' + end + object mnuCalculateColors: TMenuItem + Caption = 'Calculate Colors Values' + Hint = 'Spread the transform color parameters evenly' + OnClick = mnuCalculateColorsClick + end + object mnuRandomizeColorValues: TMenuItem + Caption = 'Randomize Color Values' + Hint = 'Randomize color parameters' + ShortCut = 49230 + OnClick = mnuRandomizeColorValuesClick + end + object N2: TMenuItem + Caption = '-' + end + object mnuRender: TMenuItem + Caption = 'Render to Disk...' + Hint = 'Render flame to disk' + ImageIndex = 35 + ShortCut = 16466 + OnClick = mnuRenderClick + end + object mnuResumeRender: TMenuItem + Caption = 'Resume unfinished render...' + Enabled = False + end + object mnuRenderAll: TMenuItem + Caption = 'Render &All Flames' + Hint = 'Render all flame in a batch to disk' + ShortCut = 49234 + OnClick = mnuRenderAllClick + end + object N12: TMenuItem + Caption = '-' + end + object mnuReportFlame: TMenuItem + Caption = 'Generate report...' + OnClick = mnuReportFlameClick + end + end + object mnuVar: TMenuItem + Caption = 'Variation' + object mnuVRandom: TMenuItem + Caption = 'Random' + GroupIndex = 2 + RadioItem = True + ShortCut = 122 + OnClick = mnuVRandomClick + end + object N8: TMenuItem + Caption = '-' + GroupIndex = 2 + end + object mnuBuiltinVars: TMenuItem + Caption = 'Built-in' + GroupIndex = 2 + end + object mnuPluginVars: TMenuItem + Caption = 'Plugins' + GroupIndex = 2 + end + end + object mnuScript: TMenuItem + Caption = 'Script' + object mnuRun: TMenuItem + Caption = 'Run script' + Hint = 'Run the currently loaded script' + ImageIndex = 43 + ShortCut = 120 + OnClick = mnuRunClick + end + object mnuStop: TMenuItem + Caption = 'Stop script' + ImageIndex = 36 + ShortCut = 121 + OnClick = mnuStopClick + end + object N15: TMenuItem + Caption = '-' + end + object mnuOpenScript: TMenuItem + Caption = 'Open...' + Hint = 'Open a script file' + ImageIndex = 1 + ShortCut = 16453 + OnClick = mnuOpenScriptClick + end + object mnuEditScript: TMenuItem + Caption = 'Edit' + Hint = 'Show Script Editor' + ImageIndex = 42 + ShortCut = 16452 + OnClick = mnuEditScriptClick + end + object N10: TMenuItem + Caption = '-' + end + object mnuManageFavorites: TMenuItem + Caption = 'Manage Favorites' + Hint = 'Show the Favorites Manager' + OnClick = mnuManageFavoritesClick + end + object mnuTurnFlameToScript: TMenuItem + Caption = 'Turn flame into script...' + OnClick = mnuTurnFlameToScriptClick + end + end + object mnuView: TMenuItem + Caption = 'Options' + object mnuToolbar: TMenuItem + Caption = 'Main toolbar' + Checked = True + Hint = 'Show or hide the toolbar' + OnClick = mnuToolbarClick + end + object mnuStatusBar: TMenuItem + Caption = 'Status Bar' + Checked = True + Hint = 'Show or hide the status bar' + OnClick = mnuStatusBarClick + end + object mnuFileContents: TMenuItem + Caption = 'File Contents' + Checked = True + Hint = 'Show or hide the file contents list' + OnClick = mnuFileContentsClick + end + object N17: TMenuItem + Caption = '-' + end + object mnuResetUI: TMenuItem + Caption = 'Reset file content list width' + OnClick = mnuResetUIClick + end + object N14: TMenuItem + Caption = '-' + end + object mnuOptions: TMenuItem + Caption = 'Options...' + Hint = 'Show the Options dialog' + ImageIndex = 13 + ShortCut = 16464 + OnClick = mnuOptionsClick + end + end + object MainHelp: TMenuItem + Caption = '&Help' + OnClick = MainHelpClick + object mnuHelpTopics: TMenuItem + Caption = 'Contents' + Hint = 'Open the Apophysis help file' + ShortCut = 112 + OnClick = mnuHelpTopicsClick + end + object mnuFlamepdf: TMenuItem + Caption = 'The Fractal Flame Algorithm' + OnClick = mnuFlamepdfClick + end + object mnuManual: TMenuItem + Caption = 'Apophysis User Manual' + OnClick = mnuManualClick + end + object N11: TMenuItem + Caption = '-' + end + object mnuAbout: TMenuItem + Caption = 'About...' + Hint = 'Show copyright and version information' + ImageIndex = 47 + OnClick = mnuAboutClick + end + end + end + object OpenDialog: TOpenDialog + Filter = + 'Apophysis Parameter Files (*.apo)|*.apo|Apophysis 1.0 Parameters' + + ' (*fla)|*.fla|IFS Files (*.ifs)|*.ifs' + Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing] + Left = 24 + Top = 456 + end + object ListPopUp: TPopupMenu + Left = 104 + Top = 168 + object mnuItemDelete: TMenuItem + Caption = '&Delete' + Hint = 'Deletes the selected IFS from the file.' + ShortCut = 16430 + OnClick = mnuItemDeleteClick + end + object mnuListRename: TMenuItem + Caption = '&Rename' + Hint = 'Renames the selected IFS.' + ShortCut = 113 + OnClick = mnuListRenameClick + end + end + object DisplayPopup: TPopupMenu + Images = Buttons + Left = 104 + Top = 120 + object mnuPopUndo: TMenuItem + Caption = 'Undo' + Enabled = False + ImageIndex = 4 + ShortCut = 16474 + OnClick = mnuUndoClick + end + object mnuPopRedo: TMenuItem + Caption = 'Redo' + Enabled = False + ImageIndex = 5 + ShortCut = 16473 + OnClick = mnuRedoClick + end + object N16: TMenuItem + Caption = '-' + end + object mnuPopResetLocation: TMenuItem + Caption = 'Reset Location' + ImageIndex = 12 + OnClick = mnuResetLocationClick + end + object N6: TMenuItem + Caption = '-' + end + object mnuPopFullscreen: TMenuItem + Caption = 'Fullscreen View' + Hint = 'Show the flame in fullscreen mode' + ImageIndex = 52 + ShortCut = 114 + OnClick = mnuFullScreenClick + end + end + object RedrawTimer: TTimer + Enabled = False + Interval = 50 + OnTimer = RedrawTimerTimer + Left = 24 + Top = 336 + end + object SaveDialog: TSaveDialog + DefaultExt = 'bmp' + Filter = 'Bitmap Files|*.bmp' + Options = [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing] + Left = 104 + Top = 400 + end + object ApplicationEvents: TApplicationEvents + OnActivate = ApplicationEventsActivate + Left = 104 + Top = 456 + end + object Thumbnails: TImageList + Height = 128 + Masked = False + Width = 128 + Left = 24 + Top = 280 + end + object SmallThumbnails: TImageList + Height = 96 + Masked = False + Width = 96 + Left = 104 + Top = 224 + end + object ColorDialog: TColorDialog + Options = [cdFullOpen] + Left = 24 + Top = 400 + end + object AutoSaveTimer: TTimer + Enabled = False + OnTimer = AutoSaveTimerTimer + Left = 104 + Top = 334 + end +end diff --git a/Forms/Main.pas b/Forms/Main.pas new file mode 100644 index 0000000..fb1d08a --- /dev/null +++ b/Forms/Main.pas @@ -0,0 +1,7015 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +//{$D-,L-,O+,Q-,R-,Y-,S-} + +unit Main; + +//{$define VAR_STR} + +{$ifdef VER240} + // we need to update TMS Scripter to the XE3 version... + {$Define DisableScripting} +{$endif} + +interface + +uses + Windows, Forms, Dialogs, Menus, Controls, ComCtrls, + ToolWin, StdCtrls, Classes, Messages, ExtCtrls, ImgList, + Jpeg, SyncObjs, SysUtils, ClipBrd, Graphics, Math, + ExtDlgs, AppEvnts, ShellAPI, Registry, Curves, + Global, Xform, XFormMan, ControlPoint, CMap, + RenderThread, RenderingCommon, RenderingInterface, (*ParameterIO,*) + LibXmlParser, LibXmlComps, PngImage, XPMan, + StrUtils, LoadTracker, CheckLst, + CommandLine, RegularExpressionsCore, MissingPlugin, Base64, Translation, + RegexHelper;//, WinInet; + +const + PixelCountMax = 32768; + RS_A1 = 0; + RS_DR = 1; + RS_XO = 2; + RS_VO = 3; + + randFilename = 'Apophysis7X.rand'; + undoFilename = 'Apophysis7X.undo'; + templateFilename = 'Apophysis7X.temp'; + templatePath = '\templates'; + scriptPath = '\scripts'; + +type + TMouseMoveState = (msUsual, msZoomWindow, msZoomOutWindow, msZoomWindowMove, + msZoomOutWindowMove, msDrag, msDragMove, msRotate, msRotateMove, msPitchYaw, msHeight); + +type + TWin32Version = (wvUnknown, wvWin95, wvWin98, wvWinNT, wvWin2000, wvWinXP, wvWinVista, wvWin7, wvWinFutureFromOuterSpace); + +type + TThumbnailThread = class(TThread) + private + ThumbnailSize : integer; + Flames : TStringList; + FileName : string; + Initialized : boolean; + + public + constructor Create(SourceFile : string; FlameNames : TstringList); + destructor Destroy; override; + procedure Execute; override; + end; + +type + pRGBTripleArray = ^TRGBTripleArray; + TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple; + TMatrix = array[0..1, 0..1] of double; + + TMainForm = class(TForm) + Buttons: TImageList; + SmallImages: TImageList; + MainMenu: TMainMenu; + MainFile: TMenuItem; + mnuSaveUPR: TMenuItem; + N1: TMenuItem; + mnuRandomBatch: TMenuItem; + FileExitSep: TMenuItem; + mnuExit: TMenuItem; + MainEdit: TMenuItem; + mnuCopyUPR: TMenuItem; + mnuEditor: TMenuItem; + mnuRandom: TMenuItem; + mnuNormalWeights: TMenuItem; + mnuEqualize: TMenuItem; + mnuRWeights: TMenuItem; + mnuOptions: TMenuItem; + MainHelp: TMenuItem; + mnuHelpTopics: TMenuItem; + OpenDialog: TOpenDialog; + ListPopUp: TPopupMenu; + mnuItemDelete: TMenuItem; + mnuListRename: TMenuItem; + DisplayPopup: TPopupMenu; + mnuPopFullscreen: TMenuItem; + RedrawTimer: TTimer; + mnuVar: TMenuItem; + mnuVRandom: TMenuItem; + N3: TMenuItem; + mnuOpen: TMenuItem; + mnuSaveAs: TMenuItem; + N8: TMenuItem; + mnuGrad: TMenuItem; + mnuSmoothGradient: TMenuItem; + mnuView: TMenuItem; + mnuToolbar: TMenuItem; + mnuStatusBar: TMenuItem; + BackPanel: TPanel; + mnuFileContents: TMenuItem; + mnuUndo: TMenuItem; + mnuRedo: TMenuItem; + N5: TMenuItem; + SaveDialog: TSaveDialog; + F1: TMenuItem; + N11: TMenuItem; + mnuAbout: TMenuItem; + mnuFullScreen: TMenuItem; + mnuRender: TMenuItem; + mnuMutate: TMenuItem; + mnuAdjust: TMenuItem; + mnuOpenGradient: TMenuItem; + mnuResetLocation: TMenuItem; + N4: TMenuItem; + N14: TMenuItem; + mnuSaveUndo: TMenuItem; + N2: TMenuItem; + mnuPopResetLocation: TMenuItem; + N6: TMenuItem; + mnuPopUndo: TMenuItem; + N16: TMenuItem; + mnuPopRedo: TMenuItem; + mnuCalculateColors: TMenuItem; + mnuRandomizeColorValues: TMenuItem; + N7: TMenuItem; + N18: TMenuItem; + N19: TMenuItem; + mnuScript: TMenuItem; + mnuRun: TMenuItem; + mnuEditScript: TMenuItem; + N15: TMenuItem; + mnuStop: TMenuItem; + mnuOpenScript: TMenuItem; + mnuImportGimp: TMenuItem; + N9: TMenuItem; + N10: TMenuItem; + mnuManageFavorites: TMenuItem; + mnuImageSize: TMenuItem; + N13: TMenuItem; + ApplicationEvents: TApplicationEvents; + mnuPaste: TMenuItem; + mnuCopy: TMenuItem; + N20: TMenuItem; + mnuExportFLame: TMenuItem; + mnuPostSheep: TMenuItem; + N21: TMenuItem; + mnuFlamepdf: TMenuItem; + mnuimage: TMenuItem; + mnuSaveAllAs: TMenuItem; + View1: TMenuItem; + mnuRenderAll: TMenuItem; + mnuBuiltinVars: TMenuItem; + mnuPluginVars: TMenuItem; + Thumbnails: TImageList; + Image1: TImage; + Splitter: TSplitter; + SmallThumbnails: TImageList; + ListBackPanel: TPanel; + Shape1: TShape; + ListView: TListView; + ListView1: TListView; + cbMain: TCoolBar; + ToolBar: TToolBar; + ToolButton8: TToolButton; + btnOpen: TToolButton; + btnSave: TToolButton; + ToolButton10: TToolButton; + btnRender: TToolButton; + tbRenderAll: TToolButton; + ToolButton9: TToolButton; + btnViewList: TToolButton; + btnViewIcons: TToolButton; + ToolButton2: TToolButton; + btnUndo: TToolButton; + btnRedo: TToolButton; + ToolButton1: TToolButton; + btnReset: TToolButton; + btnFullScreen: TToolButton; + ToolButton3: TToolButton; + tbQualityBox: TComboBoxEx; + New1: TMenuItem; + ColorDialog: TColorDialog; + mnuResetUI: TMenuItem; + ToolButton4: TToolButton; + ToolButton5: TToolButton; + ToolButton6: TToolButton; + ToolButton7: TToolButton; + ToolButton11: TToolButton; + ToolButton12: TToolButton; + ToolButton13: TToolButton; + ToolButton14: TToolButton; + ToolButton15: TToolButton; + tbShowAlpha: TToolButton; + ToolButton16: TToolButton; + ToolButton17: TToolButton; + btnRunScript: TToolButton; + btnStopScript: TToolButton; + ToolButton18: TToolButton; + tbDraw: TToolButton; + ToolButton20: TToolButton; + ToolButton21: TToolButton; + ToolButton22: TToolButton; + AutoSaveTimer: TTimer; + Restorelastautosave1: TMenuItem; + tbGuides: TToolButton; + mnuTurnFlameToScript: TMenuItem; + N12: TMenuItem; + mnuReportFlame: TMenuItem; + mnuMessages: TMenuItem; + BottomDock: TPanel; + StatusBar: TStatusBar; + Image: TImage; + pnlLSPFrame: TPanel; + LoadSaveProgress: TProgressBar; + mnuResumeRender: TMenuItem; + mnuManual: TMenuItem; + ToolButton19: TToolButton; + mnuCurves: TMenuItem; + N17: TMenuItem; + procedure mnuManualClick(Sender: TObject); + procedure mnuReportFlameClick(Sender: TObject); + procedure mnuTurnFlameToScriptClick(Sender: TObject); + procedure tbzoomoutwindowClick(Sender: TObject); + procedure mnuimageClick(Sender: TObject); + procedure mnuExitClick(Sender: TObject); + procedure mnuSaveUPRClick(Sender: TObject); + procedure ListViewChange(Sender: TObject; Item: TListItem; + Change: TItemChange); + procedure FormCreate(Sender: TObject); + procedure mnuRandomClick(Sender: TObject); + procedure mnuEqualizeClick(Sender: TObject); + procedure mnuEditorClick(Sender: TObject); + procedure mnuRWeightsClick(Sender: TObject); + procedure mnuRandomBatchClick(Sender: TObject); + procedure FormKeyPress(Sender: TObject; var Key: Char); + procedure FormKeyUpDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure mnuOptionsClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure mnuHelpTopicsClick(Sender: TObject); + procedure mnuRefreshClick(Sender: TObject); + procedure mnuNormalWeightsClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure mnuCopyUPRClick(Sender: TObject); + procedure mnuItemDeleteClick(Sender: TObject); + procedure ListViewEdited(Sender: TObject; Item: TListItem; + var S: string); + procedure mnuListRenameClick(Sender: TObject); + procedure BackPanelResize(Sender: TObject); + procedure mnuNextClick(Sender: TObject); + procedure mnuPreviousClick(Sender: TObject); + procedure RedrawTimerTimer(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure MainFileClick(Sender: TObject); + procedure MainViewClick(Sender: TObject); + procedure MainToolsClick(Sender: TObject); + procedure MainHelpClick(Sender: TObject); + procedure mnuVRandomClick(Sender: TObject); + procedure mnuSaveAsClick(Sender: TObject); + procedure mnuOpenClick(Sender: TObject); + procedure mnuGradClick(Sender: TObject); + procedure mnuSmoothGradientClick(Sender: TObject); + procedure mnuToolbarClick(Sender: TObject); + procedure mnuStatusBarClick(Sender: TObject); + procedure mnuFileContentsClick(Sender: TObject); + procedure mnuUndoClick(Sender: TObject); + procedure mnuRedoClick(Sender: TObject); + procedure Undo; + procedure Redo; + procedure mnuExportBitmapClick(Sender: TObject); + procedure mnuFullScreenClick(Sender: TObject); + procedure mnuRenderClick(Sender: TObject); + procedure mnuMutateClick(Sender: TObject); + procedure mnuAdjustClick(Sender: TObject); + procedure mnuResetLocationClick(Sender: TObject); + procedure mnuAboutClick(Sender: TObject); + procedure mnuOpenGradientClick(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure FormActivate(Sender: TObject); + procedure FormDeactivate(Sender: TObject); + procedure mnuCalculateColorsClick(Sender: TObject); + procedure mnuRandomizeColorValuesClick(Sender: TObject); + procedure mnuEditScriptClick(Sender: TObject); + procedure btnRunClick(Sender: TObject); + procedure mnuRunClick(Sender: TObject); + procedure mnuOpenScriptClick(Sender: TObject); + procedure mnuStopClick(Sender: TObject); + procedure mnuImportGimpClick(Sender: TObject); + procedure mnuManageFavoritesClick(Sender: TObject); + procedure mnuShowFullClick(Sender: TObject); + procedure mnuImageSizeClick(Sender: TObject); + procedure ApplicationEventsActivate(Sender: TObject); + procedure mnuPasteClick(Sender: TObject); + procedure mnuCopyClick(Sender: TObject); + procedure mnuExportFlameClick(Sender: TObject); + + procedure ListXmlScannerStartTag(Sender: TObject; TagName: string; + Attributes: TAttrList); + procedure XMLScannerStartTag(Sender: TObject; TagName: string; + Attributes: TAttrList); + procedure XMLScannerEmptyTag(Sender: TObject; TagName: string; + Attributes: TAttrList); + procedure mnuFlamepdfClick(Sender: TObject); + procedure ImageMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure ImageMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure ImageMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure tbzoomwindowClick(Sender: TObject); + procedure tbDragClick(Sender: TObject); + procedure tbRotateClick(Sender: TObject); + procedure mnuSaveAllAsClick(Sender: TObject); + procedure tbQualityBoxKeyPress(Sender: TObject; var Key: Char); + procedure tbQualityBoxSet(Sender: TObject); + procedure ImageDblClick(Sender: TObject); + procedure tbShowAlphaClick(Sender: TObject); + procedure tbShowTraceClick(Sender: TObject); + procedure XmlScannerContent(Sender: TObject; Content: String); + procedure mnuRenderAllClick(Sender: TObject); + procedure ListViewChanging(Sender: TObject; Item: TListItem; + Change: TItemChange; var AllowChange: Boolean); + procedure ListViewInfoTip(Sender: TObject; Item: TListItem; + var InfoTip: String); + procedure btnViewIconsClick(Sender: TObject); + procedure btnViewListClick(Sender: TObject); + procedure ListView1Click(Sender: TObject); + procedure XmlScannerEndTag(Sender: TObject; TagName: String); + procedure ToolButton7Click(Sender: TObject); + procedure RebuildListView(); + procedure ToolButton8Click(Sender: TObject); + procedure FormResize(Sender: TObject); + procedure mnuResetUIClick(Sender: TObject); + procedure AutoSaveTimerTimer(Sender: TObject); + procedure Restorelastautosave1Click(Sender: TObject); + procedure tbGuidesClick(Sender: TObject); + procedure ToolButton19Click(Sender: TObject); + procedure mnuTraceClick(Sender: TObject); + + private + SubstSource: TStringList; + SubstTarget: TStringList; + + Renderer: TRenderThread; + FNrThreads: integer; + + FMouseMoveState: TMouseMoveState; + FSelectRect, FClickRect: TRect; + DrawSelection: boolean; + FRotateAngle: double; + FClickAngle: double; + FViewImage: TPngObject; + FViewPos, FViewOldPos: TSPoint; + FViewScale: double; + FClickPitch, FNewPitch: double; + FClickYaw, FNewYaw: double; + FShiftState: TShiftState; + DoNotAskAboutChange: boolean; + ParseHandledPluginList : boolean; + + // For parsing: + FinalXformLoaded: boolean; + ActiveXformSet: integer; + XMLPaletteFormat: string; + XMLPaletteCount: integer; + + camDragMode, camDragged, camMM: boolean; + camDragPos, camDragOld: TPoint; + camDragValueX, camDragValueY: double; + + procedure CreateSubstMap; + procedure InsertStrings; + procedure DrawImageView; + procedure DrawZoomWindow; + procedure DrawRotatelines(Angle: double); + procedure DrawPitchYawLines(YawAngle: double; PitchAngle:double); + + procedure FillVariantMenu; + procedure VariantMenuClick(Sender: TObject); + + procedure FavoriteClick(Sender: TObject); + procedure ScriptItemClick(Sender: TObject); + procedure HandleThreadCompletion(var Message: TMessage); + message WM_THREAD_COMPLETE; + procedure HandleThreadTermination(var Message: TMessage); + message WM_THREAD_TERMINATE; + + public + { Public declarations } + UndoIndex, UndoMax: integer; + Center: array[0..1] of double; + MainZoom: double; + StartTime: TDateTime; + AnimPal: TColorMap; + PrevListItem: TListItem; + LockListChangeUpdate: boolean; + CurrentFileName: string; + UsedThumbnails: TImageList; + ParseLoadingBatch : boolean; + SurpressHandleMissingPlugins : boolean; + LastCaptionSel, LastCaptionFoc: string; + LastDecision: boolean; + + VarMenus: array of TMenuItem; + + ListXmlScanner : TEasyXmlScanner; + XmlScanner : TXmlScanner; + + function ReadWithSubst(Attributes: TAttrList; attrname: string): string; + procedure InvokeLoadXML(xmltext:string); + procedure LoadXMLFlame(filename, name: string); + procedure DisableFavorites; + procedure EnableFavorites; + procedure ParseXML(var cp1: TControlPoint; const params: string; const ignoreErrors : boolean); + function SaveFlame(cp1: TControlPoint; title, filename: string): boolean; + function SaveXMLFlame(const cp1: TControlPoint; title, filename: string): boolean; + procedure DisplayHint(Sender: TObject); + procedure OnProgress(prog: double); + procedure ResizeImage; + procedure DrawPreview; + procedure DrawFlame; + procedure UpdateUndo; + procedure LoadUndoFlame(index: integer; filename: string); + procedure SmoothPalette; + procedure RandomizeCP(var cp1: TControlPoint; alg: integer = 0); + function UPRString(cp1: TControlPoint; Entry: string): string; + function SaveGradient(Gradient, Title, FileName: string): boolean; + function GradientFromPalette(const pal: TColorMap; const title: string): string; + procedure StopThread; + procedure UpdateWindows; + procedure ResetLocation; + procedure RandomBatch; + procedure GetScripts; + function ApplicationOnHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean; + function SystemErrorMessage: string; + function SystemErrorMessage2(errno:cardinal): string; + function RetrieveXML(cp : TControlPoint):string; + end; + +procedure ListXML(FileName: string; sel: integer); +function EntryExists(En, Fl: string): boolean; +function XMLEntryExists(title, filename: string): boolean; +//procedure ComputeWeights(var cp1: TControlPoint; Triangles: TTriangles; t: integer); +function DeleteEntry(Entry, FileName: string): boolean; +function CleanIdentifier(ident: string): string; +function CleanUPRTitle(ident: string): string; +function GradientString(c: TColorMap): string; +//function PackVariations: int64; +//procedure UnpackVariations(v: int64); +//procedure NormalizeWeights(var cp: TControlPoint); +//procedure EqualizeWeights(var cp: TControlPoint); +procedure MultMatrix(var s: TMatrix; const m: TMatrix); +procedure ListFlames(FileName: string; sel: integer); +procedure ListIFS(FileName: string; sel: integer); +procedure NormalizeVariations(var cp1: TControlPoint); +function GetWinVersion: TWin32Version; +function LoadXMLFlameText(filename, name: string) : string; + +var + MainForm: TMainForm; + pname, ptime: String; + nxform: integer; + TbBreakWidth: integer; + + EnumPlugins: Boolean; + MainCp: TControlPoint; + ParseCp: TControlPoint; + CurrentFlame: string; + ThumbnailSize:integer; + UpdateList:TStringList; + UpdateError:boolean; + AboutToExit:boolean; + + AppVersionString:string; //APP_NAME+'.'+APP_VERSION; + +implementation + +uses + Editor, Options, Settings, Template, + FullScreen, FormRender, Mutate, Adjust, Browser, Save, About, CmapData, + {$ifdef DisableScripting} + {$else} + ScriptForm, FormFavorites, + {$endif} + FormExport, RndFlame, Tracer, Types, SplashForm, varGenericPlugin; + +{$R *.DFM} + +procedure AssignBitmapProperly(var Bitmap:TBitmap; Source:TBitmap); +begin + Bitmap.Dormant; + Bitmap.FreeImage; + Bitmap.Width := 0; + Bitmap.Assign(Source); +end; + +procedure FreeBitmapProperly(var Bitmap:TBitmap); +begin + try + Bitmap.Dormant; + Bitmap.FreeImage; + finally + Bitmap.Free; + end; +end; + +procedure NormalizeVariations(var cp1: TControlPoint); +var + totvar: double; + i, j: integer; +begin + for i := 0 to NXFORMS - 1 do + begin + totvar := 0; + for j := 0 to NRVAR - 1 do + begin + if cp1.xform[i].GetVariation(j) < 0 then + cp1.xform[i].SetVariation(j, cp1.xform[i].GetVariation(j) * -1); + totvar := totvar + cp1.xform[i].GetVariation(j); + end; + if totVar = 0 then + begin + cp1.xform[i].SetVariation(0, 1) + end + else + for j := 0 to NRVAR - 1 do begin + if totVar <> 0 then + cp1.xform[i].SetVariation(j, cp1.xform[i].GetVariation(j) / totvar); + end; + end; +end; + +function FlameInClipboard: boolean; +var + flamestr: string; + isstart, isend: integer; +begin + { returns true if a flame in clipboard - can be tricked } + result := false; + if Clipboard.HasFormat(CF_TEXT) then + begin + flamestr := Clipboard.AsText; + isstart := Pos('', flamestr); + if (isstart > 0) and (isend > 0) and (isstart < isend) then Result := true; + end +end; + +procedure MultMatrix(var s: TMatrix; const m: TMatrix); +var + a, b, c, d, e, f, g, h: double; +begin + a := s[0, 0]; + b := s[0, 1]; + c := s[1, 0]; + d := s[1, 1]; + e := m[0, 0]; + f := m[0, 1]; + g := m[1, 0]; + h := m[1, 1]; +{ + [a, b][e ,f] [a*e+b*g, a*f+b*h] + [ ][ ] = [ ] + [c, d][g, h] [c*e+d*g, c*f+d*h] +} + s[0, 0] := a * e + b * g; + s[0, 1] := a * f + b * h; + s[1, 0] := c * e + d * g; + s[1, 1] := c * f + d * h; + +end; + +(* +function PackVariations: int64; +{ Packs the variation options into an integer with Linear as lowest bit } +var + i: integer; +begin + result := 0; + for i := NRVAR-1 downto 0 do + begin + result := (result shl 1) or integer(Variations[i]); + end; +end; + +procedure UnpackVariations(v: int64); +{ Unpacks the variation options form an integer } +var + i: integer; +begin + for i := 0 to NRVAR - 1 do + Variations[i] := boolean(v shr i and 1); +end; +*) + +function GetWinVersion: TWin32Version; +{ Returns current version of a host Win32 platform } +begin + Result := wvUnknown; + if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then + if (Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and (Win32MinorVersion > 0)) then + Result := wvWin98 + else + Result := wvWin95 + else + if Win32MajorVersion <= 4 then + Result := wvWinNT + else if Win32MajorVersion = 5 then + if Win32MinorVersion = 0 then + Result := wvWin2000 + else if Win32MinorVersion >= 1 then + Result := wvWinXP + else if Win32MajorVersion = 6 then + if Win32MinorVersion = 0 then + Result := wvWinVista + else if Win32MinorVersion >= 1 then + Result := wvWin7 + else if Win32MajorVersion >= 7 then + Result := wvWinFutureFromOuterSpace; +end; + +{ ************************************* Help ********************************* } + +procedure ShowHelp(Pt: TPoint; ContextId: Integer); +//var + //Popup: THHPopup; +begin + (* -X- context help not longer supported + FillChar(Popup, SizeOf(Popup), 0); + Popup.cbStruct := SizeOf(Popup); + Popup.hinst := 0; + Popup.idString := ContextId; + Popup.pszText := nil; + GetCursorPos(Pt); + Popup.pt := Pt; + Popup.clrForeGround := TColorRef(-1); + Popup.clrBackground := TColorRef(-1); + Popup.rcMargins := Rect(-1, -1, -1, -1); + Popup.pszFont := ''; + HtmlHelp(0, PChar(AppPath + 'Apophysis7x.chm::/Popups.txt'), HH_DISPLAY_TEXT_POPUP, DWORD(@Popup)); + *) +end; + +procedure TMainForm.RebuildListView; +var + i:integer; + item:TListItem; +begin + ListView.Items.Clear; + + /// backup in old lv + for i := 0 to ListView1.Items.Count-1 do begin + item := ListView.Items.Add; + item.Caption := ListView1.Items[i].Caption; + end; + + // rebuild new lv + ListView1.Items.Clear; + + for i := 0 to ListView.Items.Count-1 do begin + item := ListView1.Items.Add; + item.Caption := ListView.Items[i].Caption; + if (not ClassicListMode) then item.ImageIndex := i; + end; + + ListView.Items.Clear; + + +end; + +procedure TMainForm.InsertStrings; +begin + mnuCopy.Caption := TextByKey('common-copy'); + mnuPaste.Caption := TextByKey('common-paste'); + mnuItemDelete.Caption := TextByKey('common-delete'); + mnuListRename.Caption := TextByKey('common-rename'); + mnuUndo.Caption := TextByKey('common-undo'); + mnuPopUndo.Caption := TextByKey('common-undo'); + btnUndo.Hint := TextByKey('common-undo'); + mnuRedo.Caption := TextByKey('common-redo'); + mnuPopRedo.Caption := TextByKey('common-redo'); + btnRedo.Hint := TextByKey('common-redo'); + MainFile.Caption := TextByKey('main-menu-file-title'); + New1.Caption := TextByKey('main-menu-file-new'); + ToolButton8.Hint := TextByKey('main-menu-file-new'); + mnuOpen.Caption := TextByKey('main-menu-file-open'); + btnOpen.Hint := TextByKey('main-menu-file-open'); + RestoreLastAutosave1.Caption := TextByKey('main-menu-file-restoreautosave'); + mnuSaveAs.Caption := TextByKey('main-menu-file-saveparams'); + btnSave.Hint := TextByKey('main-menu-file-saveparams'); + mnuSaveAllAs.Caption := TextByKey('main-menu-file-saveallparams'); + mnuSmoothGradient.Caption := TextByKey('main-menu-file-smoothpalette'); + mnuOpenGradient.Caption := TextByKey('main-menu-file-gradientbrowser'); + mnuSaveUPR.Caption := TextByKey('main-menu-file-exportupr'); + mnuExportFlame.Caption := TextByKey('main-menu-file-exportflame'); + mnuImportGimp.Caption := TextByKey('main-menu-file-importgimp'); + mnuPostSheep.Caption := TextByKey('main-menu-file-submitsheep'); + mnuRandomBatch.Caption := TextByKey('main-menu-file-randombatch'); + mnuExit.Caption := TextByKey('main-menu-file-exit'); + MainEdit.Caption := TextByKey('main-menu-edit-title'); + mnuSaveUndo.Caption := TextByKey('main-menu-edit-saveundo'); + mnuCopyUPR.Caption := TextByKey('main-menu-edit-copyasupr'); + View1.Caption := TextByKey('main-menu-view-title'); + mnuFullScreen.Caption := TextByKey('main-menu-view-fullscreen'); + mnuPopFullscreen.Caption := TextByKey('main-menu-view-fullscreen'); + btnFullScreen.Hint := TextByKey('main-menu-view-fullscreen'); + mnuEditor.Caption := TextByKey('main-menu-view-editor'); + ToolButton5.Hint := TextByKey('main-menu-view-editor'); + mnuAdjust.Caption := TextByKey('main-menu-view-adjustment'); + ToolButton6.Hint := TextByKey('main-menu-view-adjustment'); + mnuGrad.Caption := TextByKey('main-menu-view-gradient'); + ToolButton7.Hint := TextByKey('main-menu-view-gradient'); + mnuMutate.Caption := TextByKey('main-menu-view-mutation'); + ToolButton11.Hint := TextByKey('main-menu-view-mutation'); + mnuImageSize.Caption := TextByKey('main-menu-view-imagesize'); + ToolButton12.Hint := TextByKey('main-menu-view-imagesize'); + mnuMessages.Caption := TextByKey('main-menu-view-messages'); + toolButton13.Hint := TextByKey('main-menu-view-messages'); + ToolButton19.Hint := TextByKey('main-menu-view-curves'); + mnuCurves.Caption := TextByKey('main-menu-view-curves'); + F1.Caption := TextByKey('main-menu-flame-title'); + mnuResetLocation.Caption := TextByKey('main-menu-flame-reset'); + mnuPopResetLocation.Caption := TextByKey('main-menu-flame-reset'); + btnReset.Hint := TextByKey('main-menu-flame-reset'); + mnuRandom.Caption := TextByKey('main-menu-flame-randomize'); + mnuRWeights.Caption := TextByKey('main-menu-flame-randomweights'); + mnuEqualize.Caption := TextByKey('main-menu-flame-equalweights'); + mnuNormalWeights.Caption := TextByKey('main-menu-flame-computeweights'); + mnuCalculateColors.Caption := TextByKey('main-menu-flame-calculatecolors'); + mnuRandomizeColorValues.Caption := TextByKey('main-menu-flame-randomizecolors'); + mnuRender.Caption := TextByKey('main-menu-flame-rendertodisk'); + btnRender.Hint := TextByKey('main-menu-flame-rendertodisk'); + mnuRenderAll.Caption := TextByKey('main-menu-flame-renderallflames'); + tbRenderAll.Hint := TextByKey('main-menu-flame-renderallflames'); + mnuReportFlame.Caption := TextByKey('main-menu-flame-generatereport'); + mnuVar.Caption := TextByKey('main-menu-variation-title'); + mnuVRandom.Caption := TextByKey('main-menu-variation-random'); + mnuBuiltinVars.Caption := TextByKey('main-menu-variation-builtin'); + mnuPluginVars.Caption := TextByKey('main-menu-variation-plugins'); + mnuScript.Caption := TextByKey('main-menu-script-title'); + mnuRun.Caption := TextByKey('main-menu-script-run'); + btnRunScript.Hint := TextByKey('main-menu-script-run'); + mnuStop.Caption := TextByKey('main-menu-script-stop'); + btnStopScript.Hint := TextByKey('main-menu-script-stop'); + mnuOpenScript.Caption := TextByKey('main-menu-script-open'); + mnuEditScript.Caption := TextByKey('main-menu-script-edit'); + ToolButton17.Hint := TextByKey('main-menu-script-edit'); + mnuManageFavorites.Caption := TextByKey('main-menu-script-managefaves'); + mnuTurnFlameToScript.Caption := TextByKey('main-menu-script-flametoscript'); + mnuView.Caption := TextByKey('main-menu-options-title'); + mnuToolbar.Caption := TextByKey('main-menu-options-togglemaintoolbar'); + mnuStatusBar.Caption := TextByKey('main-menu-options-togglestatusbar'); + mnuFileContents.Caption := TextByKey('main-menu-options-togglefilelist'); + mnuResetUI.Caption := TextByKey('main-menu-options-resetfilelistwidth'); + mnuOptions.Caption := TextByKey('main-menu-options-showoptions'); + ToolButton14.Hint := TextByKey('main-menu-options-showoptions'); + MainHelp.Caption := TextByKey('main-menu-help-title'); + mnuHelpTopics.Caption := TextByKey('main-menu-help-contents'); + mnuFlamePDF.Caption := TextByKey('main-menu-help-aboutalgorithm'); + mnuAbout.Caption := TextByKey('main-menu-help-aboutapophysis'); + btnViewList.Hint := TextByKey('main-toolbar-listviewmode-classic'); + btnViewIcons.Hint := TextByKey('main-toolbar-listviewmode-icons'); + tbShowAlpha.Hint := TextByKey('main-toolbar-togglealpha'); + tbGuides.Hint := TextByKey('main-toolbar-toggleguides'); + tbDraw.Hint := TextByKey('main-toolbar-modemove'); + ToolButton20.Hint := TextByKey('main-toolbar-moderotate'); + ToolButton21.Hint := TextByKey('main-toolbar-modezoomin'); + ToolButton22.Hint := TextByKey('main-toolbar-modezoomout'); + ListView1.Columns[0].Caption := TextByKey('save-name'); + mnuResumeRender.Caption := TextByKey('main-menu-flame-resumeunfinished'); +end; + +procedure TMainForm.InvokeLoadXML(xmltext:string); +begin + ParseXML(MainCP, PCHAR(xmltext), false); +end; + +function TMainForm.ApplicationOnHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean; +var + Pos: TPoint; +begin + Pos.x := 0; + Pos.y := 0; + + CallHelp := False; + Result := True; + case Command of + HELP_SETPOPUP_POS: Pos := SmallPointToPoint(TSmallPoint(Data)); + HELP_CONTEXTPOPUP: ShowHelp(Pos, Data); + else Result := False; + end; +end; + +{ **************************************************************************** } + +procedure TMainForm.StopThread; +begin + RedrawTimer.Enabled := False; + if Assigned(Renderer) then begin + assert(Renderer.Suspended = false); + Renderer.Terminate; + Renderer.WaitFor; + end; +end; + +procedure EqualizeVars(const x: integer); +var + i: integer; +begin + for i := 0 to Transforms - 1 do + MainCp.xform[x].SetVariation(i, 1.0 / NRVAR); +end; + +procedure NormalVars(const x: integer); +var + i: integer; + td: double; +begin + td := 0.0; + for i := 0 to 6 do + td := td + Maincp.xform[x].GetVariation(i); + if (td < 0.001) then + EqualizeVars(x) + else + for i := 0 to 6 do + MainCp.xform[x].SetVariation(i, MainCp.xform[x].GetVariation(i) / td); +end; + +procedure RandomVariation(cp: TControlPoint); +{ Randomise variation parameters } +var + a, b, i, j: integer; +begin + inc(MainSeed); + RandSeed := MainSeed; + for i := 0 to cp.NumXForms - 1 do + begin + for j := 0 to NRVAR - 1 do + cp.xform[i].SetVariation(j, 0); + repeat + a := random(NRVAR); + until Variations[a]; + repeat + b := random(NRVAR); + until Variations[b]; + if (a = b) then + begin + cp.xform[i].SetVariation(a, 1); + end + else + begin + cp.xform[i].SetVariation(a, random); + cp.xform[i].SetVariation(b, 1 - cp.xform[i].GetVariation(a)); + end; + end; +end; + +procedure SetVariation(cp: TControlPoint); +{ Set the current Variation } +var + i, j: integer; +begin + if Variation = vRandom then + begin + RandomVariation(cp); + end + else + for i := 0 to cp.NumXForms - 1 do + begin + for j := 0 to NRVAR - 1 do + cp.xform[i].SetVariation(j, 0); + cp.xform[i].SetVariation(integer(Variation), 1); + end; +end; + +procedure TMainForm.RandomizeCP(var cp1: TControlPoint; alg: integer = 0); +(* +var + vrnd, Min, Max, i, j, rnd: integer; + Triangles: TTriangles; + cmap: TColorMap; + r, s, theta, phi: double; + skip: boolean; +*) +var + sourceCP: TControlPoint; +begin + if assigned(MainCP) then + sourceCP := MainCP.Clone + else + SourceCP := nil; + + if assigned(cp1) then begin + cp1.Free; + cp1 := nil; + end; + cp1 := RandomFlame(sourceCP, alg); + + if assigned(sourceCP) then + sourceCP.Free; + +(* + Min := randMinTransforms; + Max := randMaxTransforms; + case randGradient of + 0: + begin + cp1.CmapIndex := Random(NRCMAPS); + GetCMap(cmap_index, 1, cp1.cmap); + cmap_index := cp1.cmapindex; + end; + 1: cmap := DefaultPalette; + 2: cmap := MainCp.cmap; + 3: cmap := GradientForm.RandomGradient; + end; + inc(MainSeed); + RandSeed := MainSeed; + transforms := random(Max - (Min - 1)) + Min; + repeat + try + inc(MainSeed); + RandSeed := MainSeed; + cp1.clear; + cp1.RandomCP(transforms, transforms, false); + cp1.SetVariation(Variation); + inc(MainSeed); + RandSeed := MainSeed; + + case alg of + 1: rnd := 0; + 2: rnd := 7; + 3: rnd := 9; + else + if (Variation = vLinear) or (Variation = vRandom) then + rnd := random(10) + else + rnd := 9; + end; + case rnd of + 0..6: + begin + for i := 0 to Transforms - 1 do + begin + if Random(10) < 9 then + cp1.xform[i].c[0, 0] := 1 + else + cp1.xform[i].c[0, 0] := -1; + cp1.xform[i].c[0, 1] := 0; + cp1.xform[i].c[1, 0] := 0; + cp1.xform[i].c[1, 1] := 1; + cp1.xform[i].c[2, 0] := 0; + cp1.xform[i].c[2, 1] := 0; + cp1.xform[i].color := 0; + cp1.xform[i].symmetry := 0; + cp1.xform[i].vars[0] := 1; + for j := 1 to NVARS - 1 do + cp1.xform[i].vars[j] := 0; + Translate(cp1.xform[i], random * 2 - 1, random * 2 - 1); + Rotate(cp1.xform[i], random * 360); + if i > 0 then Scale(cp1.xform[i], random * 0.8 + 0.2) + else Scale(cp1.xform[i], random * 0.4 + 0.6); + if Random(2) = 0 then + Multiply(cp1.xform[i], 1, random - 0.5, random - 0.5, 1); + end; + SetVariation(cp1); + end; + 7, 8: + begin + { From the source to Chaos: The Software } + for i := 0 to Transforms - 1 do + begin + r := random * 2 - 1; + if ((0 <= r) and (r < 0.2)) then + r := r + 0.2; + if ((r > -0.2) and (r <= 0)) then + r := r - 0.2; + s := random * 2 - 1; + if ((0 <= s) and (s < 0.2)) then + s := s + 0.2; + if ((s > -0.2) and (s <= 0)) then + s := s - -0.2; + theta := PI * random; + phi := (2 + random) * PI / 4; + cp1.xform[i].c[0][0] := r * cos(theta); + cp1.xform[i].c[1][0] := s * (cos(theta) * cos(phi) - sin(theta)); + cp1.xform[i].c[0][1] := r * sin(theta); + cp1.xform[i].c[1][1] := s * (sin(theta) * cos(phi) + cos(theta)); + { the next bit didn't translate so well, so I fudge it} + cp1.xform[i].c[2][0] := random * 2 - 1; + cp1.xform[i].c[2][1] := random * 2 - 1; + end; + for i := 0 to NXFORMS - 1 do + cp1.xform[i].density := 0; + for i := 0 to Transforms - 1 do + cp1.xform[i].density := 1 / Transforms; + SetVariation(cp1); + end; + 9: begin + for i := 0 to NXFORMS - 1 do + cp1.xform[i].density := 0; + for i := 0 to Transforms - 1 do + cp1.xform[i].density := 1 / Transforms; + end; + end; // case + MainForm.TrianglesFromCp(cp1, Triangles); + vrnd := Random(2); + if vrnd > 0 then + ComputeWeights(cp1, Triangles, transforms) + else + EqualizeWeights(cp1); + except on E: EmathError do + begin + Continue; + end; + end; + for i := 0 to Transforms - 1 do + cp1.xform[i].color := i / (transforms - 1); + if cp1.xform[0].density = 1 then Continue; + case SymmetryType of + { Bilateral } + 1: add_symmetry_to_control_point(cp1, -1); + { Rotational } + 2: add_symmetry_to_control_point(cp1, SymmetryOrder); + { Rotational and Reflective } + 3: add_symmetry_to_control_point(cp1, -SymmetryOrder); + end; + { elimate flames with transforms that aren't affine } + skip := false; + for i := 0 to Transforms - 1 do + if not transform_affine(Triangles[i], Triangles) then + skip := True; + if skip then continue; + until not cp1.BlowsUP(5000) and (cp1.xform[0].density <> 0); + cp1.brightness := defBrightness; + cp1.gamma := defGamma; + cp1.vibrancy := defVibrancy; + cp1.sample_density := defSampleDensity; + cp1.spatial_oversample := defOversample; + cp1.spatial_filter_radius := defFilterRadius; + cp1.cmapIndex := MainCp.cmapindex; + if not KeepBackground then begin + cp1.background[0] := 0; + cp1.background[1] := 0; + cp1.background[2] := 0; + end; + if randGradient = 0 then + else cp1.cmap := cmap; + cp1.zoom := 0; + cp1.Nick := SheepNick; + cp1.URl := SheepURL; +*) +end; + +function TMainForm.GradientFromPalette(const pal: TColorMap; const title: string): string; +var + c, i, j: integer; + strings: TStringList; +begin + strings := TStringList.Create; + try + strings.add('gradient:'); + strings.add(' title="' + CleanUPRTitle(title) + '" smooth=no'); + for i := 0 to 255 do + begin + j := round(i * (399 / 255)); + c := pal[i][2] shl 16 + pal[i][1] shl 8 + pal[i][0]; + strings.Add(' index=' + IntToStr(j) + ' color=' + intToStr(c)); + end; + result := strings.text; + finally + strings.free; + end; +end; + +function CleanIdentifier(ident: string): string; +{ Strips unwanted characters from an identifier} +var + i: integer; +begin + for i := 0 to Length(ident) do + begin + if ident[i] = #32 then + ident[i] := '_' + else if ident[i] = '}' then + ident[i] := '_' + else if ident[i] = '{' then + ident[i] := '_'; + end; + Result := ident; +end; + +procedure TMainForm.OnProgress(prog: double); +var + Elapsed, Remaining: TDateTime; + IntProg: Integer; +begin + IntProg := (round(prog * 100)); + //pnlLSPFrame.Visible := true; + LoadSaveProgress.Position := IntProg; + if (IntProg = 100) then LoadSaveProgress.Position := 0; + Elapsed := Now - StartTime; + StatusBar.Panels[1].Text := Format(TextByKey('render-status-elapsed') + ' %2.2d:%2.2d:%2.2d.%2.2d', + [Trunc(Elapsed * 24), + Trunc((Elapsed * 24 - Trunc(Elapsed * 24)) * 60), + Trunc((Elapsed * 24 * 60 - Trunc(Elapsed * 24 * 60)) * 60), + Trunc((Elapsed * 24 * 60 * 60 - Trunc(Elapsed * 24 * 60 * 60)) * 100)]); + if prog > 0 then + Remaining := Elapsed/prog - Elapsed + else + Remaining := 0; + + StatusBar.Panels[2].Text := Format(TextByKey('render-status-remaining') + ' %2.2d:%2.2d:%2.2d.%2.2d', + [Trunc(Remaining * 24), + Trunc((Remaining * 24 - Trunc(Remaining * 24)) * 60), + Trunc((Remaining * 24 * 60 - Trunc(Remaining * 24 * 60)) * 60), + Trunc((Remaining * 24 * 60 * 60 - Trunc(Remaining * 24 * 60 * 60)) * 100)]); + StatusBar.Panels[3].Text := MainCp.name; + Application.ProcessMessages; +end; + +procedure TMainForm.UpdateUndo; +begin + MainCp.FillUsedPlugins; + SaveFlame(MainCp, Format('%.4d-', [UndoIndex]) + MainCp.name, + GetEnvVarValue('APPDATA') + '\' + undoFilename); + Inc(UndoIndex); + UndoMax := UndoIndex; //Inc(UndoMax); + mnuSaveUndo.Enabled := true; + mnuUndo.Enabled := True; + mnuPopUndo.Enabled := True; + mnuRedo.Enabled := false; + mnuPopRedo.Enabled := false; + btnUndo.enabled := true; + btnRedo.Enabled := false; + EditForm.mnuUndo.Enabled := True; + EditForm.mnuRedo.Enabled := false; + EditForm.tbUndo.enabled := true; + EditForm.tbRedo.enabled := false; + AdjustForm.btnUndo.enabled := true; + AdjustForm.btnRedo.enabled := false; +end; + +function GradientEntries(gFilename: string): string; +var + i, p: integer; + Title: string; + FileStrings: TStringList; + NewStrings: TStringList; +begin + FileStrings := TStringList.Create; + NewStrings := TStringList.Create; + NewStrings.Text := ''; + FileStrings.LoadFromFile(gFilename); + try + if (Pos('{', FileStrings.Text) <> 0) then + begin + for i := 0 to FileStrings.Count - 1 do + begin + p := Pos('{', FileStrings[i]); + if (p <> 0) then + begin + Title := Trim(Copy(FileStrings[i], 1, p - 1)); + if (Title <> '') and (LowerCase(Title) <> 'comment') then + begin { Otherwise bad format } + NewStrings.Add(Title); + end; + end; + end; + GradientEntries := NewStrings.Text; + end; + finally + FileStrings.Free; + NewStrings.Free; + end; +end; + +{ ********************************* File ************************************* } + +function EntryExists(En, Fl: string): boolean; +{ Searches for existing identifier in parameter files } +var + FStrings: TStringList; + i: integer; +begin + Result := False; + if FileExists(Fl) then + begin + FStrings := TStringList.Create; + try + FStrings.LoadFromFile(Fl); + for i := 0 to FStrings.Count - 1 do + if Pos(LowerCase(En) + ' {', Lowercase(FStrings[i])) <> 0 then + Result := True; + finally + FStrings.Free; + end + end + else + Result := False; +end; + +function CleanEntry(ident: string): string; +{ Strips unwanted characters from an identifier} +var + i: integer; +begin + for i := 1 to Length(ident) do + begin + if ident[i] = #32 then + ident[i] := '_' + else if ident[i] = '}' then + ident[i] := '_' + else if ident[i] = '{' then + ident[i] := '_'; + end; + Result := ident; +end; + +function CleanXMLName(ident: string): string; +var + i: integer; +begin + for i := 1 to Length(ident) do + begin + if ident[i] = '*' then + ident[i] := '_' + else if ident[i] = '"' then + ident[i] := #39; + end; + Result := ident; +end; + + +function CleanUPRTitle(ident: string): string; +{ Strips braces but leave spaces } +var + i: integer; +begin + for i := 1 to Length(ident) do + begin + if ident[i] = '}' then + ident[i] := '_' + else if ident[i] = '{' then + ident[i] := '_'; + end; + Result := ident; +end; + +function DeleteEntry(Entry, FileName: string): boolean; +{ Deletes an entry from a multi-entry file } +var + Strings: TStringList; + p, i: integer; +begin + Result := True; + Strings := TStringList.Create; + try + i := 0; + Strings.LoadFromFile(FileName); + while Pos(Entry + ' ', Trim(Strings[i])) <> 1 do + begin + inc(i); + end; + repeat + p := Pos('}', Strings[i]); + Strings.Delete(i); + until p <> 0; + if (i < Strings.Count) and (Trim(Strings[i]) = '') then Strings.Delete(i); + Strings.SaveToFile(FileName); + finally + Strings.Free; + end; +end; + +function SaveUPR(Entry, FileName: string): boolean; +{ Saves UF parameter to end of file } +var + UPRFile: TextFile; +begin + Result := True; + try + AssignFile(UPRFile, FileName); + if FileExists(FileName) then + begin + if EntryExists(Entry, FileName) then DeleteEntry(Entry, FileName); + Append(UPRFile); + end + else + ReWrite(UPRFile); + WriteLn(UPRFile, MainForm.UPRString(MainCp, Entry)); + CloseFile(UPRFile); + except on E: EInOutError do + begin + Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16); + Result := False; + end; + end; +end; + +function IFSToString(cp: TControlPoint; Title: string): string; +{ Creates a string containing a formated IFS parameter set } +var + i: integer; + a, b, c, d, e, f, p: double; + Strings: TStringList; +begin + Strings := TStringList.Create; + try + Strings.Add(CleanEntry(Title) + ' {'); + for i := 0 to Transforms - 1 do + begin + a := cp.xform[i].c[0][0]; + b := cp.xform[i].c[0][1]; + c := cp.xform[i].c[1][0]; + d := cp.xform[i].c[1][1]; + e := cp.xform[i].c[2][0]; + f := cp.xform[i].c[2][1]; + p := cp.xform[i].density; + Strings.Add(Format('%.6g %.6g %.6g %.6g %.6g %.6g %.6g', + [a, b, c, d, e, f, p])); + end; + Strings.Add('}'); + IFSToString := Strings.Text; + finally + Strings.Free; + end; +end; + +function GetTitle(str: string): string; +var + p: integer; +begin + str := Trim(str); + p := Pos(' ', str); + GetTitle := Trim(Copy(str, 1, p)); +end; + +function GetComment(str: string): string; +{ Extracts comment form line of IFS file } +var + p: integer; +begin + str := Trim(str); + p := Pos(';', str); + if p <> 0 then + GetComment := Trim(Copy(str, p + 1, Length(str) - p)) + else + GetComment := ''; +end; + +function GetParameters(str: string; var a, b, c, d, e, f, p: double): boolean; +var + Tokens: TStringList; +begin + GetParameters := False; + Tokens := TStringList.Create; + try + try + GetTokens(str, tokens); + if Tokens.Count >= 7 then {enough tokens} + begin + a := StrToFloat(Tokens[0]); + b := StrToFloat(Tokens[1]); + c := StrToFloat(Tokens[2]); + d := StrToFloat(Tokens[3]); + e := StrToFloat(Tokens[4]); + f := StrToFloat(Tokens[5]); + p := StrToFloat(Tokens[6]); + Result := True; + end; + except on E: EConvertError do + begin + Result := False + end; + end; + finally + Tokens.Free; + end; +end; + +function StringToIFS(strng: string): boolean; +{ Loads an IFS parameter set from string} +var + Strings: TStringList; + Comments: TStringList; + i, sTransforms: integer; + cmnt, sTitle: string; + a, b, c, d: double; + e, f, p: double; +begin + MainCp.clear; + StringToIFS := True; + sTransforms := 0; + Strings := TStringList.Create; + Comments := TStringList.Create; + try + try + Strings.Text := strng; + if Pos('}', Strings.Text) = 0 then + raise EFormatInvalid.Create('No closing brace'); + if Pos('{', Strings[0]) = 0 then + raise EFormatInvalid.Create('No opening brace.'); + {To Do ... !!!!} + sTitle := GetTitle(Strings[0]); + if sTitle = '' then raise EFormatInvalid.Create('No identifier.'); + cmnt := GetComment(Strings[0]); + if cmnt <> '' then Comments.Add(cmnt); + i := 1; + try + repeat + cmnt := GetComment(Strings[i]); + if cmnt <> '' then Comments.Add(cmnt); + if (Pos(';', Trim(Strings[i])) <> 1) and (Trim(Strings[i]) <> '') then + if GetParameters(Strings[i], a, b, c, d, e, f, p) then + begin + MainCp.xform[sTransforms].c[0][0] := a; + MainCp.xform[sTransforms].c[0][1] := c; + MainCp.xform[sTransforms].c[1][0] := b; + MainCp.xform[sTransforms].c[1][1] := d; + MainCp.xform[sTransforms].c[2][0] := e; + MainCp.xform[sTransforms].c[2][1] := f; + MainCp.xform[sTransforms].density := p; + inc(sTransforms); + end + else + EFormatInvalid.Create('Insufficient parameters.'); + inc(i); + until (Pos('}', Strings[i]) <> 0) or (sTransforms = NXFORMS); + except on E: EMathError do + end; + if sTransforms < 2 then + raise EFormatInvalid.Create('Insufficient parameters.'); + MainCp.name := sTitle; + Transforms := sTransforms; + for i := 1 to Transforms - 1 do + MainCp.xform[i].color := 0; + MainCp.xform[0].color := 1; + + except on E: EFormatInvalid do + begin + Application.MessageBox(PChar(TextByKey('common-invalidformat')), PChar('Apophysis'), 16); + end; + end; + finally + Strings.Free; + Comments.Free; + end; +end; + + +function SaveIFS(cp: TControlPoint; Title, FileName: string): boolean; +{ Saves IFS parameters to end of file } +var + a, b, c: double; + d, e, f, p: double; + m: integer; + IFile: TextFile; +begin + Result := True; + try + AssignFile(IFile, FileName); + if FileExists(FileName) then + begin + if EntryExists(Title, FileName) then DeleteEntry(Title, FileName); + Append(IFile); + end + else + ReWrite(IFile); + WriteLn(IFile, Title + ' {'); + for m := 0 to Transforms - 1 do + begin + a := cp.xform[m].c[0][0]; + c := cp.xform[m].c[0][1]; + b := cp.xform[m].c[1][0]; + d := cp.xform[m].c[1][1]; + e := cp.xform[m].c[2][0]; + f := cp.xform[m].c[2][1]; + p := cp.xform[m].density; + Write(IFile, Format('%.6g %.6g %.6g %.6g %.6g %.6g %.6g', + [a, b, c, d, e, f, p])); + WriteLn(IFile, ''); + end; + WriteLn(IFile, '}'); + WriteLn(IFile, ' '); + CloseFile(IFile); + except on E: EInOutError do + begin + Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16); + Result := False; + end; + end; +end; + +function TMainForm.SaveFlame(cp1: TControlPoint; title, filename: string): boolean; +{ Saves Flame parameters to end of file } +var + IFile: TextFile; + sl: TStringList; + i: integer; +begin + Result := True; + try + AssignFile(IFile, filename); + if FileExists(filename) then + begin + if EntryExists(title, filename) then DeleteEntry(title, fileName); + Append(IFile); + end + else ReWrite(IFile); + + sl := TStringList.Create; + try + cp1.SaveToStringList(sl); + WriteLn(IFile, title + ' {'); + write(IFile, sl.Text); + WriteLn(IFile, 'palette:'); + for i := 0 to 255 do + begin + WriteLn(IFile, IntToStr(cp1.cmap[i][0]) + ' ' + + IntToStr(cp1.cmap[i][1]) + ' ' + + IntToStr(cp1.cmap[i][2])) + end; + WriteLn(IFile, ' }'); + finally + sl.free + end; + WriteLn(IFile, ' '); + CloseFile(IFile); + + except on EInOutError do + begin + Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16); + Result := False; + end; + end; +end; + +function ColorToXmlCompact(cp1: TControlPoint): string; +var + i: integer; +begin + Result := ' '; + for i := 0 to 255 do begin + if ((i and 7) = 0) then Result := Result + #13#10 + ' '; + Result := Result + IntToHex(cp1.cmap[i, 0],2) + + IntToHex(cp1.cmap[i, 1],2) + + IntToHex(cp1.cmap[i, 2],2); + end; + Result := Result + #13#10 + ' '; +end; + + +function ColorToXml(cp1: TControlPoint): string; +var + i: integer; +begin + Result := ''; + for i := 0 to 255 do begin + Result := Result + ' ' + #13#10; + end; +end; + + +function FlameToXMLAS(const cp1: TControlPoint; title: string; exporting: boolean): string; +var + t, i{, j}: integer; + FileList: TStringList; + x, y: double; + parameters: string; + curves, str: string; +begin + FileList := TStringList.create; + x := cp1.center[0]; + y := cp1.center[1]; + +// if cp1.cmapindex >= 0 then pal := pal + 'gradient="' + IntToStr(cp1.cmapindex) + '" '; + + try + parameters := 'version="' + AppVersionString + '" '; + if cp1.time <> 0 then + parameters := parameters + format('time="%g" ', [cp1.time]); + + parameters := parameters + + 'size="' + IntToStr(cp1.width) + ' ' + IntToStr(cp1.height) + + format('" center="%g %g" ', [x, y]) + + format('scale="%g" ', [cp1.pixels_per_unit]); + + if cp1.FAngle <> 0 then + parameters := parameters + format('angle="%g" ', [cp1.FAngle]) + + format('rotate="%g" ', [-180 * cp1.FAngle/Pi]); + if cp1.zoom <> 0 then + parameters := parameters + format('zoom="%g" ', [cp1.zoom]); + +// 3d + if cp1.cameraPitch <> 0 then + parameters := parameters + format('cam_pitch="%g" ', [cp1.cameraPitch]); + if cp1.cameraYaw <> 0 then + parameters := parameters + format('cam_yaw="%g" ', [cp1.cameraYaw]); + if cp1.cameraPersp <> 0 then + parameters := parameters + format('cam_perspective="%g" ', [cp1.cameraPersp]); + if cp1.cameraZpos <> 0 then + parameters := parameters + format('cam_zpos="%g" ', [cp1.cameraZpos]); + if cp1.cameraDOF <> 0 then + parameters := parameters + format('cam_dof="%g" ', [cp1.cameraDOF]); +// + parameters := parameters + format( + 'oversample="%d" filter="%g" quality="%g" ', + [cp1.spatial_oversample, + cp1.spatial_filter_radius, + cp1.sample_density] + ); + if cp1.nbatches <> 1 then parameters := parameters + 'batches="' + IntToStr(cp1.nbatches) + '" '; + + parameters := parameters + + format('background="%g %g %g" ', [cp1.background[0] / 255, cp1.background[1] / 255, cp1.background[2] / 255]) + + format('brightness="%g" ', [cp1.brightness]) + + format('gamma="%g" ', [cp1.gamma]); + + if cp1.vibrancy <> 1 then + parameters := parameters + format('vibrancy="%g" ', [cp1.vibrancy]); + + if cp1.gamma_threshold <> 0 then + parameters := parameters + format('gamma_threshold="%g" ', [cp1.gamma_threshold]); + + if cp1.soloXform >= 0 then + parameters := parameters + format('soloxform="%d" ', [cp1.soloXform]); + + parameters := parameters + + format('estimator_radius="%g" ', [cp1.estimator]) + + format('estimator_minimum="%g" ', [cp1.estimator_min]) + + format('estimator_curve="%g" ', [cp1.estimator_curve]); + if (cp1.enable_de) then + parameters := parameters + ('enable_de="1" ') + else parameters := parameters + ('enable_de="0" '); + + str := ''; + for i := 0 to cp1.used_plugins.Count-1 do begin + str := str + cp1.used_plugins[i]; + if (i = cp1.used_plugins.Count-1) then break; + str := str + ' '; + end; + parameters := parameters + format('plugins="%s" new_linear="1" ', [str]); + + for i := 0 to 3 do + begin + curves := curves + FloatToStr(cp1.curvePoints[i][0].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][0].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][0]) + ' '; + + curves := curves + FloatToStr(cp1.curvePoints[i][1].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][1].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][1]) + ' '; + + curves := curves + FloatToStr(cp1.curvePoints[i][2].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][2].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][2]) + ' '; + + curves := curves + FloatToStr(cp1.curvePoints[i][3].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][3].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][3]) + ' '; + end; + + curves := trim(curves); + parameters := parameters + format('curves="%s" ', [curves]); + + FileList.Add(''); + { Write transform parameters } + t := cp1.NumXForms; + for i := 0 to t - 1 do + FileList.Add(cp1.xform[i].ToXMLString); + if cp1.HasFinalXForm then + begin + // 'enabled' flag disabled in this release + FileList.Add(cp1.xform[t].FinalToXMLString(cp1.finalXformEnabled)); + end; + + { Write palette data } + if exporting or OldPaletteFormat then + FileList.Add(ColorToXml(cp1)) + else + FileList.Add(ColorToXmlCompact(cp1)); + + FileList.Add(''); + result := FileList.text; + finally + FileList.free + end; +end; + +function GetThumbnailBase64(const cp1: TControlPoint) : string; +var + st: TMemoryStream; + tempcp : TControlPoint; + render : TRenderer; + buffer : array of byte; + base64 : string; + size : integer; + bmp : TJPegImage; + w, h, r: double; +begin + w := cp1.Width; h := cp1.Height; r := w / h; + if (w < h) then begin + w := r * ThumbnailSize; + h := ThumbnailSize; + end else if (w > h) then begin + h := ThumbnailSize / r; + w := ThumbnailSize; + end else begin + w := ThumbnailSize; + h := ThumbnailSize; + end; + + render := TRenderer.Create; + tempcp := TControlPoint.create; + tempcp.Copy(cp1); + + tempcp.AdjustScale(round(w), round(h)); + tempcp.Width := round(w); + tempcp.Height := round(h); + tempcp.spatial_oversample := defOversample; + tempcp.spatial_filter_radius := defFilterRadius; + tempcp.sample_density := 10; + + render.SetCP(tempcp); + render.Render; + + st := TMemoryStream.Create; + bmp := TJpegImage.Create; + bmp.Assign(render.GetImage); + bmp.SaveToStream(st); + size := st.Size; + SetLength(buffer, size); + st.Seek(0, soBeginning); + + st.ReadBuffer(buffer[0], length(buffer)); + base64 := B64Encode(TBinArray(buffer), length(buffer)); + + tempcp.Free; + render.Free; + st.Free; + bmp.Free; + + result := base64; +end; + +function FlameToXML(const cp1: TControlPoint; exporting, embedthumb: boolean): String; +var + t, i{, j}, pos: integer; + FileList: TStringList; + x, y: double; + parameters: string; + curves, str, buf, xdata: string; +begin + FileList := TStringList.create; + x := cp1.center[0]; + y := cp1.center[1]; + +// if cp1.cmapindex >= 0 then pal := pal + 'gradient="' + IntToStr(cp1.cmapindex) + '" '; + + try + parameters := 'version="' + AppVersionString + '" '; + if cp1.time <> 0 then + parameters := parameters + format('time="%g" ', [cp1.time]); + + parameters := parameters + + 'size="' + IntToStr(cp1.width) + ' ' + IntToStr(cp1.height) + + format('" center="%g %g" ', [x, y]) + + format('scale="%g" ', [cp1.pixels_per_unit]); + + if cp1.FAngle <> 0 then + parameters := parameters + format('angle="%g" ', [cp1.FAngle]) + // !?!?!? + format('rotate="%g" ', [-180 * cp1.FAngle/Pi]); + if cp1.zoom <> 0 then + parameters := parameters + format('zoom="%g" ', [cp1.zoom]); + +// 3d + if cp1.cameraPitch <> 0 then + parameters := parameters + format('cam_pitch="%g" ', [cp1.cameraPitch]); + if cp1.cameraYaw <> 0 then + parameters := parameters + format('cam_yaw="%g" ', [cp1.cameraYaw]); + if cp1.cameraPersp <> 0 then + parameters := parameters + format('cam_perspective="%g" ', [cp1.cameraPersp]); + if cp1.cameraZpos <> 0 then + parameters := parameters + format('cam_zpos="%g" ', [cp1.cameraZpos]); + if cp1.cameraDOF <> 0 then + parameters := parameters + format('cam_dof="%g" ', [cp1.cameraDOF]); +// + parameters := parameters + format( + 'oversample="%d" filter="%g" quality="%g" ', + [cp1.spatial_oversample, + cp1.spatial_filter_radius, + cp1.sample_density] + ); + if cp1.nbatches <> 1 then parameters := parameters + 'batches="' + IntToStr(cp1.nbatches) + '" '; + + parameters := parameters + + format('background="%g %g %g" ', [cp1.background[0] / 255, cp1.background[1] / 255, cp1.background[2] / 255]) + + format('brightness="%g" ', [cp1.brightness]) + + format('gamma="%g" ', [cp1.gamma]); + + if cp1.vibrancy <> 1 then + parameters := parameters + format('vibrancy="%g" ', [cp1.vibrancy]); + + if cp1.gamma_threshold <> 0 then + parameters := parameters + format('gamma_threshold="%g" ', [cp1.gamma_threshold]); + + if cp1.soloXform >= 0 then + parameters := parameters + format('soloxform="%d" ', [cp1.soloXform]); + + // + parameters := parameters + + format('estimator_radius="%g" ', [cp1.estimator]) + + format('estimator_minimum="%g" ', [cp1.estimator_min]) + + format('estimator_curve="%g" ', [cp1.estimator_curve]); + if exporting then parameters := parameters + + format('temporal_samples="%d" ', [cp1.jitters]); + if (cp1.enable_de) then + parameters := parameters + ('enable_de="1" ') + else parameters := parameters + ('enable_de="0" '); + + str := ''; + for i := 0 to cp1.used_plugins.Count-1 do begin + str := str + cp1.used_plugins[i]; + if (i = cp1.used_plugins.Count-1) then break; + str := str + ' '; + end; + parameters := parameters + format('plugins="%s" new_linear="1" ', [str]); + + for i := 0 to 3 do + begin + curves := curves + FloatToStr(cp1.curvePoints[i][0].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][0].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][0]) + ' '; + + curves := curves + FloatToStr(cp1.curvePoints[i][1].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][1].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][1]) + ' '; + + curves := curves + FloatToStr(cp1.curvePoints[i][2].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][2].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][2]) + ' '; + + curves := curves + FloatToStr(cp1.curvePoints[i][3].x) + ' '; + curves := curves + FloatToStr(cp1.curvePoints[i][3].y) + ' '; + curves := curves + FloatToStr(cp1.curveWeights[i][3]) + ' '; + end; + + curves := trim(curves); + parameters := parameters + format('curves="%s" ', [curves]); + + FileList.Add(''); + { Write transform parameters } + t := cp1.NumXForms; + for i := 0 to t - 1 do + FileList.Add(cp1.xform[i].ToXMLString); + if cp1.HasFinalXForm then + begin + // 'enabled' flag disabled in this release + FileList.Add(cp1.xform[t].FinalToXMLString(cp1.finalXformEnabled)); + end; + + if (embedthumb and EmbedThumbnails) then begin + xdata := GetThumbnailBase64(cp1); + buf := ''; + for i := 1 to length(xdata) do begin + buf := buf + xdata[i]; + if (length(buf) = 150) then begin + FileList.Add(' '); + buf := ''; + end; + end; + if (Length(buf) > 0) then FileList.Add(' '); + end; + + { Write palette data } + if exporting or OldPaletteFormat then + FileList.Add(ColorToXml(cp1)) + else + FileList.Add(ColorToXmlCompact(cp1)); + + FileList.Add(''); + result := FileList.text; + finally + FileList.free + end; +end; + +function RemoveExt(filename: string): string; +var + ext: string; + p: integer; +begin + filename := ExtractFileName(filename); + ext := ExtractFileExt(filename); + p := Pos(ext, filename); + Result := Copy(filename, 0, p - 1); +end; + +function XMLEntryExists(title, filename: string): boolean; +var + FileList: TStringList; +begin + + Result := false; + if FileExists(filename) then + begin + FileList := TStringList.Create; + try + FileList.LoadFromFile(filename); + if pos(' 0 then Result := true; + finally + FileList.Free; + end + end else + result := false; +end; + +procedure DeleteXMLEntry(title, filename: string); +var + Strings: TStringList; + p, i: integer; +begin + Strings := TStringList.Create; + try + i := 0; + Strings.LoadFromFile(FileName); + while Pos('name="' + title + '"', Trim(Strings[i])) = 0 do + inc(i); + + p := 0; + while p = 0 do + begin + p := Pos('', Strings[i]); + Strings.Delete(i); + end; + Strings.SaveToFile(FileName); + finally + Strings.Free; + end; +end; + + +function TMainForm.SaveXMLFlame(const cp1: TControlPoint; title, filename: string): boolean; +{ Saves Flame parameters to end of file } +var + Tag: string; + IFile: File; + FileList: TStringList; + RB: RawByteString; + + i, p: integer; + bakname: string; +begin + Tag := RemoveExt(filename); + Result := True; + try + if FileExists(filename) then + begin + bakname := ChangeFileExt(filename, '.bak'); + if FileExists(bakname) then DeleteFile(bakname); + RenameFile(filename, bakname); + + FileList := TStringList.create; + try + FileList.LoadFromFile(bakname); + + if Pos(' 0 then + begin + i := 0; + while Pos('', FileList[i]); + FileList.Delete(i); + end; + end; + +// FileList := TStringList.create; +// try +// FileList.LoadFromFile(filename); + + // fix first line + if (FileList.Count > 0) then begin + FileList[0] := ''; + end; + + if FileList.Count > 2 then + begin + if pos(' 0 then + repeat + FileList.Delete(FileList.Count - 1); + until (Pos('', FileList[FileList.count - 1]) <> 0) + else + repeat + FileList.Delete(FileList.Count - 1); + until (Pos('<' + Tag + '>', FileList[FileList.count - 1]) <> 0) or + (Pos('', FileList[FileList.count - 1]) <> 0); + end else + begin + FileList.Delete(FileList.Count - 1); + end; + + FileList.Add(Trim(FlameToXML(cp1, false, true))); + FileList.Add(''); + FileList.SaveToFile(filename); + + finally + if FileExists(bakname) and not FileExists(filename) then + RenameFile(bakname, filename); + + FileList.Free; + end; + end + else + begin + // New file ... easy + FileList := TStringList.Create; + FileList.Text := '' + #$0D#$0A + + FlameToXML(cp1, false, true) + #$0D#$0A + ''; + FileList.SaveToFile(filename, TEncoding.UTF8); + FileList.Destroy; + end; + except + begin + Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16); + Result := False; + end; + end; +end; + +function TMainForm.SaveGradient(Gradient, Title, FileName: string): boolean; +{ Saves gradient parameters to end of file } +var + IFile: TextFile; +begin + Result := True; + try + AssignFile(IFile, FileName); + if FileExists(FileName) then + begin + if EntryExists(Title, FileName) then DeleteEntry(Title, FileName); + Append(IFile); + end + else + ReWrite(IFile); + Write(IFile, Gradient); + WriteLn(IFile, ' '); + CloseFile(IFile); + except on EInOutError do + begin + Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16); + Result := False; + end; + end; +end; + +function RenameIFS(OldIdent: string; var NewIdent: string): boolean; +{ Renames an IFS parameter set in a file } +var + Strings: TStringList; + p, i: integer; + s: string; +begin + Result := True; + NewIdent := CleanEntry(NewIdent); + Strings := TStringList.Create; + try + try + i := 0; + Strings.LoadFromFile(OpenFile); + if Pos(OldIdent + ' ', Trim(Strings.Text)) <> 0 then + begin + while Pos(OldIdent + ' ', Trim(Strings[i])) <> 1 do + begin + inc(i); + end; + p := Pos('{', Strings[i]); + s := Copy(Strings[i], p, Length(Strings[i]) - p + 1); + Strings[i] := NewIdent + ' ' + s; + Strings.SaveToFile(OpenFile); + end + else + Result := False; + except on Exception do Result := False; + end; + finally + Strings.Free; + end; +end; + +function RenameXML(OldIdent: string; var NewIdent: string): boolean; +{ Renames an XML parameter set in a file } +var + Strings: TStringList; + i: integer; + bakname: string; +begin + Result := True; + Strings := TStringList.Create; + try + try + i := 0; + Strings.LoadFromFile(OpenFile); + if Pos('name="' + OldIdent + '"', Strings.Text) <> 0 then + begin + while Pos('name="' + OldIdent + '"', Strings[i]) = 0 do + begin + inc(i); + end; + Strings[i] := StringReplace(Strings[i], OldIdent, NewIdent, []); + + bakname := ChangeFileExt(OpenFile, '.bak'); + if FileExists(bakname) then DeleteFile(bakname); + RenameFile(OpenFile, bakname); + + Strings.SaveToFile(OpenFile); + end + else + Result := False; + except on Exception do Result := False; + end; + finally + Strings.Free; + end; +end; + + +procedure ListIFS(FileName: string; sel: integer); +{ List identifiers in file } +var + i, p: integer; + Title: string; + ListItem: TListItem; + FStrings: TStringList; +begin + MainForm.ParseLoadingBatch := true; + FStrings := TStringList.Create; + FStrings.LoadFromFile(FileName); + try + MainForm.ListView.Items.BeginUpdate; + MainForm.ListView.Items.Clear; + if (Pos('{', FStrings.Text) <> 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos('{', FStrings[i]); + if (p <> 0) and (Pos('(3D)', FStrings[i]) = 0) then + begin + Title := Trim(Copy(FStrings[i], 1, p - 1)); + if Title <> '' then + begin { Otherwise bad format } + ListItem := MainForm.ListView.Items.Add; + Listitem.Caption := Trim(Copy(FStrings[i], 1, p - 1)); + end; + end; + end; + end; + MainForm.ListView.Items.EndUpdate; + case sel of + 0: MainForm.ListView.Selected := MainForm.ListView.Items[MainForm.ListView.Items.Count - 1]; + 1: MainForm.ListView.Selected := MainForm.ListView.Items[0]; + end; + finally + FStrings.Free; + end; + MainForm.ParseLoadingBatch := false; +end; + +procedure ListFlames(FileName: string; sel: integer); +{ List identifiers in file } +var + i, p: integer; + Title: string; + ListItem: TListItem; + FStrings: TStringList; +begin + FStrings := TStringList.Create; + FStrings.LoadFromFile(FileName); + try + MainForm.ListView.Items.BeginUpdate; + MainForm.ListView.Items.Clear; + if (Pos('{', FStrings.Text) <> 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos('{', FStrings[i]); + if (p <> 0) then + begin + Title := Trim(Copy(FStrings[i], 1, p - 1)); + if Title <> '' then + begin { Otherwise bad format } + ListItem := MainForm.ListView.Items.Add; + Listitem.Caption := Trim(Copy(FStrings[i], 1, p - 1)); + end; + end; + end; + end; + MainForm.ListView.Items.EndUpdate; + if sel = 1 then MainForm.ListView.Selected := MainForm.ListView.Items[0]; + finally + FStrings.Free; + end; +end; + +{ ****************************** Display ************************************ } + +procedure Trace1(const str: string); +begin + if TraceLevel >= 1 then + TraceForm.MainTrace.Lines.Add('. ' + str); +end; + +procedure Trace2(const str: string); +begin + if TraceLevel >= 2 then + TraceForm.MainTrace.Lines.Add('. . ' + str); +end; + +procedure TMainForm.HandleThreadCompletion(var Message: TMessage); +var + oldscale: double; +begin + Trace2(MsgComplete + IntToStr(message.LParam)); + if not Assigned(Renderer) then begin + Trace2(MsgNotAssigned); + exit; + end; + if Renderer.ThreadID <> message.LParam then begin + Trace2(MsgAnotherRunning); + exit; + end; + Image.Cursor := crDefault; + + if assigned(FViewImage) then begin + oldscale := FViewImage.Width / Image.Width; + FViewImage.Free; + end + else oldscale := FViewScale; + + FViewImage := Renderer.GetTransparentImage; + + if (FViewImage <> nil) and (FViewImage.Width > 0) then begin + FViewScale := FViewImage.Width / Image.Width; + + FViewPos.X := FViewScale/oldscale * (FViewPos.X - FViewOldPos.X); + FViewPos.Y := FViewScale/oldscale * (FViewPos.Y - FViewOldPos.Y); + + DrawImageView; +{ + case FMouseMoveState of + msZoomWindowMove: FMouseMoveState := msZoomWindow; + msZoomOutWindowMove: FMouseMoveState := msZoomOutWindow; +// msDragMove: FMouseMoveState := msDrag; + msRotateMove: FMouseMoveState := msRotate; + end; +} + if FMouseMoveState in [msZoomWindowMove, msZoomOutWindowMove, msRotateMove] then + DrawSelection := false; + + Trace1(TimeToStr(Now) + ' : Render complete'); + Renderer.ShowSmallStats; + end + else Trace2('WARNING: No image rendered!'); + + Renderer.WaitFor; + Trace2('Destroying RenderThread #' + IntToStr(Renderer.ThreadID)); + Renderer.Free; + Renderer := nil; + Trace1(''); +end; + +procedure TMainForm.HandleThreadTermination(var Message: TMessage); +begin + Trace2(MsgTerminated + IntToStr(message.LParam)); + if not Assigned(Renderer) then begin + Trace2(MsgNotAssigned); + exit; + end; + if Renderer.ThreadID <> message.LParam then begin + Trace2(MsgAnotherRunning); + exit; + end; + Image.Cursor := crDefault; + Trace2(' Render aborted'); + + Trace2('Destroying RenderThread #' + IntToStr(Renderer.ThreadID)); + Renderer.Free; + Renderer := nil; + Trace1(''); +end; + +procedure TMainForm.DrawPreview; +var + cp : TControlPoint; + Render : TRenderer; + BM:TBitmap; +begin + Render := TRenderer.Create; + bm := TBitmap.Create; + Render := TRenderer.Create; + + cp := MainCP.Clone; + + cp.sample_density := 1; + cp.spatial_oversample := 1; + cp.spatial_filter_radius := 1; + + Render.NrThreads := NrTreads; + Render.SetCP(cp); + Render.Render; + BM.Assign(Render.GetImage); + Image.Picture.Graphic := bm; +end; + +procedure TMainForm.DrawFlame; +var + GlobalMemoryInfo: TMemoryStatus; // holds the global memory status information + RenderCP: TControlPoint; + Mem, ApproxMem: cardinal; + bs: integer; +begin + RedrawTimer.Enabled := False; + if Assigned(Renderer) then begin + assert(Renderer.Suspended = false); + + Trace2('Killing previous RenderThread #' + inttostr(Renderer.ThreadID)); + Renderer.Terminate; + Renderer.WaitFor; + Trace2('Destroying RenderThread #' + IntToStr(Renderer.ThreadID)); + + Renderer.Free; + Renderer := nil; + end; + + if not Assigned(Renderer) then + begin + if EditForm.Visible and ((MainCP.Width / MainCP.Height) <> (EditForm.cp.Width / EditForm.cp.Height)) + then EditForm.UpdateDisplay(true); // preview only? + if AdjustForm.Visible then AdjustForm.UpdateDisplay(true); // preview only! + + RenderCP := MainCP.Clone; + RenderCp.AdjustScale(Image.width, Image.height); + + // following needed ? +// cp.Zoom := Zoom; +// cp.center[0] := center[0]; +// cp.center[1] := center[1]; + + RenderCP.sample_density := defSampleDensity; + // oversample and filter are just slowing us down here... + RenderCP.spatial_oversample := 1; // defOversample; + RenderCP.spatial_filter_radius := 0.001; {?} //defFilterRadius; + RenderCP.Transparency := true; // always generate transparency here + + GlobalMemoryInfo.dwLength := SizeOf(GlobalMemoryInfo); + GlobalMemoryStatus(GlobalMemoryInfo); + Mem := GlobalMemoryInfo.dwAvailPhys; + + if (singleBuffer) then bs := 16 + else bs := 32; + +// if Output.Lines.Count >= 1000 then Output.Lines.Clear; + Trace1('--- Previewing "' + RenderCP.name + '" ---'); + Trace1(Format(' Available memory: %f Mb', [Mem / (1024*1024)])); + ApproxMem := int64(RenderCp.Width) * int64(RenderCp.Height) {* sqr(Oversample)} + * (bs + 4 + 4); // +4 for temp image(s)...? + assert(MainPreviewScale <> 0); + if ApproxMem * sqr(MainPreviewScale) < Mem then begin + if ExtendMainPreview then begin + RenderCP.sample_density := RenderCP.sample_density / sqr(MainPreviewScale); + RenderCP.Width := round(RenderCp.Width * MainPreviewScale); + RenderCP.Height := round(RenderCp.Height * MainPreviewScale); + end; + end + else Trace1('WARNING: Not enough memory for extended preview!'); + if ApproxMem > Mem then + Trace1('OUTRAGEOUS: Not enough memory even for normal preview! :-('); + Trace1(Format(' Size: %dx%d, Quality: %f', + [RenderCP.Width, RenderCP.Height, RenderCP.sample_density])); + FViewOldPos.x := FViewPos.x; + FViewOldPos.y := FViewPos.y; + StartTime := Now; + try + Renderer := TRenderThread.Create; + Renderer.TargetHandle := MainForm.Handle; + if TraceLevel > 0 then Renderer.Output := TraceForm.MainTrace.Lines; + Renderer.OnProgress := OnProgress; + Renderer.SetCP(RenderCP); + Renderer.NrThreads := FNrThreads; + + Trace2('Starting RenderThread #' + inttostr(Renderer.ThreadID)); + Renderer.Resume; + + Image.Cursor := crAppStart; + except + Trace1('ERROR: Cannot start renderer!'); + end; + RenderCP.Free; + + end; +end; + +{ ************************** IFS and triangle stuff ************************* } + +function FlameToString(Title: string): string; +{ Creates a string containing the formated flame parameter set } +var + I: integer; + sl, Strings: TStringList; +begin + Strings := TStringList.Create; + sl := TStringList.Create; + try + Strings.Add(CleanEntry(Title) + ' {'); + MainCp.SaveToStringList(sl); + Strings.Add(sl.text); + Strings.Add('palette:'); + for i := 0 to 255 do + begin + Strings.Add(IntToStr(MainCp.cmap[i][0]) + ' ' + + IntToStr(MainCp.cmap[i][1]) + ' ' + + IntToStr(MainCp.cmap[i][2])) + end; + Strings.Add('}'); + Result := Strings.Text; + finally + sl.Free; + Strings.Free; + end; +end; + +procedure TMainForm.RandomBatch; +{ Write a series of random ifs to a file } +var + i: integer; + F: TextFile; + b, RandFile: string; +begin + b := IntToStr(BatchSize); + inc(MainSeed); + RandSeed := MainSeed; + try + AssignFile(F, GetEnvVarValue('APPDATA') + '\' + randFilename); + OpenFile := GetEnvVarValue('APPDATA') + '\' + randFilename; + ReWrite(F); + WriteLn(F, ''); + for i := 0 to BatchSize - 1 do + begin + inc(RandomIndex); + Statusbar.SimpleText := Format(TextByKey('main-status-batchgenerate'), [(i+1), b]); + RandSeed := MainSeed; + if randGradient = 0 then cmap_index := random(NRCMAPS); + inc(MainSeed); + RandSeed := MainSeed; + RandomizeCP(MainCp); + MainCp.CalcBoundbox; + +(* Title := RandomPrefix + RandomDate + '-' + + IntToStr(RandomIndex); + *) + MainCp.name := RandomPrefix + RandomDate + '-' + + IntToStr(RandomIndex); + Write(F, FlameToXML(MainCp, False, false)); +// Write(F, FlameToString(Title)); +// WriteLn(F, ' '); + end; + Write(F, ''); + CloseFile(F); + except + on EInOutError do Application.MessageBox(PChar(TextByKey('main-status-batcherror')), PChar('Apophysis'), 16); + end; + RandFile := GetEnvVarValue('APPDATA') + '\' + randFilename; + MainCp.name := ''; +end; + +{ ******************************** Menu ************************************ } + +function LoadXMLFlameText(filename, name: string) : string; +var + i, p: integer; + FileStrings: TStringList; + ParamStrings: TStringList; + Tokens: TStringList; + time: integer; +begin + time := -1; + FileStrings := TStringList.Create; + ParamStrings := TStringList.Create; + Result := ''; + + if pos('*untitled', name) <> 0 then + begin + Tokens := TStringList.Create; + GetTokens(name, tokens); + time := StrToInt(tokens[1]); + Tokens.free; + end; + try + if UpperCase(ExtractFileExt(filename)) = '.PNG' then + else + FileStrings.LoadFromFile(filename); + + for i := 0 to FileStrings.Count - 1 do + begin + pname := ''; + ptime := ''; + p := Pos(' 0) then + begin + MainForm.ListXMLScanner.LoadFromBuffer(TCharType(TStringType(FileStrings[i]))); + MainForm.ListXMLScanner.Execute; + if pname <> '' then + begin + if (Trim(pname) = Trim(name)) then + begin + ParamStrings.Add(FileStrings[i]); + Break; + end; + end + else + begin + if ptime <> '' then + begin + if StrToInt(ptime) = time then + begin + ParamStrings.Add(FileStrings[i]); + Break; + end; + end; + end; + end; + end; + repeat + inc(i); + ParamStrings.Add(FileStrings[i]); + until pos('', Lowercase(FileStrings[i])) <> 0; + + Result := ParamStrings.Text; + + finally + FileStrings.free; + ParamStrings.free; + end; +end; + +procedure AddThumbnail(renderer : TRenderer; width, height : double); +var + Bmp: TBitmap; + x, y : double; +begin + Bmp := TBitmap.Create; + Bmp.PixelFormat := pf24bit; + Bmp.HandleType := bmDIB; + Bmp.Width := ThumbnailSize; + Bmp.Height := ThumbnailSize; + + x := ThumbnailSize / 2; + y := ThumbnailSize / 2; + + x := x - width / 2; + y := y - height / 2; + + with Bmp.Canvas do begin + Brush.Color := GetSysColor(5); // window background + FillRect(Rect(0, 0, Bmp.Width, Bmp.Height)); + Draw(round(x), round(y), renderer.GetImage); + end; + + MainForm.UsedThumbnails.Add(bmp, nil); + + if (Bmp <> nil) then Bmp.Free; +end; + +function ScanVariations(name:string):boolean; +var + i,count:integer; + vname:string; +begin + count:=NrVar; + for i:=0 to count - 1 do + begin + vname := VarNames(i); + if (vname = name) then + begin + Result := true; + exit; + end; + end; + for i := 0 to MainForm.SubstSource.Count - 1 do + begin + vname := MainForm.SubstSource[i]; + if (vname = name) then + begin + Result := true; + exit; + end; + end; + Result := false; +end; +function ScanVariables(name:string):boolean; +var + i,count:integer; +begin + count:=GetNrVariableNames; + for i:=0 to count - 1 do + begin + if (GetVariableNameAt(i) = name) then + begin + Result := true; + exit; + end; + end; + for i := 0 to MainForm.SubstSource.Count - 1 do + begin + if (MainForm.SubstSource[i] = name) then + begin + Result := true; + exit; + end; + end; + Result := false; +end; + +procedure TMainForm.mnuOpenClick(Sender: TObject); +var + fn:string; +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame;*.xml|' + TextByKey('common-filter-allfiles') + '|*.*'; + OpenDialog.InitialDir := ParamFolder; + OpenDialog.FileName := ''; + if OpenSaveFileDialog(MainForm, '.flame', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + OpenDialog.FileName := fn; + MainForm.CurrentFileName := OpenDialog.FileName; + LastOpenFile := OpenDialog.FileName; + Maincp.name := ''; + ParamFolder := ExtractFilePath(OpenDialog.FileName); + ListView.ReadOnly := False; + mnuListRename.Enabled := True; + mnuItemDelete.Enabled := True; + OpenFile := OpenDialog.FileName; + //MainForm.Caption := AppVersionString + ' - ' + OpenFile; // --Z-- + if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + openFile + else MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + openFile; + OpenFileType := ftXML; + (*if UpperCase(ExtractFileExt(OpenDialog.FileName)) = '.IFS' then + begin + OpenFileType := ftIfs; + Variation := vLinear; + VarMenus[0].Checked := True; + end; + if (UpperCase(ExtractFileExt(OpenDialog.FileName)) = '.FLA') or + (UpperCase(ExtractFileExt(OpenDialog.FileName)) = '.APO') then + OpenFileType := ftFla; *) + if OpenFileType = ftXML then + ListXML(OpenDialog.FileName, 1) + else + ListIFS(OpenDialog.FileName, 1) + end; +end; + +procedure TMainForm.mnuNextClick(Sender: TObject); +begin + with ListView do + if Items.Count <> 0 then + Selected := Items[(Selected.Index + 1) mod Items.Count]; +end; + +procedure TMainForm.mnuPreviousClick(Sender: TObject); +var + i: integer; +begin + with ListView do + if Items.Count <> 0 then + begin + i := Selected.Index - 1; + if i < 0 then i := Items.Count - 1; + Selected := Items[i]; + end; +end; + +procedure TMainForm.mnuListRenameClick(Sender: TObject); +begin + if ListView1.SelCount <> 0 then + ListView1.Items[ListView1.Selected.Index].EditCaption; +end; + +procedure TMainForm.mnuCopyUPRClick(Sender: TObject); +begin + Clipboard.SetTextBuf(PChar(UPRString(MainCp, Maincp.name))); +end; + +procedure TMainForm.mnuItemDeleteClick(Sender: TObject); +var + c: boolean; +begin + if ListView1.SelCount <> 0 then + begin + if ConfirmDelete then + c := Application.MessageBox( + PChar(Format(TextByKey('common-confirmdelete'), [ListView1.Selected.Caption])), 'Apophysis', 36) = IDYES + else + c := True; + if c then + if (*ListView1.Focused and*) (ListView1.SelCount <> 0) then + begin + Application.ProcessMessages; + if OpenFileType = ftXML then + DeleteXMLEntry(ListView1.Selected.Caption, OpenFile) + else + DeleteEntry(ListView1.Selected.Caption, OpenFile); + if (ListView1.Selected.Index >= 0) and (ListView1.Selected.Index < UsedThumbnails.Count) and (not ClassicListMode) then + UsedThumbnails.Delete(ListView1.Selected.Index); + ListView1.Items.Delete(ListView1.Selected.Index); + Application.ProcessMessages; + ListView1.Selected := ListView1.ItemFocused; + //RebuildListView; + ListXML(OpenFile, ListView1.ItemIndex); + end; + end; +//end; +end; + +procedure TMainForm.mnuOptionsClick(Sender: TObject); +begin + OptionsForm.ShowModal; + // --Z-- + StopThread; + RedrawTimer.Enabled := True; + tbQualityBox.Text := FloatToStr(defSampleDensity); + tbShowAlpha.Down := ShowTransparency; + DrawImageView; + UpdateWindows; +end; + +procedure TMainForm.mnuRefreshClick(Sender: TObject); +begin + RedrawTimer.enabled := true; +end; + +procedure TMainForm.mnuNormalWeightsClick(Sender: TObject); +begin + StopThread; + UpdateUndo; +// TODO: ...something +// ComputeWeights(MainCp, MainTriangles, transforms); + RedrawTimer.Enabled := True; + UpdateWindows; +end; + +procedure TMainForm.mnuRWeightsClick(Sender: TObject); +begin + StopThread; + UpdateUndo; + inc(MainSeed); + RandSeed := MainSeed; + MainCp.RandomizeWeights; + RedrawTimer.Enabled := True; + UpdateWindows; +end; + +procedure TMainForm.mnuRandomBatchClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + inc(MainSeed); + RandSeed := MainSeed; + RandomBatch; + OpenFile := GetEnvVarValue('APPDATA') + '\' + randFilename; + OpenFileType := ftXML; + MainForm.Caption := AppVersionString + ' - ' + TextByKey('main-common-randombatch'); + ListXML(OpenFile, 1); + //ListView.SetFocus; + if batchsize = 1 then DrawFlame; +end; + +function GradientString(c: TColorMap): string; +var + strings: TStringList; + i, j, cl: integer; +begin + strings := TStringList.Create; + for i := 0 to 255 do + begin + j := round(i * (399 / 255)); + cl := (c[i][2] shl 16) + (c[i][1] shl 8) + (c[i][0]); + strings.Add(' index=' + IntToStr(j) + ' color=' + intToStr(cl)); + end; + Result := Strings.Text; + strings.Free; +end; + +function TMainForm.UPRString(cp1: TControlPoint; Entry: string): string; +{ Returns a string containing an Ultra Fractal parameter set for copying + or saving to file } +var + IterDensity, m, i, j: integer; + scale, a, b, c, d, e, f, p, v: double; + GradStrings, Strings: TStringList; + rept, cby, smap, sol: string; + uprcenter: array[0..1] of double; // camera center + Backcolor: longint; + xf_str: string; +begin + cp1.Prepare; + uprcenter[0] := cp1.Center[0]; + uprcenter[1] := cp1.Center[1]; + cp1.Width := UPRWidth; + cp1.Height := UPRHeight; + scale := power(2, cp1.zoom) * CalcUPRMagn(cp1); + cp1.center[0] := uprCenter[0]; + cp1.center[1] := uprCenter[1]; + smap := 'no'; + sol := 'no'; + rept := ''; + cby := 'Hit Frequency'; + Strings := TStringList.Create; + GradStrings := TStringList.Create; + try + Strings.Add(CleanEntry(Entry) + ' {'); + Strings.Add('fractal:'); + Strings.Add(' title="' + CleanUPRTitle(Entry) + + '" width=' + IntToStr(UPRWidth) + ' height=' + IntToStr(UPRHeight) + ' layers=1'); + Strings.Add('layer:'); + Strings.Add(' method=linear caption="Background" opacity=100 mergemode=normal'); + Strings.Add('mapping:'); + Strings.Add(' center=' + floatToStr(cp1.center[0]) + '/' + floatToStr(-cp1.center[1]) + + ' magn=' + FloatToStr(scale)); + Strings.Add('formula:'); + Strings.Add(' maxiter=1 filename="' + UPRFormulaFile + '" entry="' + UPRFormulaIdent + '"'); + Strings.Add('inside:'); + Strings.Add(' transfer=none'); + Strings.Add('outside:'); + Strings.Add(' transfer=linear repeat=no ' + 'filename="' + UPRColoringFile + '" entry="' + + UPRColoringIdent + '"'); + if (UPRAdjustDensity) and (scale > 1) then + IterDensity := Trunc(UPRSampleDensity * scale * scale) + else + IterDensity := UPRSampleDensity; + Strings.Add(' p_iter_density=' + IntToStr(IterDensity) + ' p_spat_filt_rad=' + + Format('%.3g', [UPRFilterRadius]) + ' p_oversample=' + IntToStr(UPROversample)); + backcolor := 255 shl 24 + cp1.background[0] shl 16 + cp1.background[1] shl 8 + cp1.background[2]; + Strings.Add(' p_bk_color=' + IntToStr(Backcolor) + ' p_contrast=1' + + ' p_brightness=' + FloatToStr(cp1.Brightness) + ' p_gamma=' + FloatToStr(cp1.Gamma)); + Strings.Add(' p_white_level=200 p_xforms=' + inttostr(Transforms)); + for m := 0 to Transforms do + begin + a := cp1.xform[m].c[0][0]; + c := cp1.xform[m].c[0][1]; + b := cp1.xform[m].c[1][0]; + d := cp1.xform[m].c[1][1]; + e := cp1.xform[m].c[2][0]; + f := cp1.xform[m].c[2][1]; + p := cp1.xform[m].Density; + if m < Transforms then xf_str := 'p_xf' + inttostr(m) + else begin + if cp1.HasFinalXForm = false then break; + xf_str := 'p_finalxf'; + end; + Strings.Add(' ' + xf_str + '_p=' + Format('%.6g ', [p])); + Strings.Add(' ' + xf_str + '_c=' + floatTostr(cp1.xform[m].color)); + Strings.Add(' ' + xf_str + '_sym=' + floatTostr(cp1.xform[m].symmetry)); + Strings.Add(' ' + xf_str + '_cfa=' + Format('%.6g ', [a]) + + xf_str + '_cfb=' + Format('%.6g ', [b]) + + xf_str + '_cfc=' + Format('%.6g ', [c]) + + xf_str + '_cfd=' + Format('%.6g ', [d])); + Strings.Add(' ' + xf_str + '_cfe=' + Format('%.6g ', [e]) + + ' ' + xf_str + '_cff=' + Format('%.6g ', [f])); + for i := 0 to NRVAR-1 do + if cp1.xform[m].GetVariation(i) <> 0 then begin + Strings.Add(' ' + xf_str + '_var_' + VarNames(i) + '=' + + floatToStr(cp1.xform[m].GetVariation(i))); + for j:= 0 to GetNrVariableNames - 1 do begin +{$ifndef VAR_STR} + cp1.xform[m].GetVariable(GetVariableNameAt(j), v); + Strings.Add(' ' + xf_str + '_par_' + GetVariableNameAt(j) + '=' + floatToStr(v)); +{$else} + Strings.Add(' ' + xf_str + '_par_' + + GetVariableNameAt(j) + '=' + cp1.xform[m].GetVariableStr(GetVariableNameAt(j))); +{$endif} + end; + end; + end; + Strings.Add('gradient:'); + Strings.Add(GradientString(cp1.cmap)); + Strings.Add('}'); + UPRString := Strings.Text; + finally + GradStrings.Free; + Strings.Free; + end; +end; + +procedure TMainForm.mnuRandomClick(Sender: TObject); +begin + StopThread; + UpdateUndo; + inc(MainSeed); + RandomizeCP(MainCp); + inc(RandomIndex); + MainCp.name := RandomPrefix + RandomDate + '-' + + IntToStr(RandomIndex); + Transforms := MainCp.TrianglesFromCP(MainTriangles); + + if AdjustForm.visible then AdjustForm.UpdateDisplay; + + StatusBar.Panels[3].text := maincp.name; + ResetLocation; + RedrawTimer.Enabled := true; + UpdateWindows; +end; + +procedure TMainForm.mnuEqualizeClick(Sender: TObject); +begin + StopThread; + UpdateUndo; + MainCP.EqualizeWeights; + RedrawTimer.Enabled := True; + UpdateWindows; +end; + +procedure TMainForm.mnuEditorClick(Sender: TObject); +begin + EditForm.Show; +end; + +procedure TMainForm.mnuExitClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + Close; +end; + +procedure TMainForm.mnuSaveUPRClick(Sender: TObject); +{ Write a UPR to a file } +begin + SaveForm.SaveType := stExportUPR; + SaveForm.Filename := UPRPath; + SaveForm.Title := maincp.name; + if SaveForm.ShowModal = mrOK then + begin + UPRPath := SaveForm.FileName; + SaveUPR(SaveForm.Title, SaveForm.Filename); + end; +end; + +procedure TMainForm.mnuSaveAsClick(Sender: TObject); +{ Save parameters to a file } +begin + SaveForm.SaveType := stSaveParameters; + SaveForm.Filename := SavePath; + SaveForm.Title := maincp.name; + if SaveForm.ShowModal = mrOK then + begin + maincp.name := SaveForm.Title; + SavePath := SaveForm.Filename; + if ExtractFileExt(SavePath) = '' then + SavePath := SavePath + '.flame'; + SaveXMLFlame(maincp, maincp.name, SavePath); + StatusBar.Panels[3].Text := maincp.name; + if (SavePath = OpenFile) then ListXML(OpenDialog.FileName, 0); + end; +end; + +procedure TMainForm.mnuSaveAllAsClick(Sender: TObject); +{ Save all parameters to a file } +var + i, current: integer; + currentXML : string; +begin + SaveForm.SaveType := stSaveAllParameters; + SaveForm.Filename := SavePath; + if SaveForm.ShowModal = mrOK then + begin + SavePath := SaveForm.Filename; + if ExtractFileExt(SavePath) = '' then + SavePath := SavePath + '.flame'; + current := ListView1.ItemIndex; + currentXML := Trim(FlameToXML(Maincp, false, true)); + for i := 0 to ListView1.Items.Count-1 do + begin + // -X- what if there are unsaved changes at the current CP? + if (i = current) then begin + ParseXML(maincp, PCHAR(currentXML), true); + SaveXMLFlame(maincp, maincp.name, SavePath); + end else begin + LoadXMLFlame(OpenFile, ListView1.Items.Item[i].Caption); + SaveXMLFlame(maincp, maincp.name, SavePath); + end; + end; + ListXML(SavePath, 2); + if (current < 0) then current := 0; + ListView1.Selected := ListView1.Items[current]; + LoadXMLFlame(SavePath, ListView1.Selected.caption); + end; +end; + +function GradTitle(str: string): string; +var + p: integer; +begin + p := pos('{', str); + GradTitle := Trim(copy(str, 1, p - 1)); +end; + +procedure TMainForm.DisplayHint(Sender: TObject); +var + T: TComponent; +begin + T := MainForm.FindComponent('StatusBar'); + if T <> nil then + if Application.Hint = '' then + begin + TStatusBar(T).SimpleText := ''; + TStatusBar(T).SimplePanel := False; + TStatusBar(T).Refresh; + end + else + TStatusBar(T).SimpleText := Application.Hint; +end; + +procedure TMainForm.MainFileClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} +end; + +procedure TMainForm.MainViewClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} +end; + +procedure TMainForm.MainToolsClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} +end; + +procedure TMainForm.MainHelpClick(Sender: TObject); +begin +end; + +{ ********************************* Form ************************************ } +procedure TMainForm.FavoriteClick(Sender: TObject); +var + i: integer; + s: string; +begin +{$ifdef DisableScripting} +{$else} + i := TMenuItem(Sender).Tag; + Script := favorites[i]; + ScriptEditor.Editor.Lines.LoadFromFile(Script); + + s := ExtractFileName(Script); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + mnuRun.Caption := Format(TextByKey('main-menu-script-run2'), [s]);//'Run "' + s + '"'; + btnRunScript.Hint := Format(TextByKey('main-menu-script-run2'), [s]);//'Run Script (F8)|Runs the ' + s + ' script.'; + //ScriptEditor.Caption := s; + ScriptEditor.RunScript; + +{$endif} +end; + +procedure TMainForm.ScriptItemClick(Sender: TObject); +var + s: string; +begin +{$ifdef DisableScripting} +{$else} + Script := ExtractFilePath(Application.ExeName) + scriptPath + '\' + TMenuItem(Sender).Hint + '.asc'; + ScriptEditor.Editor.Lines.LoadFromFile(Script); + s := ExtractFileName(Script); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + mnuRun.Caption := Format(TextByKey('main-menu-script-run2'), [s]);//'Run "' + s + '"'; + btnRunScript.Hint := Format(TextByKey('main-menu-script-run2'), [s]);//'Run Script (F8)|Runs the ' + s + ' script.'; + //ScriptEditor.Caption := s; + ScriptEditor.RunScript; +{$endif} +end; + +procedure TMainForm.GetScripts; +var + NewItem: TMenuItem; + NewItem2 : TMenuItem; + searchResult: TSearchRec; + i: integer; + s: string; + sl: TStringList; + path : string; +begin + sl := TStringList.Create; + s := TextByKey('main-menu-script-directory'); + + NewItem := mnuScript.Find(TextByKey('main-menu-script-directory')); + if (NewItem <> nil) then mnuScript.Remove(NewItem); + NewItem := mnuScript.Find(TextByKey('main-menu-script-more')); + if (NewItem <> nil) then mnuScript.Remove(NewItem); + + {$ifdef DisableScripting} + {$else} + if FileExists(ExtractFilePath(Application.ExeName) + scriptFavsFilename) then begin + Favorites.LoadFromFile(AppPath + scriptFavsFilename); + if Trim(Favorites.Text) <> '' then begin + if Favorites.count <> 0 then + begin + NewItem := TMenuItem.Create(self); + NewItem.Caption := '-'; + mnuScript.Add(NewItem); + for i := 0 to Favorites.Count - 1 do + begin + if FileExists(Favorites[i]) then + begin + NewItem := TMenuItem.Create(Self); + if i < 12 then + NewItem.ShortCut := TextToShortCut('Ctrl+F' + IntToStr(i + 1)); + NewItem.Tag := i; + s := ExtractFileName(Favorites[i]); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + NewItem.Caption := s; + //NewItem.Hint := 'Loads and runs the ' + s + ' script.'; + NewItem.OnClick := FavoriteClick; + OnClick := FavoriteClick; + mnuScript.Add(NewItem); + sl.Add(s); + end; + end; + s := TextByKey('main-menu-script-more'); + end; + end; + end; + + // Try to find regular files matching *.asc in the scripts dir + path := ExtractFilePath(Application.ExeName) + scriptPath + '\*.asc'; + if FindFirst(path, faAnyFile, searchResult) = 0 then begin + NewItem := TMenuItem.Create(Self); + NewItem.Caption := '-'; + mnuScript.Add(NewItem); + NewItem := TMenuItem.Create(Self); + NewItem.Caption := s; + repeat + NewItem2 := TMenuItem.Create(Self); + s := searchResult.Name; + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + NewItem2.Caption := s; + NewItem2.Hint := s; + NewItem2.OnClick := ScriptItemClick; + if (sl.IndexOf(s) < 0) then NewItem.Add(NewItem2); + until (FindNext(searchResult) <> 0); + FindClose(searchResult); + mnuScript.Add(NewItem); + end; + + // -X- Copypaste code...me lazy + path := ExtractFilePath(Application.ExeName) + scriptPath + '\*.aposcript'; + if FindFirst(path, faAnyFile, searchResult) = 0 then begin + NewItem := TMenuItem.Create(Self); + NewItem.Caption := '-'; + mnuScript.Add(NewItem); + NewItem := TMenuItem.Create(Self); + NewItem.Caption := s; + repeat + NewItem2 := TMenuItem.Create(Self); + s := searchResult.Name; + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + NewItem2.Caption := s; + NewItem2.Hint := s; + NewItem2.OnClick := ScriptItemClick; + if (sl.IndexOf(s) < 0) then NewItem.Add(NewItem2); + until (FindNext(searchResult) <> 0); + FindClose(searchResult); + mnuScript.Add(NewItem); + end; + + {$endif} +end; + +procedure TMainForm.FormCreate(Sender: TObject); +var + dte: string; + cmdl : TCommandLine; +begin + //KnownPlugins := TList.Create; + + FNrThreads := 1; + AppVersionString:=APP_NAME; + + SubstSource := TStringList.Create; + SubstTarget := TStringList.Create; + + CreateSubstMap; + TbBreakWidth := 802; + + {$ifdef DisableScripting} + mnuScript.Visible := false; + {btnRunScript.Visible := false; + btnStopScript.Visible := false; + ToolButton17.Visible := false; + ToolButton18.Visible := false;} + + ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(btnRunScript), 0); + ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(btnStopScript), 0); + ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(ToolButton17), 0); + ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(ToolButton18), 0); + TbBreakWidth := TbBreakWidth - (3 * 26 + 1 * 8); + {$endif} + + ListXmlScanner := TEasyXmlScanner.Create(nil); + XmlScanner := TXmlScanner.Create(nil); + + MainForm.ListXmlScanner.Normalize := False; + MainForm.ListXmlScanner.OnStartTag := ListXmlScannerStartTag; + + MainForm.XmlScanner.Normalize := False; + MainForm.XmlScanner.OnContent := XmlScannerContent; + MainForm.XmlScanner.OnEmptyTag := XMLScannerEmptyTag; + MainForm.XmlScanner.OnEndTag := XmlScannerEndTag; + MainForm.XmlScanner.OnStartTag := XMLScannerStartTag; + + ReadSettings; + + InternalBitsPerSample := 0; + renderBitsPerSample := 0; + + // Re-save... + SaveSettings; + + LoadLanguage(LanguageFile); + InsertStrings; + + AvailableLanguages := TStringList.Create; + AvailableLanguages.Add(''); + ListLanguages; + + cmdl := TCommandLine.Create; + cmdl.Load; + + if (NXFORMS > 100) then AppVersionString := AppVersionString + ' (' + TextByKey('main-common-title-t500') + ')' + else if (NXFORMS < 100) or (cmdl.Lite) then AppVersionString := AppVersionString + ' (' + TextByKey('main-common-title-lite') + ')'; + + SplashWindow.SetInfo(TextByKey('splash-loadingui')); + LockListChangeUpdate := false; + Screen.Cursors[crEditArrow] := LoadCursor(HInstance, 'ARROW_WHITE'); + Screen.Cursors[crEditMove] := LoadCursor(HInstance, 'MOVE_WB'); + Screen.Cursors[crEditRotate] := LoadCursor(HInstance, 'ROTATE_WB'); + Screen.Cursors[crEditScale] := LoadCursor(HInstance, 'SCALE_WB'); + Caption := AppVersionString + APP_BUILD; + + mnuExportFLame.Enabled := FileExists(flam3Path); + + FMouseMoveState := msDrag; + LimitVibrancy := False; + Favorites := TStringList.Create; + GetScripts; + Randomize; + MainSeed := Random(123456789); + maincp := TControlPoint.Create; + ParseCp := TControlPoint.create; + OpenFileType := ftXML; + Application.OnHint := DisplayHint; + AppPath := ExtractFilePath(Application.ExeName); + CanDrawOnResize := False; + + SplashWindow.SetInfo(TextByKey('splash-loadingsettings')); + + Dte := FormatDateTime('yymmdd', Now); + if Dte <> RandomDate then + RandomIndex := 0; + RandomDate := Dte; + mnuExit.ShortCut := TextToShortCut('Alt+F4'); + + SplashWindow.SetInfo(TextByKey('splash-loadingplugins')); + FillVariantMenu; + + tbQualityBox.Text := FloatToStr(defSampleDensity); + tbShowAlpha.Down := ShowTransparency; + DrawSelection := true; + FViewScale := 1; + ThumbnailSize := 128; + UsedThumbnails := Thumbnails; + if (UseSmallThumbnails) then begin + ThumbnailSize := 96; + UsedThumbnails := SmallThumbnails; + end; + + LoadThumbnailPlaceholder(ThumbnailSize); + + ListView1.LargeImages := UsedThumbnails; + ListBackPanel.Width := ThumbnailSize + 90; + Splitter.Left := ListBackPanel.Width; + + if not cmdl.Lite then begin + if ClassicListMode = true then + btnViewListClick(nil) + else + btnViewIconsClick(nil); + end else begin + ListView1.ViewStyle := vsReport; + ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(btnViewList), 0); + ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(btnViewIcons), 0); + ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(ToolButton9), 0); + TbBreakWidth := TbBreakWidth - (2 * 26 + 1 * 8); + end; + +end; + +procedure TMainForm.FormShow(Sender: TObject); +var + Registry: TRegistry; + i: integer; + a,b,c,d:integer; + hnd,hr:Cardinal; + index: integer; + mins:integer; + cmdl : TCommandLine; + fn, flameXML : string; + openScript : string; +begin + tbGuides.Down := EnableGuides; + DoNotAskAboutChange := true; + { Read position from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Main', False) then + begin + if Registry.ValueExists('Left') then + MainForm.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + MainForm.Top := Registry.ReadInteger('Top'); + if Registry.ValueExists('Width') then + MainForm.Width := Registry.ReadInteger('Width'); + if Registry.ValueExists('Height') then + MainForm.Height := Registry.ReadInteger('Height'); + end; + Registry.CloseKey; + finally + Registry.Free; + end; + { Synchronize menus etc..} + // should be defaults.... + SplashWindow.SetInfo(TextByKey('splash-initrenderer')); + UndoIndex := 0; + UndoMax := 0; + index := 1; + ListView.RowSelect := True; + inc(MainSeed); + RandSeed := MainSeed; + Variation := vRandom; + Maincp.brightness := defBrightness; + maincp.gamma := defGamma; + maincp.vibrancy := defVibrancy; + maincp.sample_density := defSampleDensity; + maincp.spatial_oversample := defOversample; + maincp.spatial_filter_radius := defFilterRadius; + maincp.gammaThreshRelative := defGammaThreshold; + inc(MainSeed); + RandSeed := MainSeed; + +// somehow this doesn't work: +// Image.Width := BackPanel.Width - 2; +// Image.Height := BackPanel.Height - 2; + +// so we'll do it 'bad' way ;-) + Image.Align := alNone; + + SplashWindow.SetInfo(TextByKey('splash-initcolormap')); + if FileExists(AppPath + 'default.map') then + begin + DefaultPalette := GradientBrowser.LoadFractintMap(AppPath + 'default.map'); + maincp.cmap := DefaultPalette; + end + else + begin + cmap_index := random(NRCMAPS); + GetCMap(cmap_index, 1, maincp.cmap); + DefaultPalette := maincp.cmap; + end; + if FileExists(GetEnvVarValue('APPDATA') + '\' + randFilename) then + DeleteFile(GetEnvVarValue('APPDATA') + '\' + randFilename); + + cmdl := TCommandLine.Create; + cmdl.Load; + + openScript := ''; + + // get filename from command line argument + SplashWindow.SetInfo(TextByKey('splash-initbatch')); + if ParamCount > 0 then + openFile := ParamStr(1) + else + openFile := defFlameFile; + + if ((openFile = '') or (not FileExists(openFile))) and (RememberLastOpenFile) then begin + openFile := LastOpenFile; + index := LastOpenFileEntry; + end; + + if FileExists(openFile) and ((LowerCase(ExtractFileExt(OpenFile)) <> '.asc') or (LowerCase(ExtractFileExt(OpenFile)) <> '.aposcript')) then begin + LastOpenFile := openFile; + LastOpenFileEntry := index; + end; + + if (openFile = '') or (not FileExists(openFile)) and ((LowerCase(ExtractFileExt(OpenFile)) <> '.asc') or (LowerCase(ExtractFileExt(OpenFile)) <> '.aposcript')) then + begin + MainCp.Width := Image.Width; + MainCp.Height := Image.Height; + RandomBatch; + if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + TextByKey('main-common-randombatch') + else MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + TextByKey('main-common-randombatch'); + OpenFile := GetEnvVarValue('APPDATA') + '\' + randFilename; + ListXML(OpenFile, 1); + OpenFileType := ftXML; + if batchsize = 1 then DrawFlame; + end + else + begin + (*if (LowerCase(ExtractFileExt(OpenFile)) = '.apo') or (LowerCase(ExtractFileExt(OpenFile)) = '.fla') then + begin + ListFlames(OpenFile, index); + OpenFileType := ftFla; + end else*) if (LowerCase(ExtractFileExt(OpenFile)) = '.asc') or (LowerCase(ExtractFileExt(OpenFile)) = '.aposcript') then + begin + openScript := OpenFile; + RandomBatch; + if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + TextByKey('main-common-randombatch') + else MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + TextByKey('main-common-randombatch'); + OpenFile := GetEnvVarValue('APPDATA') + '\' + randFilename; + ListXML(OpenFile, 1); + OpenFileType := ftXML; + if batchsize = 1 then DrawFlame; + end else begin + ListXML(OpenFile, index); + OpenFileType := ftXML; + MainForm.ListView1.Selected := MainForm.ListView1.Items[index - 1]; + end; + if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + openFile + else MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + openFile; +// MainForm.Caption := AppVersionString + ' - ' + openFile; + end; + //ListView.SetFocus; + CanDrawOnResize := True; + Statusbar.Panels[3].Text := maincp.name; +{ + gradientForm.cmbPalette.Items.clear; + for i := 0 to NRCMAPS -1 do + gradientForm.cmbPalette.Items.Add(cMapnames[i]); + GradientForm.cmbPalette.ItemIndex := 0; +} + AdjustForm.cmbPalette.Items.clear; + for i := 0 to NRCMAPS -1 do + AdjustForm.cmbPalette.Items.Add(cMapnames[i]); + AdjustForm.cmbPalette.ItemIndex := 0; +// AdjustForm.cmbPalette.Items.clear; + + ExportDialog.cmbDepth.ItemIndex := 2; + DoNotAskAboutChange := false; + + if (AutoSaveFreq = 0) then mins := 1 + else if (AutoSaveFreq = 1) then mins := 2 + else if (AutoSaveFreq = 2) then mins := 5 + else if (AutoSaveFreq = 3) then mins := 10 + else begin + mins := 5; + AutoSaveFreq := 2; + AutoSaveEnabled := false; + end; + + AutoSaveTimer.Interval := 60 * 1000 * mins; + AutoSaveTimer.Enabled := AutoSaveEnabled; + + // loading done..now do what is told by cmdline ... + if (cmdl.CreateFromTemplate) then begin + if FileExists(cmdl.TemplateFile) then begin + fn:=cmdl.TemplateFile; + flameXML := LoadXMLFlameText(fn, cmdl.TemplateName); + UpdateUndo; +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + StopThread; + InvokeLoadXML(flameXML); + Transforms := MainCp.TrianglesFromCP(MainTriangles); + Statusbar.Panels[3].Text := MainCp.name; + ResizeImage; + RedrawTimer.Enabled := True; + Application.ProcessMessages; + UpdateWindows; + AdjustForm.TemplateRandomizeGradient; + end; + end; + + // .. and run autoexec.asc +{$ifdef DisableScripting} +{$else} + SplashWindow.SetInfo(TextByKey('splash-execstartupscript')); + if (FileExists(AppPath + 'autoexec.asc')) then begin + ScriptEditor.LoadRunAndClear(AppPath + 'autoexec.asc'); + mnuRun.Caption := TextByKey('main-menu-script-run'); + btnRunScript.Hint := TextByKey('main-menu-script-run'); + end; + + if (openScript <> '') then begin + ScriptEditor.LoadScriptFile(openScript); + ScriptEditor.Show; + end; +{$endif} + + //FNrThreads := Nrtreads; + + SplashWindow.Hide; + SplashWindow.Free; +end; + +function TMainForm.SystemErrorMessage: string; +var + P: PChar; +begin + if FormatMessage(Format_Message_Allocate_Buffer + Format_Message_From_System, + nil, + GetLastError, + 0, + @P, + 0, + nil) <> 0 then + begin + Result := P; + LocalFree(Integer(P)) + end + else + Result := ''; +end; +function TMainForm.SystemErrorMessage2(errno:cardinal): string; +var + P: PChar; +begin + if FormatMessage(Format_Message_Allocate_Buffer + Format_Message_From_System, + nil, + errno, + 0, + @P, + 0, + nil) <> 0 then + begin + Result := P; + LocalFree(Integer(P)) + end + else + Result := ''; +end; + +procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + if ConfirmExit and (UndoIndex <> 0) then + if Application.MessageBox(PChar(TextByKey('common-confirmexit')), 'Apophysis', MB_ICONWARNING or MB_YESNO) <> IDYES then + begin + Action := caNone; + exit; + end; + +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + HtmlHelp(0, nil, HH_CLOSE_ALL, 0); + { To capture secondary window positions } + if EditForm.visible then EditForm.Close; + if AdjustForm.visible then AdjustForm.close; + if GradientBrowser.visible then GradientBrowser.close; + if MutateForm.visible then MutateForm.Close; +// if GradientForm.visible then GradientForm.Close; +{$ifdef DisableScripting} +{$else} + if ScriptEditor.visible then ScriptEditor.Close; +{$endif} + + { Stop the render thread } + if RenderForm.Visible then RenderForm.Close; + if assigned(Renderer) then Renderer.Terminate; + if assigned(Renderer) then Renderer.WaitFor; + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Main', True) then + begin + if MainForm.WindowState <> wsMaximized then begin + Registry.WriteInteger('Top', MainForm.Top); + Registry.WriteInteger('Left', MainForm.Left); + Registry.WriteInteger('Width', MainForm.Width); + Registry.WriteInteger('Height', MainForm.Height); + end; + end; + finally + Registry.Free; + end; + Application.ProcessMessages; + CanDrawOnResize := False; + if FileExists(GetEnvVarValue('APPDATA') + '\' + randFilename) then + DeleteFile(GetEnvVarValue('APPDATA') + '\' + randFilename); + if FileExists(GetEnvVarValue('APPDATA') + '\' + undoFilename) then + DeleteFile(GetEnvVarValue('APPDATA') + '\' + undoFilename); + SaveSettings; +end; + +procedure TMainForm.FormDestroy(Sender: TObject); +begin + if assigned(Renderer) then Renderer.Terminate; + if assigned(Renderer) then Renderer.WaitFor; + if assigned(Renderer) then Renderer.Free; + if assigned(FViewImage) then FViewImage.Free; + MainCP.free; + ParseCp.free; + Favorites.Free; +end; + +procedure TMainForm.FormKeyPress(Sender: TObject; var Key: Char); +var + scale: double; +begin + if Key = #27 then begin + case FMouseMoveState of + msZoomWindowMove: + FMouseMoveState := msZoomWindow; + msZoomOutWindowMove: + FMouseMoveState := msZoomOutWindow; + msDragMove: + begin + FMouseMoveState := msDrag; + + scale := FViewScale * Image.Width / FViewImage.Width; + FViewPos.X := FViewPos.X - (FClickRect.Right - FClickRect.Left) / scale; + FViewPos.Y := FViewPos.Y - (FClickRect.Bottom - FClickRect.Top) / scale; + end; + msRotateMove: + FMouseMoveState := msRotate; + end; + DrawImageView; + end; +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} +end; + +{ ****************************** Misc controls ****************************** } + +procedure TMainForm.BackPanelResize(Sender: TObject); +begin + StopThread; + if CanDrawOnResize then + reDrawTimer.Enabled := True; + + ResizeImage; + DrawImageView; +end; + +procedure TMainForm.LoadXMLFlame(filename, name: string); +var + i, p: integer; + FileStrings: TStringList; + ParamStrings: TStringList; + Tokens: TStringList; + time: integer; + ax,bx,cx,dx:integer; + hwn,hr:cardinal; + px:pansichar; +begin + time := -1; + FileStrings := TStringList.Create; + ParamStrings := TStringList.Create; + + if pos('*untitled', name) <> 0 then + begin + Tokens := TStringList.Create; + GetTokens(name, tokens); + time := StrToInt(tokens[1]); + Tokens.free; + end; + try + FileStrings.LoadFromFile(filename); + for i := 0 to FileStrings.Count - 1 do + begin + pname := ''; + ptime := ''; + p := Pos(' 0) then + begin + MainForm.ListXMLScanner.LoadFromBuffer(TCharType(TStringType(FileStrings[i]))); + MainForm.ListXMLScanner.Execute; + if pname <> '' then + begin + if (Trim(pname) = Trim(name)) then + begin + ParamStrings.Add(FileStrings[i]); + Break; + end; + end + else + begin + if ptime='' then ptime:='0'; //hack + if StrToInt(ptime) = time then + begin + ParamStrings.Add(FileStrings[i]); + Break; + end; + end; + end; + end; + repeat + inc(i); + ParamStrings.Add(FileStrings[i]); + until pos('', Lowercase(FileStrings[i])) <> 0; + +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + StopThread; + ParseXML(MainCp,PAramStrings.Text, true); + + mnuSaveUndo.Enabled := false; + mnuUndo.Enabled := False; + mnuPopUndo.Enabled := False; + mnuRedo.enabled := False; + mnuPopRedo.enabled := False; + EditForm.mnuUndo.Enabled := False; + EditForm.mnuRedo.enabled := False; + EditForm.tbUndo.enabled := false; + EditForm.tbRedo.enabled := false; + AdjustForm.btnUndo.enabled := false; + AdjustForm.btnRedo.enabled := false; + btnUndo.Enabled := false; + btnRedo.enabled := false; + + Transforms := MainCp.TrianglesFromCP(MainTriangles); + + UndoIndex := 0; + UndoMax := 0; + if fileExists(GetEnvVarValue('APPDATA') + '\' + undoFilename) then + DeleteFile(GetEnvVarValue('APPDATA') + '\' + undoFilename); + Statusbar.Panels[3].Text := Maincp.name; + RedrawTimer.Enabled := True; + Application.ProcessMessages; + + EditForm.SelectedTriangle := 0; // (?) + + UpdateWindows; + finally + FileStrings.free; + ParamStrings.free; + end; +end; + +procedure TMainForm.ResizeImage; +var + pw, ph: integer; +begin + pw := BackPanel.Width - 2; + ph := BackPanel.Height - 2; + begin + if (MainCP.Width / MainCP.Height) > (pw / ph) then + begin + Image.Width := pw; + Image.Height := round(MainCP.Height / MainCP.Width * pw); + Image.Left := 1; + Image.Top := (ph - Image.Height) div 2; + end + else begin + Image.Height := ph; + Image.Width := round(MainCP.Width / MainCP.Height * ph); + Image.Top := 1; + Image.Left := (pw - Image.Width) div 2; + end; + end; + //MainCP.AdjustScale(Image.Width, Image.Height); +end; + +procedure TMainForm.ListViewChange(Sender: TObject; Item: TListItem; + Change: TItemChange); +var + FStrings: TStringList; + IFSStrings: TStringList; + EntryStrings, Tokens: TStringList; + SavedPal: Boolean; + i, j: integer; + floatcolor: double; + s: string; + Palette: TcolorMap; + name:string; +begin + if (ListView1.SelCount <> 0) and + (Trim(ListView1.Selected.Caption) <> Trim(maincp.name)) then + begin + LastOpenFileEntry := ListView1.Selected.Index + 1; + RedrawTimer.Enabled := False; //? + StopThread; + + if OpenFileType = ftXML then + begin + name:=ListView1.Selected.caption; + ParseLoadingBatch := false; + LoadXMLFlame(OpenFile, name); + AnnoyUser; + end + else + begin + + SavedPal := false; +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + FStrings := TStringList.Create; + IFSStrings := TStringList.Create; + Tokens := TStringList.Create; + EntryStrings := TStringList.Create; + try + FStrings.LoadFromFile(OpenFile); + for i := 0 to FStrings.count - 1 do + if Pos(ListView1.Selected.Caption + ' {', Trim(FStrings[i])) = 1 then + break; + IFSStrings.Add(FStrings[i]); + repeat + inc(i); + IFSStrings.Add(FStrings[i]); + until Pos('}', FStrings[i]) <> 0; + maincp.Clear; // initialize control point for new flame; + maincp.background[0] := 0; + maincp.background[1] := 0; + maincp.background[2] := 0; + maincp.sample_density := defSampleDensity; + maincp.spatial_oversample := defOversample; + maincp.spatial_filter_radius := defFilterRadius; + if OpenFileType = ftFla then + begin + for i := 0 to FStrings.count - 1 do + begin + if Pos(ListView1.Selected.Caption + ' {', Trim(FStrings[i])) = 1 then + break; + end; + inc(i); + while (Pos('}', FStrings[i]) = 0) and (Pos('palette:', FStrings[i]) = 0) do + begin + EntryStrings.Add(FStrings[i]); + inc(i); + end; + if Pos('palette:', FStrings[i]) = 1 then + begin + SavedPal := True; + inc(i); + for j := 0 to 255 do begin + s := FStrings[i]; + GetTokens(s, tokens); + floatcolor := StrToFloat(Tokens[0]); + Palette[j][0] := round(floatcolor); + floatcolor := StrToFloat(Tokens[1]); + Palette[j][1] := round(floatcolor); + floatcolor := StrToFloat(Tokens[2]); + Palette[j][2] := round(floatcolor); + inc(i); + end; + end; + FlameString := EntryStrings.Text; + maincp.ParseString(FlameString); + Transforms := MainCP.NumXForms; + end + else + begin + { Open *.ifs File } + Variation := vLinear; + VarMenus[0].Checked := True; + StringToIFS(IFSStrings.Text); + SetVariation(maincp); + maincp.CalcBoundBox; + end; +// Zoom := maincp.zoom; + Center[0] := maincp.Center[0]; + Center[1] := maincp.Center[1]; +// MainCP.NormalizeWeights; + mnuSaveUndo.Enabled := false; + mnuUndo.Enabled := False; + mnuPopUndo.Enabled := False; + mnuRedo.enabled := False; + mnuPopRedo.enabled := False; + EditForm.mnuUndo.Enabled := False; + EditForm.mnuRedo.enabled := False; + EditForm.tbUndo.enabled := false; + EditForm.tbRedo.enabled := false; + AdjustForm.btnUndo.enabled := false; + AdjustForm.btnRedo.enabled := false; + btnUndo.Enabled := false; + btnRedo.enabled := false; + Transforms := MainCp.TrianglesFromCP(MainTriangles); + // Fix Apophysis 1.0 parameters with negative color parameteres! + for i := 0 to Transforms - 1 do + if maincp.xform[i].color < 0 then maincp.xform[i].color := 0; + if SavedPal then maincp.cmap := Palette; + UndoIndex := 0; + UndoMax := 0; + if fileExists(GetEnvVarValue('APPDATA') + '\' + undoFilename) then + DeleteFile(GetEnvVarValue('APPDATA') + '\' + undoFilename); + maincp.name := ListView.Selected.Caption; + Statusbar.Panels[3].Text := maincp.name; + RedrawTimer.Enabled := True; + Application.ProcessMessages; + UpdateWindows; + finally + IFSStrings.Free; + FStrings.Free; + Tokens.free; + EntryStrings.free; + end; + end; + {if ResizeOnLoad then} + ResizeImage; + PrevListItem := Item; + end; +end; + +procedure TMainForm.UpdateWindows; +begin + if AdjustForm.visible then AdjustForm.UpdateDisplay; + if EditForm.visible then EditForm.UpdateDisplay; + if MutateForm.visible then MutateForm.UpdateDisplay; + if CurvesForm.Visible then CurvesForm.SetCp(MainCp); + +end; + +procedure TMainForm.LoadUndoFlame(index: integer; filename: string); +var + FStrings: TStringList; + IFSStrings: TStringList; + EntryStrings, Tokens: TStringList; + SavedPal: Boolean; + i, j: integer; + s: string; + Palette: TColorMap; +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + FStrings := TStringList.Create; + IFSStrings := TStringList.Create; + Tokens := TStringList.Create; + EntryStrings := TStringList.Create; + try + FStrings.LoadFromFile(filename); + for i := 0 to FStrings.count - 1 do + if Pos(Format('%.4d-', [UndoIndex]), Trim(FStrings[i])) = 1 then + break; + IFSStrings.Add(FStrings[i]); + repeat + inc(i); + IFSStrings.Add(FStrings[i]); + until Pos('}', FStrings[i]) <> 0; + for i := 0 to FStrings.count - 1 do + begin + if Pos(Format('%.4d-', [UndoIndex]), Trim(Lowercase(FStrings[i]))) = 1 then + break; + end; + inc(i); + while (Pos('}', FStrings[i]) = 0) and (Pos('palette:', FStrings[i]) = 0) do + begin + EntryStrings.Add(FStrings[i]); + inc(i); + end; + SavedPal := false; + if Pos('palette:', FStrings[i]) = 1 then + begin + SavedPal := True; + inc(i); + for j := 0 to 255 do begin + s := FStrings[i]; + GetTokens(s, tokens); + Palette[j][0] := StrToInt(Tokens[0]); + Palette[j][1] := StrToInt(Tokens[1]); + Palette[j][2] := StrToInt(Tokens[2]); + inc(i); + end; + end; + maincp.Clear; + FlameString := EntryStrings.Text; + maincp.zoom := 0; + maincp.center[0] := 0; + maincp.center[0] := 0; + maincp.ParseString(FlameString); + maincp.sample_density := defSampleDensity; + Center[0] := maincp.Center[0]; + Center[1] := maincp.Center[1]; +// cp.CalcBoundbox; +// MainCP.NormalizeWeights; + Transforms := MainCp.TrianglesFromCP(MainTriangles); + // Trim undo index from title + maincp.name := Copy(Fstrings[0], 6, length(Fstrings[0]) - 7); + + if SavedPal then maincp.cmap := palette; + if AdjustForm.visible then AdjustForm.UpdateDisplay; + + RedrawTimer.Enabled := True; + UpdateWindows; + finally + IFSStrings.Free; + FStrings.Free; + Tokens.free; + EntryStrings.free; + end; +end; + +procedure TMainForm.ResetLocation; +begin + maincp.zoom := 0; + //maincp.FAngle := 0; + //maincp.Width := Image.Width; + //maincp.Height := Image.Height; + maincp.CalcBoundBox; + center[0] := maincp.center[0]; + center[1] := maincp.center[1]; +end; + + +procedure TMainForm.ListViewEdited(Sender: TObject; Item: TListItem; + var S: string); +begin + if s <> Item.Caption then + + if OpenFIleType = ftXML then + begin + if not RenameXML(Item.Caption, s) then + s := Item.Caption; + end + else + if not RenameIFS(Item.Caption, s) then + s := Item.Caption + +end; + +procedure TMainForm.RedrawTimerTimer(Sender: TObject); +{ Draw flame when timer fires. This seems to stop a lot of errors } +begin + if FMouseMoveState in [msZoomWindowMove, msZoomOutWindowMove, msDragMove, msRotateMove] then exit; + + RedrawTimer.enabled := False; + DrawFlame; +end; + +procedure TMainForm.mnuVRandomClick(Sender: TObject); +begin + mnuVRandom.Checked := True; + StopThread; + UpdateUndo; + inc(MainSeed); + RandSeed := MainSeed; + repeat + Variation := vRandom; + SetVariation(maincp); + until not maincp.blowsup(1000); + inc(randomindex); + MainCp.name := RandomPrefix + RandomDate + '-' + + IntToStr(RandomIndex); + ResetLocation; + RedrawTimer.Enabled := True; + UpdateWindows; +end; + +procedure TMainForm.mnuGradClick(Sender: TObject); +begin + AdjustForm.UpdateDisplay; + AdjustForm.PageControl.TabIndex:=2; + AdjustForm.Show; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.mnuimageClick(Sender: TObject); +begin + //frmImageColoring.Show; +end; + +procedure swapcolor(var clist: array of cardinal; i, j: integer); +var + t: cardinal; +begin + t := clist[j]; + clist[j] := clist[i]; + clist[i] := t; +end; + +function diffcolor(clist: array of cardinal; i, j: integer): cardinal; +var + r1, g1, b1, r2, g2, b2: byte; +begin + r1 := clist[j] and 255; + g1 := clist[j] shr 8 and 255; + b1 := clist[j] shr 16 and 255; + r2 := clist[i] and 255; + g2 := clist[i] shr 8 and 255; + b2 := clist[i] shr 16 and 255; + Result := abs((r1 - r2) * (r1 - r2)) + abs((g1 - g2) * (g1 - g2)) + + abs((b1 - b2) * (b1 - b2)); +end; + +procedure TMainForm.mnuSmoothGradientClick(Sender: TObject); +begin + SmoothPalette; +end; + +procedure TMainForm.SmoothPalette; +{ From Draves' Smooth palette Gimp plug-in } +var + Bitmap: TBitMap; + JPEG: TJPEGImage; + pal: TColorMap; + strings: TStringlist; + ident, FileName: string; + len, len_best, as_is, swapd: cardinal; + cmap_best, original, clist: array[0..255] of cardinal; + p, total, j, rand, tryit, i0, i1, x, y, i, iw, ih: integer; + fn:string; +begin + Total := Trunc(NumTries * TryLength / 100); + p := 0; + Bitmap := TBitmap.Create; + JPEG := TJPEGImage.Create; + strings := TStringList.Create; + try + begin + inc(MainSeed); + RandSeed := MainSeed; + OpenDialog.Filter := Format('%s|*.bmp;*.dib;*.jpg;*.jpeg|%s|*.bmp;*.dib|%s|*.jpg;*.jpeg|%s|*.*', + [TextByKey('common-filter-allimages'), TextByKey('common-filter-bitmap'), + TextByKey('common-filter-jpeg'), TextByKey('common-filter-allfiles')]); + OpenDialog.InitialDir := ImageFolder; + OpenDialog.Title := TextByKey('common-browse'); + OpenDialog.FileName := ''; + if OpenSaveFileDialog(MainForm, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + OpenDialog.FileName := fn; + ImageFolder := ExtractFilePath(OpenDialog.FileName); + Application.ProcessMessages; + len_best := 0; + if (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.BMP') + or (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.DIB') then + Bitmap.LoadFromFile(Opendialog.FileName); + if (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.JPG') + or (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.JPEG') then + begin + JPEG.LoadFromFile(Opendialog.FileName); + with Bitmap do + begin + Width := JPEG.Width; + Height := JPEG.Height; + Canvas.Draw(0, 0, JPEG); + end; + end; + iw := Bitmap.Width; + ih := Bitmap.Height; + for i := 0 to 255 do + begin + { Pick colors from 256 random pixels in the image } + x := random(iw); + y := random(ih); + clist[i] := Bitmap.canvas.Pixels[x, y]; + end; + original := clist; + cmap_best := clist; + for tryit := 1 to NumTries do + begin + clist := original; + // scramble + for i := 0 to 255 do + begin + rand := random(256); + swapcolor(clist, i, rand); + end; + // measure + len := 0; + for i := 0 to 255 do + len := len + diffcolor(clist, i, i + 1); + // improve + for i := 1 to TryLength do + begin + inc(p); + //StatusBar.SimpleText := Format(StringReplace(TextByKey('main-status-calculatingpalette'), '%)', '%%)', [rfReplaceAll, rfIgnoreCase]), [(p div total)]); + i0 := 1 + random(254); + i1 := 1 + random(254); + if ((i0 - i1) = 1) then + begin + as_is := diffcolor(clist, i1 - 1, i1) + diffcolor(clist, i0, i0 + 1); + swapd := diffcolor(clist, i1 - 1, i0) + diffcolor(clist, i1, i0 + 1); + end + else if ((i1 - i0) = 1) then + begin + as_is := diffcolor(clist, i0 - 1, i0) + diffcolor(clist, i1, i1 + 1); + swapd := diffcolor(clist, i0 - 1, i1) + diffcolor(clist, i0, i1 + 1); + end + else + begin + as_is := diffcolor(clist, i0, i0 + 1) + diffcolor(clist, i0, i0 - 1) + + diffcolor(clist, i1, i1 + 1) + diffcolor(clist, i1, i1 - 1); + swapd := diffcolor(clist, i1, i0 + 1) + diffcolor(clist, i1, i0 - 1) + + diffcolor(clist, i0, i1 + 1) + diffcolor(clist, i0, i1 - 1); + end; + if (swapd < as_is) then + begin + swapcolor(clist, i0, i1); + len := abs(len + swapd - as_is); + end; + end; + if (tryit = 1) or (len < len_best) then + begin + cmap_best := clist; + len_best := len; + end; + end; + clist := cmap_best; + // clean + for i := 1 to 1024 do + begin + i0 := 1 + random(254); + i1 := i0 + 1; + as_is := diffcolor(clist, i0 - 1, i0) + diffcolor(clist, i1, i1 + 1); + swapd := diffcolor(clist, i0 - 1, i1) + diffcolor(clist, i0, i1 + 1); + if (swapd < as_is) then + begin + swapcolor(clist, i0, i1); + len_best := len_best + swapd - as_is; + end; + end; + { Convert to TColorMap, Gradient and save } + FileName := lowercase(ExtractFileName(Opendialog.FileName)); + ident := CleanEntry(FileName); + strings.add(ident + ' {'); + strings.add('gradient:'); + strings.add(' title="' + CleanUPRTitle(FileName) + '" smooth=no'); + for i := 0 to 255 do + begin + pal[i][0] := clist[i] and 255; + pal[i][1] := clist[i] shr 8 and 255; + pal[i][2] := clist[i] shr 16 and 255; + j := round(i * (399 / 255)); + strings.Add(' index=' + IntToStr(j) + ' color=' + intToStr(clist[i])); + end; + strings.Add('}'); + SaveGradient(Strings.Text, Ident, defSmoothPaletteFile); + + StopThread; + UpdateUndo; + maincp.cmap := Pal; + maincp.cmapindex := -1; + AdjustForm.UpdateDisplay; + + if EditForm.Visible then EditForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + RedrawTimer.enabled := true; + + end; + StatusBar.SimpleText := ''; + end; + finally + Bitmap.Free; + JPEG.Free; + strings.Free; + end; +end; + +procedure TMainForm.mnuToolbarClick(Sender: TObject); +begin + Toolbar.Visible := not Toolbar.Visible; + mnuToolbar.Checked := Toolbar.visible; +end; + +procedure TMainForm.mnuTraceClick(Sender: TObject); +begin + TraceForm.Show; +end; + +procedure TMainForm.mnuStatusBarClick(Sender: TObject); +begin + Statusbar.Visible := not Statusbar.Visible; + mnuStatusbar.Checked := Statusbar.visible; +end; + +procedure TMainForm.mnuFileContentsClick(Sender: TObject); +begin + ListBackPanel.Visible := not ListBackPanel.Visible; + mnuFileContents.Checked := ListView.Visible; + if ListBackPanel.Visible then Splitter.Width := 4 else Splitter.Width := 0; +end; + +procedure TMainForm.Undo; +begin + if UndoIndex = UndoMax then + SaveFlame(maincp, Format('%.4d-', [UndoIndex]) + maincp.name, + GetEnvVarValue('APPDATA') + '\' + undoFilename); + StopThread; + Dec(UndoIndex); + LoadUndoFlame(UndoIndex, GetEnvVarValue('APPDATA') + '\' + undoFilename); + mnuRedo.Enabled := True; + mnuPopRedo.Enabled := True; + btnRedo.Enabled := True; + EditForm.mnuRedo.Enabled := True; + EditForm.tbRedo.enabled := true; + AdjustForm.btnRedo.enabled := true; + if UndoIndex = 0 then begin + mnuUndo.Enabled := false; + mnuPopUndo.Enabled := false; + btnUndo.Enabled := false; + EditForm.mnuUndo.Enabled := false; + EditForm.tbUndo.enabled := false; + AdjustForm.btnUndo.enabled := false; + end; +end; + +procedure TMainForm.mnuUndoClick(Sender: TObject); +begin + Undo; + StatusBar.Panels[3].Text := maincp.name; +end; + +procedure TMainForm.Redo; +begin + StopThread; + Inc(UndoIndex); + + assert(UndoIndex <= UndoMax, 'Undo list index out of range!'); + + LoadUndoFlame(UndoIndex, GetEnvVarValue('APPDATA') + '\' + undoFilename); + mnuUndo.Enabled := True; + mnuPopUndo.Enabled := True; + btnUndo.Enabled := True; + EditForm.mnuUndo.Enabled := True; + EditForm.tbUndo.enabled := true; + AdjustForm.btnUndo.enabled := true; + if UndoIndex = UndoMax then begin + mnuRedo.Enabled := false; + mnuPopRedo.Enabled := false; + btnRedo.Enabled := false; + EditForm.mnuRedo.Enabled := false; + EditForm.tbRedo.enabled := false; + AdjustForm.btnRedo.enabled := false; + end; +end; + +procedure TMainForm.mnuRedoClick(Sender: TObject); +begin + Redo; + StatusBar.Panels[3].Text := maincp.name; +end; + +procedure TMainForm.mnuExportBitmapClick(Sender: TObject); +begin + SaveDialog.DefaultExt := 'bmp'; + SaveDialog.Filter := Format('%s|*.bmp;*.dib|%s|*.*', [TextByKey('common-filter-bitmap'), TextBykey('common-filter-allfiles')]); + SaveDialog.Filename := maincp.name; + if SaveDialog.Execute then + Image.Picture.Bitmap.SaveToFile(SaveDialog.Filename) +end; + +procedure TMainForm.mnuFullScreenClick(Sender: TObject); +begin + FullScreenForm.ActiveForm := Screen.ActiveForm; + FullScreenForm.Width := Screen.Width; + FullScreenForm.Height := Screen.Height; + FullScreenForm.Top := 0; + FullScreenForm.Left := 0; + FullScreenForm.cp.Copy(maincp); + FullScreenForm.cp.cmap := maincp.cmap; + FullScreenForm.center[0] := center[0]; + FullScreenForm.center[1] := center[1]; + FullScreenForm.Calculate := True; + FullScreenForm.Show; +end; + +procedure TMainForm.mnuRenderClick(Sender: TObject); +var + Ext: string; + NewRender: Boolean; +begin + NewRender := True; + + if Assigned(RenderForm.Renderer) then + if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then + NewRender := false; + + if NewRender then + begin + + if Assigned(RenderForm.Renderer) then RenderForm.Renderer.Terminate; + if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #1 + RenderForm.ResetControls; + RenderForm.PageCtrl.TabIndex := 0; + + case renderFileFormat of + 1: Ext := '.bmp'; + 2: Ext := '.png'; + 3: Ext := '.jpg'; + end; + + //RenderForm.caption := 'Render ' + #39 + maincp.name + #39 + ' to Disk'; + RenderForm.Filename := RenderPath + maincp.name + Ext; + RenderForm.SaveDialog.FileName := RenderPath + maincp.name + Ext; + RenderForm.txtFilename.Text := ChangeFileExt(RenderForm.SaveDialog.Filename, Ext); + + RenderForm.cp.Copy(MainCP); + RenderForm.cp.cmap := maincp.cmap; + RenderForm.zoom := maincp.zoom; + RenderForm.Center[0] := center[0]; + RenderForm.Center[1] := center[1]; + if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #2 + end; + RenderForm.Show; +end; + +procedure TMainForm.mnuRenderAllClick(Sender: TObject); +var + Ext: string; + NewRender: Boolean; +begin + NewRender := True; + + if Assigned(RenderForm.Renderer) then + if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then + NewRender := false; + + if NewRender then + begin + + if Assigned(RenderForm.Renderer) then RenderForm.Renderer.Terminate; + if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #1 + RenderForm.ResetControls; + RenderForm.PageCtrl.TabIndex := 0; + + case renderFileFormat of + 1: Ext := '.bmp'; + 2: Ext := '.png'; + 3: Ext := '.jpg'; + end; + + //RenderForm.caption := 'Render all flames to disk'; + RenderForm.bRenderAll := true; + RenderForm.Filename := RenderPath + maincp.name + Ext; + RenderForm.SaveDialog.FileName := RenderForm.Filename; + RenderForm.txtFilename.Text := ChangeFileExt(RenderForm.SaveDialog.Filename, Ext); + + RenderForm.cp.Copy(MainCP); + RenderForm.cp.cmap := maincp.cmap; + RenderForm.zoom := maincp.zoom; + RenderForm.Center[0] := center[0]; + RenderForm.Center[1] := center[1]; + if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #2 + end; + RenderForm.Show; +end; + +procedure TMainForm.mnuMutateClick(Sender: TObject); +begin + MutateForm.Show; + MutateForm.UpdateDisplay; +end; + +procedure TMainForm.mnuAdjustClick(Sender: TObject); +begin + AdjustForm.UpdateDisplay; + AdjustForm.PageControl.TabIndex := 0; + AdjustForm.Show; +end; + +procedure TMainForm.mnuResetLocationClick(Sender: TObject); +var + scale: double; + dx, dy, cdx, cdy: double; + sina, cosa: extended; +begin + UpdateUndo; + + scale := MainCP.pixels_per_unit / MainCP.Width * power(2, MainCP.zoom); + cdx := MainCP.center[0]; + cdy := MainCP.center[1]; + + ResetLocation; + + cdx := MainCP.center[0] - cdx; + cdy := MainCP.center[1] - cdy; + Sincos(MainCP.FAngle, sina, cosa); + if IsZero(sina) then begin + dy := cdy*cosa {- cdx*sina}; + dx := (cdx {+ dy*sina})/cosa; + end + else begin + dx := cdy*sina + cdx*cosa; + dy := (dx*cosa - cdx)/sina; + end; + FViewPos.x := FViewPos.x - dx * scale * Image.Width; + FViewPos.y := FViewPos.y - dy * scale * Image.Width; + + FViewScale := FViewScale * MainCP.pixels_per_unit / MainCP.Width * power(2, MainCP.zoom) / scale; + + DrawImageView; + + RedrawTimer.enabled := true; + UpdateWindows; +end; + +procedure TMainForm.mnuAboutClick(Sender: TObject); +begin + AboutForm.ShowModal; +end; + +procedure TMainForm.mnuOpenGradientClick(Sender: TObject); +begin + GradientBrowser.Filename := GradientFile; + GradientBrowser.Show; +end; + +procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + if Assigned(RenderForm.Renderer) then + if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then + CanClose := False; + + AboutToExit := CanClose; +end; + +procedure TMainForm.FormActivate(Sender: TObject); +begin + if Assigned(Renderer) then Renderer.Priority := tpNormal; +end; + +procedure TMainForm.FormDeactivate(Sender: TObject); +begin + if Assigned(Renderer) then Renderer.Priority := tpLower; +end; + +procedure TMainForm.mnuCalculateColorsClick(Sender: TObject); +var + i: integer; +begin + StopThread; + UpdateUndo; + for i := 0 to Transforms - 1 do + maincp.xform[i].color := i / (transforms - 1); + RedrawTimer.Enabled := True; + UpdateWindows; +end; + +procedure TMainForm.mnuRandomizeColorValuesClick(Sender: TObject); +var + i: integer; +begin + inc(MainSeed); + RandSeed := MainSeed; + StopThread; + UpdateUndo; + for i := 0 to Transforms - 1 do + maincp.xform[i].color := random; + RedrawTimer.Enabled := True; + UpdateWindows; +end; + + +procedure TMainForm.mnuEditScriptClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Show; +{$endif} +end; + +procedure TMainForm.btnRunClick(Sender: TObject); +begin + {$ifdef DisableScripting} +{$else} + ScriptEditor.RunScript; +{$endif} +end; + +procedure TMainForm.mnuRunClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.RunScript; +{$endif} +end; + +procedure TMainForm.mnuOpenScriptClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.OpenScript; +{$endif} +end; + +procedure TMainForm.mnuStopClick(Sender: TObject); +begin +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} +end; + +procedure TMainForm.mnuImportGimpClick(Sender: TObject); +var + flist: tStringList; +begin + flist := TStringList.Create; + OpenDialog.Filter := Format('%s|*.*', [TextByKey('common-filter-allfiles')]); + try + if OpenDialog.Execute then + begin + flist.loadFromFile(OpenDialog.filename); + maincp.clear; + maincp.ParseStringList(flist); + maincp.Width := Image.Width; + maincp.Height := Image.Height; + maincp.zoom := 0; + maincp.CalcBoundBox; + center[0] := maincp.center[0]; + center[1] := maincp.center[1]; + RedrawTimer.Enabled := True; + Application.ProcessMessages; + Transforms := MainCp.TrianglesFromCP(MainTriangles); + UpdateWindows; + end; + finally + flist.free + end; +end; + +procedure TMainForm.mnuManageFavoritesClick(Sender: TObject); +var + MenuItem: TMenuItem; + i: integer; + s: string; +begin +{$ifdef DisableScripting} +{$else} + if FavoritesForm.ShowModal = mrOK then + begin + if favorites.count <> 0 then + begin + mnuScript.Items[7].free; // remember to increment if add any items above + for i := 0 to Favorites.Count - 1 do + begin + s := ExtractFileName(Favorites[i]); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + MenuItem := mnuScript.Find(s); + if MenuItem <> nil then + MenuItem.Free; + end + end; + GetScripts; + end; +{$endif} +end; + +procedure TMainForm.DisableFavorites; +var + MenuItem: TMenuItem; + i: integer; + s: string; +begin + for i := 0 to Favorites.Count - 1 do + begin + s := ExtractFileName(Favorites[i]); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + MenuItem := mnuScript.Find(s); + if MenuItem <> nil then + MenuItem.Enabled := False; + end; +end; + +procedure TMainForm.EnableFavorites; +var + MenuItem: TMenuItem; + i: integer; + s: string; +begin + for i := 0 to Favorites.Count - 1 do + begin + s := ExtractFileName(Favorites[i]); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + MenuItem := mnuScript.Find(s); + if MenuItem <> nil then + MenuItem.Enabled := True; + end; +end; + +procedure TMainForm.mnuShowFullClick(Sender: TObject); +begin + FullScreenForm.Calculate := False; + FullScreenForm.Show; +end; + +procedure TMainForm.mnuImageSizeClick(Sender: TObject); +begin +// SizeTool.Show; + AdjustForm.UpdateDisplay; + AdjustForm.PageControl.TabIndex:=3; + AdjustForm.Show; +end; + +procedure TMainForm.ApplicationEventsActivate(Sender: TObject); +begin + if GradientInClipboard then + begin +// GradientForm.mnuPaste.enabled := true; +// GradientForm.btnPaste.enabled := true; + AdjustForm.mnuPaste.enabled := true; + AdjustForm.btnPaste.enabled := true; + end + else + begin +// GradientForm.mnuPaste.enabled := false; +// GradientForm.btnPaste.enabled := false; + AdjustForm.mnuPaste.enabled := false; + AdjustForm.btnPaste.enabled := false; + end; + if FlameInClipboard then + begin + mnuPaste.enabled := true; + end + else + begin + mnuPaste.enabled := false; + end; +end; + +procedure TMainForm.ParseXML(var cp1: TControlPoint; const params: string; const ignoreErrors : boolean); +var + i: integer; temp: string; + h, s, v: real; +begin + CurrentFlame := cp1.name; + nxform := 0; + FinalXformLoaded := false; + ActiveXformSet := 0; + XMLPaletteFormat := ''; + XMLPaletteCount := 0; + ParseHandledPluginList := false; + SurpressHandleMissingPlugins := ignoreErrors; +// Parsecp.cmapindex := -2; // generate palette from cmapindex and hue (apo 1 and earlier) +// ParseCp.symmetry := 0; +// ParseCP.finalXformEnabled := false; + //ParseCP.Clear; + + ParseCp.Free; // we're creating this CP from the scratch + ParseCp := TControlPoint.create; // to reset variables properly (randomize) + + //LoadCpFromXmlCompatible(params, ParseCP, temp); + + XMLScanner.LoadFromBuffer(TCharType(TStringType(params))); + XMLScanner.Execute; + + cp1.copy(ParseCp); + if Parsecp.cmapindex = -2 then + begin + if cp1.cmapindex < NRCMAPS then + GetCMap(cp1.cmapindex, 1, cp1.cmap) + {else + ShowMessage('Palette index too high')}; + + if (cp1.hue_rotation > 0) and (cp1.hue_rotation < 1) then begin + for i := 0 to 255 do + begin + RGBToHSV(cp1.cmap[i][0], cp1.cmap[i][1], cp1.cmap[i][2], h, s, v); + h := Round(360 + h + (cp1.hue_rotation * 360)) mod 360; + HSVToRGB(h, s, v, cp1.cmap[i][0], cp1.cmap[i][1], cp1.cmap[i][2]); + end; + end; + end; + + if FinalXformLoaded = false then begin + cp1{MainCP}.xform[nxform].Clear; + cp1{MainCP}.xform[nxform].symmetry := 1; + end; + + if nxform < NXFORMS then + for i := nxform to NXFORMS - 1 do + cp1.xform[i].density := 0; + + // Check for symmetry parameter + if ParseCp.symmetry <> 0 then + begin + add_symmetry_to_control_point(cp1, ParseCp.symmetry); + cp1.symmetry := 0; + end; + + cp1.FillUsedPlugins; + ParseHandledPluginList := false; + SurpressHandleMissingPlugins := false; +end; + +procedure TMainForm.mnuPasteClick(Sender: TObject); +begin + if Clipboard.HasFormat(CF_TEXT) then begin + UpdateUndo; +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + StopThread; + ParseXML(MainCP, PCHAR(Clipboard.AsText), false); + AnnoyUser; + Transforms := MainCp.TrianglesFromCP(MainTriangles); + Statusbar.Panels[3].Text := MainCp.name; + {if ResizeOnLoad then} + ResizeImage; + RedrawTimer.Enabled := True; + Application.ProcessMessages; + UpdateWindows; + end; +end; + +procedure TMainForm.mnuCopyClick(Sender: TObject); +var + txt: string; +begin + txt := Trim(FlameToXML(Maincp, false, false)); + Clipboard.SetTextBuf(PChar(txt)); + mnuPaste.enabled := true; + + AdjustForm.mnuPaste.enabled := False; + AdjustForm.btnPaste.enabled := False; +end; + +function WinShellExecute(const Operation, AssociatedFile: string): Boolean; +var + a1: string; + r: Cardinal; +begin + a1 := Operation; + if a1 = '' then + a1 := 'open'; + + r := ShellExecute( + application.handle + , pchar(a1) + , pchar(AssociatedFile) + , '' + , '' + , SW_SHOWNORMAL + ); + if (r > 32) then WinShellExecute := true + else WinShellExecute := false; +end; + +procedure WinShellOpen(const AssociatedFile: string); +begin + WinShellExecute('open', AssociatedFile); +end; + + +procedure TMainForm.mnuExportFlameClick(Sender: TObject); +var + FileList: Tstringlist; + Ext, ex, Path: string; + cp1: TControlPoint; +begin + if not FileExists(flam3Path) then + begin + Application.MessageBox(PChar(TextByKey('main-status-noflam3')), 'Apophysis', 16); + exit; + end; + case ExportFileFormat of + 1: Ext := 'jpg'; + 2: Ext := 'ppm'; + 3: Ext := 'png'; + end; + FileList := TstringList.Create; + cp1 := TControlPoint.Create; + cp1.copy(Maincp); + ExportDialog.ImageWidth := ExportWidth; + ExportDialog.ImageHeight := ExportHeight; + ExportDialog.Sample_density := ExportDensity; + ExportDialog.Filter_Radius := ExportFilter; + ExportDialog.Oversample := ExportOversample; + try + ExportDialog.Filename := RenderPath + Maincp.name + '.' + Ext; + if ExportDialog.ShowModal = mrOK then + begin + ex := ExtractFileExt(ExportDialog.Filename); + if ExtractFileExt(ExportDialog.Filename) = '.ppm' then + ExportFileFormat := 2 + else if ExtractFileExt(ExportDialog.Filename) = '.png' then + ExportFileFormat := 3 + else + ExportFileFormat := 1; + case ExportFileFormat of + 1: Ext := 'jpg'; + 2: Ext := 'ppm'; + 3: Ext := 'png'; + end; + ExportWidth := ExportDialog.ImageWidth; + ExportHeight := ExportDialog.ImageHeight; + ExportDensity := ExportDialog.Sample_density; + ExportFilter := ExportDialog.Filter_Radius; + ExportOversample := ExportDialog.Oversample; + ExportBatches := ExportDialog.Batches; + ExportEstimator := ExportDialog.Estimator; + ExportEstimatorMin := ExportDialog.EstimatorMin; + ExportEstimatorCurve := ExportDialog.EstimatorCurve; + ExportJitters := ExportDialog.Jitters; + ExportGammaTreshold := ExportDialog.GammaTreshold; + cp1.sample_density := ExportDensity; + cp1.spatial_oversample := ExportOversample; + cp1.spatial_filter_radius := ExportFilter; + cp1.nbatches := ExportBatches; + if (cp1.width <> ExportWidth) or (cp1.Height <> ExportHeight) then + cp1.AdjustScale(ExportWidth, ExportHeight); + cp1.estimator := ExportEstimator; + cp1.estimator_min := ExportEstimatorMin; + cp1.estimator_curve := ExportEstimatorCurve; + cp1.jitters := ExportJitters; + cp1.gamma_threshold := ExportGammaTreshold; + FileList.Text := FlameToXML(cp1, true, false); + FileList.SaveToFile(ChangeFileExt(ExportDialog.Filename, '.flame')); + FileList.Clear; + FileList.Add('@echo off'); + FileList.Add('set verbose=1'); + FileList.Add('set format=' + Ext); + if ExportFileFormat = 1 then + FileList.Add('set jpeg=' + IntToStr(JPEGQuality)); + case ExportDialog.cmbDepth.ItemIndex of + 0: FileList.Add('set bits=16'); + 1: FileList.Add('set bits=32'); + 2: FileList.Add('set bits=33'); + 3: FileList.Add('set bits=64'); + end; + if ExportDialog.udStrips.Position > 1 then + FileList.Add('set nstrips=' + IntToStr(ExportDialog.udStrips.Position)); + if (PNGTransparency > 0) then + FileList.Add('set transparency=1') + else + FileList.Add('set transparency=0'); + FileList.Add('set out=' + ExportDialog.Filename); + FileList.Add('@echo Rendering "' + ExportDialog.Filename + '"'); +{ + FileList.Add(ExtractShortPathName(hqiPath) + ' < ' + ExtractShortPathName(ChangeFileExt(ExportDialog.Filename, '.flame'))); + Path := ExtractShortPathName(ExtractFileDir(ExportDialog.Filename) + '\'); +} + FileList.Add('"' + flam3Path + '" < "' + ChangeFileExt(ExportDialog.Filename, '.flame') + '"'); + Path := ExtractFilePath(ExtractFileDir(ExportDialog.Filename) + '\'); + + FileList.SaveToFile(ChangeFileExt(ExportDialog.Filename, '.bat')); + if ExportDialog.chkRender.Checked then + begin + SetCurrentDir(Path); + WinShellOpen(ChangeFileExt(ExportDialog.Filename, '.bat')); + end; + end; + finally + FileList.Free; + cp1.free; + end; + +end; + +//////////////////////////////////////////////////////////////////////////////// + +procedure ParseCompactColors(cp: TControlPoint; count: integer; in_data: string; alpha: boolean = true); + function HexChar(c: Char): Byte; + begin + case c of + '0'..'9': Result := Byte(c) - Byte('0'); + 'a'..'f': Result := (Byte(c) - Byte('a')) + 10; + 'A'..'F': Result := (Byte(c) - Byte('A')) + 10; + else + Result := 0; + end; + end; +var + i, pos, len: integer; + c: char; + data: string; +begin + // diable generating pallete + if Parsecp.cmapindex = -2 then + Parsecp.cmapindex := -1; + + Assert(Count = 256, 'only 256 color gradients are supported at the moment'); + data := ''; + for i := 1 to Length(in_data) do + begin + c := in_data[i]; + if CharInSet(c,['0'..'9']+['A'..'F']+['a'..'f']) then data := data + c; + end; + + if alpha then len := count * 8 + else len := count * 6; + + Assert(len = Length(data), 'color-data size mismatch'); + + for i := 0 to Count-1 do begin + if alpha then pos := i*8 + 2 + else pos := i*6; + Parsecp.cmap[i][0] := 16 * HexChar(Data[pos + 1]) + HexChar(Data[pos + 2]); + Parsecp.cmap[i][1] := 16 * HexChar(Data[pos + 3]) + HexChar(Data[pos + 4]); + Parsecp.cmap[i][2] := 16 * HexChar(Data[pos + 5]) + HexChar(Data[pos + 6]); + end; +end; + +procedure TMainForm.ListXmlScannerStartTag(Sender: TObject; + TagName: string; Attributes: TAttrList); +begin + pname := String(Attributes.value(TStringType('name'))); + ptime := String(Attributes.value(TStringType('time'))); +end; + +procedure TMainForm.XMLScannerStartTag(Sender: TObject; TagName: string; + Attributes: TAttrList); +var + Tokens: TStringList; + v: TStringType; + ParsePos, i : integer; +begin + Tokens := TStringList.Create; + try + + if TagName='xformset' then // unused in this release... + begin + v := Attributes.Value(TStringType('enabled')); + if v <> '' then ParseCP.finalXformEnabled := (StrToInt(String(v)) <> 0) + else ParseCP.finalXformEnabled := true; + + inc(activeXformSet); + end + else if TagName='flame' then + begin + BeginParsing; + + v := Attributes.value(TStringType('name')); + if v <> '' then Parsecp.name := String(v) else Parsecp.name := 'untitled'; + v := Attributes.Value('time'); + if v <> '' then Parsecp.Time := StrToFloat(String(v)); + v := Attributes.value('palette'); + if v <> '' then + Parsecp.cmapindex := StrToInt(String(v)) + else + Parsecp.cmapindex := -1; + v := Attributes.value('gradient'); + if v <> '' then + Parsecp.cmapindex := StrToInt(String(v)) + else + Parsecp.cmapindex := -1; + ParseCP.hue_rotation := 1; + + v := Attributes.value('hue'); + if v <> '' then Parsecp.hue_rotation := StrToFloat(String(v)); + v := Attributes.Value('brightness'); + if v <> '' then Parsecp.Brightness := StrToFloat(String(v)); + v := Attributes.Value('gamma'); + if v <> '' then Parsecp.gamma := StrToFloat(String(v)); + v := Attributes.Value('vibrancy'); + if v <> '' then Parsecp.vibrancy := StrToFloat(String(v)); + if (LimitVibrancy) and (Parsecp.vibrancy > 1) then Parsecp.vibrancy := 1; + v := Attributes.Value('gamma_threshold'); + if v <> '' then Parsecp.gamma_threshold := StrToFloat(String(v)) + else Parsecp.gamma_threshold := 0; + + v := Attributes.Value('zoom'); + if v <> '' then Parsecp.zoom := StrToFloat(String(v)); + v := Attributes.Value('scale'); + if v <> '' then Parsecp.pixels_per_unit := StrToFloat(String(v)); + v := Attributes.Value('rotate'); + if v <> '' then Parsecp.FAngle := -PI * StrToFloat(String(v))/180; + v := Attributes.Value('angle'); + if v <> '' then Parsecp.FAngle := StrToFloat(String(v)); + + // 3d + v := Attributes.Value('cam_pitch'); + if v <> '' then Parsecp.cameraPitch := StrToFloat(String(v)); + v := Attributes.Value('cam_yaw'); + if v <> '' then Parsecp.cameraYaw := StrToFloat(String(v)); + v := Attributes.Value('cam_dist'); + if v <> '' then Parsecp.cameraPersp := 1/StrToFloat(String(v)); + v := Attributes.Value('cam_perspective'); + if v <> '' then Parsecp.cameraPersp := StrToFloat(String(v)); + v := Attributes.Value('cam_zpos'); + if v <> '' then Parsecp.cameraZpos := StrToFloat(String(v)); + v := Attributes.Value('cam_dof'); + if v <> '' then Parsecp.cameraDOF := abs(StrToFloat(String(v))); + + //density estimation + v := Attributes.Value('estimator_radius'); + if v <> '' then Parsecp.estimator := StrToFloat(String(v)); + v := Attributes.Value('estimator_minimum'); + if v <> '' then Parsecp.estimator_min := StrToFloat(String(v)); + v := Attributes.Value('estimator_curve'); + if v <> '' then Parsecp.estimator_curve := StrToFloat(String(v)); + v := Attributes.Value('enable_de'); + if (v = '1') then Parsecp.enable_de := true; + + v := Attributes.Value('new_linear'); + if (v = '1') then Parsecp.noLinearFix := true + else ParseCp.noLinearFix := false; + + v := Attributes.Value('curves'); + if (v <> '') then begin + GetTokens(String(v), tokens); + ParsePos := -1; + for i := 0 to 3 do + begin + Inc(ParsePos);ParseCp.curvePoints[i][0].x := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curvePoints[i][0].y := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curveWeights[i][0] := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curvePoints[i][1].x := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curvePoints[i][1].y := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curveWeights[i][1] := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curvePoints[i][2].x := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curvePoints[i][2].y := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curveWeights[i][2] := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curvePoints[i][3].x := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curvePoints[i][3].y := StrToFloat(Tokens[ParsePos]); + Inc(ParsePos);ParseCp.curveWeights[i][3] := StrToFloat(Tokens[ParsePos]); + end; + + end; + + try + v := Attributes.Value('center'); + GetTokens(String(v), tokens); + + Parsecp.center[0] := StrToFloat(Tokens[0]); + Parsecp.center[1] := StrToFloat(Tokens[1]); + except + Parsecp.center[0] := 0; + Parsecp.center[1] := 0; + end; + + v := Attributes.Value('size'); + GetTokens(String(v), tokens); + + Parsecp.width := StrToInt(Tokens[0]); + Parsecp.height := StrToInt(Tokens[1]); + + try + v := Attributes.Value('background'); + GetTokens(String(v), tokens); + + Parsecp.background[0] := Floor(StrToFloat(Tokens[0]) * 255); + Parsecp.background[1] := Floor(StrToFloat(Tokens[1]) * 255); + Parsecp.background[2] := Floor(StrToFloat(Tokens[2]) * 255); + except + Parsecp.background[0] := 0; + Parsecp.background[1] := 0; + Parsecp.background[2] := 0; + end; + + v := Attributes.Value('soloxform'); + if v <> '' then Parsecp.soloXform := StrToInt(String(v)); + + v := Attributes.Value('plugins'); + GetTokens(String(v), tokens); + if (tokens.Count > 0) then begin + ParseCP.used_plugins.Clear; + + for i := 0 to tokens.Count - 1 do + ParseCP.used_plugins.Add(tokens[i]); + end; + + v := Attributes.Value('nick'); + if Trim(String(v)) = '' then v := TStringType(SheepNick); + Parsecp.Nick := String(v); + v := Attributes.Value('url'); + if Trim(String(v)) = '' then v := TStringType(SheepUrl); + Parsecp.URL := String(v); + end + else if TagName='palette' then + begin + XMLPaletteFormat := String(Attributes.Value('format')); + XMLPaletteCount := StrToIntDef(String(Attributes.Value('count')), 256); + end; + finally + Tokens.free; + end; +end; + +function flatten_val(Attributes: TAttrList): double; +var + vv: array of double; + vn: array of string; + i: integer; + s: string; + d: boolean; +begin + + SetLength(vv, 24); + SetLength(vn, 24); + + d := false; + + vn[0] := 'linear3D'; vn[1] := 'bubble'; + vn[2] := 'cylinder'; vn[3] := 'zblur'; + vn[4] := 'blur3D'; vn[5] := 'pre_ztranslate'; + vn[6] := 'pre_rotate_x'; vn[7] := 'pre_rotate_y'; + vn[8] := 'ztranslate'; vn[9] := 'zcone'; + vn[10] := 'post_rotate_x'; vn[11] := 'post_rotate_y'; + vn[12] := 'julia3D'; vn[13] := 'julia3Dz'; + vn[14] := 'curl3D_cz'; vn[15] := 'hemisphere'; + vn[16] := 'bwraps2'; vn[17] := 'bwraps'; + vn[18] := 'falloff2'; vn[19] := 'crop'; + vn[20] := 'pre_falloff2'; vn[21] := 'pre_crop'; + vn[22] := 'post_falloff2'; vn[23] := 'post_crop'; + + + for i := 0 to 23 do + begin + s := String(Attributes.Value(TStringType(vn[i]))); + if (s <> '') then vv[i] := StrToFloat(s) + else vv[i] := 0; + d := d or (vv[i] <> 0); + end; + + if (d) then Result := 0 + else Result := 1; + + SetLength(vv, 0); + SetLength(vn, 0); +end; +function linear_val(Attributes: TAttrList): double; +var + vv: array of double; + vn: array of string; + i: integer; + s: string; +begin + SetLength(vv, 2); + SetLength(vn, 2); + + Result := 0; + + vn[0] := 'linear3D'; + vn[1] := 'linear'; + for i := 0 to 1 do + begin + s := String(Attributes.Value(TStringType(vn[i]))); + if (s <> '') then vv[i] := StrToFloat(s) + else vv[i] := 0; + Result := Result + vv[i]; + end; + + SetLength(vv, 0); + SetLength(vn, 0); +end; + +procedure TMainForm.XmlScannerContent(Sender: TObject; Content: String); +begin + if XMLPaletteCount <= 0 then begin + //ShowMessage('ERROR: No colors in palette!'); + Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR); + exit; + end; + if XMLPaletteFormat = 'RGB' then + begin + ParseCompactColors(ParseCP, XMLPaletteCount, Content, false); + end + else if XMLPaletteFormat = 'RGBA' then + begin + ParseCompactColors(ParseCP, XMLPaletteCount, Content); + end + else begin + Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR); + exit; + end; + Parsecp.cmapindex := -1; + + XMLPaletteFormat := ''; + XMLPaletteCount := 0; +end; + +procedure TMainForm.XMLScannerEmptyTag(Sender: TObject; TagName: string; + Attributes: TAttrList); +var + i: integer; + v, l, l3d: TStringType; + d, floatcolor, vl, vl3d: double; + Tokens: TStringList; +begin + + Tokens := TStringList.Create; + try + if (TagName = 'xform') or (TagName = 'finalxform') then + if {(TagName = 'finalxform') and} (FinalXformLoaded) then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR) + else + begin + for i := 0 to Attributes.Count - 1 do begin + if not ScanVariations(String(attributes.Name(i))) and + not ScanVariables(String(attributes.Name(i))) then + CheckAttribute(String(Attributes.Name(i))); + end; + if (TagName = 'finalxform') or (activeXformSet > 0) then FinalXformLoaded := true; + + with ParseCP.xform[nXform] do begin + Clear; + v := Attributes.Value('weight'); + if (v <> '') and (TagName = 'xform') then density := StrToFloat(String(v)); + if (TagName = 'finalxform') then + begin + v := Attributes.Value('enabled'); + if v <> '' then ParseCP.finalXformEnabled := (StrToInt(String(v)) <> 0) + else ParseCP.finalXformEnabled := true; + end; + + if activexformset > 0 then density := 0; // tmp... + + v := Attributes.Value('color'); + if v <> '' then color := StrToFloat(String(v)); + v := Attributes.Value('var_color'); + if v <> '' then pluginColor := StrToFloat(String(v)); + v := Attributes.Value('symmetry'); + if v <> '' then symmetry := StrToFloat(String(v)); + v := Attributes.Value('coefs'); + GetTokens(String(v), tokens); + if Tokens.Count < 6 then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR); + c[0][0] := StrToFloat(Tokens[0]); + c[0][1] := StrToFloat(Tokens[1]); + c[1][0] := StrToFloat(Tokens[2]); + c[1][1] := StrToFloat(Tokens[3]); + c[2][0] := StrToFloat(Tokens[4]); + c[2][1] := StrToFloat(Tokens[5]); + + v := Attributes.Value('post'); + if v <> '' then begin + GetTokens(String(v), tokens); + if Tokens.Count < 6 then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR); + p[0][0] := StrToFloat(Tokens[0]); + p[0][1] := StrToFloat(Tokens[1]); + p[1][0] := StrToFloat(Tokens[2]); + p[1][1] := StrToFloat(Tokens[3]); + p[2][0] := StrToFloat(Tokens[4]); + p[2][1] := StrToFloat(Tokens[5]); + end; + + v := Attributes.Value('chaos'); + if v <> '' then begin + GetTokens(String(v), tokens); + for i := 0 to Tokens.Count-1 do + modWeights[i] := Abs(StrToFloat(Tokens[i])); + end; + //else for i := 0 to NXFORMS-1 do modWeights[i] := 1; + + // for 2.09 flames compatibility + v := Attributes.Value('opacity'); + if v <> '' then begin + if StrToFloat(String(v)) = 0.0 then begin + transOpacity := 0; + end else begin + transOpacity := StrToFloat(String(v)); + end; + end; + + // 7x.9 name tag + v := Attributes.Value('name'); + if v <> '' then begin + TransformName := String(v); + end; + + v := Attributes.Value('plotmode'); + if v <> '' then begin + if v = 'off' then begin + transOpacity := 0; + end; + end; + + // tricky: attempt to convert parameters to 15C+-format if necessary + if (ParseCp.noLinearFix) then + for i := 0 to 1 do + begin + SetVariation(i, 0); + v := TStringType(ReadWithSubst(Attributes, varnames(i))); + //v := Attributes.Value(AnsiString(varnames(i))); + if v <> '' then + SetVariation(i, StrToFloat(String(v))); + end + else begin + SetVariation(0, linear_val(Attributes)); + SetVariation(1, flatten_val(Attributes)); + end; + + // now parse the rest of the variations...as usual + for i := 2 to NRVAR - 1 do + begin + SetVariation(i, 0); + v := TStringType(ReadWithSubst(Attributes, varnames(i))); + //v := Attributes.Value(AnsiString(varnames(i))); + if v <> '' then + SetVariation(i, StrToFloat(String(v))); + end; + + // and the variables + for i := 0 to GetNrVariableNames - 1 do begin + v := TStringType(ReadWithSubst(Attributes, GetVariableNameAt(i))); + //v := Attributes.Value(AnsiString(GetVariableNameAt(i))); + if v <> '' then begin + {$ifndef VAR_STR} + d := StrToFloat(String(v)); + SetVariable(GetVariableNameAt(i), d); + {$else} + SetVariableStr(GetVariableNameAt(i), String(v)); + {$endif} + end; + end; + + // legacy variation/variable notation + v := Attributes.Value('var1'); + if v <> '' then + begin + for i := 0 to NRVAR - 1 do + SetVariation(i, 0); + SetVariation(StrToInt(String(v)), 1); + end; + v := Attributes.Value('var'); + if v <> '' then + begin + for i := 0 to NRVAR - 1 do + SetVariation(i, 0); + GetTokens(String(v), tokens); + if Tokens.Count > NRVAR then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR); + for i := 0 to Tokens.Count - 1 do + SetVariation(i, StrToFloat(Tokens[i])); + end; + end; + Inc(nXform); + end; + if TagName = 'color' then + begin + // disable generating palette + //if Parsecp.cmapindex = -2 then + Parsecp.cmapindex := -1; + + i := StrToInt(String(Attributes.value('index'))); + v := Attributes.value('rgb'); + GetTokens(String(v), tokens); + floatcolor := StrToFloat(Tokens[0]); + Parsecp.cmap[i][0] := round(floatcolor); + floatcolor := StrToFloat(Tokens[1]); + Parsecp.cmap[i][1] := round(floatcolor); + floatcolor := StrToFloat(Tokens[2]); + Parsecp.cmap[i][2] := round(floatcolor); + end; + if TagName = 'colors' then + begin + ParseCompactcolors(Parsecp, StrToInt(String(Attributes.value('count'))), + String(Attributes.value('data'))); + Parsecp.cmapindex := -1; + end; + if TagName = 'symmetry' then + begin + i := StrToInt(String(Attributes.value('kind'))); + Parsecp.symmetry := i; + end; + if TagName = 'xdata' then + begin + Parsecp.xdata := Parsecp.xdata + String(Attributes.value('content')); + end; + finally + Tokens.free; + end; +end; + +procedure TMainForm.mnuFlamepdfClick(Sender: TObject); +begin + WinShellOpen('http://www.flam3.com/flame_draves.pdf'); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.ImageMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + if button = mbMiddle then begin + //FMouseMoveState := msHeight; + exit; + end else if button = mbRight then begin + //FMouseMoveState := msPitchYaw; + camDragValueY := MainCP.cameraPitch * 180.0 / PI; + camDragValueX := MainCP.cameraYaw * 180.0 / PI; + + camDragMode := true; + camDragPos.x := 0; + camDragPos.y := 0; + camDragOld.x := x; + camDragOld.y := y; + camMM := false; + //SetCaptureControl(TControl(Sender)); + + //Screen.Cursor := crNone; + //GetCursorPos(mousepos); // hmmm + //mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); + camDragged := false; + exit; + end; + //if button <> mbLeft then exit; + FClickRect.TopLeft := Point(x, y); + FClickRect.BottomRight := FClickRect.TopLeft; + case FMouseMoveState of + msZoomWindow: + begin + FSelectRect.TopLeft := Point(x, y); + FSelectRect.BottomRight := Point(x, y); + DrawZoomWindow; + +// if ssAlt in Shift then +// FMouseMoveState := msZoomOutWindowMove +// else + FMouseMoveState := msZoomWindowMove; + end; + msZoomOutWindow: + begin + FSelectRect.TopLeft := Point(x, y); + FSelectRect.BottomRight := Point(x, y); + DrawZoomWindow; + +// if ssAlt in Shift then +// FMouseMoveState := msZoomWindowMove +// else + FMouseMoveState := msZoomOutWindowMove; + end; + msDrag: + begin + if not assigned(FViewImage) then exit; + +// FSelectRect.TopLeft := Point(x, y); +// FSelectRect.BottomRight := Point(x, y); + FMouseMoveState := msDragMove; + end; + msRotate: + begin + FClickAngle := arctan2(y-Image.Height/2, Image.Width/2-x); + + FRotateAngle := 0; +// FSelectRect.Left := x; + DrawRotateLines(FRotateAngle); + FMouseMoveState := msRotateMove; + end; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); +const + snap_angle = 15*pi/180; +var + dx, dy, cx, cy, sgn: integer; + sc, vx, vy, scale: double; + q : Extended; +begin +{ + case FMouseMoveState of + msRotate, msRotateMove: + Image.Cursor := crEditRotate; + msDrag, msDragMove: + Image.Cursor := crEditMove; + else + Image.Cursor := crEditArrow; + end; +} + case FMouseMoveState of + msZoomWindowMove, + msZoomOutWindowMove: + begin + if DrawSelection then DrawZoomWindow; + FClickRect.BottomRight := Point(x, y); + dx := x - FClickRect.TopLeft.X; + dy := y - FClickRect.TopLeft.Y; + + if ssShift in Shift then begin + if (dy = 0) or (abs(dx/dy) >= Image.Width/Image.Height) then + dy := Round(dx / Image.Width * Image.Height) + else + dx := Round(dy / Image.Height * Image.Width); + FSelectRect.Left := FClickRect.TopLeft.X - dx; + FSelectRect.Top := FClickRect.TopLeft.Y - dy; + FSelectRect.Right := FClickRect.TopLeft.X + dx; + FSelectRect.Bottom := FClickRect.TopLeft.Y + dy; + end + else if ssCtrl in Shift then begin + FSelectRect.TopLeft := FClickRect.TopLeft; + sgn := IfThen(dy*dx >=0, 1, -1); + if (dy = 0) or (abs(dx/dy) >= Image.Width/Image.Height) then begin + FSelectRect.Right := x; + FSelectRect.Bottom := FClickRect.TopLeft.Y + sgn * Round(dx / Image.Width * Image.Height); + end + else begin + FSelectRect.Right := FClickRect.TopLeft.X + sgn * Round(dy / Image.Height * Image.Width); + FSelectRect.Bottom := y; + end; + end + else begin + sgn := IfThen(dy*dx >=0, 1, -1); + if (dy = 0) or (abs(dx/dy) >= Image.Width/Image.Height) then begin + cy := (y + FClickRect.TopLeft.Y) div 2; + FSelectRect.Left := FClickRect.TopLeft.X; + FSelectRect.Right := x; + FSelectRect.Top := cy - sgn * Round(dx / 2 / Image.Width * Image.Height); + FSelectRect.Bottom := cy + sgn * Round(dx / 2 / Image.Width * Image.Height); + end + else begin + cx := (x + FClickRect.TopLeft.X) div 2; + FSelectRect.Left := cx - sgn * Round(dy / 2 / Image.Height * Image.Width); + FSelectRect.Right := cx + sgn * Round(dy / 2 / Image.Height * Image.Width); + FSelectRect.Top := FClickRect.TopLeft.Y; + FSelectRect.Bottom := y; + end; + end; + DrawZoomWindow; + DrawSelection := true; + end; + msDragMove: + begin + assert(assigned(FviewImage)); + assert(FViewScale <> 0); + + scale := FViewScale * Image.Width / FViewImage.Width; + FViewPos.X := FViewPos.X + (x - FClickRect.Right) / scale; + FViewPos.Y := FViewPos.Y + (y - FClickRect.Bottom) / scale; + //FClickRect.BottomRight := Point(x, y); + + DrawImageView; + end; + msPitchYaw: + begin + if camDragMode and ( (x <> camDragOld.x) or (y <> camDragOld.y) ) then + begin + Inc(camDragPos.x, x - camDragOld.x); + Inc(camDragPos.y, y - camDragOld.y); + + vx := Round6(camDragValueX + camDragPos.x / 10); + vy := Round6(camDragValueY - camDragPos.y / 10); + + MainCP.cameraPitch := vy * PI / 180.0; + MainCP.cameraYaw := vx * PI / 180.0; + + vx := Round(vx); + vy := Round(vy); + + camDragged := True; + //StatusBar.Panels.Items[1].Text := Format('Pitch: %f°, Yaw: %f°', [vx,vy]); + end; + end; + msRotateMove: + begin + if DrawSelection then DrawRotatelines(FRotateAngle); + + FRotateAngle := arctan2(y-Image.Height/2, Image.Width/2-x) - FClickAngle; + if ssShift in Shift then // angle snap + FRotateAngle := Round(FRotateAngle/snap_angle)*snap_angle; + //SelectRect.Left := x; + +// pdjpointgen.Rotate(FRotateAngle); +// FRotateAngle := 0; + + DrawRotatelines(FRotateAngle); + DrawSelection := true; +{ + Image.Refresh; +if AdjustForm.Visible then begin +MainCp.FAngle:=-FRotateAngle; +AdjustForm.UpdateDisplay; +end; +} + end; + end; + FClickRect.BottomRight := Point(x, y); +end; + +function ScaleRect(r: TRect; scale: double): TSRect; +begin + Result.Left := r.Left * scale; + Result.Top := r.Top * scale; + Result.Right := r.Right * scale; + Result.Bottom := r.Bottom * scale; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.ImageMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +var + scale: double; + rs: TSRect; +begin + case FMouseMoveState of + msZoomWindowMove: + begin + DrawZoomWindow; + FMouseMoveState := msZoomWindow; + if (abs(FSelectRect.Left - FSelectRect.Right) < 10) or + (abs(FSelectRect.Top - FSelectRect.Bottom) < 10) then + Exit; // zoom to much or double clicked + + StopThread; + UpdateUndo; + MainCp.ZoomtoRect(ScaleRect(FSelectRect, MainCP.Width / Image.Width)); + + FViewScale := FViewScale * Image.Width / abs(FSelectRect.Right - FSelectRect.Left); + FViewPos.x := FViewPos.x - ((FSelectRect.Right + FSelectRect.Left) - Image.Width)/2; + FViewPos.y := FViewPos.y - ((FSelectRect.Bottom + FSelectRect.Top) - Image.Height)/2; + DrawImageView; + + RedrawTimer.Enabled := True; + UpdateWindows; + end; + msZoomOutWindowMove: + begin + DrawZoomWindow; + FMouseMoveState := msZoomOutWindow; + if (abs(FSelectRect.Left - FSelectRect.Right) < 10) or + (abs(FSelectRect.Top - FSelectRect.Bottom) < 10) then + Exit; // zoom to much or double clicked + + StopThread; + UpdateUndo; + MainCp.ZoomOuttoRect(ScaleRect(FSelectRect, MainCP.Width / Image.Width)); + + scale := Image.Width / abs(FSelectRect.Right - FSelectRect.Left); + FViewScale := FViewScale / scale; + FViewPos.x := scale * (FViewPos.x + ((FSelectRect.Right + FSelectRect.Left) - Image.Width)/2); + FViewPos.y := scale * (FViewPos.y + ((FSelectRect.Bottom + FSelectRect.Top) - Image.Height)/2); + + DrawImageView; + + RedrawTimer.Enabled := True; + UpdateWindows; + end; + msDragMove: + begin + FClickRect.BottomRight := Point(x, y); + FMouseMoveState := msDrag; + + if ((x = 0) and (y = 0)) or // double clicked + ((FClickRect.left = FClickRect.right) and (FClickRect.top = FClickRect.bottom)) + then Exit; + + StopThread; + UpdateUndo; + MainCp.MoveRect(ScaleRect(FClickRect, MainCP.Width / Image.Width)); + + RedrawTimer.Enabled := True; + UpdateWindows; + end; + msRotateMove: + begin + DrawRotatelines(FRotateAngle); + + FMouseMoveState := msRotate; + + if (FRotateAngle = 0) then Exit; // double clicked + + StopThread; + UpdateUndo; + if MainForm_RotationMode = 0 then MainCp.Rotate(FRotateAngle) + else MainCp.Rotate(-FRotateAngle); + + if assigned(FViewImage) then begin + FViewImage.Free; + FViewImage := nil; + DrawImageView; + end; + + RedrawTimer.Enabled := True; + UpdateWindows; + end; + msPitchYaw: + begin + camDragMode := false; + Screen.Cursor := crDefault; + + if camDragged then + begin + camDragged := False; + RedrawTimer.Enabled := True; + UpdateWindows; + end; + + + end; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.DrawImageView; +var + i, j: integer; + bm: TBitmap; + r: TRect; + scale: double; +const + msg = #54; // 'NO PREVIEW'; +var + ok: boolean; + GlobalMemoryInfo: TMemoryStatus; // holds the global memory status information + area: int64; + gridp: integer; +begin + bm := TBitmap.Create; + bm.Width := Image.Width; + bm.Height := Image.Height; + with bm.Canvas do begin + if ShowTransparency then begin + Brush.Color := $F0F0F0; + FillRect(Rect(0, 0, bm.Width, bm.Height)); + Brush.Color := $C0C0C0; + for i := 0 to ((bm.Width - 1) shr 3) do begin + for j := 0 to ((bm.Height - 1) shr 3) do begin + if odd(i + j) then + FillRect(Rect(i shl 3, j shl 3, (i+1) shl 3, (j+1) shl 3)); + end; + end; + end + else begin + Brush.Color := MainCP.background[0] or (MainCP.background[1] shl 8) or (MainCP.background[2] shl 16); + FillRect(Rect(0, 0, bm.Width, bm.Height)); + end; + end; + + ok := false; + if assigned(FViewImage) then begin + scale := FViewScale * Image.Width / FViewImage.Width; + + r.Left := Image.Width div 2 + round(scale * (FViewPos.X - FViewImage.Width/2)); + r.Right := Image.Width div 2 + round(scale * (FViewPos.X + FViewImage.Width/2)); + r.Top := Image.Height div 2 + round(scale * (FViewPos.Y - FViewImage.Height/2)); + r.Bottom := Image.Height div 2 + round(scale * (FViewPos.Y + FViewImage.Height/2)); + + GlobalMemoryInfo.dwLength := SizeOf(GlobalMemoryInfo); + GlobalMemoryStatus(GlobalMemoryInfo); + area := abs(r.Right - r.Left) * int64(abs(r.Bottom - r.Top)); + + if (area * 4 < GlobalMemoryInfo.dwAvailPhys div 2) or + (area <= Screen.Width*Screen.Height*4) then + try + FViewImage.Draw(bm.Canvas, r); + ok := true; + except + end; + + // Gridlines for composition (taken from JK mod by Jed Kelsey) + if (EnableGuides) then begin + with bm.Canvas do begin + Pen.Width := 1; + Pen.Color := TColor(LineCenterColor); //$000000; // Center + MoveTo(0, bm.Height shr 1); LineTo(bm.Width, bm.Height shr 1); + MoveTo(bm.Width shr 1, 0); LineTo(bm.Width shr 1, bm.Height); + Pen.Color := TColor(LineThirdsColor); //$C000C0; // Thirds + gridp := Floor(bm.Height/3); + MoveTo(0, gridp); LineTo(bm.Width, gridp); + MoveTo(0, bm.Height-gridp); LineTo(bm.Width, bm.Height-gridp); + gridp := Floor(bm.Width/3); + MoveTo(gridp, 0); LineTo(gridp, bm.Height); + MoveTo(bm.Width-gridp, 0); LineTo(bm.Width-gridp, bm.Height); + Pen.Color := TColor(LineGRColor); //$0000F0; // "Golden Ratio" (per axis) + gridp := Floor(bm.Height * 0.61803399); + MoveTo(0, gridp); LineTo(bm.Width, gridp); + MoveTo(0, bm.Height-gridp); LineTo(bm.Width, bm.Height-gridp); + gridp := Floor(bm.Width * 0.61803399); + MoveTo(gridp, 0); LineTo(gridp, bm.Height); + MoveTo(bm.Width-gridp, 0); LineTo(bm.Width-gridp, bm.Height); + end; + end; + end; + + if not ok then + with bm.Canvas do + begin + Font.Name := 'Wingdings'; // 'Arial'; + Font.Height := bm.Height div 4; + Font.Color := $808080; + Brush.Style := bsClear; + i := (bm.Width - TextWidth(msg)) div 2; + j := (bm.Height - TextHeight(msg)) div 2; + Font.Color := 0; + TextOut(i+2,j+2, msg); + Font.Color := clWhite; //$808080; + TextOut(i,j, msg); + end; + Image.Picture.Graphic := bm; + //EditForm.PaintBackground; + Image.Refresh; + bm.Free; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.DrawPitchYawLines(YawAngle: double; PitchAngle: double); +var + bkuPen: TPen; + points: array[0..3] of TPoint; + i: integer; +begin + bkuPen := TPen.Create; + bkuPen.Assign(Image.Canvas.Pen); + Image.Canvas.Pen.Mode := pmXor; + Image.Canvas.Pen.Color := clWhite; + Image.Canvas.Pen.Style := psDot; //psDash; + Image.Canvas.Brush.Style := bsClear; + +// Image.Canvas.Rectangle(FSelectRect); + points[0].x := 0; + points[0].y := round((Image.Height / 2) * sin(PitchAngle)); + points[1].x := Image.Width - 1; + points[1].y := points[0].y; + points[2].x := points[1].x; + points[2].y := round((Image.Height) - ((Image.Height / 2) * sin(PitchAngle))); + points[3].x := points[0].x; + points[3].y := points[2].y; + + Image.Canvas.MoveTo(Points[3].x, Points[3].y); + for i := 0 to 3 do begin + Image.Canvas.LineTo(Points[i].x, Points[i].y); + end; + + Image.Canvas.Pen.Assign(bkuPen); + bkuPen.Free; +end; + +procedure TMainForm.DrawRotateLines(Angle: double); +var + bkuPen: TPen; + points: array[0..3] of TPoint; + i,x,y: integer; +begin + bkuPen := TPen.Create; + bkuPen.Assign(Image.Canvas.Pen); + Image.Canvas.Pen.Mode := pmXor; + Image.Canvas.Pen.Color := clWhite; + Image.Canvas.Pen.Style := psDot; //psDash; + Image.Canvas.Brush.Style := bsClear; + +// Image.Canvas.Rectangle(FSelectRect); + points[0].x := (Image.Width div 2)-1; + points[0].y := (Image.Height div 2)-1; + points[1].x := (Image.Width div 2)-1; + points[1].y := -Image.Height div 2; + points[2].x := -Image.Width div 2; + points[2].y := -Image.Height div 2; + points[3].x := -Image.Width div 2; + points[3].y := (Image.Height div 2)-1; + + for i := 0 to 3 do begin + x := points[i].x; + y := points[i].y; + + points[i].x := round(cos(Angle) * x + sin(Angle) * y) + Image.Width div 2; + points[i].y := round(-sin(Angle) * x + cos(Angle) * y) + Image.Height div 2; + end; + + Image.Canvas.MoveTo(Points[3].x, Points[3].y); + for i := 0 to 3 do begin + Image.Canvas.LineTo(Points[i].x, Points[i].y); + end; + + Image.Canvas.Pen.Assign(bkuPen); + bkuPen.Free; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.DrawZoomWindow; +const + cornerSize = 32; +var + bkuPen: TPen; + dx, dy, cx, cy: integer; + l, r, t, b: integer; +begin + bkuPen := TPen.Create; + bkuPen.Assign(Image.Canvas.Pen); + with Image.Canvas do begin + Pen.Mode := pmXor; + Pen.Color := clWhite; + Brush.Style := bsClear; + + Pen.Style := psDot; //psDash; + + if ssShift in FShiftState then + begin + dx := FClickRect.Right - FClickRect.Left; + dy := FClickRect.Bottom - FClickRect.Top; + Rectangle(FClickRect.Left - dx, FClickRect.Top - dy, FClickRect.Right, FClickRect.Bottom); + end + else Rectangle(FClickRect); + + dx := FSelectRect.Right - FSelectRect.Left; + if dx >= 0 then begin + l := FSelectRect.Left - 1; + r := FSelectRect.Right; + end + else begin + dx := -dx; + l := FSelectRect.Right - 1; + r := FSelectRect.Left; + end; + dx := min(dx div 2 - 1, cornerSize); + + dy := FSelectRect.Bottom - FSelectRect.Top; + if dy >= 0 then begin + t := FSelectRect.Top - 1; + b := FSelectRect.Bottom; + end + else begin + dy := -dy; + t := FSelectRect.Bottom - 1; + b := FSelectRect.Top; + end; + dy := min(dy div 2, cornerSize); + + pen.Style := psSolid; + + MoveTo(l + dx, t); + LineTo(l, t); + LineTo(l, t + dy); + MoveTo(r - dx, t); + LineTo(r, t); + LineTo(r, t + dy); + MoveTo(r - dx, b); + LineTo(r, b); + LineTo(r, b - dy); + MoveTo(l + dx, b); + LineTo(l, b); + LineTo(l, b - dy); +{ + cx := (l + r) div 2; + cy := (t + b) div 2; + MoveTo(cx - dx div 2, cy); + LineTo(cx + dx div 2 + 1, cy); + MoveTo(cx, cy - dy div 2); + LineTo(cx, cy + dy div 2 + 1); +} + Pen.Assign(bkuPen); + end; + bkuPen.Free; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.tbzoomwindowClick(Sender: TObject); +begin + FMouseMoveState := msZoomWindow; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.tbzoomoutwindowClick(Sender: TObject); +begin + FMouseMoveState := msZoomOutWindow; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.tbDragClick(Sender: TObject); +begin + FMouseMoveState := msDrag; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.tbRotateClick(Sender: TObject); +begin + FMouseMoveState := msRotate; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.FillVariantMenu; +var + i: integer; + s: string; + NewMenuItem : TMenuItem; +begin + SetLength(VarMenus, NrVar); + + for i := 0 to NRVAR - 1 do begin + NewMenuItem := TMenuItem.Create(self); + s := varnames(i); + NewMenuItem.Caption := uppercase(s[1]) + copy(s, 2, length(s)-1); + NewMenuItem.OnClick := VariantMenuClick; + NewMenuItem.Enabled := True; + NewMenuItem.Name := 'var' + intTostr(i); + NewMenuItem.Tag := i; + NewMenuItem.GroupIndex := 2; + NewMenuItem.RadioItem := True; + VarMenus[i] := NewMenuItem; + if i < NumBuiltinVars then + mnuBuiltinVars.Add(NewMenuItem) + else + mnuPluginVars.Add(NewMenuItem); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// + +procedure TMainForm.VariantMenuClick(Sender: TObject); +begin + TMenuItem(Sender).Checked := True; + UpdateUndo; + Variation := TVariation(TMenuItem(Sender).Tag); + SetVariation(maincp); + ResetLocation; + RedrawTimer.Enabled := True; + UpdateWindows; +end; + +//--Z--//////////////////////////////////////////////////////////////////////// + +procedure TMainForm.tbQualityBoxKeyPress(Sender: TObject; var Key: Char); +begin + if key = #13 then + begin + tbQualityBoxSet(Sender); + key := #0; + end + else if key = #27 then tbQualityBox.Text := FloatToStr(defSampleDensity); +end; + +procedure TMainForm.tbQualityBoxSet(Sender: TObject); +var + q: double; +begin + try + q := StrToFloat(tbQualityBox.Text); + except + exit; + end; + defSampleDensity := q; + + StopThread; + RedrawTimer.Enabled := True; + UpdateWindows; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.ImageDblClick(Sender: TObject); +begin + if FMouseMoveState = msRotateMove then + begin +// FRotateAngle := 0; + StopThread; + UpdateUndo; + MainCp.FAngle := 0; + RedrawTimer.Enabled := True; + UpdateWindows; + end + else mnuResetLocationClick(Sender); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.tbShowAlphaClick(Sender: TObject); +begin + //tbShowAlpha.Down := not tbShowAlpha.Down; + ShowTransparency := tbShowAlpha.Down; + + DrawImageView; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.tbShowTraceClick(Sender: TObject); +begin + TraceForm.Show; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TMainForm.FormKeyUpDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +var + MousePos: TPoint; +begin + if Shift <> FShiftState then begin + if FMouseMoveState in [msZoomWindowMove, msZoomOutWindowMove, msRotateMove, msDragMove] then + begin + // hack: to generate MouseMove event + GetCursorPos(MousePos); + SetCursorPos(MousePos.x, MousePos.y); + end; + + if (FMouseMoveState in [msZoomWindowMove, msZoomOutWindowMove]) then + begin + DrawZoomWindow; + FShiftState := Shift; + DrawZoomWindow; + end + else FShiftState := Shift; + end; +end; + +procedure TMainForm.ListViewChanging(Sender: TObject; Item: TListItem; + Change: TItemChange; var AllowChange: Boolean); +var sc, fc: string; +begin + if (Item = nil) or (Sender <> ListView1) then exit; + + sc := ''; fc := ''; + if (ListView1.Selected <> nil) then sc := ListView1.Selected.Caption; + if (ListView1.ItemFocused <> nil) then fc := ListView1.ItemFocused.Caption; + + if (Trim(Item.Caption) = Trim(maincp.name)) and (Item.Selected) and + (Item.Selected) and (Change = ctState) then + begin + if (DoNotAskAboutChange = true) then + begin + exit; + end; + if (UndoIndex <> 0) then + begin + // hack + if (LastCaptionSel = sc) and (LastCaptionFoc = fc) then begin + AllowChange := LastDecision; + if Not AllowChange then begin + ListView1.OnChange := nil; + ListView1.OnChanging := nil; + ListView1.Selected := Item; + ListView1.ItemFocused := Item; + ListView1.OnChanging := ListViewChanging; + ListView1.OnChange := ListViewChange; + end; + Exit; + end; + + LastCaptionSel := sc; + LastCaptionFoc := fc; + + if Application.MessageBox('Do you really want to open another flame? All changes made to the current flame will be lost.', 'Apophysis', MB_ICONWARNING or MB_YESNO) <> IDYES then + begin + AllowChange := false; + ListView1.OnChange := nil; + ListView1.OnChanging := nil; + ListView1.Selected := Item; + ListView1.ItemFocused := Item; + ListView1.OnChanging := ListViewChanging; + ListView1.OnChange := ListViewChange; + end + else + begin + AllowChange := true; + end; + + LastDecision := AllowChange; + end; + end; +end; + +procedure TMainForm.ListViewInfoTip(Sender: TObject; Item: TListItem; + var InfoTip: String); +var + Bitmap: TBitmap; + lcp: TControlPoint; +begin + // flame preview in a tooltip... +{ + BitMap := TBitMap.create; + Bitmap.PixelFormat := pf24bit; + BitMap.Width := 100; + BitMap.Height := 100; + + lcp := TControlPoint.Create; + lcp.Copy(mainCP); + lcp.cmap := mainCP.cmap; + + if Assigned(Renderer) then begin + Renderer.WaitFor; + Renderer.Free; + end; + if not Assigned(Renderer) then + begin + lcp.sample_density := 1; + lcp.spatial_oversample := 1; + lcp.spatial_filter_radius := 0.3; + lcp.AdjustScale(100, 100); + lcp.Transparency := false; + end; + try + Renderer := TRenderThread.Create; + assert(Renderer <> nil); + Renderer.BitsPerSample := 0 + Renderer.TargetHandle := self.Handle; + Renderer.SetCP(lcp); + Renderer.Priority := tpLower; + Renderer.NrThreads := 1 + Renderer.Resume; + Renderer.WaitFor; + except + end; + + + lcp.Free; + Bitmap.Free; +} +end; + +procedure TMainForm.btnViewIconsClick(Sender: TObject); +begin + ListView1.ViewStyle := vsIcon; + btnViewList.Down := false; + btnViewIcons.Down := true; + ClassicListMode := false; + + if (OpenFile <> '') then + ListXML(OpenFile, 1); +end; + +procedure TMainForm.btnViewListClick(Sender: TObject); +begin + ListView1.ViewStyle := vsReport; + btnViewList.Down := true; + btnViewIcons.Down := false; + ClassicListMode := true; +end; + +procedure TMainForm.ListView1Click(Sender: TObject); +begin + //MissingStuff := ''; +end; + +procedure TMainForm.XmlScannerEndTag(Sender: TObject; TagName: String); +var sb : string; +begin + if (TagName='flame') then begin + EndParsing(ParseCP, sb); + MainForm.StatusBar.Panels[0].Text := sb; + end; +end; + +procedure TMainForm.ToolButton19Click(Sender: TObject); +begin + AdjustForm.UpdateDisplay; + AdjustForm.PageControl.TabIndex:=4; + AdjustForm.Show; +end; + +procedure TMainForm.ToolButton7Click(Sender: TObject); +begin + if (LoadForm.Showing = false) then LoadForm.Show; +end; + +procedure TMainForm.ToolButton8Click(Sender: TObject); +var + i:integer; +begin + //EditForm.InvokeResetAll; + if (AlwaysCreateBlankFlame) then EditForm.InvokeResetAll + else TemplateForm.Show; +end; + +procedure TMainForm.FormResize(Sender: TObject); +begin + if (MainForm.Width <= TbBreakWidth) then + Toolbar.Height := 26 * 2 + 8 + else Toolbar.Height := 26; +end; + +function Split(const fText: String; const fSep: Char; fTrim: Boolean=false; fQuotes: Boolean=false):TStringList; +var vI: Integer; + vBuffer: String; + vOn: Boolean; +begin + Result:=TStringList.Create; + vBuffer:=''; + vOn:=true; + for vI:=1 to Length(fText) do + begin + if (fQuotes and(fText[vI]=fSep)and vOn)or(Not(fQuotes) and (fText[vI]=fSep)) then + begin + if fTrim then vBuffer:=Trim(vBuffer); + if vBuffer='' then vBuffer:=fSep; // !!! e.g. split(',**',',')... + if vBuffer[1]=fSep then + vBuffer:=Copy(vBuffer,2,Length(vBuffer)); + Result.Add(vBuffer); + vBuffer:=''; + end; + if fQuotes then + begin + if fText[vI]='"' then + begin + vOn:=Not(vOn); + Continue; + end; + if (fText[vI]<>fSep)or((fText[vI]=fSep)and(vOn=false)) then + vBuffer:=vBuffer+fText[vI]; + end else + if fText[vI]<>fSep then + vBuffer:=vBuffer+fText[vI]; + end; + if vBuffer<>'' then + begin + if fTrim then vBuffer:=Trim(vBuffer); + Result.Add(vBuffer); + end; +end; + +procedure TMainForm.mnuResetUIClick(Sender: TObject); +begin + ListBackPanel.Width := ThumbnailSize + 90; + Splitter.Left := ListBackPanel.Width; +end; + +procedure TMainForm.AutoSaveTimerTimer(Sender: TObject); +var + filename,title : string; + Tag: string; + IFile: TextFile; + FileList, FileListPre: TStringList; + i, p: integer; + erase : boolean; + bakname: string; +begin + erase := false; + filename := AutoSavePath; + title := CleanXMLName(maincp.name) + ' (' + FormatDateTime('MM-dd-yyyy hh:mm:ss', Now) + ')'; + Tag := RemoveExt(filename); + + if FileExists(filename) then begin + FileListPre := TStringList.create; + try + FileListPre.LoadFromFile(filename); + if (FileListPre.Count > 1000) then erase := true; + finally + FileListPre.Free; + end; + + if (erase) then begin + bakname := ChangeFileExt(filename, '.bak'); + if FileExists(bakname) then DeleteFile(bakname); + RenameFile(filename, bakname); + end; + end; + + try + if FileExists(filename) then + begin + bakname := ChangeFileExt(filename, '.temp'); + if FileExists(bakname) then DeleteFile(bakname); + RenameFile(filename, bakname); + + FileList := TStringList.create; + try + FileList.LoadFromFile(bakname); + + if Pos(' 0 then + begin + i := 0; + while Pos('', FileList[i]); + FileList.Delete(i); + end; + end; + +// FileList := TStringList.create; +// try +// FileList.LoadFromFile(filename); + + // fix first line + if (FileList.Count > 0) then begin + FileList[0] := ''; + end; + + if FileList.Count > 2 then + begin + if pos(' 0 then + repeat + FileList.Delete(FileList.Count - 1); + until (Pos('', FileList[FileList.count - 1]) <> 0) + else + repeat + FileList.Delete(FileList.Count - 1); + until (Pos('<' + Tag + '>', FileList[FileList.count - 1]) <> 0) or + (Pos('', FileList[FileList.count - 1]) <> 0); + end else + begin + FileList.Delete(FileList.Count - 1); + end; + + FileList.Add(Trim(FlameToXMLAS(maincp, title, false))); + FileList.Add(''); + FileList.SaveToFile(filename); + + finally + if FileExists(bakname) and not FileExists(filename) then + RenameFile(bakname, filename); + + FileList.Free; + if FileExists(bakname) then DeleteFile(bakname); + end; + end + else + begin + // New file ... easy + AssignFile(IFile, filename); + ReWrite(IFile); + Writeln(IFile, ''); + Write(IFile, FlameToXMLAS(maincp, title, false)); + Writeln(IFile, ''); + CloseFile(IFile); + end; + except on E: EInOutError do + begin + //Application.MessageBox('Cannot save file', 'Apophysis', 16); + end; + end; +end; + +procedure TMainForm.Restorelastautosave1Click(Sender: TObject); +var fn:string; +begin + if (not fileexists(AutoSavePath)) then begin + Application.MessageBox(PChar(TextByKey('main-status-noautosave')), PChar('Apophysis'), MB_ICONERROR); + exit; + end; + +{$ifdef DisableScripting} +{$else} + ScriptEditor.Stopped := True; +{$endif} + fn := AutoSavePath; + MainForm.CurrentFileName := fn; + LastOpenFile := fn; + Maincp.name := ''; + ParamFolder := ExtractFilePath(fn); + ListView.ReadOnly := False; + mnuListRename.Enabled := True; + mnuItemDelete.Enabled := True; + OpenFile := fn; + //MainForm.Caption := AppVersionString + ' - ' + OpenFile; // --Z-- + if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + openFile + else MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + openFile; + OpenFileType := ftXML; + ListXML(fn, 1) +end; + +procedure TMainForm.mnuHelpTopicsClick(Sender: TObject); +var + URL, HelpTopic: string; +begin + {if EditForm.Active then HelpTopic := 'Transform editor.htm' +// else if GradientForm.Active then HelpTopic := 'Gradient window.htm' + else if AdjustForm.Active then HelpTopic := 'Adjust window.htm' + else if MutateForm.Active then HelpTopic := 'Mutation window.htm' + else if RenderForm.Active then HelpTopic := 'Render window.htm'; + HtmlHelp(0, nil, HH_CLOSE_ALL, 0); + URL := AppPath + 'Apophysis 2.0.chm'; + if HelpTopic <> '' then URL := URL + '::\' + HelpTopic; + HtmlHelp(0, PChar(URL), HH_DISPLAY_TOC, 0); } + //if (FileExists(HelpPath)) then + if (HelpPath <> '') then begin + if (not WinShellExecute('open', HelpPath)) then begin + MessageBox(self.Handle, PCHAR(Format(TextByKey('common-genericopenfailure'), [HelpPath])), PCHAR('Apophysis'), MB_ICONHAND); + end; + end else MessageBox(self.Handle, PCHAR(TextByKey('main-status-nohelpfile')), PCHAR('Apophysis'), MB_ICONHAND); + //else MessageBox(self.Handle, PCHAR('Could not find "' + HelpPath + '"'), PCHAR('Error'), MB_ICONHAND); +end; + +function TMainForm.RetrieveXML(cp : TControlPoint):string; +begin + Result := FlameToXML(cp, false, false); +end; + +procedure TMainForm.tbGuidesClick(Sender: TObject); +begin +// tbGuides.Down := not tbGuides.Down; + EnableGuides := tbGuides.Down; + DrawImageView; +end; + +function WinExecAndWait32(FileName: string): integer; +var + zAppName: array[0..1024] of Char; + zCurDir: array[0..255] of Char; + WorkDir: string; + StartupInfo: TStartupInfo; + ProcessInfo: TProcessInformation; + r : dword; +begin + StrPCopy(zAppName, FileName); + GetDir(0, WorkDir); + StrPCopy(zCurDir, WorkDir); + FillChar(StartupInfo, Sizeof(StartupInfo), #0); + StartupInfo.cb := Sizeof(StartupInfo); + + StartupInfo.dwFlags := STARTF_USESHOWWINDOW; + StartupInfo.wShowWindow := 0; + if (not CreateProcess(nil, zAppName, nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo)) then + Result := -1 + else begin + WaitforSingleObject(ProcessInfo.hProcess, INFINITE); + GetExitCodeProcess(ProcessInfo.hProcess, r); + result := r; + CloseHandle(ProcessInfo.hProcess); + CloseHandle(ProcessInfo.hThread); + end; +end; + +procedure TMainForm.mnuTurnFlameToScriptClick(Sender: TObject); +var + txt: string; +begin + txt := Trim(FlameToXML(Maincp, false, false)); + {$ifdef DisableScripting} +{$else} + ScriptEditor.ScriptFromFlame(txt); + ScriptEditor.Show; +{$endif} +end; + +constructor TThumbnailThread.Create(SourceFile : string; FlameNames : TstringList); +var + i : integer; + ListItem : TListItem; +begin + ThumbnailSize := MainForm.UsedThumbnails.Width; + Flames := FlameNames; + FileName := SourceFile; + + MainForm.UsedThumbnails.Clear; + MainForm.UsedThumbnails.Add(ThumbnailPlaceholder, nil); + + MainForm.ListView1.Items.BeginUpdate; + MainForm.ListView1.Items.Clear; + + for i := 0 to FlameNames.Count - 1 do begin + ListItem := MainForm.ListView1.Items.Add; + ListItem.Caption := FlameNames[i]; + ListItem.ImageIndex := 0; + end; + + MainForm.ListView1.Items.EndUpdate; + initialized := true; + + inherited create(True); +end; + +destructor TThumbnailThread.Destroy; +begin + if (Initialized) then begin + ThumbnailSize := 0; + FileName := ''; + if (Flames <> nil) then begin + Flames.Free; + Flames := nil; + end; + Initialized := false; + inherited destroy; + end; +end; + +procedure TThumbnailThread.Execute; +var + Renderer : TRenderer; + cp : TControlPoint; + Thumbnail : TBitmap; + + flameXML : string; + w, h, r : double; + i : integer; + + stored_thumb : TJPegImage; + stored_thumb_data : TBinArray; + stored_thumb_size : integer; + memstream : TMemoryStream; +begin + Inherited; + + Renderer := TRenderer.Create; + cp := TControlPoint.Create; + + //MainForm.ListView1.Items.BeginUpdate; + for i := 0 to Flames.Count - 1 do begin + cp.Clear; + flameXML := LoadXMLFlameText(filename, Flames[i]); + MainForm.ParseXML(cp, PCHAR(flameXML), true); + + if (cp.xdata <> '') then begin + stored_thumb := TJPegImage.Create; + B64Decode(cp.xdata, stored_thumb_data, stored_thumb_size); + memstream := TMemoryStream.Create; + memstream.Size := stored_thumb_size; + stored_thumb_size := Length(stored_thumb_data); + memstream.WriteBuffer(stored_thumb_data[0], stored_thumb_size); + memstream.Seek(0, soBeginning); + //-X- test thumbnail integrity...memstream.SaveToFile('C:\Test.jpg'); + stored_thumb.LoadFromStream(memstream); + memstream.Free; + + w := stored_thumb.Width; h := stored_thumb.Height; + + Thumbnail := TBitmap.Create; + Thumbnail.PixelFormat := pf24bit; + Thumbnail.HandleType := bmDIB; + Thumbnail.Width := ThumbnailSize; + Thumbnail.Height := ThumbnailSize; + Thumbnail.Canvas.Brush.Color := GetSysColor(5); + Thumbnail.Canvas.FillRect(Rect(0, 0, ThumbnailSize, ThumbnailSize)); + Thumbnail.Canvas.Draw(round(ThumbnailSize / 2 - w / 2), round(ThumbnailSize / 2 - h / 2), stored_thumb); + + MainForm.UsedThumbnails.Add(Thumbnail, nil); + MainForm.ListView1.Items[i].ImageIndex := MainForm.UsedThumbnails.Count - 1; + + Thumbnail.Free; + Thumbnail := nil; + + MainForm.ListView1.Refresh; + + stored_thumb.Free; + end else begin + w := cp.Width; h := cp.Height; r := w / h; + if (w < h) then begin + w := r * ThumbnailSize; + h := ThumbnailSize; + end else if (w > h) then begin + h := ThumbnailSize / r; + w := ThumbnailSize; + end else begin + w := ThumbnailSize; + h := ThumbnailSize; + end; + cp.AdjustScale(round(w), round(h)); + cp.Width := round(w); + cp.Height := round(h); + cp.spatial_oversample := defOversample; + cp.spatial_filter_radius := defFilterRadius; + cp.sample_density := 3; + + Thumbnail := nil; + Renderer.SetCP(cp); + Renderer.Render; + + Thumbnail := TBitmap.Create; + Thumbnail.PixelFormat := pf24bit; + Thumbnail.HandleType := bmDIB; + Thumbnail.Width := ThumbnailSize; + Thumbnail.Height := ThumbnailSize; + Thumbnail.Canvas.Brush.Color := GetSysColor(5); + Thumbnail.Canvas.FillRect(Rect(0, 0, ThumbnailSize, ThumbnailSize)); + Thumbnail.Canvas.Draw(round(ThumbnailSize / 2 - w / 2), round(ThumbnailSize / 2 - h / 2), renderer.GetImage); + + MainForm.UsedThumbnails.Add(Thumbnail, nil); + MainForm.ListView1.Items[i].ImageIndex := MainForm.UsedThumbnails.Count - 1; + + Thumbnail.Free; + Thumbnail := nil; + MainForm.ListView1.Refresh; + end; + end; + //MainForm.ListView1.Items.EndUpdate; + + cp.Free; + Renderer.Free; + ThumbnailSize := 0; + FileName := ''; + if (Flames <> nil) then begin + Flames.Free; + Flames := nil; + end; +end; + +procedure ListXMLSimple(FileName: string; sel: integer); +var + FStrings : TStringList; + i, p, n : integer; + title : string; + item : TListItem; +begin + + FStrings := TStringList.Create; + FStrings.LoadFromFile(FileName); + //MainForm.pnlLSPFrame.Visible := true; + MainForm.ListView1.Items.BeginUpdate; + MainForm.ListView1.Items.Clear; + + try + if (Pos(' 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos(' 0) then + begin + MainForm.ListXMLScanner.LoadFromBuffer(TCharType(TStringType(FSTrings[i]))); + MainForm.ListXMLScanner.Execute; + + if Trim(pname) = '' then + Title := '*untitled ' + ptime + else + Title := Trim(pname); + if Title <> '' then + begin + if ((i mod 5) = 0) then MainForm.LoadSaveProgress.Position := round(100*i/FStrings.Count); + item := MainForm.ListView1.Items.Add; item.Caption := Title; item.ImageIndex := -1; + (*Inc(n); if (n > BatchSize) and not brk then begin + if (ID_NO = Application.MessageBox(PAnsiChar('WARNING! The currently loading batch contains more than ' + + inttostr(BatchSize) + ' flames. Do you want to continue loading it?'), PAnsiChar('Apophysis'), + MB_ICONQUESTION or MB_YESNO)) then break else brk := true; + end; *) + end; + end; + end; + end; + finally + FStrings.Free; + end; + + //MainForm.pnlLSPFrame.Visible := false; + MainForm.LoadSaveProgress.Position := 0; + MainForm.ListView1.Items.EndUpdate; + + case sel of + 0: MainForm.ListView1.Selected := MainForm.ListView1.Items[MainForm.ListView1.Items.Count - 1]; + 1: MainForm.ListView1.Selected := MainForm.ListView1.Items[0]; + 2: // do nothing + end; + +end; + +procedure ListXMLThumbnails(FileName: string; sel: integer); +var + FStrings : TStringList; + FFlames : TStringList; + i, p, n : integer; + title : string; + thread : TThumbnailThread; + brk : boolean; +begin + + FStrings := TStringList.Create; + FFlames := TStringList.Create; + + FStrings.LoadFromFile(FileName); + + for i := 0 to MainForm.ListView1.Items.Count - 1 do begin + MainForm.ListView1.Items[i].ImageIndex := -1; + end; + + //MainForm.pnlLSPFrame.Visible := true; + try + if (Pos(' 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos(' 0) then + begin + MainForm.ListXMLScanner.LoadFromBuffer(TCharType(TStringType(FSTrings[i]))); + MainForm.ListXMLScanner.Execute; + + if Trim(pname) = '' then + Title := '*untitled ' + ptime + else + Title := Trim(pname); + if Title <> '' then + begin + if ((i mod 5) = 0) then MainForm.LoadSaveProgress.Position := round(100*i/FStrings.Count); + FFlames.Add(Title); + (*Inc(n); if (n > BatchSize) and not brk then begin + if (ID_NO = Application.MessageBox(PAnsiChar('WARNING! The currently loading batch contains more than ' + + inttostr(BatchSize) + ' flames. Do you want to continue loading it?'), PAnsiChar('Apophysis'), + MB_ICONQUESTION or MB_YESNO)) then break else brk := true; + end; *) + end; + end; + end; + end; + finally + FStrings.Free; + end; + //MainForm.pnlLSPFrame.Visible := false; + MainForm.LoadSaveProgress.Position := 0; + + thread := TThumbnailThread.Create(FileName, FFlames); + case sel of + 0: MainForm.ListView1.Selected := MainForm.ListView1.Items[MainForm.ListView1.Items.Count - 1]; + 1: MainForm.ListView1.Selected := MainForm.ListView1.Items[0]; + 2: // do nothing + end; + + thread.Resume; +end; + +procedure ListXML(FileName: string; sel: integer); +begin + MainForm.ParseLoadingBatch := true; + if (ClassicListMode) or (NXFORMS < 100) then ListXmlSimple(FileName, sel) + else ListXmlThumbnails(FileName, sel); + MainForm.ParseLoadingBatch := false; +end; + +procedure TMainForm.mnuReportFlameClick(Sender: TObject); +var str:string; i : integer; +begin + if (not LoadForm.Visible) then LoadForm.Show; + str := MainCP.name + #13#10 + + '===============================================' + #13#10 + + Format(TextByKey('main-report-transformcount'), [MainCp.NumXForms]) + #13#10 + + Format(TextByKey('main-report-finaltransform'), [IfThen(maincp.finalXformEnabled, TextByKey('common-yes'), TextByKey('common-no'))]) + #13#10 + + TextByKey('main-report-usedplugins'); + MainCP.FillUsedPlugins; + if MainCp.used_plugins.Count = 0 then begin + LoadForm.Output.Text := LoadForm.Output.Text + #13#10 + str + ' ' + TextByKey('main-report-noplugins') + #13#10; + exit; + end; + for i := 0 to MainCP.used_plugins.Count-1 do begin + str := str + #13#10 + ' - ' + MainCP.used_plugins[i]; + end; + LoadForm.Output.Text := LoadForm.Output.Text + #13#10 + str + #13#10; +end; + +procedure TMainForm.mnuManualClick(Sender: TObject); +begin + WinShellOpen('http://dl.dropbox.com/u/20949676/ApophysisUserManual/index.html'); +end; + +procedure TMainForm.CreateSubstMap; +begin + SubstSource.Add('cross2'); SubstTarget.Add('cross'); + SubstSource.Add('Epispiral'); SubstTarget.Add('epispiral'); + SubstSource.Add('Epispiral_n'); SubstTarget.Add('epispiral_n'); + SubstSource.Add('Epispiral_thickness'); SubstTarget.Add('epispiral_thickness'); + SubstSource.Add('Epispiral_holes'); SubstTarget.Add('epispiral_holes'); + SubstSource.Add('bwraps2'); SubstTarget.Add('bwraps'); + SubstSource.Add('bwraps2_cellsize'); SubstTarget.Add('bwraps_cellsize'); + SubstSource.Add('bwraps2_space'); SubstTarget.Add('bwraps_space'); + SubstSource.Add('bwraps2_gain'); SubstTarget.Add('bwraps_gain'); + SubstSource.Add('bwraps2_inner_twist'); SubstTarget.Add('bwraps_inner_twist'); + SubstSource.Add('bwraps2_outer_twist'); SubstTarget.Add('bwraps_outer_twist'); + SubstSource.Add('pre_bwraps2'); SubstTarget.Add('pre_bwraps'); + SubstSource.Add('pre_bwraps2_cellsize'); SubstTarget.Add('pre_bwraps_cellsize'); + SubstSource.Add('pre_bwraps2_space'); SubstTarget.Add('pre_bwraps_space'); + SubstSource.Add('pre_bwraps2_gain'); SubstTarget.Add('pre_bwraps_gain'); + SubstSource.Add('pre_bwraps2_inner_twist'); SubstTarget.Add('pre_bwraps_inner_twist'); + SubstSource.Add('pre_bwraps2_outer_twist'); SubstTarget.Add('pre_bwraps_outer_twist'); + SubstSource.Add('post_bwraps2'); SubstTarget.Add('post_bwraps'); + SubstSource.Add('post_bwraps2_cellsize'); SubstTarget.Add('post_bwraps_cellsize'); + SubstSource.Add('post_bwraps2_space'); SubstTarget.Add('post_bwraps_space'); + SubstSource.Add('post_bwraps2_gain'); SubstTarget.Add('post_bwraps_gain'); + SubstSource.Add('post_bwraps2_inner_twist'); SubstTarget.Add('post_bwraps_inner_twist'); + SubstSource.Add('post_bwraps2_outer_twist'); SubstTarget.Add('post_bwraps_outer_twist'); + SubstSource.Add('bwraps7'); SubstTarget.Add('bwraps'); + SubstSource.Add('bwraps7_cellsize'); SubstTarget.Add('bwraps_cellsize'); + SubstSource.Add('bwraps7_space'); SubstTarget.Add('bwraps_space'); + SubstSource.Add('bwraps7_gain'); SubstTarget.Add('bwraps_gain'); + SubstSource.Add('bwraps7_inner_twist'); SubstTarget.Add('bwraps_inner_twist'); + SubstSource.Add('bwraps7_outer_twist'); SubstTarget.Add('bwraps_outer_twist'); + SubstSource.Add('logn'); SubstTarget.Add('log'); + SubstSource.Add('logn_base'); SubstTarget.Add('log_base'); +end; +function TMainForm.ReadWithSubst(Attributes: TAttrList; attrname: string): string; +var i: integer; v: TStringType; +begin + v := Attributes.Value(TStringType(attrname)); + if (v <> '') then begin + Result := String(v); + Exit; + end; + + for i := 0 to SubstTarget.Count - 1 do begin + if (SubstTarget[i] = attrname) then begin + v := Attributes.Value(TStringType(SubstSource[i])); + if (v <> '') then begin + Result := String(v); + Exit; + end; + end; + end; + + Result := ''; +end; + +end. diff --git a/Forms/Mutate.dfm b/Forms/Mutate.dfm new file mode 100644 index 0000000..998ffd7 --- /dev/null +++ b/Forms/Mutate.dfm @@ -0,0 +1,421 @@ +object MutateForm: TMutateForm + Left = 589 + Top = 326 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSingle + Caption = 'Mutation' + ClientHeight = 398 + ClientWidth = 422 + Color = clBtnFace + Constraints.MinHeight = 400 + Constraints.MinWidth = 400 + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + Icon.Data = { + 0000010001001010000001002000680400001600000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000003E3937FF48403BFF39322FFF28231FFF1B1714FF000000FF0000 + 00003E3937FF48403BFF39322FFF28231FFF1B1714FF000000FF000000000000 + 00000000000089766CFFFCF7F3FFFBECDDFFE5D7C8FFD3C5B6FF181412FF0000 + 000089766CFFFCF7F3FFFBECDDFFE5D7C8FFD3C5B6FF181412FF000000000000 + 000000000000898079FFFCF7F3FFE27239FFC8622FFFE5D7C8FF231E1BFF0000 + 0000898079FFFCF7F3FFE27239FFC8622FFFE5D7C8FF231E1BFF000000000000 + 00000000000089807CFFFEFBFAFFF58250FFCD6531FFFBECDDFF322C29FF0000 + 000089807CFFFEFBFAFFF58250FFCD6531FFFBECDDFF322C29FF000000000000 + 00000000000088807CFFFFFFFFFFFDFBFAFFFCF7F3FFFCF7F3FF3F3835FF0000 + 000088807CFFFFFFFFFFFDFBFAFFFCF7F3FFFCF7F3FF3F3835FF000000000000 + 000000000000887F7AFF89807CFF89807CFF898079FF89766CFF35312EFF0000 + 0000887F7AFF89807CFF89807CFF898079FF89766CFF35312EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000003E3937FF48403BFF39322FFF28231FFF1B1714FF000000FF0000 + 00003E3937FF48403BFF39322FFF28231FFF1B1714FF000000FF000000000000 + 00000000000089766CFFFCF7F3FFFBECDDFFE5D7C8FFD3C5B6FF181412FF0000 + 000089766CFFFCF7F3FFFBECDDFFE5D7C8FFD3C5B6FF181412FF000000000000 + 000000000000898079FFFCF7F3FFE27239FFC8622FFFE5D7C8FF231E1BFF0000 + 0000898079FFFCF7F3FFE27239FFC8622FFFE5D7C8FF231E1BFF000000000000 + 00000000000089807CFFFEFBFAFFF58250FFCD6531FFFBECDDFF322C29FF0000 + 000089807CFFFEFBFAFFF58250FFCD6531FFFBECDDFF322C29FF000000000000 + 00000000000088807CFFFFFFFFFFFDFBFAFFFCF7F3FFFCF7F3FF3F3835FF0000 + 000088807CFFFFFFFFFFFDFBFAFFFCF7F3FFFCF7F3FF3F3835FF000000000000 + 000000000000887F7AFF89807CFF89807CFF898079FF89766CFF35312EFF0000 + 0000887F7AFF89807CFF89807CFF898079FF89766CFF35312EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000FFFF0000C0810000C0810000C0810000C0810000C0810000C0810000FFFF + 0000C0810000C0810000C0810000C0810000C0810000C0810000FFFF0000} + OldCreateOrder = False + Position = poDefault + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + DesignSize = ( + 422 + 398) + PixelsPerInch = 96 + TextHeight = 13 + object GroupBox1: TGroupBox + Left = 8 + Top = 8 + Width = 409 + Height = 273 + Anchors = [akLeft, akTop, akRight, akBottom] + Caption = 'Directions' + TabOrder = 0 + DesignSize = ( + 409 + 273) + object Panel10: TPanel + Left = 12 + Top = 20 + Width = 384 + Height = 238 + Anchors = [akLeft, akTop, akRight, akBottom] + BevelOuter = bvNone + TabOrder = 0 + OnResize = Panel10Resize + object Panel6: TPanel + Left = 112 + Top = 168 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 0 + object Image6: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + object Panel7: TPanel + Left = 0 + Top = 168 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 1 + object Image7: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + object Panel4: TPanel + Left = 224 + Top = 84 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 2 + object Image4: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + object Panel0: TPanel + Left = 112 + Top = 84 + Width = 108 + Height = 80 + HelpContext = 2003 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 3 + object Image0: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = Image0Click + end + end + object Panel8: TPanel + Left = 0 + Top = 84 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 4 + object Image8: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + object Panel3: TPanel + Left = 224 + Top = 0 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 5 + object Image3: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + object Panel2: TPanel + Left = 112 + Top = 0 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 6 + object Image2: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 7 + object Image1: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + object Panel5: TPanel + Left = 224 + Top = 168 + Width = 108 + Height = 80 + BevelOuter = bvLowered + Caption = 'PrevPnl3' + Color = clBlack + TabOrder = 8 + object Image5: TImage + Left = 1 + Top = 1 + Width = 106 + Height = 78 + Align = alClient + PopupMenu = QualityPopup + Stretch = True + OnClick = MutantClick + end + end + end + end + object GroupBox2: TGroupBox + Left = 8 + Top = 288 + Width = 409 + Height = 105 + Anchors = [akLeft, akRight, akBottom] + TabOrder = 1 + DesignSize = ( + 409 + 105) + object scrollTime: TScrollBar + Left = 120 + Top = 20 + Width = 202 + Height = 20 + Anchors = [akLeft, akTop, akRight] + LargeChange = 5 + Max = 50 + Min = 1 + PageSize = 0 + Position = 1 + TabOrder = 0 + OnChange = scrollTimeChange + end + object cmbTrend: TComboBox + Left = 119 + Top = 48 + Width = 282 + Height = 21 + Style = csDropDownList + Anchors = [akLeft, akTop, akRight] + DropDownCount = 16 + TabOrder = 1 + OnChange = cmbTrendChange + Items.Strings = ( + 'Random' + 'Linear' + 'Sinusoidal' + 'Spherical' + 'Swirl' + 'Horseshoe' + 'Polar' + 'Handkerchief' + 'Heart' + 'Disc' + 'Spiral' + 'Hyperbolic' + 'Diamond' + 'Ex' + 'Julia' + 'Bent' + 'Waves' + 'Fisheye' + 'Popcorn') + end + object chkSameNum: TCheckBox + Left = 12 + Top = 78 + Width = 389 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Same no. of transforms' + TabOrder = 2 + OnClick = chkSameNumClick + end + object pnlSpeed: TPanel + Left = 12 + Top = 20 + Width = 101 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Speed' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object txtTime: TEdit + Left = 328 + Top = 20 + Width = 73 + Height = 21 + Anchors = [akTop, akRight] + ReadOnly = True + TabOrder = 4 + Text = '0' + end + object pnlTrend: TPanel + Left = 12 + Top = 48 + Width = 101 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Trend' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + end + object Timer: TTimer + Enabled = False + Interval = 100 + OnTimer = TimerTimer + Left = 168 + Top = 80 + end + object QualityPopup: TPopupMenu + Images = MainForm.Buttons + Left = 144 + Top = 40 + object mnuLowQuality: TMenuItem + Caption = 'Low Quality' + RadioItem = True + OnClick = mnuLowQualityClick + end + object mnuMediumQuality: TMenuItem + Caption = 'Medium Quality' + Checked = True + RadioItem = True + OnClick = mnuMediumQualityClick + end + object mnuHighQuality: TMenuItem + Caption = 'High Quality' + RadioItem = True + OnClick = mnuHighQualityClick + end + object N3: TMenuItem + Caption = '-' + end + object mnuBack: TMenuItem + Caption = 'Previous' + Enabled = False + ImageIndex = 4 + OnClick = mnuBackClick + end + object N1: TMenuItem + Caption = '-' + end + object mnuMaintainSym: TMenuItem + Caption = 'Maintain Symmetry' + Checked = True + OnClick = mnuMaintainSymClick + end + object N2: TMenuItem + Caption = '-' + end + object mnuResetLocation: TMenuItem + Caption = 'Reset Location' + Checked = True + OnClick = mnuResetLocationClick + end + end +end diff --git a/Forms/Mutate.pas b/Forms/Mutate.pas new file mode 100644 index 0000000..04b5c29 --- /dev/null +++ b/Forms/Mutate.pas @@ -0,0 +1,695 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Mutate; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ExtCtrls, StdCtrls, ControlPoint, ComCtrls, Menus, Buttons, Cmap, + RenderingInterface, Translation, Curves; + +type + TMutateForm = class(TForm) + GroupBox1: TGroupBox; + Timer: TTimer; + GroupBox2: TGroupBox; + scrollTime: TScrollBar; + cmbTrend: TComboBox; + chkSameNum: TCheckBox; + QualityPopup: TPopupMenu; + mnuLowQuality: TMenuItem; + mnuMediumQuality: TMenuItem; + mnuHighQuality: TMenuItem; + N3: TMenuItem; + mnuResetLocation: TMenuItem; + mnuBack: TMenuItem; + N1: TMenuItem; + mnuMaintainSym: TMenuItem; + N2: TMenuItem; + Panel10: TPanel; + Panel6: TPanel; + Image6: TImage; + Panel7: TPanel; + Image7: TImage; + Panel4: TPanel; + Image4: TImage; + Panel0: TPanel; + Image0: TImage; + Panel8: TPanel; + Image8: TImage; + Panel3: TPanel; + Image3: TImage; + Panel2: TPanel; + Image2: TImage; + Panel1: TPanel; + Image1: TImage; + Panel5: TPanel; + Image5: TImage; + pnlSpeed: TPanel; + txtTime: TEdit; + pnlTrend: TPanel; + procedure Panel10Resize(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure Image0Click(Sender: TObject); + procedure MutantClick(Sender: TObject); + procedure sbTimeChange(Sender: TObject); + procedure TimerTimer(Sender: TObject); + procedure scrollTimeChange(Sender: TObject); + procedure cmbTrendChange(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure mnuHighQualityClick(Sender: TObject); + procedure mnuLowQualityClick(Sender: TObject); + procedure mnuMediumQualityClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure chkSameNumClick(Sender: TObject); + procedure mnuResetLocationClick(Sender: TObject); + procedure mnuBackClick(Sender: TObject); + procedure mnuMaintainSymClick(Sender: TObject); + private + name, nick, url: string; + bm: TBitmap; + PreviewDensity: double; + Updating: boolean; + cps: array[0..8] of TControlPoint; + Mutants: array[0..8] of TControlPoint; + Render: TRenderer; + Time: double; + bstop: boolean; + brightness, gamma, vibrancy: double; + seed, InitSeed: integer; + procedure RandomSet; + procedure ShowMain; + procedure ShowMutants; + procedure Interpolate; + public + Zoom: Double; + Center: array[0..1] of double; + cmap: TColorMap; + procedure UpdateDisplay; + procedure UpdateFlame; + end; + +var + MutateForm: TMutateForm; + +implementation + +uses + Main, Global, Registry, Editor, Adjust, XFormMan; + +{$R *.DFM} + +procedure TMutateForm.UpdateFlame; +begin + MainForm.StopThread; + MainForm.UpdateUndo; + MainCp.Copy(cps[0]); + Transforms := MainCp.TrianglesFromCP(MainTriangles); + MainCp.cmap := cmap; + MainCp.name := name; // this is kinda funny, + MainCp.nick := nick; // like author's nick can change during mutation? + mainCp.url := url; // hee-heheee :-) + if mnuResetLocation.checked then + begin + MainForm.Mainzoom := cps[0].zoom; + MainForm.Center[0] := cps[0].Center[0]; + MainForm.Center[1] := cps[0].Center[1]; + end; + MainForm.RedrawTimer.enabled := true; + if EditForm.Visible then EditForm.UpdateDisplay; +// if AdjustForm.Visible then AdjustForm.UpdateDisplay; +end; + +procedure TMutateForm.UpdateDisplay; +begin + cps[0].copy(MainCp); + cps[0].AdjustScale(Image0.Width, Image0.Height); + cps[0].cmap := MainCp.cmap; + cmap := MainCp.cmap; + name := Maincp.name; + nick := maincp.nick; + url := maincp.url; + zoom := MainCp.zoom; + center[0] := MainCp.center[0]; + center[1] := MainCp.center[1]; + vibrancy := cps[0].vibrancy; + gamma := cps[0].gamma; + brightness := cps[0].brightness; + Interpolate; + ShowMain; + Application.ProcessMessages; + ShowMutants; +end; + +procedure TMutateForm.ShowMain; +begin + cps[0].Width := Image0.Width; + cps[0].Height := Image0.Height; + cps[0].spatial_oversample := defOversample; + cps[0].spatial_filter_radius := defFilterRadius; + cps[0].sample_density := PreviewDensity; + cps[0].brightness := brightness; + cps[0].gamma := gamma; + cps[0].vibrancy := vibrancy; + cps[0].sample_density := PreviewDensity; + cps[0].cmap := cmap; + cps[0].background := MainCp.background; + if mnuResetLocation.checked then begin + cps[0].CalcBoundbox; + zoom := 0; + center[0] := cps[0].center[0]; + center[1] := cps[0].Center[1]; + end; + cps[0].zoom := zoom; + cps[0].center[0] := center[0]; + cps[0].center[1] := center[1]; +// Render.Compatibility := compatibility; + Render.SetCP(cps[0]); + Render.Render; + BM.Assign(Render.GetImage); + Image0.Picture.Graphic := bm; +end; + +procedure TMutateForm.ShowMutants; +var + i: integer; +begin + if Visible = false then exit; + + Updating := true; + for i := 1 to 8 do + begin + mutants[i].Width := Image1.Width; + mutants[i].Height := Image1.Height; + mutants[i].spatial_filter_radius := defFilterRadius; + mutants[i].spatial_oversample := defOversample; + mutants[i].sample_density := PreviewDensity; + mutants[i].brightness := brightness; + mutants[i].gamma := gamma; + mutants[i].vibrancy := vibrancy; + +{ mutants[i].zoom := 0; + mutants[i].CalcBoundbox; + if not mnuResetLocation.checked then begin + mutants[i].zoom := MainCp.zoom; + mutants[i].CalcBoundbox; + mutants[i].center[0] := MainCp.Center[0]; + mutants[i].center[1] := MainCp.Center[1]; + end; +{ if mnuResetLocation.checked then begin + mutants[i].CalcBoundbox; + zoom := 0; + center[0] := cps[0].center[0]; + center[1] := cps[0].Center[1]; + end; +} + + if mnuResetLocation.checked then + begin + mutants[i].CalcBoundbox; + mutants[i].zoom := 0; +// center[0] := cps[0].center[0]; +// center[1] := cps[0].Center[1]; + end + else begin + mutants[i].zoom := zoom; + mutants[i].center[0] := center[0]; + mutants[i].center[1] := center[1]; + end; + +// Render.Compatibility := compatibility; + Render.SetCP(mutants[i]); + Render.Render; + BM.Assign(Render.GetImage); + case i of + 1: begin + Image1.Picture.Graphic := bm; + Image1.Refresh; + end; + 2: begin + Image2.Picture.Graphic := bm; + Image2.Refresh; + end; + 3: begin + Image3.Picture.Graphic := bm; + Image3.Refresh; + end; + 4: begin + Image4.Picture.Graphic := bm; + Image4.Refresh; + end; + 5: begin + Image5.Picture.Graphic := bm; + Image5.Refresh; + end; + 6: begin + Image6.Picture.Graphic := bm; + Image6.Refresh; + end; + 7: begin + Image7.Picture.Graphic := bm; + Image7.Refresh; + end; + 8: begin + Image8.Picture.Graphic := bm; + Image8.Refresh; + end; + end; + Updating := false; + end; +end; + +procedure TMutateForm.Interpolate; +var i, j, k: Integer; +begin + if MainCp = nil then Exit; + + for i := 1 to 8 do + begin + if bstop then exit; + cps[0].Time := 0; + cps[i].Time := 1; + (* -X- something is not right here... + Mutants[i] may be destroyed already + Investigate? *) + Mutants[i].clear; + Mutants[i].InterpolateX(cps[0], cps[i], Time / 100); + Mutants[i].cmapindex := cps[0].cmapindex; + Mutants[i].cmap := cps[0].cmap; + Mutants[i].background := MainCp.background; + if mnuMaintainSym.Checked then // maintain symmetry + begin + for j := 0 to transforms - 1 do + begin + if cps[0].xform[j].Symmetry = 1 then + begin + mutants[i].xform[j].Assign(cps[0].xform[j]); +{ + mutants[i].xform[j].Symmetry := 1; + mutants[i].xform[j].Color := cps[0].xform[j].color; + mutants[i].xform[j].Density := cps[0].xform[j].Density; + mutants[i].xform[j].c[0][0] := cps[0].xform[j].c[0][0]; + mutants[i].xform[j].c[0][1] := cps[0].xform[j].c[0][1]; + mutants[i].xform[j].c[1][0] := cps[0].xform[j].c[1][0]; + mutants[i].xform[j].c[1][1] := cps[0].xform[j].c[1][1]; + mutants[i].xform[j].c[2][0] := cps[0].xform[j].c[2][0]; + mutants[i].xform[j].c[2][1] := cps[0].xform[j].c[2][1]; + for k := 0 to NRVAR - 1 do + mutants[i].xform[j].vars[k] := cps[0].xform[j].vars[k]; +} + end; + end; + end; + end; +end; + +procedure TMutateForm.RandomSet; +var i: Integer; +begin + RandSeed := seed; + for i := 1 to 8 do + begin + cps[i].clear; + if chkSameNum.checked then + cps[i].RandomCP(transforms, transforms, false) + else + cps[i].RandomCP(mutantMinTransforms, mutantMaxTransforms, false); + cps[i].SetVariation(TVariation(cmbTrend.Items.Objects[cmbTrend.ItemIndex])); + if cps[0].HasFinalXForm = false then + begin + cps[i].xform[cps[i].NumXForms].Clear; + cps[i].xform[cps[i].NumXForms].symmetry := 1; + end; + end; + Interpolate; +end; + +procedure TMutateForm.FormShow(Sender: TObject); +var + Registry: TRegistry; +begin + { Read posution from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Mutate', False) then + begin + if Registry.ValueExists('Left') then + MutateForm.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + MutateForm.Top := Registry.ReadInteger('Top'); + end; + Registry.CloseKey; + finally + Registry.Free; + end; + if (cps[0].xform[0].density <> 0) and Assigned(MainCp) then begin // hmm...!? + Interpolate; + ShowMain; + ShowMutants; + end; +end; + +procedure TMutateForm.FormCreate(Sender: TObject); +var + i: integer; +begin + self.Caption := TextByKey('mutation-title'); + GroupBox1.Caption := TextByKey('mutation-directions'); + pnlSpeed.Caption := TextByKey('mutation-speed'); + pnlTrend.Caption := TextByKey('mutation-trend'); + chkSameNum.Caption := TextByKey('mutation-keepnumberoftransforms'); + mnuLowQuality.Caption := TextByKey('common-lowquality'); + mnuMediumQuality.Caption := TextByKey('common-mediumquality'); + mnuHighQuality.Caption := TextByKey('common-highquality'); + mnuResetLocation.Caption := TextByKey('common-resetlocation'); + mnuMaintainSym.Caption := TextByKey('mutation-maintainsymmetry'); + mnuBack.Caption := TextByKey('mutation-previous'); + cmbTrend.Items.clear; + cmbTrend.AddItem(TextByKey('mutation-randomtrend'), Tobject(vRandom)); + for i:= 0 to NRVAR -1 do begin + cmbTrend.AddItem(varnames(i), Tobject(i)); + end; + + bm := TBitMap.Create; + case MutatePrevQual of + 0: begin + mnuLowQuality.Checked := true; + PreviewDensity := prevLowQuality; + end; + 1: begin + mnuMediumQuality.Checked := true; + PreviewDensity := prevMediumQuality; + end; + 2: begin + mnuHighQuality.Checked := true; + PreviewDensity := prevHighQuality; + end; + end; + Render := TRenderer.Create; + for i := 0 to 8 do + begin + cps[i] := TControlPoint.Create; + Mutants[i] := TControlPoint.Create; + end; + Time := 35; + scrollTime.Position := 25; + cmbTrend.ItemIndex := 0; + InitSeed := random(1234567890); + seed := InitSeed; + RandomSet; +end; + +procedure TMutateForm.FormDestroy(Sender: TObject); +var + i: integer; +begin + Render.Stop; + Render.Free; + for i := 0 to 8 do + begin + cps[i].Free; + Mutants[i].Free; + end; + bm.free; +end; + +procedure TMutateForm.Image0Click(Sender: TObject); +begin + Render.Stop; + mnuBack.Enabled := true; + inc(seed); + RandomSet; + ShowMutants; +end; + +procedure TMutateForm.MutantClick(Sender: TObject); +var + i, j: integer; + cpt: TControlPoint; +begin + cpt := TControlPoint.Create; + cpt.Copy(cps[0]); + bstop := true; + if sender = Image1 then + begin + cps[0].Time := 0; + cps[1].Time := 1; + cps[0].Interpolatex(cps[0], cps[1], Time / 100); + end + else if sender = Image2 then + begin + cps[0].Time := 0; + cps[2].Time := 1; + cps[0].Interpolatex(cps[0], cps[2], Time / 100); + end + else if sender = Image3 then + begin + cps[0].Time := 0; + cps[3].Time := 1; + cps[0].InterpolateX(cps[0], cps[3], Time / 100); + end + else if sender = Image4 then + begin + cps[0].Time := 0; + cps[4].Time := 1; + cps[0].Interpolatex(cps[0], cps[4], Time / 100); + end + else if sender = Image5 then + begin + cps[0].Time := 0; + cps[5].Time := 1; + cps[0].Interpolatex(cps[0], cps[5], Time / 100); + end + else if sender = Image6 then + begin + cps[0].Time := 0; + cps[6].Time := 1; + cps[0].Interpolatex(cps[0], cps[6], Time / 100); + end + else if sender = Image7 then + begin + cps[0].Time := 0; + cps[7].Time := 1; + cps[0].Interpolatex(cps[0], cps[7], Time / 100); + end + else if sender = Image8 then + begin + cps[0].Time := 0; + cps[8].Time := 1; + cps[0].Interpolatex(cps[0], cps[8], Time / 100); + end; + + if mnuMaintainSym.Checked then // maintain symmetry + begin + for i := 0 to transforms - 1 do + begin + if cpt.xform[i].Symmetry = 1 then + begin + cps[0].xform[i].Assign(cpt.xform[i]); +{ + cps[0].xform[i].Symmetry := 1; + cps[0].xform[i].Color := cpt.xform[i].color; + cps[0].xform[i].Density := cpt.xform[i].Density; + cps[0].xform[i].c[0][0] := cpt.xform[i].c[0][0]; + cps[0].xform[i].c[0][1] := cpt.xform[i].c[0][1]; + cps[0].xform[i].c[1][0] := cpt.xform[i].c[1][0]; + cps[0].xform[i].c[1][1] := cpt.xform[i].c[1][1]; + cps[0].xform[i].c[2][0] := cpt.xform[i].c[2][0]; + cps[0].xform[i].c[2][1] := cpt.xform[i].c[2][1]; + for j := 0 to NRVAR - 1 do + cps[0].xform[i].vars[j] := cpt.xform[i].vars[j]; +} + end; + end; + end; + + bstop := false; + ShowMain; + Interpolate; + ShowMutants; + UpdateFlame; + cpt.free; +end; + +procedure TMutateForm.sbTimeChange(Sender: TObject); +begin + bstop := true; + Render.Stop; + Time := scrollTime.Position; + bstop := false; + Interpolate; + ShowMutants; +end; + +procedure TMutateForm.TimerTimer(Sender: TObject); +begin + Timer.Enabled := false; + if (Time <> scrollTime.Position) and (not updating) then + begin + Time := scrollTime.Position; + Interpolate; + ShowMutants; + end; +end; + +procedure TMutateForm.scrollTimeChange(Sender: TObject); +begin + Timer.Enabled := true; + txtTime.Text := FloatToStr(scrollTime.Position / 100); +end; + +procedure TMutateForm.cmbTrendChange(Sender: TObject); +var + i: integer; +begin + for i := 1 to 8 do begin + cps[i].SetVariation(TVariation(cmbTrend.Items.Objects[cmbTrend.ItemIndex])); + end; + + Interpolate; + ShowMutants; +end; + +procedure TMutateForm.btnCancelClick(Sender: TObject); +begin + ModalResult := mrCancel; +end; + +procedure TMutateForm.mnuHighQualityClick(Sender: TObject); +begin + mnuHighQuality.Checked := True; + PreviewDensity := prevHighQuality; + MutatePrevQual := 2; + ShowMain; + ShowMutants; +end; + +procedure TMutateForm.mnuLowQualityClick(Sender: TObject); +begin + mnuLowQuality.Checked := True; + PreviewDensity := prevLowQuality; + MutatePrevQual := 0; + ShowMain; + ShowMutants; +end; + +procedure TMutateForm.mnuMediumQualityClick(Sender: TObject); +begin + mnuMediumQuality.Checked := True; + PreviewDensity := prevMediumQuality; + MutatePrevQual := 1; + ShowMain; + ShowMutants; +end; + +procedure TMutateForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Mutate', True) then + begin + Registry.WriteInteger('Top', MutateForm.Top); + Registry.WriteInteger('Left', MutateForm.Left); + end; + finally + Registry.Free; + end; +end; + +procedure TMutateForm.chkSameNumClick(Sender: TObject); +begin + RandomSet; + Interpolate; + ShowMutants; +end; + +procedure TMutateForm.mnuResetLocationClick(Sender: TObject); +begin + mnuResetLocation.Checked := not mnuResetLocation.Checked; + if not mnuResetLocation.checked then + begin + cps[0].width := MainCp.width; + cps[0].height := MainCp.height; + cps[0].pixels_per_unit := MainCp.pixels_per_unit; + cps[0].AdjustScale(Image0.width, Image0.Height); + cps[0].zoom := MainCp.zoom; + cps[0].center[0] := MainCp.center[0]; + cps[0].center[1] := MainCp.center[1]; + zoom := cps[0].zoom; + center[0] := cps[0].center[0]; + center[1] := cps[0].center[1]; + end; + ShowMain; + ShowMutants; +end; + +procedure TMutateForm.mnuBackClick(Sender: TObject); +begin + Render.Stop; + if seed > InitSeed then + dec(seed); + if seed = InitSeed then mnuBack.enabled := false; + RandomSet; + ShowMutants; +end; + +procedure TMutateForm.mnuMaintainSymClick(Sender: TObject); +begin + mnuMaintainSym.Checked := not mnuMaintainSym.Checked; + Interpolate; + ShowMutants; +end; + +procedure TMutateForm.Panel10Resize(Sender: TObject); +const gap:integer = 4 ; +var + w, h : integer; +begin + w := (Panel10.Width - 2*gap) div 3; + h := (Panel10.Height - 2*gap) div 3; + + Panel0.Width := w; Panel1.Width := w; Panel2.Width := w; + Panel3.Width := w; Panel4.Width := w; Panel5.Width := w; + Panel6.Width := w; Panel7.Width := w; Panel8.Width := w; + Panel0.Height := h; Panel1.Height := h; Panel2.Height := h; + Panel3.Height := h; Panel4.Height := h; Panel5.Height := h; + Panel6.Height := h; Panel7.Height := h; Panel8.Height := h; + + Panel2.Left := w + gap; Panel0.Left := w + gap; Panel6.Left := w + gap; + Panel3.Left := 2*(w + gap); Panel4.Left := 2*(w + gap); Panel5.Left := 2*(w + gap); + + Panel8.Top := h + gap; Panel0.Top := h + gap; Panel4.Top := h + gap; + Panel7.Top := 2*(h + gap); Panel6.Top := 2*(h + gap); Panel5.Top := 2*(h + gap); +end; + +end. + + diff --git a/Forms/Options.dfm b/Forms/Options.dfm new file mode 100644 index 0000000..70621ba --- /dev/null +++ b/Forms/Options.dfm @@ -0,0 +1,2848 @@ +object OptionsForm: TOptionsForm + Left = 899 + Top = 428 + BorderIcons = [biSystemMenu, biMinimize, biMaximize, biHelp] + BorderStyle = bsSingle + Caption = 'Options' + ClientHeight = 438 + ClientWidth = 487 + Color = clBtnFace + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + HelpFile = 'Apophysis 2.0.chm' + Icon.Data = { + 0000010001001010000001002000680400001600000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000007C75 + 73FF4E4B4BFF544F4DFF544F4DFF544F4DFF56514DFF53504CFF524F4BFF524F + 4CFF524F4BFF514E4BFF544E46FF00000000000000000000000000000000D9CF + C8FFFFFFFFFFFBFDFFFFFBFDFFFFFFFFF6FFFFFFF6FFFFFFF6FFFFF9ECFFFFF0 + E1FFFFEAD5FFFFEAD2FF544E46FF00000000000000000000000000000000D2C8 + C1FFFFFFFFFFC4AFA2FFC4AFA2FFFFFBF9FFC4AFA2FFC4AFA2FFC4AFA2FFC4AF + A2FFC4AFA2FFFDDECBFF544E46FF00000000000000000000000000000000D2C8 + C1FFFFFFFFFFFBFDFFFFFBFDFFFFFFFEFCFFFDFAF8FFFBF4EFFFFBEEE6FFFAE9 + DEFFF8E2D2FFFFE2D0FF544E46FF00000000000000000000000000000000D3C9 + C2FFFFFFFFFFC4AFA2FFC4AFA2FFFFFFFEFFC4AFA2FFC4AFA2FFC4AFA2FFC4AF + A2FFC4AFA2FFFFE5D6FF544E46FF00000000000000000000000000000000D1C7 + C0FFFFFFFFFFFBFDFFFFFBFDFFFFFFFFFFFFFEFEFDFFFEFBF8FFFDF6F2FFFCF0 + E8FFFCF0E8FFFFE9DCFF544E46FF00000000000000000000000000000000D1C8 + C1FFFFFFFFFFFBFDFFFFFBFDFFFFFFFFFFFFFFFFFFFFFEFEFCFFB0ADACFF415C + 72FFE3D9D3FFFFEDE3FF544E46FF00000000000000000000000000000000D1C8 + C1FFFFFFFFFFE2E9E9FF5E7584FFDFE4E5FFFFFFFFFFC2CACEFF4A6170FF2EA9 + D6FF0B101BFF5D5C60FFA49D96FF00000000000000001C6629791C6629FFDF9D + 7DFFF1CAB7FF8FA4ACFF86D3E5FF4B6170FFA79289FF4A6170FF61C1DEFF574D + 59FF1FD0FFFF152733FF10070AFF02212EFF4F5665FF59785BFF188C32FFDF9D + 7DFFFFC5A4FFE5C9B9FF8FA4ACFF83E1F6FF4B6170FF7ACDE2FF526067FF68ED + FFFF413D50FF32B2DFFF1D99C8FF1593C4FF14628EFF406651FF29973FFFDF9D + 7DFFDF9D7DFFDF9D7DFFDABAAAFF8FA4ACFF7FE3F9FF538495FF68EDFFFF303A + 4FFF69DBF6FF58D2F3FF40C3EDFF31BBEAFF11A8ECFF50908CFF329E41FF0000 + 0000000000000000000000000000869BA43341576FE168EDFFFF5898AEFF6EEB + FFFF72E1F9FF6ADDF7FF56CFF2FF4BC7EDFF22BAFAFF5FA2A6FF41AC53FF0000 + 0000000000000000000000000000A2AAB7A686E0F7A642566BDD6EEBFFFF6EEB + FFFF6EEBFFFF72E2FAFF67D7F4FF54BDDCFF51728BFF699C89FF85CC85FF0000 + 0000000000000000000096AAB005939EACDA86AEBCE06778854880A5B4FC8097 + A3FF8096A0FF7A8F99FF738593FF5B7080FE7A8B967A41AC538741AC53C00000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000C + 0000000000000000000000000000F0000000F0000000E0000000FFFF0000} + OldCreateOrder = True + Position = poDefault + OnClose = FormClose + OnCreate = FormCreate + OnShow = FormShow + DesignSize = ( + 487 + 438) + PixelsPerInch = 96 + TextHeight = 13 + object Label45: TLabel + Left = 16 + Top = 600 + Width = 244 + Height = 26 + Caption = + 'You must restart Apophysis when changed thumbnail size to see ef' + + 'fect!' + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + Visible = False + WordWrap = True + end + object GroupBox15: TGroupBox + Left = 64 + Top = 108 + Width = 297 + Height = 69 + Caption = 'On render complete' + TabOrder = 2 + object btnBrowseSound: TSpeedButton + Left = 264 + Top = 41 + Width = 24 + Height = 24 + Hint = 'Browse...' + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnBrowseSoundClick + end + object btnPlay: TSpeedButton + Left = 264 + Top = 14 + Width = 24 + Height = 24 + Hint = 'Play' + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFDEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF096314DEEAE0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FF11681B04600FDEEAE0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF1A6F2420732C04 + 600FDEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FF23752E2F833D20732C04600FDEEAE0FF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF2E7C3750A25A2F + 833D20732C04600FDEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FF3883415DB06850A25A2F833D20732C0B6618DEEAE0FF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF438A4C6BBF766B + BF7650A25A2F7639D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FF4B90536BBF76A3DAB02F7639D6EDD9FF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52945AA3DAB02F + 7639D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FF5898602F7639D6EDD9FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF589860D6EDD9FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFD6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnPlayClick + end + object Label44: TLabel + Left = 10 + Top = 44 + Width = 49 + Height = 13 + Caption = 'File name:' + end + object txtSoundFile: TEdit + Left = 64 + Top = 42 + Width = 193 + Height = 21 + HelpContext = 1000 + ParentShowHint = False + ShowHint = False + TabOrder = 0 + end + object chkPlaysound: TCheckBox + Left = 8 + Top = 18 + Width = 81 + Height = 17 + Caption = 'Play sound' + TabOrder = 1 + end + end + object Tabs: TPageControl + Left = 8 + Top = 8 + Width = 475 + Height = 396 + ActivePage = PathsPage + Anchors = [akLeft, akTop, akRight, akBottom] + MultiLine = True + TabOrder = 3 + TabStop = False + object GeneralPage: TTabSheet + HelpContext = 1 + Caption = 'General' + DesignSize = ( + 467 + 368) + object SpeedButton1: TSpeedButton + Left = 437 + Top = 7 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = SpeedButton1Click + end + object pnlJPEGQuality: TPanel + Left = 8 + Top = 36 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'JPEG Quality' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + end + object chkConfirmDel: TCheckBox + Left = 236 + Top = 143 + Width = 221 + Height = 17 + HelpContext = 1005 + Caption = 'Confirm delete' + TabOrder = 0 + end + object chkOldPaletteFormat: TCheckBox + Left = 236 + Top = 92 + Width = 221 + Height = 13 + Caption = 'Save gradient in old file format' + TabOrder = 1 + WordWrap = True + end + object chkConfirmExit: TCheckBox + Left = 236 + Top = 169 + Width = 221 + Height = 17 + HelpContext = 1005 + Caption = 'Confirm exit' + TabOrder = 2 + end + object chkConfirmStopRender: TCheckBox + Left = 236 + Top = 194 + Width = 221 + Height = 17 + Caption = 'Confirm stop render' + TabOrder = 3 + end + object cbUseTemplate: TCheckBox + Left = 236 + Top = 40 + Width = 221 + Height = 17 + Caption = 'Always create blank flame' + TabOrder = 4 + end + object cbMissingPlugin: TCheckBox + Left = 236 + Top = 65 + Width = 221 + Height = 17 + Caption = 'Warn when plugins are missing' + TabOrder = 5 + WordWrap = True + end + object cbEmbedThumbs: TCheckBox + Left = 236 + Top = 115 + Width = 221 + Height = 17 + Caption = 'Enable thumbnail embedding' + TabOrder = 6 + WordWrap = True + end + object chkShowRenderStats: TCheckBox + Left = 236 + Top = 219 + Width = 221 + Height = 17 + Caption = 'Show extended render statistics' + TabOrder = 7 + end + object pnlMultithreading: TPanel + Left = 8 + Top = 92 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Multithreading' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + end + object cbNrTheads: TComboBox + Left = 112 + Top = 92 + Width = 113 + Height = 21 + Style = csDropDownList + ItemIndex = 0 + TabOrder = 9 + Text = 'Off' + Items.Strings = ( + 'Off' + '2' + '3' + '4' + '5' + '6' + '7' + '8' + '9' + '10' + '11' + '12') + end + object pnlPNGTransparency: TPanel + Left = 8 + Top = 64 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'PNG Transparency' + ParentShowHint = False + ShowHint = True + TabOrder = 12 + end + object grpGuidelines: TGroupBox + Left = 8 + Top = 124 + Width = 217 + Height = 141 + Anchors = [akLeft, akTop, akBottom] + Caption = 'Guidelines' + TabOrder = 14 + object cbGL: TCheckBox + Left = 8 + Top = 23 + Width = 193 + Height = 17 + Caption = 'Enable' + TabOrder = 0 + OnClick = cbGLClick + end + object pnlCenterLine: TPanel + Left = 112 + Top = 48 + Width = 97 + Height = 21 + Cursor = crHandPoint + BevelInner = bvRaised + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clBlack + TabOrder = 1 + OnClick = pnlCenterLineClick + object shCenterLine: TShape + Left = 2 + Top = 2 + Width = 89 + Height = 13 + Align = alClient + OnMouseUp = shCenterLineMouseUp + end + end + object pnlThirdsLine: TPanel + Left = 112 + Top = 72 + Width = 97 + Height = 21 + Cursor = crHandPoint + BevelInner = bvRaised + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clBlack + TabOrder = 2 + OnClick = pnlThirdsLineClick + object shThirdsLine: TShape + Left = 2 + Top = 2 + Width = 89 + Height = 13 + Align = alClient + OnMouseUp = shThirdsLineMouseUp + end + end + object pnlGRLine: TPanel + Left = 112 + Top = 96 + Width = 97 + Height = 21 + Cursor = crHandPoint + BevelInner = bvRaised + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clBlack + TabOrder = 3 + OnClick = pnlGRLineClick + object shGRLine: TShape + Left = 2 + Top = 2 + Width = 89 + Height = 13 + Align = alClient + OnMouseUp = shGRLineMouseUp + end + end + object pnlCenter: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Center' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object pnlThirds: TPanel + Left = 8 + Top = 72 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Thirds' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object pnlGoldenRatio: TPanel + Left = 8 + Top = 96 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Golden ratio' + ParentShowHint = False + ShowHint = True + TabOrder = 6 + end + end + object rgRotationMode: TRadioGroup + Left = 5 + Top = 272 + Width = 220 + Height = 81 + Anchors = [akLeft, akBottom] + Caption = 'Rotation Mode' + Items.Strings = ( + 'Rotate image' + 'Rotate frame') + TabOrder = 15 + end + object rgZoomingMode: TRadioGroup + Left = 232 + Top = 272 + Width = 226 + Height = 81 + Anchors = [akLeft, akRight, akBottom] + Caption = 'Zooming mode' + Items.Strings = ( + 'Preserve quality' + 'Preserve speed') + TabOrder = 16 + end + object Panel46: TPanel + Left = 8 + Top = 8 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Language file' + ParentShowHint = False + ShowHint = True + TabOrder = 17 + end + object txtLanguageFile: TComboBox + Left = 112 + Top = 8 + Width = 323 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 18 + end + object cbPNGTransparency: TComboBox + Left = 112 + Top = 64 + Width = 113 + Height = 21 + Style = csDropDownList + ItemIndex = 0 + TabOrder = 13 + Text = 'Disabled' + Items.Strings = ( + 'Disabled' + 'Enabled') + end + object txtJPEGquality: TComboBox + Left = 112 + Top = 36 + Width = 113 + Height = 21 + ItemIndex = 2 + TabOrder = 11 + Text = '100' + Items.Strings = ( + '60' + '80' + '100' + '120') + end + object cbSinglePrecision: TCheckBox + Left = 236 + Top = 243 + Width = 193 + Height = 17 + Caption = 'Use single-precision buffers' + TabOrder = 19 + Visible = False + end + end + object EditorPage: TTabSheet + Caption = 'Editor' + ImageIndex = 8 + DesignSize = ( + 467 + 368) + object GroupBox1: TGroupBox + Left = 8 + Top = 4 + Width = 217 + Height = 61 + Caption = 'Editor Graph' + TabOrder = 0 + object chkUseXFormColor: TCheckBox + Left = 8 + Top = 16 + Width = 201 + Height = 17 + Caption = 'Use transform color' + TabOrder = 0 + end + object chkHelpers: TCheckBox + Left = 8 + Top = 36 + Width = 201 + Height = 17 + Caption = 'Helper lines' + Checked = True + State = cbChecked + TabOrder = 1 + end + end + object rgReferenceMode: TRadioGroup + Left = 240 + Top = 96 + Width = 222 + Height = 105 + Anchors = [akTop, akRight] + Caption = 'Reference Triangle' + ItemIndex = 0 + Items.Strings = ( + 'Normal' + 'Proportional' + 'Wandering (old-style)') + TabOrder = 1 + Visible = False + end + object GroupBox21: TGroupBox + Left = 240 + Top = 4 + Width = 222 + Height = 85 + Anchors = [akTop, akRight] + Caption = 'Editor defaults' + TabOrder = 2 + object chkAxisLock: TCheckBox + Left = 8 + Top = 38 + Width = 209 + Height = 17 + Caption = 'Lock transform axis' + Checked = True + State = cbChecked + TabOrder = 0 + end + object chkExtendedEdit: TCheckBox + Left = 8 + Top = 18 + Width = 209 + Height = 17 + Caption = 'Extended edit mode' + Checked = True + State = cbChecked + TabOrder = 1 + end + object chkXaosRebuild: TCheckBox + Left = 8 + Top = 58 + Width = 209 + Height = 17 + Caption = 'Rebuild xaos links' + Checked = True + State = cbChecked + TabOrder = 2 + end + end + object grpEditorColors: TGroupBox + Left = 8 + Top = 72 + Width = 217 + Height = 129 + Caption = 'Editor colors' + TabOrder = 3 + object pnlBackground: TPanel + Left = 8 + Top = 24 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Background' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object pnlReferenceC: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Reference' + ParentShowHint = False + ShowHint = True + TabOrder = 6 + end + object pnlHelpers: TPanel + Left = 8 + Top = 72 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Helpers' + ParentShowHint = False + ShowHint = True + TabOrder = 7 + end + object pnlGrid: TPanel + Left = 8 + Top = 96 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Grid' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + end + object pnlBackColor: TPanel + Left = 112 + Top = 24 + Width = 97 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clBlack + TabOrder = 0 + OnClick = pnlBackColorClick + object shBackground: TShape + Left = 1 + Top = 1 + Width = 91 + Height = 15 + Align = alClient + Pen.Style = psClear + OnMouseUp = shBackgroundMouseUp + end + end + object pnlReference: TPanel + Left = 112 + Top = 48 + Width = 97 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clGray + TabOrder = 1 + OnClick = pnlReferenceClick + object shRef: TShape + Left = 1 + Top = 1 + Width = 91 + Height = 15 + Align = alClient + Pen.Style = psClear + OnMouseUp = shRefMouseUp + end + end + object pnlHelpersColor: TPanel + Left = 112 + Top = 72 + Width = 97 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clGray + TabOrder = 2 + OnClick = pnlHelpersColorClick + object shHelpers: TShape + Left = 1 + Top = 1 + Width = 91 + Height = 15 + Align = alClient + Pen.Style = psClear + OnMouseUp = shHelpersMouseUp + end + end + object pnlGridColor1: TPanel + Left = 112 + Top = 96 + Width = 49 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clBlack + TabOrder = 3 + OnClick = pnlGridColor1Click + object shGC1: TShape + Left = 1 + Top = 1 + Width = 43 + Height = 15 + Align = alClient + Pen.Style = psClear + OnMouseUp = shGC1MouseUp + end + end + object pnlGridColor2: TPanel + Left = 164 + Top = 96 + Width = 45 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + BorderStyle = bsSingle + Color = clBlack + TabOrder = 4 + OnClick = pnlGridColor2Click + object shGC2: TShape + Left = 1 + Top = 1 + Width = 39 + Height = 15 + Align = alClient + Pen.Style = psClear + OnMouseUp = shGC2MouseUp + end + end + end + object chkShowAllXforms: TCheckBox + Left = 8 + Top = 264 + Width = 454 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Always show both type of transforms' + Checked = True + State = cbChecked + TabOrder = 4 + WordWrap = True + end + object chkEnableEditorPreview: TCheckBox + Left = 8 + Top = 208 + Width = 449 + Height = 17 + Anchors = [akLeft, akTop, akRight] + Caption = 'Enable editor preview' + TabOrder = 5 + OnClick = chkEnableEditorPreviewClick + end + object Panel48: TPanel + Left = 16 + Top = 232 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Transparency' + ParentShowHint = False + ShowHint = True + TabOrder = 6 + end + object tbEPTransparency: TTrackBar + Left = 128 + Top = 230 + Width = 329 + Height = 25 + Anchors = [akLeft, akTop, akRight] + LineSize = 4 + Max = 255 + PageSize = 32 + Frequency = 16 + TabOrder = 7 + end + end + object DisplayPage: TTabSheet + Caption = 'Display' + DesignSize = ( + 467 + 368) + object GroupBox2: TGroupBox + Left = 253 + Top = 84 + Width = 209 + Height = 109 + Anchors = [akTop, akRight] + Caption = 'Preview density' + TabOrder = 1 + object Panel8: TPanel + Left = 8 + Top = 24 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Low quality' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object Panel9: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Medium quality' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object Panel10: TPanel + Left = 8 + Top = 72 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'High quality' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object txtHighQuality: TEdit + Left = 112 + Top = 72 + Width = 81 + Height = 21 + HelpContext = 1014 + TabOrder = 2 + end + object txtMediumQuality: TEdit + Left = 112 + Top = 48 + Width = 81 + Height = 21 + HelpContext = 1013 + TabOrder = 1 + end + object txtLowQuality: TEdit + Left = 112 + Top = 24 + Width = 81 + Height = 21 + HelpContext = 1012 + TabOrder = 0 + end + end + object grpRendering: TGroupBox + Left = 8 + Top = 84 + Width = 217 + Height = 205 + Caption = 'Rendering' + TabOrder = 0 + object Panel1: TPanel + Left = 8 + Top = 24 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Density' + ParentShowHint = False + ShowHint = True + TabOrder = 7 + end + object Panel2: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Gamma' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + end + object Panel3: TPanel + Left = 8 + Top = 72 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Brightness' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + end + object Panel4: TPanel + Left = 8 + Top = 96 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Vibrancy' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + end + object Panel5: TPanel + Left = 8 + Top = 120 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Gamma threshold' + ParentShowHint = False + ShowHint = True + TabOrder = 11 + end + object Panel6: TPanel + Left = 8 + Top = 144 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Oversample' + ParentShowHint = False + ShowHint = True + TabOrder = 12 + end + object Panel7: TPanel + Left = 8 + Top = 168 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Filter radius' + ParentShowHint = False + ShowHint = True + TabOrder = 13 + end + object txtGammaThreshold: TEdit + Left = 112 + Top = 120 + Width = 89 + Height = 21 + HelpContext = 1011 + TabOrder = 6 + end + object txtFilterRadius: TEdit + Left = 112 + Top = 168 + Width = 89 + Height = 21 + HelpContext = 1011 + TabOrder = 5 + end + object txtOversample: TEdit + Left = 112 + Top = 144 + Width = 89 + Height = 21 + HelpContext = 1010 + TabOrder = 4 + end + object txtVibrancy: TEdit + Left = 112 + Top = 96 + Width = 89 + Height = 21 + HelpContext = 1009 + TabOrder = 3 + end + object txtBrightness: TEdit + Left = 112 + Top = 72 + Width = 89 + Height = 21 + HelpContext = 1008 + TabOrder = 2 + end + object txtGamma: TEdit + Left = 112 + Top = 48 + Width = 89 + Height = 21 + HelpContext = 1007 + TabOrder = 1 + end + object txtSampleDensity: TEdit + Left = 112 + Top = 24 + Width = 89 + Height = 21 + HelpContext = 1006 + TabOrder = 0 + end + end + object GroupBox20: TGroupBox + Left = 8 + Top = 8 + Width = 454 + Height = 73 + Anchors = [akLeft, akTop, akRight] + Caption = 'Main Window Preview' + TabOrder = 2 + object Label48: TLabel + Left = 424 + Top = 20 + Width = 11 + Height = 13 + Caption = '%' + end + object chkShowTransparency: TCheckBox + Left = 8 + Top = 42 + Width = 233 + Height = 17 + Caption = 'Show Transparency' + TabOrder = 2 + end + object chkExtendMainPreview: TCheckBox + Left = 8 + Top = 20 + Width = 225 + Height = 17 + Caption = 'Extend preview buffer' + TabOrder = 0 + end + object pnlExtension: TPanel + Left = 244 + Top = 16 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Buffer extension' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object cbExtendPercent: TComboBox + Left = 348 + Top = 16 + Width = 73 + Height = 21 + TabOrder = 1 + Items.Strings = ( + '0' + '10' + '25' + '50' + '100' + '150' + '200') + end + end + object chkUseSmallThumbs: TCheckBox + Left = 253 + Top = 202 + Width = 209 + Height = 31 + Anchors = [akTop, akRight] + Caption = 'Use small thumbnails' + TabOrder = 3 + WordWrap = True + OnClick = chkUseSmallThumbsClick + end + end + object RandomPage: TTabSheet + Caption = 'Random' + DesignSize = ( + 467 + 368) + object gpNumberOfTransforms: TGroupBox + Left = 8 + Top = 6 + Width = 209 + Height = 75 + Caption = 'Number of transforms' + TabOrder = 0 + object udMinXforms: TUpDown + Left = 189 + Top = 20 + Width = 12 + Height = 21 + Associate = txtMinXForms + Min = 1 + Position = 2 + TabOrder = 2 + end + object udMaxXForms: TUpDown + Left = 189 + Top = 44 + Width = 12 + Height = 21 + Associate = txtMaxXforms + Min = 2 + Position = 6 + TabOrder = 3 + end + object Panel15: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object Panel16: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Maximum' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object txtMaxXforms: TEdit + Left = 112 + Top = 44 + Width = 77 + Height = 21 + HelpContext = 1018 + TabOrder = 1 + Text = '6' + OnChange = txtMaxXformsChange + end + object txtMinXForms: TEdit + Left = 112 + Top = 20 + Width = 77 + Height = 21 + HelpContext = 1017 + TabOrder = 0 + Text = '2' + OnChange = txtMinXFormsChange + end + end + object gpFlameTitlePrefix: TGroupBox + Left = 232 + Top = 88 + Width = 217 + Height = 97 + Anchors = [akTop, akRight] + Caption = 'Random batch' + TabOrder = 1 + object udBatchSize: TUpDown + Left = 195 + Top = 20 + Width = 13 + Height = 21 + Associate = txtBatchSize + Min = 1 + Max = 300 + Position = 10 + TabOrder = 2 + Thousands = False + end + object chkKeepBackground: TCheckBox + Left = 8 + Top = 72 + Width = 201 + Height = 17 + HelpContext = 1023 + Caption = 'Keep background color' + TabOrder = 3 + end + object Panel11: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Batch size' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object Panel12: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Title prefix' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object txtBatchSize: TEdit + Left = 112 + Top = 20 + Width = 83 + Height = 21 + HelpContext = 1004 + TabOrder = 1 + Text = '10' + end + object txtRandomPrefix: TEdit + Left = 112 + Top = 44 + Width = 96 + Height = 21 + HelpContext = 1021 + TabOrder = 0 + Text = 'Apophysis' + end + end + object gpMutationTransforms: TGroupBox + Left = 232 + Top = 6 + Width = 214 + Height = 75 + Anchors = [akTop, akRight] + Caption = 'Mutation transforms' + TabOrder = 3 + object udMinMutate: TUpDown + Left = 197 + Top = 20 + Width = 12 + Height = 21 + Associate = txtMinMutate + Min = 2 + Max = 12 + Position = 2 + TabOrder = 2 + end + object udMaxMutate: TUpDown + Left = 197 + Top = 44 + Width = 12 + Height = 21 + Associate = txtMaxMutate + Min = 2 + Max = 12 + Position = 6 + TabOrder = 3 + end + object Panel13: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object Panel14: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Maximum' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object txtMaxMutate: TEdit + Left = 112 + Top = 44 + Width = 85 + Height = 21 + HelpContext = 1020 + TabOrder = 1 + Text = '6' + OnChange = txtMaxMutateChange + end + object txtMinMutate: TEdit + Left = 112 + Top = 20 + Width = 85 + Height = 21 + HelpContext = 1019 + TabOrder = 0 + Text = '2' + OnChange = txtMinMutateChange + end + end + object gpForcedSymmetry: TGroupBox + Left = 8 + Top = 88 + Width = 209 + Height = 97 + Caption = 'Forced symmetry' + TabOrder = 2 + object udSymOrder: TUpDown + Left = 187 + Top = 43 + Width = 13 + Height = 21 + Associate = txtSymOrder + Min = 2 + Max = 2000 + Position = 4 + TabOrder = 2 + Thousands = False + end + object udSymNVars: TUpDown + Left = 187 + Top = 68 + Width = 13 + Height = 21 + Associate = txtSymNVars + Min = 4 + Position = 12 + TabOrder = 4 + Thousands = False + end + object Panel17: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Type' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object Panel18: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Order' + ParentShowHint = False + ShowHint = True + TabOrder = 6 + end + object Panel19: TPanel + Left = 8 + Top = 68 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Limit' + ParentShowHint = False + ShowHint = True + TabOrder = 7 + end + object txtSymNVars: TEdit + Left = 112 + Top = 68 + Width = 75 + Height = 21 + TabOrder = 3 + Text = '12' + end + object txtSymOrder: TEdit + Left = 112 + Top = 43 + Width = 75 + Height = 21 + HelpContext = 1025 + TabOrder = 1 + Text = '4' + end + object cmbSymType: TComboBox + Left = 112 + Top = 20 + Width = 89 + Height = 21 + HelpContext = 1024 + Style = csDropDownList + TabOrder = 0 + OnChange = cmbSymTypeChange + Items.Strings = ( + 'None' + 'Bilateral' + 'Rotational' + 'Dihedral') + end + end + object grpGradient: TRadioGroup + Left = 8 + Top = 192 + Width = 209 + Height = 121 + HelpContext = 1029 + Caption = 'On random flame' + ItemIndex = 0 + Items.Strings = ( + 'Use random preset' + 'Use default' + 'Use current' + 'Randomize' + 'Random from a file') + TabOrder = 4 + end + object GroupBox16: TGroupBox + Left = 231 + Top = 192 + Width = 217 + Height = 49 + Caption = 'Random file to use' + TabOrder = 5 + object btnGradientsFile: TSpeedButton + Left = 185 + Top = 18 + Width = 24 + Height = 24 + Hint = 'Browse...' + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnGradientsFileClick + end + object txtGradientsFile: TEdit + Left = 11 + Top = 19 + Width = 174 + Height = 21 + TabOrder = 0 + end + end + end + object VariationsPage: TTabSheet + Caption = 'Variations' + ImageIndex = 4 + DesignSize = ( + 467 + 368) + object btnSetAll: TButton + Left = 373 + Top = 4 + Width = 91 + Height = 25 + HelpContext = 1027 + Anchors = [akTop, akRight] + Caption = 'Set All' + TabOrder = 0 + OnClick = btnSetAllClick + end + object btnClearAll: TButton + Left = 373 + Top = 32 + Width = 91 + Height = 25 + HelpContext = 1028 + Anchors = [akTop, akRight] + Caption = 'Clear All' + TabOrder = 1 + OnClick = btnClearAllClick + end + object clbVarEnabled: TCheckListBox + Left = 0 + Top = 0 + Width = 366 + Height = 366 + Anchors = [akLeft, akTop, akRight, akBottom] + Columns = 2 + ItemHeight = 13 + TabOrder = 2 + TabWidth = 100 + end + end + object TabSheet1: TTabSheet + Caption = 'Gradient' + ImageIndex = 5 + DesignSize = ( + 467 + 368) + object GroupBox13: TGroupBox + Left = 8 + Top = 186 + Width = 209 + Height = 79 + Caption = 'Smooth palette' + TabOrder = 0 + object Panel28: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Number of tries' + ParentShowHint = False + ShowHint = True + TabOrder = 2 + end + object Panel29: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Try length' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object txtTryLength: TEdit + Left = 112 + Top = 44 + Width = 89 + Height = 21 + HelpContext = 1003 + TabOrder = 1 + Text = '10000' + end + object txtNumtries: TEdit + Left = 112 + Top = 20 + Width = 89 + Height = 21 + HelpContext = 1002 + TabOrder = 0 + Text = '50' + end + end + object GroupBox17: TGroupBox + Left = 8 + Top = 8 + Width = 209 + Height = 81 + Caption = 'Hue range' + TabOrder = 1 + object udMinHue: TUpDown + Left = 185 + Top = 20 + Width = 15 + Height = 21 + HelpContext = 1032 + Associate = txtMinHue + Max = 600 + TabOrder = 0 + end + object Panel20: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Maximum' + ParentShowHint = False + ShowHint = True + TabOrder = 2 + end + object Panel21: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object udMaxHue: TUpDown + Left = 185 + Top = 44 + Width = 15 + Height = 21 + HelpContext = 1033 + Associate = txtMaxHue + Max = 600 + Position = 600 + TabOrder = 4 + end + object txtMaxHue: TEdit + Left = 112 + Top = 44 + Width = 73 + Height = 21 + HelpContext = 1033 + TabOrder = 5 + Text = '600' + OnChange = txtMaxHueChange + end + object txtMinHue: TEdit + Left = 112 + Top = 20 + Width = 73 + Height = 21 + HelpContext = 1032 + TabOrder = 1 + Text = '0' + OnChange = txtMinHueChange + end + end + object GroupBox18: TGroupBox + Left = 229 + Top = 8 + Width = 209 + Height = 81 + Anchors = [akTop, akRight] + Caption = 'Saturation range' + TabOrder = 2 + object Panel22: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 0 + end + object Panel23: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Maximum' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object udMinSat: TUpDown + Left = 185 + Top = 20 + Width = 15 + Height = 21 + HelpContext = 1034 + Associate = txtMinSat + TabOrder = 2 + end + object txtMinSat: TEdit + Left = 112 + Top = 20 + Width = 73 + Height = 21 + HelpContext = 1034 + TabOrder = 3 + Text = '0' + OnChange = txtMinSatChange + end + object udmaxSat: TUpDown + Left = 185 + Top = 44 + Width = 15 + Height = 21 + HelpContext = 1035 + Associate = txtMaxSat + Position = 100 + TabOrder = 4 + end + object txtMaxSat: TEdit + Left = 112 + Top = 44 + Width = 73 + Height = 21 + HelpContext = 1035 + TabOrder = 5 + Text = '100' + OnChange = txtMaxSatChange + end + end + object GroupBox22: TGroupBox + Left = 8 + Top = 96 + Width = 209 + Height = 81 + Caption = 'Luminance range' + TabOrder = 3 + object Panel24: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Maximum' + ParentShowHint = False + ShowHint = True + TabOrder = 0 + end + object Panel25: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object udMinLum: TUpDown + Left = 185 + Top = 20 + Width = 15 + Height = 21 + HelpContext = 1036 + Associate = txtMinLum + Min = 1 + Position = 1 + TabOrder = 2 + end + object txtMinLum: TEdit + Left = 112 + Top = 20 + Width = 73 + Height = 21 + HelpContext = 1036 + TabOrder = 3 + Text = '1' + OnChange = txtMinLumChange + end + object udMaxLum: TUpDown + Left = 185 + Top = 44 + Width = 15 + Height = 21 + HelpContext = 1037 + Associate = txtMaxLum + Position = 100 + TabOrder = 4 + end + object txtMaxLum: TEdit + Left = 112 + Top = 44 + Width = 73 + Height = 21 + HelpContext = 1037 + TabOrder = 5 + Text = '100' + OnChange = txtMaxLumChange + end + end + object GroupBox23: TGroupBox + Left = 229 + Top = 96 + Width = 209 + Height = 81 + Anchors = [akTop, akRight] + Caption = 'Number of nodes' + TabOrder = 4 + object Panel26: TPanel + Left = 8 + Top = 20 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Minimum' + ParentShowHint = False + ShowHint = True + TabOrder = 0 + end + object Panel27: TPanel + Left = 8 + Top = 44 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Maximum' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object udMinNodes: TUpDown + Left = 185 + Top = 20 + Width = 15 + Height = 21 + HelpContext = 1030 + Associate = txtMinNodes + Min = 2 + Max = 64 + Position = 2 + TabOrder = 2 + end + object txtMinNodes: TEdit + Left = 112 + Top = 20 + Width = 73 + Height = 21 + HelpContext = 1030 + TabOrder = 3 + Text = '2' + OnChange = txtMinNodesChange + end + object udMaxNodes: TUpDown + Left = 185 + Top = 44 + Width = 15 + Height = 21 + HelpContext = 1031 + Associate = txtMaxNodes + Min = 2 + Max = 64 + Position = 2 + TabOrder = 4 + end + object txtMaxNodes: TEdit + Left = 112 + Top = 44 + Width = 73 + Height = 21 + HelpContext = 1031 + TabOrder = 5 + Text = '2' + OnChange = txtMaxNodesChange + end + end + end + object TabSheet6: TTabSheet + Caption = 'UPR' + ImageIndex = 5 + DesignSize = ( + 467 + 368) + object chkAdjustDensity: TCheckBox + Left = 237 + Top = 264 + Width = 228 + Height = 33 + Anchors = [akTop, akRight] + Caption = 'Adjust sample density' + TabOrder = 5 + WordWrap = True + end + object UPRPage: TPageControl + Left = 0 + Top = 4 + Width = 441 + Height = 249 + MultiLine = True + Style = tsButtons + TabOrder = 4 + end + object GroupBox11: TGroupBox + Left = 237 + Top = 184 + Width = 228 + Height = 81 + Anchors = [akTop, akRight] + Caption = 'UPR size' + TabOrder = 1 + object Panel37: TPanel + Left = 8 + Top = 24 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Width' + ParentShowHint = False + ShowHint = True + TabOrder = 2 + end + object Panel38: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Height' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object txtUPRHeight: TEdit + Left = 112 + Top = 48 + Width = 105 + Height = 21 + TabOrder = 1 + Text = '480' + end + object txtUPRWidth: TEdit + Left = 112 + Top = 24 + Width = 105 + Height = 21 + TabOrder = 0 + Text = '640' + end + end + object GroupBox9: TGroupBox + Left = 8 + Top = 182 + Width = 217 + Height = 107 + Caption = 'Parameter defaults' + TabOrder = 0 + object Panel34: TPanel + Left = 8 + Top = 24 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Sample density' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object Panel35: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Filter radius' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object Panel36: TPanel + Left = 8 + Top = 72 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Oversample' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object txtUPROversample: TEdit + Left = 112 + Top = 72 + Width = 97 + Height = 21 + TabOrder = 2 + Text = '3' + end + object txtUPRFilterRadius: TEdit + Left = 112 + Top = 48 + Width = 97 + Height = 21 + TabOrder = 1 + Text = '0.7' + end + object txtFIterDensity: TEdit + Left = 112 + Top = 24 + Width = 97 + Height = 21 + TabOrder = 0 + Text = '35' + end + end + object GroupBox4: TGroupBox + Left = 8 + Top = 6 + Width = 457 + Height = 83 + Anchors = [akLeft, akTop, akRight] + Caption = 'Coloring algorithm' + TabOrder = 2 + object Panel30: TPanel + Left = 8 + Top = 24 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Title' + ParentShowHint = False + ShowHint = True + TabOrder = 2 + end + object Panel31: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'File name' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object txtFCFile: TEdit + Left = 112 + Top = 48 + Width = 337 + Height = 21 + TabOrder = 1 + Text = 'apophysis.ucl' + end + object txtFCIdent: TEdit + Left = 112 + Top = 24 + Width = 337 + Height = 21 + TabOrder = 0 + Text = 'enr-flame-a' + end + end + object GroupBox5: TGroupBox + Left = 8 + Top = 95 + Width = 457 + Height = 82 + Anchors = [akLeft, akTop, akRight] + Caption = 'Fractal formula' + TabOrder = 3 + object Panel32: TPanel + Left = 8 + Top = 24 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Title' + ParentShowHint = False + ShowHint = True + TabOrder = 2 + end + object Panel33: TPanel + Left = 8 + Top = 48 + Width = 105 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'File name' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object txtFFFile: TEdit + Left = 112 + Top = 48 + Width = 337 + Height = 21 + TabOrder = 1 + Text = 'mt.ufm' + end + object txtFFIdent: TEdit + Left = 112 + Top = 24 + Width = 337 + Height = 21 + TabOrder = 0 + Text = 'mt-pixel' + end + end + end + object TabSheet2: TTabSheet + Caption = 'Sheep' + Enabled = False + ImageIndex = 6 + TabVisible = False + object GroupBox6: TGroupBox + Left = 8 + Top = 6 + Width = 245 + Height = 99 + Caption = 'Credit' + TabOrder = 0 + object Label5: TLabel + Left = 10 + Top = 18 + Width = 23 + Height = 13 + Caption = 'Nick:' + end + object Label6: TLabel + Left = 10 + Top = 42 + Width = 23 + Height = 13 + Caption = 'URL:' + end + object Label15: TLabel + Left = 10 + Top = 66 + Width = 50 + Height = 13 + Caption = 'Password:' + Visible = False + end + object txtNick: TEdit + Left = 82 + Top = 16 + Width = 151 + Height = 21 + TabOrder = 0 + end + object txtURL: TEdit + Left = 82 + Top = 40 + Width = 151 + Height = 21 + TabOrder = 1 + end + object txtPassword: TEdit + Left = 82 + Top = 64 + Width = 151 + Height = 21 + Enabled = False + TabOrder = 2 + Visible = False + end + end + object GroupBox8: TGroupBox + Left = 8 + Top = 106 + Width = 425 + Height = 51 + Caption = 'Server' + TabOrder = 1 + object Label17: TLabel + Left = 10 + Top = 20 + Width = 43 + Height = 13 + Caption = 'Address:' + end + object txtServer: TEdit + Left = 67 + Top = 19 + Width = 310 + Height = 21 + HelpContext = 1000 + ParentShowHint = False + ShowHint = False + TabOrder = 0 + end + end + end + object PathsPage: TTabSheet + Caption = 'Environment' + ImageIndex = 7 + DesignSize = ( + 467 + 368) + object btnDefGradient: TSpeedButton + Left = 437 + Top = 7 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnDefGradientClick + end + object btnSmooth: TSpeedButton + Left = 437 + Top = 31 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnSmoothClick + end + object SpeedButton2: TSpeedButton + Left = 437 + Top = 55 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = SpeedButton2Click + end + object btnRenderer: TSpeedButton + Left = 437 + Top = 79 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnRendererClick + end + object btnHelp: TSpeedButton + Left = 437 + Top = 103 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnHelpClick + end + object Label49: TLabel + Left = 245 + Top = 236 + Width = 37 + Height = 13 + Caption = 'minutes' + end + object btnFindDefaultSaveFile: TSpeedButton + Left = 437 + Top = 207 + Width = 24 + Height = 24 + Hint = 'Browse...' + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnFindDefaultSaveFileClick + end + object btnPluginPath: TSpeedButton + Left = 437 + Top = 128 + Width = 24 + Height = 24 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnPluginPathClick + end + object chkRememberLastOpen: TCheckBox + Left = 8 + Top = 160 + Width = 433 + Height = 17 + Caption = 'Remember last opened parameters' + TabOrder = 0 + OnClick = chkRememberLastOpenClick + end + object Panel39: TPanel + Left = 8 + Top = 8 + Width = 129 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Default parameters' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object txtDefParameterFile: TEdit + Left = 136 + Top = 8 + Width = 302 + Height = 21 + HelpContext = 1000 + Anchors = [akLeft, akTop, akRight] + ParentShowHint = False + ShowHint = False + TabOrder = 2 + end + object Panel40: TPanel + Left = 8 + Top = 32 + Width = 129 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Smooth palette file' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object txtDefSmoothFile: TEdit + Left = 136 + Top = 32 + Width = 302 + Height = 21 + HelpContext = 1001 + Anchors = [akLeft, akTop, akRight] + TabOrder = 3 + end + object Panel41: TPanel + Left = 8 + Top = 56 + Width = 129 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Function library' + ParentShowHint = False + ShowHint = True + TabOrder = 8 + end + object Panel42: TPanel + Left = 8 + Top = 80 + Width = 129 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'flam3' + ParentShowHint = False + ShowHint = True + TabOrder = 9 + end + object Panel43: TPanel + Left = 8 + Top = 104 + Width = 129 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Help file' + ParentShowHint = False + ShowHint = True + TabOrder = 10 + end + object txtLibrary: TEdit + Left = 136 + Top = 56 + Width = 302 + Height = 21 + HelpContext = 1000 + Anchors = [akLeft, akTop, akRight] + ParentShowHint = False + ShowHint = False + TabOrder = 5 + end + object txtRenderer: TEdit + Left = 136 + Top = 80 + Width = 302 + Height = 21 + HelpContext = 1000 + Anchors = [akLeft, akTop, akRight] + ParentShowHint = False + ShowHint = False + TabOrder = 6 + end + object txtHelp: TEdit + Left = 136 + Top = 104 + Width = 302 + Height = 21 + HelpContext = 1000 + Anchors = [akLeft, akTop, akRight] + ParentShowHint = False + ShowHint = False + TabOrder = 7 + end + object cbEnableAutosave: TCheckBox + Left = 8 + Top = 184 + Width = 425 + Height = 17 + Caption = 'Enable autosave' + TabOrder = 13 + OnClick = cbEnableAutosaveClick + end + object Panel44: TPanel + Left = 24 + Top = 208 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'File name' + ParentShowHint = False + ShowHint = True + TabOrder = 14 + end + object txtDefaultSaveFile: TEdit + Left = 136 + Top = 208 + Width = 302 + Height = 21 + HelpContext = 1000 + ParentShowHint = False + ShowHint = False + TabOrder = 12 + end + object Panel45: TPanel + Left = 24 + Top = 232 + Width = 113 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Save frequency' + ParentShowHint = False + ShowHint = True + TabOrder = 15 + end + object cbFreq: TComboBox + Left = 136 + Top = 232 + Width = 105 + Height = 21 + Style = csDropDownList + ItemIndex = 2 + TabOrder = 11 + Text = '5' + Items.Strings = ( + '1' + '2' + '5' + '10') + end + object Panel50: TPanel + Left = 8 + Top = 130 + Width = 129 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Plugin folder' + ParentShowHint = False + ShowHint = True + TabOrder = 16 + end + object txtPluginFolder: TEdit + Left = 136 + Top = 130 + Width = 302 + Height = 21 + HelpContext = 1000 + Anchors = [akLeft, akTop, akRight] + ParentShowHint = False + ShowHint = False + TabOrder = 17 + end + end + end + object btnOK: TButton + Left = 304 + Top = 409 + Width = 86 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'OK' + Default = True + TabOrder = 0 + OnClick = btnOKClick + end + object btnCancel: TButton + Left = 397 + Top = 409 + Width = 86 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Cancel' + TabOrder = 1 + OnClick = btnCancelClick + end + object OpenDialog: TOpenDialog + Left = 8 + Top = 408 + end +end diff --git a/Forms/Options.pas b/Forms/Options.pas new file mode 100644 index 0000000..5c32b96 --- /dev/null +++ b/Forms/Options.pas @@ -0,0 +1,1398 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +//{$D-,L-,O+,Q-,R-,Y-,S-} +unit Options; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ComCtrls, ExtCtrls, Buttons, Registry, Mask, CheckLst, + MMSystem, Translation, RegexHelper, FileCtrl, StrUtils, ShellAPI, ShlObj; + +type + TOptionsForm = class(TForm) + btnOK: TButton; + btnCancel: TButton; + OpenDialog: TOpenDialog; + Label45: TLabel; + GroupBox15: TGroupBox; + btnBrowseSound: TSpeedButton; + btnPlay: TSpeedButton; + Label44: TLabel; + txtSoundFile: TEdit; + chkPlaysound: TCheckBox; + Tabs: TPageControl; + GeneralPage: TTabSheet; + SpeedButton1: TSpeedButton; + pnlJPEGQuality: TPanel; + chkConfirmDel: TCheckBox; + chkOldPaletteFormat: TCheckBox; + chkConfirmExit: TCheckBox; + chkConfirmStopRender: TCheckBox; + cbUseTemplate: TCheckBox; + cbMissingPlugin: TCheckBox; + cbEmbedThumbs: TCheckBox; + chkShowRenderStats: TCheckBox; + pnlMultithreading: TPanel; + cbNrTheads: TComboBox; + pnlPNGTransparency: TPanel; + grpGuidelines: TGroupBox; + cbGL: TCheckBox; + pnlCenterLine: TPanel; + shCenterLine: TShape; + pnlThirdsLine: TPanel; + shThirdsLine: TShape; + pnlGRLine: TPanel; + shGRLine: TShape; + pnlCenter: TPanel; + pnlThirds: TPanel; + pnlGoldenRatio: TPanel; + rgRotationMode: TRadioGroup; + rgZoomingMode: TRadioGroup; + Panel46: TPanel; + txtLanguageFile: TComboBox; + cbPNGTransparency: TComboBox; + txtJPEGquality: TComboBox; + cbSinglePrecision: TCheckBox; + EditorPage: TTabSheet; + GroupBox1: TGroupBox; + chkUseXFormColor: TCheckBox; + chkHelpers: TCheckBox; + rgReferenceMode: TRadioGroup; + GroupBox21: TGroupBox; + chkAxisLock: TCheckBox; + chkExtendedEdit: TCheckBox; + chkXaosRebuild: TCheckBox; + grpEditorColors: TGroupBox; + pnlBackground: TPanel; + pnlReferenceC: TPanel; + pnlHelpers: TPanel; + pnlGrid: TPanel; + pnlBackColor: TPanel; + shBackground: TShape; + pnlReference: TPanel; + shRef: TShape; + pnlHelpersColor: TPanel; + shHelpers: TShape; + pnlGridColor1: TPanel; + shGC1: TShape; + pnlGridColor2: TPanel; + shGC2: TShape; + chkShowAllXforms: TCheckBox; + chkEnableEditorPreview: TCheckBox; + Panel48: TPanel; + tbEPTransparency: TTrackBar; + DisplayPage: TTabSheet; + GroupBox2: TGroupBox; + Panel8: TPanel; + Panel9: TPanel; + Panel10: TPanel; + txtHighQuality: TEdit; + txtMediumQuality: TEdit; + txtLowQuality: TEdit; + grpRendering: TGroupBox; + Panel1: TPanel; + Panel2: TPanel; + Panel3: TPanel; + Panel4: TPanel; + Panel5: TPanel; + Panel6: TPanel; + Panel7: TPanel; + txtGammaThreshold: TEdit; + txtFilterRadius: TEdit; + txtOversample: TEdit; + txtVibrancy: TEdit; + txtBrightness: TEdit; + txtGamma: TEdit; + txtSampleDensity: TEdit; + GroupBox20: TGroupBox; + Label48: TLabel; + chkShowTransparency: TCheckBox; + chkExtendMainPreview: TCheckBox; + pnlExtension: TPanel; + cbExtendPercent: TComboBox; + chkUseSmallThumbs: TCheckBox; + RandomPage: TTabSheet; + gpNumberOfTransforms: TGroupBox; + udMinXforms: TUpDown; + udMaxXForms: TUpDown; + Panel15: TPanel; + Panel16: TPanel; + txtMaxXforms: TEdit; + txtMinXForms: TEdit; + gpFlameTitlePrefix: TGroupBox; + udBatchSize: TUpDown; + chkKeepBackground: TCheckBox; + Panel11: TPanel; + Panel12: TPanel; + txtBatchSize: TEdit; + txtRandomPrefix: TEdit; + gpMutationTransforms: TGroupBox; + udMinMutate: TUpDown; + udMaxMutate: TUpDown; + Panel13: TPanel; + Panel14: TPanel; + txtMaxMutate: TEdit; + txtMinMutate: TEdit; + gpForcedSymmetry: TGroupBox; + udSymOrder: TUpDown; + udSymNVars: TUpDown; + Panel17: TPanel; + Panel18: TPanel; + Panel19: TPanel; + txtSymNVars: TEdit; + txtSymOrder: TEdit; + cmbSymType: TComboBox; + grpGradient: TRadioGroup; + GroupBox16: TGroupBox; + btnGradientsFile: TSpeedButton; + txtGradientsFile: TEdit; + VariationsPage: TTabSheet; + btnSetAll: TButton; + btnClearAll: TButton; + clbVarEnabled: TCheckListBox; + TabSheet1: TTabSheet; + GroupBox13: TGroupBox; + Panel28: TPanel; + Panel29: TPanel; + txtTryLength: TEdit; + txtNumtries: TEdit; + GroupBox17: TGroupBox; + udMinHue: TUpDown; + Panel20: TPanel; + Panel21: TPanel; + udMaxHue: TUpDown; + txtMaxHue: TEdit; + txtMinHue: TEdit; + GroupBox18: TGroupBox; + Panel22: TPanel; + Panel23: TPanel; + udMinSat: TUpDown; + txtMinSat: TEdit; + udmaxSat: TUpDown; + txtMaxSat: TEdit; + GroupBox22: TGroupBox; + Panel24: TPanel; + Panel25: TPanel; + udMinLum: TUpDown; + txtMinLum: TEdit; + udMaxLum: TUpDown; + txtMaxLum: TEdit; + GroupBox23: TGroupBox; + Panel26: TPanel; + Panel27: TPanel; + udMinNodes: TUpDown; + txtMinNodes: TEdit; + udMaxNodes: TUpDown; + txtMaxNodes: TEdit; + TabSheet6: TTabSheet; + chkAdjustDensity: TCheckBox; + UPRPage: TPageControl; + GroupBox11: TGroupBox; + Panel37: TPanel; + Panel38: TPanel; + txtUPRHeight: TEdit; + txtUPRWidth: TEdit; + GroupBox9: TGroupBox; + Panel34: TPanel; + Panel35: TPanel; + Panel36: TPanel; + txtUPROversample: TEdit; + txtUPRFilterRadius: TEdit; + txtFIterDensity: TEdit; + GroupBox4: TGroupBox; + Panel30: TPanel; + Panel31: TPanel; + txtFCFile: TEdit; + txtFCIdent: TEdit; + GroupBox5: TGroupBox; + Panel32: TPanel; + Panel33: TPanel; + txtFFFile: TEdit; + txtFFIdent: TEdit; + TabSheet2: TTabSheet; + GroupBox6: TGroupBox; + Label5: TLabel; + Label6: TLabel; + Label15: TLabel; + txtNick: TEdit; + txtURL: TEdit; + txtPassword: TEdit; + GroupBox8: TGroupBox; + Label17: TLabel; + txtServer: TEdit; + PathsPage: TTabSheet; + btnDefGradient: TSpeedButton; + btnSmooth: TSpeedButton; + SpeedButton2: TSpeedButton; + btnRenderer: TSpeedButton; + btnHelp: TSpeedButton; + Label49: TLabel; + btnFindDefaultSaveFile: TSpeedButton; + chkRememberLastOpen: TCheckBox; + Panel39: TPanel; + txtDefParameterFile: TEdit; + Panel40: TPanel; + txtDefSmoothFile: TEdit; + Panel41: TPanel; + Panel42: TPanel; + Panel43: TPanel; + txtLibrary: TEdit; + txtRenderer: TEdit; + txtHelp: TEdit; + cbEnableAutosave: TCheckBox; + Panel44: TPanel; + txtDefaultSaveFile: TEdit; + Panel45: TPanel; + cbFreq: TComboBox; + btnPluginPath: TSpeedButton; + Panel50: TPanel; + txtPluginFolder: TEdit; + procedure chkEnableEditorPreviewClick(Sender: TObject); + procedure SpeedButton1Click(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnOKClick(Sender: TObject); + procedure btnDefGradientClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure btnSmoothClick(Sender: TObject); + procedure cmbSymTypeChange(Sender: TObject); + procedure btnSetAllClick(Sender: TObject); + procedure btnClearAllClick(Sender: TObject); + procedure txtMinNodesChange(Sender: TObject); + procedure txtMaxNodesChange(Sender: TObject); + procedure txtMaxHueChange(Sender: TObject); + procedure txtMaxSatChange(Sender: TObject); + procedure txtMaxLumChange(Sender: TObject); + procedure txtMinHueChange(Sender: TObject); + procedure txtMinSatChange(Sender: TObject); + procedure txtMinLumChange(Sender: TObject); + procedure txtMinXFormsChange(Sender: TObject); + procedure txtMaxXformsChange(Sender: TObject); + procedure txtMinMutateChange(Sender: TObject); + procedure txtMaxMutateChange(Sender: TObject); + procedure btnRendererClick(Sender: TObject); + procedure SpeedButton2Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure pnlBackColorClick(Sender: TObject); + procedure pnlReferenceClick(Sender: TObject); + procedure pnlGridColor1Click(Sender: TObject); + procedure pnlGridColor2Click(Sender: TObject); + procedure pnlHelpersColorClick(Sender: TObject); + procedure btnBrowseSoundClick(Sender: TObject); + procedure pnlCenterLineClick(Sender: TObject); + procedure pnlThirdsLineClick(Sender: TObject); + procedure pnlGRLineClick(Sender: TObject); + procedure btnPlayClick(Sender: TObject); + procedure btnGradientsFileClick(Sender: TObject); + procedure shCenterLineMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure shThirdsLineMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure shGRLineMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure UpdateShapeColors; + procedure shBackgroundMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure shGC1MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure shGC2MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure shRefMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure shHelpersMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure chkRememberLastOpenClick(Sender: TObject); + procedure chkUseSmallThumbsClick(Sender: TObject); + procedure btnFindDefaultSaveFileClick(Sender: TObject); + procedure cbEnableAutosaveClick(Sender: TObject); + procedure btnHelpClick(Sender: TObject); + procedure cbGLClick(Sender: TObject); + procedure btnPluginPathClick(Sender: TObject); + + private + { Private declarations } + public + { Public declarations } + end; + +var + OptionsForm: TOptionsForm; + +implementation + +{$R *.DFM} + +uses + Main, Global, Editor, ControlPoint, XFormMan, Adjust; + +procedure TOptionsForm.btnCancelClick(Sender: TObject); +begin + Close; +end; + +procedure TOptionsForm.UpdateShapeColors; +begin + shBackground.Brush.Color := pnlBackColor.Color; + shGC1.Brush.Color := pnlGridColor1.Color; + shGC2.Brush.Color := pnlGridColor2.Color; + shRef.Brush.Color := pnlReference.Color; + shHelpers.Brush.Color := pnlHelpersColor.Color; + shCenterLine.Brush.Color := pnlCenterLine.Color; + shThirdsLine.Brush.Color := pnlThirdsLine.Color; + shGRLine.Brush.Color := pnlGRLine.Color; +end; + +procedure TOptionsForm.FormShow(Sender: TObject); +var + Registry: TRegistry; + i, j: integer; + s1, s2: string; +begin + { Read position from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Options', False) then + begin + if Registry.ValueExists('Left') then + OptionsForm.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + OptionsForm.Top := Registry.ReadInteger('Top'); + end; + Registry.CloseKey; + finally + Registry.Free; + end; + + { General tab } + txtDefParameterFile.Text := DefFlameFile; + txtDefSmoothFile.Text := defSmoothPaletteFile; + txtNumtries.text := IntToStr(Numtries); + txtTryLength.text := IntToStr(Trylength); + udBatchSize.Position := BatchSize; +// chkResize.checked := ResizeOnLoad; + if NrTreads <= 1 then + cbNrTheads.ItemIndex := 0 + else begin + // not with fucking Delphi 2005... :( + //cbNrTheads.text := intTostr(NrTreads); + + // Hack + cbNrTheads.ItemIndex := 0; + case NrTreads of + 2: cbNrTheads.ItemIndex := 1; + 3: cbNrTheads.ItemIndex := 2; + 4: cbNrTheads.ItemIndex := 3; + 5: cbNrTheads.ItemIndex := 4; + 6: cbNrTheads.ItemIndex := 5; + 7: cbNrTheads.ItemIndex := 6; + 8: cbNrTheads.ItemIndex := 7; + 9: cbNrTheads.ItemIndex := 8; + 10: cbNrTheads.ItemIndex := 9; + 11: cbNrTheads.ItemIndex := 10; + 12: cbNrTheads.ItemIndex := 11; + end; + end; + + chkConfirmDel.Checked := ConfirmDelete; + chkOldPaletteFormat.Checked := OldPaletteFormat; + chkConfirmExit.Checked := ConfirmExit; + chkConfirmStopRender.Checked := ConfirmStopRender; + chkRememberLastOpen.Checked := RememberLastOpenFile; + chkUseSmallThumbs.Checked := UseSmallThumbnails; + cbUseTemplate.Checked := AlwaysCreateBlankFlame; + cbMissingPlugin.Checked := WarnOnMissingPlugin; + cbEmbedThumbs.Checked := EmbedThumbnails; + //cbSinglePrecision.Checked := SingleBuffer; + + rgRotationMode.ItemIndex := MainForm_RotationMode; + if PreserveQuality then + rgZoomingMode.ItemIndex := 0 + else + rgZoomingMode.ItemIndex := 1; + txtJPEGQuality.text := IntToStr(JPEGQuality); + + chkPlaySound.Checked := PlaySoundOnRenderComplete; + txtSoundFile.Text := RenderCompleteSoundFile; + + //cbInternalBitsPerSample.ItemIndex := InternalBitsPerSample; + + + { Editor } +// rgReferenceMode.ItemIndex := ReferenceMode; + chkUseXFormColor.checked := UseTransformColors; + chkHelpers.Checked := HelpersEnabled; + chkExtendedEdit.Checked := ExtEditEnabled; + chkAxisLock.Checked := TransformAxisLock; + chkXaosRebuild.Checked := RebuildXaosLinks; + chkShowAllXforms.Checked := ShowAllXforms; + chkEnableEditorPreview.Checked := EnableEditorPreview; + tbEPTransparency.Position := EditorPreviewTransparency; + chkEnableEditorPreviewClick(self); + + { Display tab } + txtSampleDensity.Text := FloatToStr(defSampleDensity); + txtGamma.Text := FloatToStr(defGamma); + txtBrightness.Text := FloatToStr(defBrightness); + txtVibrancy.Text := FloatToStr(defVibrancy); + txtOversample.Text := IntToStr(defOversample); + txtFilterRadius.Text := FloatToStr(defFilterRadius); + txtGammaThreshold.Text := FloatToStr(defGammaThreshold); + + txtLowQuality.Text := FloatToStr(prevLowQuality); + txtMediumQuality.Text := FloatToStr(prevMediumQuality); + txtHighQuality.Text := FloatToStr(prevHighQuality); + + pnlBackColor.Color := TColor(EditorBkgColor); + pnlGridColor1.Color := GridColor1; + pnlGridColor2.Color := GridColor2; + pnlReference.color := TColor(ReferenceTriangleColor); + + cbPNGTransparency.ItemIndex := PNGTransparency; + chkShowTransparency.Checked := ShowTransparency; + cbExtendPercent.Text := FloatToStr((MainPreviewScale - 1) / 0.02); + chkExtendMainPreview.Checked := ExtendMainPreview; + + chkShowRenderStats.Checked := ShowRenderStats; + + { Random tab } + udMinXforms.Position := randMinTransforms; + udMaxXforms.Position := randMaxTransforms; + udMinMutate.Position := mutantMinTransforms; + udMaxMutate.Position := mutantMaxTransforms; + txtRandomPrefix.text := RandomPrefix; + chkKeepbackground.Checked := KeepBackground; + cmbSymType.ItemIndex := SymmetryType; + if (SymmetryType = 0) or (SymmetryType = 1) then + begin + txtSymOrder.enabled := false; + txtSymNVars.enabled := false; + end; + udSymOrder.Position := SymmetryOrder; + udSymNVars.Position := SymmetryNVars; + + { Variations tab } + //UnpackVariations(VariationOptions); + for i := 0 to NRVAR -1 do + clbVarEnabled.Checked[i] := Variations[i]; + + { Gradient tab } + grpGradient.ItemIndex := randGradient; + txtGradientsFile.Text := randGradientFile; + udMinNodes.Position := MinNodes; + udMaxNodes.Position := MaxNodes; + udMinHue.Position := MinHue; + udMinSat.Position := MinSat; + udMinLum.Position := MinLum; + udMaxHue.Position := MaxHue; + udMaxSat.Position := MaxSat; + udMaxLum.Position := MaxLum; + + { UPR tab } + txtFIterDensity.text := IntToStr(UPRSampleDensity); + txtUPRFilterRadius.text := FloatToStr(UPRFilterRadius); + txtUPROversample.text := IntToStr(UPROversample); + txtFCIdent.text := UPRColoringIdent; + txtFCFile.text := UPRColoringFile; + txtFFIdent.text := UPRFormulaIdent; + txtFFFile.text := UPRFormulaFile; + txtUPRWidth.text := IntToStr(UPRWidth); + txtUPRHeight.text := IntToStr(UPRHeight); + chkAdjustDensity.checked := UPRAdjustDensity; + + { UPR tab } + txtNick.Text := SheepNick; + txtURL.Text := SheepURL; + txtPassword.Text := SheepPW; + txtRenderer.Text := flam3Path; + txtServer.Text := SheepServer; + + txtHelp.Text := HelpPath; + txtLibrary.text := defLibrary; + Label45.Visible := false; + + cbEnableAutosave.Checked := AutoSaveEnabled; + txtDefaultSaveFile.Text := AutoSavePath; + cbFreq.ItemIndex := AutoSaveFreq; + + cbEnableAutosaveClick(nil); + + pnlCenterLine.Color := TColor(LineCenterColor); + pnlThirdsLine.Color := TColor(LineThirdsColor); + pnlGRLine.Color := TColor(LineGRColor); + cbGL.Checked := EnableGuides; + cbGLClick(nil); + + txtPluginFolder.Text := PluginPath; + + UpdateShapeColors; + + j := -1; + txtLanguageFile.Items.Clear; + for i := 0 to AvailableLanguages.Count-1 do begin + if AvailableLanguages.Strings[i] = '' then begin + txtLanguageFile.Items.Add('Default (English)'); + end else begin + LanguageInfo(AvailableLanguages.Strings[i], s1, s2); + if (s2 <> '') then s1 := s2 + ' (' + s1 + ')'; + txtLanguageFile.Items.Add(s1); + end; + if (lowercase(AvailableLanguages.Strings[i]) = lowercase(languagefile)) then + j := i; + + end; + txtLanguageFile.ItemIndex := j; +end; + +procedure TOptionsForm.btnOKClick(Sender: TObject); +var + vars: boolean; + i: integer; + warn: boolean; +begin + + { Variations tab } + { Get option values from controls. Disallow bad values } + vars := false; + for i := 0 to NRVAR-1 do begin + Variations[i] := clbVarEnabled.Checked[i]; + vars := vars or Variations[i]; + end; + + if vars = false then begin + //Application.MessageBox('You must select at least one variation.', 'Apophysis', 48); + //Tabs.ActivePage := VariationsPage; + //Exit; + Variations[0] := true; + end; + + warn := (LanguageFile <> AvailableLanguages[txtLanguageFile.ItemIndex]) or (UseSmallThumbnails <> chkUseSmallThumbs.Checked); + + { General tab } + JPEGQuality := StrToInt(txtJPEGQuality.text); + Numtries := StrToInt(txtNumtries.text); + if NumTries < 1 then Numtries := 1; + Trylength := StrToInt(txtTrylength.text); + if Trylength < 100 then trylength := 100; + if JPEGQuality > 100 then JPEGQuality := 100; + if JPEGQuality < 1 then JPEGQuality := 100; + BatchSize := udBatchSize.Position; + if BatchSize < 1 then BatchSize := 1; + if BatchSize > 300 then BatchSize := 300; + + PNGTransparency := cbPNGTransparency.ItemIndex; + ShowTransparency := chkShowTransparency.Checked; + + NrTreads := StrToIntDef(cbNrTheads.text, 0); + ConfirmDelete := chkConfirmDel.Checked; + OldPaletteFormat := chkOldPaletteFormat.Checked; + ConfirmExit := chkConfirmExit.Checked; + ConfirmStopRender := chkConfirmStopRender.Checked; + RememberLastOpenFile := chkRememberLastOpen.Checked; + UseSmallThumbnails := chkUseSmallThumbs.Checked; + AlwaysCreateBlankFlame := cbUseTemplate.Checked; + EmbedThumbnails := cbEmbedThumbs.Checked; + WarnOnMissingPlugin := cbMissingPlugin.Checked; + LanguageFile := AvailableLanguages.Strings[txtLanguageFile.ItemIndex]; + //SingleBuffer := cbSinglePrecision.Checked; + + MainForm_RotationMode := rgRotationMode.ItemIndex; + PreserveQuality := (rgZoomingMode.ItemIndex = 0); +// ResizeOnLoad := chkResize.checked; + + //InternalBitsPerSample := cbInternalBitsPerSample.ItemIndex; + LineCenterColor := pnlCenterLine.Color; + LineThirdsColor := pnlThirdsLine.Color; + LineGRColor := pnlGRLine.Color; + EnableGuides := cbGL.Checked; + + // Editor +// ReferenceMode := rgReferenceMode.ItemIndex; + UseTransformColors := chkUseXFormColor.checked; + HelpersEnabled := chkHelpers.Checked; + ShowAllXforms := chkShowAllXforms.Checked; + + ExtEditEnabled := chkExtendedEdit.Checked; + TransformAxisLock := chkAxisLock.Checked; + RebuildXaosLinks := chkXaosRebuild.Checked; + EnableEditorPreview := chkEnableEditorPreview.Checked; + EditorPreviewTransparency := tbEPTransparency.Position; + + { Display tab } + defSampleDensity := StrToFloat(txtSampleDensity.Text); + if defSampleDensity > 100 then defSampleDensity := 100; + if defSampleDensity <= 0 then defSampleDensity := 0.1; + defGamma := StrToFloat(txtGamma.Text); + if defGamma < 0.1 then defGamma := 0.1; + defBrightness := StrToFloat(txtBrightness.Text); + if defBrightness < 0.1 then defBrightness := 0.1; + defVibrancy := StrToFloat(txtVibrancy.Text); + if defVibrancy < 0 then defVibrancy := 0.1; + defFilterRadius := StrToFloat(txtFilterRadius.Text); + if defFilterRadius <= 0 then defFilterRadius := 0.1; + defGammaThreshold := StrToFloat(txtGammaThreshold.Text); + if defGammaThreshold < 0 then defGammaThreshold := 0; + defOversample := StrToInt(txtOversample.Text); + if defOversample > 4 then defOversample := 4; + if defOversample < 1 then defOversample := 1; + prevLowQuality := StrToFloat(txtLowQuality.Text); + if prevLowQuality > 100 then prevLowQuality := 100; + if prevLowQuality < 0.01 then prevLowQuality := 0.01; + prevMediumQuality := StrToFloat(txtMediumQuality.Text); + if prevMediumQuality > 1000 then prevMediumQuality := 1000; + if prevMediumQuality < 0.01 then prevMediumQuality := 0.01; + prevHighQuality := StrToFloat(txtHighQuality.Text); + if prevHighQuality > 10000 then prevHighQuality := 10000; + if prevHighQuality < 0.01 then prevHighQuality := 0.01; + + MainPreviewScale := 1 + 0.02 * StrToFloatDef(cbExtendPercent.Text, 0); + if MainPreviewScale < 1 then MainPreviewScale := 1 + else if MainPreviewScale > 5 then MainPreviewScale := 5; + ExtendMainPreview := chkExtendMainPreview.Checked; + + ShowRenderStats := chkShowRenderStats.Checked; + + { Random tab } + randMinTransforms := udMinXforms.Position; + randMaxTransforms := udMaxXforms.Position; + mutantMinTransforms := udMinMutate.Position; + mutantMaxTransforms := udMaxMutate.Position; + RandomPrefix := txtRandomPrefix.text; + SymmetryType := cmbSymType.ItemIndex; + SymmetryOrder := udSymOrder.Position; + SymmetryNVars := udSymNVars.Position; + KeepBackground := chkKeepbackground.Checked; + + {Gradient tab } + randGradient := grpGradient.ItemIndex; + randGradientFile := txtGradientsFile.Text; + MinNodes := udMinNodes.Position; + MaxNodes := udMaxNodes.Position; + MinHue := udMinHue.Position; + MinSat := udMinSat.Position; + MinLum := udMinLum.Position; + MaxHue := udMaxHue.Position; + MaxSat := udMaxSat.Position; + MaxLum := udMaxLum.Position; + + { UPR options } + UPRSampleDensity := StrToInt(txtFIterDensity.text); + UPRFilterRadius := StrToFloat(txtUPRFilterRadius.text); + UPROversample := StrToInt(txtUPROversample.text); + UPRColoringIdent := txtFCIdent.text; + UPRColoringFile := txtFCFile.text; + UPRFormulaIdent := txtFFIdent.text; + UPRFormulaFile := txtFFFile.text; + UPRAdjustDensity := chkAdjustDensity.checked; + UPRWidth := StrToInt(txtUPRWidth.text); + UPRHeight := StrToInt(txtUPRHeight.text); + + { Sheep options } + SheepNick := txtNick.Text; + SheepURL := txtURL.Text; + SheepPW := txtPassword.text; + flam3Path := txtRenderer.text; + SheepServer := txtServer.text; + + {Paths} + defLibrary := txtLibrary.text; + if (not RememberLastOpenFile) then defFlameFile := txtDefParameterFile.Text; + defSmoothPaletteFile := txtDefSmoothFile.Text; + PlaySoundOnRenderComplete := chkPlaySound.Checked; + RenderCompleteSoundFile := txtSoundFile.Text; + HelpPath := txtHelp.Text; + + //{$ifdef Apo7X64} + //{$else} + PluginPath := txtPluginFolder.Text; + if (RightStr(PluginPath, 1) <> '\') and (PluginPath <> '') then + PluginPath := PluginPath + '\'; + //{$endif} + + AutoSaveEnabled := cbEnableAutosave.Checked; + AutoSavePath := txtDefaultSaveFile.Text; + AutoSaveFreq := cbFreq.ItemIndex; + + + + + MainForm.mnuExportFLame.Enabled := FileExists(flam3Path); + + if (warn) then + Application.MessageBox(PChar(TextByKey('options-restartnotice')), PChar('Apophysis'), MB_ICONWARNING); + + Close; +end; + +procedure TOptionsForm.btnDefGradientClick(Sender: TObject); +var + fn:string; +begin + OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame|' + TextBykey('common-filter-allfiles') + '|*.*'; + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '.flame', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + txtDefParameterFile.text := fn; + end; +end; + +procedure TOptionsForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Options', True) then + begin + Registry.WriteInteger('Top', OptionsForm.Top); + Registry.WriteInteger('Left', OptionsForm.Left); + end; + finally + Registry.Free; + end; + +end; + +procedure TOptionsForm.btnSmoothClick(Sender: TObject); +var + fn:string; +begin + OpenDialog.Filter := TextByKey('common-filter-gradientfiles') + '|*.gradient;*.ugr|' + TextBykey('common-filter-allfiles') + '|*.*'; + OpenDialog.InitialDir := ExtractFilePath(defSmoothPaletteFile); + OpenDialog.FileName := ''; + OpenDialog.DefaultExt := 'ugr'; + if OpenSaveFileDialog(OptionsForm, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + txtDefSmoothFile.text := fn; + end; +end; + +procedure TOptionsForm.cmbSymTypeChange(Sender: TObject); +begin + if (cmbSymType.ItemIndex = 0) or (cmbSymType.ItemIndex = 1) then + begin + txtSymOrder.enabled := false; + txtSymNVars.enabled := false; + end else + begin + txtSymOrder.enabled := true; + txtSymNVars.enabled := true; + end; +end; + +procedure TOptionsForm.btnSetAllClick(Sender: TObject); +var + i: integer; +begin + for i := 0 to NRVAR - 1 do + clbVarEnabled.Checked[i] := True; +end; + +procedure TOptionsForm.btnClearAllClick(Sender: TObject); +var + i: integer; +begin + for i := 0 to NRVAR - 1 do + clbVarEnabled.Checked[i] := False; +end; + +procedure TOptionsForm.txtMinNodesChange(Sender: TObject); +begin + if StrToInt(txtMinNodes.Text) > udMaxNodes.position then + udMaxNodes.Position := StrToInt(txtMinNodes.Text); +end; + +procedure TOptionsForm.txtMaxNodesChange(Sender: TObject); +begin + if StrToInt(txtMaxNodes.Text) < udMinNodes.position then + udMinNodes.Position := StrToInt(txtMaxNodes.Text); +end; + +procedure TOptionsForm.txtMaxHueChange(Sender: TObject); +begin + if StrToInt(txtMaxHue.Text) < udMinHue.position then + udMinHue.Position := StrToInt(txtMaxHue.Text); +end; + +procedure TOptionsForm.txtMaxSatChange(Sender: TObject); +begin + if StrToInt(txtMaxSat.Text) < udMinSat.position then + udMinSat.Position := StrToInt(txtMaxSat.Text); +end; + +procedure TOptionsForm.txtMaxLumChange(Sender: TObject); +begin + if StrToInt(txtMaxLum.Text) < udMinLum.position then + udMinLum.Position := StrToInt(txtMaxLum.Text); +end; + +procedure TOptionsForm.txtMinHueChange(Sender: TObject); +begin + if StrToInt(txtMinHue.Text) > udMaxHue.position then + udMaxHue.Position := StrToInt(txtMinHue.Text); +end; + +procedure TOptionsForm.txtMinSatChange(Sender: TObject); +begin + if StrToInt(txtMinSat.Text) > udMaxSat.position then + udMaxSat.Position := StrToInt(txtMinSat.Text); +end; + +procedure TOptionsForm.txtMinLumChange(Sender: TObject); +begin + if StrToInt(txtMinLum.Text) > udMaxLum.position then + udMaxLum.Position := StrToInt(txtMinLum.Text); +end; + +procedure TOptionsForm.txtMinXFormsChange(Sender: TObject); +begin + if StrToInt(txtMinXForms.Text) > udMaxXForms.position then + udMaxXFOrms.Position := StrToInt(txtMinXForms.Text); +end; + +procedure TOptionsForm.txtMaxXformsChange(Sender: TObject); +begin + if StrToInt(txtMaxXForms.Text) < udMinXForms.position then + udMinXForms.Position := StrToInt(txtMaxXforms.Text); +end; + +procedure TOptionsForm.txtMinMutateChange(Sender: TObject); +begin + if StrToInt(txtMinMutate.Text) > udMaxMutate.position then + udMaxMutate.Position := StrToInt(txtMinMutate.Text); +end; + +procedure TOptionsForm.txtMaxMutateChange(Sender: TObject); +begin + if StrToInt(txtMaxMutate.Text) < udMinMutate.position then + udMinMutate.Position := StrToInt(txtMaxMutate.Text); +end; + +procedure TOptionsForm.btnRendererClick(Sender: TObject); +var + fn:string; +begin + OpenDialog.Filter := TextBykey('common-filter-allfiles') + '|*.*'; + OpenDialog.InitialDir := ExtractFilePath(flam3Path); + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + txtRenderer.text := fn; + end; + +end; + +procedure TOptionsForm.SpeedButton2Click(Sender: TObject); +var + fn:string; +begin + OpenDialog.Filter := TextByKey('common-filter-scriptfiles') + '|*.aposcript;*.asc|' + TextBykey('common-filter-allfiles') + '|*.*';; + OpenDialog.InitialDir := ExtractFilePath(defLibrary); + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '.asc', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + txtLibrary.text := fn; + end; +end; + +procedure TOptionsForm.FormCreate(Sender: TObject); +var + i: integer; +begin + btnOK.Caption := TextByKey('common-ok'); + btnCancel.Caption := TextByKey('common-cancel'); + Panel8.Caption := TextByKey('common-lowquality'); + Panel9.Caption := TextByKey('common-mediumquality'); + Panel10.Caption := TextByKey('common-highquality'); + Panel37.Caption := TextByKey('common-width'); + Panel38.Caption := TextByKey('common-height'); + Panel31.Caption := TextByKey('common-filename'); + Panel33.Caption := TextByKey('common-filename'); + Panel44.Caption := TextByKey('common-filename'); + Panel7.Caption := TextByKey('common-filterradius'); + Panel35.Caption := TextByKey('common-filterradius'); + Panel1.Caption := TextByKey('common-density'); + Panel34.Caption := TextByKey('common-density'); + Panel6.Caption := TextByKey('common-oversample'); + Panel36.Caption := TextByKey('common-oversample'); + Panel2.Caption := TextByKey('common-gamma'); + Panel3.Caption := TextByKey('common-brightness'); + Panel4.Caption := TextByKey('common-vibrancy'); + Panel5.Caption := TextByKey('common-gammathreshold'); + cbPNGTransparency.Items[1] := TextByKey('common-enabled'); + cbPNGTransparency.Items[0] := TextByKey('common-disabled'); + Panel13.Caption := TextByKey('common-minimum'); + Panel15.Caption := TextByKey('common-minimum'); + Panel21.Caption := TextByKey('common-minimum'); + Panel22.Caption := TextByKey('common-minimum'); + Panel25.Caption := TextByKey('common-minimum'); + Panel26.Caption := TextByKey('common-minimum'); + Panel14.Caption := TextByKey('common-maximum'); + Panel16.Caption := TextByKey('common-maximum'); + Panel20.Caption := TextByKey('common-maximum'); + Panel23.Caption := TextByKey('common-maximum'); + Panel24.Caption := TextByKey('common-maximum'); + Panel27.Caption := TextByKey('common-maximum'); + Label49.Caption := TextByKey('common-minutes'); + Panel50.Caption := TextByKey('options-tab-general-pluginpath'); + //Panel49.Caption := TextByKey('common-filename') + ' (x64)'; + Panel48.Caption := TextByKey('options-tab-editor-previewtransparency'); + chkEnableEditorPreview.Caption := TextByKey('options-tab-editor-enablepreview'); + self.Caption := TextByKey('options-title'); + GeneralPage.Caption := TextByKey('options-tab-general-title'); + Panel46.Caption := TextByKey('options-tab-general-language'); + pnlMultithreading.Caption := TextByKey('options-tab-general-multithreading'); + cbNrTheads.Items[0] := TextByKey('options-tab-general-multithreading-off'); + //pnlBufferDepth.Caption := TextByKey('options-tab-general-bufferdepth'); + pnlJPEGQuality.Caption := TextByKey('options-tab-general-jpegquality'); + pnlPNGTransparency.Caption := TextByKey('options-tab-general-pngtransparency'); + chkShowRenderStats.Caption := TextByKey('options-tab-general-showextendedstatistics'); + chkConfirmDel.Caption := TextByKey('options-tab-general-confirmdelete'); + chkConfirmExit.Caption := TextByKey('options-tab-general-confirmexit'); + chkconfirmStopRender.Caption := TextByKey('options-tab-general-confirmrenderstop'); + chkOldPaletteFormat.Caption := TextByKey('options-tab-general-oldgradientformat'); + cbUseTemplate.Caption := TextByKey('options-tab-general-alwaysblankflame'); + cbMissingplugin.Caption := TextByKey('options-tab-general-enablemissingpluginswarning'); + cbEmbedThumbs.Caption := TextByKey('options-tab-general-enablethumbnailembedding'); + rgRotationMode.Caption := TextByKey('options-tab-general-rotatemode'); + rgRotationMode.Items[0] := TextByKey('options-tab-general-rotateimage'); + rgRotationMode.Items[1] := TextByKey('options-tab-general-rotateframe'); + rgZoomingMode.Caption := TextByKey('options-tab-general-zoommode'); + rgZoomingMode.Items[0] := TextByKey('options-tab-general-preservequality'); + rgZoomingMode.Items[1] := TextByKey('options-tab-general-preservespeed'); + grpGuidelines.Caption := TextByKey('options-tab-general-guides'); + cbGl.Caption := TextByKey('options-tab-general-enableguides'); + pnlCenter.Caption := TextByKey('options-tab-general-guidecentercolor'); + pnlThirds.Caption := TextByKey('options-tab-general-guidethirdscolor'); + pnlGoldenRatio.Caption := TextByKey('options-tab-general-guidegoldenratiocolor'); + EditorPage.Caption := TextByKey('options-tab-editor-title'); + GroupBox1.Caption := TextByKey('options-tab-editor-editorgraph'); + GroupBox21.Caption := TextByKey('options-tab-editor-editordefaults'); + rgReferenceMode.Caption := TextByKey('options-tab-editor-referencetriangle'); + chkUseXFormColor.Caption := TextByKey('options-tab-editor-usetransformcolor'); + chkHelpers.Caption := TextByKey('options-tab-editor-helperlines'); + chkShowAllXForms.Caption := TextByKey('options-tab-editor-alwaysshowbothtransformtypes'); + pnlBackground.Caption := TextByKey('options-tab-editor-backgroundcolor'); + pnlGrid.Caption := TextByKey('options-tab-editor-gridcolors'); + pnlReferenceC.Caption := TextByKey('options-tab-editor-referencecolor'); + pnlHelpers.Caption := TextByKey('options-tab-editor-helpercolors'); + chkExtendedEdit.Caption := TextByKey('options-tab-editor-extendededit'); + chkAxisLock.Caption := TextByKey('options-tab-editor-locktransformaxes'); + chkXaosRebuild.Caption := TextByKey('options-tab-editor-rebuildxaoslinks'); + rgReferenceMode.Items[0] := TextByKey('options-tab-editor-normalreference'); + rgReferenceMode.Items[1] := TextByKey('options-tab-editor-proportionalreference'); + rgReferenceMode.Items[2] := TextByKey('options-tab-editor-wanderingreference'); + DisplayPage.Caption := TextByKey('options-tab-display-title'); + grpRendering.Caption := TextByKey('options-tab-display-rendering'); + GroupBox2.Caption := TextByKey('options-tab-display-previewdensity'); + GroupBox20.Caption := TextByKey('options-tab-display-mainpreview'); + chkExtendMainPreview.Caption := TextByKey('options-tab-display-extendpreviewbuffer'); + pnlExtension.Caption := TextByKey('options-tab-display-extenspreviewbufferlabel'); + chkShowTransparency.Caption := TextByKey('options-tab-display-showtransparency'); + chkUseSmallThumbs.Caption := TextByKey('options-tab-display-usesmallthumbs'); + RandomPage.Caption := TextByKey('options-tab-random-title'); + gpNumberOfTransforms.Caption := TextByKey('options-tab-random-numberoftransforms'); + gpMutationTransforms.Caption := TextByKey('options-tab-random-mutationtransforms'); + gpFlameTitlePrefix.Caption := TextByKey('options-tab-random-randombatch'); + gpForcedSymmetry.Caption := TextByKey('options-tab-random-forcedsymmetry'); + Panel11.Caption := TextByKey('options-tab-random-batchsize'); + Panel12.Caption := TextByKey('options-tab-random-titleprefix'); + chkKeepBackground.Caption := TextByKey('options-tab-random-keepbackground'); + Panel17.Caption := TextByKey('options-tab-random-symtype'); + Panel18.Caption := TextByKey('options-tab-random-symorder'); + Panel19.Caption := TextByKey('options-tab-random-symlimit'); + cmbSymType.Items[0] := TextByKey('options-tab-random-type-none'); + cmbSymType.Items[1] := TextByKey('options-tab-random-type-bilateral'); + cmbSymType.Items[2] := TextByKey('options-tab-random-type-rotational'); + cmbSymType.Items[3] := TextByKey('options-tab-random-type-dihedral'); + grpGradient.Caption := TextByKey('options-tab-random-onrandom'); + grpGradient.Items[0] := TextByKey('options-tab-random-userandom'); + grpGradient.Items[1] := TextByKey('options-tab-random-usedefault'); + grpGradient.Items[2] := TextByKey('options-tab-random-usecurrent'); + grpGradient.Items[3] := TextByKey('options-tab-random-randomcalculated'); + grpGradient.Items[4] := TextByKey('options-tab-random-randomfromfile'); + GroupBox16.Caption := TextByKey('options-tab-random-filetouse'); + VariationsPage.Caption := TextByKey('options-tab-variations-title'); + btnSetAll.Caption := TextByKey('options-tab-variations-setall'); + btnClearAll.Caption := TextByKey('options-tab-variations-clearall'); + TabSheet1.Caption := TextByKey('options-tab-gradient-title'); + GroupBox23.Caption := TextByKey('options-tab-gradient-numberofnodes'); + GroupBox13.Caption := TextByKey('options-tab-gradient-smoothpalette'); + GroupBox17.Caption := TextByKey('options-tab-gradient-huebetween'); + GroupBox18.Caption := TextByKey('options-tab-gradient-satbetween'); + GroupBox22.Caption := TextByKey('options-tab-gradient-lumbetween'); + Panel28.Caption := TextByKey('options-tab-gradient-numtries'); + Panel29.Caption := TextByKey('options-tab-gradient-trylength'); + TabSheet6.Caption := TextByKey('options-tab-upr-title'); + GroupBox9.Caption := TextByKey('options-tab-upr-paramdefaults'); + GroupBox4.Caption := TextByKey('options-tab-upr-coloralgorithm'); + GroupBox11.Caption := TextByKey('options-tab-upr-uprsize'); + GroupBox5.Caption := TextByKey('options-tab-upr-formula'); + Panel30.Caption := TextByKey('options-tab-upr-identifier'); + Panel32.Caption := TextByKey('options-tab-upr-identifier'); + chkAdjustDensity.Caption := TextByKey('options-tab-upr-adjustdensity'); + PathsPage.Caption := TextByKey('options-tab-environment-title'); + Panel39.Caption := TextByKey('options-tab-environment-defaultparams'); + Panel40.Caption := TextByKey('options-tab-environment-smoothpalette'); + Panel41.Caption := TextByKey('options-tab-environment-functionlib'); + //Panel42.Caption := TextByKey('options-tab-environment-exportrenderer'); + Panel43.Caption := TextByKey('options-tab-environment-helpfile'); + chkRememberLastOpen.Caption := TextByKey('options-tab-environment-rememberlastopen'); + cbEnableAutosave.Caption := TextByKey('options-tab-environment-autosave'); + panel45.Caption := TextByKey('options-tab-environment-savefrequency'); + cbSinglePrecision.Caption := TextByKey('options-tab-general-singleprecision'); + grpEditorColors.Caption := TextByKey('editor-tab-color-title'); + + {$ifdef Apo7X64} + {Panel50.Enabled := false; + btnPluginPath.Enabled := false; + txtPluginFolder.Enabled := false; + Panel50.Font.Color := clGrayText; + cbc64.Enabled := false; + cbc64.Font.Color := clGrayText; } + {$endif} + + for i:= 0 to NRVAR - 1 do begin + clbVarEnabled.AddItem(varnames(i),nil); + end; +end; + +procedure TOptionsForm.pnlCenterLineClick(Sender: TObject); +begin + if (not cbGL.Checked) then exit; + AdjustForm.ColorDialog.Color := pnlCenterLine.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlCenterLine.Color := AdjustForm.ColorDialog.Color; + LineCenterColor := Integer(pnlCenterLine.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.pnlThirdsLineClick(Sender: TObject); +begin + if (not cbGL.Checked) then exit; + AdjustForm.ColorDialog.Color := pnlThirdsLine.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlThirdsLine.Color := AdjustForm.ColorDialog.Color; + LineThirdsColor := Integer(pnlThirdsLine.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.pnlGRLineClick(Sender: TObject); +begin + if (not cbGL.Checked) then exit; + AdjustForm.ColorDialog.Color := pnlGRLine.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlGRLine.Color := AdjustForm.ColorDialog.Color; + LineGRColor := Integer(pnlGRLine.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.pnlBackColorClick(Sender: TObject); +begin + AdjustForm.ColorDialog.Color := pnlBackColor.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlBackColor.Color := AdjustForm.ColorDialog.Color; + EditorBkgColor := Integer(pnlBackColor.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.pnlReferenceClick(Sender: TObject); +begin + AdjustForm.ColorDialog.Color := pnlReference.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlReference.Color := AdjustForm.ColorDialog.Color; + ReferenceTriangleColor := Integer(pnlReference.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.pnlGridColor1Click(Sender: TObject); +begin + AdjustForm.ColorDialog.Color := pnlGridColor1.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlGridColor1.Color := AdjustForm.ColorDialog.Color; + GridColor1 := Integer(pnlGridColor1.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.pnlGridColor2Click(Sender: TObject); +begin + AdjustForm.ColorDialog.Color := pnlGridColor2.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlGridColor2.Color := AdjustForm.ColorDialog.Color; + GridColor2 := Integer(pnlGridColor2.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.pnlHelpersColorClick(Sender: TObject); +begin + AdjustForm.ColorDialog.Color := pnlHelpersColor.Color; + if AdjustForm.ColorDialog.Execute then + begin + pnlHelpersColor.Color := AdjustForm.ColorDialog.Color; + HelpersColor := Integer(pnlHelpersColor.color); + UpdateShapeColors; + end; +end; + +procedure TOptionsForm.btnBrowseSoundClick(Sender: TObject); +var + fn:string; +begin + OpenDialog.InitialDir := ExtractFilePath(RenderCompleteSoundFile); + OpenDialog.Filter := 'Waveform files (*.wav)|*.wav'; + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '.wav', OpenDialog.Filter, OpenDialog.InitialDir, 'Open file...', fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + txtSoundFile.text := fn; + end; +end; + +procedure TOptionsForm.btnPlayClick(Sender: TObject); +begin + if txtSoundFile.text <> '' then + sndPlaySound(PChar(txtSoundFile.text), SND_FILENAME or SND_ASYNC) + else + sndPlaySound(pchar(SND_ALIAS_SYSTEMASTERISK), SND_ALIAS_ID or SND_NOSTOP or SND_ASYNC); +end; + +procedure TOptionsForm.btnPluginPathClick(Sender: TObject); +var + TitleName : string; + lpItemID : PItemIDList; + BrowseInfo : TBrowseInfo; + DisplayName : array[0..MAX_PATH] of char; + TempPath : array[0..MAX_PATH] of char; +begin + FillChar(BrowseInfo, sizeof(TBrowseInfo), #0); + BrowseInfo.hwndOwner := self.Handle; + BrowseInfo.pszDisplayName := @DisplayName; + TitleName := 'Please specify the plugin folder'; + BrowseInfo.lpszTitle := PChar(TitleName); + BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS; + lpItemID := SHBrowseForFolder(BrowseInfo); + if lpItemId <> nil then begin + SHGetPathFromIDList(lpItemID, TempPath); + txtPluginFolder.Text := TempPath; + GlobalFreePtr(lpItemID); + end; +end; + +procedure TOptionsForm.btnGradientsFileClick(Sender: TObject); +var + fn:string; +begin + OpenDialog.Filter := TextByKey('common-filter-gradientfiles') + '|*.gradient;*.ugr|' + TextBykey('common-filter-allfiles') + '|*.*'; + OpenDialog.InitialDir := ExtractFilePath(randGradientFile); + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '.ugr', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + txtGradientsFile.text := fn; + end; +end; + +procedure TOptionsForm.shBackgroundMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + pnlBackColorClick(Sender); +end; + +procedure TOptionsForm.shCenterLineMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + pnlCenterLineClick(Sender); +end; + +procedure TOptionsForm.shThirdsLineMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + pnlThirdsLineClick(Sender); +end; + +procedure TOptionsForm.shGRLineMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + pnlGRLineClick(Sender); +end; + +procedure TOptionsForm.shGC1MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + pnlGridColor1Click(Sender); +end; + +procedure TOptionsForm.shGC2MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + pnlGridColor2Click(Sender); +end; + +procedure TOptionsForm.shRefMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + pnlReferenceClick(Sender); +end; + +procedure TOptionsForm.shHelpersMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + pnlHelpersColorClick(Sender); +end; + +procedure TOptionsForm.chkRememberLastOpenClick(Sender: TObject); +begin + if chkRememberLastOpen.Checked then begin + txtDefParameterFile.Enabled := false; + txtDefParameterFile.Text := ''; //LastOpenFile; + btnDefGradient.Enabled := false; + end else begin + txtDefParameterFile.Enabled := true; + btnDefGradient.Enabled := true; + end; + + Panel39.Enabled := txtDefParameterFile.Enabled; + + if (Panel39.Enabled) then Panel39.Font.Color := clWindowText + else Panel39.Font.Color := clGrayText; +end; + +procedure TOptionsForm.chkUseSmallThumbsClick(Sender: TObject); +begin + Label45.Visible := true; +end; + +procedure TOptionsForm.btnFindDefaultSaveFileClick(Sender: TObject); +var fn:string; +begin + OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame|' + TextBykey('common-filter-allfiles') + '|*.*'; + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '.flame', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, false, false, false, false) then + //if OpenDialog.Execute then + begin + txtDefaultSaveFile.text := fn; + end; +end; + +procedure TOptionsForm.cbEnableAutosaveClick(Sender: TObject); +begin + Panel44.Enabled := cbEnableAutoSave.Checked; + Panel45.Enabled := cbEnableAutoSave.Checked; + Label49.Enabled := cbEnableAutoSave.Checked; + if (Panel44.Enabled) then Panel44.Font.Color := clWindowText + else Panel44.Font.Color := clGrayText; + if (Panel45.Enabled) then Panel45.Font.Color := clWindowText + else Panel45.Font.Color := clGrayText; + txtDefaultSaveFile.Enabled := cbEnableAutoSave.Checked; + btnFindDefaultSaveFile.Enabled := cbEnableAutoSave.Checked; + cbFreq.Enabled := cbEnableAutoSave.Checked; +end; + +procedure TOptionsForm.btnHelpClick(Sender: TObject); +var + fn:string; +begin + OpenDialog.Filter := TextBykey('common-filter-allfiles') + '|*.*'; + OpenDialog.InitialDir := ExtractFilePath(helpPath); + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + txtHelp.text := fn; + end; +end; + +procedure TOptionsForm.cbGLClick(Sender: TObject); +begin + pnlCenter.Enabled := cbGL.Checked; + pnlThirds.Enabled := cbGL.Checked; + pnlGoldenRatio.Enabled := cbGL.Checked; + + if (pnlCenter.Enabled) then pnlCenter.Font.Color := clWindowText + else pnlCenter.Font.Color := clGrayText; + + if (pnlThirds.Enabled) then pnlThirds.Font.Color := clWindowText + else pnlThirds.Font.Color := clGrayText; + + if (pnlGoldenRatio.Enabled) then pnlGoldenRatio.Font.Color := clWindowText + else pnlGoldenRatio.Font.Color := clGrayText; +end; + +procedure TOptionsForm.SpeedButton1Click(Sender: TObject); +var fn, fn2, s1, s2:string; i : integer; +begin + OpenDialog.Filter := 'Extensible Markup Language Files (*.xml)|*.xml'; + OpenDialog.InitialDir := ExtractFilePath(helpPath); + OpenDialog.FileName := ''; + if OpenSaveFileDialog(OptionsForm, '', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then + //if OpenDialog.Execute then + begin + fn2 := ExtractFilePath(Application.ExeName) + 'Languages\' + ExtractFileName(fn); + LanguageInfo(fn, s1, s2); + if s1 <> '' then begin + if not DirectoryExists(ExtractFilePath(Application.ExeName) + 'Languages\') then + CreateDirectory(PChar(ExtractFilePath(Application.ExeName) + 'Languages\'), nil); + if (lowercase(ExtractFilePath(fn)) <> lowercase(ExtractFilePath(Application.ExeName) + 'Languages\')) then + CopyFile(PChar(fn), PChar(fn2), False); + AvailableLanguages.Add(fn2); + i := AvailableLanguages.Count - 1; + if (s2 <> '') then + s1 := s2 + ' (' + s1 + ')'; + txtLanguageFile.Items.Add(s1); + txtLanguageFile.ItemIndex := txtLanguageFile.Items.Count - 1; + end else begin + Application.MessageBox(PChar(TextByKey('common-invalidformat')), PChar('Apophysis'), MB_ICONERROR); + end; + end; +end; + +procedure TOptionsForm.chkEnableEditorPreviewClick(Sender: TObject); +begin + Panel48.Enabled := chkEnableEditorPreview.Checked; + if chkEnableEditorPreview.Checked then + Panel48.Font.Color := clWindowText + else Panel48.Font.Color := clGrayText; + tbEPTransparency.Enabled := chkEnableEditorPreview.Checked; +end; + +end. + diff --git a/Forms/Preview.dfm b/Forms/Preview.dfm new file mode 100644 index 0000000..ff56580 --- /dev/null +++ b/Forms/Preview.dfm @@ -0,0 +1,42 @@ +object PreviewForm: TPreviewForm + Left = 541 + Top = 357 + Width = 212 + Height = 181 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSizeToolWin + Caption = 'Preview' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnKeyPress = FormKeyPress + PixelsPerInch = 96 + TextHeight = 13 + object BackPanel: TPanel + Left = 0 + Top = 0 + Width = 204 + Height = 152 + Align = alClient + BevelInner = bvLowered + BevelOuter = bvLowered + Color = clBlack + TabOrder = 0 + object Image: TImage + Left = 2 + Top = 2 + Width = 200 + Height = 153 + Align = alClient + AutoSize = True + Stretch = True + end + end +end diff --git a/Forms/Preview.pas b/Forms/Preview.pas new file mode 100644 index 0000000..07385ac --- /dev/null +++ b/Forms/Preview.pas @@ -0,0 +1,94 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Preview; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ExtCtrls, ControlPoint, RenderingInterface, Translation; + +type + TPreviewForm = class(TForm) + BackPanel: TPanel; + Image: TImage; + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormKeyPress(Sender: TObject; var Key: Char); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + private + public + cp: TControlPoint; + Render: TRenderer; + procedure DrawFlame; + end; + +var + PreviewForm: TPreviewForm; + +implementation + +uses Main, Global, ScriptForm; + +{$R *.DFM} + +procedure TPreviewForm.DrawFlame; +begin + Render.Stop; +// ScriptEditor.GetCpFromFlame(cp); + cp.width := Image.width; + cp.Height := Image.Height; +// Render.Compatibility := Compatibility; + Render.SetCP(cp); + Render.Render; + Image.Picture.Bitmap.Assign(Render.GetImage); + Application.ProcessMessages; +end; + + +procedure TPreviewForm.FormCreate(Sender: TObject); +begin + self.Caption := TextbyKey('preview-title'); + cp := TControlPoint.Create; + Render := TRenderer.Create; +end; + +procedure TPreviewForm.FormDestroy(Sender: TObject); +begin + Render.Free; + cp.Free; +end; + +procedure TPreviewForm.FormKeyPress(Sender: TObject; var Key: Char); +begin + ScriptEditor.Stopped := True; +end; + +procedure TPreviewForm.FormClose(Sender: TObject; + var Action: TCloseAction); +begin + ScriptEditor.Stopped := True; +end; + +end. + diff --git a/Forms/Save.dfm b/Forms/Save.dfm new file mode 100644 index 0000000..9d54ddb --- /dev/null +++ b/Forms/Save.dfm @@ -0,0 +1,152 @@ +object SaveForm: TSaveForm + Left = 434 + Top = 432 + BorderStyle = bsDialog + Caption = 'Save Parameters' + ClientHeight = 153 + ClientWidth = 517 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -14 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poOwnerFormCenter + OnCreate = FormCreate + OnShow = FormShow + DesignSize = ( + 517 + 153) + PixelsPerInch = 120 + TextHeight = 16 + object btnDefGradient: TSpeedButton + Left = 480 + Top = 9 + Width = 30 + Height = 29 + Hint = 'Browse...' + Anchors = [akTop, akRight] + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -15 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F + 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13 + 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708 + 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3 + 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367 + 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51 + C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF + 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC + EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67 + D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2 + 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8 + FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788 + A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6 + A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788 + 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89 + 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA + ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnDefGradientClick + end + object btnSave: TButton + Left = 322 + Top = 116 + Width = 93 + Height = 30 + Anchors = [akRight, akBottom] + Caption = '&Save' + Default = True + TabOrder = 2 + OnClick = btnSaveClick + end + object btnCancel: TButton + Left = 421 + Top = 116 + Width = 92 + Height = 30 + Anchors = [akRight, akBottom] + Caption = 'Cancel' + TabOrder = 3 + OnClick = btnCancelClick + end + object pnlTarget: TPanel + Left = 10 + Top = 10 + Width = 124 + Height = 26 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Destination' + ParentShowHint = False + ShowHint = True + TabOrder = 4 + end + object pnlName: TPanel + Left = 10 + Top = 39 + Width = 124 + Height = 26 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Name' + ParentShowHint = False + ShowHint = True + TabOrder = 5 + end + object txtFilename: TEdit + Left = 128 + Top = 10 + Width = 353 + Height = 24 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + Text = 'txtFilename' + end + object txtTitle: TEdit + Left = 128 + Top = 39 + Width = 383 + Height = 24 + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + Text = 'txtTitle' + end + object optUseOldFormat: TRadioButton + Left = 10 + Top = 79 + Width = 304 + Height = 21 + Anchors = [akLeft, akTop, akRight] + Caption = 'Use classic flame format' + Checked = True + TabOrder = 6 + TabStop = True + end + object optUseNewFormat: TRadioButton + Left = 10 + Top = 101 + Width = 304 + Height = 21 + Anchors = [akLeft, akTop, akRight] + Caption = 'Use new flame format' + Enabled = False + TabOrder = 7 + end +end diff --git a/Forms/Save.pas b/Forms/Save.pas new file mode 100644 index 0000000..9da6f9c --- /dev/null +++ b/Forms/Save.pas @@ -0,0 +1,225 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Save; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, Buttons, ExtCtrls, Translation; + +type + ESaveType = (stSaveParameters, stSaveAllParameters, stSaveGradient, stExportUPR); + TSaveForm = class(TForm) + txtFilename: TEdit; + txtTitle: TEdit; + btnSave: TButton; + btnCancel: TButton; + btnDefGradient: TSpeedButton; + pnlTarget: TPanel; + pnlName: TPanel; + optUseOldFormat: TRadioButton; + optUseNewFormat: TRadioButton; + procedure FormCreate(Sender: TObject); + procedure btnSaveClick(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnDefGradientClick(Sender: TObject); + private + public + Title: string; + Filename: string; + SaveType : ESaveType; + end; + +var + SaveForm: TSaveForm; + +implementation + +uses Main, Global, cmap; + +{$R *.DFM} + +function EntryExists(En, Fl: string): boolean; +{ Searches for existing identifier in parameter files } +var + FStrings: TStringList; + i: integer; +begin + Result := False; + if FileExists(Fl) then + begin + FStrings := TStringList.Create; + try + FStrings.LoadFromFile(Fl); + for i := 0 to FStrings.Count - 1 do + if Pos(LowerCase(En) + ' {', Lowercase(FStrings[i])) = 1 then + Result := True; + finally + FStrings.Free; + end + end + else + Result := False; +end; + +function SaveTypeTextKey(st : ESaveType) : string; +begin + case st of + stSaveParameters: Result := 'save-type-parameters'; + stSaveAllParameters: Result := 'save-type-allparameters'; + stSaveGradient: Result := 'save-type-gradient'; + stExportUPR: Result := 'save-type-exportupr'; + end; +end; + +function SaveDefaultExt(st : ESaveType) : string; +begin + case st of + stSaveParameters: Result := 'flame'; + stSaveAllParameters: Result := 'flame'; + stSaveGradient: Result := 'gradient'; + stExportUPR: Result := 'upr'; + end; +end; + +function SaveFilter(st : ESaveType): string; +begin + case st of + stSaveParameters: Result := Format('%s|*.flame;*.xml|%s|*.*', + [TextByKey('common-filter-flamefiles'), TextByKey('common-filter-allfiles')]); + stSaveAllParameters: Result := Format('%s|*.flame;*.xml|%s|*.*', + [TextByKey('common-filter-flamefiles'), TextByKey('common-filter-allfiles')]); + stSaveGradient: Result := Format('%s|*.gradient;*.ugr|%s|*.*', + [TextByKey('common-filter-gradientfiles'), TextByKey('common-filter-allfiles')]); + stExportUPR: Result := Format('%s|*.upr|%s|*.*', + [TextByKey('common-filter-uprfiles'), TextByKey('common-filter-allfiles')]); + end; + +end; + +procedure TSaveForm.btnSaveClick(Sender: TObject); +var + t, f: string; + check, onestr: boolean; +begin + t := Trim(txtTitle.Text); + f := Trim(txtFilename.Text); + + if ((t = '') and txtTitle.Enabled) then + begin + Application.MessageBox(PChar(TextByKey('save-status-notitle')), 'Apophysis', 48); + Exit; + end; + if f = '' then + begin + Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), 'Apophysis', 48); + Exit; + end; + if ExtractFileExt(f) = '' then + begin + Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), 'Apophysis', 48); + Exit; + end; + + if SaveType = stSaveParameters then + begin + check := XMLEntryExists(t, f); + onestr := false; + end + else if SaveType = stSaveAllParameters then + begin + onestr := true; + check := FileExists(f); + end + else + begin + onestr := false; + t := CleanIdentifier(t); + check := EntryExists(t, f); + end; + + if check then begin if onestr then begin + if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists2'), [f])), + 'Apophysis', 52) = ID_NO then exit; + end else begin + if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists'), [t, f])), + 'Apophysis', 52) = ID_NO then exit; + end end; + + if (t = '*') then t := ''; + Title := t; + Filename := f; + ModalResult := mrOK; +end; + +procedure TSaveForm.btnCancelClick(Sender: TObject); +begin + ModalResult := mrCancel; +end; + +procedure TSaveForm.FormShow(Sender: TObject); +begin + txtFilename.Text := Filename; + txtTitle.Text := Title; + //btnSave.SetFocus; + self.Caption := TextByKey(SaveTypeTextKey(SaveType)); + {if (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters) then + self.Height := 160 + else self.Height := 120; } + + if (SaveType = stSaveAllParameters) then txtTitle.Text := ''; + txtTitle.Enabled := (SaveType = stSaveParameters) or (SaveType = stExportUPR) or (SaveType = stSaveGradient); + if (not txtTitle.Enabled) then pnlName.Font.Color := clGrayText + else pnlName.Font.Color := clWindowText; + + optUseOldFormat.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters); + optUseNewFormat.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters); +end; + +procedure TSaveForm.btnDefGradientClick(Sender: TObject); +var + fn:string; + promptOverwrite: boolean; +begin + promptOverwrite := (SaveType <> stSaveParameters); + if OpenSaveFileDialog(self, SaveDefaultExt(SaveType), SaveFilter(SaveType), + ExtractFilePath(txtFilename.Text), TextByKey('common-browse'), fn, false, + (*promptOverwrite*)false, false, false) then + txtFileName.Text := fn; +end; + +procedure TSaveForm.FormCreate(Sender: TObject); +begin + btnCancel.Caption := TextByKey('common-cancel'); + btnSave.Caption := TextByKey('common-ok'); + btnDefGradient.Hint := TextByKey('common-browse'); + pnlTarget.Caption := TextByKey('common-destination'); + pnlName.Caption := TextByKey('save-name'); + optUseOldFormat.Caption := TextByKey('save-oldformat'); + optUseNewFormat.Caption := TextByKey('save-newformat'); +end; + +end. + diff --git a/Forms/SavePreset.dfm b/Forms/SavePreset.dfm new file mode 100644 index 0000000..664790d --- /dev/null +++ b/Forms/SavePreset.dfm @@ -0,0 +1,63 @@ +object SavePresetForm: TSavePresetForm + Left = 295 + Top = 331 + BorderStyle = bsDialog + Caption = 'Save Preset' + ClientHeight = 66 + ClientWidth = 349 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnCreate = FormCreate + DesignSize = ( + 349 + 66) + PixelsPerInch = 96 + TextHeight = 13 + object Button1: TButton + Left = 190 + Top = 37 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'OK' + Default = True + ModalResult = 1 + TabOrder = 1 + OnClick = Button1Click + end + object Button2: TButton + Left = 270 + Top = 37 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Cancel' + ModalResult = 2 + TabOrder = 2 + end + object pnlName: TPanel + Left = 8 + Top = 8 + Width = 101 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Name' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + object txtPresetName: TEdit + Left = 104 + Top = 8 + Width = 239 + Height = 21 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + end +end diff --git a/Forms/SavePreset.pas b/Forms/SavePreset.pas new file mode 100644 index 0000000..c255827 --- /dev/null +++ b/Forms/SavePreset.pas @@ -0,0 +1,69 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit SavePreset; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls, Translation; + +type + TSavePresetForm = class(TForm) + txtPresetName: TEdit; + Button1: TButton; + Button2: TButton; + pnlName: TPanel; + procedure FormCreate(Sender: TObject); + procedure Button1Click(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + SavePresetForm: TSavePresetForm; + +implementation + +{$R *.DFM} + +procedure TSavePresetForm.Button1Click(Sender: TObject); +begin + if txtPresetName.Text = '' then + begin + Application.MessageBox(PChar(TextByKey('savepreset-notitle')), 'Apophysis', 48); + Exit; + end; +end; + +procedure TSavePresetForm.FormCreate(Sender: TObject); +begin + self.Caption := TextBykey('savepreset-title'); + button1.Caption := TextByKey('common-ok'); + button2.Caption := TextByKey('common-cancel'); + pnlName.Caption := TextByKey('savepreset-name'); +end; + +end. diff --git a/Forms/ScriptForm.dfm b/Forms/ScriptForm.dfm new file mode 100644 index 0000000..ca3ac3c --- /dev/null +++ b/Forms/ScriptForm.dfm @@ -0,0 +1,625 @@ +object ScriptEditor: TScriptEditor + Left = 312 + Top = 383 + Caption = 'Script Editor' + ClientHeight = 485 + ClientWidth = 583 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + Icon.Data = { + 0000010001001010000001002000680400001600000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000006349 + 35146349352E927A69FF8C7563FF87705EFF6349352E7F6654FF7A624FFF755D + 4AFF6349352E6E5441FF6A513EFF674E3AFF6349352E00000000000000006349 + 352EAE9888FFEFE3DDFFF2E7E1FFEDDFD7FF836B59FFB79B8BFFDBBDADFFD9B7 + A6FF725946FFAE8B77FFD0A692FFCC9E87FF654B38FF6349352E00000000B7A2 + 93FFFBF8F7FFF9F4F2FFF7F0ECFFF4EBE6FFF1E5DFFF7F6754FF7A624FFF765D + 4AFF735946FF6E5542FF6B523EFF674E3AFF654B38FF634935FF00000000B7A2 + 93FFFDFCFBFFFBF9F7FFFAF5F2FFF7EFEDFFF4EAE6FFF2E5DFFFDDDCD7FFDFD7 + CEFFDECDC0FFDEC5B6FFDEBFACFFDBBAA6FFD8B5A3FF634935FF00000000B7A2 + 93FFFFFFFFFFB47F65FFB47F64FFEDDDD5FFB37E63FFF4EBE6FFF1E5DFFFEFDF + D7FFEBD9D1FFE8D3C9FFE5CDC1FFE1C6B9FFD6B3A1FF634A35FF00000000B9A4 + 95FFFFFFFFFFFFFFFFFFFDFCFCFFFCF9F7FFFAF4F2FFF6F0ECFFF4EBE5FFF2E5 + DFFFEEDFD8FFEBD9D0FFE8D3C8FFE5CCC1FFDBBDADFF634A36FF00000000BDA7 + 98FFFFFFFFFF968E88FFEEDED7FF968E87FFEDDDD6FF968D86FF958C85FFF4EB + E6FFF2E5DFFFEFDFD8FFECD9D0FFE8D3C9FFE0C7BAFF634A35FF00000000C1AB + 9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFCFFFBF8F7FFFAF4F2FFF7F0 + ECFFF4EAE6FFF1E5DFFFEEDFD7FFEBD9D0FFE6D1C6FF634A35FF00000000C5AF + A0FFFFFFFFFFB48065FFB48065FF968E88FFC2B0A3FF968E87FF968E86FFF9F4 + F2FFF7EFECFFF4EBE6FFF2E5DFFFEFDFD8FFEADBD1FF634936FF00000000C8B2 + A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFCFFFCF8 + F7FFF9F5F2FFF7F0ECFFF4EBE6FFF1E5DFFFEEE2DAFF644A36FF00000000C9B4 + A5FFFFFFFFFFFFFFFFFF66A365FF66A365FF66A365FFC0B4ADFF66A365FF66A3 + 65FF66A264FFFAF5F2FFF7F0ECFFF4EBE6FFEEE2DAFF644A36FF00000000C8B2 + A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFEFCFBFFFBF9F7FFFAF4F2FFF7F0EDFFF3EAE4FF644A36FF00000000C8B2 + A3FFCAB4A5FFCBB5A6FFCAB4A5FFC9B3A4FFC7B2A3FFC6B0A1FFC3AE9FFFC1AC + 9DFFBFAA9BFFBDA899FFBBA697FFB9A495FFB8A394FFB7A293FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000FFFF00000003000000010000000100000001000000010000000100000001 + 0000000100000001000000010000000100000001000000010000FFFF0000} + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShortCut = FormShortCut + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object Splitter1: TSplitter + Left = 0 + Top = 373 + Width = 583 + Height = 4 + Cursor = crVSplit + Align = alBottom + end + object ToolBar: TToolBar + Left = 560 + Top = 0 + Width = 23 + Height = 373 + Align = alRight + AutoSize = True + Caption = 'ToolBar' + Images = MainForm.Buttons + ParentShowHint = False + ShowHint = True + TabOrder = 0 + object btnNew: TToolButton + Left = 0 + Top = 0 + Hint = 'New' + Caption = 'btnNew' + ImageIndex = 0 + Wrap = True + OnClick = btnNewClick + end + object btnOpen: TToolButton + Left = 0 + Top = 22 + Hint = 'Open' + Caption = 'btnOpen' + ImageIndex = 1 + Wrap = True + OnClick = btnOpenClick + end + object btnSave: TToolButton + Left = 0 + Top = 44 + Hint = 'Save' + Caption = 'btnSave' + ImageIndex = 2 + Wrap = True + OnClick = btnSaveClick + end + object btnRun: TToolButton + Left = 0 + Top = 66 + Hint = 'Run' + Caption = 'btnRun' + ImageIndex = 43 + Wrap = True + OnClick = btnRunClick + end + object btnStop: TToolButton + Left = 0 + Top = 88 + Hint = 'Stop' + Caption = 'btnStop' + Enabled = False + ImageIndex = 36 + Wrap = True + OnClick = btnStopClick + end + object btnBreak: TToolButton + Left = 0 + Top = 110 + Hint = 'Break' + Enabled = False + ImageIndex = 37 + OnClick = btnBreakClick + end + end + object StatusBar: TStatusBar + Left = 0 + Top = 466 + Width = 583 + Height = 19 + Anchors = [akLeft, akRight] + Panels = <> + end + object BackPanel: TPanel + Left = 0 + Top = 0 + Width = 560 + Height = 373 + Align = alClient + BevelInner = bvLowered + BevelOuter = bvLowered + Caption = 'BackPanel' + TabOrder = 2 + object Editor: TAdvMemo + Left = 2 + Top = 2 + Width = 556 + Height = 369 + Cursor = crIBeam + PopupMenu = PopupMenu + ActiveLineSettings.ShowActiveLine = False + ActiveLineSettings.ShowActiveLineIndicator = False + Align = alClient + AutoCompletion.Font.Charset = DEFAULT_CHARSET + AutoCompletion.Font.Color = clWindowText + AutoCompletion.Font.Height = -11 + AutoCompletion.Font.Name = 'MS Sans Serif' + AutoCompletion.Font.Style = [] + AutoCompletion.Height = 120 + AutoCompletion.StartToken = '(.' + AutoCompletion.Width = 400 + AutoCorrect.Active = True + AutoHintParameterPosition = hpBelowCode + BlockShow = False + BlockColor = clWindow + BlockLineColor = clGray + BkColor = clWindow + BookmarkGlyph.Data = { + 36050000424D3605000000000000360400002800000010000000100000000100 + 0800000000000001000000000000000000000001000000000000000000000000 + 80000080000000808000800000008000800080800000C0C0C000C0DCC000F0CA + A6000020400000206000002080000020A0000020C0000020E000004000000040 + 20000040400000406000004080000040A0000040C0000040E000006000000060 + 20000060400000606000006080000060A0000060C0000060E000008000000080 + 20000080400000806000008080000080A0000080C0000080E00000A0000000A0 + 200000A0400000A0600000A0800000A0A00000A0C00000A0E00000C0000000C0 + 200000C0400000C0600000C0800000C0A00000C0C00000C0E00000E0000000E0 + 200000E0400000E0600000E0800000E0A00000E0C00000E0E000400000004000 + 20004000400040006000400080004000A0004000C0004000E000402000004020 + 20004020400040206000402080004020A0004020C0004020E000404000004040 + 20004040400040406000404080004040A0004040C0004040E000406000004060 + 20004060400040606000406080004060A0004060C0004060E000408000004080 + 20004080400040806000408080004080A0004080C0004080E00040A0000040A0 + 200040A0400040A0600040A0800040A0A00040A0C00040A0E00040C0000040C0 + 200040C0400040C0600040C0800040C0A00040C0C00040C0E00040E0000040E0 + 200040E0400040E0600040E0800040E0A00040E0C00040E0E000800000008000 + 20008000400080006000800080008000A0008000C0008000E000802000008020 + 20008020400080206000802080008020A0008020C0008020E000804000008040 + 20008040400080406000804080008040A0008040C0008040E000806000008060 + 20008060400080606000806080008060A0008060C0008060E000808000008080 + 20008080400080806000808080008080A0008080C0008080E00080A0000080A0 + 200080A0400080A0600080A0800080A0A00080A0C00080A0E00080C0000080C0 + 200080C0400080C0600080C0800080C0A00080C0C00080C0E00080E0000080E0 + 200080E0400080E0600080E0800080E0A00080E0C00080E0E000C0000000C000 + 2000C0004000C0006000C0008000C000A000C000C000C000E000C0200000C020 + 2000C0204000C0206000C0208000C020A000C020C000C020E000C0400000C040 + 2000C0404000C0406000C0408000C040A000C040C000C040E000C0600000C060 + 2000C0604000C0606000C0608000C060A000C060C000C060E000C0800000C080 + 2000C0804000C0806000C0808000C080A000C080C000C080E000C0A00000C0A0 + 2000C0A04000C0A06000C0A08000C0A0A000C0A0C000C0A0E000C0C00000C0C0 + 2000C0C04000C0C06000C0C08000C0C0A000F0FBFF00A4A0A000808080000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FDFD25252525 + 2525252525252525FDFDFD2E25FFFFFFFFFFFFFFFFFFFF25FDFDFD2525252525 + 2525252525252525FDFD9A9AB7B7B7B7B7B7B7B7B7B72525FDFDFD25B7B7B7B7 + B7B7B7B7B7B72525FDFD9A9AB7B7B7B7B7B7B7B7B7B72525FDFDFD25BFB7BFBF + B7B7B7B7B7B72525FDFD9A9ABFBFBFB7BFBFB7B7B7B72525FDFDFD25BFBFBFBF + BFB7BFBFB7B72525FDFD9A9ABFBFBFB7BFBFBFB7BFB72525FDFDFD25BFBFBFBF + BFBFBFBFBFB72525FDFD9A9ABFBFBFBFBFB7BFBFB7B72525FDFDFD25BFBFBFBF + BFBFBFBFBFB72525FDFD9A9ABFBFBFBFBFBFBFBFBFB725FDFDFDFD2525252525 + 25252525252525FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD} + BorderStyle = bsNone + ClipboardFormats = [cfText] + CodeFolding.Enabled = False + CodeFolding.LineColor = clGray + Ctl3D = False + DelErase = True + EnhancedHomeKey = False + Gutter.DigitCount = 4 + Gutter.Font.Charset = DEFAULT_CHARSET + Gutter.Font.Color = clWindowText + Gutter.Font.Height = -13 + Gutter.Font.Name = 'Courier New' + Gutter.Font.Style = [] + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlack + Font.Height = -13 + Font.Name = 'COURIER NEW' + Font.Style = [] + HiddenCaret = False + Lines.Strings = ( + '{ Rotate the reference triangle continuously }' + '{ Hit any key to stop }' + 'Flame.SampleDensity := 1;' + 'while not Stopped do' + 'begin' + ' RotateReference(3.6);' + ' Preview;' + 'end;') + MarkerList.UseDefaultMarkerImageIndex = False + MarkerList.DefaultMarkerImageIndex = -1 + MarkerList.ImageTransparentColor = 33554432 + PrintOptions.MarginLeft = 0 + PrintOptions.MarginRight = 0 + PrintOptions.MarginTop = 0 + PrintOptions.MarginBottom = 0 + PrintOptions.PageNr = False + PrintOptions.PrintLineNumbers = False + RightMarginColor = 14869218 + ScrollHint = False + SelColor = clWhite + SelBkColor = clHighlight + ShowRightMargin = True + SmartTabs = False + SyntaxStyles = Styler + TabOrder = 0 + TabSize = 4 + TabStop = True + TrimTrailingSpaces = False + UILanguage.ScrollHint = 'Row' + UILanguage.Undo = 'Undo' + UILanguage.Redo = 'Redo' + UILanguage.Copy = 'Copy' + UILanguage.Cut = 'Cut' + UILanguage.Paste = 'Paste' + UILanguage.Delete = 'Delete' + UILanguage.SelectAll = 'Select All' + UrlAware = False + UrlStyle.TextColor = clBlue + UrlStyle.BkColor = clWhite + UrlStyle.Style = [fsUnderline] + UseStyler = True + Version = '3.0.0.0' + WordWrap = wwNone + OnChange = EditorChange + end + end + object Console: TMemo + Left = 0 + Top = 377 + Width = 583 + Height = 89 + Align = alBottom + Constraints.MinHeight = 20 + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 3 + end + object MainOpenDialog: TOpenDialog + DefaultExt = 'asc' + Filter = 'Apophysis Script Files (*.asc)|*.asc|Text files (*.txt)|*.txt' + Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing] + Left = 472 + Top = 64 + end + object MainSaveDialog: TSaveDialog + DefaultExt = 'asc' + Filter = 'Apophysis Script Files (*.asc)|*.asc|Text files (*.txt)|*.txt' + Options = [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing] + Left = 344 + Top = 32 + end + object PopupMenu: TPopupMenu + Images = MainForm.Buttons + Left = 280 + Top = 112 + object mnuUndo: TMenuItem + Caption = 'Undo' + ImageIndex = 4 + OnClick = mnuUndoClick + end + object N1: TMenuItem + Caption = '-' + end + object mnuCut: TMenuItem + Caption = 'Cut' + ImageIndex = 6 + ShortCut = 16472 + OnClick = mnuCutClick + end + object mnuCopy: TMenuItem + Caption = 'Copy' + ImageIndex = 7 + OnClick = mnuCopyClick + end + object mnuPaste: TMenuItem + Caption = 'Paste' + ImageIndex = 8 + OnClick = mnuPasteClick + end + end + object Scripter: TatPascalScripter + SourceCode.Strings = ( + '') + SaveCompiledCode = False + EventSupport = False + OnCompileError = ScripterCompileError + ShortBooleanEval = False + LibOptions.SearchPath.Strings = ( + '$(CURDIR)' + '$(APPDIR)') + LibOptions.SourceFileExt = '.psc' + LibOptions.CompiledFileExt = '.pcu' + LibOptions.UseScriptFiles = False + CallExecHookEvent = False + Left = 480 + Top = 200 + end + object OpenDialog: TOpenDialog + DefaultExt = 'fla' + Filter = + 'Flame files (*.flame)|*.flame|Apophysis 1.0 parameters (*.apo;*.' + + 'fla)|*.apo;*.fla|All files (*.*)|*.*' + Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing] + Left = 416 + Top = 200 + end + object SaveDialog: TSaveDialog + DefaultExt = 'flame' + Filter = 'Flame files (*.flame)|*.flame' + Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing] + Left = 440 + Top = 128 + end + object Styler: TAdvPascalMemoStyler + BlockStart = 'begin,try,case,class,record' + BlockEnd = 'end' + LineComment = '//' + MultiCommentLeft = '{' + MultiCommentRight = '}' + CommentStyle.TextColor = clNavy + CommentStyle.BkColor = clWhite + CommentStyle.Style = [fsItalic] + NumberStyle.TextColor = clFuchsia + NumberStyle.BkColor = clWhite + NumberStyle.Style = [fsBold] + HighlightStyle.TextColor = clWhite + HighlightStyle.BkColor = clRed + HighlightStyle.Style = [fsBold] + AllStyles = < + item + KeyWords.Strings = ( + 'absolute' + 'abstract' + 'and' + 'array' + 'as' + 'asm' + 'assembler' + 'automated' + 'begin' + 'break' + 'case' + 'cdecl' + 'class' + 'class' + 'const' + 'constructor' + 'continue' + 'default' + 'deprecated' + 'destructor' + 'dispid' + 'dispinterface' + 'div' + 'do' + 'downto' + 'dynamic' + 'else' + 'end' + 'except' + 'exports' + 'external' + 'far' + 'file' + 'finalise' + 'finally' + 'for' + 'forward' + 'function' + 'if' + 'implementation' + 'in' + 'inherited' + 'initialise' + 'inline' + 'interface' + 'is' + 'label' + 'library' + 'message' + 'mod' + 'near' + 'nil' + 'not' + 'object' + 'of' + 'or' + 'out' + 'overload' + 'override' + 'packed' + 'pascal' + 'platform' + 'private' + 'procedure' + 'program' + 'program' + 'property' + 'protected' + 'public' + 'published' + 'raise' + 'record' + 'register' + 'reintroduce' + 'repeat' + 'resourcestring' + 'safecall' + 'set' + 'shl' + 'shr' + 'stdcall' + 'stored' + 'string' + 'then' + 'threadvar' + 'to' + 'try' + 'type' + 'unit' + 'until' + 'uses' + 'var' + 'virtual' + 'while' + 'with' + 'xor') + Font.Charset = DEFAULT_CHARSET + Font.Color = clGreen + Font.Height = -11 + Font.Name = 'Courier New' + Font.Style = [fsBold] + BGColor = clWhite + StyleType = stKeyword + BracketStart = #0 + BracketEnd = #0 + Info = 'Pascal Standard Default' + end + item + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Courier New' + Font.Style = [] + BGColor = clWhite + StyleType = stBracket + BracketStart = #39 + BracketEnd = #39 + Info = 'Simple Quote' + end + item + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'Courier New' + Font.Style = [] + BGColor = clWhite + StyleType = stBracket + BracketStart = '"' + BracketEnd = '"' + Info = 'Double Quote' + end + item + Font.Charset = DEFAULT_CHARSET + Font.Color = clRed + Font.Height = -11 + Font.Name = 'Courier New' + Font.Style = [] + BGColor = clWhite + StyleType = stSymbol + BracketStart = #0 + BracketEnd = #0 + Symbols = ' ,;:.(){}[]=+-*/^%<>#'#13#10 + Info = 'Symbols Delimiters' + end> + AutoCompletion.Strings = ( + 'ShowMessage' + 'MessageDlg') + HintParameter.TextColor = clBlack + HintParameter.BkColor = clInfoBk + HintParameter.HintCharStart = '(' + HintParameter.HintCharEnd = ')' + HintParameter.HintCharDelimiter = ';' + HintParameter.HintClassDelimiter = '.' + HintParameter.HintCharWriteDelimiter = ',' + HintParameter.Parameters.Strings = ( + 'ShowMessage(const Msg: string);' + + 'MessageDlg(const Msg: string; DlgType: TMsgDlgType; Buttons: TMs' + + 'gDlgButtons; HelpCtx: Longint): Integer);') + HexIdentifier = '$' + Description = 'Pascal' + Filter = 'Pascal Files (*.pas,*.dpr,*.dpk,*.inc)|*.pas;*.dpr;*.dpk;*.inc' + DefaultExtension = '.pas' + StylerName = 'Pascal' + Extensions = 'pas;dpr;dpk;inc' + RegionDefinitions = < + item + Identifier = 'procedure' + RegionStart = 'begin' + RegionEnd = 'end' + RegionType = rtClosed + ShowComments = False + end + item + Identifier = 'constructor' + RegionStart = 'begin' + RegionEnd = 'end' + RegionType = rtClosed + ShowComments = False + end + item + Identifier = 'destructor' + RegionStart = 'begin' + RegionEnd = 'end' + RegionType = rtClosed + ShowComments = False + end + item + Identifier = 'interface' + RegionStart = 'interface' + RegionType = rtOpen + ShowComments = False + end + item + Identifier = 'unit' + RegionStart = 'unit' + RegionType = rtFile + ShowComments = False + end + item + Identifier = 'implementation' + RegionStart = 'implementation' + RegionType = rtOpen + ShowComments = False + end + item + Identifier = 'case' + RegionStart = 'case' + RegionEnd = 'end' + RegionType = rtIgnore + ShowComments = False + end + item + Identifier = 'try' + RegionStart = 'try' + RegionEnd = 'end' + RegionType = rtIgnore + ShowComments = False + end + item + Identifier = 'function' + RegionStart = 'begin' + RegionEnd = 'end' + RegionType = rtClosed + ShowComments = False + end + item + Identifier = '{$region' + RegionStart = '{$region' + RegionEnd = '{$endregion' + RegionType = rtClosed + ShowComments = False + end> + Left = 288 + Top = 208 + end +end diff --git a/Forms/ScriptForm.pas b/Forms/ScriptForm.pas new file mode 100644 index 0000000..eaa301a --- /dev/null +++ b/Forms/ScriptForm.pas @@ -0,0 +1,4210 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit ScriptForm; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ExtCtrls, StdCtrls, ControlPoint, Buttons, ComCtrls, ToolWin, Menus, + XFormMan, XForm, GradientHlpr, cmap,LibXmlParser, LibXmlComps, Math, Translation, + atScript, atPascal, AdvMemo, Advmps; + +const + NCPS = 10; + + scriptFavsFilename = 'scripts7X.fav'; + +type + TOptions = class + public + end; + TFlame = class + public + { Byte sized properties, since + they're just place-holders } + Hue: double; + Time: byte; + Gamma: byte; + Brightness: byte; + Vibrancy: byte; + Zoom: byte; + SampleDensity: byte; + Oversample: byte; + FilterRadius: byte; + PixelsPerUnit: byte; + Width: byte; + Height: byte; + x: byte; + y: byte; + Gradient: byte; + Background: byte; + end; + TScriptRender = class + public + MaxMemory, Width, Height: integer; + Filename: string; + end; + TPivot = class + public + end; + TScriptEditor = class(TForm) + MainOpenDialog: TOpenDialog; + MainSaveDialog: TSaveDialog; + ToolBar: TToolBar; + btnOpen: TToolButton; + btnSave: TToolButton; + btnRun: TToolButton; + StatusBar: TStatusBar; + btnNew: TToolButton; + PopupMenu: TPopupMenu; + mnuCut: TMenuItem; + mnuCopy: TMenuItem; + mnuPaste: TMenuItem; + mnuUndo: TMenuItem; + N1: TMenuItem; + BackPanel: TPanel; + Editor: TAdvMemo; + Scripter: TatPascalScripter; + Splitter1: TSplitter; + Console: TMemo; + btnStop: TToolButton; + btnBreak: TToolButton; + OpenDialog: TOpenDialog; + SaveDialog: TSaveDialog; + Styler: TAdvPascalMemoStyler; + procedure F2SXMLStartTag(Sender: TObject; TagName: string; + Attributes: TAttrList); + procedure F2SXMLEndTag(Sender: TObject; TagName: string); + procedure F2SXMLEmptyTag(Sender: TObject; TagName: string; + Attributes: TAttrList); + procedure F2SXMLContent(Sender: TObject; Content: string); + procedure FormShortCut(var Msg: TWMKey; var Handled: Boolean); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure btnOpenClick(Sender: TObject); + procedure btnSaveClick(Sender: TObject); + procedure btnRunClick(Sender: TObject); + procedure btnNewClick(Sender: TObject); + procedure mnuCutClick(Sender: TObject); + procedure mnuCopyClick(Sender: TObject); + procedure mnuPasteClick(Sender: TObject); + procedure mnuUndoClick(Sender: TObject); + procedure EditorChange(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure ScripterCompileError(Sender: TObject; var msg: string; row, + col: Integer; var ShowException: Boolean); + procedure btnStopClick(Sender: TObject); + procedure btnBreakClick(Sender: TObject); + procedure btnFavoriteClick(Sender: TObject); + public + cp: TControlPoint; + Stopped: boolean; + cmap: TColorMap; + Flame: TFlame; + Options: TOptions; + Pivot: TPivot; + Renderer: TScriptRender; + Another: TScriptRender; + AddedXForms : integer; + chaosLines : TStringList; + procedure LoadRunAndClear(scriptFile:string); + procedure LoadScriptFile(filename:string); + procedure ScriptFromFlame(flameXML:string); + procedure UpdateFlame; + procedure PrepareScripter; + procedure OpenScript; + procedure RunScript; + { Flame interface } + procedure SetFlameNameProc(AMachine: TatVirtualMachine); + procedure GetFlameNameProc(AMachine: TatVirtualMachine); + procedure SetFlameHueProc(AMachine: TatVirtualMachine); + procedure GetFlameHueProc(AMachine: TatVirtualMachine); + procedure GetFlameGammaProc(AMachine: TatVirtualMachine); + procedure SetFlameGammaProc(AMachine: TatVirtualMachine); + procedure GetFlameGammaTresholdProc(AMachine: TatVirtualMachine); + procedure SetFlameGammaTresholdProc(AMachine: TatVirtualMachine); + procedure GetFlameBrightnessProc(AMachine: TatVirtualMachine); + procedure SetFlameBrightnessProc(AMachine: TatVirtualMachine); + procedure GetFlameVibrancyProc(AMachine: TatVirtualMachine); + procedure SetFlameVibrancyProc(AMachine: TatVirtualMachine); + procedure GetFlameTimeProc(AMachine: TatVirtualMachine); + procedure SetFlameTimeProc(AMachine: TatVirtualMachine); + procedure GetFlameDensityProc(AMachine: TatVirtualMachine); + procedure SetFlameDensityProc(AMachine: TatVirtualMachine); + procedure GetFlameOversampleProc(AMachine: TatVirtualMachine); + procedure SetFlameOversampleProc(AMachine: TatVirtualMachine); + procedure GetFlameFilterRadiusProc(AMachine: TatVirtualMachine); + procedure SetFlameFilterRadiusProc(AMachine: TatVirtualMachine); + procedure GetFlameWidthProc(AMachine: TatVirtualMachine); + procedure SetFlameWidthProc(AMachine: TatVirtualMachine); + procedure GetFlameHeightProc(AMachine: TatVirtualMachine); + procedure SetFlameHeightProc(AMachine: TatVirtualMachine); + procedure GetFlameZoomProc(AMachine: TatVirtualMachine); + procedure SetFlameZoomProc(AMachine: TatVirtualMachine); + procedure GetFlameXProc(AMachine: TatVirtualMachine); + procedure SetFlameXProc(AMachine: TatVirtualMachine); + procedure GetFlameYProc(AMachine: TatVirtualMachine); + procedure SetFlameYProc(AMachine: TatVirtualMachine); + procedure GetFlamePixelsPerUnitProc(AMachine: TatVirtualMachine); + procedure SetFlamePixelsPerUnitProc(AMachine: TatVirtualMachine); + procedure GetFlamePaletteProc(AMachine: TatVirtualMachine); + procedure SetFlamePaletteProc(AMachine: TatVirtualMachine); + procedure GetFlameBackgroundProc(AMachine: TatVirtualMachine); + procedure SetFlameBackgroundProc(AMachine: TatVirtualMachine); + procedure SetFlameNickProc(AMachine: TatVirtualMachine); + procedure GetFlameNickProc(AMachine: TatVirtualMachine); + procedure SetFlameURLProc(AMachine: TatVirtualMachine); + procedure GetFlameURLProc(AMachine: TatVirtualMachine); + procedure SetFlameBatchesProc(AMachine: TatVirtualMachine); + procedure GetFlameBatchesProc(AMachine: TatVirtualMachine); + procedure GetFlameFinalxformEnabledProc(AMachine: TatVirtualMachine); + procedure SetFlameFinalxformEnabledProc(AMachine: TatVirtualMachine); + procedure GetFlameSoloXformProc(AMachine: TatVirtualMachine); + procedure SetFlameSoloXformProc(AMachine: TatVirtualMachine); + procedure GetFlameAngleProc(AMachine: TatVirtualMachine); + procedure SetFlameAngleProc(AMachine: TatVirtualMachine); + procedure GetFlamePitchProc(AMachine: TatVirtualMachine); + procedure SetFlamePitchProc(AMachine: TatVirtualMachine); + procedure GetFlameYawProc(AMachine: TatVirtualMachine); + procedure SetFlameYawProc(AMachine: TatVirtualMachine); + procedure GetFlameCamZposProc(AMachine: TatVirtualMachine); + procedure SetFlameCamZposProc(AMachine: TatVirtualMachine); + procedure GetFlamePerspectiveProc(AMachine: TatVirtualMachine); + procedure SetFlamePerspectiveProc(AMachine: TatVirtualMachine); + procedure GetFlameDOFProc(AMachine: TatVirtualMachine); + procedure SetFlameDOFProc(AMachine: TatVirtualMachine); + + { Transform interface } + procedure GetTransformAProc(AMachine: TatVirtualMachine); + procedure SetTransformAProc(AMachine: TatVirtualMachine); + procedure GetTransformBProc(AMachine: TatVirtualMachine); + procedure SetTransformBProc(AMachine: TatVirtualMachine); + procedure GetTransformCProc(AMachine: TatVirtualMachine); + procedure SetTransformCProc(AMachine: TatVirtualMachine); + procedure GetTransformDProc(AMachine: TatVirtualMachine); + procedure SetTransformDProc(AMachine: TatVirtualMachine); + procedure GetTransformEProc(AMachine: TatVirtualMachine); + procedure SetTransformEProc(AMachine: TatVirtualMachine); + procedure GetTransformFProc(AMachine: TatVirtualMachine); + procedure SetTransformFProc(AMachine: TatVirtualMachine); + procedure GetTransformVarProc(AMachine: TatVirtualMachine); + procedure SetTransformVarProc(AMachine: TatVirtualMachine); + procedure GetTransformVariProc(AMachine: TatVirtualMachine); + procedure SetTransformVariProc(AMachine: TatVirtualMachine); + + procedure GetTransformChaosProc(AMachine: TatVirtualMachine); + procedure SetTransformChaosProc(AMachine: TatVirtualMachine); + procedure GetTransformPlotModeProc(AMachine: TatVirtualMachine); + procedure SetTransformPlotModeProc(AMachine: TatVirtualMachine); + procedure GetTransformOpacityProc(AMachine: TatVirtualMachine); + procedure SetTransformOpacityProc(AMachine: TatVirtualMachine); + + procedure GetTransformColorProc(AMachine: TatVirtualMachine); + procedure SetTransformColorProc(AMachine: TatVirtualMachine); + procedure GetTransformVarColorProc(AMachine: TatVirtualMachine); + procedure SetTransformVarColorProc(AMachine: TatVirtualMachine); + procedure GetTransformWeightProc(AMachine: TatVirtualMachine); + procedure SetTransformWeightProc(AMachine: TatVirtualMachine); + procedure GetTransformSymProc(AMachine: TatVirtualMachine); + procedure SetTransformSymProc(AMachine: TatVirtualMachine); + + procedure GetTransformVariationProc(AMachine: TatVirtualMachine); + procedure SetTransformVariationProc(AMachine: TatVirtualMachine); + procedure GetTransformVariableProc(AMachine: TatVirtualMachine); + procedure SetTransformVariableProc(AMachine: TatVirtualMachine); + + procedure GetTransformCoefsProc(AMachine: TatVirtualMachine); + procedure SetTransformCoefsProc(AMachine: TatVirtualMachine); + procedure GetTransformPostCoefsProc(AMachine: TatVirtualMachine); + procedure SetTransformPostCoefsProc(AMachine: TatVirtualMachine); + + procedure TransformClearProc(AMachine: TatVirtualMachine); + procedure TransformRotateProc(AMachine: TatVirtualMachine); + procedure TransformScaleProc(AMachine: TatVirtualMachine); + procedure TransformRotateOriginProc(AMachine: TatVirtualMachine); + + { Render interface } + procedure GetRenderFilenameProc(AMachine: TatVirtualMachine); + procedure SetRenderFilenameProc(AMachine: TatVirtualMachine); + procedure GetRenderWidthProc(AMachine: TatVirtualMachine); + procedure SetRenderWidthProc(AMachine: TatVirtualMachine); + procedure GetRenderHeightProc(AMachine: TatVirtualMachine); + procedure SetRenderHeightProc(AMachine: TatVirtualMachine); + procedure GetRenderMaxMemoryProc(AMachine: TatVirtualMachine); + procedure SetRenderMaxMemoryProc(AMachine: TatVirtualMachine); + procedure FillFileList; + + { Options interface } + procedure GetJPEGQuality(AMachine: TatVirtualMachine); + procedure SetJPEGQuality(AMachine: TatVirtualMachine); + procedure GetBatchSize(AMachine: TatVirtualMachine); + procedure SetBatchSize(AMachine: TatVirtualMachine); + procedure GetParameterFile(AMachine: TatVirtualMachine); + procedure SetParameterFile(AMachine: TatVirtualMachine); + procedure GetSmoothPaletteFile(AMachine: TatVirtualMachine); + procedure SetSmoothPaletteFile(AMachine: TatVirtualMachine); + procedure GetNumTries(AMachine: TatVirtualMachine); + procedure SetNumTries(AMachine: TatVirtualMachine); + procedure GetTryLength(AMachine: TatVirtualMachine); + procedure SetTryLength(AMachine: TatVirtualMachine); + procedure GetConfirmDelete(AMachine: TatVirtualMachine); + procedure SetConfirmDelete(AMachine: TatVirtualMachine); + procedure GetFixedReference(AMachine: TatVirtualMachine); + procedure SetFixedReference(AMachine: TatVirtualMachine); + procedure GetSampleDensity(AMachine: TatVirtualMachine); + procedure SetSampleDensity(AMachine: TatVirtualMachine); + procedure GetGamma(AMachine: TatVirtualMachine); + procedure SetGamma(AMachine: TatVirtualMachine); + procedure GetBrightness(AMachine: TatVirtualMachine); + procedure SetBrightness(AMachine: TatVirtualMachine); + procedure GetVibrancy(AMachine: TatVirtualMachine); + procedure SetVibrancy(AMachine: TatVirtualMachine); + procedure GetOversample(AMachine: TatVirtualMachine); + procedure SetOversample(AMachine: TatVirtualMachine); + procedure GetFilterRadius(AMachine: TatVirtualMachine); + procedure SetFilterRadius(AMachine: TatVirtualMachine); + procedure GetTransparency(AMachine: TatVirtualMachine); + procedure SetTransparency(AMachine: TatVirtualMachine); + procedure GetLowQuality(AMachine: TatVirtualMachine); + procedure SetLowQuality(AMachine: TatVirtualMachine); + procedure GetMediumQuality(AMachine: TatVirtualMachine); + procedure SetMediumQuality(AMachine: TatVirtualMachine); + procedure GetHighQuality(AMachine: TatVirtualMachine); + procedure SetHighQuality(AMachine: TatVirtualMachine); + procedure GetMinTransforms(AMachine: TatVirtualMachine); + procedure SetMinTransforms(AMachine: TatVirtualMachine); + procedure GetMaxTransforms(AMachine: TatVirtualMachine); + procedure SetMaxTransforms(AMachine: TatVirtualMachine); + procedure GetMutateMinTransforms(AMachine: TatVirtualMachine); + procedure SetMutateMinTransforms(AMachine: TatVirtualMachine); + procedure GetMutateMaxTransforms(AMachine: TatVirtualMachine); + procedure SetMutateMaxTransforms(AMachine: TatVirtualMachine); + procedure GetPrefix(AMachine: TatVirtualMachine); + procedure SetPrefix(AMachine: TatVirtualMachine); + procedure GetKeepBackground(AMachine: TatVirtualMachine); + procedure SetKeepBackground(AMachine: TatVirtualMachine); + procedure GetSymmetryType(AMachine: TatVirtualMachine); + procedure SetSymmetryType(AMachine: TatVirtualMachine); + procedure GetSymmetryOrder(AMachine: TatVirtualMachine); + procedure SetSymmetryOrder(AMachine: TatVirtualMachine); + procedure GetVariations(AMachine: TatVirtualMachine); + procedure SetVariations(AMachine: TatVirtualMachine); + procedure GetRandomGradient(AMachine: TatVirtualMachine); + procedure SetRandomGradient(AMachine: TatVirtualMachine); + procedure GetMinNodes(AMachine: TatVirtualMachine); + procedure SetMinNodes(AMachine: TatVirtualMachine); + procedure GetMaxNodes(AMachine: TatVirtualMachine); + procedure SetMaxNodes(AMachine: TatVirtualMachine); + procedure GetMinHue(AMachine: TatVirtualMachine); + procedure SetMinHue(AMachine: TatVirtualMachine); + procedure GetMaxHue(AMachine: TatVirtualMachine); + procedure SetMaxHue(AMachine: TatVirtualMachine); + procedure GetMinSat(AMachine: TatVirtualMachine); + procedure SetMinSat(AMachine: TatVirtualMachine); + procedure GetMaxSat(AMachine: TatVirtualMachine); + procedure SetMaxSat(AMachine: TatVirtualMachine); + procedure GetMinLum(AMachine: TatVirtualMachine); + procedure SetMinLum(AMachine: TatVirtualMachine); + procedure GetMaxLum(AMachine: TatVirtualMachine); + procedure SetMaxLum(AMachine: TatVirtualMachine); + procedure GetUPRSampleDensity(AMachine: TatVirtualMachine); + procedure SetUPRSampleDensity(AMachine: TatVirtualMachine); + procedure GetUPROversample(AMachine: TatVirtualMachine); + procedure SetUPROversample(AMachine: TatVirtualMachine); + procedure GetUPRFilterRadius(AMachine: TatVirtualMachine); + procedure SetUPRFilterRadius(AMachine: TatVirtualMachine); + procedure GetUPRColoringIdent(AMachine: TatVirtualMachine); + procedure SetUPRColoringIdent(AMachine: TatVirtualMachine); + procedure GetUPRColoringFile(AMachine: TatVirtualMachine); + procedure SetUPRColoringFile(AMachine: TatVirtualMachine); + procedure GetUPRFormulaIdent(AMachine: TatVirtualMachine); + procedure SetUPRFormulaIdent(AMachine: TatVirtualMachine); + procedure GetUPRFormulaFile(AMachine: TatVirtualMachine); + procedure SetUPRFormulaFile(AMachine: TatVirtualMachine); + procedure GetUPRAdjustDensity(AMachine: TatVirtualMachine); + procedure SetUPRAdjustDensity(AMachine: TatVirtualMachine); + procedure GetUPRWidth(AMachine: TatVirtualMachine); + procedure SetUPRWidth(AMachine: TatVirtualMachine); + procedure GetUPRHeight(AMachine: TatVirtualMachine); + procedure SetUPRHeight(AMachine: TatVirtualMachine); + procedure GetExportPath(AMachine: TatVirtualMachine); + procedure SetExportPath(AMachine: TatVirtualMachine); + + { Pivot interface } + procedure GetPivotModeProc(AMachine: TatVirtualMachine); + procedure SetPivotModeProc(AMachine: TatVirtualMachine); + procedure GetPivotXProc(AMachine: TatVirtualMachine); + procedure SetPivotXProc(AMachine: TatVirtualMachine); + procedure GetPivotYProc(AMachine: TatVirtualMachine); + procedure SetPivotYProc(AMachine: TatVirtualMachine); + procedure SetPivotProc(AMachine: TatVirtualMachine); + procedure ResetPivotProc(AMachine: TatVirtualMachine); + + end; + TTransform = class + public + { Transform class only serves as an + interface to active transform } + a: byte; + b: byte; + c: byte; + d: byte; + e: byte; + f: byte; + Color: byte; + Weight: byte; + Variation: byte; + VarColor: byte; + end; + + TMatrix = array[0..2, 0..2] of double; + +var + ScriptEditor: TScriptEditor; + LastParseError: string; + NumTransforms: integer; // Keeps track of number of xforms in flame. + ActiveTransform: integer; // Operations affect this transform. + LastError: string; + color: double; + cps: array[0..NCPS - 1] of TControlPoint; + Transform: TTransform; + Stopped, ResetLocation, UpdateIt: Boolean; + ParamFile: string; + FileList: TStringList; + +function Mul33(M1, M2: TMatrix): TMatrix; +//procedure Normalize(var cp: TControlPoint); + +implementation + +{ +[00 01 02] +[10 11 12] +[20 21 22] + +[a b e ] +[c d f ] +[0 0 1 ] +} + +uses Main, Editor, Adjust, Global, Mutate, Registry, Preview, + ScriptRender, ap_math, ap_classes, ap_sysutils, ap_Dialogs, + SavePreset, ap_windows, ap_FileCtrl(*, bmdll32*); + +{$R *.DFM} + +const + ErrorOutOfRange = 'Transform out of range!'; + +type +{ Library for math functions } + TMathLibrary = class(TatScripterLibrary) + protected + procedure CosProc(AMachine: TatVirtualMachine); + procedure SinProc(AMachine: TatVirtualMachine); + procedure Init; override; + end; + + TOperationLibrary = class(TatScripterLibrary) + protected + procedure RotateFlameProc(AMachine: TatVirtualMachine); + procedure RotateReferenceProc(AMachine: TatVirtualMachine); + procedure RotateProc(AMachine: TatVirtualMachine); + procedure ScaleProc(AMachine: TatVirtualMachine); + procedure MulProc(AMachine: TatVirtualMachine); + procedure TranslateProc(AMachine: TatVirtualMachine); + procedure GetActiveTransformProc(AMachine: TatVirtualMachine); + procedure SetActiveTransformProc(AMachine: TatVirtualMachine); + procedure TransformsProc(AMachine: TatVirtualMachine); + procedure FileCountProc(AMachine: TatVirtualMachine); + procedure AddTransformProc(AMachine: TatVirtualMachine); + procedure DeleteTransformProc(AMachine: TatVirtualMachine); + procedure CopyTransformProc(AMachine: TatVirtualMachine); + procedure ClearProc(AMachine: TatVirtualMachine); + procedure PreviewProc(AMachine: TatVirtualMachine); + procedure Print(AMachine: TatVirtualMachine); + procedure MorphProc(AMachine: TatVirtualMachine); + procedure RenderProc(AMachine: TatVirtualMachine); + procedure AddSymmetryProc(AMachine: TatVirtualMachine); + procedure StoreFlameProc(AMachine: TatVirtualMachine); + procedure GetFlameProc(AMachine: TatVirtualMachine); + procedure LoadFlameProc(AMachine: TatVirtualMachine); + procedure SetRenderBounds(AMachine: TatVirtualMachine); + procedure GetFileName(AMachine: TatVirtualMachine); + procedure ListFileProc(AMachine: TatVirtualMachine); + procedure SetParamFileProc(AMachine: TatVirtualMachine); + procedure SaveFlameProc(AMachine: TatVirtualMachine); + procedure ShowStatusProc(AMachine: TatVirtualMachine); + procedure RandomFlame(AMachine: TatVirtualMachine); + procedure RandomGradientProc(AMachine: TatVirtualMachine); + procedure SaveGradientProc(AMachine: TatVirtualMachine); + procedure GetVariation(AMachine: TatVirtualMachine); + procedure SetVariation(AMachine: TatVirtualMachine); + + procedure VariationIndexProc(AMachine: TatVirtualMachine); + procedure VariationNameProc(AMachine: TatVirtualMachine); + procedure VariableIndexProc(AMachine: TatVirtualMachine); + procedure VariableNameProc(AMachine: TatVirtualMachine); + + procedure CalculateScale(AMachine: TatVirtualMachine); + procedure NormalizeVars(AMachine: TatVirtualMachine); + procedure CalculateBounds(AMachine: TatVirtualMachine); + procedure GetSaveFileName(AMachine: TatVirtualMachine); + procedure CopyFileProc(AMachine: TatVirtualMachine); + // procedure BM_OpenProc(AMachine: TatVirtualMachine); + // procedure BM_DllCFuncProc(AMachine: TatVirtualMachine); + procedure Init; override; + end; + +procedure TScriptEditor.ScriptFromFlame(flameXML:string); +var i : integer; xml : TXmlScanner; +begin + // Clear & Set caption to "New Script" + btnNewClick(btnNew); + + chaosLines := TStringList.Create; + xml := TXmlScanner.Create(nil); + xml.Normalize := True; + xml.OnContent := F2SXMLContent; + xml.OnEmptyTag := F2SXMLEmptyTag; + xml.OnEndTag := F2SXMLEndTag; + xml.OnStartTag := F2SXMLStartTag; + xml.LoadFromBuffer(PANSICHAR(AnsiString(flameXML))); + xml.Execute; + xml.Destroy; + + // use chaosLines... + for i := 0 to chaosLines.Count - 1 do + Editor.Lines.Add(chaosLines.Strings[i]); + chaosLines.Destroy; +end; +{ ************************ Options interface ********************************* } + +procedure TScriptEditor.GetJPEGQuality(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(JPEGQuality); +end; + +procedure TScriptEditor.SetJPEGQuality(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v > 0) and (v <= 100) then JPEGQuality := v; + end; +end; + +procedure TScriptEditor.GetBatchSize(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(BatchSize); +end; + +procedure TScriptEditor.SetBatchSize(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 10) and (v <= 100) then BatchSize := v; + end; +end; + +procedure TScriptEditor.GetParameterFile(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defFlameFile); +end; + +procedure TScriptEditor.SetParameterFile(AMachine: TatVirtualMachine); +begin + with AMachine do + defFlameFile := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetSmoothPaletteFile(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defSmoothPaletteFile); +end; + +procedure TScriptEditor.SetSmoothPaletteFile(AMachine: TatVirtualMachine); +begin + with AMachine do + defSmoothPaletteFile := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetNumTries(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(NumTries); +end; + +procedure TScriptEditor.SetNumTries(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v > 0) and (v <= 100) then NumTries := v; + end; +end; + +procedure TScriptEditor.GetTryLength(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(TryLength); +end; + +procedure TScriptEditor.SetTryLength(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 100) and (v <= 1000000) then TryLength := v; + end; +end; + +procedure TScriptEditor.GetConfirmDelete(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(ConfirmDelete); +end; + +procedure TScriptEditor.SetConfirmDelete(AMachine: TatVirtualMachine); +begin + with AMachine do + ConfirmDelete := GetInputArgAsBoolean(0); +end; + +procedure TScriptEditor.GetFixedReference(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(true); //ReferenceMode = 0); +end; + +procedure TScriptEditor.SetFixedReference(AMachine: TatVirtualMachine); +begin +// with AMachine do +// if GetInputArgAsBoolean(0) then ReferenceMode := 0 +// else ReferenceMode := 1; +end; + +procedure TScriptEditor.GetSampleDensity(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defSampleDensity); +end; + +procedure TScriptEditor.SetSampleDensity(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0.1) and (v <= 100) then defSampleDensity := v; + end; +end; + +procedure TScriptEditor.GetGamma(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defGamma); +end; + +procedure TScriptEditor.SetGamma(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0.1) and (v <= 100) then defGamma := v; + end; +end; + +procedure TScriptEditor.GetBrightness(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defBrightness); +end; + +procedure TScriptEditor.SetBrightness(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0.1) and (v <= 100) then defBrightness := v; + end; +end; + +procedure TScriptEditor.GetVibrancy(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defVibrancy); +end; + +procedure TScriptEditor.SetVibrancy(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0) and (v <= 100) then defVibrancy := v; + end; +end; + +procedure TScriptEditor.GetOversample(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defOversample); +end; + +procedure TScriptEditor.SetOversample(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 1) and (v <= 4) then defOversample := v; + end; +end; + +procedure TScriptEditor.GetFilterRadius(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(defFilterRadius); +end; + +procedure TScriptEditor.SetFilterRadius(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0.1) then defFilterRadius := v; + end; +end; + +procedure TScriptEditor.GetTransparency(AMachine: TatVirtualMachine); +begin + AMachine.ReturnOutPutArg(PNGTransparency); +end; + +procedure TScriptEditor.SetTransparency(AMachine: TatVirtualMachine); +var + v: double; +begin + if AMachine.GetInputArgAsInteger(0) = 0 then + PNGTransparency := 0 + else + PNGTransparency := 1; +end; + +procedure TScriptEditor.GetLowQuality(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(prevLowQuality); +end; + +procedure TScriptEditor.SetLowQuality(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0.01) and (v <= 100) then prevLowQuality := v; + end; +end; + +procedure TScriptEditor.GetMediumQuality(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(prevMediumQuality); +end; + +procedure TScriptEditor.SetMediumQuality(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0.01) and (v <= 100) then prevMediumQuality := v; + end; +end; + +procedure TScriptEditor.GetHighQuality(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(prevHighQuality); +end; + +procedure TScriptEditor.SetHighQuality(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0.01) and (v <= 100) then prevHighQuality := v; + end; +end; + +procedure TScriptEditor.GetMinTransforms(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(randMinTransforms); +end; + +procedure TScriptEditor.SetMinTransforms(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 2) and (v <= NXFORMS) and (v <= randMaxTransforms) then randMinTransforms := v; + end; +end; + +procedure TScriptEditor.GetMaxTransforms(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(randMaxTransforms); +end; + +procedure TScriptEditor.SetMaxTransforms(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 2) and (v <= NXFORMS) and (v >= randMinTransforms) then randMaxTransforms := v; + end; +end; + +procedure TScriptEditor.GetMutateMinTransforms(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(mutantMinTransforms); +end; + +procedure TScriptEditor.SetMutateMinTransforms(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 2) and (v <= NXFORMS) and (v <= mutantMaxTransforms) then mutantMinTransforms := v; + end; +end; + +procedure TScriptEditor.GetMutateMaxTransforms(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(mutantMaxTransforms); +end; + +procedure TScriptEditor.SetMutateMaxTransforms(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 2) and (v <= NXFORMS) and (v >= mutantMinTransforms) then mutantMaxTransforms := v; + end; +end; + +procedure TScriptEditor.GetPrefix(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(RandomPrefix); +end; + +procedure TScriptEditor.SetPrefix(AMachine: TatVirtualMachine); +begin + with AMachine do + RandomPrefix := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetKeepBackground(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(KeepBackground); +end; + +procedure TScriptEditor.SetKeepBackground(AMachine: TatVirtualMachine); +begin + with AMachine do + KeepBackground := GetInputArgAsBoolean(0); +end; + +procedure TScriptEditor.GetSymmetryType(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(SymmetryType); +end; + +procedure TScriptEditor.SetSymmetryType(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 3) then SymmetryType := v; + end; +end; + +procedure TScriptEditor.GetSymmetryOrder(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(SymmetryOrder); +end; + +procedure TScriptEditor.SetSymmetryOrder(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 2) and (v <= 2000) then SymmetryOrder := v; + end; +end; + +procedure TScriptEditor.GetVariations(AMachine: TatVirtualMachine); +var + I: Integer; +begin + with AMachine do + begin + i := GetArrayIndex(0); + if (i >= 0) and (i < NRVAR) then + ReturnOutPutArg(Variations[i]); + end; +end; + +procedure TScriptEditor.SetVariations(AMachine: TatVirtualMachine); +var + v: boolean; + i, vars: integer; +begin + with AMachine do + begin + v := GetInputArgAsBoolean(0); + i := GetArrayIndex(0); + if (i >= 0) and (i < NRVAR) then + begin + Variations[i] := v; +{ + vars := PackVariations; + if vars <> 0 then + VariationOptions := vars + else + VariationOptions := 1; +} + end; + + end; +end; + +procedure TScriptEditor.GetRandomGradient(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(randGradient); +end; + +procedure TScriptEditor.SetRandomGradient(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 3) then randGradient := v; + end; +end; + +procedure TScriptEditor.GetMinNodes(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MinNodes); +end; + +procedure TScriptEditor.SetMinNodes(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 2) and (v <= 64) and (v <= MaxNodes) then MinNodes := v; + end; +end; + +procedure TScriptEditor.GetMaxNodes(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MaxNodes); +end; + +procedure TScriptEditor.SetMaxNodes(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 2) and (v <= 64) and (v >= MinNodes) then MaxNodes := v; + end; +end; + +procedure TScriptEditor.GetMinHue(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MinHue); +end; + +procedure TScriptEditor.SetMinHue(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 600) and (v <= MaxHue) then MinHue := v; + end; +end; + +procedure TScriptEditor.GetMaxHue(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MaxHue); +end; + +procedure TScriptEditor.SetMaxHue(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 600) and (v >= MinHue) then MaxHue := v; + end; +end; + + +procedure TScriptEditor.GetMinSat(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MinSat); +end; + +procedure TScriptEditor.SetMinSat(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 100) and (v <= MaxSat) then MinSat := v; + end; +end; + +procedure TScriptEditor.GetMaxSat(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MaxSat); +end; + +procedure TScriptEditor.SetMaxSat(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 100) and (v >= MinSat) then MaxSat := v; + end; +end; + +procedure TScriptEditor.GetMinLum(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MinLum); +end; + +procedure TScriptEditor.SetMinLum(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 100) and (v <= MaxLum) then MinLum := v; + end; +end; + +procedure TScriptEditor.GetMaxLum(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(MaxLum); +end; + +procedure TScriptEditor.SetMaxLum(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) and (v <= 100) and (v >= MinLum) then MaxLum := v; + end; +end; + +procedure TScriptEditor.GetUPRSampleDensity(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRSampleDensity); +end; + +procedure TScriptEditor.SetUPRSampleDensity(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v > 0) then UPRSampleDensity := v; + end; +end; + +procedure TScriptEditor.GetUPROversample(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPROversample); +end; + +procedure TScriptEditor.SetUPROversample(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v > 0) then UPROversample := v; + end; +end; + +procedure TScriptEditor.GetUPRFilterRadius(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRFilterRadius); +end; + +procedure TScriptEditor.SetUPRFilterRadius(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v > 0) then UPRFilterRadius := v; + end; +end; + +procedure TScriptEditor.GetUPRColoringIdent(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRColoringIdent); +end; + +procedure TScriptEditor.SetUPRColoringIdent(AMachine: TatVirtualMachine); +begin + with AMachine do + UPRColoringIdent := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetUPRColoringFile(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRColoringFile); +end; + +procedure TScriptEditor.SetUPRColoringFile(AMachine: TatVirtualMachine); +begin + with AMachine do + UPRColoringFile := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetUPRFormulaFile(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRFormulaFile); +end; + +procedure TScriptEditor.SetUPRFormulaFile(AMachine: TatVirtualMachine); +begin + with AMachine do + UPRFormulaFile := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetUPRFormulaIdent(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRFormulaIdent); +end; + +procedure TScriptEditor.SetUPRFormulaIdent(AMachine: TatVirtualMachine); +begin + with AMachine do + UPRFormulaIdent := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetUPRAdjustDensity(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRAdjustDensity); +end; + +procedure TScriptEditor.SetUPRAdjustDensity(AMachine: TatVirtualMachine); +begin + with AMachine do + UPRAdjustDensity := GetInputArgAsBoolean(0); +end; + +procedure TScriptEditor.GetUPRWidth(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRWidth); +end; + +procedure TScriptEditor.SetUPRWidth(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v > 0) then UPRWidth := v; + end; +end; + +procedure TScriptEditor.GetUPRHeight(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(UPRHeight); +end; + +procedure TScriptEditor.SetUPRHeight(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v > 0) then UPRHeight := v; + end; +end; + +procedure TScriptEditor.GetExportPath(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(flam3Path); +end; + +procedure TScriptEditor.SetExportPath(AMachine: TatVirtualMachine); +begin + with AMachine do + flam3Path := GetInputArgAsString(0); +end; + +{ ***************************** Operation Library **************************** } + +procedure TOperationLibrary.Init; +begin + Scripter.DefineMethod('RotateFlame', 1, tkNone, nil, RotateFlameProc); + Scripter.DefineMethod('RotateReference', 1, tkNone, nil, RotateReferenceProc); + Scripter.DefineMethod('Rotate', 1, tkNone, nil, RotateProc); + Scripter.DefineMethod('Multiply', 4, tkNone, nil, MulProc); + Scripter.DefineMethod('StoreFlame', 1, tkNone, nil, StoreFlameProc); + Scripter.DefineMethod('GetFlame', 1, tkNone, nil, GetFlameProc); + Scripter.DefineMethod('LoadFlame', 1, tkNone, nil, LoadFlameProc); + Scripter.DefineMethod('Scale', 1, tkNone, nil, ScaleProc); + Scripter.DefineMethod('Translate', 2, tkNone, nil, TranslateProc); +// Scripter.DefineMethod('ActiveTransform', 0, tkInteger, nil, GetActiveTransformProc); + Scripter.DefineProp('ActiveTransform', tkInteger, GetActiveTransformProc, SetActiveTransformProc); + Scripter.DefineMethod('SetActiveTransform', 1, tkInteger, nil, SetActiveTransformProc); + Scripter.DefineMethod('Transforms', 0, tkInteger, nil, TransformsProc); + Scripter.DefineMethod('FileCount', 0, tkInteger, nil, FileCountProc); + Scripter.DefineMethod('AddTransform', 0, tkNone, nil, AddTransformProc); + Scripter.DefineMethod('DeleteTransform', 0, tkNone, nil, DeleteTransformProc); + Scripter.DefineMethod('CopyTransform', 0, tkNone, nil, CopyTransformProc); + Scripter.DefineMethod('Clear', 0, tkNone, nil, ClearProc); + Scripter.DefineMethod('Preview', 0, tkNone, nil, PreviewProc); + Scripter.DefineMethod('Render', 0, tkNone, nil, RenderProc); + Scripter.DefineMethod('Print', 1, tkNone, nil, Print); + Scripter.DefineMethod('AddSymmetry', 1, tkNone, nil, AddSymmetryProc); + Scripter.DefineMethod('Morph', 3, tkNone, nil, MorphProc); + Scripter.DefineMethod('SetRenderBounds', 0, tkNone, nil, SetRenderBounds); + Scripter.DefineMethod('SetFlameFile', 1, tkNone, nil, SetParamFileProc); + Scripter.DefineMethod('ListFile', 1, tkNone, nil, ListFileProc); + Scripter.DefineMethod('SaveFlame', 1, tkNone, nil, SaveFlameProc); + Scripter.DefineMethod('GetFileName', 0, tkString, nil, GetFileName); + Scripter.DefineMethod('ShowStatus', 1, tkNone, nil, ShowStatusProc); + Scripter.DefineMethod('RandomFlame', 1, tkNone, nil, RandomFlame); + Scripter.DefineMethod('RandomGradient', 0, tkNone, nil, RandomGradientProc); + Scripter.DefineMethod('SaveGradient', 2, tkNone, nil, SaveGradientProc); + Scripter.DefineMethod('Variation', 0, tkInteger, nil, GetVariation); + Scripter.DefineMethod('SetVariation', 1, tkInteger, nil, SetVariation); + + Scripter.AddConstant('ProgramVersionString', AppVersionString); + Scripter.DefineMethod('VariationIndex', 1, tkInteger, nil, VariationIndexProc); + Scripter.DefineMethod('VariationName', 1, tkString, nil, VariationNameProc); + Scripter.DefineMethod('VariableIndex', 1, tkInteger, nil, VariableIndexProc); + Scripter.DefineMethod('VariableName', 1, tkString, nil, VariableNameProc); + + Scripter.DefineMethod('CalculateScale', 0, tkNone, nil, CalculateScale); + Scripter.DefineMethod('CalculateBounds', 0, tkNone, nil, CalculateBounds); + Scripter.DefineMethod('NormalizeVars', 0, tkNone, nil, NormalizeVars); + Scripter.DefineMethod('GetSaveFileName', 0, tkString, nil, GetSaveFileName); + Scripter.DefineMethod('CopyFile', 2, tkString, nil, CopyFileProc); + + //Scripter.DefineMethod('StrToFloat', 1, tkFloat, nil, StrToFloatProc); + + //Scripter.DefineMethod('BM_Open', 1, tkInteger, nil, BM_OpenProc); + //Scripter.DefineMethod('BM_DllCFunc', 2, tkInteger, nil, BM_DllCFuncProc); +end; + +procedure TOperationLibrary.RandomFlame(AMachine: TatVirtualMachine); +var + i: integer; +begin + try + i := AMachine.GetInputArgAsInteger(0); + MainForm.RandomizeCP(ScriptEditor.cp, i); + for i := 0 to NXFORMS - 1 do + if ScriptEditor.cp.xform[i].density = 0 then break; + NumTransforms := i; + except on E: EMathError do + end; +end; + +procedure TOperationLibrary.RandomGradientProc(AMachine: TatVirtualMachine); +begin + ScriptEditor.cp.cmap := GradientHelper.RandomGradient; +end; + +procedure TOperationLibrary.CalculateScale(AMachine: TatVirtualMachine); +var + x, y: double; +begin + x := ScriptEditor.cp.center[0]; + y := ScriptEditor.cp.center[1]; + ScriptEditor.cp.CalcBoundBox; + ScriptEditor.cp.center[0] := x; + ScriptEditor.cp.center[1] := y +end; + +procedure TOperationLibrary.CalculateBounds(AMachine: TatVirtualMachine); +begin + ScriptEditor.cp.CalcBoundBox; +end; + + +procedure TOperationLibrary.SetRenderBounds(AMachine: TatVirtualMachine); +begin + ScriptRenderForm.SetRenderBounds; +end; + +procedure TOperationLibrary.GetFileName(AMachine: TatVirtualMachine); +begin + if ScriptEditor.OpenDialog.Execute then + with AMachine do + ReturnOutputArg(ScriptEditor.OpenDialog.Filename) + else + begin + LastError := 'Invalid file name.'; + AMachine.Halt; + end; +end; + +procedure TOperationLibrary.GetSaveFileName(AMachine: TatVirtualMachine); +begin + if ScriptEditor.SaveDialog.Execute then + with AMachine do + ReturnOutputArg(ScriptEditor.SaveDialog.Filename) + else + begin + LastError := 'Invalid file name.'; + AMachine.Halt; + end; +end; + +procedure TOperationLibrary.CopyFileProc(AMachine: TatVirtualMachine); +var + src, dest: string; + FileList: TStringList; +begin + src := AMachine.GetInputArgAsString(0); + dest := AMachine.GetInputArgAsString(1); + FileList := TStringList.Create; + try + + if FileExists(src) then + begin + FileList.LoadFromFile(src); + try + FileList.SaveToFile(dest); + except + LastError := 'Cannot copy file'; + AMachine.Halt; + end; + + end + else + + begin + LastError := 'Cannot copy file'; + AMachine.Halt; + end; + + finally + FileList.free; + end; +end; + +(*procedure TOperationLibrary.BM_OpenProc(AMachine: TatVirtualMachine); +var + Name: string; +begin + Name := AMachine.GetInputArgAsString(0); + + if @bmdll32.Open <> nil then begin + AMachine.ReturnOutputArg(bmdll32.Open(Pchar(Name))); + end else begin + LastError := 'bmdll32.dll not loaded'; + AMachine.Halt; + end; +end; *) + +(*procedure TOperationLibrary.BM_DllCFuncProc(AMachine: TatVirtualMachine); +var + var1, var2: Integer; +begin + var1 := AMachine.GetInputArgAsInteger(0); + var2 := AMachine.GetInputArgAsInteger(1); + + if @bmdll32.DllCFunc <> nil then begin + AMachine.ReturnOutputArg(bmdll32.DllCFunc(var1, var2)); + end else begin + LastError := 'bmdll32.dll not loaded'; + AMachine.Halt; + end; +end; *) + +procedure TOperationLibrary.SetParamFileProc(AMachine: TatVirtualMachine); +var + filen: string; +begin + filen := AMachine.GetInputArgAsString(0); + if FileExists(filen) then + begin + ParamFile := filen; + ScriptEditor.FillFileList; + end + else + begin + LastError := 'Parameter file does not exist.'; + AMachine.Halt; + end; +end; + +procedure TOperationLibrary.RotateProc(AMachine: TatVirtualMachine); +begin + try + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then raise EFormatInvalid.Create(ErrorOutOfRange); + with AMachine do + ScriptEditor.cp.xform[ActiveTransform].Rotate(GetInputArgAsFloat(0)); + except on E: EFormatInvalid do + begin + ScriptEditor.Console.Lines.Add('Rotate: ' + E.message); + Application.ProcessMessages; + LastError := E.Message; + end; + end; +end; + +procedure TOperationLibrary.MulProc(AMachine: TatVirtualMachine); +begin + try + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then raise EFormatInvalid.Create(ErrorOutOfRange); + with AMachine do + ScriptEditor.cp.xform[ActiveTransform].Multiply(GetInputArgAsFloat(0), GetInputArgAsFloat(1), GetInputArgAsFloat(2), GetInputArgAsFloat(3)); + except on E: EFormatInvalid do + begin + ScriptEditor.Console.Lines.Add('Multiply: ' + E.message); + Application.ProcessMessages; + LastError := E.Message; + end; + end; +end; + +procedure TOperationLibrary.Print(AMachine: TatVirtualMachine); +begin + ScriptEditor.Console.Lines.Add(AMachine.GetInputArg(0)); + Application.ProcessMessages; +end; + +procedure TOperationLibrary.ShowStatusProc(AMachine: TatVirtualMachine); +begin + MainForm.StatusBar.Panels[0].Text := AMachine.GetInputArg(0); + Application.ProcessMessages; +end; + + +procedure TOperationLibrary.SaveFlameProc(AMachine: TatVirtualMachine); +var + filename: string; +begin + with AMachine do + begin + filename := GetInputArgAsString(0); + (*if (LowerCase(ExtractFileExt(filename)) = '.apo') or + (LowerCase(ExtractFileExt(filename)) = '.fla') then + MainForm.SaveFlame(ScriptEditor.cp, ScriptEditor.cp.name, filename) + else *) + MainForm.SaveXMLFlame(ScriptEditor.cp, ScriptEditor.cp.name, filename) + end; +end; + +procedure TOperationLibrary.SaveGradientProc(AMachine: TatVirtualMachine); +var + gradstr: TStringList; +begin + gradstr := TStringList.Create; + try + gradstr.add(CleanIdentifier(AMachine.GetInputArgAsString(1)) + ' {'); + gradstr.add(MainForm.GradientFromPalette(ScriptEditor.cp.cmap, AMachine.GetInputArgAsString(1))); + gradstr.add('}'); + MainForm.SaveGradient(gradstr.text, AMachine.GetInputArgAsString(1), AMachine.GetInputArgAsString(0)) + finally + gradstr.free + end; +end; + +procedure TOperationLibrary.ListFileProc(AMachine: TatVirtualMachine); +var + flafile: string; +begin + flafile := AMachine.GetInputArgAsString(0); + if FileExists(flafile) then + begin + OpenFile := flafile; + MainForm.Caption := AppVersionString + ' - ' + OpenFile; + (*if (LowerCase(ExtractFileExt(flafile)) = '.apo') or + (LowerCase(ExtractFileExt(flafile)) = '.fla') then + begin + ListIFS(OpenFile, 1); + OpenFileType := ftFla + end + else + begin*) + ListXML(OpenFile, 1); + OpenFileType := ftXML; + //end; + MainForm.SetFocus; + end + else + begin + LastError := 'Cannot open file: ' + Flafile; + AMachine.Halt; + end; +end; + +procedure TOperationLibrary.StoreFlameProc(AMachine: TatVirtualMachine); +var + v: integer; +begin + v := AMachine.GetInputArgAsInteger(0); + if (v >= 0) and (v < NCPS) then + begin + cps[v].copy(ScriptEditor.cp); + cps[v].cmap := ScriptEditor.cp.cmap; + end; +end; + +procedure TOperationLibrary.GetFlameProc(AMachine: TatVirtualMachine); +var + i, v: integer; +begin + v := AMachine.GetInputArgAsInteger(0); + if (v >= 0) and (v < NCPS) then + begin + ScriptEditor.cp.copy(cps[v]); + ScriptEditor.cp.cmap := cps[v].cmap; + end; + for i := 0 to NXFORMS - 1 do + if ScriptEditor.cp.xform[i].density = 0 then break; + NumTransforms := i; +end; + +(* +procedure ParseXML(var cp1: TControlPoint; const params: PCHAR); +var + i: integer; + h, s, v: real; +begin + nxform := 0; + FinalXformLoaded := false; + MainForm.XMLScanner.LoadFromBuffer(params); + MainForm.XMLScanner.Execute; + cp1.copy(ParseCp); + if Parsecp.cmapindex <> -1 then + begin + if cp1.cmapindex < NRCMAPS then + GetCMap(cp1.cmapindex, 1, cp1.cmap) + else + ShowMessage('Palette index too high'); + end; + if (cp1.hue_rotation > 0) and (cp1.hue_rotation < 1) then + begin + for i := 0 to 255 do + begin + RGBToHSV(cp1.cmap[i][0], cp1.cmap[i][1], cp1.cmap[i][2], h, s, v); + h := Round(360 + h + (cp1.hue_rotation * 360)) mod 360; + HSVToRGB(h, s, v, cp1.cmap[i][0], cp1.cmap[i][1], cp1.cmap[i][2]); + end; + end; + if nxform < NXFORMS then + for i := nxform to NXFORMS - 1 do + cp1.xform[i].density := 0; + // Check for symmetry parameter + if cp1.symmetry <> 0 then + begin + add_symmetry_to_control_point(cp1, cp1.symmetry); + cp1.symmetry := 0; + end; +end; +*) + +procedure LoadXMLFlame(index: integer); +var + FStrings: TStringList; + IFSStrings: TStringList; + EntryStrings, Tokens: TStringList; + i: integer; +begin + FStrings := TStringList.Create; + IFSStrings := TStringList.Create; + Tokens := TStringList.Create; + EntryStrings := TStringList.Create; + try + FStrings.LoadFromFile(ParamFile); + + for i := 0 to FStrings.count - 1 do + begin + if Pos('', FStrings[i]) <> 0; + MainForm.ParseXML(ScriptEditor.Cp, IFSStrings.Text, true); + for i := 0 to NXFORMS - 1 do + if ScriptEditor.cp.xform[i].density = 0 then break; + NumTransforms := i; +// FlameName := FileList[index]; + finally + IFSStrings.Free; + FStrings.Free; + Tokens.free; + EntryStrings.free; + end; +end; + +procedure LoadFlame(index: integer); +var + FStrings: TStringList; + IFSStrings: TStringList; + EntryStrings, Tokens: TStringList; + SavedPal: Boolean; + i, j: integer; + FlameString, s: string; + Palette: TcolorMap; +// x, y: double; +begin + SavedPal := false; + FStrings := TStringList.Create; + IFSStrings := TStringList.Create; + Tokens := TStringList.Create; + EntryStrings := TStringList.Create; + try + FStrings.LoadFromFile(ParamFile); + for i := 0 to FStrings.count - 1 do + if Pos(FileList[index] + ' ', Trim(FStrings[i])) = 1 then + break; + IFSStrings.Add(FStrings[i]); + repeat + inc(i); + IFSStrings.Add(FStrings[i]); + until Pos('}', FStrings[i]) <> 0; + ScriptEditor.cp.Clear; // initialize control point for new flame; + ScriptEditor.cp.background[0] := 0; + ScriptEditor.cp.background[1] := 0; + ScriptEditor.cp.background[2] := 0; + ScriptEditor.cp.sample_density := defSampleDensity; + ScriptEditor.cp.spatial_oversample := defOversample; + ScriptEditor.cp.spatial_filter_radius := defFilterRadius; + for i := 0 to FStrings.count - 1 do + begin + if Pos(Lowercase(FileList[index]) + ' ', Trim(Lowercase(FStrings[i]))) = 1 then + break; + end; + inc(i); + while (Pos('}', FStrings[i]) = 0) and (Pos('palette:', FStrings[i]) = 0) do + begin + EntryStrings.Add(FStrings[i]); + inc(i); + end; + if Pos('palette:', FStrings[i]) = 1 then + begin + SavedPal := True; + inc(i); + for j := 0 to 255 do begin + s := FStrings[i]; + GetTokens(s, Tokens); + Palette[j][0] := StrToInt(Tokens[0]); + Palette[j][1] := StrToInt(Tokens[1]); + Palette[j][2] := StrToInt(Tokens[2]); + inc(i); + end; + end; + FlameString := EntryStrings.Text; + ScriptEditor.cp.ParseString(FlameString); + for i := 0 to NXFORMS - 1 do + if ScriptEditor.cp.xform[i].density = 0 then break; + NumTransforms := i; + if SavedPal then ScriptEditor.cp.cmap := Palette; + ScriptEditor.cp.name := FileList[index]; + finally + IFSStrings.Free; + FStrings.Free; + Tokens.free; + EntryStrings.free; + end; +end; + +procedure TOperationLibrary.LoadFlameProc(AMachine: TatVirtualMachine); +var + i: integer; +begin + i := AMachine.GetInputArgAsInteger(0); + if (i >= 0) and (i < FileList.count) then + begin + (*if (LowerCase(ExtractFileExt(ParamFile)) = '.fla') or + (LowerCase(ExtractFileExt(ParamFile)) = '.apo') then + LoadFlame(i) + else*) + LoadXMLFlame(i); ; + end; +end; + +procedure TOperationLibrary.RotateFlameProc(AMachine: TatVirtualMachine); +var + Triangles: TTriangles; + i: integer; + r: double; +begin + ScriptEditor.cp.TrianglesFromCp(Triangles); + r := AMachine.GetInputArgAsFloat(0) * pi / 180; + for i := -1 to NumTransforms - 1 do + begin + Triangles[i] := RotateTriangle(Triangles[i], r); + end; + ScriptEditor.cp.GetFromTriangles(Triangles, NumTransforms); +end; + +procedure TOperationLibrary.AddSymmetryProc(AMachine: TatVirtualMachine); +var + i: integer; +begin + add_symmetry_to_control_point(ScriptEditor.cp, AMachine.GetInputArgAsInteger(0)); + for i := 0 to NXFORMS - 1 do + if ScriptEditor.cp.xform[i].density = 0 then break; + NumTransforms := i; +end; + +procedure TOperationLibrary.RotateReferenceProc(AMachine: TatVirtualMachine); +var + Triangles: TTriangles; + r: double; + tx: TXForm; +begin + tx := TXForm.Create; + tx.Assign(scripteditor.cp.xform[NumTransforms]); + ScriptEditor.cp.TrianglesFromCp(Triangles); + r := AMachine.GetInputArgAsFloat(0) * pi / 180; + Triangles[-1] := RotateTriangle(Triangles[-1], r); + ScriptEditor.cp.GetFromTriangles(Triangles, NumTransforms); + scripteditor.cp.xform[NumTransforms].Assign(tx); + tx.Free; +end; + +procedure TOperationLibrary.ScaleProc(AMachine: TatVirtualMachine); +begin + try + if (ActiveTransform < 0) or (ActiveTransform >= ScriptEditor.cp.NumXForms) then raise EFormatInvalid.Create(ErrorOutOfRange); + with AMachine do + ScriptEditor.cp.xform[ActiveTransform].Scale(GetInputArgAsFloat(0)); + except on E: EFormatInvalid do + begin + ScriptEditor.Console.Lines.Add('Scale: ' + E.message); + Application.ProcessMessages; + LastError := E.Message; + end; + end; +end; + +procedure TOperationLibrary.GetActiveTransformProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutputArg(ActiveTransform); +end; + +procedure TOperationLibrary.TransformsProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutputArg(NumTransforms); +end; + +procedure TOperationLibrary.GetVariation(AMachine: TatVirtualMachine); +var + i: integer; +begin + with AMachine do + begin + i := integer(Variation); + if (i >= NRVAR) or (i < 0) then + i := -1; + ReturnOutputArg(i); + end +end; + +procedure TOperationLibrary.SetVariation(AMachine: TatVirtualMachine); +var + i: integer; +begin + with AMachine do + begin + i := GetInputArgAsInteger(0); + if (i < 0) or (i >= NRVAR) then + i := NRVAR ; + Variation := TVariation(i); + if i = NRVAR then + MainForm.mnuVRandom.checked := True + else + MainForm.VarMenus[i].Checked := True; + end +end; + +procedure TOperationLibrary.VariationIndexProc(AMachine: TatVirtualMachine); +var + i: integer; + str: string; +begin + with AMachine do begin + str := LowerCase(GetInputArgAsString(0)); + i := NRVAR-1; + while (i >= 0) and (LowerCase(varnames(i)) <> str) do Dec(i); + ReturnOutputArg(i); + end; +end; + +procedure TOperationLibrary.VariationNameProc(AMachine: TatVirtualMachine); +var + i: integer; + str: string; +begin + with AMachine do begin + i := GetInputArgAsInteger(0); + if (i >= 0) and (i < NRVAR) then + ReturnOutputArg(varnames(i)) + else + ReturnOutputArg(''); + end; +end; + +procedure TOperationLibrary.VariableIndexProc(AMachine: TatVirtualMachine); +var + i: integer; + str: string; +begin + with AMachine do begin + str := LowerCase(GetInputArgAsString(0)); + i := GetNrVariableNames-1; + while (i >= 0) and (LowerCase(GetVariableNameAt(i)) <> str) do Dec(i); + ReturnOutputArg(i); + end; +end; + +procedure TOperationLibrary.VariableNameProc(AMachine: TatVirtualMachine); +var + i: integer; + str: string; +begin + with AMachine do begin + i := GetInputArgAsInteger(0); + if (i >= 0) and (i < GetNrVariableNames) then + ReturnOutputArg(GetVariableNameAt(i)) + else + ReturnOutputArg(''); + end; +end; + +procedure TOperationLibrary.FileCountProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutputArg(FileList.Count); +end; + +procedure TOperationLibrary.ClearProc(AMachine: TatVirtualMachine); +var + i: integer; +begin + NumTransforms := 0; + ActiveTransform := -1; +{ + for i := 0 to NXFORMS - 1 do + ScriptEditor.cp.xform[i].density := 0; +} + ScriptEditor.cp.Clear; + ScriptEditor.cp.xform[0].symmetry := 1; +end; + +procedure TOperationLibrary.MorphProc(AMachine: TatVirtualMachine); +var + a, b, i: integer; + v: double; +begin + with AMachine do + begin + a := GetInputArgAsInteger(0); + b := GetInputArgAsInteger(1); + v := GetInputArgAsFloat(2); + if (a >= 0) and (a < NCPS) and (b >= 0) and (b < NCPS) then + begin + ScriptEditor.cp.InterpolateX(cps[a], cps[b], v); + for i := 0 to NXFORMS - 1 do + if ScriptEditor.cp.xform[i].density = 0 then break; + NumTransforms := i; + end; + end; +end; + +procedure TOperationLibrary.PreviewProc(AMachine: TatVirtualMachine); +begin + if NumTransforms > 0 then + begin + AMachine.Paused := True; + PreviewForm.cp.Copy(ScriptEditor.cp); + PreviewForm.cp.AdjustScale(PreviewForm.Image.Width, PreviewForm.Image.Height); + PreviewForm.Show; + PreviewForm.DrawFlame; + AMachine.Paused := False; + Application.ProcessMessages; + end + else AMachine.Halt; +end; + +procedure TOperationLibrary.RenderProc(AMachine: TatVirtualMachine); +begin + if NumTransforms > 0 then + begin + ScriptRenderForm.cp.Copy(ScriptEditor.cp); + //ScriptRenderForm.Caption := 'Rendering ' + ScriptEditor.Renderer.Filename; ; + ScriptRenderForm.Show; + ScriptRenderForm.Render; + end + else AMachine.Halt; +end; + +procedure TOperationLibrary.SetActiveTransformProc(AMachine: TatVirtualMachine); +var + i: integer; +begin + try + with AMachine do + i := GetInputArgAsInteger(0); + if (i >= 0) and (i < NXFORMS) then + ActiveTransform := i + else raise EFormatInvalid.Create(ErrorOutOfRange); + except on E: EFormatInvalid do + begin + Application.ProcessMessages; + LastError := E.Message; + Scripter.Halt; + end; + end; +end; + +procedure TOperationLibrary.AddTransformProc(AMachine: TatVirtualMachine); +var + i: integer; +begin + try + if NumTransforms < NXFORMS then + begin + ActiveTransform := NumTransforms; + inc(NumTransforms); + scriptEditor.cp.xform[NumTransforms].Assign(scriptEditor.cp.xform[ActiveTransform]); +{ ScriptEditor.cp.xform[ActiveTransform].c[0, 0] := 1; + ScriptEditor.cp.xform[ActiveTransform].c[0, 1] := 0; + ScriptEditor.cp.xform[ActiveTransform].c[1, 0] := 0; + ScriptEditor.cp.xform[ActiveTransform].c[1, 1] := 1; + ScriptEditor.cp.xform[ActiveTransform].c[2, 0] := 0; + ScriptEditor.cp.xform[ActiveTransform].c[2, 1] := 0; + ScriptEditor.cp.xform[ActiveTransform].color := 0; + ScriptEditor.cp.xform[ActiveTransform].density := 1 / NumTransforms; + ScriptEditor.cp.xform[ActiveTransform].vars[0] := 1; + for i := 1 to NRVAR - 1 do + ScriptEditor.cp.xform[ActiveTransform].vars[i] := 0;} + scriptEditor.cp.xform[ActiveTransform].Clear; + ScriptEditor.cp.xform[ActiveTransform].density := 0.5; + end + else raise EFormatInvalid.Create('Too many transforms.'); + except on E: EFormatInvalid do + begin + Application.ProcessMessages; + LastError := E.Message; + Scripter.Halt; + end; + end; +end; + +procedure TOperationLibrary.DeleteTransformProc(AMachine: TatVirtualMachine); +var + i, j: integer; +begin + try + // I'm not sure, but *maybe* this will help scripts not to screw up finalXform + if ActiveTransform = NumTransforms then + // final xform - just clear it + begin + scriptEditor.cp.xform[NumTransforms].Clear; + scriptEditor.cp.xform[NumTransforms].symmetry := 1; + scriptEditor.cp.finalXformEnabled := false; + exit; + end; + if NumTransforms <= 1 then exit; + + // delete xform from all probability tables + for i := 0 to NumTransforms-1 do + with scriptEditor.cp.xform[i] do begin + for j := ActiveTransform to NumTransforms-1 do + modWeights[j] := modWeights[j+1]; + modWeights[NumTransforms-1] := 1; + end; + // + + with scriptEditor.cp do begin + if ActiveTransform = (NumTransforms - 1) then + Dec(ActiveTransform) + else begin + for i := ActiveTransform to NumTransforms - 2 do + xform[i].Assign(xform[i + 1]); + end; + Dec(NumTransforms); + xform[NumTransforms].Assign(xform[NumTransforms+1]); + xform[NumTransforms+1].Clear; + end; + except + begin + Application.ProcessMessages; + LastError := 'Oops!'; + Scripter.Halt; + end; + end; +end; + + +procedure TOperationLibrary.CopyTransformProc(AMachine: TatVirtualMachine); +var + old, i: integer; +begin + try + if NumTransforms < NXFORMS then + with ScriptEditor.cp do + begin + old := ActiveTransform; + ActiveTransform := NumTransforms; + inc(NumTransforms); + xform[NumTransforms].Assign(xform[ActiveTransform]); // final xform + xform[ActiveTransform].Assign(xform[old]); + + for i := 0 to NumTransforms-1 do + xform[i].modWeights[ActiveTransform] := xform[i].modWeights[old]; + xform[ActiveTransform].modWeights[ActiveTransform] := xform[old].modWeights[old]; + end + else raise EFormatInvalid.Create('Too many transforms.'); + except on E: EFormatInvalid do + begin + Application.ProcessMessages; + LastError := E.Message; + Scripter.Halt; + end; + end; +end; + +procedure TOperationLibrary.TranslateProc(AMachine: TatVirtualMachine); +begin + try + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then // was: NXFORMS-1 + raise EFormatInvalid.Create(ErrorOutOfRange); + with AMachine do + ScriptEditor.cp.xform[ActiveTransform].Translate(GetInputArgAsFloat(0), GetInputArgAsFloat(1)); + except on E: EFormatInvalid do + begin + Application.ProcessMessages; + LastError := E.Message; + Scripter.Halt; + end; + end; +end; + +procedure TOperationLibrary.NormalizeVars(AMachine: TatVirtualMachine); +begin + NormalizeVariations(ScriptEditor.cp); +end; + +{ ******************************** Math Library ****************************** } + +procedure TMathLibrary.Init; +begin + Scripter.DefineMethod('Cos', 1, tkfloat, nil, CosProc); + Scripter.DefineMethod('Sin', 1, tkfloat, nil, SinProc); +end; + +procedure TMathLibrary.CosProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutputArg(cos(GetInputArgAsFloat(0))); +end; + +procedure TMathLibrary.SinProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutputArg(sin(GetInputArgAsFloat(0))); +end; + +{ **************************** Matrix functions ******************************* } + + +function Mul33(M1, M2: TMatrix): TMatrix; +begin + result[0, 0] := M1[0][0] * M2[0][0] + M1[0][1] * M2[1][0] + M1[0][2] * M2[2][0]; + result[0, 1] := M1[0][0] * M2[0][1] + M1[0][1] * M2[1][1] + M1[0][2] * M2[2][1]; + result[0, 2] := M1[0][0] * M2[0][2] + M1[0][1] * M2[1][2] + M1[0][2] * M2[2][2]; + result[1, 0] := M1[1][0] * M2[0][0] + M1[1][1] * M2[1][0] + M1[1][2] * M2[2][0]; + result[1, 1] := M1[1][0] * M2[0][1] + M1[1][1] * M2[1][1] + M1[1][2] * M2[2][1]; + result[1, 2] := M1[1][0] * M2[0][2] + M1[1][1] * M2[1][2] + M1[1][2] * M2[2][2]; + result[2, 0] := M1[2][0] * M2[0][0] + M1[2][1] * M2[1][0] + M1[2][2] * M2[2][0]; + result[2, 0] := M1[2][0] * M2[0][1] + M1[2][1] * M2[1][1] + M1[2][2] * M2[2][1]; + result[2, 0] := M1[2][0] * M2[0][2] + M1[2][1] * M2[1][2] + M1[2][2] * M2[2][2]; +end; + +function Identity: TMatrix; +var i, j: integer; +begin + for i := 0 to 2 do + for j := 0 to 2 do + Result[i, j] := 0; + Result[0][0] := 1; + Result[1][1] := 1; + Result[2][2] := 1; +end; + +procedure init(var xform: Txform); +var + i: integer; +begin + xform.c[0, 0] := 1; + xform.c[0, 1] := 0; + xform.c[1, 0] := 0; + xform.c[1, 1] := 1; + xform.c[2, 0] := 0; + xform.c[2, 1] := 0; + xform.color := 0; + xform.density := 1 / NumTransforms; + xform.SetVariation(0, 1); + for i := 1 to NRVAR - 1 do + xform.SetVariation(i, 0); +end; + +{ ************************************* Form ********************************* } + +procedure TScriptEditor.FormCreate(Sender: TObject); +var + i: integer; +begin + self.Caption := TextByKey('script-title'); + btnBreak.Hint := TextByKey('script-break'); + btnNew.Hint := TextByKey('script-new'); + btnOpen.Hint := TextByKey('script-open'); + btnSave.Hint := TextByKey('script-save'); + btnRun.Hint := TextByKey('script-run'); + btnStop.Hint := TextByKey('script-stop'); + + Transform := TTransform.create; + FileList := TStringList.Create; + Flame := TFlame.Create; + Options := TOptions.Create; + Pivot := TPivot.Create; + Renderer := TScriptRender.create; + Another := TScriptRender.create; + cp := TControlPoint.create; + for i := 0 to 9 do + cps[i] := TControlPoint.create; + ScriptEditor.PrepareScripter; +end; + +procedure TScriptEditor.FormDestroy(Sender: TObject); +var + i: integer; +begin + FileList.Free; + Renderer.Free; + Another.Free; + for i := 0 to 9 do + cps[i].free; + cp.free; + Flame.Free; + Transform.Free; + Options.Free; + Pivot.Free; +end; + +procedure TScriptEditor.FormShow(Sender: TObject); +var + Registry: TRegistry; +begin + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Script', False) then + begin + { Size and position } + if Registry.ValueExists('Left') then + ScriptEditor.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + ScriptEditor.Top := Registry.ReadInteger('Top'); + if Registry.ValueExists('Width') then + ScriptEditor.Width := Registry.ReadInteger('Width'); + if Registry.ValueExists('Height') then + ScriptEditor.Height := Registry.ReadInteger('Height'); + end; + Registry.CloseKey; + finally + Registry.Free; + end; +end; + +procedure TScriptEditor.FormClose(Sender: TObject; + var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + { Defaults } + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Script', True) then + begin + { Size and position } + if ScriptEditor.WindowState <> wsMaximized then begin + Registry.WriteInteger('Top', ScriptEditor.Top); + Registry.WriteInteger('Left', ScriptEditor.Left); + Registry.WriteInteger('Width', ScriptEditor.Width); + Registry.WriteInteger('Height', ScriptEditor.Height); + end; + end; + finally + Registry.Free; + end; +end; +{ ************************ Flame interface *********************************** } + +{ The TFlame class is used only as an interface. The control point parameters + are read and set directly. Parameter ranges aren't limited but values not + in the correct range are ignored. } + +procedure TScriptEditor.GetFlameGammaTresholdProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.gammaThreshRelative); +end; + +procedure TScriptEditor.SetFlameGammaTresholdProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v > 0) then cp.gammaThreshRelative := v; + end; +end; + +procedure TScriptEditor.GetFlameGammaProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.Gamma); +end; + +procedure TScriptEditor.SetFlameGammaProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v > 0) then cp.Gamma := v; + end; +end; + +procedure TScriptEditor.GetFlameBrightnessProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.Brightness); +end; + +procedure TScriptEditor.SetFlameBrightnessProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if v > 0 then cp.Brightness := v; + end; +end; + +procedure TScriptEditor.GetFlameVibrancyProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.Vibrancy); +end; + +procedure TScriptEditor.SetFlameVibrancyProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if v > 0 then cp.Vibrancy := v; + end; +end; + +procedure TScriptEditor.GetFlameTimeProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.Time); +end; + +procedure TScriptEditor.SetFlameTimeProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0) then cp.Time := v; + end; +end; + +procedure TScriptEditor.GetFlameZoomProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.Zoom); +end; + +procedure TScriptEditor.SetFlameZoomProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.Zoom := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetFlameXProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.center[0]); +end; + +procedure TScriptEditor.SetFlameXProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.center[0] := GetInputArgAsFloat(0); +end; + + +procedure TScriptEditor.GetFlameYProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.center[1]); +end; + +procedure TScriptEditor.SetFlameYProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.center[1] := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetFlameDensityProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.sample_density); +end; + +procedure TScriptEditor.SetFlameDensityProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if v >= 0 then cp.sample_density := v; + end; +end; + +procedure TScriptEditor.GetFlameOversampleProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.spatial_oversample); +end; + +procedure TScriptEditor.SetFlameOversampleProc(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + { Range = 1 to 4 ... (document this) } + if (v >= 1) and (v <= 4) then cp.spatial_oversample := v; + end; +end; + +procedure TScriptEditor.GetFlameFilterRadiusProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.spatial_filter_radius); +end; + +procedure TScriptEditor.SetFlameFilterRadiusProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if v >= 0 then cp.spatial_filter_radius := v; + end; +end; + +procedure TScriptEditor.GetFlameFinalxformEnabledProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.finalXformEnabled); +end; + +procedure TScriptEditor.SetFlameFinalxformEnabledProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.finalXformEnabled := (GetInputArgAsInteger(0) <> 0); +end; + +procedure TScriptEditor.GetFlameSoloXformProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.soloXform); +end; + +procedure TScriptEditor.SetFlameSoloXformProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.soloXform := GetInputArgAsInteger(0); + if (cp.soloXform < 0) or (cp.soloXform >= NumTransforms) then + cp.soloXform := -1; +end; + +procedure TScriptEditor.GetFlameWidthProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.width); +end; + +procedure TScriptEditor.SetFlameWidthProc(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if v >= 1 then cp.width := v; + end; +end; + +procedure TScriptEditor.GetFlameHeightProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.height); +end; + +procedure TScriptEditor.SetFlameHeightProc(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if v >= 1 then cp.height := v; + end; +end; + +procedure TScriptEditor.GetFlamePixelsPerUnitProc(AMachine: TatVirtualMachine); +begin + with AMachine do +// ReturnOutPutArg(cp.pixels_per_unit); + ReturnOutPutArg(100*cp.pixels_per_unit/cp.Width); +end; + +procedure TScriptEditor.SetFlamePixelsPerUnitProc(AMachine: TatVirtualMachine); +begin + with AMachine do +// cp.pixels_per_unit := GetInputArgAsInteger(0); <<--- hmm, ppu isn't integer :-\ + cp.pixels_per_unit := GetInputArgAsFloat(0) * cp.Width / 100.0; +end; + +procedure TScriptEditor.GetFlamePaletteProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.cmap[Integer(GetArrayIndex(0)), Integer(GetArrayIndex(1))]); +end; + +procedure TScriptEditor.SetFlamePaletteProc(AMachine: TatVirtualMachine); +var + i0, i1, v: integer; +begin + with AMachine do + begin + i0 := GetArrayIndex(0); + i1 := GetArrayIndex(1); + v := GetInputArgAsInteger(0); + if (i0 >= 0) and (i0 <= 255) and (i1 >= 0) and (i1 <= 2) and + (v >= 0) and (v < 256) then + cp.cmap[i0, i1] := v; + end; +end; + +procedure TScriptEditor.GetFlameBackgroundProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.background[Integer(GetArrayIndex(0))]); +end; + +procedure TScriptEditor.SetFlameBackgroundProc(AMachine: TatVirtualMachine); +var + i, v: integer; +begin + with AMachine do + begin + i := GetArrayIndex(0); + v := GetInputArgAsInteger(0); + if (i >= 0) and (i <= 2) and (v >= 0) and (v < 256) then + cp.Background[i] := v; + end; +end; + +procedure TScriptEditor.SetFlameNameProc(AMachine: TatVirtualMachine); +begin + cp.name := AMachine.GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetFlameNameProc(AMachine: TatVirtualMachine); +begin + AMachine.ReturnOutPutArg(cp.name); +end; + +procedure TScriptEditor.SetFlameNickProc(AMachine: TatVirtualMachine); +begin + cp.nick := AMachine.GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetFlameURLProc(AMachine: TatVirtualMachine); +begin + AMachine.ReturnOutPutArg(cp.url); +end; + +procedure TScriptEditor.SetFlameURLProc(AMachine: TatVirtualMachine); +begin + cp.url := AMachine.GetInputArgAsString(0); +end; + + +procedure TScriptEditor.GetFlameNickProc(AMachine: TatVirtualMachine); +begin + AMachine.ReturnOutPutArg(cp.nick); +end; + + +procedure TScriptEditor.SetFlameHueProc(AMachine: TatVirtualMachine); +var + v: double; +begin + v := AMachine.GetInputArgAsFloat(0); + if (v >= 0) and (v <= 1) then + cp.hue_rotation := v; +end; + +procedure TScriptEditor.GetFlameHueProc(AMachine: TatVirtualMachine); +begin + AMachine.ReturnOutPutArg(cp.hue_rotation); +end; + +procedure TScriptEditor.GetFlameBatchesProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.nbatches); +end; + +procedure TScriptEditor.SetFlameBatchesProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.nbatches := GetInputArgAsInteger(0); +end; + +procedure TScriptEditor.GetFlameAngleProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.FAngle); +end; + +procedure TScriptEditor.SetFlameAngleProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.FAngle := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetFlamePitchProc(AMachine: TatVirtualMachine); +var + v:double; +begin + // fix: someone forgot to translate from/to radians + v := cp.cameraPitch * 180 / PI; + with AMachine do + ReturnOutPutArg(v); +end; + +procedure TScriptEditor.SetFlamePitchProc(AMachine: TatVirtualMachine); +var + v:double; +begin + // fix: someone forgot to translate from/to radians + with AMachine do + v := GetInputArgAsFloat(0); + cp.cameraPitch := v * PI / 180; +end; + +procedure TScriptEditor.GetFlameYawProc(AMachine: TatVirtualMachine); +var + v:double; +begin + // fix: someone forgot to translate from/to radians + v := cp.cameraYaw * 180 / PI; + with AMachine do + ReturnOutPutArg(v); +end; + +procedure TScriptEditor.SetFlameYawProc(AMachine: TatVirtualMachine); +var + v:double; +begin + // fix: someone forgot to translate from/to radians + with AMachine do + v := GetInputArgAsFloat(0); + cp.cameraYaw := v * PI / 180; +end; + +procedure TScriptEditor.GetFlameCamZposProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.cameraZpos); +end; + +procedure TScriptEditor.SetFlameCamZposProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.cameraZpos := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetFlamePerspectiveProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.cameraPersp); +end; + +procedure TScriptEditor.SetFlamePerspectiveProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.cameraPersp := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetFlameDOFProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.cameraDOF); +end; + +procedure TScriptEditor.SetFlameDOFProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.cameraDOF := GetInputArgAsFloat(0); +end; + +{ *************************** Transform interface **************************** } + +procedure TScriptEditor.GetTransformAProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].c[0, 0]); +end; + +procedure TScriptEditor.SetTransformAProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.xform[ActiveTransform].c[0, 0] := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetTransformBProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].c[1, 0]); +end; + +procedure TScriptEditor.SetTransformBProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.xform[ActiveTransform].c[1, 0] := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetTransformCProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].c[0, 1]); +end; + +procedure TScriptEditor.SetTransformCProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.xform[ActiveTransform].c[0, 1] := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetTransformDProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].c[1, 1]); +end; + +procedure TScriptEditor.SetTransformDProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.xform[ActiveTransform].c[1, 1] := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetTransformEProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].c[2, 0]); +end; + +procedure TScriptEditor.SetTransformEProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.xform[ActiveTransform].c[2, 0] := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetTransformFProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].c[2, 1]); +end; + +procedure TScriptEditor.SetTransformFProc(AMachine: TatVirtualMachine); +begin + with AMachine do + cp.xform[ActiveTransform].c[2, 1] := GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetTransformColorProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].Color); +end; + +procedure TScriptEditor.SetTransformColorProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0) and (v <= 1) then + cp.xform[ActiveTransform].Color := v; + end; +end; + +procedure TScriptEditor.GetTransformVarColorProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].pluginColor); +end; + +procedure TScriptEditor.SetTransformVarColorProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= 0) and (v <= 1) then + cp.xform[ActiveTransform].pluginColor := v; + end; +end; + +procedure TScriptEditor.GetTransformWeightProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].density); +end; + +procedure TScriptEditor.SetTransformWeightProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v > 0) and (v <= MAX_WEIGHT) then + cp.xform[ActiveTransform].density := v; + end; +end; + +procedure TScriptEditor.GetTransformSymProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].symmetry); +end; + +procedure TScriptEditor.SetTransformSymProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + if (v >= -1) and (v <= 1) then + cp.xform[ActiveTransform].symmetry := v; + end; +end; + +procedure TScriptEditor.GetTransformVarProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].GetVariation(Integer(GetArrayIndex(0)))); +end; + +procedure TScriptEditor.SetTransformVarProc(AMachine: TatVirtualMachine); +var + v: double; + i: integer; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + i := GetArrayIndex(0); + if (i >= 0) and (i < NRVAR) then + cp.xform[ActiveTransform].SetVariation(i, v); + end; +end; + +procedure TScriptEditor.GetTransformVariProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do begin + cp.xform[ActiveTransform].GetVariable(GetVariableNameAt(Integer(GetArrayIndex(0))), v); + ReturnOutPutArg(v); + end; +end; + +procedure TScriptEditor.SetTransformVariProc(AMachine: TatVirtualMachine); +var + v: double; + i: integer; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + i := GetArrayIndex(0); + if (i >= 0) and (i < GetNrVariableNames) then + cp.xform[ActiveTransform].SetVariable(GetVariableNameAt(i), v); + end; +end; + +procedure TScriptEditor.GetTransformChaosProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(cp.xform[ActiveTransform].modWeights[Integer(GetArrayIndex(0))]); +end; + +procedure TScriptEditor.SetTransformChaosProc(AMachine: TatVirtualMachine); +var + v: double; + i: integer; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + i := GetArrayIndex(0); + if (i >= 0) and (i < NumTransforms) then + cp.xform[ActiveTransform].modWeights[i] := v; + end; +end; + +procedure TScriptEditor.GetTransformPlotModeProc(AMachine: TatVirtualMachine); +begin + with AMachine do + if cp.xform[ActiveTransform].transOpacity=0 then + ReturnOutPutArg(1) + else + ReturnOutPutArg(0); +end; + +procedure TScriptEditor.SetTransformPlotModeProc(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v <> 0) then cp.xform[ActiveTransform].transOpacity := 1 + else cp.xform[ActiveTransform].transOpacity := 0; + end; +end; + +procedure TScriptEditor.GetTransformOpacityProc(AMachine: TatVirtualMachine); +begin + AMachine.ReturnOutPutArg(cp.xform[ActiveTransform].transOpacity) +end; + +procedure TScriptEditor.SetTransformOpacityProc(AMachine: TatVirtualMachine); +var + v: double; +begin + with AMachine do + begin + v := GetInputArgAsFloat(0); + cp.xform[ActiveTransform].transOpacity := v; + end; +end; + +// -- vars as props -- + +procedure TScriptEditor.GetTransformVariationProc(AMachine: TatVirtualMachine); +var + i: integer; + v: double; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do + begin + i := 0; + while (i < NRVAR) and (Lowercase(varnames(i)) <> Lowercase(CurrentPropertyName)) do Inc(i); + if (i < NRVAR) then + ReturnOutPutArg(cp.xform[ActiveTransform].GetVariation(i)) + else begin // shouldn't happen + LastError := 'Cannot find variation at index ' + CurrentPropertyName + ' - ignoring'; + ScriptEditor.Console.Lines.Add(LastError); + //Scripter.Halt; + end; + end; +end; + +procedure TScriptEditor.SetTransformVariationProc(AMachine: TatVirtualMachine); +var + i: integer; + v: double; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do + begin + i := 0; + while (i < NRVAR) and (lowercase(varnames(i)) <> lowercase(CurrentPropertyName)) do Inc(i); + if (i < NRVAR) then + cp.xform[ActiveTransform].SetVariation(i, GetInputArgAsFloat(0)) + else begin // shouldn't happen + LastError := 'Cannot find variation at index ' + CurrentPropertyName + ' - ignoring'; + ScriptEditor.Console.Lines.Add(LastError); + //Scripter.Halt; + end; + end; +end; + +procedure TScriptEditor.GetTransformVariableProc(AMachine: TatVirtualMachine); +var + v: double; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do + begin + cp.xform[ActiveTransform].GetVariable(CurrentPropertyName, v); + ReturnOutPutArg(v); + end; +end; + +procedure TScriptEditor.SetTransformVariableProc(AMachine: TatVirtualMachine); +var + v: double; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do + begin + v := GetInputArgAsFloat(0); + cp.xform[ActiveTransform].SetVariable(CurrentPropertyName, v); + end +end; + +// -- coefs & post-coefs -- + +procedure TScriptEditor.GetTransformCoefsProc(AMachine: TatVirtualMachine); +var + v: double; + i, j: integer; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do begin + i := GetArrayIndex(0); + j := GetArrayIndex(1); + v := cp.xform[ActiveTransform].c[i, j]; + if (i=0)and(j=0) or (i=1)and(j=1) or (i=2)and(j=0) then + ReturnOutPutArg(v) + else + ReturnOutPutArg(-v); + end; +end; + +procedure TScriptEditor.SetTransformCoefsProc(AMachine: TatVirtualMachine); +var + v: double; + i, j: integer; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do + begin + v := GetInputArgAsFloat(0); + i := GetArrayIndex(0); + j := GetArrayIndex(1); + if (i=0)and(j=0) or (i=1)and(j=1) or (i=2)and(j=0) then + cp.xform[ActiveTransform].c[i, j] := v + else if (i=0)and(j=1) or (i=1)and(j=0) or (i=2)and(j=1) then + cp.xform[ActiveTransform].c[i, j] := -v; + end; +end; + +procedure TScriptEditor.GetTransformPostCoefsProc(AMachine: TatVirtualMachine); +var + v: double; + i, j: integer; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do begin + i := GetArrayIndex(0); + j := GetArrayIndex(1); + v := cp.xform[ActiveTransform].p[i, j]; + if (i=0)and(j=0) or (i=1)and(j=1) or (i=2)and(j=0) then + ReturnOutPutArg(v) + else + ReturnOutPutArg(-v); + end; +end; + +procedure TScriptEditor.SetTransformPostCoefsProc(AMachine: TatVirtualMachine); +var + v: double; + i, j: integer; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + with AMachine do + begin + v := GetInputArgAsFloat(0); + i := GetArrayIndex(0); + j := GetArrayIndex(1); + if (i=0)and(j=0) or (i=1)and(j=1) or (i=2)and(j=0) then + cp.xform[ActiveTransform].p[i, j] := v + else if (i=0)and(j=1) or (i=1)and(j=0) or (i=2)and(j=1) then + cp.xform[ActiveTransform].p[i, j] := -v; + end; +end; + +procedure TScriptEditor.TransformClearProc(AMachine: TatVirtualMachine); +begin + cp.xform[ActiveTransform].Clear; + if ActiveTransform < Transforms then + cp.xform[ActiveTransform].density := 0.5 + else + cp.xform[ActiveTransform].symmetry := 1; +end; + +procedure TScriptEditor.TransformRotateOriginProc(AMachine: TatVirtualMachine); +var + tx, ty, rad: double; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + rad := AMachine.GetInputArgAsFloat(0) * pi / 180; + with EditForm.WorldPivot do + with cp.xform[ActiveTransform] do begin + tx := x + (c[2,0] - x) * cos(rad) - (-c[2,1] - y) * sin(rad); + ty := y + (c[2,0] - x) * sin(rad) + (-c[2,1] - y) * cos(rad); + c[2,0] := tx; + c[2,1] := -ty; + end; +end; + +// -- pivot-aware rotating & scaling -- + +procedure TScriptEditor.TransformRotateProc(AMachine: TatVirtualMachine); +var + Triangles: TTriangles; + px, py: double; + + tx: TXForm; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + tx := TXForm.Create; + tx.Assign(scripteditor.cp.xform[NumTransforms]); // just in case (?) + + EditForm.ScriptGetPivot(px, py); + cp.TrianglesFromCp(Triangles); // it's ugly but it works... + Triangles[ActiveTransform] := + RotateTrianglePoint(Triangles[ActiveTransform], px, py, AMachine.GetInputArgAsFloat(0) * pi / 180); + cp.GetFromTriangles(Triangles, NumTransforms); + + cp.xform[NumTransforms].Assign(tx); + tx.Free; +end; + +procedure TScriptEditor.TransformScaleProc(AMachine: TatVirtualMachine); +var + Triangles: TTriangles; + px, py: double; + + tx: TXForm; +begin + if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin + ScriptEditor.Console.Lines.Add(ErrorOutOfRange); + LastError := ErrorOutOfRange; + Scripter.Halt; + exit; + end; + + tx := TXForm.Create; + tx.Assign(scripteditor.cp.xform[NumTransforms]); // just in case (?) + + EditForm.ScriptGetPivot(px, py); + cp.TrianglesFromCp(Triangles); // it's ugly but it works... + Triangles[ActiveTransform] := + ScaleTrianglePoint(Triangles[ActiveTransform], px, py, AMachine.GetInputArgAsFloat(0)); + cp.GetFromTriangles(Triangles, NumTransforms); + + cp.xform[NumTransforms].Assign(tx); + tx.Free; +end; + +{ *************************** Render interface ****************************** } + + +procedure TScriptEditor.GetRenderFilenameProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(TScriptRender(CurrentObject).Filename); +end; + +procedure TScriptEditor.SetRenderFilenameProc(AMachine: TatVirtualMachine); +begin + with AMachine do + TScriptRender(CurrentObject).Filename := GetInputArgAsString(0); +end; + +procedure TScriptEditor.GetRenderWidthProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(TScriptRender(CurrentObject).Width); +end; + +procedure TScriptEditor.SetRenderWidthProc(AMachine: TatVirtualMachine); +begin + with AMachine do + TScriptRender(CurrentObject).Width := GetInputArgAsInteger(0); +end; + +procedure TScriptEditor.GetRenderHeightProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(TScriptRender(CurrentObject).Height); +end; + +procedure TScriptEditor.SetRenderHeightProc(AMachine: TatVirtualMachine); +begin + with AMachine do + TScriptRender(CurrentObject).Height := GetInputArgAsInteger(0); +end; + +procedure TScriptEditor.GetRenderMaxMemoryProc(AMachine: TatVirtualMachine); +begin + with AMachine do + ReturnOutPutArg(TScriptRender(CurrentObject).Height); +end; + +procedure TScriptEditor.SetRenderMaxMemoryProc(AMachine: TatVirtualMachine); +var + v: integer; +begin + with AMachine do + begin + v := GetInputArgAsInteger(0); + if (v >= 0) then + TScriptRender(CurrentObject).MaxMemory := v; + end; +end; + +{ **************************************************************************** } + +procedure TScriptEditor.GetPivotModeProc(AMachine: TatVirtualMachine); +begin + AMachine.ReturnOutputArg(Integer(EditForm.PivotMode)); +end; + +procedure TScriptEditor.SetPivotModeProc(AMachine: TatVirtualMachine); +var + n: integer; +begin + n := AMachine.GetInputArgAsInteger(0); + if n = 0 then + EditForm.PivotMode := pivotLocal + else + EditForm.PivotMode := pivotWorld; +end; + +procedure TScriptEditor.GetPivotXProc(AMachine: TatVirtualMachine); +begin +// EditForm.ScriptGetPivot(px, py); +// AMachine.ReturnOutputArg(px); + if EditForm.PivotMode = pivotLocal then + AMachine.ReturnOutputArg(EditForm.LocalPivot.x) + else + AMachine.ReturnOutputArg(EditForm.WorldPivot.x); +end; + +procedure TScriptEditor.SetPivotXProc(AMachine: TatVirtualMachine); +begin + if EditForm.PivotMode = pivotLocal then + EditForm.LocalPivot.x := AMachine.GetInputArgAsFloat(0) + else + EditForm.WorldPivot.x := AMachine.GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.GetPivotYProc(AMachine: TatVirtualMachine); +begin +// EditForm.ScriptGetPivot(px, py); +// AMachine.ReturnOutputArg(py); + if EditForm.PivotMode = pivotLocal then + AMachine.ReturnOutputArg(EditForm.LocalPivot.y) + else + AMachine.ReturnOutputArg(EditForm.WorldPivot.y); +end; + +procedure TScriptEditor.SetPivotYProc(AMachine: TatVirtualMachine); +begin + if EditForm.PivotMode = pivotLocal then + EditForm.LocalPivot.y := AMachine.GetInputArgAsFloat(0) + else + EditForm.WorldPivot.y := AMachine.GetInputArgAsFloat(0); +end; + +procedure TScriptEditor.SetPivotProc(AMachine: TatVirtualMachine); +begin + with AMachine do begin + if EditForm.PivotMode = pivotLocal then begin + EditForm.LocalPivot.x := GetInputArgAsFloat(0); + EditForm.LocalPivot.y := GetInputArgAsFloat(1); + end + else begin + EditForm.WorldPivot.x := GetInputArgAsFloat(0); + EditForm.WorldPivot.y := GetInputArgAsFloat(1); + end; + end; +end; + +procedure TScriptEditor.ResetPivotProc(AMachine: TatVirtualMachine); +begin + EditForm.btnResetPivotClick(nil); +end; + +{ ********************************* Scripter ********************************* } + +procedure TScriptEditor.PrepareScripter; +var + i: integer; +begin + Scripter.AddLibrary(TatSysUtilsLibrary); + with Scripter.defineClass(TScriptRender) do + begin + DefineProp('Filename', tkString, GetRenderFilenameProc, SetRenderFilenameProc); + DefineProp('Width', tkInteger, GetRenderWidthProc, SetRenderWidthProc); + DefineProp('Height', tkInteger, GetRenderHeightProc, SetRenderHeightProc); + DefineProp('MaxMemory', tkInteger, GetRenderMaxMemoryProc, SetRenderMaxMemoryProc); + end; + Scripter.AddObject('Renderer', Renderer); + + { Flame interface } + with Scripter.defineClass(TFlame) do + begin + DefineProp('Gamma', tkFloat, GetFlameGammaProc, SetFlameGammaProc); + DefineProp('GammaTreshold', tkFloat, GetFlameGammaTresholdProc, SetFlameGammaTresholdProc); + DefineProp('Brightness', tkFloat, GetFlameBrightnessProc, SetFlameBrightnessProc); + DefineProp('Vibrancy', tkFloat, GetFlameVibrancyProc, SetFlameVibrancyProc); + DefineProp('Time', tkFloat, GetFlameTimeProc, SetFlameTimeProc); + DefineProp('Zoom', tkFloat, GetFlameZoomProc, SetFlameZoomProc); + DefineProp('X', tkFloat, GetFlameXProc, SetFlameXProc); + DefineProp('Y', tkFloat, GetFlameYProc, SetFlameYProc); + DefineProp('Width', tkFloat, GetFlameWidthProc, SetFlameWidthProc); + DefineProp('Height', tkFloat, GetFlameHeightProc, SetFlameHeightProc); + DefineProp('SampleDensity', tkFloat, GetFlameDensityProc, SetFlameDensityProc); + DefineProp('Quality', tkFloat, GetFlameDensityProc, SetFlameDensityProc); + DefineProp('Oversample', tkInteger, GetFlameOversampleProc, SetFlameOversampleProc); + DefineProp('FilterRadius', tkFloat, GetFlameFilterRadiusProc, SetFlameFilterRadiusProc); + DefineProp('Scale', tkFloat, GetFlamePixelsPerUnitProc, SetFlamePixelsPerUnitProc); + DefineProp('Gradient', tkInteger, GetFlamePaletteProc, SetFlamePaletteProc, nil, false, 2); + DefineProp('Background', tkInteger, GetFlameBackgroundProc, SetFlameBackgroundProc, nil, false, 1); + DefineProp('Name', tkString, GetFlameNameProc, SetFlameNameProc); + DefineProp('Nick', tkString, GetFlameNickProc, SetFlameNickProc); + DefineProp('URL', tkString, GetFlameURLProc, SetFlameURLProc); + DefineProp('Hue', tkFloat, GetFlameHueProc, SetFlameHueProc); + DefineProp('Batches', tkInteger, GetFlameBatchesProc, SetFlameBatchesProc); + DefineProp('FinalXformEnabled', tkInteger, GetFlameFinalxformEnabledProc, SetFlameFinalxformEnabledProc); + DefineProp('Angle', tkFloat, GetFlameAngleProc, SetFlameAngleProc); + DefineProp('Pitch', tkFloat, GetFlamePitchProc, SetFlamePitchProc); + DefineProp('Yaw', tkFloat, GetFlameYawProc, SetFlameYawProc); + DefineProp('Perspective', tkFloat, GetFlamePerspectiveProc, SetFlamePerspectiveProc); + DefineProp('Z', tkFloat, GetFlameCamZposProc, SetFlameCamZposProc); + DefineProp('DOF', tkFloat, GetFlameDOFProc, SetFlameDOFProc); + DefineProp('SoloXform', tkInteger, GetFlameSoloXformProc, SetFlameSoloXformProc); + end; + Scripter.AddObject('Flame', Flame); + + { Transform interface } + with Scripter.defineClass(TTransform) do + begin + DefineProp('coefs', tkFloat, GetTransformCoefsProc, SetTransformCoefsProc, nil, false, 2); + DefineProp('post', tkFloat, GetTransformPostCoefsProc, SetTransformPostCoefsProc, nil, false, 2); + DefineProp('Color', tkFloat, GetTransformColorProc, SetTransformColorProc); + DefineProp('VarColor', tkFloat, GetTransformVarColorProc, SetTransformVarColorProc); + DefineProp('Weight', tkFloat, GetTransformWeightProc, SetTransformWeightProc); + DefineProp('Symmetry', tkFloat, GetTransformSymProc, SetTransformSymProc); + DefineProp('ColorSpeed', tkFloat, GetTransformSymProc, SetTransformSymProc); + for i:= 0 to NRVAR - 1 do begin + DefineProp(Varnames(i), tkFloat, GetTransformVariationProc, SetTransformVariationProc); + Editor.SyntaxStyles.AutoCompletion.Add(Varnames(i)); + end; + for i:= 0 to GetNrVariableNames - 1 do begin + DefineProp(GetVariableNameAt(i), tkFloat, GetTransformVariableProc, SetTransformVariableProc); + Editor.SyntaxStyles.AutoCompletion.Add(GetVariableNameAt(i)); + end; + Editor.SyntaxStyles.AutoCompletion.Sort; + while Editor.SyntaxStyles.AutoCompletion.Strings[0] = '' do Editor.SyntaxStyles.AutoCompletion.Delete(0); + + DefineMethod('Clear', 0, tkNone, nil, TransformClearProc); + DefineMethod('Rotate', 1, tkNone, nil, TransformRotateProc); + DefineMethod('Scale', 1, tkNone, nil, TransformScaleProc); + DefineMethod('RotateOrigin', 1, tkNone, nil, TransformRotateOriginProc); + + DefineProp('a', tkFloat, GetTransformAProc, SetTransformAProc); + DefineProp('b', tkFloat, GetTransformBProc, SetTransformBProc); + DefineProp('c', tkFloat, GetTransformCProc, SetTransformCProc); + DefineProp('d', tkFloat, GetTransformDProc, SetTransformDProc); + DefineProp('e', tkFloat, GetTransformEProc, SetTransformEProc); + DefineProp('f', tkFloat, GetTransformFProc, SetTransformFProc); + DefineProp('Variation', tkFloat, GetTransformVarProc, SetTransformVarProc, nil, false, 1); + DefineProp('Variable', tkFloat, GetTransformVariProc, SetTransformVariProc, nil, false, 1); + DefineProp('Chaos', tkFloat, GetTransformChaosProc, SetTransformChaosProc, nil, false, 1); + DefineProp('PlotMode', tkInteger, GetTransformPlotModeProc, SetTransformPlotModeProc); + DefineProp('Opacity', tkFloat, GetTransformOpacityProc, SetTransformOpacityProc); + end; + Scripter.AddObject('Transform', Transform); + + { Options interface } + with Scripter.defineClass(TOptions) do + begin + DefineProp('JPEGQuality', tkInteger, GetJPEGQuality, SetJPEGQuality); + DefineProp('BatchSize', tkInteger, GetBatchSize, SetBatchSize); + DefineProp('ParameterFile', tkString, GetParameterFile, SetParameterFile); + DefineProp('SmoothPaletteFile', tkString, GetSmoothPaletteFile, SetSmoothPaletteFile); + DefineProp('NumTries', tkInteger, GetNumTries, SetNumTries); + DefineProp('TryLength', tkInteger, GetTryLength, SetTryLength); + DefineProp('ConfirmDelete', tkVariant, GetConfirmDelete, SetConfirmDelete); + DefineProp('FixedReference', tkVariant, GetFixedReference, SetFixedReference); + DefineProp('SampleDensity', tkFloat, GetSampleDensity, SetSampleDensity); + DefineProp('Gamma', tkFloat, GetGamma, SetGamma); + DefineProp('Brightness', tkFloat, GetBrightness, SetBrightness); + DefineProp('Vibrancy', tkFloat, GetVibrancy, SetVibrancy); + DefineProp('Oversample', tkInteger, GetOversample, SetOversample); + DefineProp('FilterRadius', tkFloat, GetFilterRadius, SetFilterRadius); + DefineProp('Transparency', tkInteger, GetTransparency, SetTransparency); + DefineProp('PreviewLowQuality', tkFloat, GetLowQuality, SetLowQuality); + DefineProp('PreviewMediumQuality', tkFloat, GetMediumQuality, SetMediumQuality); + DefineProp('PreviewHighQuality', tkFloat, GetHighQuality, SetHighQuality); + DefineProp('MinTransforms', tkInteger, GetMinTransforms, SetMinTransforms); + DefineProp('MaxTransforms', tkInteger, GetMaxTransforms, SetMaxTransforms); + DefineProp('MutateMinTransforms', tkInteger, GetMutateMinTransforms, SetMutateMinTransforms); + DefineProp('MutateMaxTransforms', tkInteger, GetMutateMaxTransforms, SetMutateMaxTransforms); + DefineProp('RandomPrefix', tkString, GetPrefix, SetPrefix); + DefineProp('KeepBackground', tkInteger, GetKeepBackground, SetKeepBackground); + DefineProp('SymmetryType', tkInteger, GetSymmetryType, SetSymmetryType); + DefineProp('SymmetryOrder', tkInteger, GetSymmetryOrder, SetSymmetryOrder); + DefineProp('Variations', tkVariant, GetVariations, SetVariations, nil, false, 1); + DefineProp('GradientOnRandom', tkInteger, GetRandomGradient, SetRandomGradient); + DefineProp('MinNodes', tkInteger, GetMinNodes, SetMinNodes); + DefineProp('MaxNodes', tkInteger, GetMaxNodes, SetMaxNodes); + DefineProp('MinHue', tkInteger, GetMinHue, SetMinHue); + DefineProp('MaxHue', tkInteger, GetMaxHue, SetMaxHue); + DefineProp('MinSaturation', tkInteger, GetMinSat, SetMinSat); + DefineProp('MaxSaturation', tkInteger, GetMaxSat, SetMaxSat); + DefineProp('MinLuminance', tkInteger, GetMinLum, SetMinLum); + DefineProp('MaxLuminance', tkInteger, GetMaxLum, SetMaxLum); + DefineProp('UPRSampleDensity', tkInteger, GetUPRSampleDensity, SetUPRSampleDensity); + DefineProp('UPRFilterRadius', tkFloat, GetUPRFilterRadius, SetUPRFilterRadius); + DefineProp('UPROversample', tkInteger, GetUPROversample, SetUPROversample); + DefineProp('UPRAdjustDensity', tkVariant, GetUPRAdjustDensity, SetUPRAdjustDensity); + DefineProp('UPRColoringIdent', tkString, GetUPRColoringIdent, SetUPRColoringIdent); + DefineProp('UPRColoringFile', tkString, GetUPRColoringFile, SetUPRColoringFile); + DefineProp('UPRFormulaFile', tkString, GetUPRFormulaFile, SetUPRFormulaFile); + DefineProp('UPRFormulaIdent', tkString, GetUPRFormulaIdent, SetUPRFormulaIdent); + DefineProp('UPRWidth', tkInteger, GetUPRWidth, SetUPRWidth); + DefineProp('UPRHeight', tkInteger, GetUPRHeight, SetUPRHeight); + DefineProp('ExportRenderer', tkInteger, GetExportPath, SetExportPath); + end; + Scripter.AddObject('Options', Options); + + with Scripter.defineClass(TPivot) do + begin + DefineProp('Mode', tkInteger, GetPivotModeProc, SetPivotModeProc); + DefineProp('X', tkFloat, GetPivotXProc, SetPivotXProc); + DefineProp('Y', tkFloat, GetPivotYProc, SetPivotYProc); + DefineMethod('Set', 2, tkNone, nil, SetPivotProc); + DefineMethod('Reset', 0, tkNone, nil, ResetPivotProc); + end; + Scripter.AddObject('Pivot', Pivot); + + Scripter.AddComponent(OpenDialog); + Scripter.AddLibrary(TOperationLibrary); + Scripter.AddLibrary(TatClassesLibrary); + + { Variables and constants } + Scripter.AddConstant('PI', pi); + Scripter.AddConstant('NVARS', NRVAR); + Scripter.AddConstant('NumVariables', GetNrVariableNames); + Scripter.AddConstant('NXFORMS', NXFORMS); + Scripter.AddConstant('INSTALLPATH', ExtractFilePath(Application.exename)); + Scripter.AddConstant('SYM_NONE', 0); + Scripter.AddConstant('SYM_BILATERAL', 1); + Scripter.AddConstant('SYM_ROTATIONAL', 2); + { Variations } + Scripter.AddConstant('V_LINEAR', 0); + Scripter.AddConstant('V_SINUSOIDAL', 1); + Scripter.AddConstant('V_SPHERICAL', 2); + Scripter.AddConstant('V_SWIRL', 3); + Scripter.AddConstant('V_HORSESHOE', 4); + Scripter.AddConstant('V_POLAR', 5); + Scripter.AddConstant('V_HANDKERCHIEF', 6); + Scripter.AddConstant('V_HEART', 7); + Scripter.AddConstant('V_DISC', 8); + Scripter.AddConstant('V_SPIRAL', 9); + Scripter.AddConstant('V_HYPERBOLIC', 10); + Scripter.AddConstant('V_DIAMOND', 11); + Scripter.AddConstant('V_EX', 12); + Scripter.AddConstant('V_JULIA', 13); + Scripter.AddConstant('V_BENT', 14); + Scripter.AddConstant('V_WAVES', 15); + Scripter.AddConstant('V_FISHEYE', 16); + Scripter.AddConstant('V_POPCORN', 17); + Scripter.AddConstant('V_EXPONENTIAL', 18); + Scripter.AddConstant('V_POWER', 19); + Scripter.AddConstant('V_COSINE', 20); + Scripter.AddConstant('V_RINGS', 21); + Scripter.AddConstant('V_FAN', 22); + Scripter.AddConstant('V_EYEFISH', 23); + Scripter.AddConstant('V_BUBBLE', 24); + Scripter.AddConstant('V_CYLINDER', 25); + Scripter.AddConstant('V_NOISE', 26); + Scripter.AddConstant('V_BLUR', 27); + Scripter.AddConstant('V_GAUSSIANBLUR', 28); + Scripter.AddConstant('V_RADIALBLUR', 29); + Scripter.AddConstant('V_RINGS2', 30); + Scripter.AddConstant('V_FAN2', 31); + Scripter.AddConstant('V_BLOB', 32); + Scripter.AddConstant('V_PDJ', 33); + Scripter.AddConstant('V_PERSPECTIVE', 34); + Scripter.AddConstant('V_JULIAN', 35); + Scripter.AddConstant('V_JULIASCOPE', 36); + Scripter.AddConstant('V_CURL', 37); + Scripter.AddConstant('V_RANDOM', -1); +(* + { Variation parameters } + Scripter.AddConstant('RADIALBLUR_ANGLE', 0); + Scripter.AddConstant('RINGS2_VAL', 1); + Scripter.AddConstant('FAN2_X', 2); + Scripter.AddConstant('FAN2_Y', 3); + Scripter.AddConstant('BLOB_LOW', 4); + Scripter.AddConstant('BLOB_HI', 5); + Scripter.AddConstant('BLOB_WAVES', 6); + Scripter.AddConstant('PDJ_A', 7); + Scripter.AddConstant('PDJ_B', 8); + Scripter.AddConstant('PDJ_C', 9); + Scripter.AddConstant('PDJ_D', 10); + Scripter.AddConstant('PERSPECTIVE_ANGLE', 11); + Scripter.AddConstant('PERSPECTIVE_DIST', 12); + Scripter.AddConstant('JULIAN_POWER', 13); + Scripter.AddConstant('JULIAN_DIST', 14); + Scripter.AddConstant('JULIASCOPE_POWER', 15); + Scripter.AddConstant('JULIASCOPE_DIST', 16); + Scripter.AddConstant('CURL_C1', 17); + Scripter.AddConstant('CURL_C2', 18); +*) + { Variables } + Scripter.AddVariable('SelectedTransform', EditForm.SelectedTriangle); + Scripter.AddVariable('Compatibility', Compatibility); // obsolete + Scripter.AddVariable('ActiveTransform', ActiveTransform); + Scripter.AddVariable('UpdateFlame', UpdateIt); + Scripter.AddVariable('ResetLocation', ResetLocation); + Scripter.AddVariable('BatchIndex', RandomIndex); + Scripter.AddVariable('DateCode', RandomDate); + Scripter.AddVariable('Stopped', Stopped); + Scripter.AddVariable('ShowProgress', ShowProgress); + Scripter.AddVariable('CurrentFile', OpenFile); + Scripter.AddVariable('LimitVibrancy', LimitVibrancy); + + Scripter.AddLibrary(TMathLibrary); + Scripter.AddLibrary(TatMathLibrary); +// Scripter.AddLibrary(TatWindowsLibrary); + Scripter.AddLibrary(TatSysUtilsLibrary); + Scripter.AddLibrary(TatFileCtrlLibrary); + { Nonsense - it's the only way to get the last real + library to work! } + Scripter.AddObject('Not_Any_Thing_Useful', Another); + Scripter.AddObject('IglooFunkyRubber', Another); + Scripter.AddObject('Darn it', Another); + Scripter.AddObject('Scrumptious', Another); +end; + +{ ************************* Buttons ***************************************** } + +procedure TScriptEditor.btnNewClick(Sender: TObject); + +begin + Editor.Lines.Clear; + Caption := TextByKey('script-title'); //'New Script'; + Script := ''; +end; + +procedure TScriptEditor.LoadScriptFile(filename:string); +var + s: string; + fn:string; +begin + Editor.Lines.LoadFromFile(filename); + s := ExtractFileName(filename); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + MainForm.mnuRun.Caption := Format(TextByKey('main-menu-script-run2'), [s]); + Caption := s; +end; + +procedure TScriptEditor.OpenScript; +var + s: string; + fn:string; +begin + MainOpenDialog.InitialDir := ScriptPath; + MainOpenDialog.Filename := ''; + MainOpenDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*', [TextByKey('common-filter-script'), TextByKey('common-filter-allfiles')]); + if OpenSaveFileDialog(ScriptEditor, '.aposcript', MainOpenDialog.Filter, MainOpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then +// if MainOpenDialog.execute then + begin + MainOpenDialog.FileName := fn; + Script := MainOpenDialog.Filename; + Editor.Lines.LoadFromFile(MainOpenDialog.Filename); + s := ExtractFileName(MainOpenDialog.Filename); + s := Copy(s, 0, length(s) - Length(ExtractFileExt(s))); + MainForm.mnuRun.Caption := Format(TextByKey('main-menu-script-run2'), [s]); + Caption := s; + ScriptPath := ExtractFileDir(MainOpenDialog.Filename); + end; +end; + +procedure TScriptEditor.btnOpenClick(Sender: TObject); +begin + OpenScript; +end; + +procedure TScriptEditor.btnSaveClick(Sender: TObject); +var fn : string; +begin + if Script = '' then fn := '' else fn := ChangeFileExt(ExtractFileName(Script), '.aposcript'); + if OpenSaveFileDialog(ScriptEditor, '.aposcript', + Format('%s|*.aposcript;*.asc|%s|*.*', + [TextByKey('common-filter-script'), + TextByKey('common-filter-allfiles')]), + ScriptPath, TextByKey('common-browse'), fn, + false, true, false, false) then + //if MainSaveDialog.Execute then + begin + MainOpenDialog.FileName := fn; + Script := fn; + Editor.Lines.SaveToFile(fn); + Caption := ExtractFileName(fn); + ScriptPath := ExtractFileDir(fn); + end; +end; + +procedure TScriptEditor.FillFileList; +var + i, p: integer; + ext, Title: string; + FStrings: TStringList; +begin + FStrings := TStringList.Create; + FStrings.LoadFromFile(ParamFile); + try + FileList.Clear; + + ext := LowerCase(ExtractFileExt(ParamFile)); + (*if (ext = '.fla') or (ext = '.apo') then + begin + + // Get names from .fla or .apo file + if (Pos('{', FStrings.Text) <> 0) then + for i := 0 to FStrings.Count - 1 do + begin + p := Pos('{', FStrings[i]); + if (p <> 0) then + begin + Title := Trim(Copy(FStrings[i], 1, p - 1)); + if Title <> '' then + begin { Otherwise bad format } + FileList.Add(Trim(Copy(FStrings[i], 1, p - 1))); + end; + end; + end; + + end + else + + begin *) + // Get names from .flame file + if (Pos(' 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos(' 0) then + begin + pname := ''; + MainForm.ListXMLScanner.LoadFromBuffer(PANSICHAR(AnsiString(FSTrings[i]))); + MainForm.ListXMLScanner.Execute; + if Trim(pname) = '' then + Title := '*untitled ' + ptime + else + FileList.Add(pname); + end; + end; + + end; + //end; + finally + FStrings.Free; + end; +end; + +procedure TScriptEditor.RunScript; +var + lib: TStringList; +begin + + btnRun.Enabled := False; + btnBreak.Enabled := True; + MainForm.btnRunScript.Enabled := False; + MainForm.mnuRun.Enabled := False; + MainForm.DisableFavorites; + + ParamFile := OpenFile; + FillFileList; + { Set defaults } + { Set render defaults } + Renderer.Width := 320; + Renderer.Height := 240; + Stopped := False; + UpdateIt := True; + ResetLocation := False; + Console.Clear; + LastError := ''; + ActiveTransform := EditForm.SelectedTriangle; + NumTransforms := Transforms; + cp.copy(MainCp); + cmap := MainCp.cmap; + Application.ProcessMessages; + Randomize; + + // what in the sweet loving sake of jesus is this fuck? + if Pos('stopped', Lowercase(Editor.Lines.text)) <> 0 then + begin + btnStop.Enabled := True; + MainForm.mnuStop.Enabled := True; + MainForm.btnStopScript.Enabled := True; + end; + with Scripter do + begin + SourceCode.Assign(Editor.Lines); + if FileExists(defLibrary) then + begin + lib := TStringList.Create; + try + Lib.LoadFromFile(defLibrary); + with Scripts.Add do + begin + SourceCode := lib; + SelfRegisterAsLibrary('Functions'); + end; + finally + lib.free; + end; + end; + //Compile; + Execute; + end; + if (NumTransforms < 1) and UpdateIt then + begin + Console.Lines.Add('Not enough transforms.'); + ScriptRenderForm.Close; + btnRun.Enabled := True; + btnStop.Enabled := False; + MainForm.btnRunScript.Enabled := True; + MainForm.btnStopScript.Enabled := False; + MainForm.mnuRun.Enabled := True; + MainForm.mnuStop.Enabled := False; + btnBreak.Enabled := False; + Exit; + end + else + if (LastError = '') and UpdateIt then + begin + MainForm.UpdateUndo; + MainCp.Copy(cp); + UpdateFlame; + if ResetLocation then MainForm.ResetLocation; + end + else + begin + Console.Lines.Add(LastError); + end; + ScriptRenderForm.Close; + btnRun.Enabled := True; + btnStop.Enabled := False; + MainForm.btnRunScript.Enabled := True; + MainForm.btnStopScript.Enabled := False; + MainForm.mnuRun.Enabled := True; + MainForm.mnuStop.Enabled := False; + btnBreak.Enabled := False; + MainForm.EnableFavorites; +end; + +procedure TScriptEditor.btnRunClick(Sender: TObject); +begin + RunScript; +end; + +{ ****************************** Update flame ******************************* } + +procedure TScriptEditor.UpdateFlame; +begin + MainForm.StopThread; + MainForm.UpdateUndo; + MainCp.Copy(cp); +// MainCp.name := FlameName; + Transforms := MainCp.TrianglesFromCP(MainTriangles); + MainCp.AdjustScale(MainForm.Image.Width, MainForm.Image.Height); + if ResetLocation then MainCp.CalcBoundBox else + begin; + MainCp.Zoom := cp.zoom; + MainCp.center[0] := cp.center[0]; + MainCp.center[1] := cp.center[1]; + end; + MainCp.cmap := cp.cmap; + MainForm.RedrawTimer.enabled := true; + if EditForm.Visible then EditForm.UpdateDisplay; + if AdjustForm.Visible then AdjustForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; +end; + +{ ******************************* functions ********************************** } + + +{ ******************************* Parseing *********************************** } + +procedure copyxform(var dest: Txform; const source: TXform); +var + i: integer; +begin + dest.c[0, 0] := source.c[0, 0]; + dest.c[0, 1] := source.c[0, 1]; + dest.c[1, 0] := source.c[1, 0]; + dest.c[1, 1] := source.c[1, 1]; + dest.c[2, 0] := source.c[2, 0]; + dest.c[2, 1] := source.c[2, 1]; + dest.color := source.color; +// hmm, why no symmetry here? // dest.symmetry := source.symmetry; + dest.density := source.density; + for i := 0 to NRVAR - 1 do + dest.SetVariation(i, source.GetVariation(i)); +end; + +{ ************************ Editor Popup menu ********************************* } + +procedure TScriptEditor.mnuCutClick(Sender: TObject); +begin + Editor.CutToClipboard; +end; + +procedure TScriptEditor.mnuCopyClick(Sender: TObject); +begin + Editor.CopyToClipboard; +end; + +procedure TScriptEditor.mnuPasteClick(Sender: TObject); +begin + Editor.PasteFromClipboard; +end; + +procedure TScriptEditor.mnuUndoClick(Sender: TObject); +begin + if Editor.CanUndo then Editor.Undo; +end; + +procedure TScriptEditor.EditorChange(Sender: TObject); +begin + Editor.activeLine := -1; + if not Editor.CanUndo then mnuUndo.Enabled := false + else mnuUndo.Enabled := true; +end; + +procedure TScriptEditor.ScripterCompileError(Sender: TObject; + var msg: string; row, col: Integer; var ShowException: Boolean); +begin + Editor.ActiveLine := row - 1; + Console.Lines.Add('Line '+IntToStr(row)+' : '+msg); + ScriptRenderForm.Close; + btnRun.Enabled := True; + btnStop.Enabled := False; + MainForm.btnRunScript.Enabled := True; + MainForm.btnStopScript.Enabled := False; + MainForm.mnuRun.Enabled := True; + MainForm.mnuStop.Enabled := False; + btnBreak.Enabled := False; + ShowException := true; + Application.ProcessMessages; +end; + +procedure TScriptEditor.btnStopClick(Sender: TObject); +begin + Stopped := True; +end; + +procedure TScriptEditor.btnBreakClick(Sender: TObject); +begin + LastError := 'Execution stopped by user.'; + Scripter.Halt; +end; + +procedure TScriptEditor.btnFavoriteClick(Sender: TObject); +var + i: integer; + there: boolean; +begin + there := False; + for i := 0 to Favorites.Count - 1 do + if Lowercase(Script) = Favorites[i] then + There := true; + if there then exit; + Favorites.Add(Script); + Favorites.SaveToFile(GetEnvVarValue('APPDATA') + '\' + scriptFavsFilename); +end; + +procedure TScriptEditor.FormShortCut(var Msg: TWMKey; var Handled: Boolean); +begin + if GetKeyState(VK_CONTROL) >= 0 then + Exit; + + if Msg.CharCode = Ord('C') then begin + Editor.CopyToClipBoard; + Handled := True; + end; + + if Msg.CharCode = Ord('V') then begin + Editor.PasteFromClipBoard; + Handled := True; + end; + + if Msg.CharCode = Ord('X') then begin + Editor.CutToClipBoard; + Handled := True; + end; +end; + +procedure TScriptEditor.F2SXMLContent(Sender: TObject; Content: string); +begin +// +end; + +procedure TScriptEditor.F2SXMLEmptyTag(Sender: TObject; TagName: string; + Attributes: TAttrList); +var + i: integer; + v,w: TStringType; + d, floatcolor: double; + Tokens: TStringList; +begin + + Tokens := TStringList.Create; + try + if (TagName = 'xform') or (TagName = 'finalxform') then + Editor.Lines.Add(''); + if TagName = 'finalxform' then begin + Editor.Lines.Add('{ Final Transform }'); + Editor.Lines.Add('Flame.FinalXformEnabled := True;'); + Editor.Lines.Add('SetActiveTransform(transforms);'); + end else begin + w := TStringType('{ Transform ' + IntToStr(AddedXForms + 1)); + v := Attributes.Value('name'); + if (v <> '') then w := w + ' (' + v + ')'; + w := w + ' }'; + Editor.Lines.Add(String(w)); + Editor.Lines.Add('AddTransform;'); + end; + Editor.Lines.Add('with Transform do begin'); + //Editor.Lines.Add(' for i := 0 to NXFORMS do Chaos[i] := 1;'); + Editor.Lines.Add(' for i := 0 to NVARS do Variation[i] := 0;'); + + v := Attributes.Value('weight'); + if (v <> '') and (TagName = 'xform') then + Editor.Lines.Add(' Weight := ' + String(v) + ';'); + v := Attributes.Value('color'); + if (v <> '') then Editor.Lines.Add(' Color := ' + String(v) + ';'); + v := Attributes.Value('var_color'); + if (v <> '') then Editor.Lines.Add(' VarColor := ' + String(v) + ';'); + v := Attributes.Value('symmetry'); + if (v <> '') and (TagName = 'xform') then Editor.Lines.Add(' Symmetry := ' + String(v) + ';'); + v := Attributes.Value('coefs'); + if (v <> '') then begin + GetTokens(String(v), tokens); + Editor.Lines.Add(' a := ' + Tokens[0] + ';'); + Editor.Lines.Add(' b := ' + Tokens[2] + ';'); + Editor.Lines.Add(' c := ' + Tokens[1] + ';'); + Editor.Lines.Add(' d := ' + Tokens[3] + ';'); + Editor.Lines.Add(' e := ' + Tokens[4] + ';'); + Editor.Lines.Add(' f := ' + Tokens[5] + ';'); + end; + + v := Attributes.Value('post'); + if v <> '' then begin + GetTokens(String(v), tokens); + Editor.Lines.Add(' post[0,0] := ' + Tokens[0] + ';'); + Editor.Lines.Add(' post[0,1] := (-1) * ' + Tokens[1] + ';'); + Editor.Lines.Add(' post[1,0] := (-1) * ' + Tokens[2] + ';'); + Editor.Lines.Add(' post[1,1] := ' + Tokens[3] + ';'); + Editor.Lines.Add(' post[2,0] := ' + Tokens[4] + ';'); + Editor.Lines.Add(' post[2,1] := (-1) * ' + Tokens[5] + ';'); + end; + + + v := Attributes.Value('chaos'); + if v <> '' then begin + chaosLines.Add(''); + chaosLines.Add('{ Weight modifiers for transform ' + IntToStr(AddedXForms + 1) + ' }'); + chaosLines.Add('SetActiveTransform(' + IntToStr(AddedXForms) + ');'); + chaosLines.Add('with Transform do begin'); + GetTokens(String(v), tokens); + for i := 0 to Tokens.Count-1 do + chaosLines.Add(' chaos[' + IntToStr(i) + '] := ' + Tokens[i]) ; + chaosLines.Add('end;'); + end; + + v := Attributes.Value('opacity'); + if v <> '' then begin + Editor.Lines.Add(' Opacity := ' + String(v)); + end; + + for i := 0 to NRVAR - 1 do + begin + v := Attributes.Value(TStringType(varnames(i))); + if v <> '' then + Editor.Lines.Add(' ' + varnames(i) + ' := ' + String(v)); + end; + + for i := 0 to GetNrVariableNames - 1 do begin + v := Attributes.Value(TStringType(GetVariableNameAt(i))); + if v <> '' then begin + Editor.Lines.Add(' ' + GetVariableNameAt(i) + ' := ' + String(v)); + end; + end; + + Editor.Lines.Add('end;'); + AddedXForms := AddedXForms + 1; + finally + Tokens.free; + end; +end; + +procedure TScriptEditor.F2SXMLEndTag(Sender: TObject; TagName: string); +begin +// +end; + +procedure TScriptEditor.F2SXMLStartTag(Sender: TObject; TagName: string; + Attributes: TAttrList); +var + Tokens: TStringList; + v: TStringType; + f, b: double; +begin + Tokens := TStringList.Create; + try + + if TagName='flame' then + begin + AddedXForms := 0; + Editor.Lines.Add('{ Flame }'); + Editor.Lines.Add('Clear;'); + Editor.Lines.Add('if (pos(''7x'', LowerCase(ProgramVersionString)) >= 0) then'); + Editor.Lines.Add(' AngleTransform := 180 / PI else AngleTransform := 1;'); + Editor.Lines.Add('with Flame do begin'); + + v := Attributes.Value(TStringType('size')); + if (v <> '') then begin + GetTokens(String(v), tokens); + + Editor.Lines.Add(' Width := ' + Tokens[0] + ';'); + Editor.Lines.Add(' Height := ' + Tokens[1] + ';'); + + f := 100 / StrToFloat(Tokens[0]); + end else f := 0; + b := 0; + + v := Attributes.Value(TStringType('brightness')); + if (v <> '') then begin + Editor.Lines.Add(' Brightness := ' + String(v) + ';'); + b := StrToFloat(String(v)); + end; + v := Attributes.Value(TStringType('gamma')); + if (v <> '') then Editor.Lines.Add(' Gamma := ' + String(v) + ';'); + v := Attributes.Value(TStringType('vibrancy')); + if (v <> '') then Editor.Lines.Add(' Vibrancy := ' + String(v) + ';'); + v := Attributes.Value(TStringType('gamma_threshold')); + if (v <> '') then begin + if b <> 0 then b := StrToFloat(String(v)) / b; + Editor.Lines.Add(' GammaTreshold := ' + FloatToStr(b) + ';'); + end; + + v := Attributes.Value(TStringType('zoom')); + if (v <> '') then Editor.Lines.Add(' Zoom := ' + String(v) + ';'); + v := Attributes.Value(TStringType('scale')); + if (v <> '') then Editor.Lines.Add(' Scale := ' + FloatToStr(StrToFloat(String(v)) * f) + ';'); + v := Attributes.Value(TStringType('angle')); + if (v <> '') then Editor.Lines.Add(' Angle := ' + String(v) + ';'); + + // 3d + v := Attributes.Value(TStringType('cam_pitch')); + if (v <> '') then Editor.Lines.Add(' Pitch := ' + String(v) + ' * AngleTransform;'); + v := Attributes.Value(TStringType('cam_yaw')); + if (v <> '') then Editor.Lines.Add(' Yaw := ' + String(v) + ' * AngleTransform;'); + v := Attributes.Value(TStringType('cam_perspective')); + if (v <> '') then Editor.Lines.Add(' Perspective := ' + String(v) + ';'); + v := Attributes.Value(TStringType('cam_zpos')); + if (v <> '') then Editor.Lines.Add(' Z := ' + String(v) + ';'); + v := Attributes.Value(TStringType('cam_dof')); + if (v <> '') then Editor.Lines.Add(' DOF := ' + String(v) + ';'); + + try + v := Attributes.Value(TStringType('center')); + if (v <> '') then begin + GetTokens(String(v), tokens); + Editor.Lines.Add(' X := ' + Tokens[0] + ';'); + Editor.Lines.Add(' Y := ' + Tokens[1] + ';'); + end; + except + Editor.Lines.Add(' X := 0' + ';'); + Editor.Lines.Add(' Y := 0' + ';'); + end; + + try + v := Attributes.Value(TStringType('background')); + if (v <> '') then begin + GetTokens(String(v), tokens); + + Editor.Lines.Add(' Background[0] := ' + FloatToStr(Floor(StrToFloat(Tokens[0]) * 255)) + ';'); + Editor.Lines.Add(' Background[1] := ' + FloatToStr(Floor(StrToFloat(Tokens[1]) * 255)) + ';'); + Editor.Lines.Add(' Background[2] := ' + FloatToStr(Floor(StrToFloat(Tokens[2]) * 255)) + ';'); + end; + except + Editor.Lines.Add(' Background[0] := 0' + ';'); + Editor.Lines.Add(' Background[1] := 0' + ';'); + Editor.Lines.Add(' Background[2] := 0' + ';'); + end; + + v := Attributes.Value(TStringType('soloxform')); + if (v <> '') then Editor.Lines.Add('SoloXform := ' + String(v) + ';'); + + Editor.Lines.Add('end;'); + end; + finally + Tokens.free; + end; +end; + +procedure TScriptEditor.LoadRunAndClear(scriptFile:string); +begin + LoadScriptFile(scriptFile); + RunScript; + btnNewClick(btnNew); +end; + +end. + + diff --git a/Forms/ScriptRender.dfm b/Forms/ScriptRender.dfm new file mode 100644 index 0000000..1b60fcc --- /dev/null +++ b/Forms/ScriptRender.dfm @@ -0,0 +1,40 @@ +object ScriptRenderForm: TScriptRenderForm + Left = 390 + Top = 391 + BorderStyle = bsDialog + Caption = 'ScriptRenderForm' + ClientHeight = 58 + ClientWidth = 285 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnCreate = FormCreate + OnDestroy = FormDestroy + DesignSize = ( + 285 + 58) + PixelsPerInch = 96 + TextHeight = 13 + object btnCancel: TButton + Left = 96 + Top = 28 + Width = 95 + Height = 25 + Anchors = [akLeft, akRight, akBottom] + Caption = '&Cancel' + TabOrder = 0 + OnClick = btnCancelClick + end + object ProgressBar: TProgressBar + Left = 8 + Top = 8 + Width = 271 + Height = 13 + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + end +end diff --git a/Forms/ScriptRender.pas b/Forms/ScriptRender.pas new file mode 100644 index 0000000..a38725c --- /dev/null +++ b/Forms/ScriptRender.pas @@ -0,0 +1,172 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit ScriptRender; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ComCtrls, StdCtrls, RenderThread, cmap, ControlPoint, Translation; + +type + TScriptRenderForm = class(TForm) + btnCancel: TButton; + ProgressBar: TProgressBar; + procedure FormDestroy(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + private +// PixelsPerUnit: double; + StartTime: TDateTime; + Remainder: TDateTime; + + procedure HandleThreadCompletion(var Message: TMessage); + message WM_THREAD_COMPLETE; + procedure HandleThreadTermination(var Message: TMessage); + message WM_THREAD_TERMINATE; + public + Renderer: TRenderThread; + ColorMap: TColorMap; + cp: TControlPoint; + Filename: string; + ImageWidth, ImageHeight, Oversample: Integer; + zoom, Sample_Density, Brightness, Gamma, Vibrancy, Filter_Radius: double; + center: array[0..1] of double; + procedure OnProgress(prog: double); + procedure Render; + procedure SetRenderBounds; + end; + +var + ScriptRenderForm: TScriptRenderForm; + Cancelled: boolean; + +implementation + +uses Global, Math, FormRender, ScriptForm; +{$R *.DFM} + +procedure TScriptRenderForm.SetRenderBounds; +begin + cp.copy(ScriptEditor.cp); + //cp.Width := ScriptEditor.Renderer.Width; + //cp.Height := ScriptEditor.Renderer.Height; + cp.AdjustScale(ScriptEditor.Renderer.Width, ScriptEditor.Renderer.Height); + // --?-- cp.CalcBoundBox; + cp.center[0] := ScriptEditor.cp.center[0]; + cp.center[1] := ScriptEditor.cp.center[1]; + cp.zoom := ScriptEditor.cp.zoom; + //PixelsPerUnit := cp.Pixels_per_unit; +end; + +procedure TScriptRenderForm.Render; +begin + assert(not Assigned(Renderer)); + Renderer := TRenderThread.Create; + + Cancelled := False; + ScriptEditor.Scripter.Paused := True; + StartTime := Now; + Remainder := 1; + cp.copy(ScriptEditor.cp); + Filename := ScriptEditor.Renderer.Filename; + //cp.Width := ScriptEditor.Renderer.Width; + //cp.Height := ScriptEditor.Renderer.Height; + //cp.pixels_per_unit := PixelsPerUnit; + cp.AdjustScale(ScriptEditor.Renderer.Width, ScriptEditor.Renderer.Height); + cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(ScriptEditor.Renderer.FileName)) = '.PNG'); + + Renderer.OnProgress := OnProgress; +// Renderer.Compatibility := Compatibility; + Renderer.SetCP(cp); + if (ScriptEditor.Renderer.MaxMemory > 0) then Renderer.MaxMem := ScriptEditor.Renderer.MaxMemory; + Renderer.TargetHandle := Handle; + renderPath := ExtractFilePath(ScriptEditor.Renderer.Filename); + Renderer.Priority := tpLower; + Renderer.NrThreads := NrTreads; + Renderer.Resume; + +// Renderer.SaveImage(FileName); +// ScriptEditor.Scripter.Paused := False; +end; + +procedure TScriptRenderForm.OnProgress(prog: double); +var + Elapsed: TDateTime; +begin + prog := (Renderer.Slice + Prog) / Renderer.NrSlices; + ProgressBar.Position := round(100 * prog); + Elapsed := Now - StartTime; +// if prog > 0 then Remainder := Elapsed * (1/prog - 1); + //Application.ProcessMessages; +end; + +procedure TScriptRenderForm.FormDestroy(Sender: TObject); +begin + cp.free; + assert(not Assigned(Renderer)); //if Assigned(Renderer) then Renderer.free; +end; + +procedure TScriptRenderForm.FormCreate(Sender: TObject); +begin + //Renderer := TRenderThread.Create; + self.Caption := TextByKey('script-rendering'); + btnCancel.Caption := TextByKey('common-cancel'); + cp := TControlPoint.Create; +end; + +procedure TScriptRenderForm.btnCancelClick(Sender: TObject); +begin + ScriptEditor.Scripter.Halt; + Cancelled := True; +// Renderer.Stop; + if Assigned(Renderer) then begin + Renderer.Terminate; + Renderer.WaitFor; + Renderer.Free; + Renderer := nil; + end; + LastError := 'Render cancelled'; +end; + +procedure TScriptRenderForm.HandleThreadCompletion(var Message: TMessage); +begin + Renderer.SaveImage(FileName); + + Renderer.Free; + Renderer := nil; + + ScriptEditor.Scripter.Paused := False; +end; + +procedure TScriptRenderForm.HandleThreadTermination(var Message: TMessage); +begin + if Assigned(Renderer) then + begin + Renderer.Free; + Renderer := nil; + end; +end; + +end. + diff --git a/Forms/SplashForm.dfm b/Forms/SplashForm.dfm new file mode 100644 index 0000000..dc83f8d --- /dev/null +++ b/Forms/SplashForm.dfm @@ -0,0 +1,11305 @@ +object SplashWindow: TSplashWindow + Left = 0 + Top = 0 + BorderIcons = [] + BorderStyle = bsNone + Caption = 'Apophysis 7x' + ClientHeight = 300 + ClientWidth = 400 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + DesignSize = ( + 400 + 300) + PixelsPerInch = 96 + TextHeight = 13 + object BackgroundImage: TImage + Left = 0 + Top = 0 + Width = 400 + Height = 300 + Align = alClient + Picture.Data = { + 07544269746D6170767E0500424D767E05000000000036000000280000009001 + 00002C0100000100180000000000407E0500120B0000120B0000000000000000 + 00008F8F8F8A8A8A8484847E7E7E7B7B7B787878767676757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575757575757575 + 7575757575757575757575757575757575757575757575757575747474737373 + 727272717171717171727272747474767676949494B2B2B2ABABABA5A5A5A0A0 + A09C9C9C99999998989897979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979797979797979797979797979797979797979797 + 9797979797979797979797979796969694949492929290909090909091919176 + 7676999999BABABAB3B3B3AEAEAEA9A9A9A5A5A5A2A2A2A1A1A1A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A09E9E9E + 9B9B9B9898989696969494949494947676769E9E9EC1C1C1BABABAB6B6B6B1B1 + B1AEAEAEABABABA9A9A9A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8A8A8A8A8A8A8A6A6A6A2A2A29E9E9E9B9B9B99999997979779 + 7979A0A0A0C6C6C6C2C2C2BDBDBDBABABAB6B6B6B3B3B3B2B2B2B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B0B0B0AEAEAE + A9A9A9A5A5A5A2A2A29E9E9E9B9B9B7A7A7AA2A2A2C9C9C9C8C8C8C6C6C6C2C2 + C2BFBFBFBDBDBDBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBBBABABAB7B7B7B3B3B3ADADADA9A9A9A4A4A4A0A0A07E + 7E7EA2A2A2CBCBCBCACACAC9C9C9C8C8C8C6C6C6C4C4C4C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2 + C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2BEBEBE + B9B9B9B3B3B3AFAFAFA9A9A9A4A4A4818181A3A3A3CBCBCBCBCBCBCACACAC9C9 + C9C8C8C8C7C7C7C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 + C6C6C6C6C6C6C6C6C6C6C5C5C5C2C2C2BDBDBDB7B7B7B2B2B2ACACACA6A6A682 + 8282A3A3A3CCCCCCCBCBCBCACACAC9C9C9C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C6C6C6C4C4C4 + BEBEBEB8B8B8B3B3B3ACACACA7A7A7828282A3A3A3CCCCCCCBCBCBCACACAC9C9 + C9C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C6C6C6C4C4C4BEBEBEB8B8B8B3B3B3ACACACA7A7A782 + 8282A3A3A3CCCCCCCBCBCBCACACAC9C9C9C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C6C6C6C4C4C4 + BEBEBEB8B8B8B3B3B3ACACACA7A7A7828282A3A3A3CCCCCCCBCBCBCACACAC9C9 + C9C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C6C6C6C4C4C4BEBEBEB8B8B8B3B3B3ACACACA7A7A782 + 8282A3A3A3CCCCCCCBCBCBCACACAC9C9C9C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C6C6C6C4C4C4 + BEBEBEB8B8B8B3B3B3ACACACA7A7A7828282A4A4A4CDCDCDCCCCCCCBCBCBCACA + CAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5BFBFBFB9B9B9B4B4B4ADADADA8A8A883 + 8383A4A4A4CDCDCDCCCCCCCBCBCBCACACAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5 + BFBFBFB9B9B9B4B4B4ADADADA8A8A8838383A4A4A4CDCDCDCCCCCCCBCBCBCACA + CAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5BFBFBFB9B9B9B4B4B4ADADADA8A8A883 + 8383A4A4A4CDCDCDCCCCCCCBCBCBCACACAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5 + BFBFBFB9B9B9B4B4B4ADADADA8A8A8838383A4A4A4CDCDCDCCCCCCCBCBCBCACA + CAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5BFBFBFB9B9B9B4B4B4ADADADA8A8A883 + 8383A4A4A4CDCDCDCCCCCCCBCBCBCACACAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5 + BFBFBFB9B9B9B4B4B4ADADADA8A8A8838383A4A4A4CDCDCDCCCCCCCBCBCBCACA + CAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5BFBFBFB9B9B9B4B4B4ADADADA8A8A883 + 8383A4A4A4CDCDCDCCCCCCCBCBCBCACACAC9C9C9C9C9C9C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8 + C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C7C7C7C5C5C5 + BFBFBFB9B9B9B4B4B4ADADADA8A8A8838383A5A5A5CDCDCDCDCDCDCCCCCCCBCB + CBCACACACACACAC9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6C0C0C0BABABAB5B5B5AEAEAEA9A9A984 + 8484A5A5A5CDCDCDCDCDCDCCCCCCCBCBCBCACACACACACAC9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6 + C0C0C0BABABAB5B5B5AEAEAEA9A9A9848484A5A5A5CDCDCDCDCDCDCCCCCCCBCB + CBCACACACACACAC9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6C0C0C0BABABAB5B5B5AEAEAEA9A9A984 + 8484A5A5A5CDCDCDCDCDCDCCCCCCCBCBCBCACACACACACAC9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6 + C0C0C0BABABAB5B5B5AEAEAEA9A9A9848484A5A5A5CDCDCDCDCDCDCCCCCCCBCB + CBCACACACACACAC9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6C0C0C0BABABAB5B5B5AEAEAEA9A9A984 + 8484A5A5A5CDCDCDCDCDCDCCCCCCCBCBCBCACACACACACAC9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6 + C0C0C0BABABAB5B5B5AEAEAEA9A9A9848484A5A5A5CDCDCDCDCDCDCCCCCCCBCB + CBCACACACACACAC9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6C0C0C0BABABAB5B5B5AEAEAEA9A9A984 + 8484A5A5A5CDCDCDCDCDCDCCCCCCCBCBCBCACACACACACAC9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 + C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C8C8C8C6C6C6 + C0C0C0BABABAB5B5B5AEAEAEA9A9A9848484A6A6A6CECECECECECECDCDCDCCCC + CCCBCBCBCBCBCBCACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACAC9C9C9C7C7C7C1C1C1BBBBBBB5B5B5AFAFAFAAAAAA85 + 8585A6A6A6CECECECECECECDCDCDCCCCCCCBCBCBCBCBCBCACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACAC9C9C9C7C7C7 + C1C1C1BBBBBBB5B5B5AFAFAFAAAAAA858585A6A6A6CECECECECECECDCDCDCCCC + CCCBCBCBCBCBCBCACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACAC9C9C9C7C7C7C1C1C1BBBBBBB5B5B5AFAFAFAAAAAA85 + 8585A6A6A6CECECECECECECDCDCDCCCCCCCBCBCBCBCBCBCACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACAC9C9C9C7C7C7 + C1C1C1BBBBBBB5B5B5AFAFAFAAAAAA858585A6A6A6CECECECECECECDCDCDCCCC + CCCBCBCBCBCBCBCACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACAC9C9C9C7C7C7C1C1C1BBBBBBB5B5B5AFAFAFAAAAAA85 + 8585A6A6A6CECECECECECECDCDCDCCCCCCCBCBCBCBCBCBCACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACAC9C9C9C7C7C7 + C1C1C1BBBBBBB5B5B5AFAFAFAAAAAA858585A6A6A6CFCFCFCECECECECECECDCD + CDCCCCCCCCCCCCCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCACACAC8C8C8C2C2C2BCBCBCB6B6B6B0B0B0AAAAAA85 + 8585A6A6A6CFCFCFCECECECECECECDCDCDCCCCCCCCCCCCCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCACACAC8C8C8 + C2C2C2BCBCBCB6B6B6B0B0B0AAAAAA858585A6A6A6CFCFCFCECECECECECECDCD + CDCCCCCCCCCCCCCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCACACAC8C8C8C2C2C2BCBCBCB6B6B6B0B0B0AAAAAA85 + 8585A6A6A6CFCFCFCECECECECECECDCDCDCCCCCCCCCCCCCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCACACAC8C8C8 + C2C2C2BCBCBCB6B6B6B0B0B0AAAAAA858585A6A6A6CFCFCFCECECECECECECDCD + CDCCCCCCCCCCCCCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCACACAC8C8C8C2C2C2BCBCBCB6B6B6B0B0B0AAAAAA85 + 8585A6A6A6CFCFCFCECECECECECECDCDCDCCCCCCCCCCCCCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCACACAC8C8C8 + C2C2C2BCBCBCB6B6B6B0B0B0AAAAAA858585A7A7A7D0D0D0CFCFCFCFCFCFCECE + CECDCDCDCDCDCDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCBCBCBC9C9C9C3C3C3BDBDBDB7B7B7B1B1B1ABABAB86 + 8686A7A7A7D0D0D0CFCFCFCFCFCFCECECECDCDCDCDCDCDCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBC9C9C9 + C3C3C3BDBDBDB7B7B7B1B1B1ABABAB868686A7A7A7D0D0D0CFCFCFCFCFCFCECE + CECDCDCDCDCDCDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCBCBCBC9C9C9C3C3C3BDBDBDB7B7B7B1B1B1ABABAB86 + 8686A7A7A7D0D0D0CFCFCFCFCFCFCECECECDCDCDCDCDCDCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBC9C9C9 + C3C3C3BDBDBDB7B7B7B1B1B1ABABAB868686A7A7A7D0D0D0CFCFCFCFCFCFCECE + CECDCDCDCDCDCDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCBCBCBC9C9C9C3C3C3BDBDBDB7B7B7B1B1B1ABABAB86 + 8686A7A7A7D0D0D0CFCFCFCFCFCFCECECECDCDCDCDCDCDCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBC9C9C9 + C3C3C3BDBDBDB7B7B7B1B1B1ABABAB868686A8A8A8D1D1D1D0D0D0D0D0D0CFCF + CFCECECECECECECDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCCCCCCCACACAC4C4C4BEBEBEB8B8B8B2B2B2ACACAC86 + 8686A8A8A8D1D1D1D0D0D0D0D0D0CFCFCFCECECECECECECDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCCCCCCCACACA + C4C4C4BEBEBEB8B8B8B2B2B2ACACAC868686A8A8A8D1D1D1D0D0D0D0D0D0CFCF + CFCECECECECECECDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCCCCCCCACACAC4C4C4BEBEBEB8B8B8B2B2B2ACACAC86 + 8686A8A8A8D1D1D1D0D0D0D0D0D0CFCFCFCECECECECECECDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCCCCCCCACACA + C4C4C4BEBEBEB8B8B8B2B2B2ACACAC868686A8A8A8D1D1D1D0D0D0D0D0D0CFCF + CFCECECECECECECDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCCCCCCCACACAC4C4C4BEBEBEB8B8B8B2B2B2ACACAC86 + 8686A8A8A8D1D1D1D0D0D0D0D0D0CFCFCFCECECECECECECDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD + CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCCCCCCCACACA + C4C4C4BEBEBEB8B8B8B2B2B2ACACAC868686A9A9A9D2D2D2D1D1D1D0D0D0D0D0 + D0CFCFCFCFCFCFCECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECDCDCDCBCBCBC5C5C5BFBFBFB9B9B9B3B3B3ADADAD87 + 8787A9A9A9D2D2D2D1D1D1D0D0D0D0D0D0CFCFCFCFCFCFCECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECDCDCDCBCBCB + C5C5C5BFBFBFB9B9B9B3B3B3ADADAD878787A9A9A9D2D2D2D1D1D1D0D0D0D0D0 + D0CFCFCFCFCFCFCECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECDCDCDCBCBCBC5C5C5BFBFBFB9B9B9B3B3B3ADADAD87 + 8787A9A9A9D2D2D2D1D1D1D0D0D0D0D0D0CFCFCFCFCFCFCECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECDCDCDCBCBCB + C5C5C5BFBFBFB9B9B9B3B3B3ADADAD878787A9A9A9D2D2D2D1D1D1D0D0D0D0D0 + D0CFCFCFCFCFCFCECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECDCDCDCBCBCBC5C5C5BFBFBFB9B9B9B3B3B3ADADAD87 + 8787A9A9A9D2D2D2D1D1D1D0D0D0D0D0D0CFCFCFCFCFCFCECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECDCDCDCBCBCB + C5C5C5BFBFBFB9B9B9B3B3B3ADADAD878787AAAAAAD3D3D3D2D2D2D1D1D1D1D1 + D1D0D0D0D0D0D0CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCECECECCCCCCC6C6C6C0C0C0BABABAB3B3B3AEAEAE88 + 8888AAAAAAD3D3D3D2D2D2D1D1D1D1D1D1D0D0D0D0D0D0CFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCECECECCCCCC + C6C6C6C0C0C0BABABAB3B3B3AEAEAE888888AAAAAAD3D3D3D2D2D2D1D1D1D1D1 + D1D0D0D0D0D0D0CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCECECECCCCCCC6C6C6C0C0C0BABABAB3B3B3AEAEAE88 + 8888AAAAAAD3D3D3D2D2D2D1D1D1D1D1D1D0D0D0D0D0D0CFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCECECECCCCCC + C6C6C6C0C0C0BABABAB3B3B3AEAEAE888888AAAAAAD3D3D3D2D2D2D1D1D1D1D1 + D1D0D0D0D0D0D0CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCF + CFCFCFCFCFCFCFCFCFCFCECECECCCCCCC6C6C6C0C0C0BABABAB3B3B3AEAEAE88 + 8888AAAAAAD4D4D4D3D3D3D2D2D2D2D2D2D1D1D1D1D1D1D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFCDCDCD + C7C7C7C1C1C1BBBBBBB4B4B4AFAFAF888888AAAAAAD4D4D4D3D3D3D2D2D2D2D2 + D2D1D1D1D1D1D1D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0CFCFCFCDCDCDC7C7C7C1C1C1BBBBBBB4B4B4AFAFAF88 + 8888AAAAAAD4D4D4D3D3D3D2D2D2D2D2D2D1D1D1D1D1D1D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFCDCDCD + C7C7C7C1C1C1BBBBBBB4B4B4AFAFAF888888AAAAAAD4D4D4D3D3D3D2D2D2D2D2 + D2D1D1D1D1D1D1D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0CFCFCFCDCDCDC7C7C7C1C1C1BBBBBBB4B4B4AFAFAF88 + 8888AAAAAAD4D4D4D3D3D3D2D2D2D2D2D2D1D1D1D1D1D1D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFCDCDCD + C7C7C7C1C1C1BBBBBBB4B4B4AFAFAF888888AAAAAAD5D5D5D4D4D4D3D3D3D3D3 + D3D2D2D2D2D2D2D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D0D0D0CECECEC8C8C8C1C1C1BCBCBCB5B5B5AFAFAF89 + 8989AAAAAAD5D5D5D4D4D4D3D3D3D3D3D3D2D2D2D2D2D2D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0D0D0CECECE + C8C8C8C1C1C1BCBCBCB5B5B5AFAFAF898989AAAAAAD5D5D5D4D4D4D3D3D3D3D3 + D3D2D2D2D2D2D2D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D0D0D0CECECEC8C8C8C1C1C1BCBCBCB5B5B5AFAFAF89 + 8989AAAAAAD5D5D5D4D4D4D3D3D3D3D3D3D2D2D2D2D2D2D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0D0D0CECECE + C8C8C8C1C1C1BCBCBCB5B5B5AFAFAF898989AAAAAAD5D5D5D4D4D4D3D3D3D3D3 + D3D2D2D2D2D2D2D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D0D0D0CECECEC8C8C8C1C1C1BCBCBCB5B5B5AFAFAF89 + 8989ABABABD6D6D6D5D5D5D4D4D4D4D4D4D3D3D3D3D3D3D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1CFCFCF + C9C9C9C2C2C2BDBDBDB6B6B6B0B0B08A8A8AABABABD6D6D6D5D5D5D4D4D4D4D4 + D4D3D3D3D3D3D3D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D1D1D1CFCFCFC9C9C9C2C2C2BDBDBDB6B6B6B0B0B08A + 8A8AABABABD6D6D6D5D5D5D4D4D4D4D4D4D3D3D3D3D3D3D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1CFCFCF + C9C9C9C2C2C2BDBDBDB6B6B6B0B0B08A8A8AABABABD6D6D6D5D5D5D4D4D4D4D4 + D4D3D3D3D3D3D3D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D1D1D1CFCFCFC9C9C9C2C2C2BDBDBDB6B6B6B0B0B08A + 8A8AABABABD6D6D6D5D5D5D4D4D4D4D4D4D3D3D3D3D3D3D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1CFCFCF + C9C9C9C2C2C2BDBDBDB6B6B6B0B0B08A8A8AACACACD7D7D7D6D6D6D5D5D5D5D5 + D5D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D2D2D2D0D0D0CACACAC3C3C3BDBDBDB7B7B7B1B1B18A + 8A8AACACACD7D7D7D6D6D6D5D5D5D5D5D5D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D2D2D2D0D0D0 + CACACAC3C3C3BDBDBDB7B7B7B1B1B18A8A8AACACACD7D7D7D6D6D6D5D5D5D5D5 + D5D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D2D2D2D0D0D0CACACAC3C3C3BDBDBDB7B7B7B1B1B18A + 8A8AACACACD7D7D7D6D6D6D5D5D5D5D5D5D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D2D2D2D0D0D0 + CACACAC3C3C3BDBDBDB7B7B7B1B1B18A8A8AACACACD7D7D7D6D6D6D5D5D5D5D5 + D5D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D2D2D2D0D0D0CACACAC3C3C3BDBDBDB7B7B7B1B1B18A + 8A8AADADADD8D8D8D7D7D7D6D6D6D6D6D6D5D5D5D5D5D5D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D3D3D3D1D1D1 + CBCBCBC4C4C4BEBEBEB8B8B8B2B2B28B8B8BADADADD8D8D8D7D7D7D6D6D6D6D6 + D6D5D5D5D5D5D5D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D3D3D3D1D1D1CBCBCBC4C4C4BEBEBEB8B8B8B2B2B28B + 8B8BADADADD8D8D8D7D7D7D6D6D6D6D6D6D5D5D5D5D5D5D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D3D3D3D1D1D1 + CBCBCBC4C4C4BEBEBEB8B8B8B2B2B28B8B8BADADADD8D8D8D7D7D7D6D6D6D6D6 + D6D5D5D5D5D5D5D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D3D3D3D1D1D1CBCBCBC4C4C4BEBEBEB8B8B8B2B2B28B + 8B8BADADADD8D8D8D7D7D7D6D6D6D6D6D6D5D5D5D5D5D5D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D3D3D3D1D1D1 + CBCBCBC4C4C4BEBEBEB8B8B8B2B2B28B8B8BAEAEAED8D8D8D8D8D8D7D7D7D7D7 + D7D6D6D6D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D4D4D4D2D2D2CCCCCCC5C5C5BFBFBFB9B9B9B3B3B38C + 8C8CAEAEAED8D8D8D8D8D8D7D7D7D7D7D7D6D6D6D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D4D4D4D2D2D2 + CCCCCCC5C5C5BFBFBFB9B9B9B3B3B38C8C8CAEAEAED8D8D8D8D8D8D7D7D7D7D7 + D7D6D6D6D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D4D4D4D2D2D2CCCCCCC5C5C5BFBFBFB9B9B9B3B3B38C + 8C8CAEAEAED8D8D8D8D8D8D7D7D7D7D7D7D6D6D6D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D4D4D4D2D2D2 + CCCCCCC5C5C5BFBFBFB9B9B9B3B3B38C8C8CAEAEAED9D9D9D9D9D9D8D8D8D8D8 + D8D7D7D7D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D5D5D5D3D3D3CDCDCDC6C6C6C0C0C0B9B9B9B4B4B48C + 8C8CAEAEAED9D9D9D9D9D9D8D8D8D8D8D8D7D7D7D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D5D5D5D3D3D3 + CDCDCDC6C6C6C0C0C0B9B9B9B4B4B48C8C8CAEAEAED9D9D9D9D9D9D8D8D8D8D8 + D8D7D7D7D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D5D5D5D3D3D3CDCDCDC6C6C6C0C0C0B9B9B9B4B4B48C + 8C8CAEAEAED9D9D9D9D9D9D8D8D8D8D8D8D7D7D7D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D5D5D5D3D3D3 + CDCDCDC6C6C6C0C0C0B9B9B9B4B4B48C8C8CAEAEAED9D9D9D9D9D9D8D8D8D8D8 + D8D7D7D7D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6 + D6D6D6D6D6D6D6D6D6D6D5D5D5D3D3D3CDCDCDC6C6C6C0C0C0B9B9B9B4B4B48C + 8C8CAFAFAFDADADADADADAD9D9D9D9D9D9D8D8D8D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D6D6D6D4D4D4 + CECECEC7C7C7C1C1C1BABABAB4B4B48D8D8DAFAFAFDADADADADADAD9D9D9D9D9 + D9D8D8D8D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D6D6D6D4D4D4CECECEC7C7C7C1C1C1BABABAB4B4B48D + 8D8DAFAFAFDADADADADADAD9D9D9D9D9D9D8D8D8D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D6D6D6D4D4D4 + CECECEC7C7C7C1C1C1BABABAB4B4B48D8D8DAFAFAFDADADADADADAD9D9D9D9D9 + D9D8D8D8D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7 + D7D7D7D7D7D7D7D7D7D7D6D6D6D4D4D4CECECEC7C7C7C1C1C1BABABAB4B4B48D + 8D8DB0B0B0DBDBDBDBDBDBDADADADADADAD9D9D9D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D7D7D7D5D5D5 + CFCFCFC8C8C8C2C2C2BBBBBBB5B5B58E8E8EB0B0B0DBDBDBDBDBDBDADADADADA + DAD9D9D9D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D7D7D7D5D5D5CFCFCFC8C8C8C2C2C2BBBBBBB5B5B58E + 8E8EB0B0B0DBDBDBDBDBDBDADADADADADAD9D9D9D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D7D7D7D5D5D5 + CFCFCFC8C8C8C2C2C2BBBBBBB5B5B58E8E8EB0B0B0DBDBDBDBDBDBDADADADADA + DAD9D9D9D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D7D7D7D5D5D5CFCFCFC8C8C8C2C2C2BBBBBBB5B5B58E + 8E8EB0B0B0DBDBDBDBDBDBDADADADADADAD9D9D9D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D7D7D7D5D5D5 + CFCFCFC8C8C8C2C2C2BBBBBBB5B5B58E8E8EB1B1B1DCDCDCDCDCDCDBDBDBDADA + DADADADAD9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D8D8D8D6D6D6D0D0D0C9C9C9C3C3C3BCBCBCB6B6B68E + 8E8EB1B1B1DCDCDCDCDCDCDBDBDBDADADADADADAD9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D8D8D8D6D6D6 + D0D0D0C9C9C9C3C3C3BCBCBCB6B6B68E8E8EB1B1B1DCDCDCDCDCDCDBDBDBDADA + DADADADAD9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D8D8D8D6D6D6D0D0D0C9C9C9C3C3C3BCBCBCB6B6B68E + 8E8EB1B1B1DCDCDCDCDCDCDBDBDBDADADADADADAD9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9 + D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D8D8D8D6D6D6 + D0D0D0C9C9C9C3C3C3BCBCBCB6B6B68E8E8EB1B1B1DDDDDDDCDCDCDCDCDCDBDB + DBDBDBDBDADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADAD9D9D9D7D7D7D1D1D1CACACAC4C4C4BDBDBDB7B7B78F + 8F8FB1B1B1DDDDDDDCDCDCDCDCDCDBDBDBDBDBDBDADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADAD9D9D9D7D7D7 + D1D1D1CACACAC4C4C4BDBDBDB7B7B78F8F8FB1B1B1DDDDDDDCDCDCDCDCDCDBDB + DBDBDBDBDADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADAD9D9D9D7D7D7D1D1D1CACACAC4C4C4BDBDBDB7B7B78F + 8F8FB1B1B1DDDDDDDCDCDCDCDCDCDBDBDBDBDBDBDADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADAD9D9D9D7D7D7 + D1D1D1CACACAC4C4C4BDBDBDB7B7B78F8F8FB2B2B2DEDEDEDDDDDDDDDDDDDCDC + DCDCDCDCDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDADADAD8D8D8D2D2D2CBCBCBC5C5C5BEBEBEB8B8B88F + 8F8FB2B2B2DEDEDEDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDADADAD8D8D8 + D2D2D2CBCBCBC5C5C5BEBEBEB8B8B88F8F8FB2B2B2DEDEDEDDDDDDDDDDDDDCDC + DCDCDCDCDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDADADADADADAD9D9D9D8D8D8D7D7D7D7D7D7D7D7 + D7D7D7D7D8D8D8D9D9D9DADADADADADADBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDADADADADADAD9D9D9D8D8D8D7D7D7D7D7D7D7D7 + D7D7D7D7D8D8D8D9D9D9DADADADADADADBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDADADADADA + DAD9D9D9D8D8D8D7D7D7D6D6D6D6D6D6D7D7D7D8D8D8D8D8D8DADADADADADADB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDADADAD8D8D8D2D2D2CBCBCBC5C5C5BEBEBEB8B8B88F + 8F8FB2B2B2DEDEDEDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDADADAD8 + D8D8D5D5D5D2D2D2CECECECDCDCDCDCDCDCECECED2D2D2D5D5D5D8D8D8DADADA + DADADADBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDADADAD8 + D8D8D5D5D5D2D2D2CECECECDCDCDCDCDCDCECECED2D2D2D5D5D5D8D8D8DADADA + DADADADBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDADADAD8D8D8D6D6D6D2D2D2CFCFCFCDCDCDCCCCCC + CDCDCDD0D0D0D3D3D3D6D6D6D8D8D8DADADADBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDADADAD8D8D8 + D2D2D2CBCBCBC5C5C5BEBEBEB8B8B88F8F8FB2B2B2DEDEDEDDDDDDDDDDDDDCDC + DCDCDCDCDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDADADAD8D8D8D5D5D5CFCFCFC8C8C8C2C2C2BFBFBFBEBE + BEC1C1C1C8C8C8CFCFCFD4D4D4D8D8D8DADADADBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDADADAD8D8D8D5D5D5CFCFCFC8C8C8C2C2C2BFBFBFBEBE + BEC1C1C1C8C8C8CFCFCFD4D4D4D8D8D8DADADADBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBD9D9D9D7D7 + D7D2D2D2CCCCCCC4C4C4C0C0C0BEBEBEBEBEBEC3C3C3CACACAD1D1D1D5D5D5D9 + D9D9DADADADBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB + DBDBDBDBDBDBDBDBDBDBDADADAD8D8D8D2D2D2CBCBCBC5C5C5BEBEBEB8B8B88F + 8F8FB2B2B2DFDFDFDEDEDEDEDEDEDDDDDDDDDDDDDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDBDBDBD8D8D8D1 + D1D1C8C8C8BCBCBCB2B2B2ADADADADADADB2B2B2BCBCBCC7C7C7D1D1D1D7D7D7 + DBDBDBDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDBDBDBD8D8D8D1 + D1D1C8C8C8BCBCBCB2B2B2ADADADADADADB2B2B2BCBCBCC7C7C7D1D1D1D7D7D7 + DBDBDBDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCD9D9D9D5D5D5CECECEC4C4C4B8B8B8AEAEAEAAAAAA + ACACACB2B2B2BEBEBEC9C9C9D2D2D2D8D8D8DBDBDBDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDBDBDBD9D9D9 + D3D3D3CCCCCCC6C6C6BFBFBFB9B9B9909090B2B2B2DFDFDFDEDEDEDEDEDEDDDD + DDDDDDDDDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDBDBDBD5D5D5CCCCCCBEBEBEADADAD9D9D9D9494949494 + 949B9B9BACACACBDBDBDCBCBCBD4D4D4DADADADCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDBDBDBD5D5D5CCCCCCBEBEBEADADAD9D9D9D9494949494 + 949B9B9BACACACBDBDBDCBCBCBD4D4D4DADADADCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDBDBDBD9D9D9D3D3 + D3C8C8C8B9B9B9A8A8A89A9A9A9393939393939C9C9CACACACBCBCBCCBCBCBD4 + D4D4DADADADCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDBDBDBD9D9D9D3D3D3CCCCCCC6C6C6BFBFBFB9B9B990 + 9090B2B2B2DFDFDFDEDEDEDEDEDEDDDDDDDDDDDDDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDADADAD3D3D3C6 + C6C6B6B6B6A0A0A08B8B8B8181818181818B8B8B9E9E9EB4B4B4C6C6C6D3D3D3 + D9D9D9DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDADADAD3D3D3C6 + C6C6B6B6B6A0A0A08B8B8B8181818181818B8B8B9E9E9EB4B4B4C6C6C6D3D3D3 + D9D9D9DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCD9D9D9D2D2D2C6C6C6B4B4B4A0A0A08C8C8C818181 + 8080808888889A9A9AAFAFAFC2C2C2CFCFCFD8D8D8DBDBDBDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDBDBDBD9D9D9 + D3D3D3CCCCCCC6C6C6BFBFBFB9B9B9909090B2B2B2DFDFDFDEDEDEDEDEDEDDDD + DDDDDDDDDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCD9D9D9D2D2D2C4C4C4B0B0B09696967F7F7F7373737373 + 737E7E7E949494AEAEAEC3C3C3D1D1D1D9D9D9DCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCD9D9D9D2D2D2C4C4C4B0B0B09696967F7F7F7373737373 + 737E7E7E949494AEAEAEC3C3C3D1D1D1D9D9D9DCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD9D9D9D3D3 + D3C6C6C6B4B4B49D9D9D8686867676767171717878788A8A8AA2A2A2B9B9B9C9 + C9C9D5D5D5DADADADCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDBDBDBD9D9D9D3D3D3CCCCCCC6C6C6BFBFBFB9B9B990 + 9090B3B3B3E0E0E0DFDFDFDFDFDFDEDEDEDEDEDEDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADADAD9D9D9DE + DEDEDEDEDEDEDEDEDEDEDEAEAEAE7070707676768E8E8EABABABC1C1C1D1D1D1 + DADADADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADADAD9D9D9DE + DEDEDEDEDEDEDEDEDEDEDEAEAEAE7070707676768E8E8EABABABC1C1C1D1D1D1 + DADADADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDEDEDEDEDEDEDEDEDEDEDEDED2D2D2A3A3A3 + 6A6A6A6C6C6C7D7D7D959595AEAEAEC3C3C3D2D2D2DADADADCDCDCDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCDADADA + D3D3D3CDCDCDC6C6C6C0C0C0B9B9B9919191B3B3B3E0E0E0DFDFDFDFDFDFDEDE + DEDEDEDEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDCDCDCBDBDBD8A8A8A8A8A8A8A8A8A8A8A8AB7B7B79E9E + 9E7272728C8C8CA9A9A9C0C0C0D0D0D0DADADADDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDCDCDCBDBDBD8A8A8A8A8A8A8A8A8A8A8A8AB7B7B79E9E + 9E7272728C8C8CA9A9A9C0C0C0D0D0D0DADADADDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEDEDEC8C8C88A8A + 8A8A8A8A8A8A8A8A8A8A959595D1D1D1676767666666727272898989A3A3A3BA + BABACDCDCDD7D7D7DCDCDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDCDCDCDADADAD3D3D3CDCDCDC6C6C6C0C0C0B9B9B991 + 9191B3B3B3E0E0E0DFDFDFDFDFDFDEDEDEDEDEDEDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCBEBEBE8B + 8B8B8B8B8B8B8B8B8B8B8BB8B8B89E9E9E7272728C8C8CA8A8A8BFBFBFCDCDCD + D7D7D7D9D9D9D8D8D8D7D7D7D7D7D7D8D8D8D9D9D9DADADADBDBDBDCDCDCDCDC + DCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDADADA + DADADAD9D9D9D7D7D7D7D7D7D7D7D7D8D8D8D9D9D9DADADADADADADCDCDCDCDC + DCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCBEBEBE8B + 8B8B8B8B8B8B8B8B8B8B8BB8B8B89E9E9E7272728C8C8CA8A8A8BFBFBFCDCDCD + D7D7D7D9D9D9D8D8D8D7D7D7D7D7D7D8D8D8D9D9D9DADADADBDBDBDCDCDCDCDC + DCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDFDFDFA2A2A28B8B8B8B8B8B8B8B8B8B8B8BC4C4C4 + 9393936565656B6B6B7E7E7E989898B1B1B1C5C5C5D3D3D3DADADADCDCDCDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDCDCDCDCDCDCDCDCDCDADADADADADAD9D9D9D8D8D8D7D7D7 + D7D7D7D7D7D7D7D7D7D8D8D8DADADADADADADBDBDBDCDCDCDCDCDCDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDCDCDCDCDCDCDCDCDCDADADADADADAD9D9D9D8D8D8D7D7D7D7D7D7D7D7 + D7D7D7D7D8D8D8DADADADADADADBDBDBDCDCDCDCDCDCDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCDADADA + D3D3D3CDCDCDC6C6C6C0C0C0B9B9B9919191B3B3B3E0E0E0DFDFDFDFDFDFDEDE + DEDEDEDEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDADADA + D9D9D9D8D8D8D8D8D8D9D9D9DADADADADADADCDCDCDCDCDCDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDADADAD9D9D9D8D8D8D8D8D8 + D9D9D9DADADADADADADDDDDDBFBFBF8C8C8C8C8C8C8C8C8C8C8C8CB9B9B99E9E + 9E707070898989A4A4A4B8B8B8C6C6C6CDCDCDCDCDCDCCCCCCCBCBCBCBCBCBCD + CDCDCECECED2D2D2D4D4D4D7D7D7DADADADBDBDBDCDCDCDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDC + DCDCDCDCDADADAD8D8D8D5D5D5D2D2D2CFCFCFCDCDCDCCCCCCCACACACBCBCBCC + CCCCCECECED1D1D1D3D3D3D6D6D6D9D9D9DADADADCDCDCDCDCDCDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDBFBFBF8C8C8C8C8C8C8C8C8C8C8C8CB9B9B99E9E + 9E707070898989A4A4A4B8B8B8C6C6C6CDCDCDCDCDCDCCCCCCCBCBCBCBCBCBCD + CDCDCECECED2D2D2D4D4D4D7D7D7DADADADBDBDBDCDCDCDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDADADAD9D9D9D9D9 + D9D9D9D9D9D9D9DADADADBDBDBDCDCDCDCDCDCDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDADADAD9D9D9D9D9D9D9D9D9D9D9D9 + DADADADBDBDBDCDCDCDCDCDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDFDFDFBFBF + BF8C8C8C8C8C8C8C8C8C8C8C8CA3A3A3C4C4C46767676767677474748C8C8CA6 + A6A6BDBDBDCDCDCDD8D8D8DCDCDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDADADAD8D8D8D5D5 + D5D3D3D3D0D0D0CECECECDCDCDCBCBCBCACACACACACACBCBCBCDCDCDCFCFCFD2 + D2D2D4D4D4D7D7D7DADADADBDBDBDCDCDCDCDCDCDDDDDDDDDDDDDDDDDDDDDDDD + DCDCDCDCDCDCDBDBDBDADADADADADAD9D9D9D9D9D9D9D9D9DADADADBDBDBDCDC + DCDCDCDCDDDDDDDDDDDDDCDCDCDCDCDCDBDBDBDADADAD8D8D8D5D5D5D3D3D3D0 + D0D0CECECECDCDCDCBCBCBCACACACACACACBCBCBCDCDCDCFCFCFD2D2D2D4D4D4 + D7D7D7DADADADBDBDBDCDCDCDCDCDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDC + DCDCDCDCDCDBDBDBDADADAD9D9D9D8D8D8D8D8D8D9D9D9DADADADADADADCDCDC + DCDCDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDCDCDCDCDCDADADADADADAD9 + D9D9D8D8D8D8D8D8D9D9D9DADADADBDBDBDCDCDCDCDCDCDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDC + DCDCDCDCDBDBDBDADADAD9D9D9D8D8D8D8D8D8D8D8D8D9D9D9DADADADBDBDBDC + DCDCDCDCDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD + DDDDDDDDDDDDDDDDDDDDDCDCDCDADADAD3D3D3CDCDCDC6C6C6C0C0C0B9B9B991 + 9191B4B4B4E1E1E1E0E0E0E0E0E0DFDFDFDFDFDFDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDDDDDDDBDBDBD9D9D9D5D5D5D2D2D2D0D0D0CECECED0D0D0D3D3D3D5 + D5D5D9D9D9DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDCDCDCDBDB + DBD7D7D7D3D3D3D0D0D0CECECECECECED0D0D0D4D4D4D8D8D8DDDDDDC1C1C18C + 8C8C8C8C8C8C8C8C8C8C8CBBBBBB9F9F9F6D6D6D8383839C9C9CAEAEAEB9B9B9 + BEBEBEBCBCBCB9B9B9B9B9B9B9B9B9BBBBBBBEBEBEC3C3C3C8C8C8CDCDCDD3D3 + D3D8D8D8DBDBDBDDDDDDDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDDDDDDDDDDDDDBDBDBD8D8D8D4D4D4CFCFCFCACACAC5C5C5 + C0C0C0BBBBBBB9B9B9B9B9B9B9B9B9BABABABEBEBEC1C1C1C6C6C6CCCCCCD2D2 + D2D6D6D6DADADADCDCDCDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDFDFDFC1C1C18C + 8C8C8C8C8C8C8C8C8C8C8CBBBBBB9F9F9F6D6D6D8383839C9C9CAEAEAEB9B9B9 + BEBEBEBCBCBCB9B9B9B9B9B9B9B9B9BBBBBBBEBEBEC3C3C3C8C8C8CDCDCDD3D3 + D3D8D8D8DBDBDBDDDDDDDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDD + DDDDDBDBDBD8D8D8D4D4D4D1D1D1D0D0D0D0D0D0D1D1D1D4D4D4D8D8D8DBDBDB + DDDDDDDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD8D8 + D8D4D4D4D1D1D1D0D0D0D0D0D0D1D1D1D4D4D4D8D8D8DBDBDBDDDDDDDDDDDDDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEE3E3E39898988C8C8C8C8C8C8C8C8C8C8C8C + D2D2D28585856767676E6E6E8282829C9C9CB4B4B4C8C8C8D5D5D5DBDBDBDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDB + DBDBDADADAD6D6D6D3D3D3CECECECACACAC5C5C5C0C0C0BEBEBEBABABAB9B9B9 + B8B8B8B8B8B8B9B9B9BBBBBBBEBEBEC3C3C3C7C7C7CDCDCDD2D2D2D6D6D6DADA + DADCDCDCDDDDDDDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD8D8D8D5D5D5D2D2D2D0 + D0D0D0D0D0D1D1D1D4D4D4D8D8D8DBDBDBDDDDDDDDDDDDDDDDDDDBDBDBDADADA + D6D6D6D3D3D3CECECECACACAC5C5C5C0C0C0BEBEBEBABABAB9B9B9B8B8B8B8B8 + B8B9B9B9BBBBBBBEBEBEC3C3C3C7C7C7CDCDCDD2D2D2D6D6D6DADADADCDCDCDD + DDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD8D8D8D5D5D5D1D1D1CFCF + CFCECECED0D0D0D3D3D3D5D5D5D9D9D9DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DDDDDDDCDCDCDBDBDBD7D7D7D3D3D3D0D0D0CECECECECECED0D0D0D3D3D3D7D7 + D7DADADADCDCDCDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDDDDDDDDDDDDDBDBDBD8D8D8D4D4D4D0D0D0CECECE + CDCDCDCECECED1D1D1D5D5D5D8D8D8DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDB + D4D4D4CDCDCDC7C7C7C0C0C0BABABA929292B4B4B4E1E1E1E0E0E0E0E0E0DFDF + DFDFDFDFDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDCDCDCD9D9D9D4D4D4CDCDCD + C6C6C6C1C1C1C0C0C0C0C0C0C6C6C6CDCDCDD4D4D4D8D8D8DCDCDCDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDDDDDDDADADAD5D5D5CFCFCFC7C7C7C2C2C2BFBFBFC0C0C0 + C3C3C3CACACAD1D1D1DBDBDBC2C2C28D8D8D8D8D8D8D8D8D8D8D8DBCBCBC9E9E + 9E6868687A7A7A8F8F8F9C9C9CA4A4A4A6A6A6A4A4A4A0A0A09E9E9E9F9F9FA1 + A1A1A6A6A6ADADADB5B5B5BEBEBEC6C6C6CECECED5D5D5D9D9D9DCDCDCDDDDDD + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDCDCDCDADADAD5D5 + D5D0D0D0C8C8C8C0C0C0B7B7B7AFAFAFA9A9A9A4A4A49F9F9F9E9E9E9E9E9EA1 + A1A1A5A5A5ACACACB2B2B2BBBBBBC3C3C3CCCCCCD3D3D3D8D8D8DBDBDBDDDDDD + DEDEDEDEDEDEDEDEDEDFDFDFC2C2C28D8D8D8D8D8D8D8D8D8D8D8DBCBCBC9E9E + 9E6868687A7A7A8F8F8F9C9C9CA4A4A4A6A6A6A4A4A4A0A0A09E9E9E9F9F9FA1 + A1A1A6A6A6ADADADB5B5B5BEBEBEC6C6C6CECECED5D5D5D9D9D9DCDCDCDDDDDD + DEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD8D8D8D2D2D2CBCBCBC5C5C5C1C1 + C1C0C0C0C4C4C4CBCBCBD2D2D2D7D7D7DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDDDDDDDBDBDBD8D8D8D2D2D2CBCBCBC5C5C5C1C1C1C0C0C0C4C4C4 + CBCBCBD2D2D2D7D7D7DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEE1E1 + E1C2C2C28D8D8D8D8D8D8D8D8D8D8D8DB0B0B0B7B7B76868686868687777778F + 8F8FAAAAAAC0C0C0D0D0D0DADADADDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD8D8D8D3D3D3CDCDCDC6C6C6BEBEBEB6B6 + B6B0B0B0AAAAAAA5A5A5A1A1A19E9E9E9E9E9E9E9E9E9E9E9EA2A2A2A6A6A6AC + ACACB3B3B3BBBBBBC4C4C4CCCCCCD3D3D3D8D8D8DBDBDBDDDDDDDEDEDEDDDDDD + DBDBDBD8D8D8D3D3D3CCCCCCC6C6C6C2C2C2C1C1C1C5C5C5CBCBCBD2D2D2D7D7 + D7DBDBDBDCDCDCDBDBDBD8D8D8D3D3D3CDCDCDC6C6C6BEBEBEB6B6B6B0B0B0AA + AAAAA5A5A5A1A1A19E9E9E9E9E9E9E9E9E9E9E9EA2A2A2A6A6A6ACACACB3B3B3 + BBBBBBC4C4C4CCCCCCD3D3D3D8D8D8DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDC + DCDCD8D8D8D4D4D4CDCDCDC6C6C6C0C0C0BFBFBFC0C0C0C6C6C6CDCDCDD3D3D3 + D8D8D8DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD7D7D7D1D1D1CBCBCBC3 + C3C3C0C0C0BFBFBFC1C1C1C6C6C6CDCDCDD4D4D4D9D9D9DCDCDCDDDDDDDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDB + DBD5D5D5D0D0D0C8C8C8C2C2C2BEBEBEBEBEBEC0C0C0C6C6C6CDCDCDD4D4D4D9 + D9D9DCDCDCDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD4D4D4CDCDCDC7C7C7C0C0C0BABABA92 + 9292B4B4B4E1E1E1E0E0E0E0E0E0DFDFDFDFDFDFDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDBDBDBD6D6D6CFCFCFC5C5C5B9B9B9AFAFAFACACACADADADB4B4B4C0 + C0C0CBCBCBD4D4D4DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD6D6D6CECE + CEC3C3C3B8B8B8AEAEAEABABABACACACB3B3B3BEBEBECACACAD9D9D9C3C3C38E + 8E8E8E8E8E8E8E8E8E8E8EBDBDBD9C9C9C6060606E6E6E7E7E7E8888888D8D8D + 8E8E8E8A8A8A8686868484848484848686868B8B8B9292929C9C9CA7A7A7B3B3 + B3C0C0C0CBCBCBD3D3D3D8D8D8DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDDDDDDDCDCDCD9D9D9D4D4D4CCCCCCC1C1C1B6B6B6ABABAB9E9E9E959595 + 8E8E8E8888888484848383838383838585858A8A8A919191999999A4A4A4B0B0 + B0BBBBBBC6C6C6D0D0D0D7D7D7DBDBDBDDDDDDDEDEDEDEDEDEE0E0E0C3C3C38E + 8E8E8E8E8E8E8E8E8E8E8EBDBDBD9C9C9C6060606E6E6E7E7E7E8888888D8D8D + 8E8E8E8A8A8A8686868484848484848686868B8B8B9292929C9C9CA7A7A7B3B3 + B3C0C0C0CBCBCBD3D3D3D8D8D8DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDDDDDDDA + DADAD3D3D3CACACABEBEBEB3B3B3AEAEAEAEAEAEB3B3B3BEBEBEC9C9C9D3D3D3 + D9D9D9DDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDADADAD3D3D3CACA + CABEBEBEB3B3B3AEAEAEAEAEAEB3B3B3BEBEBEC9C9C9D3D3D3D9D9D9DDDDDDDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDFDFDFE1E1E19494948E8E8E8E8E8E8E8E8E + 8E8E8EE1E1E17070706565656E6E6E8383839E9E9EB8B8B8CACACAD6D6D6DCDC + DCDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDCDCDCD8D8D8D3 + D3D3CACACABEBEBEB3B3B3A8A8A89E9E9E9494948E8E8E8A8A8A858585838383 + 8282828282828484848787878C8C8C9292929B9B9BA5A5A5B1B1B1BCBCBCC7C7 + C7D0D0D0D7D7D7DBDBDBDDDDDDDDDDDDDBDBDBD4D4D4CBCBCBC0C0C0B5B5B5AF + AFAFAEAEAEB3B3B3BEBEBEC9C9C9D3D3D3D9D9D9DBDBDBD8D8D8D3D3D3CACACA + BEBEBEB3B3B3A8A8A89E9E9E9494948E8E8E8A8A8A8585858383838282828282 + 828484848787878C8C8C9292929B9B9BA5A5A5B1B1B1BCBCBCC7C7C7D0D0D0D7 + D7D7DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD5D5D5CDCDCDC3C3C3B7B7B7AEAE + AEABABABACACACB3B3B3BEBEBECACACAD3D3D3D9D9D9DDDDDDDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DDDDDDDADADAD4D4D4CBCBCBC0C0C0B5B5B5ADADADABABABADADADB5B5B5C0C0 + C0CBCBCBD4D4D4DADADADDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDDDDDDDBDBDBD5D5D5CDCDCDC4C4C4B9B9B9AEAEAEA9A9A9 + A9A9A9AEAEAEB9B9B9C4C4C4CECECED6D6D6DBDBDBDDDDDDDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDB + D4D4D4CDCDCDC7C7C7C0C0C0BABABA929292B4B4B4E1E1E1E0E0E0E0E0E0DFDF + DFDFDFDFDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD4D4D4C8C8C8B9B9B9 + A8A8A89999999393939494949E9E9EAEAEAEC0C0C0CDCDCDD7D7D7DCDCDCDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDDDDDDD9D9D9D0D0D0C5C5C5B4B4B4A2A2A2969696919191949494 + 9F9F9FB1B1B1C1C1C1D8D8D8C5C5C58F8F8F8F8F8F8F8F8F8F8F8FBFBFBF9B9B + 9B5858586262626F6F6F7676767B7B7B7C7C7C7A7A7A76767675757574747475 + 75757676767B7B7B8383838F8F8F9D9D9DACACACBBBBBBC8C8C8D3D3D3D8D8D8 + DCDCDCDDDDDDDEDEDEDEDEDEDEDEDEDDDDDDDCDCDCD9D9D9D3D3D3CACACABEBE + BEAEAEAE9F9F9F9191918686867D7D7D78787875757574747474747474747475 + 75757676767A7A7A8080808A8A8A979797A6A6A6B6B6B6C4C4C4CFCFCFD7D7D7 + DBDBDBDDDDDDDEDEDEE1E1E1C5C5C58F8F8F8F8F8F8F8F8F8F8F8FBFBFBF9B9B + 9B5858586262626F6F6F7676767B7B7B7C7C7C7A7A7A76767675757574747475 + 75757676767B7B7B8383838F8F8F9D9D9DACACACBBBBBBC8C8C8D3D3D3D8D8D8 + DCDCDCDDDDDDDEDEDEDEDEDEDDDDDDD7D7D7CDCDCDC0C0C0AEAEAE9E9E9E9696 + 969696969D9D9DADADADBFBFBFCDCDCDD6D6D6DCDCDCDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDDDDDDD7D7D7CDCDCDC0C0C0AEAEAE9E9E9E9696969696969D9D9D + ADADADBFBFBFCDCDCDD6D6D6DCDCDCDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEE4E4E4BFBFBF8F8F8F8F8F8F8F8F8F8F8F8FBFBFBFACACAC61616166666677 + 7777929292ADADADC3C3C3D2D2D2DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDDDDDDDBDBDBD4D4D4CBCBCBBDBDBDACACAC9C9C9C8F8F8F8383 + 837C7C7C7777777575757373737373737373737474747575757676767878787C + 7C7C8383838C8C8C999999A7A7A7B6B6B6C5C5C5D0D0D0D7D7D7DBDBDBDCDCDC + D8D8D8CFCFCFC2C2C2B1B1B1A0A0A09797979797979E9E9EADADADBFBFBFCDCD + CDD5D5D5D9D9D9D4D4D4CBCBCBBDBDBDACACAC9C9C9C8F8F8F8383837C7C7C77 + 77777575757373737373737373737474747575757676767878787C7C7C838383 + 8C8C8C999999A7A7A7B6B6B6C5C5C5D0D0D0D7D7D7DBDBDBDDDDDDDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDB + DBDBD3D3D3C8C8C8B9B9B9A7A7A79999999191919393939C9C9CACACACBCBCBC + CBCBCBD5D5D5DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDD8D8D8D0D0D0C4C4C4B4B4B4A4 + A4A49797979191919494949E9E9EAEAEAEBEBEBECCCCCCD5D5D5DBDBDBDDDDDD + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDCDCDCD8D8D8CFCF + CFC3C3C3B3B3B3A2A2A29595958F8F8F9191919A9A9AA9A9A9BBBBBBC9C9C9D4 + D4D4DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD4D4D4CDCDCDC7C7C7C0C0C0BABABA92 + 9292B4B4B4E1E1E1E0E0E0E0E0E0DFDFDFDFDFDFDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDBDBDBD3D3D3C6C6C6B3B3B39E9E9E8A8A8A8080808080808A8A8A9E + 9E9EB4B4B4C6C6C6D3D3D3DBDBDBDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDCDCDCD5D5D5CBCBCBBABA + BAA5A5A58F8F8F8181817C7C7C838383929292A9A9A9BEBEBED8D8D8C7C7C790 + 9090909090909090909090C1C1C19A9A9A5353535B5B5B6666666E6E6E747474 + 7676767676767575757373737171716F6F6F6E6E6E6E6E6E7272727A7A7A8686 + 86979797A9A9A9B9B9B9C8C8C8D3D3D3DADADADDDDDDDEDEDEDEDEDEDEDEDEDD + DDDDDBDBDBD4D4D4CBCBCBBCBCBCACACAC9999998989897C7C7C7373736F6F6F + 6F6F6F6F6F6F7070707171717171716F6F6F6F6F6F6F6F6F7070707676768181 + 81909090A2A2A2B3B3B3C3C3C3D0D0D0D8D8D8DBDBDBDDDDDDE1E1E1C7C7C790 + 9090909090909090909090C1C1C19A9A9A5353535B5B5B6666666E6E6E747474 + 7676767676767575757373737171716F6F6F6E6E6E6E6E6E7272727A7A7A8686 + 86979797A9A9A9B9B9B9C8C8C8D3D3D3DADADADDDDDDDEDEDEDEDEDEDCDCDCD5 + D5D5C8C8C8B8B8B8A1A1A18C8C8C8282828282828C8C8C9F9F9FB6B6B6C8C8C8 + D4D4D4DBDBDBDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDCDCDCD5D5D5C8C8C8B8B8 + B8A1A1A18C8C8C8282828282828C8C8C9F9F9FB6B6B6C8C8C8D4D4D4DBDBDBDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDFDFDFE5E5E5969696909090909090 + 909090969696E2E2E25C5C5C5E5E5E6D6D6D868686A2A2A2BABABACCCCCCD8D8 + D8DDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDD8D8D8D0D0D0C2 + C2C2B0B0B09B9B9B8989897B7B7B7171716D6D6D6D6D6D6E6E6E6F6F6F707070 + 727272727272727272727272727272727272747474797979838383919191A4A4 + A4B5B5B5C5C5C5D1D1D1D8D8D8DBDBDBD6D6D6CBCBCBBABABAA5A5A590909084 + 84848383838C8C8C9F9F9FB6B6B6C8C8C8D4D4D4D6D6D6D0D0D0C2C2C2B0B0B0 + 9B9B9B8989897B7B7B7171716D6D6D6D6D6D6E6E6E6F6F6F7070707272727272 + 72727272727272727272727272747474797979838383919191A4A4A4B5B5B5C5 + C5C5D1D1D1D8D8D8DCDCDCDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDBD3D3D3C6C6C6B3B3B39E9E9E8B8B + 8B7F7F7F7E7E7E878787989898AEAEAEC0C0C0CFCFCFD8D8D8DDDDDDDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DDDDDDD8D8D8D0D0D0C3C3C3B0B0B09C9C9C8A8A8A8080808080808A8A8A9B9B + 9BAEAEAEC0C0C0CECECED8D8D8DCDCDCDDDDDDDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDDDDDDDADADAD3D3D3C6C6C6B4B4B4A0A0A08C8C8C7F7F7F7B7B7B + 8181818F8F8FA3A3A3B8B8B8C8C8C8D4D4D4DBDBDBDDDDDDDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDDDDDDDBDBDB + D4D4D4CDCDCDC7C7C7C0C0C0BABABA929292B5B5B5E2E2E2E1E1E1E1E1E1E0E0 + E0E0E0E0DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDCDCDCD5D5D5C7C7C7B3B3B3 + 9A9A9A8282827474747272727A7A7A8F8F8FA9A9A9BFBFBFCFCFCFDADADADEDE + DEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDEDEDEDCDCDCD3D3D3C4C4C4B0B0B09696967F7F7F7171716F6F6F787878 + 8D8D8DA7A7A7BEBEBED9D9D9C8C8C8919191919191919191919191C2C2C29B9B + 9B515151959595ADADADE5E5E5EDEDEDEDEDEDEDEDEDEDEDEDD0D0D0B1B1B188 + 88887373736D6D6D6B6B6B6C6C6C747474828282959595AAAAAABCBCBCCCCCCC + D6D6D6DCDCDCDEDEDEDFDFDFDEDEDEDCDCDCD7D7D7CECECEBFBFBFACACAC9797 + 978B8B8BAEAEAEB8B8B8EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDD7D7D7B1B1B199 + 99997575757070706C6C6C6C6C6C7171717D7D7D8E8E8EA2A2A2B6B6B6C7C7C7 + D3D3D3DADADADEDEDEE3E3E3C8C8C8919191919191919191919191C2C2C29B9B + 9B515151959595ADADADE5E5E5EDEDEDEDEDEDEDEDEDEDEDEDD0D0D0B1B1B188 + 88887373736D6D6D6B6B6B6C6C6C747474828282959595AAAAAABCBCBCCCCCCC + D6D6D6DCDCDCDEDEDEDFDFDFDCDCDCD5D5D5C7C7C7B2B2B29898988181817474 + 74747474808080969696B1B1B1C6C6C6D4D4D4DCDCDCDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDCDCDCD5D5D5C7C7C7B2B2B2989898818181747474747474808080 + 969696B1B1B1C6C6C6D4D4D4DCDCDCDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFE7E7E7B6B6B6919191919191919191919191C8C8C893939356565663 + 63637A7A7A979797B2B2B2C7C7C7D4D4D4DCDCDCDEDEDEDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDEDEDED8D8D8CDCDCDBDBDBDA8A8A8909090ABABABACACACC2C2 + C2EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDC1C1C1B2B2B293939378787873 + 73737070706F6F6F737373808080909090A4A4A4B9B9B9C9C9C9D5D5D5DADADA + D5D5D5C9C9C9B6B6B69D9D9D848484777777757575808080969696B1B1B1C6C6 + C6D3D3D3D5D5D5CDCDCDBDBDBDA8A8A8909090ABABABACACACC2C2C2EDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDC1C1C1B2B2B2939393787878737373707070 + 6F6F6F737373808080909090A4A4A4B9B9B9C9C9C9D5D5D5DCDCDCDEDEDEDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDC + DCDCD5D5D5C7C7C7B4B4B49D9D9D8686867575757070707676768888889F9F9F + B6B6B6C8C8C8D5D5D5DCDCDCDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDBDBDBD3D3D3C6C6C6B2B2B29D + 9D9D8787877878787373737878788888889E9E9EB4B4B4C7C7C7D4D4D4DBDBDB + DEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDCDCDCD6D6D6CCCCCCBABA + BAA4A4A48E8E8E7A7A7A6F6F6F6F6F6F7A7A7A8D8D8DA4A4A4B9B9B9CBCBCBD6 + D6D6DCDCDCDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDEDEDEDCDCDCD5D5D5CECECEC8C8C8C1C1C1BBBBBB92 + 9292B5B5B5E2E2E2E1E1E1E1E1E1E0E0E0E0E0E0DFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFE8E8E8EFEFEFEFEFEFEFEFEFEFEFEFE8E8E8B1B1B16868686E6E6E82 + 82829D9D9DB7B7B7C9C9C9D6D6D6DDDDDDDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDED9D9D9D4D4D4DBDBDBEFEF + EFEFEFEFEFEFEFEFEFEFCACACA9C9C9C8D8D8DA9A9A9C0C0C0DBDBDBCACACA92 + 9292929292929292929292C4C4C4B0B0B0EFEFEFCACACAC4C4C4989898929292 + 929292929292929292ABABABC4C4C4E3E3E3CBCBCB9898987070706969696A6A + 6A737373828282979797ADADADC1C1C1CFCFCFD9D9D9DDDDDDDFDFDFDEDEDEDA + DADAD1D1D1C4C4C4B1B1B1A4A4A4C3C3C3EFEFEFC4C4C4C4C4C4929292929292 + 929292929292929292A5A5A5C4C4C4D6D6D6E1E1E1B1B1B17373736B6B6B6868 + 686D6D6D7B7B7B8F8F8FA5A5A5BABABACBCBCBD6D6D6DCDCDCE4E4E4CACACA92 + 9292929292929292929292C4C4C4B0B0B0EFEFEFCACACAC4C4C4989898929292 + 929292929292929292ABABABC4C4C4E3E3E3CBCBCB9898987070706969696A6A + 6A737373828282979797ADADADC1C1C1CFCFCFD9D9D9DDDDDDDFDFDFDCDCDCE4 + E4E4EFEFEFEFEFEFEFEFEFEFEFEFB9B9B97272727777778F8F8FACACACC3C3C3 + D3D3D3DCDCDCDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDCDCDCE4E4E4EFEFEFEFEF + EFEFEFEFEFEFEFB9B9B97272727777778F8F8FACACACC3C3C3D3D3D3DCDCDCDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFE0E0E0E3E3E3929292929292 + 929292929292A5A5A5CFCFCF4F4F4F5959596F6F6F8A8A8AA7A7A7BEBEBECECE + CED9D9D9DEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDED7D7D7CCCCCCCC + CCCCD1D1D1EFEFEFCACACAC4C4C4B1B1B1929292929292929292929292929292 + 929292B7B7B7C4C4C4DCDCDCDBDBDBACACAC7878786E6E6E6B6B6B7171717F7F + 7F949494ABABABC0C0C0CFCFCFD7D7D7E4E4E4EFEFEFEFEFEFEFEFEFEFEFEFB9 + B9B97373737878788F8F8FACACACC3C3C3D1D1D1D4D4D4CCCCCCCCCCCCD1D1D1 + EFEFEFCACACAC4C4C4B1B1B1929292929292929292929292929292929292B7B7 + B7C4C4C4DCDCDCDBDBDBACACAC7878786E6E6E6B6B6B7171717F7F7F949494AB + ABABC0C0C0CFCFCFD9D9D9DEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEE0E0E0E0E0E0E0E0E0E0E0E0D4D4 + D4A5A5A56868686A6A6A7878788F8F8FA9A9A9BFBFBFCFCFCFD9D9D9DEDEDEDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFE0E0E0E0E0E0E0E0E0E0E0E0BDBDBD8484846C6C6C6C6C6C7878 + 788D8D8DA4A4A4BABABACBCBCBD6D6D6DCDCDCDEDEDEDFDFDFDFDFDFDFDFDFDE + DEDEDDDDDDD9D9D9CFCFCFC1C1C1CBCBCBE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + B6B6B69B9B9BAAAAAABFBFBFCECECED9D9D9DDDDDDDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDCDCDC + D5D5D5CECECEC8C8C8C1C1C1BBBBBB929292B5B5B5E2E2E2E1E1E1E1E1E1E0E0 + E0E0E0E0DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFE4E4E4D8D8D8939393939393939393 + 939393999999E8E8E8646464666666777777929292ADADADC4C4C4D3D3D3DCDC + DCDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDDDDDDD6D6D6E1E1E1B9B9B9939393939393939393939393ACACACD1D1D1 + 929292AEAEAEC4C4C4DEDEDECBCBCB939393939393939393939393BFBFBFC5C5 + C593939393939393939393939393939393939393939393939393939393939393 + 9393B2B2B2E4E4E4C2C2C27070706868686868687373738686869D9D9DB4B4B4 + C7C7C7D4D4D4DCDCDCDEDEDEDCDCDCD6D6D6CACACAB9B9B9CBCBCBEBEBEBBFBF + BF93939393939393939393939393939393939393939393939393939393939393 + 9393A0A0A0D2D2D2CDCDCD9494946969696666666D6D6D7E7E7E959595ACACAC + C1C1C1D0D0D0D9D9D9E4E4E4CBCBCB939393939393939393939393BFBFBFC5C5 + C593939393939393939393939393939393939393939393939393939393939393 + 9393B2B2B2E4E4E4C2C2C27070706868686868687373738686869D9D9DB4B4B4 + C7C7C7D4D4D4DCDCDCDEDEDEE4E4E4CBCBCB939393939393939393939393C5C5 + C5A6A6A67373738D8D8DABABABC1C1C1D2D2D2DCDCDCDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFE4E4E4CBCBCB939393939393939393939393C5C5C5A6A6A6737373 + 8D8D8DABABABC1C1C1D2D2D2DCDCDCDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDEDEDEDADADAE4E4E4B9B9B9939393939393939393939393D8D8D877777753 + 53536565658080809B9B9BB4B4B4C8C8C8D5D5D5DCDCDCDEDEDEDFDFDFDFDFDF + DFDFDFDFDFDFDEDEDEE3E3E3ECECECD2D2D2B9B9B99393939393939393939393 + 93939393939393939393939393939393939393939393939393939393A6A6A6D2 + D2D2CECECE9595956A6A6A6969697373738585859D9D9DB7B7B7C9C9C9DCDCDC + D8D8D8939393939393939393939393C5C5C5A7A7A77373738D8D8DABABABC1C1 + C1D1D1D1E1E1E1ECECECD2D2D2B9B9B993939393939393939393939393939393 + 9393939393939393939393939393939393939393939393A6A6A6D2D2D2CECECE + 9595956A6A6A6969697373738585859D9D9DB7B7B7C9C9C9D6D6D6DDDDDDDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFE0E0E0A3 + 88D95C23CF5C23CF5C23CF5C23CF6E3CD1D3D3D36868686464646D6D6D818181 + 9B9B9BB4B4B4C7C7C7D5D5D5DCDCDCDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD8D4E06E3CD15C23CF5C23CF5C23CF5C + 23CF9A7CD7B9B9B96D6D6D6868686D6D6D7D7D7D949494ABABABC0C0C0CFCFCF + D9D9D9DDDDDDDEDEDEDFDFDFDFDFDFDEDEDEDBDBDBD4D4D4C7C7C7C8C8C8BEAE + DC5C23CF5C23CF5C23CF5C23CF5C23CF9A7CD7C1C1C1B4B4B4C7C7C7D4D4D4DB + DBDBDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDEDEDEDCDCDCD5D5D5CECECEC8C8C8C1C1C1BBBBBB92 + 9292B5B5B5E2E2E2E1E1E1E1E1E1E0E0E0E0E0E0DFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFEFEFEFA1A1A1949494949494949494949494D9D9D98B8B8B65656570 + 7070888888A4A4A4BCBCBCCECECED9D9D9DEDEDEDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDCDCDCD2D2D2EFEFEF9A9A9A9494 + 94949494949494949494CCCCCCAEAEAE9D9D9DB7B7B7CACACAE0E0E0CCCCCC94 + 9494949494949494949494949494949494949494949494949494949494949494 + 949494949494949494949494949494949494949494949494D3D3D3C3C3C36E6E + 6E6565656A6A6A7878788E8E8EA7A7A7BFBFBFCECECED9D9D9DDDDDDDADADAD1 + D1D1C1C1C1D5D5D5D9D9D99A9A9A949494949494949494949494949494949494 + 949494949494949494949494949494949494949494949494B3B3B3D5D5D59C9C + 9C6666666666667171718585859E9E9EB7B7B7C9C9C9D6D6D6E4E4E4CCCCCC94 + 9494949494949494949494949494949494949494949494949494949494949494 + 949494949494949494949494949494949494949494949494D3D3D3C3C3C36E6E + 6E6565656A6A6A7878788E8E8EA7A7A7BFBFBFCECECED9D9D9DEDEDEE5E5E5CC + CCCC949494949494949494949494C6C6C6A7A7A77373738D8D8DABABABC1C1C1 + D2D2D2DCDCDCDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFE5E5E5CCCCCC9494949494 + 94949494949494C6C6C6A7A7A77373738D8D8DABABABC1C1C1D2D2D2DCDCDCDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDDDDDDD6D6D6D5D5D5D9D9D9949494 + 949494949494949494B3B3B3BABABA5050505E5E5E7575758F8F8FAAAAAAC0C0 + C0D1D1D1DADADADEDEDEDFDFDFDFDFDFDFDFDFDFDFDFE1E1E1E5E5E5A1A1A194 + 9494949494949494949494949494949494949494949494949494949494949494 + 949494949494949494949494949494949494B3B3B3DCDCDCA1A1A16565656A6A + 6A7A7A7A929292AFAFAFC4C4C4DADADAD9D9D9949494949494949494949494C6 + C6C6A8A8A87373738D8D8DABABABC1C1C1D5D5D5E5E5E5A1A1A1949494949494 + 9494949494949494949494949494949494949494949494949494949494949494 + 94949494949494949494949494B3B3B3DCDCDCA1A1A16565656A6A6A7A7A7A92 + 9292AFAFAFC4C4C4D4D4D4DCDCDCDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDAD6E26631D15D24D05D24D05D24D05D24 + D0AD97DBA4A4A46565656666667575758D8D8DA7A7A7BFBFBFCECECED9D9D9DE + DEDEDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + E1E1E1BFB0DE5D24D05D24D05D24D05D24D05D24D0C8BDDFA9A9A96B6B6B6868 + 687272728484849C9C9CB2B2B2C6C6C6D3D3D3DBDBDBDEDEDEDFDFDFDEDEDEDC + DCDCD6D6D6CCCCCCBFBFBFDAD6E26F3DD35D24D05D24D05D24D05D24D06F3DD3 + D9D9D9B4B4B4C1C1C1D0D0D0D9D9D9DDDDDDDEDEDEDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDCDCDC + D5D5D5CECECEC8C8C8C1C1C1BBBBBB929292B6B6B6E3E3E3E2E2E2E2E2E2E1E1 + E1E1E1E1E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E9E9E9C8C8C8969696969696 + 969696969696BCBCBCBDBDBD6464646B6B6B7E7E7E9B9B9BB5B5B5CACACAD7D7 + D7DEDEDEE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0DF + DFDFDADADADBDBDBD5D5D59696969696969696969696969C9C9CEEEEEE929292 + A8A8A8BFBFBFD0D0D0E3E3E3CECECE9696969696969696969696969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 9696969696969696969696CECECEC2C2C26969696666666E6E6E8181819B9B9B + B5B5B5C9C9C9D6D6D6DCDCDCD8D8D8CDCDCDDCDCDCDBDBDB9696969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 9696969696969696969696AFAFAFD5D5D58F8F8F656565696969797979929292 + ADADADC3C3C3D2D2D2E4E4E4CECECE9696969696969696969696969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 9696969696969696969696CECECEC2C2C26969696666666E6E6E8181819B9B9B + B5B5B5C9C9C9D6D6D6DDDDDDE6E6E6CECECE969696969696969696969696C8C8 + C8A8A8A87373738D8D8DABABABC2C2C2D3D3D3DCDCDCE0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E6E6E6CECECE969696969696969696969696C8C8C8A8A8A8737373 + 8D8D8DABABABC2C2C2D3D3D3DCDCDCE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0DFDF + DFDCDCDCD4D4D4DEDEDEC2C2C2969696969696969696969696969696E7E7E767 + 67675C5C5C6E6E6E868686A0A0A0B8B8B8CBCBCBD7D7D7DEDEDEE0E0E0E0E0E0 + E0E0E0E0E0E0E5E5E5DBDBDB9696969696969696969696969696969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + 9696969696A9A9A9DADADA8080806666667373738B8B8BAAAAAAC1C1C1DADADA + DBDBDB969696969696969696969696C8C8C8A9A9A97373738D8D8DABABABC2C2 + C2DBDBDBDBDBDB96969696969696969696969696969696969696969696969696 + 9696969696969696969696969696969696969696969696969696969696969696 + A9A9A9DADADA8080806666667373738B8B8BAAAAAAC1C1C1D2D2D2DCDCDCE0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E3 + E3E3A78CDD5F26D25F26D25F26D25F26D27140D5D8D8D87070706464646D6D6D + 8080809B9B9BB4B4B4C7C7C7D5D5D5DCDCDCDFDFDFE0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E4E4E49E80DB5F26D25F26D25F + 26D25F26D27140D5D9D9D98282826969696B6B6B7777778D8D8DA4A4A4BABABA + CCCCCCD7D7D7DCDCDCDFDFDFDEDEDEDADADAD1D1D1C2C2C2CFCFCF9E80DB5F26 + D25F26D25F26D25F26D25F26D2CBC0E2C3C3C3BDBDBDCDCDCDD7D7D7DDDDDDDF + DFDFE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0DFDFDFDCDCDCD6D6D6CFCFCFC9C9C9C2C2C2BCBCBC93 + 9393B6B6B6E3E3E3E2E2E2E2E2E2E1E1E1E1E1E1E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E3E3E3E9E9E99797979797979797979797979D9D9DEDEDED65656567 + 67677676768E8E8EAAAAAABFBFBFCECECED6D6D6D9D9D9DADADADADADADADADA + DADADADADADADADADADADADADADADAD7D7D7D1D1D1E5E5E5B7B7B79797979797 + 97979797979797BDBDBDC4C4C4959595B1B1B1C7C7C7D5D5D5E5E5E5D0D0D097 + 9797979797979797979797979797979797AAAAAACACACAE3E3E3F6F6F6F6F6F6 + F6F6F6F6F6F6DDDDDDC3C3C3979797979797979797979797979797979797D6D6 + D6B6B6B6666666696969777777909090ABABABC2C2C2D2D2D2D9D9D9D5D5D5DC + DCDCE3E3E3979797979797979797979797979797979797BDBDBDD6D6D6F6F6F6 + F6F6F6F6F6F6F0F0F0CACACAA4A4A4979797979797979797979797979797B7B7 + B7CBCBCB6E6E6E656565707070868686A3A3A3BCBCBCCECECEE3E3E3D0D0D097 + 9797979797979797979797979797979797AAAAAACACACAE3E3E3F6F6F6F6F6F6 + F6F6F6F6F6F6DDDDDDC3C3C3979797979797979797979797979797979797D6D6 + D6B6B6B6666666696969777777909090ABABABC2C2C2D2D2D2DCDCDCE6E6E6D0 + D0D0979797979797979797979797CACACAA9A9A97373738D8D8DABABABC2C2C2 + D3D3D3DCDCDCE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E7E7E7D0D0D09797979797 + 97979797979797CACACAA9A9A97373738D8D8DABABABC2C2C2D3D3D3DCDCDCE0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0DFDFDFD9D9D9D1D1D1F0F0F09D9D9D979797 + 979797979797979797979797CACACAAAAAAA5D5D5D6969697C7C7C949494AEAE + AEC4C4C4D3D3D3DCDCDCDFDFDFE0E0E0E0E0E0E0E0E0E5E5E5DDDDDD97979797 + 9797979797979797979797979797CACACACACACAF6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6CACACABDBDBD979797979797979797979797979797BDBDBDBBBBBB6363 + 636F6F6F878787A6A6A6BFBFBFD9D9D9DDDDDD979797979797979797979797CA + CACAAAAAAA7373738D8D8DABABABC2C2C2DCDCDCDDDDDD979797979797979797 + 979797979797979797CACACACACACAF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6CACA + CABDBDBD979797979797979797979797979797BDBDBDBBBBBB6363636F6F6F87 + 8787A6A6A6BFBFBFD0D0D0DCDCDCE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E7E7E77241D66027D36027D36027 + D36027D3A98EDEAFAFAF6666666868687676768D8D8DA7A7A7BEBEBECFCFCFDA + DADADEDEDEE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E1E1E1E6E6E67B4ED76027D36027D36027D36027D39F81DDBEBEBE7070 + 706969696E6E6E7E7E7E949494ABABABC0C0C0CFCFCFD9D9D9DCDCDCDCDCDCD5 + D5D5C7C7C7CCCCCCC4B5E26027D36027D36027D36027D36027D39F81DDCACACA + B6B6B6C8C8C8D5D5D5DCDCDCDFDFDFE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0DFDFDFDCDCDC + D6D6D6CFCFCFC9C9C9C2C2C2BCBCBC939393B6B6B6E3E3E3E2E2E2E2E2E2E1E1 + E1E1E1E1E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0F1F1F1B2B2B2989898 + 989898989898989898D8D8D89898986464646E6E6E8181819B9B9BB0B0B0BFBF + BFC7C7C7CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA + CACAC6C6C6F2F2F29E9E9E989898989898989898989898DEDEDEA2A2A2A0A0A0 + BABABACDCDCDD9D9D9E7E7E7D2D2D2989898989898989898989898B2B2B2E5E5 + E5DDDDDDBFBFBFBABABAC2C2C2D3D3D3DCDCDCE0E0E0E6E6E6EEEEEEEBEBEBB2 + B2B29898989898989898989898989E9E9EEBEBEB838383656565707070868686 + A3A3A3BCBCBCCECECED5D5D5D3D3D3F1F1F1A5A5A59898989898989898989898 + 98A5A5A5E5E5E5D8D8D8D1D1D1CFCFCFDADADADEDEDEE1E1E1EBEBEBF5F5F5C5 + C5C5989898989898989898989898989898CBCBCBB4B4B46363636A6A6A7E7E7E + 9A9A9AB5B5B5C9C9C9E3E3E3D2D2D2989898989898989898989898B2B2B2E5E5 + E5DDDDDDBFBFBFBABABAC2C2C2D3D3D3DCDCDCE0E0E0E6E6E6EEEEEEEBEBEBB2 + B2B29898989898989898989898989E9E9EEBEBEB838383656565707070868686 + A3A3A3BCBCBCCECECEDADADAE7E7E7D2D2D2989898989898989898989898CBCB + CBAAAAAA7373738D8D8DABABABC2C2C2D3D3D3DCDCDCE0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E8E8E8D2D2D2989898989898989898989898CBCBCBAAAAAA737373 + 8D8D8DABABABC2C2C2D3D3D3DCDCDCE0E0E0E0E0E0E0E0E0E0E0E0DFDFDFDCDC + DCD5D5D5DDDDDDD2D2D29898989898989898989898989898989898989E9E9EF2 + F2F26C6C6C686868747474888888A3A3A3BBBBBBCDCDCDD9D9D9DEDEDEE0E0E0 + E0E0E0E0E0E0E6E6E6DEDEDE989898989898989898ABABABD8D8D8F8F8F8EAEA + EAE8E8E8DEDEDEDCDCDCDCDCDCDADADADADADAE5E5E5E9E9E9EBEBEBA5A5A598 + 9898989898989898989898E5E5E58080806F6F6F878787A6A6A6BFBFBFDADADA + DEDEDE989898989898989898989898CBCBCBABABAB7373738D8D8DABABABC2C2 + C2DDDDDDDEDEDE989898989898989898ABABABD8D8D8F8F8F8EAEAEAE8E8E8DE + DEDEDCDCDCDCDCDCDADADADADADAE5E5E5E9E9E9EBEBEBA5A5A5989898989898 + 989898989898E5E5E58080806F6F6F878787A6A6A6BFBFBFD1D1D1DCDCDCE0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E5E5E5B49DE26229D56229D56229D56229D56B36D6E1DDE9737373656565 + 6D6D6D8080809A9A9AB2B2B2C7C7C7D5D5D5DCDCDCDFDFDFE0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E4E4E4CFC3E66229D562 + 29D56229D56229D56229D5C6B7E4ADADAD6D6D6D6969697272728585859B9B9B + B2B2B2C6C6C6D3D3D3D8D8D8D6D6D6CDCDCDC2C2C2E1E1E17443D86229D56229 + D56229D56229D57D50D9D9D9D9B6B6B6C3C3C3D2D2D2DADADADEDEDEE0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0DFDFDFDCDCDCD6D6D6CFCFCFC9C9C9C2C2C2BCBCBC93 + 9393B6B6B6E3E3E3E2E2E2E2E2E2E1E1E1E1E1E1E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0ECECECCCCCCC999999999999999999999999B9B9B9CACACA63 + 63636666667474748888889B9B9BAAAAAAB3B3B3B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B5B5B5CBCBCBD3D3D39999999999999999 + 999999999F9F9FF0F0F08D8D8DAAAAAAC1C1C1D2D2D2DCDCDCE8E8E8D3D3D399 + 9999999999999999999999CCCCCCABABAB7373738D8D8DABABABC2C2C2D3D3D3 + DCDCDCE0E0E0E0E0E0E0E0E0E8E8E8F4F4F4ACACAC9999999999999999999999 + 99BFBFBFC0C0C06464646A6A6A7E7E7E9B9B9BB6B6B6CACACAD2D2D2E4E4E4CC + CCCC999999999999999999999999A6A6A6ECECECC2C2C2B0B0B0C6C6C6D5D5D5 + DDDDDDDFDFDFE0E0E0E0E0E0E3E3E3EFEFEFCCCCCC9999999999999999999999 + 999F9F9FF3F3F36D6D6D666666777777929292AFAFAFC5C5C5E2E2E2D3D3D399 + 9999999999999999999999CCCCCCABABAB7373738D8D8DABABABC2C2C2D3D3D3 + DCDCDCE0E0E0E0E0E0E0E0E0E8E8E8F4F4F4ACACAC9999999999999999999999 + 99BFBFBFC0C0C06464646A6A6A7E7E7E9B9B9BB6B6B6CACACAD7D7D7E8E8E8D3 + D3D3999999999999999999999999CCCCCCABABAB7373738D8D8DABABABC2C2C2 + D3D3D3DCDCDCE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E8E8E8D3D3D39999999999 + 99999999999999CCCCCCABABAB7373738D8D8DABABABC2C2C2D3D3D3DCDCDCE0 + E0E0E0E0E0E0E0E0E0E0E0DFDFDFDADADACFCFCFF1F1F1A6A6A6999999999999 + 999999999999999999999999999999D3D3D3ACACAC6969697070707E7E7E9797 + 97B1B1B1C7C7C7D5D5D5DCDCDCDFDFDFE0E0E0E0E0E0E7E7E7DFDFDF999999A6 + A6A6D9D9D9F3F3F3E7E7E7DBDBDBDADADADADADAD7D7D7D5D5D5D2D2D2CECECE + CBCBCBC7C7C7C2C2C2D8D8D8DFDFDF999999999999999999999999C6C6C6B3B3 + B37272728C8C8CAAAAAAC1C1C1DBDBDBDFDFDF999999999999999999999999CC + CCCCACACAC7373738D8D8DABABABC2C2C2DDDDDDDFDFDF999999A6A6A6D9D9D9 + F3F3F3E7E7E7DBDBDBDADADADADADAD7D7D7D5D5D5D2D2D2CECECECBCBCBC7C7 + C7C2C2C2D8D8D8DFDFDF999999999999999999999999C6C6C6B3B3B37272728C + 8C8CAAAAAAC1C1C1D2D2D2DCDCDCE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0EAEAEA7645DA642BD7642B + D7642BD7642BD7AD92E2B2B2B26666666767677575758C8C8CA5A5A5BDBDBDCE + CECED9D9D9DEDEDEE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E7E7E7AD92E2642BD7642BD7642BD7642BD77645DAE3DF + EB8484846B6B6B6B6B6B7777778C8C8CA3A3A3B9B9B9C9C9C9D0D0D0CECECEC2 + C2C2D2D2D2A385E1642BD7642BD7642BD7642BD7642BD7D1C5E8C2C2C2BDBDBD + CECECED7D7D7DDDDDDDFDFDFE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 + E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0DFDFDFDCDCDC + D6D6D6CFCFCFC9C9C9C2C2C2BCBCBC939393B6B6B6E3E3E3E3E3E3E3E3E3E2E2 + E2E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E3E3E3F5F5F59B9B9B + 9B9B9B9B9B9B9B9B9BA1A1A1F5F5F56E6E6E6060606666667676768585859191 + 919999999D9D9D9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9B + 9B9BD8D8D8BBBBBB9B9B9B9B9B9B9B9B9B9B9B9BC8C8C8C0C0C0999999B4B4B4 + C8C8C8D7D7D7DEDEDEEAEAEAD5D5D59B9B9B9B9B9B9B9B9B9B9B9BCECECEACAC + AC7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1EB + EBEBEEEEEEA1A1A19B9B9B9B9B9B9B9B9B9B9B9BEEEEEE797979686868797979 + 959595B2B2B2C7C7C7CFCFCFF8F8F8A1A1A19B9B9B9B9B9B9B9B9B9B9B9BE1E1 + E1B7B7B79C9C9CB8B8B8CCCCCCD9D9D9E0E0E0E1E1E1E1E1E1E1E1E1E1E1E1E2 + E2E2F4F4F4B5B5B59B9B9B9B9B9B9B9B9B9B9B9BCECECEABABAB656565737373 + 8C8C8CABABABC3C3C3E1E1E1D5D5D59B9B9B9B9B9B9B9B9B9B9B9BCECECEACAC + AC7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1EB + EBEBEEEEEEA1A1A19B9B9B9B9B9B9B9B9B9B9B9BEEEEEE797979686868797979 + 959595B2B2B2C7C7C7D6D6D6E9E9E9D5D5D59B9B9B9B9B9B9B9B9B9B9B9BCECE + CEACACAC7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1EAEAEAD5D5D59B9B9B9B9B9B9B9B9B9B9B9BCECECEACACAC747474 + 8E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1DEDEDED7D7 + D7D7D7D7E1E1E19B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BA8 + A8A8E9E9E96E6E6E6D6D6D7777778C8C8CA7A7A7BFBFBFD0D0D0DBDBDBE0E0E0 + E1E1E1E1E1E1E8E8E8E1E1E1BBBBBBF7F7F7ECECECDEDEDEDDDDDDDADADAD6D6 + D6D2D2D2CDCDCDC7C7C7C2C2C2BDBDBDB8B8B8B2B2B2ABABABA4A4A4F4F4F4A1 + A1A19B9B9B9B9B9B9B9B9BAEAEAEDDDDDD7B7B7B959595B0B0B0C7C7C7DEDEDE + E1E1E19B9B9B9B9B9B9B9B9B9B9B9BCECECEADADAD7474748E8E8EACACACC3C3 + C3DEDEDEE1E1E1BBBBBBF7F7F7ECECECDEDEDEDDDDDDDADADAD6D6D6D2D2D2CD + CDCDC7C7C7C2C2C2BDBDBDB8B8B8B2B2B2ABABABA4A4A4F4F4F4A1A1A19B9B9B + 9B9B9B9B9B9BAEAEAEDDDDDD7B7B7B959595B0B0B0C7C7C7D6D6D6DDDDDDE1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E7E7E7CABBE9662DD9662DD9662DD9662DD96F3ADAE6E2EE757575 + 6565656D6D6D7F7F7F999999B2B2B2C7C7C7D6D6D6DDDDDDE0E0E0E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E2E2E2ECECEC81 + 54DD662DD9662DD9662DD9662DD9A688E3C3C3C37373736B6B6B6E6E6E7E7E7E + 939393ABABABBDBDBDC5C5C5C2C2C2CFCFCFD4C8EB662DD9662DD9662DD9662D + D9662DD9AF94E5CECECEB7B7B7C9C9C9D6D6D6DDDDDDE0E0E0E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E0E0E0DDDDDDD7D7D7D0D0D0CACACAC3C3C3BDBDBD93 + 9393B6B6B6E3E3E3E3E3E3E3E3E3E2E2E2E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1F3F3F3BCBCBC9C9C9C9C9C9C9C9C9C9C9C9CD6D6D6A2 + A2A25C5C5C5B5B5B6262626D6D6D7676767D7D7D818181838383838383838383 + 838383838383838383838383828282868686F6F6F69C9C9C9C9C9C9C9C9C9C9C + 9C9C9C9CE9E9E99E9E9EA3A3A3BCBCBCCECECEDBDBDBE0E0E0EAEAEAD6D6D69C + 9C9C9C9C9C9C9C9C9C9C9CCFCFCFACACAC7474748E8E8EACACACC3C3C3D4D4D4 + DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EFEFEFCFCFCF9C9C9C9C9C9C9C9C + 9C9C9C9CC9C9C9B6B6B6666666757575919191AEAEAEC4C4C4DDDDDDDCDCDC9C + 9C9C9C9C9C9C9C9C9C9C9CB6B6B6D6D6D6838383A1A1A1BBBBBBCECECEDBDBDB + E0E0E0E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EAEAEAE2E2E29C9C9C9C9C9C9C9C + 9C9C9C9CA9A9A9E8E8E86464646F6F6F888888A8A8A8C0C0C0E1E1E1D6D6D69C + 9C9C9C9C9C9C9C9C9C9C9CCFCFCFACACAC7474748E8E8EACACACC3C3C3D4D4D4 + DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EFEFEFCFCFCF9C9C9C9C9C9C9C9C + 9C9C9C9CC9C9C9B6B6B6666666757575919191AEAEAEC5C5C5D6D6D6E9E9E9D6 + D6D69C9C9C9C9C9C9C9C9C9C9C9CCFCFCFACACAC7474748E8E8EACACACC3C3C3 + D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EAEAEAD6D6D69C9C9C9C9C + 9C9C9C9C9C9C9CCFCFCFACACAC7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1 + E1E1E1E1E1E1E1E1E0E0E0DCDCDCD3D3D3E9E9E9BCBCBC9C9C9C9C9C9C9C9C9C + 9C9C9CC2C2C29C9C9C9C9C9C9C9C9C9C9C9CE2E2E2A0A0A06C6C6C7171718282 + 829B9B9BB5B5B5C9C9C9D7D7D7DEDEDEE0E0E0E1E1E1E1E1E1E8E8E8F3F3F3E7 + E7E7DEDEDEDCDCDCD7D7D7D1D1D1CACACAC1C1C1B9B9B9B1B1B1AAAAAAA3A3A3 + 9C9C9C9696968E8E8E878787EBEBEBA9A9A99C9C9C9C9C9C9C9C9CA9A9A9EAEA + EA878787A1A1A1B9B9B9CCCCCCE0E0E0E2E2E29C9C9C9C9C9C9C9C9C9C9C9CCF + CFCFADADAD7474748E8E8EACACACC3C3C3D4D4D4E5E5E5F3F3F3E7E7E7DEDEDE + DCDCDCD7D7D7D1D1D1CACACAC1C1C1B9B9B9B1B1B1AAAAAAA3A3A39C9C9C9696 + 968E8E8E878787EBEBEBA9A9A99C9C9C9C9C9C9C9C9CA9A9A9EAEAEA878787A1 + A1A1B9B9B9CCCCCCD8D8D8DFDFDFE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1ECECEC8D63E1682F + DB682FDB682FDB682FDBB196E7B5B5B56767676767677474748B8B8BA6A6A6BE + BEBECECECEDADADADFDFDFE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E7E7E7DFD7EE713CDC682FDB682FDB682FDB682F + DBCCBDEBB2B2B26E6E6E6B6B6B737373838383999999ABABABB3B3B3B8B8B8E6 + E6E67A49DE682FDB682FDB682FDB682FDB8356DFDFDFDFB4B4B4C4C4C4D3D3D3 + DBDBDBDFDFDFE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E0E0E0DDDDDD + D7D7D7D0D0D0CACACAC3C3C3BDBDBD939393B6B6B6E3E3E3E3E3E3E3E3E3E2E2 + E2E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EAEAEADDDDDD + 9E9E9E9E9E9E9E9E9E9E9E9EBEBEBECCCCCC5B5B5B5454545656565E5E5E6666 + 666D6D6D717171747474747474757575757575757575757575747474737373B1 + B1B1D1D1D19E9E9E9E9E9E9E9E9E9E9E9EB1B1B1E2E2E2919191ADADADC4C4C4 + D4D4D4DDDDDDE0E0E0EAEAEAD7D7D79E9E9E9E9E9E9E9E9E9E9E9ED1D1D1ACAC + AC7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E5E5E5F0F0F09E9E9E9E9E9E9E9E9E9E9E9EABABABE9E9E9656565737373 + 8D8D8DABABABC2C2C2ECECECBEBEBE9E9E9E9E9E9E9E9E9E9E9E9ED7D7D7A7A7 + A7858585A5A5A5BEBEBED0D0D0DCDCDCE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1F7F7F7B1B1B19E9E9E9E9E9E9E9E9E9E9E9EEAEAEA8383836D6D6D + 858585A5A5A5BEBEBEE1E1E1D7D7D79E9E9E9E9E9E9E9E9E9E9E9ED1D1D1ACAC + AC7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E5E5E5F0F0F09E9E9E9E9E9E9E9E9E9E9E9EABABABE9E9E9656565737373 + 8D8D8DABABABC3C3C3D4D4D4E9E9E9D7D7D79E9E9E9E9E9E9E9E9E9E9E9ED1D1 + D1ACACAC7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1EAEAEAD7D7D79E9E9E9E9E9E9E9E9E9E9E9ED1D1D1ACACAC747474 + 8E8E8EACACACC3C3C3D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1DFDFDFD8D8D8D3D3 + D3F0F0F09E9E9E9E9E9E9E9E9E9E9E9EB1B1B1F4F4F4A4A4A49E9E9E9E9E9E9E + 9E9EB7B7B7DBDBDB6E6E6E6D6D6D797979909090AAAAAAC1C1C1D2D2D2DCDCDC + E0E0E0E1E1E1E1E1E1E1E1E1E0E0E0DEDEDEDBDBDBD6D6D6CECECEC3C3C3B7B7 + B7ABABABA0A0A09696968D8D8D8585857F7F7F7A7A7A7575757A7A7AF7F7F79E + 9E9E9E9E9E9E9E9E9E9E9EABABABEDEDED989898AFAFAFC3C3C3D2D2D2E3E3E3 + E4E4E49E9E9E9E9E9E9E9E9E9E9E9ED1D1D1AEAEAE7474748E8E8EACACACC3C3 + C3D4D4D4DDDDDDE0E0E0DEDEDEDBDBDBD6D6D6CECECEC3C3C3B7B7B7ABABABA0 + A0A09696968D8D8D8585857F7F7F7A7A7A7575757A7A7AF7F7F79E9E9E9E9E9E + 9E9E9E9E9E9EABABABEDEDED989898AFAFAFC3C3C3D2D2D2DBDBDBE0E0E0E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E7E7E7CEBFED6A31DD6A31DD6A31DD6A31DD733EDEEAE6F2 + 8686866666666D6D6D7E7E7E999999B1B1B1C7C7C7D6D6D6DDDDDDE0E0E0E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EA + EAEABCA5EA6A31DD6A31DD6A31DD6A31DD7C4BE0EAE6F29090906D6D6D6C6C6C + 7676768686869696969E9E9ECFCFCFAA8CE76A31DD6A31DD6A31DD6A31DD6A31 + DDE1D9F0C6C6C6BEBEBECECECED9D9D9DEDEDEE0E0E0E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E0E0E0DDDDDDD7D7D7D0D0D0CACACAC3C3C3BDBDBD93 + 9393B6B6B6E3E3E3E3E3E3E3E3E3E2E2E2E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1FCFCFCA5A5A59F9F9F9F9F9F9F9F9F9F9F9FF8 + F8F86969695151514F4F4F5555555E5E5E6767676E6E6E727272747474757575 + 7575757575757474747373736F6F6FD6D6D6B8B8B89F9F9F9F9F9F9F9F9F9F9F + 9FD2D2D2BABABA9B9B9BB6B6B6CBCBCBD8D8D8DFDFDFE1E1E1EBEBEBD8D8D89F + 9F9F9F9F9F9F9F9F9F9F9FD2D2D2ADADAD7474748E8E8EACACACC3C3C3D4D4D4 + DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1F8F8F8B2B2B29F9F9F9F9F + 9F9F9F9F9F9F9FEBEBEB8484847171718B8B8BAAAAAAC0C0C0F7F7F7ACACAC9F + 9F9F9F9F9F9F9F9F9F9F9FF8F8F8787878878787A6A6A6BFBFBFD1D1D1DDDDDD + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1F0F0F0CBCBCB9F9F9F9F9F + 9F9F9F9F9F9F9FD2D2D2ABABAB6D6D6D838383A3A3A3BEBEBEE1E1E1D8D8D89F + 9F9F9F9F9F9F9F9F9F9F9FD2D2D2ADADAD7474748E8E8EACACACC3C3C3D4D4D4 + DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1F8F8F8B2B2B29F9F9F9F9F + 9F9F9F9F9F9F9FEBEBEB8484847171718B8B8BAAAAAAC2C2C2D3D3D3E9E9E9D8 + D8D89F9F9F9F9F9F9F9F9F9F9F9FD2D2D2ADADAD7474748E8E8EACACACC3C3C3 + D4D4D4DDDDDDE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EBEBEBD8D8D89F9F9F9F9F + 9F9F9F9F9F9F9FD2D2D2ADADAD7474748E8E8EACACACC3C3C3D4D4D4DDDDDDE1 + E1E1E1E1E1E0E0E0DDDDDDD5D5D5E4E4E4CBCBCB9F9F9F9F9F9F9F9F9F9F9F9F + D8D8D8C5C5C5D2D2D29F9F9F9F9F9F9F9F9F9F9F9FF1F1F18D8D8D6C6C6C7272 + 728484849E9E9EB8B8B8CBCBCBD8D8D8DEDEDEE1E1E1E1E1E1E1E1E1DFDFDFDC + DCDCD6D6D6CBCBCBBEBEBEAEAEAE9F9F9F9191918383837B7B7B7474746F6F6F + 6D6D6D6A6A6A8F8F8FCCCCCCD2D2D29F9F9F9F9F9F9F9F9F9F9F9FB2B2B2E9E9 + E9AAAAAABEBEBECDCDCDD7D7D7E5E5E5E5E5E59F9F9F9F9F9F9F9F9F9F9F9FD2 + D2D2AEAEAE7474748E8E8EACACACC3C3C3D4D4D4DDDDDDDFDFDFDCDCDCD6D6D6 + CBCBCBBEBEBEAEAEAE9F9F9F9191918383837B7B7B7474746F6F6F6D6D6D6A6A + 6A8F8F8FCCCCCCD2D2D29F9F9F9F9F9F9F9F9F9F9F9FB2B2B2E9E9E9AAAAAABE + BEBECDCDCDD7D7D7DDDDDDE0E0E0E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1F0F0F09167 + E56C33DF6C33DF6C33DF6C33DFA381E8C2C2C26969696868687474748B8B8BA5 + A5A5BDBDBDCECECED9D9D9DFDFDFE0E0E0E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EEEEEE9A74E66C33DF6C33DF6C33 + DF6C33DFA381E8C9C9C97474746C6C6C6D6D6D767676818181B1B1B1DACEF16C + 33DF6C33DF6C33DF6C33DF6C33DFB59AEBD2D2D2B8B8B8CACACAD6D6D6DDDDDD + E0E0E0E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E0E0E0DDDDDD + D7D7D7D0D0D0CACACAC3C3C3BDBDBD939393B7B7B7E4E4E4E4E4E4E3E3E3E3E3 + E3E3E3E3E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2F1F1F1 + CCCCCCA0A0A0A0A0A0A0A0A0A0A0A0D2D2D2FEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF1 + F1F1A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0F8F8F8919191A7A7A7BFBFBFD1D1D1 + DCDCDCE1E1E1E2E2E2EBEBEBD8D8D8A0A0A0A0A0A0A0A0A0A0A0A0D2D2D2ADAD + AD7474748F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2F0F0F0CCCCCCA0A0A0A0A0A0A0A0A0A0A0A0DFDFDF999999717171 + 8C8C8CAAAAAAC5C5C5F8F8F8A0A0A0A0A0A0A0A0A0A0A0A0ADADADEAEAEA6F6F + 6F888888A7A7A7C0C0C0D2D2D2DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2EBEBEBDFDFDFA0A0A0A0A0A0A0A0A0A0A0A0C6C6C6C0C0C06D6D6D + 848484A4A4A4BFBFBFE2E2E2D8D8D8A0A0A0A0A0A0A0A0A0A0A0A0D2D2D2ADAD + AD7474748F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2F0F0F0CCCCCCA0A0A0A0A0A0A0A0A0A0A0A0DFDFDF999999717171 + 8C8C8CAAAAAAC3C3C3D4D4D4EAEAEAD8D8D8A0A0A0A0A0A0A0A0A0A0A0A0D2D2 + D2ADADAD7474748F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2EBEBEBD8D8D8A0A0A0A0A0A0A0A0A0A0A0A0D2D2D2ADADAD747474 + 8F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E2E2E2E1E1E1DBDBDBD2D2D2F8F8 + F8A6A6A6A0A0A0A0A0A0A0A0A0A6A6A6F8F8F8A0A0A0F1F1F1A0A0A0A0A0A0A0 + A0A0A0A0A0C6C6C6C9C9C96C6C6C6D6D6D7B7B7B939393AEAEAEC4C4C4D4D4D4 + DEDEDEE1E1E1E2E2E2E1E1E1DEDEDED8D8D8CFCFCFBFBFBFACACAC9999998787 + 877979796F6F6F696969858585ADADADC0C0C0FEFEFEEBEBEBBFBFBFA0A0A0A0 + A0A0A0A0A0A0A0A0A0A0A0CCCCCCD8D8D8BEBEBECCCCCCD6D6D6DDDDDDE7E7E7 + E5E5E5A0A0A0A0A0A0A0A0A0A0A0A0D2D2D2AFAFAF7474748F8F8FADADADC4C4 + C4D5D5D5DEDEDEDEDEDED8D8D8CFCFCFBFBFBFACACAC9999998787877979796F + 6F6F696969858585ADADADC0C0C0FEFEFEEBEBEBBFBFBFA0A0A0A0A0A0A0A0A0 + A0A0A0A0A0A0CCCCCCD8D8D8BEBEBECCCCCCD6D6D6DDDDDDE0E0E0E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E9E9E9E6DEF56E35E16E35E16E35E16E35E16E35E1 + E6DEF58989896767676D6D6D7F7F7F989898B1B1B1C7C7C7D6D6D6DEDEDEE1E1 + E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E8E8E8EFEBF67742E36E35E16E35E16E35E16E35E1CAB7F0B7B7B7717171 + 696969696969757575DDDDDD8A5CE66E35E16E35E16E35E16E35E18A5CE6E5E5 + E5B5B5B5C6C6C6D4D4D4DCDCDCE0E0E0E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E1E1E1DEDEDED8D8D8D1D1D1CBCBCBC4C4C4BEBEBE94 + 9494B7B7B7E4E4E4E4E4E4E3E3E3E3E3E3E3E3E3E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2EAEAEAE6E6E6A2A2A2A2A2A2A2A2A2A2A2A2A2 + A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2 + A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2BBBB + BBDBDBDB949494B0B0B0C7C7C7D6D6D6DEDEDEE1E1E1E2E2E2ECECECDADADAA2 + A2A2A2A2A2A2A2A2A2A2A2D4D4D4AEAEAE7474748F8F8FADADADC4C4C4D5D5D5 + DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2EEEEEED4D4D4A2A2A2A2A2 + A2A2A2A2A2A2A2D4D4D4ADADAD7272728C8C8CABABABCDCDCDECECECA2A2A2A2 + A2A2A2A2A2A2A2A2BBBBBBD6D6D66F6F6F868686A6A6A6BFBFBFD1D1D1DDDDDD + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E7E7E7ECECECA2A2A2A2A2 + A2A2A2A2A2A2A2BBBBBBD6D6D66E6E6E868686A6A6A6BFBFBFE2E2E2DADADAA2 + A2A2A2A2A2A2A2A2A2A2A2D4D4D4AEAEAE7474748F8F8FADADADC4C4C4D5D5D5 + DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2EEEEEED4D4D4A2A2A2A2A2 + A2A2A2A2A2A2A2D4D4D4ADADAD7272728C8C8CABABABC3C3C3D4D4D4EAEAEADA + DADAA2A2A2A2A2A2A2A2A2A2A2A2D4D4D4AEAEAE7474748F8F8FADADADC4C4C4 + D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2ECECECDADADAA2A2A2A2A2 + A2A2A2A2A2A2A2D4D4D4AEAEAE7474748F8F8FADADADC4C4C4D5D5D5DEDEDEE2 + E2E2E1E1E1DEDEDED6D6D6E2E2E2DADADAA2A2A2A2A2A2A2A2A2A2A2A2CDCDCD + C5C5C59F9F9FE7E7E7C1C1C1A2A2A2A2A2A2A2A2A2A8A8A8F9F9F97A7A7A6B6B + 6B747474888888A2A2A2BCBCBCCFCFCFDADADAE0E0E0E2E2E2E1E1E1DCDCDCD3 + D3D3C4C4C4AFAFAF999999848484AAAAAAB6B6B6F5F5F5FFFFFFECECECD4D4D4 + D4D4D4A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2F3F3F3C9C9 + C9CDCDCDD6D6D6DCDCDCDFDFDFE8E8E8E6E6E6A2A2A2A2A2A2A2A2A2A2A2A2D4 + D4D4AFAFAF7474748F8F8FADADADC4C4C4D5D5D5DEDEDEDCDCDCD3D3D3C4C4C4 + AFAFAF999999848484AAAAAAB6B6B6F5F5F5FFFFFFECECECD4D4D4D4D4D4A2A2 + A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2F3F3F3C9C9C9CDCDCDD6 + D6D6DCDCDCDFDFDFE1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2F0F0 + F0A785EC7138E47138E47138E47138E4A785ECC5C5C56969696969697474748A + 8A8AA4A4A4BCBCBCCFCFCFDADADADFDFDFE1E1E1E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2EEEEEECCB9F27138E47138 + E47138E47138E48352E7F0ECF89A9A9A6A6A6A616161BABABABA9FEF7138E471 + 38E47138E47138E47A45E5E7DFF6C8C8C8BFBFBFD0D0D0DADADADFDFDFE1E1E1 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E1E1E1DEDEDE + D8D8D8D1D1D1CBCBCBC4C4C4BEBEBE949494B7B7B7E4E4E4E4E4E4E3E3E3E3E3 + E3E3E3E3E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + FBFBFBAFAFAFA3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3 + A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3 + A3A3A3A3A3A3A3A3A3A3A3A3A3A3DADADAB3B3B39F9F9FB9B9B9CDCDCDD9D9D9 + E0E0E0E2E2E2E2E2E2ECECECDADADAA3A3A3A3A3A3A3A3A3A3A3A3D4D4D4AEAE + AE7474748F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2EBEBEBDADADAA3A3A3A3A3A3A3A3A3A3A3A3C8C8C8C2C2C2737373 + 8F8F8FACACACD3D3D3E6E6E6A3A3A3A3A3A3A3A3A3A3A3A3C8C8C8C1C1C16D6D + 6D838383A2A2A2BCBCBCCFCFCFDCDCDCE1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E4E4E4F3F3F3A3A3A3A3A3A3A3A3A3A3A3A3B5B5B5E0E0E0707070 + 888888A8A8A8C1C1C1E3E3E3DADADAA3A3A3A3A3A3A3A3A3A3A3A3D4D4D4AEAE + AE7474748F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2EBEBEBDADADAA3A3A3A3A3A3A3A3A3A3A3A3C8C8C8C2C2C2737373 + 8F8F8FACACACC4C4C4D5D5D5EAEAEADADADAA3A3A3A3A3A3A3A3A3A3A3A3D4D4 + D4AEAEAE7474748F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2ECECECDADADAA3A3A3A3A3A3A3A3A3A3A3A3D4D4D4AEAEAE747474 + 8F8F8FADADADC4C4C4D5D5D5DEDEDEE2E2E2E1E1E1DCDCDCD1D1D1F7F7F7AFAF + AFA3A3A3A3A3A3A3A3A3A3A3A3EDEDEDA5A5A5A9A9A9D2D2D2E6E6E6A3A3A3A3 + A3A3A3A3A3A3A3A3D4D4D4B6B6B66B6B6B6E6E6E7E7E7E979797B1B1B1C7C7C7 + D6D6D6DEDEDEE1E1E1DFDFDFD9D9D9CCCCCCB9B9B9B3B3B3CFCFCFFFFFFFDADA + DAD4D4D4A9A9A9A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3 + A3A3A3A3A3A3A3A3CECECEE9E9E9D1D1D1D7D7D7DCDCDCDFDFDFE1E1E1E8E8E8 + E6E6E6A3A3A3A3A3A3A3A3A3A3A3A3D4D4D4AFAFAF7474748F8F8FADADADC4C4 + C4D5D5D5DCDCDCD9D9D9CCCCCCB9B9B9B3B3B3CFCFCFFFFFFFDADADAD4D4D4A9 + A9A9A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3 + A3A3A3CECECEE9E9E9D1D1D1D7D7D7DCDCDCDFDFDFE1E1E1E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E7E7E7E9E1F8733AE6733AE6733AE6733AE6 + 733AE6E9E1F88A8A8A6767676C6C6C7E7E7E979797B0B0B0C6C6C6D5D5D5DEDE + DEE1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2F1F1F1B294F0733AE6733AE6733AE6733AE6A07AEDD4D4D4 + 6F6F6F9C9C9CE0D4F7733AE6733AE6733AE6733AE6733AE6BCA1F1D0D0D0B8B8 + B8CCCCCCD7D7D7DEDEDEE1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E1E1E1DEDEDED8D8D8D1D1D1CBCBCBC4C4C4BEBEBE94 + 9494B7B7B7E4E4E4E4E4E4E3E3E3E3E3E3E3E3E3E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2F0F0F0D5D5D5A5A5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5ABABABF9F9 + F9949494A9A9A9C1C1C1D2D2D2DDDDDDE1E1E1E2E2E2E2E2E2ECECECDBDBDBA5 + A5A5A5A5A5A5A5A5A5A5A5D5D5D5AEAEAE7474748F8F8FADADADC4C4C4D5D5D5 + DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E7E7E7E7E7E7A5A5A5A5A5 + A5A5A5A5A5A5A5C9C9C9C2C2C2757575919191AFAFAFD4D4D4E7E7E7A5A5A5A5 + A5A5A5A5A5A5A5A5C9C9C9C1C1C16B6B6B7F7F7F9E9E9EB9B9B9CDCDCDDADADA + E1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2F3F3F3A5A5A5A5A5 + A5A5A5A5A5A5A5B1B1B1EBEBEB7373738D8D8DACACACC4C4C4E3E3E3DBDBDBA5 + A5A5A5A5A5A5A5A5A5A5A5D5D5D5AEAEAE7474748F8F8FADADADC4C4C4D5D5D5 + DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E7E7E7E7E7E7A5A5A5A5A5 + A5A5A5A5A5A5A5C9C9C9C2C2C2757575919191AFAFAFC7C7C7D6D6D6EBEBEBDB + DBDBA5A5A5A5A5A5A5A5A5A5A5A5D5D5D5AEAEAE7474748F8F8FADADADC4C4C4 + D5D5D5DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2EBEBEBDBDBDBA5A5A5A5A5 + A5A5A5A5A5A5A5D5D5D5AEAEAE747474909090AEAEAEC5C5C5D6D6D6DFDFDFE2 + E2E2DFDFDFD9D9D9D9D9D9E7E7E7A5A5A5A5A5A5A5A5A5A5A5A5BDBDBDDDDDDD + 999999B4B4B4C9C9C9FAFAFAB1B1B1A5A5A5A5A5A5A5A5A5B1B1B1EEEEEE6E6E + 6E6B6B6B7575758B8B8BA6A6A6BFBFBFD0D0D0DCDCDCE0E0E0DEDEDED5D5D5C9 + C9C9DEDEDEF3F3F3C9C9C9A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5CFCFCFECECECDBDBDBDBDB + DBDEDEDEE0E0E0E1E1E1E2E2E2E8E8E8E7E7E7A5A5A5A5A5A5A5A5A5A5A5A5D5 + D5D5AFAFAF7474748F8F8FADADADC4C4C4D5D5D5DBDBDBD5D5D5C9C9C9DEDEDE + F3F3F3C9C9C9A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5 + A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5CFCFCFECECECDBDBDBDBDBDBDEDEDEE0 + E0E0E1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2F1F1F1B596F2763DE9763DE9763DE9763DE9AC89F1C8C8C86A6A6A69696973 + 7373898989A3A3A3BCBCBCCECECED9D9D9DFDFDFE1E1E1E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E5E5E5F3EFFB8856 + EC763DE9763DE9763DE9763DE9CFBCF6BBBBBBDDDDDD9163ED763DE9763DE976 + 3DE9763DE99A70EEE0E0E0B2B2B2C4C4C4D4D4D4DCDCDCE1E1E1E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E1E1E1DEDEDE + D8D8D8D1D1D1CBCBCBC4C4C4BEBEBE949494B7B7B7E4E4E4E4E4E4E3E3E3E3E3 + E3E3E3E3E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E6E6E6F3F3F3A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6 + A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6 + A6A6A6A6A6A6A6A6A6A6A6CACACACACACA979797B2B2B2C8C8C8D6D6D6DEDEDE + E1E1E1E2E2E2E2E2E2ECECECDBDBDBA6A6A6A6A6A6A6A6A6A6A6A6D5D5D5ADAD + AD7272728D8D8DABABABC3C3C3D4D4D4DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E1E1E1E5E5E5E7E7E7A6A6A6A6A6A6A6A6A6A6A6A6CACACAC3C3C3797979 + 969696B2B2B2D7D7D7E7E7E7A6A6A6A6A6A6A6A6A6A6A6A6CACACAC1C1C16969 + 69797979979797B2B2B2C8C8C8D7D7D7DFDFDFE1E1E1E2E2E2E2E2E2E2E2E2E2 + E2E2E1E1E1E1E1E1F3F3F3A6A6A6A6A6A6A6A6A6A6A6A6B2B2B2EBEBEB787878 + 939393B0B0B0C7C7C7E5E5E5DBDBDBA6A6A6A6A6A6A6A6A6A6A6A6D5D5D5ADAD + AD7272728D8D8DABABABC3C3C3D4D4D4DEDEDEE2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E1E1E1E5E5E5E7E7E7A6A6A6A6A6A6A6A6A6A6A6A6CACACAC3C3C3797979 + 969696B2B2B2C8C8C8D7D7D7EBEBEBDBDBDBA6A6A6A6A6A6A6A6A6A6A6A6D5D5 + D5ADADAD7272728C8C8CABABABC3C3C3D4D4D4DEDEDEE2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2EBEBEBDBDBDBA6A6A6A6A6A6A6A6A6A6A6A6D5D5D5AEAEAE757575 + 919191AFAFAFC6C6C6D6D6D6DFDFDFE1E1E1DEDEDED4D4D4EBEBEBC4C4C4A6A6 + A6A6A6A6A6A6A6A6A6A6DBDBDBB8B8B8A5A5A5BEBEBED0D0D0ECECECD5D5D5A6 + A6A6A6A6A6A6A6A6A6A6A6DBDBDBABABAB6A6A6A6F6F6F818181999999B4B4B4 + C9C9C9D6D6D6DEDEDEDDDDDDD4D4D4E5E5E5D5D5D5A6A6A6A6A6A6A6A6A6A6A6 + A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6BE + BEBEE7E7E7EFEFEFE0E0E0DEDEDEDEDEDEE0E0E0E1E1E1E1E1E1E1E1E1E8E8E8 + E7E7E7A6A6A6A6A6A6A6A6A6A6A6A6D5D5D5AFAFAF7474748F8F8FADADADC4C4 + C4D5D5D5DADADAD4D4D4E5E5E5D5D5D5A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6 + A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6BEBEBEE7E7E7 + EFEFEFE0E0E0DEDEDEDEDEDEE0E0E0E1E1E1E1E1E1E1E1E1E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E5E5E5F5F1FD814CEC783FEB783FEB + 783FEB783FEBECE5FB9595956868686C6C6C7C7C7C969696AFAFAFC5C5C5D4D4 + D4DEDEDEE1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2EFEFEFE3D8FA783FEB783FEB783FEB783FEB814CEC + F5F1FDBFA5F5783FEB783FEB783FEB783FEB814CECECE5FBBBBBBBB5B5B5C9C9 + C9D7D7D7DEDEDEE1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2 + E2E2E2E2E2E2E2E2E2E2E1E1E1DEDEDED8D8D8D1D1D1CBCBCBC4C4C4BEBEBE94 + 9494B8B8B8E5E5E5E5E5E5E4E4E4E4E4E4E4E4E4E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3F8F8F8B8B8B8A7A7A7A7A7A7A7 + A7A7A7A7A7EDEDEDFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEADADADA7A7A7A7A7A7A7A7A7A7A7A7E1E1E1ADAD + ADA2A2A2BCBCBCCFCFCFDCDCDCE2E2E2E3E3E3E3E3E3E3E3E3ECECECDBDBDBA7 + A7A7A7A7A7A7A7A7A7A7A7D5D5D5ACACAC6F6F6F898989A7A7A7BFBFBFD2D2D2 + DDDDDDE2E2E2E2E2E2E3E3E3E3E3E3E2E2E2E0E0E0E6E6E6E1E1E1A7A7A7A7A7 + A7A7A7A7A7A7A7CACACAC3C3C37E7E7E9D9D9DB7B7B7DADADAE7E7E7A7A7A7A7 + A7A7A7A7A7A7A7A7CACACAC2C2C26767677575758E8E8EAAAAAAC2C2C2D3D3D3 + DEDEDEE2E2E2E3E3E3E3E3E3E3E3E3E2E2E2E0E0E0DEDEDEF2F2F2A7A7A7A7A7 + A7A7A7A7A7A7A7B8B8B8E1E1E17F7F7F9C9C9CB7B7B7CCCCCCE7E7E7DBDBDBA7 + A7A7A7A7A7A7A7A7A7A7A7D5D5D5ACACAC6F6F6F898989A7A7A7BFBFBFD2D2D2 + DDDDDDE2E2E2E2E2E2E3E3E3E3E3E3E2E2E2E0E0E0E6E6E6E1E1E1A7A7A7A7A7 + A7A7A7A7A7A7A7CACACAC3C3C37E7E7E9D9D9DB7B7B7CDCDCDDADADAEBEBEBDB + DBDBA7A7A7A7A7A7A7A7A7A7A7A7D5D5D5ACACAC6F6F6F888888A6A6A6BFBFBF + D1D1D1DDDDDDE1E1E1E2E2E2E3E3E3E3E3E3E2E2E2EBEBEBDBDBDBA7A7A7A7A7 + A7A7A7A7A7A7A7D5D5D5ADADAD777777949494B1B1B1C7C7C7D7D7D7E0E0E0E1 + E1E1DBDBDBD5D5D5F2F2F2A7A7A7A7A7A7A7A7A7A7A7A7ADADADF5F5F5959595 + B0B0B0C7C7C7D7D7D7E1E1E1F8F8F8ADADADA7A7A7A7A7A7A7A7A7BEBEBEDBDB + DB6D6D6D6C6C6C7777778F8F8FAAAAAAC2C2C2D2D2D2DDDDDDDCDCDCEBEBEBD5 + D5D5A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7 + A7A7A7A7A7A7CACACAD5D5D5F2F2F2F5F5F5E9E9E9DFDFDFDEDEDEDDDDDDDDDD + DDDDDDDDDFDFDFDFDFDFE1E1E1E8E8E8E7E7E7A7A7A7A7A7A7A7A7A7A7A7A7D5 + D5D5AFAFAF7575758F8F8FAEAEAEC5C5C5D6D6D6DADADAEBEBEBD5D5D5A7A7A7 + A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7A7 + A7CACACAD5D5D5F2F2F2F5F5F5E9E9E9DFDFDFDEDEDEDDDDDDDDDDDDDDDDDDDF + DFDFDFDFDFE1E1E1E2E2E2E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3F1F1F1C1A6F77B42EE7B42EE7B42EE7B42EEA781F3D2D2D26C6C6C69 + 6969747474888888A3A3A3BBBBBBCECECEDADADAE0E0E0E2E2E2E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3F2F2 + F2B89AF57B42EE7B42EE7B42EE7B42EE9E74F27B42EE7B42EE7B42EE7B42EE7B + 42EECAB3F8C2C2C29D9D9DB7B7B7CCCCCCDADADAE0E0E0E2E2E2E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E2E2E2DFDFDF + D9D9D9D2D2D2CCCCCCC5C5C5BFBFBF959595B8B8B8E5E5E5E5E5E5E4E4E4E4E4 + E4E4E4E4E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3F0F0F0D6D6D6A8A8A8A8A8A8A8A8A8A8A8A8D0D0D0BBBBBB6767676E6E + 6E8282829E9E9EB8B8B8CDCDCDDADADADFDFDFDDDDDDE0E0E0E1E1E1A8A8A8A8 + A8A8A8A8A8A8A8A8AEAEAEF5F5F58F8F8FACACACC4C4C4D5D5D5DFDFDFE2E2E2 + E3E3E3E3E3E3E3E3E3ECECECDCDCDCA8A8A8A8A8A8A8A8A8A8A8A8D6D6D6AAAA + AA6A6A6A8282829E9E9EB6B6B6C9C9C9D6D6D6DDDDDDDFDFDFE1E1E1E2E2E2E0 + E0E0DDDDDDE4E4E4DCDCDCA8A8A8A8A8A8A8A8A8A8A8A8D0D0D0BBBBBB868686 + A4A4A4BDBDBDD9D9D9EDEDEDA8A8A8A8A8A8A8A8A8A8A8A8BFBFBFD7D7D76666 + 666E6E6E8383839E9E9EB6B6B6CACACAD7D7D7DEDEDEE0E0E0E2E2E2E1E1E1DF + DFDFDBDBDBDADADAEDEDEDA8A8A8A8A8A8A8A8A8A8A8A8BFBFBFD9D9D9888888 + A5A5A5BFBFBFD0D0D0E8E8E8DCDCDCA8A8A8A8A8A8A8A8A8A8A8A8D6D6D6AAAA + AA6A6A6A8282829E9E9EB6B6B6C9C9C9D6D6D6DDDDDDDFDFDFE1E1E1E2E2E2E0 + E0E0DDDDDDE4E4E4DCDCDCA8A8A8A8A8A8A8A8A8A8A8A8D0D0D0BBBBBB868686 + A4A4A4BDBDBDD0D0D0DDDDDDEBEBEBDCDCDCA8A8A8A8A8A8A8A8A8A8A8A8D6D6 + D6AAAAAA6A6A6A8080809D9D9DB5B5B5C7C7C7D5D5D5DCDCDCDFDFDFE1E1E1E2 + E2E2E1E1E1E9E9E9DCDCDCA8A8A8A8A8A8A8A8A8A8A8A8D6D6D6ADADAD7A7A7A + 979797B5B5B5CACACAD9D9D9E0E0E0DFDFDFD7D7D7E4E4E4D0D0D0A8A8A8A8A8 + A8A8A8A8A8A8A8D6D6D6C4C4C4A1A1A1BABABACECECEDADADAE1E1E1F3F3F3CA + CACAA8A8A8A8A8A8A8A8A8A8A8A8E7E7E79797976A6A6A7070708484849E9E9E + B7B7B7CCCCCCD9D9D9E1E1E1F3F3F3A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8A8A8A8A8A8C5C5C5D6D6D6DCDCDCFEFEFEFEFEFEF2F2F2EEEEEEE4E4E4DF + DFDFDDDDDDD9D9D9D6D6D6D4D4D4D3D3D3D5D5D5D8D8D8DDDDDDDFDFDFE7E7E7 + E7E7E7A8A8A8A8A8A8A8A8A8A8A8A8D6D6D6AFAFAF7575758F8F8FAEAEAEC5C5 + C5D6D6D6E1E1E1F3F3F3A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8A8 + A8A8C5C5C5D6D6D6DCDCDCFEFEFEFEFEFEF2F2F2EEEEEEE4E4E4DFDFDFDDDDDD + D9D9D9D6D6D6D4D4D4D3D3D3D5D5D5D8D8D8DDDDDDDFDFDFE2E2E2E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E5E5E5F6F3FE8650F17D44F0 + 7D44F07D44F07D44F0DCCDFB9F9F9F6969696D6D6D7D7D7D959595AFAFAFC5C5 + C5D5D5D5DEDEDEE2E2E2E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E5E5E5F8F8F89769F37D44F07D44F07D44F0 + 7D44F07D44F07D44F07D44F07D44F0A882F5CCCCCC7D7D7D979797B2B2B2C7C7 + C7D7D7D7DFDFDFE2E2E2E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E2E2E2DFDFDFD9D9D9D2D2D2CCCCCCC5C5C5BFBFBF95 + 9595B8B8B8E5E5E5E5E5E5E4E4E4E4E4E4E4E4E4E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E5E5E5F7F7F7AAAAAAAAAAAAAA + AAAAAAAAAAB0B0B0F4F4F46868686A6A6A7A7A7A949494AFAFAFC7C7C7D6D6D6 + DDDDDDD8D8D8E9E9E9CBCBCBAAAAAAAAAAAAAAAAAAAAAAAAD1D1D1C2C2C29A9A + 9AB5B5B5CACACAD9D9D9E0E0E0E3E3E3E3E3E3E3E3E3E3E3E3ECECECDCDCDCAA + AAAAAAAAAAAAAAAAAAAAAAD6D6D6A8A8A8636363767676909090A7A7A7BABABA + C8C8C8D1D1D1D6D6D6D8D8D8D9D9D9D7D7D7D2D2D2E0E0E0D6D6D6AAAAAAAAAA + AAAAAAAAAAAAAAD6D6D6B5B5B58F8F8FACACACC4C4C4D8D8D8F7F7F7AAAAAAAA + AAAAAAAAAAAAAAAAB5B5B5EAEAEA6767676969697777778E8E8EA6A6A6BABABA + CACACAD3D3D3D7D7D7DADADAD9D9D9D7D7D7CFCFCFD6D6D6E1E1E1AAAAAAAAAA + AAAAAAAAAAAAAACBCBCBC9C9C9949494AFAFAFC6C6C6D5D5D5E9E9E9DCDCDCAA + AAAAAAAAAAAAAAAAAAAAAAD6D6D6A8A8A8636363767676909090A7A7A7BABABA + C8C8C8D1D1D1D6D6D6D8D8D8D9D9D9D7D7D7D2D2D2E0E0E0D6D6D6AAAAAAAAAA + AAAAAAAAAAAAAAD6D6D6B5B5B58F8F8FACACACC4C4C4D5D5D5DFDFDFEBEBEBDC + DCDCAAAAAAAAAAAAAAAAAAAAAAAAD6D6D6A8A8A86262627676768E8E8EA5A5A5 + B8B8B8C7C7C7CFCFCFD5D5D5D8D8D8DADADAD7D7D7E3E3E3DCDCDCAAAAAAAAAA + AAAAAAAAAAAAAAD6D6D6AFAFAF7F7F7F9D9D9DB8B8B8CDCDCDDADADAE0E0E0DD + DDDDD3D3D3F7F7F7B0B0B0AAAAAAAAAAAAAAAAAAAAAAAAF2F2F29F9F9FACACAC + C3C3C3D4D4D4DEDEDEE2E2E2E8E8E8ECECECAAAAAAAAAAAAAAAAAAAAAAAACBCB + CBC7C7C76B6B6B6C6C6C7A7A7A929292ADADADC4C4C4D5D5D5EEEEEECBCBCBAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAC0C0C0E1E1E1FDFDFDE1E1E1DCDCDCE1E1E1 + D7D7D7DADADADADADADADADAD7D7D7D5D5D5D0D0D0CBCBCBC7C7C7C5C5C5C5C5 + C5C8C8C8D0D0D0D7D7D7DDDDDDE7E7E7E7E7E7AAAAAAAAAAAAAAAAAAAAAAAAD6 + D6D6AEAEAE7575758F8F8FAEAEAEC5C5C5D6D6D6EFEFEFCBCBCBAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC0C0C0E1E1E1FDFDFDE1E1E1DCDCDCE1E1E1D7D7D7DADA + DADADADADADADAD7D7D7D5D5D5D0D0D0CBCBCBC7C7C7C5C5C5C5C5C5C8C8C8D0 + D0D0D7D7D7DDDDDDE1E1E1E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3F2F2F2CCB5FA8047F38047F38047F38047F3A278F6DCDCDC6D + 6D6D696969737373878787A2A2A2BABABACDCDCDDADADAE0E0E0E2E2E2E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E2E2E2DFDF + DFE7E7E7EEE6FD8047F38047F38047F38047F38047F38047F38047F38853F4EE + E6FD8B8B8B7676768E8E8EA7A7A7BEBEBECFCFCFDADADAE0E0E0E2E2E2E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E2E2E2DFDFDF + D9D9D9D2D2D2CCCCCCC5C5C5BFBFBF959595B8B8B8E5E5E5E5E5E5E4E4E4E4E4 + E4E4E4E4E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3F3F3F3C6C6C6ABABABABABABABABABABABABE6E6E69292926868 + 687373738A8A8AA6A6A6BFBFBFD0D0D0D8D8D8D7D7D7F7F7F7B0B0B0ABABABAB + ABABABABABABABABECECEC9E9E9EA5A5A5BEBEBED0D0D0DDDDDDE2E2E2E3E3E3 + E3E3E3E3E3E3E3E3E3EBEBEBDCDCDCABABABABABABABABABABABABD6D6D6A5A5 + A55C5C5C6A6A6A808080959595A6A6A6B5B5B5BFBFBFC5C5C5C9C9C9CACACAC7 + C7C7C0C0C0DFDFDFCBCBCBABABABABABABABABABABABABE1E1E1A9A9A99A9A9A + B6B6B6CACACAD8D8D8F8F8F8B6B6B6ABABABABABABABABABABABABF7F7F77777 + 776767676E6E6E7E7E7E939393A6A6A6B6B6B6C2C2C2C8C8C8CACACACACACAC6 + C6C6BDBDBDD8D8D8D1D1D1ABABABABABABABABABABABABD6D6D6BEBEBEA1A1A1 + BABABACDCDCDDADADAEAEAEADCDCDCABABABABABABABABABABABABD6D6D6A5A5 + A55C5C5C6A6A6A808080959595A6A6A6B5B5B5BFBFBFC5C5C5C9C9C9CACACAC7 + C7C7C0C0C0DFDFDFCBCBCBABABABABABABABABABABABABE1E1E1A9A9A99A9A9A + B6B6B6CACACAD8D8D8E0E0E0EBEBEBDCDCDCABABABABABABABABABABABABD6D6 + D6A4A4A45B5B5B6A6A6A7F7F7F939393A5A5A5B4B4B4BEBEBEC5C5C5C9C9C9CA + CACAC8C8C8DCDCDCD6D6D6ABABABABABABABABABABABABD6D6D6B1B1B1878787 + A5A5A5BEBEBED0D0D0DDDDDDDFDFDFD7D7D7DEDEDEDCDCDCABABABABABABABAB + ABABABABC6C6C6D3D3D39C9C9CB6B6B6CBCBCBD9D9D9E0E0E0E3E3E3E3E3E3F5 + F5F5C1C1C1ABABABABABABABABABABABABF1F1F1818181696969727272868686 + A1A1A1BABABACECECEFAFAFAB0B0B0ABABABABABABABABABABABABD1D1D1D4D4 + D49F9F9F8686869D9D9DB0B0B0BFBFBFC8C8C8CCCCCCCDCDCDCBCBCBC8C8C8C4 + C4C4BEBEBEB6B6B6B0B0B0AFAFAFB1B1B1B8B8B8C5C5C5D0D0D0D9D9D9E6E6E6 + E6E6E6ABABABABABABABABABABABABD6D6D6AEAEAE7575758F8F8FAEAEAEC5C5 + C5D6D6D6FAFAFAB0B0B0ABABABABABABABABABABABABD1D1D1D4D4D49F9F9F86 + 86869D9D9DB0B0B0BFBFBFC8C8C8CCCCCCCDCDCDCBCBCBC8C8C8C4C4C4BEBEBE + B6B6B6B0B0B0AFAFAFB1B1B1B8B8B8C5C5C5D0D0D0D9D9D9DFDFDFE3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3FBFBFB9361F6 + 8249F58249F58249F58249F5DECEFCA1A1A16A6A6A6D6D6D7C7C7C949494AEAE + AEC5C5C5D4D4D4DEDEDEE2E2E2E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E2E2E2E0E0E0DADADACFCFCFE5E5E5C5AAFA8249F58249F5 + 8249F58249F58249F58249F5D5C2FCB1B1B16363636F6F6F828282989898B0B0 + B0C5C5C5D4D4D4DDDDDDE1E1E1E2E2E2E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3 + E3E3E3E3E3E3E3E3E3E3E2E2E2DFDFDFD9D9D9D2D2D2CCCCCCC5C5C5BFBFBF95 + 9595B9B9B9E6E6E6E6E6E6E5E5E5E5E5E5E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4ECECECE2E2E2ADADADAD + ADADADADADADADADCDCDCDC4C4C46868686E6E6E8181819C9C9CB7B7B7CBCBCB + D3D3D3E1E1E1DCDCDCADADADADADADADADADADADADBDBDBDE2E2E2939393AFAF + AFC6C6C6D7D7D7E0E0E0E3E3E3E4E4E4E4E4E4E4E4E4E4E4E4ECECECDCDCDCAD + ADADADADADADADADADADADD7D7D7A3A3A3565656616161727272838383939393 + A0A0A0A9A9A9B0B0B0B4B4B4B6B6B6B2B2B2ABABABE9E9E9BDBDBDADADADADAD + ADADADADADADADECECECA3A3A3A8A8A8C0C0C0D2D2D2DDDDDDF3F3F3C7C7C7AD + ADADADADADADADADADADADE2E2E2A4A4A46C6C6C6A6A6A727272808080909090 + 9F9F9FABABABB3B3B3B6B6B6B5B5B5B0B0B0A6A6A6E8E8E8BDBDBDADADADADAD + ADADADADADADADECECECACACACB0B0B0C6C6C6D5D5D5DEDEDEEBEBEBDCDCDCAD + ADADADADADADADADADADADD7D7D7A3A3A3565656616161727272838383939393 + A0A0A0A9A9A9B0B0B0B4B4B4B6B6B6B2B2B2ABABABE9E9E9BDBDBDADADADADAD + ADADADADADADADECECECA3A3A3A8A8A8C0C0C0D2D2D2DDDDDDE2E2E2ECECECDC + DCDCADADADADADADADADADADADADD7D7D7A3A3A3565656616161727272838383 + 9191919D9D9DA8A8A8AEAEAEB4B4B4B6B6B6B3B3B3D6D6D6D2D2D2ADADADADAD + ADADADADADADADDCDCDCADADAD939393AEAEAEC6C6C6D6D6D6DEDEDEDEDEDED4 + D4D4F1F1F1BDBDBDADADADADADADADADADADADADE7E7E7A9A9A9A8A8A8C0C0C0 + D3D3D3DEDEDEE3E3E3E4E4E4E4E4E4EEEEEEDCDCDCADADADADADADADADADADAD + ADD7D7D7BBBBBB6A6A6A6C6C6C7C7C7C959595B1B1B1CBCBCBF7F7F7ADADADAD + ADADADADADADADADB2B2B2F3F3F37B7B7B6C6C6C7A7A7A8B8B8B9C9C9CAAAAAA + B3B3B3B6B6B6B8B8B8B6B6B6B3B3B3ADADADA5A5A59C9C9C9797979797979D9D + 9DA9A9A9BCBCBCCBCBCBD7D7D7E6E6E6E7E7E7ADADADADADADADADADADADADD7 + D7D7AEAEAE757575909090AEAEAEC6C6C6D9D9D9F7F7F7ADADADADADADADADAD + ADADADB2B2B2F3F3F37B7B7B6C6C6C7A7A7A8B8B8B9C9C9CAAAAAAB3B3B3B6B6 + B6B8B8B8B6B6B6B3B3B3ADADADA5A5A59C9C9C9797979797979D9D9DA9A9A9BC + BCBCCBCBCBD7D7D7E0E0E0E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4F0F0F0CEB7FC854CF8854CF8854CF8854CF8A57BFADC + DCDC6E6E6E6A6A6A727272878787A1A1A1BABABACECECEDADADAE1E1E1E3E3E3 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3E2E2E2DEDEDED5D5 + D5C6C6C6DEDEDEC6ABFB854CF8854CF8854CF8854CF8854CF88D58F8EEE6FD9A + 9A9A6868686B6B6B7777778A8A8AA1A1A1B8B8B8CBCBCBD8D8D8E0E0E0E3E3E3 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3E0E0E0 + DADADAD3D3D3CDCDCDC6C6C6BFBFBF969696B9B9B9E6E6E6E6E6E6E5E5E5E5E5 + E5E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4F9F9F9B3B3B3AEAEAEAEAEAEAEAEAEB3B3B3F6F6F67474 + 746A6A6A797979929292ADADADC3C3C3CBCBCBE9E9E9C8C8C8AEAEAEAEAEAEAE + AEAEAEAEAED7D7D7BABABA9D9D9DB8B8B8CDCDCDDBDBDBE1E1E1E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4EBEBEBDCDCDCAEAEAEAEAEAEAEAEAEAEAEAED7D7D7A5A5 + A55959596161616D6D6D7979798383838B8B8B9393939696969A9A9A9A9A9A96 + 9696A5A5A5ECECECAEAEAEAEAEAEAEAEAEAEAEAEB3B3B3F3F3F39D9D9DB6B6B6 + CACACAD7D7D7E0E0E0EBEBEBE1E1E1AEAEAEAEAEAEAEAEAEAEAEAEC8C8C8D5D5 + D57777776D6D6D6C6C6C7272727B7B7B8787879090909797979A9A9A99999994 + 9494A8A8A8F1F1F1AEAEAEAEAEAEAEAEAEAEAEAEB8B8B8EDEDEDA9A9A9BEBEBE + CFCFCFDBDBDBE0E0E0EBEBEBDCDCDCAEAEAEAEAEAEAEAEAEAEAEAED7D7D7A5A5 + A55959596161616D6D6D7979798383838B8B8B9393939696969A9A9A9A9A9A96 + 9696A5A5A5ECECECAEAEAEAEAEAEAEAEAEAEAEAEB3B3B3F3F3F39D9D9DB6B6B6 + CACACAD7D7D7E0E0E0E3E3E3EBEBEBDCDCDCAEAEAEAEAEAEAEAEAEAEAEAED7D7 + D7A3A3A35555555E5E5E6C6C6C7878788383838B8B8B9191919696969A9A9A9B + 9B9B989898D7D7D7C8C8C8AEAEAEAEAEAEAEAEAEAEAEAEE1E1E1ACACACA0A0A0 + B9B9B9CDCDCDD9D9D9E0E0E0DBDBDBDBDBDBE6E6E6AEAEAEAEAEAEAEAEAEAEAE + AEB8B8B8EAEAEA989898B3B3B3C8C8C8D8D8D8E0E0E0E3E3E3E4E4E4E4E4E4E4 + E4E4F9F9F9B3B3B3AEAEAEAEAEAEAEAEAEB3B3B3F6F6F67979796D6D6D797979 + 8F8F8FAAAAAACACACAF1F1F1AEAEAEAEAEAEAEAEAEAEAEAEC3C3C3D9D9D97070 + 706A6A6A7070707A7A7A8585859090909797979B9B9B9C9C9C9B9B9B96969691 + 91918A8A8A8383838181818585858F8F8FA0A0A0B6B6B6C8C8C8D6D6D6E6E6E6 + E6E6E6AEAEAEAEAEAEAEAEAEAEAEAED7D7D7B0B0B07A7A7A939393B0B0B0C7C7 + C7DCDCDCF1F1F1AEAEAEAEAEAEAEAEAEAEAEAEC3C3C3D9D9D97070706A6A6A70 + 70707A7A7A8585859090909797979B9B9B9C9C9C9B9B9B9696969191918A8A8A + 8383838181818585858F8F8FA0A0A0B6B6B6C8C8C8D6D6D6E0E0E0E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4FAFAFA + 9866FB884FFB884FFB884FFB884FFBDFCFFDABABAB6A6A6A6D6D6D7B7B7B9494 + 94ADADADC5C5C5D5D5D5DEDEDEE3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E3E3E3E0E0E0D8D8D8CBCBCBD3D3D3EEE7FE884FFB884FFB884FFB + 884FFB884FFB884FFB884FFBA77EFCDBDBDB7A7A7A6C6C6C6F6F6F7B7B7B9090 + 90A8A8A8BEBEBED0D0D0DBDBDBE0E0E0E3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E3E3E3E0E0E0DADADAD3D3D3CDCDCDC6C6C6BFBFBF96 + 9696B9B9B9E6E6E6E6E6E6E5E5E5E5E5E5E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4F1F1F1CECECEB0 + B0B0B0B0B0B0B0B0B0B0B0E1E1E19C9C9C696969727272888888A4A4A4B9B9B9 + C6C6C6F5F5F5B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0F0F0F09A9A9AA8A8A8C0C0 + C0D3D3D3DEDEDEE3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4EBEBEBDCDCDCB0 + B0B0B0B0B0B0B0B0B0B0B0D3D3D3C9C9C98B8B8B6A6A6A7373737A7A7A7E7E7E + 8181818383838383838383838282827E7E7EC6C6C6CECECEB0B0B0B0B0B0B0B0 + B0B0B0B0CECECED3D3D3AEAEAEC3C3C3D3D3D3DDDDDDE2E2E2E4E4E4F8F8F8B5 + B5B5B0B0B0B0B0B0B0B0B0B0B0B0EBEBEBBCBCBC7979797171716E6E6E717171 + 7575757A7A7A7F7F7F8080808080807D7D7DCFCFCFC9C9C9B0B0B0B0B0B0B0B0 + B0B0B0B0D7D7D7CDCDCDBABABACBCBCBD7D7D7DFDFDFE3E3E3EBEBEBDCDCDCB0 + B0B0B0B0B0B0B0B0B0B0B0D3D3D3C9C9C98B8B8B6A6A6A7373737A7A7A7E7E7E + 8181818383838383838383838282827E7E7EC6C6C6CECECEB0B0B0B0B0B0B0B0 + B0B0B0B0CECECED3D3D3AEAEAEC3C3C3D3D3D3DDDDDDE2E2E2E4E4E4EBEBEBDC + DCDCB0B0B0B0B0B0B0B0B0B0B0B0CECECECFCFCF8D8D8D6262626F6F6F787878 + 7D7D7D818181838383838383838383838383808080F1F1F1B5B5B5B0B0B0B0B0 + B0B0B0B0B0B0B0EBEBEBAAAAAAAEAEAEC4C4C4D3D3D3DEDEDEE0E0E0DADADAEB + EBEBC9C9C9B0B0B0B0B0B0B0B0B0B0B0B0D7D7D7C0C0C0A6A6A6BEBEBED0D0D0 + DCDCDCE2E2E2E4E4E4E4E4E4E4E4E4E4E4E4EFEFEFD7D7D7B0B0B0B0B0B0B0B0 + B0B0B0B0DCDCDCB5B5B57676767C7C7C8E8E8EA7A7A7BFBFBFFAFAFAB0B0B0B0 + B0B0B0B0B0B0B0B0BFBFBFE4E4E47D7D7D7272726F6F6F7171717575757A7A7A + 7F7F7F8282828383838181817E7E7E7A7A7A777777A0A0A0D7D7D7A5A5A58B8B + 8B9D9D9DB6B6B6C8C8C8D7D7D7E5E5E5E6E6E6B0B0B0B0B0B0B0B0B0B0B0B0D7 + D7D7B5B5B58383839A9A9AB5B5B5CACACAD8D8D8FAFAFAB0B0B0B0B0B0B0B0B0 + B0B0B0BFBFBFE4E4E47D7D7D7272726F6F6F7171717575757A7A7A7F7F7F8282 + 828383838181817E7E7E7A7A7A777777A0A0A0D7D7D7A5A5A58B8B8B9D9D9DB6 + B6B6C8C8C8D7D7D7E0E0E0E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4EFEFEFDECFFD8A51FD8A51FD8A51FD8A51FDA1 + 73FDE4E4E47070706A6A6A727272868686A0A0A0B9B9B9CECECEDADADAE0E0E0 + E3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3E0E0E0DBDBDBD0D0D0C2C2 + C2ECECECA173FD8A51FD8A51FD8A51FD8A51FD8A51FD8A51FD8A51FD8A51FDC7 + ADFDCACACA7272726C6C6C727272818181989898B0B0B0C5C5C5D4D4D4DEDEDE + E2E2E2E3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3E0E0E0 + DADADAD3D3D3CDCDCDC6C6C6BFBFBF969696B9B9B9E6E6E6E6E6E6E5E5E5E5E5 + E5E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E9E9E9E5E5E5B1B1B1B1B1B1B1B1B1B1B1B1C9C9C9CBCB + CB6969696D6D6D7F7F7F999999AEAEAED5D5D5D7D7D7B1B1B1B1B1B1B1B1B1B1 + B1B1C4C4C4D6D6D6959595B2B2B2C8C8C8D7D7D7E0E0E0E3E3E3E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4EBEBEBDCDCDCB1B1B1B1B1B1B1B1B1B1B1B1B1B1B1C9C9 + C9EFEFEFBDBDBD8484848686868686868383838080807C7C7C7A7A7A777777B0 + B0B0EAEAEAB1B1B1B1B1B1B1B1B1B1B1B1B1B1B1E5E5E5C0C0C0BEBEBECFCFCF + D9D9D9E0E0E0E3E3E3E4E4E4EEEEEED7D7D7B1B1B1B1B1B1B1B1B1B1B1B1BABA + BAF3F3F3B6B6B68080807777777272727272727272727474747575757C7C7CC1 + C1C1DCDCDCB1B1B1B1B1B1B1B1B1B1B1B1B6B6B6F3F3F3BCBCBCC8C8C8D6D6D6 + DEDEDEE1E1E1E3E3E3EBEBEBDCDCDCB1B1B1B1B1B1B1B1B1B1B1B1B1B1B1C9C9 + C9EFEFEFBDBDBD8484848686868686868383838080807C7C7C7A7A7A777777B0 + B0B0EAEAEAB1B1B1B1B1B1B1B1B1B1B1B1B1B1B1E5E5E5C0C0C0BEBEBECFCFCF + D9D9D9E0E0E0E3E3E3E4E4E4EAEAEADCDCDCB1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1C4C4C4EFEFEFBEBEBE8181818181818585858484848181817D7D7D7A7A7A78 + 7878B1B1B1E5E5E5B1B1B1B1B1B1B1B1B1B1B1B1B6B6B6F1F1F1A9A9A9BEBEBE + CECECED9D9D9E0E0E0E0E0E0DDDDDDEFEFEFB1B1B1B1B1B1B1B1B1B1B1B1B1B1 + B1F3F3F3A3A3A3B5B5B5C8C8C8D6D6D6E0E0E0E3E3E3E4E4E4E4E4E4E4E4E4E4 + E4E4E7E7E7EFEFEFB1B1B1B1B1B1B1B1B1B1B1B1BABABAE9E9E9848484888888 + 949494AAAAAABFBFBFEDEDEDC4C4C4B1B1B1B1B1B1B1B1B1B1B1B1EFEFEFB8B8 + B8828282787878747474727272737373757575757575757575757575747474A8 + A8A8DDDDDDE0E0E0C4C4C4D9D9D9919191A5A5A5BBBBBBCCCCCCD8D8D8E6E6E6 + E5E5E5B1B1B1B1B1B1B1B1B1B1B1B1D7D7D7BCBCBC909090A4A4A4BBBBBBCECE + CEDADADAF2F2F2C4C4C4B1B1B1B1B1B1B1B1B1B1B1B1EFEFEFB8B8B882828278 + 7878747474727272737373757575757575757575757575747474A8A8A8DDDDDD + E0E0E0C4C4C4D9D9D9919191A5A5A5BBBBBBCCCCCCD8D8D8E0E0E0E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + F5F5F5AB82FE8E56FF8E56FF8E56FF8E56FFCFB9FDB4B4B46B6B6B6D6D6D7B7B + 7B939393ADADADC3C3C3D4D4D4DEDEDEE3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E3 + E3E3E2E2E2DEDEDED5D5D5C6C6C6DCDCDCC8AEFD8E56FF8E56FF8E56FF8E56FF + 9561FF9561FF8E56FF8E56FF8E56FF8E56FFECE5FCAEAEAE7070706C6C6C7575 + 758888889F9F9FB6B6B6CACACAD7D7D7DFDFDFE3E3E3E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E3E3E3E0E0E0DADADAD3D3D3CDCDCDC6C6C6BFBFBF96 + 9696B9B9B9E7E7E7E7E7E7E6E6E6E6E6E6E6E6E6E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F4F4F4BC + BCBCB3B3B3B3B3B3B3B3B3B3B3B3F2F2F27474746B6B6B7878788E8E8EA2A2A2 + E8E8E8C1C1C1B3B3B3B3B3B3B3B3B3B3B3B3DCDCDCB2B2B2A1A1A1BCBCBCCFCF + CFDCDCDCE3E3E3E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5ECECECDCDCDCB3 + B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B8B8B8DCDCDCF1F1F1CBCBCBB2B2B2 + 9393938B8B8B848484979797C4C4C4E9E9E9BCBCBCB3B3B3B3B3B3B3B3B3B3B3 + B3C5C5C5E4E4E4BEBEBECECECED9D9D9E0E0E0E3E3E3E5E5E5E5E5E5E6E6E6F4 + F4F4BCBCBCB3B3B3B3B3B3B3B3B3B3B3B3C1C1C1EEEEEECFCFCFAEAEAE818181 + 7C7C7C7979797E7E7EB3B3B3DDDDDDD7D7D7B3B3B3B3B3B3B3B3B3B3B3B3B3B3 + B3D7D7D7DBDBDBCACACAD6D6D6DEDEDEE1E1E1E4E4E4E5E5E5ECECECDCDCDCB3 + B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B8B8B8DCDCDCF1F1F1CBCBCBB2B2B2 + 9393938B8B8B848484979797C4C4C4E9E9E9BCBCBCB3B3B3B3B3B3B3B3B3B3B3 + B3C5C5C5E4E4E4BEBEBECECECED9D9D9E0E0E0E3E3E3E5E5E5E5E5E5EAEAEADC + DCDCB3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3D7D7D7F7F7F7CECECE + B6B6B69393938E8E8E868686888888BCBCBCF2F2F2BCBCBCB3B3B3B3B3B3B3B3 + B3B3B3B3CECECED8D8D8BCBCBCCCCCCCD8D8D8DFDFDFE3E3E3E1E1E1EAEAEAD7 + D7D7B3B3B3B3B3B3B3B3B3B3B3B3CECECED5D5D5B1B1B1C3C3C3D1D1D1DCDCDC + E2E2E2E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F1F1F1CACACAB3B3B3B3B3 + B3B3B3B3B3B3B3E5E5E5B7B7B79A9A9AA3A3A3B3B3B3C5C5C5E1E1E1DCDCDCB3 + B3B3B3B3B3B3B3B3B3B3B3C1C1C1EEEEEED0D0D0B0B0B08383837E7E7E7A7A7A + 787878888888B3B3B3C4C4C4F7F7F7DCDCDCC1C1C1B3B3B3BCBCBCEAEAEAA1A1 + A1B3B3B3C5C5C5D3D3D3DDDDDDE7E7E7E5E5E5B3B3B3B3B3B3B3B3B3B3B3B3D7 + D7D7C6C6C6A3A3A3B3B3B3C5C5C5D3D3D3DDDDDDEBEBEBDCDCDCB3B3B3B3B3B3 + B3B3B3B3B3B3C1C1C1EEEEEED0D0D0B0B0B08383837E7E7E7A7A7A7878788888 + 88B3B3B3C4C4C4F7F7F7DCDCDCC1C1C1B3B3B3BCBCBCEAEAEAA1A1A1B3B3B3C5 + C5C5D3D3D3DDDDDDE2E2E2E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5ECECECDECFFB9059FF9059FF9059FF90 + 59FF9E6EFEEAEAEA7171716B6B6B737373868686A0A0A0B9B9B9CECECEDADADA + E1E1E1E4E4E4E5E5E5E5E5E5E5E5E5E4E4E4E1E1E1D9D9D9CCCCCCD2D2D2E5DA + FB9059FF9059FF9059FF9059FF9059FFD0BAFCD0BAFC9059FF9059FF9059FF90 + 59FFA579FEE4E4E48888886E6E6E6E6E6E7A7A7A8F8F8FA7A7A7BDBDBDCFCFCF + DBDBDBE1E1E1E4E4E4E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E4E4E4E1E1E1 + DBDBDBD4D4D4CECECEC6C6C6C0C0C0969696B9B9B9E7E7E7E7E7E7E6E6E6E6E6 + E6E6E6E6E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5EDEDEDD7D7D7B4B4B4B4B4B4B4B4B4B4B4B4D7D7 + D7ADADAD696969717171828282A0A0A0EDEDEDB4B4B4B4B4B4B4B4B4B4B4B4B8 + B8B8F2F2F2959595ACACACC4C4C4D5D5D5E0E0E0E4E4E4E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5EBEBEBDCDCDCB4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4 + B4B4B4B4B4B4B4B8B8B8D7D7D7E4E4E4F6F6F6F6F6F6F6F6F6E9E9E9D3D3D3B4 + B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4E9E9E9D3D3D3CFCFCFD8D8D8DFDFDF + E2E2E2E4E4E4E5E5E5E5E5E5E5E5E5EDEDEDE9E9E9B4B4B4B4B4B4B4B4B4B4B4 + B4B4B4B4B4B4B4D3D3D3E0E0E0F6F6F6F6F6F6F6F6F6F6F6F6D7D7D7C1C1C1B4 + B4B4B4B4B4B4B4B4B4B4B4B4B4B4CACACAE4E4E4CFCFCFD7D7D7DEDEDEE1E1E1 + E4E4E4E5E5E5E5E5E5EBEBEBDCDCDCB4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4 + B4B4B4B4B4B4B4B8B8B8D7D7D7E4E4E4F6F6F6F6F6F6F6F6F6E9E9E9D3D3D3B4 + B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4E9E9E9D3D3D3CFCFCFD8D8D8DFDFDF + E2E2E2E4E4E4E5E5E5E5E5E5EAEAEADCDCDCB4B4B4B4B4B4B4B4B4B4B4B4B4B4 + B4B4B4B4B4B4B4B4B4B4B4B4B4D3D3D3E0E0E0F6F6F6F6F6F6F6F6F6F2F2F2D7 + D7D7B8B8B8B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4E9E9E9C9C9C9CCCCCCD7D7D7 + DEDEDEE2E2E2E4E4E4E3E3E3F2F2F2B8B8B8B4B4B4B4B4B4B4B4B4B4B4B4E4E4 + E4C9C9C9C4C4C4D0D0D0D9D9D9E0E0E0E4E4E4E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5EAEAEAE4E4E4B4B4B4B4B4B4B4B4B4B4B4B4C6C6C6E4E4E4B2B2B2 + B7B7B7C1C1C1CFCFCFD8D8D8F1F1F1C1C1C1B4B4B4B4B4B4B4B4B4B4B4B4B4B4 + B4D3D3D3E0E0E0F6F6F6F6F6F6F6F6F6F6F6F6EDEDEDD7D7D7CECECEB4B4B4B4 + B4B4B4B4B4B4B4B4BDBDBDECECECB7B7B7C4C4C4D0D0D0D9D9D9E0E0E0E8E8E8 + E4E4E4B4B4B4B4B4B4B4B4B4B4B4B4D7D7D7D3D3D3B9B9B9C4C4C4CFCFCFD9D9 + D9E0E0E0E4E4E4F3F3F3C1C1C1B4B4B4B4B4B4B4B4B4B4B4B4B4B4B4D3D3D3E0 + E0E0F6F6F6F6F6F6F6F6F6F6F6F6EDEDEDD7D7D7CECECEB4B4B4B4B4B4B4B4B4 + B4B4B4BDBDBDECECECB7B7B7C4C4C4D0D0D0D9D9D9E0E0E0E4E4E4E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5F2F2F2B591FD935DFF935DFF935DFF935DFFD0BBFBB3B3B36D6D6D6E6E + 6E7B7B7B929292ACACACC4C4C4D4D4D4DFDFDFE4E4E4E5E5E5E5E5E5E4E4E4E1 + E1E1DCDCDCD1D1D1C2C2C2E9E9E9A77CFE935DFF935DFF935DFF935DFFB591FD + DADADAE2E2E2B591FD935DFF935DFF935DFF935DFFC3A6FCCACACA7373736C6C + 6C707070808080969696AEAEAEC4C4C4D4D4D4DEDEDEE2E2E2E4E4E4E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E4E4E4E1E1E1DBDBDBD4D4D4CECECEC6C6C6C0C0C096 + 9696B9B9B9E7E7E7E7E7E7E6E6E6E6E6E6E6E6E6E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E7E7E7EC + ECECB5B5B5B5B5B5B5B5B5B5B5B5C6C6C6D3D3D36A6A6A6C6C6C767676B9B9B9 + D7D7D7B5B5B5B5B5B5B5B5B5B5B5B5CFCFCFC5C5C5999999B5B5B5CBCBCBD9D9 + D9E1E1E1E4E4E4E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5EBEBEBDBDBDBB5 + B5B5B5B5B5B5B5B5B5B5B5C6C6C6B9B9B9B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5D7D7 + D7E3E3E3D2D2D2D9D9D9DFDFDFE2E2E2E4E4E4E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5EEEEEEE4E4E4B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5C6C6C6E9E9 + E9DBDBDBD9D9D9DFDFDFE2E2E2E4E4E4E5E5E5E5E5E5E5E5E5EBEBEBDBDBDBB5 + B5B5B5B5B5B5B5B5B5B5B5C6C6C6B9B9B9B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5D7D7 + D7E3E3E3D2D2D2D9D9D9DFDFDFE2E2E2E4E4E4E5E5E5E5E5E5E5E5E5EAEAEADB + DBDBB5B5B5B5B5B5B5B5B5B5B5B5CFCFCFC2C2C2B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5D3D3D3E2E2E2CFCFCFD8D8D8DFDFDFE1E1E1E4E4E4E4E4E4EAEAEADBDBDBB5 + B5B5B5B5B5B5B5B5B5B5B5C2C2C2ECECECCBCBCBD2D2D2D9D9D9DFDFDFE2E2E2 + E4E4E4E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F3F3F3BEBEBEB5B5 + B5B5B5B5B5B5B5B5B5B5ECECECCFCFCFC9C9C9CFCFCFD7D7D7DCDCDCE9E9E9EC + ECECB9B9B9B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5BEBEBEEEEEEECACA + CAD2D2D2D9D9D9DFDFDFE2E2E2E9E9E9E4E4E4B5B5B5B5B5B5B5B5B5B5B5B5D7 + D7D7DADADAC6C6C6CDCDCDD6D6D6DCDCDCE1E1E1E4E4E4EBEBEBECECECB9B9B9 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5 + B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5BEBEBEEEEEEECACACAD2D2D2D9 + D9D9DFDFDFE2E2E2E4E4E4E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5EAEAEAEAE3F89560FF9560FF95 + 60FF9560FFA274FEE8E8E87272726C6C6C737373868686A0A0A0B9B9B9CDCDCD + DADADAE1E1E1E4E4E4E4E4E4E3E3E3DFDFDFD5D5D5C6C6C6DADADAC9B1FB9560 + FF9560FF9560FF9560FF9C6AFEEAE3F8BFBFBFD0D0D0EAE3F89C6AFE9560FF95 + 60FF9560FF9560FFE3D9F9B6B6B66F6F6F6B6B6B7373738686869D9D9DB5B5B5 + C9C9C9D7D7D7E0E0E0E3E3E3E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E4E4E4E1E1E1 + DBDBDBD4D4D4CECECEC6C6C6C0C0C0969696B9B9B9E7E7E7E7E7E7E6E6E6E6E6 + E6E6E6E6E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F1F1F1C2C2C2B6B6B6B6B6B6B6B6B6B6B6 + B6ECECEC7E7E7E6868686B6B6BDADADAC2C2C2B6B6B6B6B6B6B6B6B6B6B6B6DF + DFDFABABABA3A3A3BDBDBDD1D1D1DEDEDEE4E4E4E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5EBEBEBDBDBDBB6B6B6B6B6B6B6B6B6B6B6B6D7D7D7F0F0 + F0CBCBCBB6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6D7D7D7E6E6E6D9D9D9DCDCDCE1E1E1E3E3E3E4E4E4 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5EEEEEEE3E3E3BABABAB6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6CBCBCBEBEBEBE1E1E1DDDDDDE1E1E1E3E3E3E4E4E4E5E5E5 + E5E5E5E5E5E5E5E5E5EBEBEBDBDBDBB6B6B6B6B6B6B6B6B6B6B6B6D7D7D7F0F0 + F0CBCBCBB6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6D7D7D7E6E6E6D9D9D9DCDCDCE1E1E1E3E3E3E4E4E4 + E5E5E5E5E5E5E5E5E5E5E5E5E9E9E9DBDBDBB6B6B6B6B6B6B6B6B6B6B6B6D7D7 + D7D8D8D8CFCFCFB6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6C7C7C7EAEAEADADADADBDBDBE0E0E0E2E2E2 + E4E4E4E5E5E5E5E5E5F1F1F1C2C2C2B6B6B6B6B6B6B6B6B6B6B6B6DBDBDBE2E2 + E2D8D8D8DCDCDCE0E0E0E2E2E2E4E4E4E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5ECECECD7D7D7B6B6B6B6B6B6B6B6B6B6B6B6CFCFCFE8E8E8 + D7D7D7D9D9D9DDDDDDE1E1E1E3E3E3ECECECE8E8E8BEBEBEB6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6BEBEBEF0F0F0D8D8D8DCDCDCE0E0E0E2E2E2E4E4E4E8E8E8 + E3E3E3B6B6B6B6B6B6B6B6B6B6B6B6D7D7D7DBDBDBC9C9C9CFCFCFD7D7D7DDDD + DDE1E1E1E4E4E4E5E5E5EDEDEDE8E8E8BEBEBEB6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6 + B6B6B6BEBEBEF0F0F0D8D8D8DCDCDCE0E0E0E2E2E2E4E4E4E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E4E4E4E4E4E4E3E3E3E2E2E2E1 + E1E1E0E0E0DFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDF + DFDFDFDFDFDFECECECBE9FFB9865FF9865FF9865FF9865FFD0BCFAB0B0B06B6B + 6B6C6C6C7B7B7B929292ADADADC5C5C5D6D6D6E0E0E0E4E4E4E4E4E4E1E1E1D9 + D9D9CCCCCCD4D4D4E3D9F89865FF9865FF9865FF9865FF9865FFD0BCFACECECE + BBBBBBCECECEE9E9E9D0BCFA9865FF9865FF9865FF9865FFA578FEF0ECF79090 + 906D6D6D6D6D6D7878788C8C8CA4A4A4BCBCBCCFCFCFDADADAE1E1E1E4E4E4E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E4E4E4E1E1E1DBDBDBD4D4D4CECECEC6C6C6C0C0C096 + 9696BABABAE8E8E8E8E8E8E7E7E7E7E7E7E7E7E7E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6EC + ECECD7D7D7B8B8B8B8B8B8B8B8B8B8B8B8D7D7D7AEAEAE666666808080E7E7E7 + B8B8B8B8B8B8B8B8B8B8B8B8BCBCBCEBEBEB919191AEAEAEC6C6C6D8D8D8E1E1 + E1E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6EBEBEBDBDBDBB8 + B8B8B8B8B8B8B8B8B8B8B8D7D7D7E9E9E9EDEDEDE3E3E3C4C4C4B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8BCBCBCDFDFDFE9E9E9DFDF + DFE1E1E1E3E3E3E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6EDEDEDEFEFEFD4D4D4B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8C0C0C0DFDFDFEBEBEBE4E4E4E1E1 + E1E3E3E3E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6EBEBEBDBDBDBB8 + B8B8B8B8B8B8B8B8B8B8B8D7D7D7E9E9E9EDEDEDE3E3E3C4C4C4B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8BCBCBCDFDFDFE9E9E9DFDF + DFE1E1E1E3E3E3E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E9E9E9DB + DBDBB8B8B8B8B8B8B8B8B8B8B8B8D7D7D7A9A9A9C1C1C1E7E7E7CCCCCCB8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8D0D0D0ECEC + ECE4E4E4E0E0E0E2E2E2E4E4E4E5E5E5E6E6E6E6E6E6E9E9E9E3E3E3B8B8B8B8 + B8B8B8B8B8B8B8B8BCBCBCEFEFEFE2E2E2E2E2E2E3E3E3E5E5E5E5E5E5E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7E7E7EFEFEFBCBC + BCB8B8B8B8B8B8B8B8B8BCBCBCEFEFEFE2E2E2E2E2E2E3E3E3E5E5E5E5E5E5E6 + E6E6ECECECF1F1F1D7D7D7B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8BCBCBCD7D7D7EFEFEFE9E9E9E2E2 + E2E3E3E3E5E5E5E5E5E5E6E6E6E9E9E9E3E3E3B8B8B8B8B8B8B8B8B8B8B8B8D7 + D7D7D8D8D8C4C4C4CBCBCBD5D5D5DBDBDBE1E1E1E5E5E5E6E6E6E6E6E6ECECEC + F1F1F1D7D7D7B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8 + B8B8B8B8B8B8B8B8B8B8B8B8B8BCBCBCD7D7D7EFEFEFE9E9E9E2E2E2E3E3E3E5 + E5E5E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E5E5E5E3E3E3E1E1E1DDDDDDD9D9D9D6D6D6D4D4D4D2D2D2D1D1D1D1D1 + D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D8D8D8E9E2F69A68FF9A + 68FF9A68FF9A68FFA67BFEEFECF6727272666666717171878787A3A3A3BDBDBD + D1D1D1DEDEDEE3E3E3E2E2E2DDDDDDD1D1D1C6C6C6EBEBEBA67BFE9A68FF9A68 + FF9A68FF9A68FFB28EFCDDDDDDB4B4B4C9C9C9D8D8D8E0E0E0EFEFEFB897FC9A + 68FF9A68FF9A68FF9A68FFBEA0FBC9C9C97373736B6B6B6F6F6F7E7E7E949494 + ACACACC3C3C3D3D3D3DEDEDEE3E3E3E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E5E5E5E2E2E2 + DCDCDCD5D5D5CFCFCFC7C7C7C1C1C1979797BABABAE8E8E8E8E8E8E7E7E7E7E7 + E7E7E7E7E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7E7E7EEEEEEB8B8B8B8B8B8B8B8B8B8B8 + B8C4C4C4D9D9D9666666ACACACD3D3D3B8B8B8B8B8B8B8B8B8B8B8B8D3D3D3BD + BDBD9C9C9CB7B7B7CDCDCDDCDCDCE3E3E3E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6EDEDEDF2F2F2F2F2F2F2F2F2F2F2F2EDEDEDE7E7 + E7E6E6E6EBEBEBF0F0F0E6E6E6D7D7D7C4C4C4B8B8B8B8B8B8B8B8B8B8B8B8CF + CFCFD7D7D7F1F1F1EAEAEAE3E3E3E4E4E4E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7E7E7EDED + EDF2F2F2D7D7D7D7D7D7B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8C4C4C4D7D7D7E3 + E3E3F0F0F0E9E9E9E3E3E3E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6EDEDEDF2F2F2F2F2F2F2F2F2F2F2F2EDEDEDE7E7 + E7E6E6E6EBEBEBF0F0F0E6E6E6D7D7D7C4C4C4B8B8B8B8B8B8B8B8B8B8B8B8CF + CFCFD7D7D7F1F1F1EAEAEAE3E3E3E4E4E4E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E9E9E9DBDBDBB8B8B8B8B8B8B8B8B8B8B8B8D7D7 + D7A9A9A9767676AAAAAADCDCDCEEEEEED7D7D7CBCBCBB8B8B8B8B8B8B8B8B8B8 + B8B8C4C4C4D7D7D7EAEAEAEBEBEBE5E5E5E4E4E4E5E5E5E5E5E5E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6EDEDEDF2F2F2F2F2F2F2F2F2F2F2F2F1F1F1ECECECE6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6ECECECF1F1F1F2F2F2F2F2F2F2F2F2F1F1F1ECECEC + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7E7E7EDEDEDF2F2F2DBDB + DBD7D7D7C0C0C0B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8C4C4C4D7D7D7D7D7D7EE + EEEEF1F1F1EBEBEBE5E5E5E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E5E5E5 + EBEBEBF2F2F2F2F2F2F2F2F2F2F2F2D7D7D7B3B3B3B4B4B4BFBFBFCCCCCCD7D7 + D7DFDFDFE3E3E3E6E6E6E6E6E6E6E6E6E7E7E7EDEDEDF2F2F2DBDBDBD7D7D7C0 + C0C0B8B8B8B8B8B8B8B8B8B8B8B8B8B8B8C4C4C4D7D7D7D7D7D7EEEEEEF1F1F1 + EBEBEBE5E5E5E5E5E5E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E4E4E4E1E1E1DBDBDBD5D5D5CD + CDCDC6C6C6C1C1C1BEBEBEBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBD + BDBDBDBDBDBDBDBDBDDDDDDDC5AAF99C6BFF9C6BFF9C6BFF9C6BFFCAB4F9AFAF + AF6161616A6A6A7D7D7D999999B6B6B6CCCCCCDADADAE1E1E1E0E0E0D6D6D6C6 + C6C6D8D8D8C5AAF99C6BFF9C6BFF9C6BFF9C6BFFA274FEE7E1F5C3C3C3C2C2C2 + D3D3D3DEDEDEE3E3E3E9E9E9EDEAF4A274FE9C6BFF9C6BFF9C6BFF9C6BFFD6C6 + F7BCBCBC7070706B6B6B7373738484849C9C9CB4B4B4C8C8C8D8D8D8E0E0E0E4 + E4E4E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E5E5E5E2E2E2DCDCDCD5D5D5CFCFCFC7C7C7C1C1C197 + 9797BABABAE8E8E8E8E8E8E7E7E7E7E7E7E7E7E7E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6ECECECCCCCCCBABABABABABABABABABABABAE5E5E5838383E6E6E6BEBEBE + BABABABABABABABABABABABAE5E5E59E9E9EA7A7A7C0C0C0D3D3D3E0E0E0E5E5 + E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E8E8E8EBEBEB + EEEEEEF0F0F0F0F0F0F0F0F0F0F0F0ECECECEBEBEBE7E7E7E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7E7E7EBEBEBECECECF0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0EEEEEEEBEBEBE9E9E9E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E8E8E8EBEBEB + EEEEEEF0F0F0F0F0F0F0F0F0F0F0F0ECECECEBEBEBE7E7E7E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E8E8E8DA + DADABABABABABABABABABABABABAD7D7D7A8A8A8767676919191B0B0B0CACACA + E3E3E3EBEBEBF0F0F0F0F0F0F0F0F0F0F0F0EEEEEEEBEBEBE7E7E7E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6EAEAEAEBEBEBEFEFEFF0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0EEEEEEEBEBEBEBEBEBE7E7E7E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E3E3E3DDDDDDD2D2D2C4C4C4B0B0B09F9F9F95 + 95959494949B9B9BAAAAAABFBFBFCFCFCFDADADAE2E2E2E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6EAEAEAEBEBEBEFEFEFF0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0EEEEEEEBEBEBEBEBEBE7E7E7E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E5E5E5E2E2E2DDDDDDD4D4D4C8C8C8BCBCBCB1B1B1A9A9A9A4A4A4A1A1A1A1A1 + A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1ABABABEBE8F2A4 + 77FE9E6EFF9E6EFF9E6EFFA477FEEBE8F2656565636363767676919191B0B0B0 + C7C7C7D8D8D8DDDDDDD9D9D9CCCCCCD2D2D2E0D7F49E6EFF9E6EFF9E6EFF9E6E + FF9E6EFFCAB4F8CCCCCCBBBBBBCFCFCFDADADAE2E2E2E5E5E5E6E6E6ECECECD5 + C5F69E6EFF9E6EFF9E6EFF9E6EFFA477FEEBE8F29898986C6C6C6B6B6B767676 + 8B8B8BA3A3A3BBBBBBCECECEDADADAE1E1E1E5E5E5E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E5E5E5E2E2E2 + DCDCDCD5D5D5CFCFCFC7C7C7C1C1C1979797BABABAE8E8E8E8E8E8E7E7E7E7E7 + E7E7E7E7E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E9E9E9DEDEDEBBBBBBBBBBBBBBBB + BBBBBBBBD3D3D3B4B4B4E1E1E1BBBBBBBBBBBBBBBBBBBBBBBBC5C5C5D8D8D896 + 9696B2B2B2C8C8C8D8D8D8E2E2E2E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E8E8E8DADADABBBBBBBBBBBBBBBBBBBBBBBBD7D7 + D7A8A8A8767676919191B0B0B0C7C7C7D8D8D8E2E2E2E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E3E3E3 + DBDBDBCFCFCFBDBDBDA6A6A69090908585858484848C8C8C9F9F9FB7B7B7CACA + CAD8D8D8E2E2E2E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E5E5E5E1E1E1D9D9D9CDCDCDBDBDBDAA + AAAA9B9B9B909090898989858585858585858585858585858585858585858585 + 858585858585858585858585BDBDBDCBB5F7A071FFA071FFA071FFA071FFCBB5 + F7A8A8A8636363757575909090AFAFAFC6C6C6D5D5D5DADADAD4D4D4C9C9C9E7 + E7E7AB82FDA071FFA071FFA071FFA071FFB593FBD9D9D9B6B6B6C8C8C8D8D8D8 + E0E0E0E4E4E4E6E6E6E6E6E6E6E6E6EDEDEDBB9BFAA071FFA071FFA071FFA071 + FFBB9BFACDCDCD7D7D7D6E6E6E727272818181989898B0B0B0C6C6C6D5D5D5E0 + E0E0E4E4E4E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E6E6E6E6E6E6E6E5E5E5E2E2E2DCDCDCD5D5D5CFCFCFC7C7C7C1C1C197 + 9797BABABAE9E9E9E9E9E9E8E8E8E8E8E8E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7EDEDEDBFBFBFBCBCBCBCBCBCBCBCBCBFBFBFE7E7E7D0D0D0BCBCBC + BCBCBCBCBCBCBCBCBCD7D7D7B9B9B9A4A4A4BCBCBCD0D0D0DEDEDEE4E4E4E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E8E8E8DA + DADABCBCBCBCBCBCBCBCBCBCBCBCD7D7D7A7A7A7777777929292B1B1B1C8C8C8 + D9D9D9E3E3E3E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E3E3E3DBDBDBCECECEBBBBBBA2A2A28C8C8C81 + 81817F7F7F8888889C9C9CB5B5B5CACACAD9D9D9E2E2E2E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E6E6E6E2E2E2D9D9D9CACACAB8B8B8A2A2A29191918484847C7C7C7878787878 + 78787878787878787878787878787878787878787878787878787878808080EA + E7F0A77CFEA274FFA274FFA274FFA77CFEEAE7F07575757C7C7C959595B2B2B2 + C8C8C8D6D6D6D9D9D9D0D0D0DBDBDBC6ADF8A274FFA274FFA274FFA274FFA274 + FFE5DFF1C2C2C2C3C3C3D4D4D4DFDFDFE4E4E4E6E6E6E7E7E7E7E7E7E7E7E7E9 + E9E9EAE7F0A77CFEA274FFA274FFA274FFA274FFCBB6F6BCBCBC787878777777 + 818181939393AAAAAAC1C1C1D2D2D2DEDEDEE4E4E4E6E6E6E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E6E6E6E3E3E3 + DDDDDDD6D6D6CFCFCFC8C8C8C2C2C2979797BABABAE9E9E9E9E9E9E8E8E8E8E8 + E8E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7EBEBEBD0D0D0BDBDBDBDBD + BDBDBDBDBDBDBDDDDDDDC0C0C0BDBDBDBDBDBDBDBDBDBDBDBDE7E7E7A5A5A5B2 + B2B2C6C6C6D6D6D6E1E1E1E6E6E6E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E8E8E8DADADABDBDBDBDBDBDBDBDBDBDBDBDD7D7 + D7AAAAAA7B7B7B959595B2B2B2CACACADADADAE3E3E3E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E6E6E6 + E6E6E6EDEDEDEDEDEDEDEDEDEDEDEDDFDFDFB4B4B48C8C8C9F9F9FB8B8B8CBCB + CBD9D9D9E3E3E3E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E6E6E6E2E2E2D9D9D9CACACAB8B8B8A2 + A2A29191918484847C7C7C787878787878787878787878787878787878787878 + 787878787878787878787878787878B5B5B5D0BEF4A477FFA477FFA477FFA477 + FFCBB6F5B0B0B08A8A8A9F9F9FB8B8B8CBCBCBD6D6D6D8D8D8DDDDDDDACEF2A4 + 77FFA477FFA477FFA477FFA477FFCBB6F5D1D1D1BDBDBDCFCFCFDBDBDBE3E3E3 + E6E6E6E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7EAEAEAD5C6F3A477FFA477FFA477 + FFA477FFA97FFEE3DDEFB0B0B0838383888888969696AAAAAABFBFBFD0D0D0DC + DCDCE3E3E3E6E6E6E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E6E6E6E3E3E3DDDDDDD6D6D6CFCFCFC8C8C8C2C2C297 + 9797BABABAE9E9E9E9E9E9E8E8E8E8E8E8E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E8E8E8E0E0E0BEBEBEBEBEBEBEBEBEBEBEBEC4C4C4BEBEBEBEBEBE + BEBEBEBEBEBECACACAD7D7D7ADADADC0C0C0D0D0D0DBDBDBE3E3E3E6E6E6E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7DA + DADABEBEBEBEBEBEBEBEBEBEBEBED7D7D7AEAEAE8484849C9C9CB7B7B7CDCDCD + DBDBDBE4E4E4E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E9E9E9D0D0D0BEBEBEBEBEBEBEBEBEBEBEBEC4 + C4C4E0E0E09C9C9CABABABC0C0C0D0D0D0DBDBDBE3E3E3E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E6E6E6E8E8E8ECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECAF89FCA67AFFA67AFFA67AFFB998FAD3D3D39D9D9DAEAEAEC2C2C2 + D0D0D0D9D9D9DBDBDBE7E4EDAF89FCA67AFFA67AFFA67AFFA67AFFB491FBDFDF + DFBFBFBFCCCCCCD9D9D9E1E1E1E5E5E5E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7EAEAEAC2A8F7A67AFFA67AFFA67AFFA67AFFB491FBDDDDDD9D9D9D + 999999A2A2A2B1B1B1C3C3C3D1D1D1DCDCDCE3E3E3E6E6E6E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E6E6E6E3E3E3 + DDDDDDD6D6D6CFCFCFC8C8C8C2C2C2979797BABABAE9E9E9E9E9E9E8E8E8E8E8 + E8E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7EAEAEAC5C5C5BFBF + BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFD9D9D9CBCBCBC3C3C3CF + CFCFD9D9D9E1E1E1E5E5E5E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7D9D9D9BFBFBFBFBFBFBFBFBFBFBFBFD6D6 + D6B6B6B6929292A6A6A6BDBDBDD0D0D0DDDDDDE4E4E4E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E9E9E9 + D1D1D1BFBFBFBFBFBFBFBFBFBFBFBFC5C5C5E3E3E3B5B5B5C0C0C0CDCDCDD8D8 + D8E0E0E0E4E4E4E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E1DBEDA77BFFA77BFFA77BFFA7 + 7BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFF + A77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77BFFA77B + FFB999F9DADADAB5B5B5C1C1C1CFCFCFD9D9D9DDDDDDE4E4E4C6AFF5A77BFFA7 + 7BFFA77BFFA77BFFA77BFFE1DBEDD0D0D0CDCDCDD8D8D8DFDFDFE4E4E4E6E6E6 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E8E8E8E6E3EBB08AFCA77B + FFA77BFFA77BFFA77BFFCBB6F4D3D3D3B2B2B2B6B6B6C0C0C0CCCCCCD7D7D7DF + DFDFE3E3E3E6E6E6E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E6E6E6E3E3E3DDDDDDD6D6D6CFCFCFC8C8C8C2C2C297 + 9797BABABAE9E9E9E9E9E9E8E8E8E8E8E8E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E8E8E8D6D6D6C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0 + C0C0C0C3C3C3E7E7E7CDCDCDD2D2D2D9D9D9E0E0E0E3E3E3E6E6E6E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E8E8E8D9 + D9D9C0C0C0C0C0C0C0C0C0C0C0C0D6D6D6C0C0C0A3A3A3B4B4B4C6C6C6D5D5D5 + DFDFDFE5E5E5E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E8E8E8D1D1D1C0C0C0C0C0C0C0C0C0C0C0C0C6 + C6C6E5E5E5C9C9C9CFCFCFD8D8D8DEDEDEE2E2E2E6E6E6E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E0DBECA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA97E + FFA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA97EFFA9 + 7EFFA97EFFA97EFFA97EFFA97EFFA97EFFBA9BF9DFDFDFC9C9C9D0D0D0D9D9D9 + DEDEDEE5E5E5D4C5F0A97EFFA97EFFA97EFFA97EFFA97EFFCBB7F3DDDDDDD1D1 + D1D9D9D9DFDFDFE3E3E3E6E6E6E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E8E8E8D4C5F0A97EFFA97EFFA97EFFA97EFFA97EFFDCD4ED + D6D6D6C8C8C8CECECED6D6D6DCDCDCE2E2E2E5E5E5E6E6E6E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E6E6E6E3E3E3 + DDDDDDD6D6D6CFCFCFC8C8C8C2C2C2979797BBBBBBEAEAEAEAEAEAE9E9E9E9E9 + E9E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E2E2E2C0C0 + C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CECECEE4E4E4D9D9D9DEDEDEE2 + E2E2E4E4E4E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8D9D9D9C0C0C0C0C0C0C0C0C0C0C0C0D6D6 + D6CECECEBBBBBBC6C6C6D2D2D2DCDCDCE3E3E3E7E7E7E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E9E9E9 + D1D1D1C0C0C0C0C0C0C0C0C0C0C0C0C6C6C6E8E8E8D9D9D9DCDCDCE0E0E0E3E3 + E3E6E6E6E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E1DBECAA80FFAA80FFAA80FFAA + 80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FF + AA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80FFAA80 + FFBB9CF9E4E4E4D9D9D9DCDCDCE1E1E1E5E5E5E5E2EAB28EFCAA80FFAA80FFAA + 80FFAA80FFB795FBE6E6E6DBDBDBDEDEDEE2E2E2E4E4E4E7E7E7E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E9E9E9C3AA + F6AA80FFAA80FFAA80FFAA80FFB28EFCE7E7E7DBDBDBDADADADFDFDFE2E2E2E4 + E4E4E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E7E7E7E4E4E4DEDEDED7D7D7D0D0D0C9C9C9C3C3C398 + 9898BBBBBBEAEAEAEAEAEAE9E9E9E9E9E9E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E9E9E9C9C9C9C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1 + C1C1C1DCDCDCE5E5E5E3E3E3E4E4E4E6E6E6E7E7E7E7E7E7E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8D9 + D9D9C1C1C1C1C1C1C1C1C1C1C1C1D6D6D6D8D8D8CDCDCDD4D4D4DBDBDBE1E1E1 + E4E4E4E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E9E9E9D1D1D1C1C1C1C1C1C1C1C1C1C1C1C1C6 + C6C6E8E8E8E3E3E3E4E4E4E5E5E5E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E0DAEBAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81 + FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB81FFAB + 81FFAB81FFAB81FFAB81FFAB81FFAB81FFBB9CF9E6E6E6E3E3E3E4E4E4E5E5E5 + E8E8E8BFA3F7AB81FFAB81FFAB81FFAB81FFAB81FFDCD3EDE5E5E5E4E4E4E5E5 + E5E6E6E6E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E4E1EAB38FFCAB81FFAB81FFAB81FFAB81FF + C7B1F4E6E6E6E3E3E3E4E4E4E6E6E6E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E7E7E7E4E4E4 + DEDEDED7D7D7D0D0D0C9C9C9C3C3C3989898BBBBBBEAEAEAEAEAEAE9E9E9E9E9 + E9E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8D9D9D9C2C2C2C2C2C2C2C2C2C2C2C2D7D7 + D7E0E0E0DADADADEDEDEE2E2E2E4E4E4E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E7E7E7E4E4E4DEDEDED7D7D7D0D0D0C9C9C9C3C3C398 + 9898BBBBBBEAEAEAEAEAEAE9E9E9E9E9E9E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8D9 + D9D9C2C2C2C2C2C2C2C2C2C2C2C2D6D6D6E5E5E5E3E3E3E4E4E4E6E6E6E7E7E7 + E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8 + E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E7E7E7E4E4E4 + DEDEDED7D7D7D0D0D0C9C9C9C3C3C3989898BCBCBCEBEBEBEAEAEAEAEAEAEAEA + EAEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E8E8E8E5E5E5DFDFDFD8D8D8D1D1D1CACACAC4C4C499 + 9999BCBCBCEBEBEBEAEAEAEAEAEAEAEAEAEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E8E8E8E5E5E5 + DFDFDFD8D8D8D1D1D1CACACAC4C4C4999999BCBCBCEBEBEBEAEAEAEAEAEAEAEA + EAEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E8E8E8E5E5E5DFDFDFD8D8D8D1D1D1CACACAC4C4C499 + 9999BCBCBCEBEBEBEAEAEAEAEAEAEAEAEAEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 + E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E8E8E8E5E5E5 + DFDFDFD8D8D8D1D1D1CACACAC4C4C4999999BDBDBDECECECEBEBEBEBEBEBEBEB + EBEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAE9E9E9E6E6E6E0E0E0D9D9D9D2D2D2CBCBCBC4C4C49A + 9A9ABDBDBDECECECEBEBEBEBEBEBEBEBEBEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE9E9E9E6E6E6 + E0E0E0D9D9D9D2D2D2CBCBCBC4C4C49A9A9ABDBDBDECECECEBEBEBEBEBEBEBEB + EBEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAE9E9E9E6E6E6E0E0E0D9D9D9D2D2D2CBCBCBC4C4C49A + 9A9ABDBDBDECECECEBEBEBEBEBEBEBEBEBEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE9E9E9E6E6E6 + E0E0E0D9D9D9D2D2D2CBCBCBC4C4C49A9A9ABDBDBDECECECEBEBEBEBEBEBEBEB + EBEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA + EAEAEAEAEAEAEAEAEAEAE9E9E9E6E6E6E0E0E0D9D9D9D2D2D2CBCBCBC4C4C49A + 9A9ABEBEBEEDEDEDECECECECECECECECECEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEAEAEAE7E7E7 + E1E1E1D9D9D9D3D3D3CCCCCCC5C5C59A9A9ABEBEBEEDEDEDECECECECECECECEC + ECEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEAEAEAE7E7E7E1E1E1D9D9D9D3D3D3CCCCCCC5C5C59A + 9A9ABEBEBEEDEDEDECECECECECECECECECEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEAEAEAE7E7E7 + E1E1E1D9D9D9D3D3D3CCCCCCC5C5C59A9A9ABEBEBEEDEDEDECECECECECECECEC + ECEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEB + EBEBEBEBEBEBEBEBEBEBEAEAEAE7E7E7E1E1E1D9D9D9D3D3D3CCCCCCC5C5C59A + 9A9ABEBEBEEEEEEEEDEDEDEDEDEDEDEDEDECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECEBEBEBE8E8E8 + E2E2E2DADADAD4D4D4CDCDCDC6C6C69A9A9ABEBEBEEEEEEEEDEDEDEDEDEDEDED + EDECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECEBEBEBE8E8E8E2E2E2DADADAD4D4D4CDCDCDC6C6C69A + 9A9ABEBEBEEEEEEEEDEDEDEDEDEDEDEDEDECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECEBEBEBE8E8E8 + E2E2E2DADADAD4D4D4CDCDCDC6C6C69A9A9ABEBEBEEEEEEEEDEDEDEDEDEDEDED + EDECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECEC + ECECECECECECECECECECEBEBEBE8E8E8E2E2E2DADADAD4D4D4CDCDCDC6C6C69A + 9A9ABFBFBFEEEEEEEEEEEEEEEEEEEEEEEEEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDECECECE9E9E9 + E3E3E3DBDBDBD5D5D5CDCDCDC7C7C79B9B9BBFBFBFEEEEEEEEEEEEEEEEEEEEEE + EEEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDECECECE9E9E9E3E3E3DBDBDBD5D5D5CDCDCDC7C7C79B + 9B9BBFBFBFEEEEEEEEEEEEEEEEEEEEEEEEEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDECECECE9E9E9 + E3E3E3DBDBDBD5D5D5CDCDCDC7C7C79B9B9BBFBFBFEEEEEEEEEEEEEEEEEEEEEE + EEEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDECECECE9E9E9E3E3E3DBDBDBD5D5D5CDCDCDC7C7C79B + 9B9BBFBFBFEEEEEEEEEEEEEEEEEEEEEEEEEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDECECECE9E9E9 + E3E3E3DBDBDBD5D5D5CDCDCDC7C7C79B9B9BC0C0C0EFEFEFEFEFEFEFEFEFEFEF + EFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEDEDEDEAEAEAE4E4E4DCDCDCD6D6D6CECECEC8C8C89C + 9C9CC0C0C0EFEFEFEFEFEFEFEFEFEFEFEFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDEDEDEAEAEA + E4E4E4DCDCDCD6D6D6CECECEC8C8C89C9C9CC0C0C0EFEFEFEFEFEFEFEFEFEFEF + EFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEDEDEDEAEAEAE4E4E4DCDCDCD6D6D6CECECEC8C8C89C + 9C9CC0C0C0EFEFEFEFEFEFEFEFEFEFEFEFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDEDEDEAEAEA + E4E4E4DCDCDCD6D6D6CECECEC8C8C89C9C9CC1C1C1F0F0F0F0F0F0F0F0F0F0F0 + F0EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEEEEEEEBEBEBE5E5E5DDDDDDD7D7D7CFCFCFC9C9C99D + 9D9DC1C1C1F0F0F0F0F0F0F0F0F0F0F0F0EFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEEEEEEEBEBEB + E5E5E5DDDDDDD7D7D7CFCFCFC9C9C99D9D9DC1C1C1F0F0F0F0F0F0F0F0F0F0F0 + F0EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEEEEEEEBEBEBE5E5E5DDDDDDD7D7D7CFCFCFC9C9C99D + 9D9DC1C1C1F0F0F0F0F0F0F0F0F0F0F0F0EFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEEEEEEEBEBEB + E5E5E5DDDDDDD7D7D7CFCFCFC9C9C99D9D9DC1C1C1F0F0F0F0F0F0F0F0F0F0F0 + F0EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF + EFEFEFEFEFEFEFEFEFEFEEEEEEEBEBEBE5E5E5DDDDDDD7D7D7CFCFCFC9C9C99D + 9D9DC1C1C1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0EFEFEFECECEC + E6E6E6DEDEDED8D8D8D0D0D0C9C9C99E9E9EC1C1C1F1F1F1F1F1F1F1F1F1F1F1 + F1F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0EFEFEFECECECE6E6E6DEDEDED8D8D8D0D0D0C9C9C99E + 9E9EC1C1C1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0EFEFEFECECEC + E6E6E6DEDEDED8D8D8D0D0D0C9C9C99E9E9EC1C1C1F1F1F1F1F1F1F1F1F1F1F1 + F1F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 + F0F0F0F0F0F0F0F0F0F0EFEFEFECECECE6E6E6DEDEDED8D8D8D0D0D0C9C9C99E + 9E9EC2C2C2F2F2F2F2F2F2F2F2F2F2F2F2F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0EDEDED + E7E7E7DFDFDFD8D8D8D1D1D1CACACA9E9E9EC2C2C2F2F2F2F2F2F2F2F2F2F2F2 + F2F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F0F0F0EDEDEDE7E7E7DFDFDFD8D8D8D1D1D1CACACA9E + 9E9EC2C2C2F2F2F2F2F2F2F2F2F2F2F2F2F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0EDEDED + E7E7E7DFDFDFD8D8D8D1D1D1CACACA9E9E9EC2C2C2F2F2F2F2F2F2F2F2F2F2F2 + F2F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F0F0F0EDEDEDE7E7E7DFDFDFD8D8D8D1D1D1CACACA9E + 9E9EC2C2C2F2F2F2F2F2F2F2F2F2F2F2F2F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0EDEDED + E7E7E7DFDFDFD8D8D8D1D1D1CACACA9E9E9EC2C2C2F3F3F3F3F3F3F3F3F3F3F3 + F3F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F1F1F1EEEEEEE8E8E8E0E0E0D9D9D9D2D2D2CBCBCB9E + 9E9EC2C2C2F3F3F3F3F3F3F3F3F3F3F3F3F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F1F1F1EEEEEE + E8E8E8E0E0E0D9D9D9D2D2D2CBCBCB9E9E9EC2C2C2F3F3F3F3F3F3F3F3F3F3F3 + F3F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F1F1F1EEEEEEE8E8E8E0E0E0D9D9D9D2D2D2CBCBCB9E + 9E9EC2C2C2F3F3F3F3F3F3F3F3F3F3F3F3F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F1F1F1EEEEEE + E8E8E8E0E0E0D9D9D9D2D2D2CBCBCB9E9E9EC2C2C2F3F3F3F3F3F3F3F3F3F3F3 + F3F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F2F2F2F2F2F2F1F1F1EEEEEEE8E8E8E0E0E0D9D9D9D2D2D2CBCBCB9E + 9E9EC3C3C3F4F4F4F4F4F4F4F4F4F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F2F2F2EFEFEF + E9E9E9E1E1E1DADADAD3D3D3CCCCCC9F9F9FC3C3C3F4F4F4F4F4F4F4F4F4F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F2F2F2EFEFEFE9E9E9E1E1E1DADADAD3D3D3CCCCCC9F + 9F9FC3C3C3F4F4F4F4F4F4F4F4F4F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F2F2F2EFEFEF + E9E9E9E1E1E1DADADAD3D3D3CCCCCC9F9F9FC3C3C3F4F4F4F4F4F4F4F4F4F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F2F2F2EFEFEFE9E9E9E1E1E1DADADAD3D3D3CCCCCC9F + 9F9FC3C3C3F4F4F4F4F4F4F4F4F4F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F2F2F2EFEFEF + E9E9E9E1E1E1DADADAD3D3D3CCCCCC9F9F9FC4C4C4F5F5F5F5F5F5F5F5F5F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F3F3F3F0F0F0E9E9E9E2E2E2DBDBDBD3D3D3CDCDCDA0 + A0A0C4C4C4F5F5F5F5F5F5F5F5F5F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F3F3F3F0F0F0 + E9E9E9E2E2E2DBDBDBD3D3D3CDCDCDA0A0A0C4C4C4F5F5F5F5F5F5F5F5F5F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F3F3F3F0F0F0E9E9E9E2E2E2DBDBDBD3D3D3CDCDCDA0 + A0A0C4C4C4F5F5F5F5F5F5F5F5F5F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F3F3F3F0F0F0 + E9E9E9E2E2E2DBDBDBD3D3D3CDCDCDA0A0A0C4C4C4F5F5F5F5F5F5F5F5F5F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4 + F4F4F4F4F4F4F4F4F4F4F3F3F3F0F0F0E9E9E9E2E2E2DBDBDBD3D3D3CDCDCDA0 + A0A0C5C5C5F6F6F6F6F6F6F6F6F6F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F4F4F4F1F1F1 + EAEAEAE3E3E3DCDCDCD4D4D4CECECEA1A1A1C5C5C5F6F6F6F6F6F6F6F6F6F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F4F4F4F1F1F1EAEAEAE3E3E3DCDCDCD4D4D4CECECEA1 + A1A1C5C5C5F6F6F6F6F6F6F6F6F6F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F4F4F4F1F1F1 + EAEAEAE3E3E3DCDCDCD4D4D4CECECEA1A1A1C5C5C5F6F6F6F6F6F6F6F6F6F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F4F4F4F1F1F1EAEAEAE3E3E3DCDCDCD4D4D4CECECEA1 + A1A1C5C5C5F6F6F6F6F6F6F6F6F6F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F4F4F4F1F1F1 + EAEAEAE3E3E3DCDCDCD4D4D4CECECEA1A1A1C6C6C6F7F7F7F7F7F7F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F5F5F5F2F2F2EBEBEBE4E4E4DDDDDDD5D5D5CECECEA2 + A2A2C6C6C6F7F7F7F7F7F7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F5F5F5F2F2F2 + EBEBEBE4E4E4DDDDDDD5D5D5CECECEA2A2A2C6C6C6F7F7F7F7F7F7F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F5F5F5F2F2F2EBEBEBE4E4E4DDDDDDD5D5D5CECECEA2 + A2A2C6C6C6F7F7F7F7F7F7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F5F5F5F2F2F2 + EBEBEBE4E4E4DDDDDDD5D5D5CECECEA2A2A2C6C6C6F7F7F7F7F7F7F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F6F6F5F5F5F2F2F2EBEBEBE4E4E4DDDDDDD5D5D5CECECEA2 + A2A2C6C6C6F8F8F8F8F8F8F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6F3F3F3 + ECECECE5E5E5DEDEDED6D6D6CFCFCFA2A2A2C6C6C6F8F8F8F8F8F8F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F6F6F6F3F3F3ECECECE5E5E5DEDEDED6D6D6CFCFCFA2 + A2A2C6C6C6F8F8F8F8F8F8F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6F3F3F3 + ECECECE5E5E5DEDEDED6D6D6CFCFCFA2A2A2C6C6C6F8F8F8F8F8F8F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F6F6F6F3F3F3ECECECE5E5E5DEDEDED6D6D6CFCFCFA2 + A2A2C6C6C6F8F8F8F8F8F8F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6F3F3F3 + ECECECE5E5E5DEDEDED6D6D6CFCFCFA2A2A2C6C6C6F8F8F8F8F8F8F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7 + F7F7F7F7F7F7F7F7F7F7F6F6F6F3F3F3ECECECE5E5E5DEDEDED6D6D6CFCFCFA2 + A2A2C7C7C7F9F9F9F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F7F7F7F4F4F4 + EDEDEDE6E6E6DFDFDFD7D7D7D0D0D0A2A2A2C7C7C7F9F9F9F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F7F7F7F4F4F4EDEDEDE6E6E6DFDFDFD7D7D7D0D0D0A2 + A2A2C7C7C7F9F9F9F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F7F7F7F4F4F4 + EDEDEDE6E6E6DFDFDFD7D7D7D0D0D0A2A2A2C7C7C7F9F9F9F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F7F7F7F4F4F4EDEDEDE6E6E6DFDFDFD7D7D7D0D0D0A2 + A2A2C7C7C7F9F9F9F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F7F7F7F4F4F4 + EDEDEDE6E6E6DFDFDFD7D7D7D0D0D0A2A2A2C7C7C7F9F9F9F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 + F8F8F8F8F8F8F8F8F8F8F7F7F7F4F4F4EDEDEDE6E6E6DFDFDFD7D7D7D0D0D0A2 + A2A2C8C8C8F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F8F8F8F5F5F5 + EEEEEEE6E6E6E0E0E0D8D8D8D1D1D1A3A3A3C8C8C8F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F8F8F8F5F5F5EEEEEEE6E6E6E0E0E0D8D8D8D1D1D1A3 + A3A3C8C8C8F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F8F8F8F5F5F5 + EEEEEEE6E6E6E0E0E0D8D8D8D1D1D1A3A3A3C8C8C8F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F8F8F8F5F5F5EEEEEEE6E6E6E0E0E0D8D8D8D1D1D1A3 + A3A3C8C8C8F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F8F8F8F5F5F5 + EEEEEEE6E6E6E0E0E0D8D8D8D1D1D1A3A3A3C8C8C8F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9 + F9F9F9F9F9F9F9F9F9F9F8F8F8F5F5F5EEEEEEE6E6E6E0E0E0D8D8D8D1D1D1A3 + A3A3C8C8C8FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF9F9F9F6F6F6 + EFEFEFE7E7E7E1E1E1D9D9D9D2D2D2A4A4A4C8C8C8FAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAF9F9F9F6F6F6EFEFEFE7E7E7E1E1E1D9D9D9D2D2D2A4 + A4A4C8C8C8FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF9F9F9F6F6F6 + EFEFEFE7E7E7E1E1E1D9D9D9D2D2D2A4A4A4C8C8C8FAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAF9F9F9F6F6F6EFEFEFE7E7E7E1E1E1D9D9D9D2D2D2A4 + A4A4C8C8C8FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF9F9F9F6F6F6 + EFEFEFE7E7E7E1E1E1D9D9D9D2D2D2A4A4A4C8C8C8FAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAF9F9F9F6F6F6EFEFEFE7E7E7E1E1E1D9D9D9D2D2D2A4 + A4A4C9C9C9FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFAFAFAF7F7F7 + F0F0F0E8E8E8E1E1E1DADADAD3D3D3A5A5A5C9C9C9FBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFAFAFAF7F7F7F0F0F0E8E8E8E1E1E1DADADAD3D3D3A5 + A5A5C9C9C9FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFAFAFAF7F7F7 + F0F0F0E8E8E8E1E1E1DADADAD3D3D3A5A5A5C9C9C9FBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFAFAFAF7F7F7F0F0F0E8E8E8E1E1E1DADADAD3D3D3A5 + A5A5C9C9C9FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFAFAFAF7F7F7 + F0F0F0E8E8E8E1E1E1DADADAD3D3D3A5A5A5C9C9C9FBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFAFAFAF7F7F7F0F0F0E8E8E8E1E1E1DADADAD3D3D3A5 + A5A5C9C9C9FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFAFAFAF7F7F7 + F0F0F0E8E8E8E1E1E1DADADAD3D3D3A5A5A5CACACAFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFBFBFBF8F8F8F1F1F1E9E9E9E2E2E2DADADAD3D3D3A6 + A6A6CACACAFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFBFBFBF8F8F8 + F1F1F1E9E9E9E2E2E2DADADAD3D3D3A6A6A6CACACAFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFBFBFBF8F8F8F1F1F1E9E9E9E2E2E2DADADAD3D3D3A6 + A6A6CACACAFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFBFBFBF8F8F8 + F1F1F1E9E9E9E2E2E2DADADAD3D3D3A6A6A6CACACAFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFBFBFBF8F8F8F1F1F1E9E9E9E2E2E2DADADAD3D3D3A6 + A6A6CACACAFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFBFBFBF8F8F8 + F1F1F1E9E9E9E2E2E2DADADAD3D3D3A6A6A6CACACAFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFBFBFBF8F8F8F1F1F1E9E9E9E2E2E2DADADAD3D3D3A6 + A6A6CACACAFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9 + F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6A6A6CACACAFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6 + A6A6CACACAFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9 + F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6A6A6CACACAFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6 + A6A6CACACAFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9 + F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6A6A6CACACAFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6 + A6A6CACACAFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9 + F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6A6A6CACACAFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFCFCFCF9F9F9F2F2F2EAEAEAE3E3E3DBDBDBD4D4D4A6 + A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFDFDFAFAFA + F3F3F3EBEBEBE4E4E4DCDCDCD5D5D5A6A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFDFDFDFAFAFAF3F3F3EBEBEBE4E4E4DCDCDCD5D5D5A6 + A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFDFDFAFAFA + F3F3F3EBEBEBE4E4E4DCDCDCD5D5D5A6A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFDFDFDFAFAFAF3F3F3EBEBEBE4E4E4DCDCDCD5D5D5A6 + A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFDFDFAFAFA + F3F3F3EBEBEBE4E4E4DCDCDCD5D5D5A6A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFDFDFDFAFAFAF3F3F3EBEBEBE4E4E4DCDCDCD5D5D5A6 + A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFBFBFB + F4F4F4EDEDEDE5E5E5DEDEDED6D6D6A6A6A6CBCBCBFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF8F8F8F1F1F1E9E9E9E1E1E1D9D9D9A9 + A9A9CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFF8F8F8F1F1F1E9E9E9E0E0E0AEAEAECCCCCCFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8F0F0F0E7E7E7B3 + B3B3CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFF9F9F9EFEFEFBABABACCCCCCFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8C0 + C0C0CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8CCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCC} + Stretch = True + end + object lblVersion: TLabel + Left = 16 + Top = 272 + Width = 3 + Height = 13 + Anchors = [akLeft, akBottom] + Transparent = True + end + object lblInfo: TLabel + Left = 176 + Top = 272 + Width = 209 + Height = 13 + Alignment = taRightJustify + Anchors = [akLeft, akRight, akBottom] + AutoSize = False + Color = 13224393 + ParentColor = False + Transparent = False + end +end diff --git a/Forms/SplashForm.pas b/Forms/SplashForm.pas new file mode 100644 index 0000000..7152443 --- /dev/null +++ b/Forms/SplashForm.pas @@ -0,0 +1,39 @@ +unit SplashForm; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, ExtCtrls, Global; + +type + TSplashWindow = class(TForm) + BackgroundImage: TImage; + lblVersion: TLabel; + lblInfo: TLabel; + procedure FormCreate(Sender: TObject); + private + { Private declarations } + public + procedure SetInfo(info:string); + end; + +var + SplashWindow: TSplashWindow; + +implementation + +{$R *.dfm} + +procedure TSplashWindow.FormCreate(Sender: TObject); +begin + lblVersion.Caption := APP_BUILD; +end; + +procedure TSplashWindow.SetInfo(info:string); +begin + lblInfo.Caption := info; + //Application.ProcessMessages; +end; + +end. diff --git a/Forms/Template.dfm b/Forms/Template.dfm new file mode 100644 index 0000000..d5fa41e --- /dev/null +++ b/Forms/Template.dfm @@ -0,0 +1,117 @@ +object TemplateForm: TTemplateForm + Left = 399 + Top = 213 + BorderIcons = [biSystemMenu] + BorderStyle = bsSingle + Caption = 'New Flame' + ClientHeight = 391 + ClientWidth = 547 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + FormStyle = fsStayOnTop + Icon.Data = { + 0000010001001010000001001800680300001600000028000000100000002000 + 0000010018000000000000030000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000B7A293634935634935634935 + 6349356349356349356349356349356349356349350000000000000000000000 + 00000000B7A293FFFFFFB7A293B7A293B7A293B7A293B7A293B7A293B7A293B7 + A293634935000000000000000000000000000000B7A293FFFFFFFFFFFFFCFAF9 + F7F1EEF1E7E1ECDDD5E6D3C9E1CABDB7A2936349350000000000000000000000 + 00000000B7A293FFFFFFFFFFFFF5F5F5F1EEECECE4E0E6DBD4E1D1C9E4CFC4B7 + A293634935000000000000000000000000000000B7A293FFFFFFC1C1C1ACACAC + ABAAA9A7A4A2A39D99A09692B4A69FB7A2936349350000000000000000000000 + 00000000BAA596FFFFFFB6B6B6ECECECFFFFFFFBF8F7EEE7E49C9591E8D8D0B7 + A293634935000000000000000000000000000000BEA99AFFFFFFB6B6B6ECECEC + FFFFFFF8F7F6ACAAA7E7DEDAEEE1DAB7A2936349350000000000000000000000 + 00000000C3AE9EFFFFFFB6B6B6ECECECFCFCFCB9B9B9CCCBCAF7F1EEF1E7E1B7 + A293634935000000000000000000000000000000C8B2A3FFFFFFB5B5B5EDEDED + C1C1C1CBCBCBFEFEFEFAF7F5F5EDE9B7A2936349350000000000000000000000 + 00000000CCB6A7FFFFFFB0B0B0C7C7C7C7C7C7FFFFFFFFFFFFFDFCFBB7A293B7 + A293644A36000000000000000000000000000000D1BBABFFFFFFB6B6B6C1C1C1 + FFFFFFFFFFFFFFFFFFB7A293644A36644A36644A360000000000000000000000 + 00000000D5BFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9A495D4C5BA64 + 4A36E1D5CD000000000000000000000000000000D8C2B2FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFC0AB9C644A36E2D6CD0000000000000000000000000000 + 00000000D8C2B2D8C2B2D8C2B2D8C2B2D8C2B2D4BEAECFB9A9C9B3A4E2D6CD00 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + 0000C0070000C0070000C0070000C0070000C0070000C0070000C0070000C007 + 0000C0070000C0070000C0070000C0070000C00F0000C01F0000FFFF0000} + OldCreateOrder = False + OnCreate = FormCreate + OnShow = FormShow + DesignSize = ( + 547 + 391) + PixelsPerInch = 96 + TextHeight = 13 + object lblFile: TLabel + Left = 16 + Top = 364 + Width = 329 + Height = 13 + Anchors = [akLeft, akRight, akBottom] + AutoSize = False + Visible = False + end + object btnCancel: TButton + Left = 454 + Top = 360 + Width = 89 + Height = 25 + Anchors = [akRight, akBottom] + Cancel = True + Caption = 'Cancel' + TabOrder = 1 + OnClick = btnCancelClick + end + object btnOK: TButton + Left = 357 + Top = 359 + Width = 89 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'OK' + Default = True + Enabled = False + TabOrder = 2 + OnClick = btnOKClick + end + object Files: TListBox + Left = 112 + Top = 8 + Width = 417 + Height = 113 + ItemHeight = 13 + TabOrder = 3 + Visible = False + end + object TemplateList: TListView + Left = 8 + Top = 8 + Width = 529 + Height = 344 + Anchors = [akLeft, akTop, akRight, akBottom] + BevelInner = bvNone + BevelOuter = bvNone + BevelKind = bkTile + BorderStyle = bsNone + Color = clBtnFace + Columns = <> + LargeImages = UsedThumbnails + TabOrder = 0 + OnChange = TemplateListChange + end + object UsedThumbnails: TImageList + Height = 128 + Masked = False + Width = 128 + Left = 8 + Top = 320 + end +end diff --git a/Forms/Template.pas b/Forms/Template.pas new file mode 100644 index 0000000..09ef181 --- /dev/null +++ b/Forms/Template.pas @@ -0,0 +1,344 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit Template; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Translation, + Dialogs, StdCtrls, ComCtrls, ImgList, ControlPoint, cmap, RenderingInterface, Main, + Global, Adjust; + +type + TTemplateForm = class(TForm) + TemplateList: TListView; + btnCancel: TButton; + btnOK: TButton; + UsedThumbnails: TImageList; + Files: TListBox; + lblFile: TLabel; + procedure FormShow(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure TemplateListChange(Sender: TObject; Item: TListItem; + Change: TItemChange); + procedure btnOKClick(Sender: TObject); + procedure btnCancelClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + TemplateForm: TTemplateForm; +const + blankFlameXML1 = ''; + blankFlameXML2 = ''; + blankFlameXML3 = ''; + + procedure ListTemplateByFileName(filename:string); + +implementation + +{$R *.dfm} + +function LoadUserTemplates2(mask:string): integer; +var + FindResult: integer; + SearchRec : TSearchRec; + Path : string; +begin + Path:=AppPath + templatePath + '\'; + result := 0; + + FindResult := FindFirst(Path + Mask, faAnyFile - faDirectory, SearchRec); + while FindResult = 0 do + begin + ListTemplateByFileName(Path + SearchRec.Name); + result := result + 1; + + FindResult := FindNext(SearchRec); + end; + { free memory } + FindClose(SearchRec); +end; + +function LoadUserTemplates:integer; +begin + LoadUserTemplates2('*.flame'); + LoadUserTemplates2('*.template'); + Result := 0; // make RTL happy +end; + +function BlankXML:string; +var + i:integer; + s:string; +const + break = ' '; +begin + s:=blankFlameXML1 + break + blankFlameXML2 + break + blankFlameXML3 + break; + for i:=1 to 256 do begin + s := s + '000000'; + if (i mod 32 = 0) then s := s + break; + end; + s := s + ''; + Result := s; +end; + +procedure DropBlank(); +var + flameXML: string; + cp: TControlPoint; + bm: TBitmap; + cmap: TColorMap; + zoom: double; + center: array[0..1] of double; + brightness, gamma, vibrancy: double; + Render: TRenderer; + ListItem: TListItem; + index: integer; +begin + cp := TControlPoint.Create; + Render := TRenderer.Create; + bm := TBitmap.Create; + + cp.Clear; + flameXML := BlankXML; + MainForm.ParseXML(cp, PCHAR(flameXML), true); + cp.AdjustScale(TemplateForm.UsedThumbnails.Width, TemplateForm.UsedThumbnails.Height); + + //Clipboard.SetTextBuf(PChar(Trim(flameXML))); + + // start preview + cp.Width := TemplateForm.UsedThumbnails.Width; + cp.Height := TemplateForm.UsedThumbnails.Height; + cp.spatial_oversample := 1; + cp.spatial_filter_radius := 0.1; + cp.sample_density := 3; + // Render.Compatibility := compatibility; + try + Render.SetCP(cp); + Render.Render; + finally + BM.Assign(Render.GetImage); + cp.Free; + Render.free; + end; +// Thumbnails + TemplateForm.UsedThumbnails.Add(bm, nil); + ListItem := TemplateForm.TemplateList.Items.Add; + ListItem.Caption := 'Blank Flame'; + ListItem.ImageIndex := 0; + TemplateForm.Files.Items.Add('n/a'); + //end preview + // + Application.ProcessMessages; +end; + +procedure DropListItem(FileName: string; FlameName: string); +var + flameXML: string; + cp: TControlPoint; + bm: TBitmap; + cmap: TColorMap; + zoom: double; + center: array[0..1] of double; + brightness, gamma, vibrancy: double; + Render: TRenderer; + ListItem: TListItem; + index: integer; +begin + cp := TControlPoint.Create; + Render := TRenderer.Create; + bm := TBitmap.Create; + + cp.Clear; + flameXML := LoadXMLFlameText(filename, FlameName); + MainForm.ParseXML(cp, PCHAR(flameXML), true); + cp.AdjustScale(TemplateForm.UsedThumbnails.Width, TemplateForm.UsedThumbnails.Height); + + //Clipboard.SetTextBuf(PChar(Trim(flameXML))); + + // start preview + cp.Width := TemplateForm.UsedThumbnails.Width; + cp.Height := TemplateForm.UsedThumbnails.Height; + cp.spatial_oversample := 1; + cp.spatial_filter_radius := 0.1; + cp.sample_density := 3; + // Render.Compatibility := compatibility; + try + Render.SetCP(cp); + Render.Render; + finally + BM.Assign(Render.GetImage); + cp.Free; + Render.free; + end; +// Thumbnails + TemplateForm.UsedThumbnails.Add(bm, nil); + ListItem := TemplateForm.TemplateList.Items.Add; + ListItem.Caption := FlameName; + ListItem.ImageIndex := TemplateForm.TemplateList.Items.Count - 1; + TemplateForm.Files.Items.Add(FileName); + //end preview + // + Application.ProcessMessages; +end; + +procedure ListTemplateByFileName(filename:string); +{ List .flame file } +var + sel:integer; + i, p, img: integer; + Title: string; + ListItem: TListItem; + FStrings: TStringList; + bm: TBitmap; +begin + sel := 0; + if not FileExists(FileName) then exit; + FStrings := TStringList.Create; + FStrings.LoadFromFile(FileName); + try + if (Pos(' 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos(' 0) then + begin + MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(AnsiString(FSTrings[i]))); + MainForm.ListXMLScanner.Execute; + + if Length(pname) = 0 then + Title := '*untitled ' + ptime + else + Title := Trim(pname); + if Title <> '' then + begin { Otherwise bad format } + //ListItem := MainForm.ListView.Items.Add; + //Listitem.Caption := Title; + DropListItem(FileName, Title); + end; + end; + end; + end; + finally + FStrings.Free; + end; +end; + +procedure ListTemplate; +var + i:integer; + bm:TBitmap; +begin + TemplateForm.TemplateList.Items.BeginUpdate; + TemplateForm.TemplateList.Items.Clear; + TemplateForm.UsedThumbnails.Clear; + + // hmmm... + (*for i := 0 to TemplateForm.UsedThumbnails.Count - 1 do + begin + TemplateForm.UsedThumbnails.GetBitmap(i, bm); + bm.Free; + end; *) + + DropBlank; + + ListTemplateByFileName(AppPath + templateFileName); + LoadUserTemplates; + + TemplateForm.TemplateList.Items.EndUpdate; + TemplateForm.TemplateList.Selected := TemplateForm.TemplateList.Items[0]; +end; + +procedure TTemplateForm.FormCreate(Sender: TObject); +begin + self.Caption := TextByKey('template-title'); + btnOK.Caption := TextByKey('common-ok'); + btnCancel.Caption := TextByKey('common-cancel'); +end; + +procedure TTemplateForm.TemplateListChange(Sender: TObject; + Item: TListItem; Change: TItemChange); +var + fn : string; +begin + if (TemplateList.Selected = nil) then begin + btnOK.Enabled := false; + end else begin + if (TemplateList.Selected.Index >= 0) then begin + btnOK.Enabled := true; + if (TemplateList.Selected.Index > 0) then begin + fn := ChangeFileExt(ExtractFileName(Files.Items[TemplateList.Selected.Index]), ''); + if (LowerCase(fn) <> 'default') then lblFile.Caption := 'Template file: ' + fn + else lblFile.Caption := ''; + end else begin + lblFile.Caption := ''; + end; + end else begin + btnOK.Enabled := false; + end; + end; +end; + +procedure TTemplateForm.btnOKClick(Sender: TObject); +var + flameXML:string; + fn:string; + ci:integer; +begin + fn:=Files.Items[TemplateList.Selected.Index]; + if (TemplateList.Selected.Index = 0) then flameXML := BlankXML + else flameXML := LoadXMLFlameText(fn, TemplateList.Selected.Caption); + MainForm.UpdateUndo; + MainForm.StopThread; + MainForm.InvokeLoadXML(flameXML); + Transforms := MainCp.TrianglesFromCP(MainTriangles); + MainForm.Statusbar.Panels[3].Text := MainCp.name; + {if ResizeOnLoad then} + MainForm.ResizeImage; + MainForm.RedrawTimer.Enabled := True; + Application.ProcessMessages; + MainForm.UpdateWindows; + ci := Random(256); //Random(NRCMAPS); + GetCMap(ci, 1, MainCp.cmap); + MainCp.cmapIndex := ci; + AdjustForm.TemplateRandomizeGradient; + btnCancelClick(sender); +end; + +procedure TTemplateForm.btnCancelClick(Sender: TObject); +begin + Close(); +end; + +procedure TTemplateForm.FormShow(Sender: TObject); +begin + ListTemplate; +end; + +end. diff --git a/Forms/Tracer.dfm b/Forms/Tracer.dfm new file mode 100644 index 0000000..0689c21 --- /dev/null +++ b/Forms/Tracer.dfm @@ -0,0 +1,133 @@ +object TraceForm: TTraceForm + Left = 36 + Top = 159 + Width = 411 + Height = 527 + Caption = 'Trace' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + Icon.Data = { + 0000010001001010000000000800680500001600000028000000100000002000 + 0000010008000000000000010000000000000000000000010000000100000000 + 0000000080000080000000808000800000008000800080800000C0C0C000C0DC + C000F0CAA60004040400080808000C0C0C0011111100161616001C1C1C002222 + 220029292900555555004D4D4D004242420039393900807CFF005050FF009300 + D600FFECCC00C6D6EF00D6E7E70090A9AD000000330000006600000099000000 + CC00003300000033330000336600003399000033CC000033FF00006600000066 + 330000666600006699000066CC000066FF000099000000993300009966000099 + 99000099CC000099FF0000CC000000CC330000CC660000CC990000CCCC0000CC + FF0000FF660000FF990000FFCC00330000003300330033006600330099003300 + CC003300FF00333300003333330033336600333399003333CC003333FF003366 + 00003366330033666600336699003366CC003366FF0033990000339933003399 + 6600339999003399CC003399FF0033CC000033CC330033CC660033CC990033CC + CC0033CCFF0033FF330033FF660033FF990033FFCC0033FFFF00660000006600 + 330066006600660099006600CC006600FF006633000066333300663366006633 + 99006633CC006633FF00666600006666330066666600666699006666CC006699 + 00006699330066996600669999006699CC006699FF0066CC000066CC330066CC + 990066CCCC0066CCFF0066FF000066FF330066FF990066FFCC00CC00FF00FF00 + CC009999000099339900990099009900CC009900000099333300990066009933 + CC009900FF00996600009966330099336600996699009966CC009933FF009999 + 330099996600999999009999CC009999FF0099CC000099CC330066CC660099CC + 990099CCCC0099CCFF0099FF000099FF330099CC660099FF990099FFCC0099FF + FF00CC00000099003300CC006600CC009900CC00CC0099330000CC333300CC33 + 6600CC339900CC33CC00CC33FF00CC660000CC66330099666600CC669900CC66 + CC009966FF00CC990000CC993300CC996600CC999900CC99CC00CC99FF00CCCC + 0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF0000CCFF330099FF + 6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF009900CC330000FF33 + 3300FF336600FF339900FF33CC00FF33FF00FF660000FF663300CC666600FF66 + 9900FF66CC00CC66FF00FF990000FF993300FF996600FF999900FF99CC00FF99 + FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCCFF00FFFF3300CCFF + 6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF666600FF66FF00FFFF + 66002100A5005F5F5F00777777008686860096969600CBCBCB00B2B2B200D7D7 + D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FBFF00A4A0A0008080 + 80000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF000000 + 000000000000000000000000000000000000000000000000000000000000AC12 + 1212121212121212121212F70000AC000000000000000000000000120000AC00 + 0000000000000000000000120000AC00FA00FAFA00FA0000000000120000AC00 + 0000000000000000000000120000AC00FAFA00FAFAFA00FA000000120000AC00 + 0000000000000000000000120000AC00FA00FAFA00FAFA00000000120000AC00 + 0000000000000000000000120000AC000000000000000000000000120000ACAC + ACACACACACACACACACACACAC0000ACFF090909090909090909FFADFF0000ACAC + ACACACACACACACACACACACACAC0000000000000000000000000000000000FFFF + 0000000100000001000000010000000100000001000000010000000100000001 + 0000000100000001000000010000000100000001000000010000FFFF0000} + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + DesignSize = ( + 403 + 500) + PixelsPerInch = 96 + TextHeight = 13 + object PageControl1: TPageControl + Left = 0 + Top = 0 + Width = 403 + Height = 500 + ActivePage = TabMain + Align = alClient + Images = MainForm.Buttons + TabOrder = 0 + object TabMain: TTabSheet + Caption = 'Main' + ImageIndex = 47 + object MainTrace: TMemo + Left = 0 + Top = 0 + Width = 395 + Height = 471 + Align = alClient + Color = clBlack + Font.Charset = DEFAULT_CHARSET + Font.Color = clLime + Font.Height = -11 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 0 + end + end + object TabFullscreen: TTabSheet + Caption = 'Fullscreen' + ImageIndex = 52 + object FullscreenTrace: TMemo + Left = 0 + Top = 0 + Width = 395 + Height = 471 + Align = alClient + Color = clBlack + Font.Charset = DEFAULT_CHARSET + Font.Color = clLime + Font.Height = -11 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 0 + end + end + end + object cbTraceLevel: TComboBox + Left = 280 + Top = 0 + Width = 121 + Height = 21 + Style = csDropDownList + Anchors = [akTop, akRight] + ItemHeight = 13 + TabOrder = 1 + OnSelect = cbTraceLevelSelect + Items.Strings = ( + 'No trace' + 'Minimal trace' + 'Full trace') + end +end diff --git a/Forms/Tracer.pas b/Forms/Tracer.pas new file mode 100644 index 0000000..9905119 --- /dev/null +++ b/Forms/Tracer.pas @@ -0,0 +1,149 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit Tracer; + +{$define TRACEFORM_HIDDEN} + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, ComCtrls; + +type + TTraceForm = class(TForm) + PageControl1: TPageControl; + TabMain: TTabSheet; + TabFullscreen: TTabSheet; + FullscreenTrace: TMemo; + cbTraceLevel: TComboBox; + MainTrace: TMemo; + procedure cbTraceLevelSelect(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormCreate(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + TraceForm: TTraceForm; + +var + TraceLevel: integer; + +const + MsgComplete = '< Received WM_THREAD_COMPLETE from RenderThread #'; + MsgTerminated = '< Received WM_THREAD_TERMINATE from RenderThread #'; + MsgNotAssigned = 'Ignoring message: RenderThread does not exist'; + MsgAnotherRunning = 'Ignoring message: another RenderThread is running'; + +implementation + +{$R *.dfm} + +uses + Registry, + Global, Main; + +procedure TTraceForm.cbTraceLevelSelect(Sender: TObject); +begin + TraceLevel := cbTraceLevel.ItemIndex; +end; + +procedure TTraceForm.FormCreate(Sender: TObject); +var + Registry: TRegistry; +begin + { Read position from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Trace', False) then + begin + if Registry.ValueExists('Top') then + self.Top := Registry.ReadInteger('Top'); + if Registry.ValueExists('Left') then + self.Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Width') then + self.Width := Registry.ReadInteger('Width'); + if Registry.ValueExists('Height') then + self.Height := Registry.ReadInteger('Height'); + +{$ifndef TRACEFORM_HIDDEN} + + if Registry.ValueExists('TraceLevel') then + TraceLevel := Registry.ReadInteger('TraceLevel') + else + TraceLevel := 0; + MainForm.tbShowTrace.Visible := true; + MainForm.tbShowTrace.Enabled := true; + MainForm.tbTraceSeparator.Visible := true; + MainForm.tbTraceSeparator.Enabled := true; + +{$else} // Tracer disabled in release version + + TraceLevel := 0; + //MainForm.tbShowTrace.Visible := false; + //MainForm.tbShowTrace.Enabled := false; + //MainForm.tbTraceSeparator.Visible := false; + //MainForm.tbTraceSeparator.Enabled := false; + +{$endif} + + end; + Registry.CloseKey; + finally + Registry.Free; + end; + + cbTraceLevel.ItemIndex := TraceLevel; +end; + +procedure TTraceForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Trace', True) then + begin + if self.WindowState <> wsMaximized then begin + Registry.WriteInteger('Top', self.Top); + Registry.WriteInteger('Left', self.Left); + Registry.WriteInteger('Width', self.Width); + Registry.WriteInteger('Height', self.Height); + + Registry.WriteInteger('TraceLevel', TraceLevel); + end; + end; + finally + Registry.Free; + end; +end; + +end. diff --git a/Forms/formPostProcess.dfm b/Forms/formPostProcess.dfm new file mode 100644 index 0000000..e1d2648 --- /dev/null +++ b/Forms/formPostProcess.dfm @@ -0,0 +1,251 @@ +object frmPostProcess: TfrmPostProcess + Left = 421 + Top = 359 + Width = 709 + Height = 575 + Caption = 'Post Render' + Color = clBtnFace + Constraints.MinHeight = 200 + Constraints.MinWidth = 700 + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + DesignSize = ( + 701 + 548) + PixelsPerInch = 96 + TextHeight = 13 + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 701 + Height = 81 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + DesignSize = ( + 701 + 81) + object pnlFilter: TPanel + Left = 8 + Top = 32 + Width = 121 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = 'Filter Radius' + TabOrder = 11 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlVibrancy: TPanel + Left = 360 + Top = 32 + Width = 105 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = 'Vibrancy' + TabOrder = 10 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlBrightness: TPanel + Left = 192 + Top = 32 + Width = 105 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = 'Brightness' + TabOrder = 8 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlContrast: TPanel + Left = 360 + Top = 8 + Width = 105 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = 'Contrast' + TabOrder = 9 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlGamma: TPanel + Left = 192 + Top = 8 + Width = 105 + Height = 21 + Cursor = crHandPoint + BevelOuter = bvLowered + Caption = 'Gamma' + TabOrder = 7 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object ProgressBar1: TProgressBar + Left = 8 + Top = 61 + Width = 690 + Height = 20 + Anchors = [akLeft, akRight, akBottom] + TabOrder = 1 + end + object txtFilterRadius: TEdit + Left = 128 + Top = 32 + Width = 57 + Height = 21 + TabOrder = 2 + end + object txtGamma: TEdit + Left = 296 + Top = 8 + Width = 57 + Height = 21 + TabOrder = 3 + end + object txtVibrancy: TEdit + Left = 464 + Top = 32 + Width = 57 + Height = 21 + TabOrder = 6 + end + object txtContrast: TEdit + Left = 464 + Top = 8 + Width = 57 + Height = 21 + TabOrder = 5 + end + object txtBrightness: TEdit + Left = 296 + Top = 32 + Width = 57 + Height = 21 + TabOrder = 4 + end + object pnlBackground: TPanel + Left = 8 + Top = 8 + Width = 121 + Height = 21 + Cursor = crArrow + BevelOuter = bvLowered + Caption = 'Background' + TabOrder = 12 + OnDblClick = DragPanelDblClick + OnMouseDown = DragPanelMouseDown + OnMouseMove = DragPanelMouseMove + OnMouseUp = DragPanelMouseUp + end + object pnlBackColor: TPanel + Left = 128 + Top = 8 + Width = 57 + Height = 21 + Cursor = crHandPoint + BevelInner = bvRaised + BevelOuter = bvLowered + BorderStyle = bsSingle + TabOrder = 0 + OnClick = pnlBackColorClick + object shBack: TShape + Left = 2 + Top = 2 + Width = 49 + Height = 13 + Align = alClient + Brush.Color = clBlack + Pen.Color = clWindow + Pen.Style = psClear + Pen.Width = 0 + OnMouseUp = shBackMouseUp + end + end + object btnApply: TButton + Left = 597 + Top = 16 + Width = 97 + Height = 25 + Anchors = [akTop, akRight] + Caption = '&Apply' + Default = True + TabOrder = 13 + OnClick = btnApplyClick + end + end + object ScrollBox1: TScrollBox + Left = 8 + Top = 88 + Width = 689 + Height = 417 + Align = alCustom + Anchors = [akLeft, akTop, akRight, akBottom] + BevelInner = bvNone + BevelKind = bkSoft + BorderStyle = bsNone + Color = clAppWorkSpace + ParentColor = False + TabOrder = 1 + object Image: TImage + Left = 0 + Top = 0 + Width = 687 + Height = 415 + Align = alClient + AutoSize = True + Center = True + Proportional = True + Stretch = True + end + end + object btnSave: TButton + Left = 599 + Top = 516 + Width = 97 + Height = 25 + Anchors = [akRight, akBottom] + Caption = '&Save' + TabOrder = 2 + OnClick = btnSaveClick + end + object chkFitToWindow: TCheckBox + Left = 8 + Top = 520 + Width = 490 + Height = 17 + Anchors = [akLeft, akRight, akBottom] + Caption = 'Fit to window' + Checked = True + State = cbChecked + TabOrder = 3 + Visible = False + OnClick = chkFitToWindowClick + end + object ColorDialog: TColorDialog + Left = 612 + Top = 76 + end +end diff --git a/Forms/formPostProcess.pas b/Forms/formPostProcess.pas new file mode 100644 index 0000000..f0eb756 --- /dev/null +++ b/Forms/formPostProcess.pas @@ -0,0 +1,523 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit formPostProcess; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, ExtCtrls, RenderingInterface, controlpoint, StdCtrls, ComCtrls, + Translation; + +type + TfrmPostProcess = class(TForm) + Panel1: TPanel; + ScrollBox1: TScrollBox; + Image: TImage; + pnlBackColor: TPanel; + ColorDialog: TColorDialog; + ProgressBar1: TProgressBar; + txtFilterRadius: TEdit; + txtGamma: TEdit; + txtVibrancy: TEdit; + txtContrast: TEdit; + txtBrightness: TEdit; + pnlGamma: TPanel; + pnlBrightness: TPanel; + pnlContrast: TPanel; + pnlVibrancy: TPanel; + pnlFilter: TPanel; + shBack: TShape; + pnlBackground: TPanel; + btnSave: TButton; + chkFitToWindow: TCheckBox; + btnApply: TButton; + procedure chkFitToWindowClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure btnSaveClick(Sender: TObject); + procedure btnApplyClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure pnlBackColorClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormShow(Sender: TObject); + + procedure DragPanelMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure DragPanelMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure DragPanelMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure DragPanelDblClick(Sender: TObject); + procedure shBackMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + private + { Private declarations } + FRenderer: TBaseRenderer; + FCP: TControlPoint; + FImagename: string; + + pnlDragMode, pnlDragged, pnlMM: boolean; + pnlDragPos, pnlDragOld: integer; + pnlDragValue: double; + mousepos: TPoint; + + BkgColor: TColor; + Filter, + Gamma, Brightness, + Contrast, Vibrancy: double; + + procedure UpdateFlame; + procedure SetDefaultValues; + + procedure OnProgress(prog: double); + + public + cp : TControlPoint; + + procedure SetRenderer(Renderer: TBaseRenderer); + procedure SetControlPoint(CP: TControlPoint); + procedure SetImageName(imagename: string); + end; + +var + frmPostProcess: TfrmPostProcess; + +implementation + +uses + Registry, Global, Main; + +{$R *.dfm} + +{ TfrmPostProcess } + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.SetRenderer(Renderer: TBaseRenderer); +begin + if assigned(FRenderer) then + FRenderer.Free; + + FRenderer := Renderer; + Frenderer.OnProgress := OnProgress; + Image.Picture.Graphic := FRenderer.GetImage; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.FormShow(Sender: TObject); +var + Registry: TRegistry; +begin + { Read posution from registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\PostProcess', False) then begin + if Registry.ValueExists('Left') then + Left := Registry.ReadInteger('Left'); + if Registry.ValueExists('Top') then + Top := Registry.ReadInteger('Top'); + //if Registry.ValueExists('Width') then + //Width := Registry.ReadInteger('Width'); + //if Registry.ValueExists('Height') then + // Height := Registry.ReadInteger('Height'); + end; + Registry.CloseKey; + finally + Registry.Free; + end; + +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.FormClose(Sender: TObject; var Action: TCloseAction); +var + Registry: TRegistry; +begin + { Write position to registry } + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\PostProcess', True) then + begin + Registry.WriteInteger('Top', Top); + Registry.WriteInteger('Left', Left); + // Registry.WriteInteger('Width', Width); + // Registry.WriteInteger('Height', Height); + end; + finally + Registry.Free; + end; + + FRenderer.Free; // weirdness!!! :-/ + FRenderer := nil; + Image.Picture.Graphic := nil; + FCP.Free; + FCP := nil; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.SetDefaultValues; +begin + BkgColor := RGB(Fcp.background[0], Fcp.background[1], Fcp.background[2]); + pnlBackColor.Color := BkgColor; + shBack.Brush.Color := BkgColor; + Filter := FCP.spatial_filter_radius; + txtFilterRadius.Text := FloatTostr(Filter); + Gamma := FCP.gamma; + txtGamma.Text := FloatTostr(Gamma); + Vibrancy := FCP.vibrancy; + txtVibrancy.Text := FloatTostr(Vibrancy); + Contrast := FCP.contrast; + txtContrast.Text := FloatTostr(Contrast); + Brightness := FCP.brightness; + txtBrightness.Text := FloatTostr(brightness); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.SetControlPoint(CP: TControlPoint); +begin + if assigned(FCP) then + FCP.Free; + + FCP := cp.Clone; + SetDefaultValues; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.pnlBackColorClick(Sender: TObject); +var + col: Longint; +begin + ColorDialog.Color := shBack.Brush.Color; + if ColorDialog.Execute then begin + pnlBackColor.Color := ColorDialog.Color; + shBack.Brush.Color := ColorDialog.Color; + col := ColorToRGB(ColorDialog.Color); + Fcp.background[0] := col and 255; + Fcp.background[1] := (col shr 8) and 255; + Fcp.background[2] := (col shr 16) and 255; + UpdateFlame; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.UpdateFlame; +begin + Screen.Cursor := crHourGlass; + FRenderer.UpdateImage(FCP); + Image.Picture.Graphic := FRenderer.GetImage; + Screen.Cursor := crDefault; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.FormDestroy(Sender: TObject); +begin + if assigned(FRenderer) then + FRenderer.Free; + + if assigned(FCP) then + FCP.Free; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.OnProgress(prog: double); +begin + ProgressBar1.Position := round(100 * prog); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.btnApplyClick(Sender: TObject); +var + temp: double; +begin + TryStrToFloat(txtFilterRadius.Text, FCP.spatial_filter_radius); + if FCP.spatial_filter_radius > 2 then begin + FCP.spatial_filter_radius := 2; + txtFilterRadius.Text := '2'; + end else if FCP.spatial_filter_radius < 0 then begin + FCP.spatial_filter_radius := 0.01; + txtFilterRadius.Text := FloatTostr(0.01); + end; + + TryStrToFloat(txtGamma.Text, FCP.gamma); + if FCP.gamma > 10 then begin + FCP.gamma := 10; + txtGamma.Text := '10'; + end else if FCP.gamma < 0.01 then begin + FCP.gamma := 0.01; + txtGamma.Text := FloatTostr(0.01); + end; + + TryStrToFloat(txtVibrancy.Text, FCP.vibrancy); + if FCP.vibrancy > 10 then begin + FCP.vibrancy := 10; + txtVibrancy.Text := '10'; + end else if FCP.vibrancy < 0.01 then begin + FCP.vibrancy := 0.01; + txtVibrancy.Text := FloatTostr(0.01); + end; + + TryStrToFloat(txtContrast.Text, FCP.contrast); + if FCP.contrast > 10 then begin + FCP.contrast := 10; + txtContrast.Text := '10'; + end else if FCP.contrast < 0.01 then begin + FCP.contrast := 0.01; + txtContrast.Text := FloatTostr(0.01); + end; + + if TryStrToFloat(txtBrightness.Text, temp) then FCP.brightness := temp; + //TryStrToFloat(txtBrightness.Text, FCP.brightness); + if FCP.brightness > 100 then begin + FCP.brightness := 100; + txtBrightness.Text := '100'; + end else if FCP.brightness < 0.01 then begin + FCP.brightness := 0.01; + txtBrightness.Text := FloatTostr(0.01); + end; + + UpdateFlame; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.btnSaveClick(Sender: TObject); +begin + FRenderer.SaveImage(FImagename); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TfrmPostProcess.SetImageName(imagename: string); +begin + FImagename := imagename; +end; + +// ----------------------------------------------------------------------------- + +procedure TfrmPostProcess.DragPanelMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if Button <> mbLeft then exit; + + if (Sender = pnlFilter) then + pnlDragValue := fcp.spatial_filter_radius * 10 + else if (Sender = pnlGamma) then + pnlDragValue := fcp.gamma + else if (Sender = pnlBrightness) then + pnlDragValue := fcp.brightness + else if (Sender = pnlContrast) then + pnlDragValue := fcp.contrast + else if (Sender = pnlVibrancy) then + pnlDragValue := fcp.vibrancy + else exit;//assert(false); + + pnlDragMode := true; + pnlDragPos := 0; + pnlDragOld := x; + pnlMM := false; + SetCaptureControl(TControl(Sender)); + Screen.Cursor := crHSplit; + GetCursorPos(mousepos); // hmmm + pnlDragged := false; +end; + +procedure TfrmPostProcess.DragPanelMouseMove(Sender: TObject; Shift: TShiftState; + X, Y: Integer); +var + v: double; + pEdit: ^TEdit; + enableDrag : boolean; +begin + if pnlMM then // hack: to skip MouseMove event + begin + pnlMM:=false; + end + else + if pnlDragMode and (x <> pnlDragOld) then + begin + Inc(pnlDragPos, x - pnlDragOld); + + if GetKeyState(VK_MENU) < 0 then v := 100000 + else if GetKeyState(VK_CONTROL) < 0 then v := 10000 + else if GetKeyState(VK_SHIFT) < 0 then v := 100 + else v := 1000; + + v := Round6(pnlDragValue + pnlDragPos / v); + + SetCursorPos(MousePos.x, MousePos.y); // hmmm + pnlMM:=true; + + enableDrag := true; + if (Sender = pnlFilter) then + begin + v := v / 10; + if v > 2 then v := 2 + else if v < 0.01 then v := 0.01; + fcp.spatial_filter_radius := v; + pEdit := @txtFilterRadius; + end + else if (Sender = pnlGamma) then + begin + if v > 10 then v := 10 + else if v < 0.01 then v := 0.01; + fcp.gamma := v; + pEdit := @txtGamma; + end + else if (Sender = pnlBrightness) then + begin + if v > 100 then v := 100 + else if v < 0.01 then v := 0.01; + fcp.brightness := v; + pEdit := @txtBrightness; + end + else if (Sender = pnlContrast) then + begin + if v > 10 then v := 10 + else if v < 0.01 then v := 0.01; + fcp.contrast := v; + pEdit := @txtContrast; + end + else if (Sender = pnlVibrancy) then + begin + if v > 10 then v := 10 + else if v < 0.01 then v := 0.01; + fcp.vibrancy := v; + pEdit := @txtVibrancy; + end else exit; + + if enableDrag then begin + pEdit^.Text := FloatToStr(v); + //pEdit.Refresh; + pnlDragged := True; + // TODO: image preview (?) + //DrawPreview; + end; + end; +end; + +procedure TfrmPostProcess.DragPanelMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + if Button <> mbLeft then exit; + + if pnlDragMode then + begin + SetCaptureControl(nil); + pnlDragMode := false; + Screen.Cursor := crDefault; + + if pnlDragged then + begin + //UpdateFlame; + pnlDragged := False; + end; + end; +end; + +procedure TfrmPostProcess.DragPanelDblClick(Sender: TObject); +var + pValue: ^double; + pDefaultValue: ^double; + pEdit: ^TEdit; +begin + if (Sender = pnlFilter) then + begin + pValue := @fcp.spatial_filter_radius; + pDefaultValue := @Filter; + pEdit := @txtFilterRadius; + end + else if (Sender = pnlGamma) then + begin + pValue := @fcp.gamma; + pDefaultValue := @Gamma; + pEdit := @txtGamma; + end + else if (Sender = pnlBrightness) then + begin +{ + pValue := @fcp.brightness; + pDefaultValue := @Brightness; + pEdit := @txtBrightness; +} + if fcp.brightness = Brightness then exit; + fcp.brightness := Brightness; + txtBrightness.Text := FloatToStr(fcp.brightness); + exit; + end + else if (Sender = pnlContrast) then + begin + pValue := @fcp.contrast; + pDefaultValue := @Contrast; + pEdit := @txtContrast + end + else if (Sender = pnlVibrancy) then + begin + pValue := @fcp.vibrancy; + pDefaultValue := @Vibrancy; + pEdit := @txtVibrancy; + end + else exit; //assert(false); + + if pValue^ = pDefaultValue^ then exit; + pValue^ := pDefaultValue^; + pEdit^.Text := FloatToStr(pValue^); + //UpdateFlame; +end; + +procedure TfrmPostProcess.shBackMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + pnlBackColorClick(sender); +end; + +procedure TfrmPostProcess.FormCreate(Sender: TObject); +begin + btnApply.Caption := TextByKey('common-apply'); + pnlFilter.Caption := TextByKey('common-filterradius'); + pnlGamma.Caption := TextByKey('common-gamma'); + pnlBrightness.Caption := TextByKey('common-brightness'); + pnlContrast.Caption := TextByKey('common-contrast'); + pnlVibrancy.Caption := TextByKey('common-vibrancy'); + pnlBackground.Caption := TextByKey('common-background'); + pnlFilter.Hint := TextByKey('common-dragpanelhint'); + pnlGamma.Hint := TextByKey('common-dragpanelhint'); + pnlBrightness.Hint := TextByKey('common-dragpanelhint'); + pnlVibrancy.Hint := TextByKey('common-dragpanelhint'); + pnlContrast.Hint := TextByKey('common-dragpanelhint'); + self.Caption := TextByKey('postprocess-title'); + btnSave.Caption := TextByKey('postprocess-save'); + chkFitToWindow.Caption := TextByKey('postprocess-fittowindow'); +end; + +procedure TfrmPostProcess.chkFitToWindowClick(Sender: TObject); +begin + {if (chkFitToWindow.Checked) then begin + Image.Stretch := true; + Image.Align := alClient; + end else begin + Image.Stretch := false; + Image.Align := alNone; + end; } +end; + +end. diff --git a/IO/Base64.pas b/IO/Base64.pas new file mode 100644 index 0000000..8b60561 --- /dev/null +++ b/IO/Base64.pas @@ -0,0 +1,267 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit Base64; + +interface +uses + Windows, Sysutils; + +type TBinArray = Array of Byte; + +{ Base64 encode and decode a string } +function B64Encode(const data: TBinArray; size : integer): string; +procedure B64Decode(S: string; var data : TBinArray; var size : integer); + +{******************************************************************************} +{******************************************************************************} +implementation + +const + B64Table= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +procedure StringToBinArray(const s: String; var bin: TBinArray); +var + l: Integer; +begin + l := Length(s); + SetLength(bin, l); + CopyMemory(@bin[0], @s[1], l); +end; + +procedure BinArrayToString(const bin: TBinArray; var s: string); +var + l: Integer; +begin + l := Length(bin); + SetLength(s, l); + CopyMemory(@s[1], @bin[0], l); +end; + +function B64Encode(const data: TBinArray; size : integer) : string; +var + i: integer; + S: string; + InBuf: array[0..2] of byte; + OutBuf: array[0..3] of char; +begin + BinArrayToString(data, s); + SetLength(Result,((size+2) div 3)*4); + for i:= 1 to ((size+2) div 3) do + begin + if size< (i*3) then + Move(S[(i-1)*3+1],InBuf,size-(i-1)*3) + 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 (size mod 3)= 1 then + begin + Result[Length(Result)-1]:= '='; + Result[Length(Result)]:= '='; + end + else if (Length(S) mod 3)= 2 then + Result[Length(Result)]:= '='; +end; + +procedure B64Decode(S: string; var data : TBinArray; var size : integer); +var + i: integer; + InBuf: array[0..3] of byte; + OutBuf: array[0..2] of byte; + Result2: string; +begin + if (Length(S) mod 4)<> 0 then + raise Exception.Create('Base64: Incorrect string format'); + SetLength(Result2,((Length(S) div 4)-1)*3); + 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 + Dec(InBuf[0],65) + else if (InBuf[0]> 96) and (InBuf[0]< 123) then + Dec(InBuf[0],71) + else if (InBuf[0]> 47) and (InBuf[0]< 58) then + Inc(InBuf[0],4) + else if InBuf[0]= 43 then + InBuf[0]:= 62 + else + InBuf[0]:= 63; + if (InBuf[1]> 64) and (InBuf[1]< 91) then + Dec(InBuf[1],65) + else if (InBuf[1]> 96) and (InBuf[1]< 123) then + Dec(InBuf[1],71) + else if (InBuf[1]> 47) and (InBuf[1]< 58) then + Inc(InBuf[1],4) + else if InBuf[1]= 43 then + InBuf[1]:= 62 + else + InBuf[1]:= 63; + if (InBuf[2]> 64) and (InBuf[2]< 91) then + Dec(InBuf[2],65) + else if (InBuf[2]> 96) and (InBuf[2]< 123) then + Dec(InBuf[2],71) + else if (InBuf[2]> 47) and (InBuf[2]< 58) then + Inc(InBuf[2],4) + else if InBuf[2]= 43 then + InBuf[2]:= 62 + else + InBuf[2]:= 63; + if (InBuf[3]> 64) and (InBuf[3]< 91) then + Dec(InBuf[3],65) + else if (InBuf[3]> 96) and (InBuf[3]< 123) then + Dec(InBuf[3],71) + else if (InBuf[3]> 47) and (InBuf[3]< 58) then + Inc(InBuf[3],4) + else if InBuf[3]= 43 then + InBuf[3]:= 62 + 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,Result2[(i-1)*3+1],3); + end; + if Length(S)<> 0 then + begin + Move(S[Length(S)-3],InBuf,4); + 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 + Dec(InBuf[0],71) + else if (InBuf[0]> 47) and (InBuf[0]< 58) then + Inc(InBuf[0],4) + else if InBuf[0]= 43 then + InBuf[0]:= 62 + else + InBuf[0]:= 63; + if (InBuf[1]> 64) and (InBuf[1]< 91) then + Dec(InBuf[1],65) + else if (InBuf[1]> 96) and (InBuf[1]< 123) then + Dec(InBuf[1],71) + else if (InBuf[1]> 47) and (InBuf[1]< 58) then + Inc(InBuf[1],4) + else if InBuf[1]= 43 then + InBuf[1]:= 62 + else + InBuf[1]:= 63; + OutBuf[0]:= (InBuf[0] shl 2) or ((InBuf[1] shr 4) and $03); + Result2:= Result2 + char(OutBuf[0]); + 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 + Dec(InBuf[0],71) + else if (InBuf[0]> 47) and (InBuf[0]< 58) then + Inc(InBuf[0],4) + else if InBuf[0]= 43 then + InBuf[0]:= 62 + else + InBuf[0]:= 63; + if (InBuf[1]> 64) and (InBuf[1]< 91) then + Dec(InBuf[1],65) + else if (InBuf[1]> 96) and (InBuf[1]< 123) then + Dec(InBuf[1],71) + else if (InBuf[1]> 47) and (InBuf[1]< 58) then + Inc(InBuf[1],4) + else if InBuf[1]= 43 then + InBuf[1]:= 62 + else + InBuf[1]:= 63; + if (InBuf[2]> 64) and (InBuf[2]< 91) then + Dec(InBuf[2],65) + else if (InBuf[2]> 96) and (InBuf[2]< 123) then + Dec(InBuf[2],71) + else if (InBuf[2]> 47) and (InBuf[2]< 58) then + Inc(InBuf[2],4) + else if InBuf[2]= 43 then + InBuf[2]:= 62 + 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); + Result2:= Result2 + char(OutBuf[0]) + char(OutBuf[1]); + 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 + Dec(InBuf[0],71) + else if (InBuf[0]> 47) and (InBuf[0]< 58) then + Inc(InBuf[0],4) + else if InBuf[0]= 43 then + InBuf[0]:= 62 + else + InBuf[0]:= 63; + if (InBuf[1]> 64) and (InBuf[1]< 91) then + Dec(InBuf[1],65) + else if (InBuf[1]> 96) and (InBuf[1]< 123) then + Dec(InBuf[1],71) + else if (InBuf[1]> 47) and (InBuf[1]< 58) then + Inc(InBuf[1],4) + else if InBuf[1]= 43 then + InBuf[1]:= 62 + else + InBuf[1]:= 63; + if (InBuf[2]> 64) and (InBuf[2]< 91) then + Dec(InBuf[2],65) + else if (InBuf[2]> 96) and (InBuf[2]< 123) then + Dec(InBuf[2],71) + else if (InBuf[2]> 47) and (InBuf[2]< 58) then + Inc(InBuf[2],4) + else if InBuf[2]= 43 then + InBuf[2]:= 62 + else + InBuf[2]:= 63; + if (InBuf[3]> 64) and (InBuf[3]< 91) then + Dec(InBuf[3],65) + else if (InBuf[3]> 96) and (InBuf[3]< 123) then + Dec(InBuf[3],71) + else if (InBuf[3]> 47) and (InBuf[3]< 58) then + Inc(InBuf[3],4) + else if InBuf[3]= 43 then + InBuf[3]:= 62 + 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); + Result2:= Result2 + Char(OutBuf[0]) + Char(OutBuf[1]) + Char(OutBuf[2]); + end; + end; + + StringToBinArray(Result2, data); + size := Length(result2); +end; + +end. + diff --git a/IO/Binary.pas b/IO/Binary.pas new file mode 100644 index 0000000..59326b3 --- /dev/null +++ b/IO/Binary.pas @@ -0,0 +1,177 @@ +unit Binary; + +interface + +const + + HIB_BLOCKSIZE = $10; // 16 bytes + HIB_MAXOFFSET = $0F; // HIB_BLOCKSIZE - 1 + +type + + // low-level binary types + TBlock = array[0..HIB_MAXOFFSET] of byte; + TWord = array[0..1] of byte; + TDWord = array[0..3] of byte; + TQWord = array[0..7] of byte; + THibRawString = array of byte; + +// procedures to write blocks at low level +procedure WriteData2(var target: TBlock; data: TWord; pos: integer); +procedure WriteData4(var target: TBlock; data: TDWord; pos: integer); +procedure WriteData8(var target: TBlock; data: TQWord; pos: integer); + +// procedures to read blocks at low level +procedure ReadData2(source: TBlock; var data: TWord; pos: integer); +procedure ReadData4(source: TBlock; var data: TDWord; pos: integer); +procedure ReadData8(source: TBlock; var data: TQWord; pos: integer); + +// procedures to write typed data to blocks +procedure Int16ToBlock(var target: TBlock; pos: integer; data: SmallInt); +procedure Int32ToBlock(var target: TBlock; pos: integer; data: Integer); +procedure LongWordToBlock(var target: TBlock; pos: integer; data: LongWord); +procedure Int64ToBlock(var target: TBlock; pos: integer; data: Int64); +procedure SingleToBlock(var target: TBlock; pos: integer; data: Single); +procedure DoubleToBlock(var target: TBlock; pos: integer; data: Double); + +// procedures to read typed data from blocks +function BlockToInt16(source: TBlock; pos: integer): SmallInt; +function BlockToInt32(source: TBlock; pos: integer): Integer; +function BlockToLongWord(source: TBlock; pos: integer): LongWord; +function BlockToInt64(source: TBlock; pos: integer): Int64; +function BlockToSingle(source: TBlock; pos: integer): Single; +function BlockToDouble(source: TBlock; pos: integer): Double; + +implementation + +procedure ReadData2(source: TBlock; var data: TWord; pos: integer); +const size = 2; +var i: integer; +begin + for i := 0 to size - 1 do + if i + pos < HIB_BLOCKSIZE then + data[i] := source[i + pos]; +end; +procedure ReadData4(source: TBlock; var data: TDWord; pos: integer); +const size = 4; +var i: integer; +begin + for i := 0 to size - 1 do + if i + pos < HIB_BLOCKSIZE then + data[i] := source[i + pos]; +end; +procedure ReadData8(source: TBlock; var data: TQWord; pos: integer); +const size = 8; +var i: integer; +begin + for i := 0 to size - 1 do + if i + pos < HIB_BLOCKSIZE then + data[i] := source[i + pos]; +end; + +procedure WriteData2(var target: TBlock; data: TWord; pos: integer); +const size = 2; +var i: integer; +begin + for i := 0 to size - 1 do + if i + pos < HIB_BLOCKSIZE then + target[i + pos] := data[i]; +end; +procedure WriteData4(var target: TBlock; data: TDWord; pos: integer); +const size = 4; +var i: integer; +begin + for i := 0 to size - 1 do + if i + pos < HIB_BLOCKSIZE then + target[i + pos] := data[i]; +end; +procedure WriteData8(var target: TBlock; data: TQWord; pos: integer); +const size = 8; +var i: integer; +begin + for i := 0 to size - 1 do + if i + pos < HIB_BLOCKSIZE then + target[i + pos] := data[i]; +end; + +function BlockToInt16(source: TBlock; pos: integer): SmallInt; +var temp: TWord; data: SmallInt; +begin + ReadData2(source, temp, pos); + Move(temp, data, SizeOf(TWord)); + Result := data; +end; +function BlockToInt32(source: TBlock; pos: integer): Integer; +var temp: TDWord; data: Integer; +begin + ReadData4(source, temp, pos); + Move(temp, data, SizeOf(TDWord)); + Result := data; +end; +function BlockToLongWord(source: TBlock; pos: integer): LongWord; +var temp: TDWord; data: LongWord; +begin + ReadData4(source, temp, pos); + Move(temp, data, SizeOf(TDWord)); + Result := data; +end; +function BlockToInt64(source: TBlock; pos: integer): Int64; +var temp: TQWord; data: Int64; +begin + ReadData8(source, temp, pos); + Move(temp, data, SizeOf(TQWord)); + Result := data; +end; +function BlockToSingle(source: TBlock; pos: integer): Single; +var temp: TDWord; data: Single; +begin + ReadData4(source, temp, pos); + Move(temp, data, SizeOf(TDWord)); + Result := data; +end; +function BlockToDouble(source: TBlock; pos: integer): Double; +var temp: TQWord; data: Double; +begin + ReadData8(source, temp, pos); + Move(temp, data, SizeOf(TQWord)); + Result := data; +end; + +procedure Int16ToBlock(var target: TBlock; pos: integer; data: SmallInt); +var temp: TWord; +begin + Move(data, temp, SizeOf(TWord)); + WriteData2(target, temp, pos); +end; +procedure Int32ToBlock(var target: TBlock; pos: integer; data: Integer); +var temp: TDWord; +begin + Move(data, temp, SizeOf(TDWord)); + WriteData4(target, temp, pos); +end; +procedure LongWordToBlock(var target: TBlock; pos: integer; data: LongWord); +var temp: TDWord; +begin + Move(data, temp, SizeOf(TDWord)); + WriteData4(target, temp, pos); +end; +procedure Int64ToBlock(var target: TBlock; pos: integer; data: Int64); +var temp: TQWord; +begin + Move(data, temp, SizeOf(TQWord)); + WriteData8(target, temp, pos); +end; +procedure SingleToBlock(var target: TBlock; pos: integer; data: single); +var temp: TDWord; +begin + Move(data, temp, SizeOf(TDWord)); + WriteData4(target, temp, pos); +end; +procedure DoubleToBlock(var target: TBlock; pos: integer; data: double); +var temp: TQWord; +begin + Move(data, temp, SizeOf(TQWord)); + WriteData8(target, temp, pos); +end; + +end. diff --git a/IO/CommandLine.pas b/IO/CommandLine.pas new file mode 100644 index 0000000..4f72a70 --- /dev/null +++ b/IO/CommandLine.pas @@ -0,0 +1,48 @@ +unit CommandLine; + +interface + uses Dialogs, RegularExpressionsCore; + + type TCommandLine = class + public + CreateFromTemplate : boolean; + TemplateFile : string; + TemplateName : string; + Lite: boolean; + + procedure Load; + + end; + +implementation + +procedure TCommandLine.Load; +var + Regex: TPerlRegEx; +begin + Regex := TPerlRegEx.Create; + Regex.RegEx := '-template\s+"(.+)"\s+"(.+)"'; + Regex.Options := [preSingleLine, preCaseless]; + Regex.Subject := Utf8String(CmdLine); + CreateFromTemplate := false; + if Regex.Match then begin + if Regex.GroupCount = 2 then begin + CreateFromTemplate := true; + TemplateFile := String(Regex.Groups[1]); + TemplateName := String(Regex.Groups[2]); + end; + end; + Regex.Destroy; + + Regex := TPerlRegEx.Create; + Regex.RegEx := '-lite'; + Regex.Options := [preSingleLine, preCaseless]; + Regex.Subject := Utf8String(CmdLine); + CreateFromTemplate := false; + if Regex.Match then begin + Lite := true; + end; + Regex.Destroy; +end; + +end. diff --git a/IO/Hibernation.pas b/IO/Hibernation.pas new file mode 100644 index 0000000..54b7ef0 --- /dev/null +++ b/IO/Hibernation.pas @@ -0,0 +1,397 @@ +unit Hibernation; + +interface + +uses RenderingCommon, RenderingInterface, SysUtils, Windows, Forms, Classes, Binary, ControlPoint; + +const + HIB_VERSION_MAJOR = 2; // Apophysis7X.15 + HIB_VERSION_MINOR = 10; + HIB_VERSION_REVISION = 1500; + + HIB_ADDR_HEADER = $30; // 48 bytes + HIB_SIZE_HEADER = $30; // 48 bytes + HIB_ADDR_LOCATOR = $60; // HIB_SIZE_HEADER + HIB_ADDR_HEADER + HIB_SIZE_LOCATOR = $20; // 32 bytes + + HIB_COOKIE_INTRO_HIGH = $AB; // A B0F + HIB_COOKIE_INTRO_LOW = $0F; + HIB_COOKIE_OUTRO_HIGH = $AE; // A E0F + HIB_COOKIE_OUTRO_LOW = $0F; + +type + EHibBitsPerPixel = ( + EBP_32 = 32, + EBP_64 = 64 // 64 bit renderer; probably used later + ); + EHibPixelLayout = ( + EPL_XYZW = 0123, + EPL_YXZW = 1023, // indicates different subpixel orders; + EPL_YZXW = 1203, // for example, metaphysis uses WXYZ (3012) + EPL_YZWX = 1230, + EPL_XZYW = 0213, + EPL_XZWY = 0231, + EPL_XYWZ = 0132, + EPL_ZXYW = 2013, + EPL_WXYZ = 3012, + EPL_XWYZ = 0312 + ); + EHibFileFlags = ( + EFF_NONE = 0, // no flags (default) + EFF_FLOATBUFFER = 1, // using a float buffer (32/64bit) + EFF_SEPARATEFLAME = 2, // flame stored in separate file (unused yet) + EFF_BINARYFLAME = 4, // flame stored in binary format (unused yet) + EFF_COMPRESSED = 8 // data is GZIP-compressed (unused yet) + ); + + // some types for the header (some unused) + THibInt2_32 = record X, Y : integer; end; + THibInt2_64 = record X, Y : int64; end; + THibFloat2 = record X, Y : double; end; + THibFloat4 = record X, Y, Z, W : double; end; + THibBoolean = (HB_YES = -1, HB_NO = 0); + + // the actual header + THibHeader = record + ActualDensity : double; + Size2D : THibInt2_64; + Size : int64; + RenderTime : TDateTime; + PauseTime : TDateTime; + end; + +// file allocation and release procedures +procedure HibAllocate(var handle: File; path: string); +procedure HibOpen(var handle: File; path: string); +procedure HibFree(const handle: File); + +// high-level write procedures +procedure HibWriteIntro(const handle: File); +procedure HibWriteOutro(const handle: File); +procedure HibWriteGlobals(const handle: File; flags: EHibFileFlags; + layout: EHibPixelLayout; bpp: EHibBitsPerPixel); +procedure HibWriteHeader(const handle: File; header: THibHeader); +procedure HibWriteData(const handle: File; header: THibHeader; + flame: TControlPoint; buckets: TBucket32Array; + colormap: TColorMapArray; callback: TOnProgress); + +// high-level read procedures +procedure HibReadIntro(const handle: File; var cookieValid: boolean); +procedure HibReadOutro(const handle: File; var cookieValid: boolean); +procedure HibReadGlobals(const handle: File; var versionRel: smallint; + var flags: EHibFileFlags; var layout: EHibPixelLayout; var bpp: EHibBitsPerPixel); +procedure HibReadHeader(const handle: File; var header: THibHeader); +procedure HibReadData(const handle: File; header: THibHeader; var flame: TStringList; + var buckets: TBucket32Array; var colormap: TColorMapArray; callback: TOnProgress); + +implementation + +//////////////////////////////////////////////////////////////////////////////// + +procedure HibAllocate(var handle: File; path: string); +begin + AssignFile(handle, path); + ReWrite(handle, HIB_BLOCKSIZE); +end; + +procedure HibOpen(var handle: File; path: string); +begin + AssignFile(handle, path); + FileMode := fmOpenRead; + Reset(handle, HIB_BLOCKSIZE); +end; + +procedure HibFree(const handle: File); +begin + CloseFile(handle); +end; + +//////////////////////////////////////////////////////////////////////////////// + +procedure HibWriteIntro(const handle: File); +var + block: TBlock; + chunk: string; +begin + block[0] := HIB_COOKIE_INTRO_HIGH; + block[1] := HIB_COOKIE_INTRO_LOW; + chunk := 'Apophysis7X Hi'; + CopyMemory(@block[2], @chunk[1], Length(chunk)); + BlockWrite(handle, block, 1); + chunk := 'bernation File'; + block[14] := $0; block[15] := $0; + CopyMemory(@block[0], @chunk[1], Length(chunk)); + BlockWrite(handle, block, 1); +end; + +procedure HibWriteOutro(const handle: File); +var + block: TBlock; +begin + block[0] := $0; block[1] := $0; block[2] := $0; block[3] := $0; + block[4] := $0; block[5] := $0; block[6] := $0; block[7] := $0; + block[8] := $0; block[9] := $0; block[10] := $0; block[11] := $0; + block[12] := $0; block[13] := $0; + block[14] := HIB_COOKIE_OUTRO_HIGH; + block[15] := HIB_COOKIE_OUTRO_LOW; + BlockWrite(handle, block, 1); +end; + +procedure HibWriteGlobals(const handle: File; flags: EHibFileFlags; + layout: EHibPixelLayout; bpp: EHibBitsPerPixel); +var + block: TBlock; +begin + Int16ToBlock(block, 0, HIB_VERSION_MAJOR); + Int16ToBlock(block, 2, HIB_VERSION_MINOR); + Int32ToBlock(block, 4, HIB_VERSION_REVISION); + Int16ToBlock(block, 8, SmallInt(flags)); + Int16ToBlock(block, 10, HIB_SIZE_HEADER); + Int16ToBlock(block, 12, SmallInt(layout)); + Int16ToBlock(block, 14, SmallInt(bpp)); + BlockWrite(handle, block, 1); +end; + +procedure HibWriteHeader(const handle: File; header: THibHeader); +var + block: TBlock; +begin + DoubleToBlock(block, 0, header.ActualDensity); + Int64ToBlock(block, 8, header.Size); + BlockWrite(handle, block, 1); + + Int64ToBlock(block, 0, header.Size2D.X); + Int64ToBlock(block, 8, header.Size2D.Y); + BlockWrite(handle, block, 1); + + Int64ToBlock(block, 0, + Int64(((Trunc(header.RenderTime) - 25569) * 86400) + + Trunc(86400 * (header.RenderTime - + Trunc(header.RenderTime))) - 7200)); + Int64ToBlock(block, 8, + Int64(((Trunc(header.PauseTime) - 25569) * 86400) + + Trunc(86400 * (header.PauseTime - + Trunc(header.PauseTime))) - 7200)); + BlockWrite(handle, block, 1); +end; + +procedure HibWriteData(const handle: File; header: THibHeader; flame: TControlPoint; + buckets: TBucket32Array; colormap: TColorMapArray; callback: TOnProgress); +var + block: TBlock; + flametext: string; + rawflame: THibRawString; + rawflamesize: integer; + rawflamechunks: integer; + i, j, c: integer; + p, step: double; +begin + rawflamesize := CalcBinaryFlameSize(flame); + + Int64ToBlock(block, 0, HIB_ADDR_LOCATOR + HIB_SIZE_LOCATOR); + Int64ToBlock(block, 8, Int64(rawflamesize) ); + BlockWrite(handle, block, 1); + + Int64ToBlock(block, 0, HIB_ADDR_LOCATOR + HIB_SIZE_LOCATOR + rawflamesize); + Int64ToBlock(block, 8, 16 * header.Size2D.X * header.Size2D.Y); + BlockWrite(handle, block, 1); + + flame.SaveToBinary(handle); + + callback(0); + c := 0; p := 0; + step := 1.0 / (header.Size2D.X * header.Size2D.Y); + for j := 0 to header.Size2D.Y - 1 do + for i := 0 to header.Size2D.X - 1 do + with buckets[j][i] do begin + Int32ToBlock(block, 0, Red); + Int32ToBlock(block, 4, Green); + Int32ToBlock(block, 8, Blue); + Int32ToBlock(block, 12, Count); + BlockWrite(handle, block, 1); + p := p + step; + c := (c + 1) mod 64; + if (c = 0) then begin + callback(p*0.99); + Application.ProcessMessages; + end; + end; + callback(0.99); + + i := 0; + while i < 256 do begin + Int32ToBlock(block, 0, + (colormap[i+0].Red) or + (((colormap[i+0].Green) and $ff) shl 8) or + (((colormap[i+0].Blue) and $ff) shl 16)); + Int32ToBlock(block, 4, + (colormap[i+1].Red) or + (((colormap[i+1].Green) and $ff) shl 8) or + (((colormap[i+1].Blue) and $ff) shl 16)); + Int32ToBlock(block, 8, + (colormap[i+2].Red) or + (((colormap[i+2].Green) and $ff) shl 8) or + (((colormap[i+2].Blue) and $ff) shl 16)); + Int32ToBlock(block, 12, + (colormap[i+3].Red) or + (((colormap[i+3].Green) and $ff) shl 8) or + (((colormap[i+3].Blue) and $ff) shl 16)); + BlockWrite(handle, block, 1); + i := i + 4; + end; + callback(1); +end; + +//////////////////////////////////////////////////////////////////////////////// + +procedure HibReadIntro(const handle: File; var cookieValid: boolean); +var + block1, block2: TBlock; +begin + BlockRead(handle, block1, 1); + BlockRead(handle, block2, 1); + cookieValid := + (block1[0] = HIB_COOKIE_INTRO_HIGH) and + (block1[1] = HIB_COOKIE_INTRO_LOW); +end; +procedure HibReadOutro(const handle: File; var cookieValid: boolean); +var + block1, block2: TBlock; +begin + BlockRead(handle, block1, 1); + BlockRead(handle, block2, 1); + cookieValid := + (block2[14] = HIB_COOKIE_OUTRO_HIGH) and + (block2[15] = HIB_COOKIE_OUTRO_LOW); +end; +procedure HibReadGlobals(const handle: File; var versionRel: SmallInt; + var flags: EHibFileFlags; var layout: EHibPixelLayout; var bpp: EHibBitsPerPixel); +var + block: TBlock; + major, minor, rev: Integer; +begin + BlockRead(handle, block, 1); + major := BlockToInt16(block, 0); + minor := BlockToInt16(block, 2); + rev := BlockToInt32(block, 4); + flags := EHibFileFlags(BlockToInt16(block, 8)); + assert(BlockToInt16(block, 10) <> HIB_SIZE_HEADER, 'Invalid header size'); + layout := EHibPixelLayout(BlockToInt16(block, 12)); + bpp := EHibBitsPerPixel(BlockToInt16(block, 14)); + + if major < HIB_VERSION_MAJOR then versionRel := -1 + else if major > HIB_VERSION_MAJOR then versionRel := 1 + else begin + if minor < HIB_VERSION_MINOR then versionRel := -1 + else if minor > HIB_VERSION_MINOR then versionRel := 1 + else begin + if rev < HIB_VERSION_REVISION then versionRel := -1 + else if rev > HIB_VERSION_REVISION then versionRel := 1 + else versionRel := 0; + end; + end; +end; +procedure HibReadHeader(const handle: File; var header: THibHeader); +var + block: TBlock; +begin + BlockRead(handle, block, 1); + header.ActualDensity := BlockToDouble(block, 0); + header.Size := BlockToInt64(block, 8); + + BlockRead(handle, block, 1); + header.Size2D.X := BlockToInt64(block, 0); + header.Size2D.Y := BlockToInt64(block, 8); + + BlockRead(handle, block, 1); + header.RenderTime := ((BlockToInt64(block, 0) + 7200) / 86500) + 25569; + header.PauseTime := ((BlockToInt64(block, 8) + 7200) / 86500) + 25569; +end; +procedure HibReadData(const handle: File; header: THibHeader; var flame: TStringList; + var buckets: TBucket32Array; var colormap: TColorMapArray; callback: TOnProgress); +var + block: TBlock; + pos, offsf, sizef, offsd, sized : Int64; + fbytes: THibRawString; + i, c, bx, by: Integer; + p, step: Double; +begin + BlockRead(handle, block, 1); + offsf := BlockToInt64(block, 0); + sizef := BlockToInt64(block, 8); + + BlockRead(handle, block, 1); + offsd := BlockToInt64(block, 0); + sized := BlockToInt64(block, 8); + + pos := 0; + Seek(handle, offsf); + SetLength(fbytes, sizef); + + while pos < sizef do begin + BlockRead(handle, block, 1); + CopyMemory(@fbytes[pos], @block[0], HIB_BLOCKSIZE); + pos := pos + HIB_BLOCKSIZE; + end; + flame := TStringList.Create; + flame.Text := PChar(fbytes); + + pos := 0; + bx := 0; by := 0; + Seek(handle, offsd); + SetLength(buckets, header.Size2D.Y, header.Size2D.X); + + callback(0); + c := 0; p := 0; + step := 1.0 / sized; + while pos < sized do begin + with buckets[by][bx] do begin + BlockRead(handle, block, 1); + Red := BlockToInt32(block, 0); + Green := BlockToInt32(block, 4); + Blue := BlockToInt32(block, 8); + Count := BlockToInt32(block, 12); + end; + Inc(bx); + pos := pos + HIB_BLOCKSIZE; + if bx >= header.Size2D.X then begin + Inc(by); bx := 0; + end; + p := p + step; + c := (c + 1) mod 64; + if (c = 0) then begin + callback(p*0.99); + Application.ProcessMessages; + end; + end; + callback(0.99); + + i := 0; + while i < 256 do begin + BlockRead(handle, block, 1); + + c := BlockToInt32(block, 0); + colormap[i+0].Red := c and $ff; + colormap[i+0].Green := (c and $ff00) shr 8; + colormap[i+0].Blue := (c and $ff0000) shr 16; + + c := BlockToInt32(block, 4); + colormap[i+1].Red := c and $ff; + colormap[i+1].Green := (c and $ff00) shr 8; + colormap[i+1].Blue := (c and $ff0000) shr 16; + + c := BlockToInt32(block, 8); + colormap[i+2].Red := c and $ff; + colormap[i+2].Green := (c and $ff00) shr 8; + colormap[i+2].Blue := (c and $ff0000) shr 16; + + c := BlockToInt32(block, 12); + colormap[i+3].Red := c and $ff; + colormap[i+3].Green := (c and $ff00) shr 8; + colormap[i+3].Blue := (c and $ff0000) shr 16; + + i := i + 4; + end; +end; + +end. diff --git a/IO/MissingPlugin.pas b/IO/MissingPlugin.pas new file mode 100644 index 0000000..78e54a1 --- /dev/null +++ b/IO/MissingPlugin.pas @@ -0,0 +1,76 @@ +unit MissingPlugin; + +interface + uses Windows, Global, Classes, LoadTracker, ComCtrls, SysUtils, + ControlPoint, Translation; + const RegisteredAttributes : array[0..13] of string = ( + 'weight', 'color', 'symmetry', 'color_speed', 'coefs', 'chaos', + 'plotmode', 'opacity', 'post', 'var', 'var1', 'var_color', + 'name', 'linear3D' + ); + var MissingPluginList : TStringList; + Parsing : boolean; + ErrorMessageString : string; + + procedure BeginParsing; + procedure CheckAttribute(attr:string); + function EndParsing(cp : TControlPoint; var statusPanelText : string): boolean; + procedure AnnoyUser; +implementation + + procedure BeginParsing; + begin + MissingPluginList := TStringList.Create; + if (AutoOpenLog = true) then + if (LoadForm.Showing = false) then + LoadForm.Show; + end; + + procedure CheckAttribute(attr:string); + var i : integer; + begin + for i := 0 to Length(RegisteredAttributes)-1 do + if attr=RegisteredAttributes[i] then exit; + + if MissingPluginList.IndexOf(attr) < 0 then + MissingPluginList.Add(attr); + end; + + function EndParsing(cp : TControlPoint; var statusPanelText : string): boolean; + var str, str2 : string; i : integer; newl : TStringList; + begin + str2 := TextByKey('main-status-variationsorvariables'); + if (cp.used_plugins.Count > 0) then begin + newl := TStringList.Create; + for i := 0 to MissingPluginList.Count - 1 do begin + if cp.used_plugins.IndexOf(MissingPluginList[i]) >= 0 then + newl.Add(MissingPluginList[i]); + end; + str2 := TextByKey('main-status-plugins'); + MissingPluginList.Free; + MissingPluginList := newl; + end; + + if MissingPluginList.Count > 0 then begin + statusPanelText := Format(TextByKey('main-status-loadingerrorcount'), [MissingPluginList.Count]); + + for i := 0 to MissingPluginList.Count - 1 do + str := str + #13#10 + ' - ' + MissingPluginList[i]; + ErrorMessageString := Format(TextByKey('main-status-morepluginsneeded'), [cp.name, str2]) + str; + LoadForm.Output.Text := LoadForm.Output.Text + + ErrorMessageString + #13#10#13#10; + Result := false; + end else begin + statusPanelText := TextByKey('main-status-noloadingerrors'); + ErrorMessageString := ''; + Result := true; + end; + MissingPluginList.Free; + end; + + procedure AnnoyUser; + begin + if (ErrorMessageString = '') or (not WarnOnMissingPlugin) then exit; + MessageBox($00000000, PChar(ErrorMessageString), PChar('Apophysis'), MB_ICONHAND or MB_OK); + end; +end. diff --git a/IO/ParameterIO.pas b/IO/ParameterIO.pas new file mode 100644 index 0000000..84e3440 --- /dev/null +++ b/IO/ParameterIO.pas @@ -0,0 +1,603 @@ +unit ParameterIO; + +interface + uses Global, SysUtils, StrUtils, ControlPoint, XForm, cmap, + XFormMan, RegularExpressionsCore, RegexHelper, Classes; + +function IsRegisteredVariation(name: string): boolean; +function IsRegisteredVariable(name: string): boolean; + +procedure EnumParameters(xml: string; var list: TStringList); +function NameOf(xml: string): string; +function FindFlameInBatch(xml, name: string): string; + +procedure LoadPaletteFromXmlCompatible(xml: Utf8String; var cp: TControlPoint); +procedure LoadXFormFromXmlCompatible(xml: Utf8String; isFinalXForm: boolean; var xf: TXForm; var enabled: boolean); +function LoadCpFromXmlCompatible(xml: string; var cp: TControlPoint; var statusOutput: string): boolean; +function SaveCpToXmlCompatible(var xml: string; const cp1: TControlPoint): boolean; + +implementation + +(* *************************** Validation functions ***************************** *) +function IsRegisteredVariation(name: string): boolean; +var i, count: integer; vname: string; xf: txform; +begin +xf := txform.Create; +xf.Destroy; + count:=NrVar; + for i:=0 to count - 1 do + begin + vname := VarNames(i); + if (lowercase(vname) = lowercase(name)) then + begin + Result := true; + exit; + end; + end; + Result := false; +end; +function IsRegisteredVariable(name: string): boolean; +var i, count: integer; +begin + count:=GetNrVariableNames; + for i:=0 to count - 1 do + begin + if (LowerCase(GetVariableNameAt(i)) = LowerCase(name)) then + begin + Result := true; + exit; + end; + end; + Result := false; +end; + +(* ***************************** Loading functions ******************************* *) +function NameOf(xml: string): string; +var + Regex: TPerlRegEx; +begin + Regex := TPerlRegEx.Create; + Regex.RegEx := '.*?'; + Regex.Options := [preSingleLine, preCaseless]; + Regex.Subject := Utf8String(xml); + if Regex.Match then begin + Result := String(Regex.Groups[1]); + end else Result := ''; + Regex.Free; +end; +procedure EnumParameters(xml: string; var list: TStringList); +var + Regex: TPerlRegEx; +begin + Regex := TPerlRegEx.Create; + Regex.RegEx := '.*?'; + Regex.Options := [preSingleLine, preCaseless]; + Regex.Subject := Utf8String(xml); + if Regex.Match then begin + repeat + list.Add(String(Regex.MatchedText)); + until not Regex.MatchAgain; + end; + Regex.Free; +end; +function FindFlameInBatch(xml, name: string): string; +var + Regex: TPerlRegEx; +begin + Regex := TPerlRegEx.Create; + Regex.RegEx := '.*?'; + Regex.Options := [preSingleLine, preCaseless]; + Regex.Subject := Utf8String(xml); + if Regex.Match then begin + repeat + if (Utf8String(name) = Regex.Groups[1]) then begin + Result := String(Regex.MatchedText); + Regex.Free; + exit; + end; + until not Regex.MatchAgain; + end; + Result := ''; + Regex.Free; +end; + +function LoadCpFromXmlCompatible(xml: string; var cp: TControlPoint; var statusOutput: string): boolean; +const + re_flame : string = '(.*?)'; + re_xform : string = '<((?:final)?xform)(.*?)/>'; + re_palette : string = '([a-f0-9\s]+)'; + re_attrib : string = '([0-9a-z_]+)="(.*?)"'; + re_strtoken : string = '([a-z0-9_]+)'; +var + flame_attribs : Utf8String; + flame_content : Utf8String; + xform_type : Utf8String; + xform_attribs : Utf8String; + palette_attribs : Utf8String; + palette_content : Utf8String; + + find_attribs : TPerlRegEx; + found_attrib : boolean; + attrib_name : Utf8String; + attrib_match : Utf8String; + + find_xforms : TPerlRegEx; + found_xform : boolean; + xform_index : integer; + + find_strtokens : TPerlRegEx; + found_strtoken : boolean; + strtoken_index : integer; + strtoken_value : Utf8String; + + find_palette : TPerlRegEx; + + temp2i : T2Int; + temp2f : T2Float; + temprgb : TRGB; + + dummy: boolean; + attrib_success: boolean; + i: integer; +begin + find_strtokens := TPerlRegEx.Create; + find_attribs := TPerlRegEx.Create; + find_xforms := TPerlRegEx.Create; + find_palette := TPerlRegEx.Create; + + find_attribs.RegEx := Utf8String(re_attrib); + find_strtokens.RegEx := Utf8String(re_strtoken); + find_xforms.RegEx := Utf8String(re_xform); + find_palette.RegEx := Utf8String(re_palette); + + find_attribs.Options := [preSingleLine, preCaseless]; + find_strtokens.Options := [preSingleLine, preCaseless]; + find_xforms.Options := [preSingleLine, preCaseless]; + find_palette.Options := [preSingleLine, preCaseless]; + + flame_attribs := Utf8String(GetStringPart(xml, re_flame, 1, '')); + flame_content := Utf8String(GetStringPart(xml, re_flame, 2, '')); + + find_attribs.Subject := Utf8String(flame_attribs); + found_attrib := find_attribs.Match; + + Result := true; + + while found_attrib do begin + attrib_match := find_attribs.MatchedText; + attrib_name := Utf8String(Lowercase(String(find_attribs.Groups[1]))); + attrib_success := true; + + if attrib_name = 'name' then + cp.name := GetStringPart(String(attrib_match), re_attrib, 2, '') + else if attrib_name = 'vibrancy' then + cp.vibrancy := GetFloatPart(String(attrib_match), re_attrib, 2, defVibrancy) + else if attrib_name = 'brightness' then + cp.brightness := GetFloatPart(String(attrib_match), re_attrib, 2, defBrightness) + else if attrib_name = 'gamma' then + cp.gamma := GetFloatPart(String(attrib_match), re_attrib, 2, defGamma) + else if attrib_name = 'gamma_threshold' then + cp.gamma_threshold := GetFloatPart(String(attrib_match), re_attrib, 2, defGammaThreshold) + else if attrib_name = 'oversample' then + cp.spatial_oversample := GetIntPart(String(attrib_match), re_attrib, 2, defOversample) + else if attrib_name = 'filter' then + cp.spatial_filter_radius := GetFloatPart(String(attrib_match), re_attrib, 2, defFilterRadius) + else if attrib_name = 'zoom' then + cp.zoom := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'scale' then + cp.pixels_per_unit := GetFloatPart(String(attrib_match), re_attrib, 2, 25) + else if attrib_name = 'quality' then + cp.sample_density := GetFloatPart(String(attrib_match), re_attrib, 2, 5) + else if attrib_name = 'angle' then + cp.fangle := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'rotate' then // angle = -pi*x/180 + cp.vibrancy := -PI * GetFloatPart(String(attrib_match), re_attrib, 2, 0) / 180 + else if attrib_name = 'cam_pitch' then + cp.cameraPitch := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'cam_yaw' then + cp.cameraYaw := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'cam_perspective' then + cp.cameraPersp := GetFloatPart(String(attrib_match), re_attrib, 2, 1) + else if attrib_name = 'cam_dist' then // perspective = 1/x + begin + cp.cameraPersp := GetFloatPart(String(attrib_match), re_attrib, 2, 1); + if cp.cameraPersp = 0 then + cp.cameraPersp := EPS; + cp.cameraPersp := 1 / cp.cameraPersp; + end + else if attrib_name = 'cam_zpos' then + cp.cameraZpos := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'cam_dof' then + cp.cameraDOF := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + + else if attrib_name = 'estimator_radius' then + cp.estimator := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'estimator_minimum' then + cp.estimator_min := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'estimator_curve' then + cp.estimator_curve := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if attrib_name = 'enable_de' then + cp.enable_de := GetBoolPart(String(attrib_match), re_attrib, 2, false) + + else if attrib_name = 'center' then + begin + temp2f := Get2FloatPart(String(attrib_match), re_attrib, 2, 0); + cp.center[0] := temp2f.f1; cp.center[1] := temp2f.f2; + end + else if attrib_name = 'size' then + begin + temp2i := Get2IntPart(String(attrib_match), re_attrib, 2, 0); + cp.Width := temp2i.i1; cp.Height := temp2i.i2; + end + else if attrib_name = 'background' then + begin + temprgb := GetRGBPart(String(attrib_match), re_attrib, 2, 0); + cp.background[0] := temprgb.r; + cp.background[1] := temprgb.g; + cp.background[2] := temprgb.b; + end + + else if attrib_name = 'soloxform' then + cp.soloXform := GetIntPart(String(attrib_match), re_attrib, 2, 0); + + found_attrib := find_attribs.MatchAgain; + end; + + if LimitVibrancy and (cp.vibrancy > 1) then + cp.vibrancy := 1; + cp.cmapindex := -1; + + find_xforms.Subject := flame_content; + found_xform := find_xforms.Match; + xform_index := 0; + cp.finalXformEnabled := false; + + for i := 0 TO NXFORMS - 1 do + cp.xform[i].density := 0; + + while found_xform do begin + xform_type := find_xforms.Groups[1]; + xform_attribs := find_xforms.Groups[2]; + if (LowerCase(String(xform_type)) = 'xform') then begin + LoadXFormFromXmlCompatible(find_xforms.MatchedText, + false, cp.xform[xform_index], cp.finalXformEnabled); + xform_index := xform_index + 1; + end else begin + cp.finalXform := Txform.Create; + LoadXFormFromXmlCompatible(find_xforms.MatchedText, + true, cp.finalXform, dummy); + cp.finalXformEnabled := true; + cp.useFinalXform := true; + xform_index := xform_index + 1; + cp.xform[cp.NumXForms] := cp.finalXform; + end; + found_xform := find_xforms.MatchAgain; + end; + + find_palette.Subject := Utf8String(xml); + if (find_palette.Match) then + LoadPaletteFromXmlCompatible(find_palette.MatchedText, cp); + + find_strtokens.Free; + find_attribs.Free; + find_xforms.Free; + find_palette.Free; +end; +procedure LoadPaletteFromXmlCompatible(xml: Utf8String; var cp: TControlPoint); +const + re_palette: string = '([a-f0-9\s]+)'; + re_attrib : string = '([0-9a-z_]+)="(.*?)"'; +var + i, pos, len, count: integer; c: char; + data, attr, hexdata, format: string; + alpha: boolean; + + find_attribs : TPerlRegEx; + found_attrib : boolean; + attrib_name : Utf8String; + attrib_match : Utf8String; + attrib_success : Boolean; +function HexChar(c: Char): Byte; + begin + case c of + '0'..'9': Result := (Byte(c) - Byte('0')); + 'a'..'f': Result := (Byte(c) - Byte('a')) + 10; + 'A'..'F': Result := (Byte(c) - Byte('A')) + 10; + else + Result := 0; + end; + end; +begin + hexdata := GetStringPart(String(xml), re_palette, 2, ''); + attr := GetStringPart(String(xml), re_palette, 1, ''); + + find_attribs := TPerlRegEx.Create; + find_attribs.RegEx := Utf8String(re_attrib); + find_attribs.Options := [preSingleLine, preCaseless]; + find_attribs.Subject := Utf8String(attr); + found_attrib := find_attribs.Match; + + count := 0; + + while found_attrib do begin + attrib_match := find_attribs.MatchedText; + attrib_name := Utf8String(Lowercase(String(find_attribs.Groups[1]))); + attrib_success := true; + + if (attrib_name = 'count') then + count := GetIntPart(String(attrib_match), re_attrib, 2, 256) + else if (attrib_name = 'format') then + format := GetStringPart(String(attrib_match), re_attrib, 2, 'RGB'); + + found_attrib := find_attribs.MatchAgain; + end; + + find_attribs.Free; + + alpha := (lowercase(format) = 'rgba'); + data := ''; + + for i := 1 to Length(hexdata) do + begin + c := hexdata[i]; + if CharInSet(c, ['0'..'9']+['A'..'F']+['a'..'f']) then data := data + c; + end; + + if alpha then len := count * 8 + else len := count * 6; + + for i := 0 to Count-1 do begin + if alpha then pos := i * 8 + 2 + else pos := i * 6; + cp.cmap[i][0] := 16 * HexChar(Data[pos + 1]) + HexChar(Data[pos + 2]); + cp.cmap[i][1] := 16 * HexChar(Data[pos + 3]) + HexChar(Data[pos + 4]); + cp.cmap[i][2] := 16 * HexChar(Data[pos + 5]) + HexChar(Data[pos + 6]); + end; +end; +procedure LoadXFormFromXmlCompatible(xml: Utf8String; isFinalXForm: boolean; var xf: TXForm; var enabled: boolean); +const + re_attrib : string = '([0-9a-z_]+)="(.*?)"'; + re_xform : string = '<((?:final)?xform)(.*?)/>'; + re_coefs : string = '([\d.eE+-]+)\s+([\d.eE+-]+)\s+([\d.eE+-]+)\s+([\d.eE+-]+)\s+([\d.eE+-]+)\s+([\d.eE+-]+)'; +var + xform_attribs: string; + find_attribs : TPerlRegEx; + found_attrib : boolean; + attrib_name : Utf8String; + attrib_match : Utf8String; + token_part : string; + i, j : integer; + d : double; + t : TStringList; + v_set : Boolean; + attrib_success: Boolean; +begin + enabled := true; + xform_attribs := GetStringPart(String(xml), re_xform, 2, ''); + + find_attribs := TPerlRegEx.Create; + find_attribs.RegEx := Utf8String(re_attrib); + find_attribs.Options := [preSingleLine, preCaseless]; + find_attribs.Subject := Utf8String(xform_attribs); + found_attrib := find_attribs.Match; + + for i := 0 to NRVAR-1 do + xf.SetVariation(i, 0); + + while found_attrib do begin + attrib_match := find_attribs.MatchedText; + attrib_name := (find_attribs.Groups[1]); + attrib_success := true; + + if (attrib_name = 'enabled') and isFinalXform then + enabled := GetBoolPart(String(attrib_match), re_attrib, 2, true) + else if (attrib_name = 'weight') and (not isFinalXform) then + xf.density := GetFloatPart(String(attrib_match), re_attrib, 2, 0.5) + else if (attrib_name = 'symmetry') and (not isFinalXform) then + xf.symmetry := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if (attrib_name = 'color_speed') and (not isFinalXform) then + xf.symmetry := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if (attrib_name = 'chaos') and (not isFinalXform) then + begin + token_part := GetStringPart(String(attrib_match), re_attrib, 2, ''); + if token_part <> '' then + begin + t := TStringList.Create; + GetTokens(token_part, t); + for i := 0 to t.Count-1 do + xf.modWeights[i] := Abs(StrToFloat(t[i])); + t.Destroy; + end; + end + else if (attrib_name = 'opacity') and (not isFinalXform) then + xf.transOpacity := GetFloatPart(String(attrib_match), re_attrib, 2, 1) + else if (attrib_name = 'name') and (not isFinalXform) then + xf.TransformName := GetStringPart(String(attrib_match), re_attrib, 2, '') + else if (attrib_name = 'plotmode') and (not isFinalXform) then + xf.transOpacity := StrToFloat(IfThen(LowerCase(GetStringPart(String(attrib_match), re_attrib, 2, '')) = 'off', '0', '1')) + else if (attrib_name = 'coefs') then + begin + token_part := GetStringPart(String(attrib_match), re_attrib, 2, '1 0 0 1 0 0'); + xf.c[0][0] := GetFloatPart(token_part, re_coefs, 1, 1); + xf.c[0][1] := GetFloatPart(token_part, re_coefs, 2, 0); + xf.c[1][0] := GetFloatPart(token_part, re_coefs, 3, 0); + xf.c[1][1] := GetFloatPart(token_part, re_coefs, 4, 1); + xf.c[2][0] := GetFloatPart(token_part, re_coefs, 5, 0); + xf.c[2][1] := GetFloatPart(token_part, re_coefs, 6, 0); + end + else if (attrib_name = 'post') then + begin + token_part := GetStringPart(String(attrib_match), re_attrib, 2, '1 0 0 1 0 0'); + xf.p[0][0] := GetFloatPart(token_part, re_coefs, 1, 1); + xf.p[0][1] := GetFloatPart(token_part, re_coefs, 2, 0); + xf.p[1][0] := GetFloatPart(token_part, re_coefs, 3, 0); + xf.p[1][1] := GetFloatPart(token_part, re_coefs, 4, 1); + xf.p[2][0] := GetFloatPart(token_part, re_coefs, 5, 0); + xf.p[2][1] := GetFloatPart(token_part, re_coefs, 6, 0); + end + else if (attrib_name = 'color') then + xf.color := GetFloatPart(String(attrib_match), re_attrib, 2, 0) + else if (attrib_name = 'var_color') then + xf.vc := GetFloatPart(String(attrib_match), re_attrib, 2, 1) + else if ((String(attrib_name) = 'symmetry') or (String(attrib_name) = 'weight') or + (String(attrib_name) = 'color_speed') or (String(attrib_name) = 'chaos') or + (String(attrib_name) = 'opacity') or (String(attrib_name) = 'name') or + (String(attrib_name) = 'plotmode')) and (isFinalXForm) then + begin + //EmitWarning('Malformed attribute "xform.' + attrib_name + '" - ignoring'); + //LogWrite('WARNING|' +'Malformed attribute "xform.' + attrib_name + '" - ignoring', 'parser.log'); + attrib_success := false; + end + else begin + if (String(attrib_name) = 'linear3D') then begin + xf.SetVariation(0, GetFloatPart(String(attrib_match), re_attrib, 2, 0)); + end else if (IsRegisteredVariation(String(attrib_name))) then begin + for i := 0 to NRVAR - 1 do begin + if lowercase(varnames(i)) = lowercase(String(attrib_name)) then begin + xf.SetVariation(i, GetFloatPart(String(attrib_match), re_attrib, 2, 0)); + v_set := true; + break; + end; + end; + if (IsRegisteredVariable(String(attrib_name))) then begin + d := GetFloatPart(String(attrib_match), re_attrib, 2, 0); + xf.SetVariable(String(attrib_name), d); + end; + end else if (IsRegisteredVariable(String(attrib_name))) then begin + d := GetFloatPart(String(attrib_match), re_attrib, 2, 0); + xf.SetVariable(String(attrib_name), d); + end; + attrib_success := false; + end; + + found_attrib := find_attribs.MatchAgain; + end; + + if (isFinalXform) then begin + xf.symmetry := 1; + xf.color := 0; + end; + + find_attribs.Free; +end; + +// Replace... +function SaveCpToXmlCompatible(var xml: string; const cp1: TControlPoint): boolean; +function ColorToXmlCompact(cp1: TControlPoint): string; +var + i: integer; +begin + Result := ' '; + for i := 0 to 255 do begin + if ((i and 7) = 0) then Result := Result + #13#10 + ' '; + Result := Result + IntToHex(cp1.cmap[i, 0],2) + + IntToHex(cp1.cmap[i, 1],2) + + IntToHex(cp1.cmap[i, 2],2); + end; + Result := Result + #13#10 + ' '; +end; +var + t, i{, j}: integer; + FileList: TStringList; + x, y: double; + parameters: string; + str: string; +begin + FileList := TStringList.create; + x := cp1.center[0]; + y := cp1.center[1]; + +// if cp1.cmapindex >= 0 then pal := pal + 'gradient="' + IntToStr(cp1.cmapindex) + '" '; + + try + parameters := 'version="Apophysis 7X" '; + if cp1.time <> 0 then + parameters := parameters + format('time="%g" ', [cp1.time]); + + parameters := parameters + + 'size="' + IntToStr(cp1.width) + ' ' + IntToStr(cp1.height) + + format('" center="%g %g" ', [x, y]) + + format('scale="%g" ', [cp1.pixels_per_unit]); + + if cp1.FAngle <> 0 then + parameters := parameters + format('angle="%g" ', [cp1.FAngle]) + + format('rotate="%g" ', [-180 * cp1.FAngle/Pi]); + if cp1.zoom <> 0 then + parameters := parameters + format('zoom="%g" ', [cp1.zoom]); + +// 3d + if cp1.cameraPitch <> 0 then + parameters := parameters + format('cam_pitch="%g" ', [cp1.cameraPitch]); + if cp1.cameraYaw <> 0 then + parameters := parameters + format('cam_yaw="%g" ', [cp1.cameraYaw]); + if cp1.cameraPersp <> 0 then + parameters := parameters + format('cam_perspective="%g" ', [cp1.cameraPersp]); + if cp1.cameraZpos <> 0 then + parameters := parameters + format('cam_zpos="%g" ', [cp1.cameraZpos]); + if cp1.cameraDOF <> 0 then + parameters := parameters + format('cam_dof="%g" ', [cp1.cameraDOF]); +// + parameters := parameters + format( + 'oversample="%d" filter="%g" quality="%g" ', + [cp1.spatial_oversample, + cp1.spatial_filter_radius, + cp1.sample_density] + ); + if cp1.nbatches <> 1 then parameters := parameters + 'batches="' + IntToStr(cp1.nbatches) + '" '; + + parameters := parameters + + format('background="%g %g %g" ', [cp1.background[0] / 255, cp1.background[1] / 255, cp1.background[2] / 255]) + + format('brightness="%g" ', [cp1.brightness]) + + format('gamma="%g" ', [cp1.gamma]); + + if cp1.vibrancy <> 1 then + parameters := parameters + format('vibrancy="%g" ', [cp1.vibrancy]); + + if cp1.gamma_threshold <> 0 then + parameters := parameters + format('gamma_threshold="%g" ', [cp1.gamma_threshold]); + + if cp1.soloXform >= 0 then + parameters := parameters + format('soloxform="%d" ', [cp1.soloXform]); + + parameters := parameters + + format('estimator_radius="%g" ', [cp1.estimator]) + + format('estimator_minimum="%g" ', [cp1.estimator_min]) + + format('estimator_curve="%g" ', [cp1.estimator_curve]); + if (cp1.enable_de) then + parameters := parameters + ('enable_de="1" ') + else parameters := parameters + ('enable_de="0" '); + + str := ''; + for i := 0 to cp1.used_plugins.Count-1 do begin + str := str + cp1.used_plugins[i]; + if (i = cp1.used_plugins.Count-1) then break; + str := str + ' '; + end; + parameters := parameters + format('plugins="%s" ', [str]); + + FileList.Add(''); + { Write transform parameters } + t := cp1.NumXForms; + for i := 0 to t - 1 do + FileList.Add(cp1.xform[i].ToXMLString); + if cp1.HasFinalXForm then + begin + // 'enabled' flag disabled in this release + FileList.Add(cp1.xform[t].FinalToXMLString(cp1.finalXformEnabled)); + end; + + { Write palette data } + //if exporting or OldPaletteFormat then + // FileList.Add(ColorToXml(cp1)) + //else + FileList.Add(ColorToXmlCompact(cp1)); + + FileList.Add(''); + xml := FileList.text; + result := true; + finally + FileList.free + end; +end; + +end. diff --git a/IO/Settings.pas b/IO/Settings.pas new file mode 100644 index 0000000..ac00b2a --- /dev/null +++ b/IO/Settings.pas @@ -0,0 +1,1545 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit Settings; + +interface + +uses graphics, Messages, Translation; + +function ReadPluginDir: string; +procedure ReadSettings; +procedure SaveSettings; + +implementation + +uses Windows, Classes, SysUtils, StrUtils, Forms, Registry, Global, Dialogs, XFormMan; + +(* +procedure UnpackVariations(v: int64); +{ Unpacks the variation options form an integer } +var + i: integer; +begin + for i := 0 to NRVAR - 1 do + Variations[i] := boolean(v shr i and 1); +end; +*) + +function ReadPluginDir: string; +var + settingFileName: string; + sl : TStringList; +begin + sl := TStringList.Create; + + settingFileName := ExtractFilePath(Application.ExeName) + 'ApoPluginSrc.dat'; + if FileExists(settingFileName) then + sl.LoadFromFile(settingFileName) + else begin + settingFileName := GetEnvVarValue('APPDATA') + '\ApoPluginSrc.dat'; + + if FileExists(settingFileName) then + sl.LoadFromFile(settingFileName) + else + sl.Text := ExtractFilePath(Application.ExeName) + 'Plugins\'; + end; + + if Trim(sl.Text) = '' then + sl.Text := ExtractFilePath(Application.ExeName) + 'Plugins\'; + + Result := Trim(sl.Text); + if (RightStr(Result, 1) <> '\') and (Result <> '') then + Result := Result + '\'; + + sl.Destroy; +end; + +procedure SavePluginDir(data: string); +var + settingFileName: string; + sl : TStringList; +begin + settingFileName := ExtractFilePath(Application.ExeName) + 'ApoPluginSrc.dat'; + sl := TStringList.Create; + sl.Text := PluginPath; + + try + sl.SaveToFile(settingFileName); + sl.Destroy; + except + // not elevated? + settingFileName := GetEnvVarValue('APPDATA') + '\ApoPluginSrc.dat'; + try + sl.SaveToFile(settingFileName); + except + MessageBox(0, PCHAR(TextByKey('main-status-pluginpath-ioerror')), + PCHAR('Apophysis'), MB_ICONWARNING); + end; + sl.Destroy; + end; +end; + +procedure ReadSettings; +var + Registry: TRegistry; + DefaultPath: string; + i, maxVars: integer; + VariationOptions: int64; +begin + DefaultPath := GetEnvVarValue('USERPROFILE');///ExtractFilePath(Application.Exename); + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + { Defaults } + if Registry.OpenKey('Software\' + APP_NAME + '\Defaults', False) then + begin + if Registry.ValueExists('DefaultFlameFile3D') then + begin + defFlameFile := Registry.ReadString('DefaultFlameFile3D'); + end + else begin + if Registry.ValueExists('DefaultFlameFile') then + defFlameFile := Registry.ReadString('DefaultFlameFile') + else + defFlameFile := ''; + end; + + if Registry.ValueExists('AlwaysCreateBlankFlame') then + begin + AlwaysCreateBlankFlame := Registry.ReadBool('AlwaysCreateBlankFlame'); + end + else + begin + AlwaysCreateBlankFlame := false; + end; + + if Registry.ValueExists('GradientFile') then + begin + GradientFile := Registry.ReadString('GradientFile'); + end + else + begin + GradientFile := '' + end; + + if Registry.ValueExists('SavePath3D') then + begin + SavePath := Registry.ReadString('SavePath3D'); + end + else begin + if Registry.ValueExists('SavePath') then + SavePath := Registry.ReadString('SavePath') + else + SavePath := DefaultPath + '\Flames.flame'; + end; + + if Registry.ValueExists('EmbedThumbnails') then + begin + EmbedThumbnails := Registry.ReadBool('EmbedThumbnails'); + end + else EmbedThumbnails := false; + + if Registry.ValueExists('WarnOnMissingPlugin') then + begin + WarnOnMissingPlugin := Registry.ReadBool('WarnOnMissingPlugin'); + end + else WarnOnMissingPlugin := true; + if Registry.ValueExists('LanguageFile') then + begin + LanguageFile := Registry.ReadString('LanguageFile'); + end + else LanguageFile := ''; + + if Registry.ValueExists('SmoothPaletteFile') then + begin + defSmoothPaletteFile := Registry.ReadString('SmoothPaletteFIle'); + end + else + begin + defSmoothPaletteFile := DefaultPath + '\SmoothPalette.ugr'; + end; + + if Registry.ValueExists('PlaySoundOnRenderComplete') then + PlaySoundOnRenderComplete := Registry.ReadBool('PlaySoundOnRenderComplete') + else + PlaySoundOnRenderComplete := false; + if Registry.ValueExists('RenderCompleteSoundFile') then + RenderCompleteSoundFile := Registry.ReadString('RenderCompleteSoundFile') + else + RenderCompleteSoundFile := ''; + + if Registry.ValueExists('ConfirmDelete') then + ConfirmDelete := Registry.ReadBool('ConfirmDelete') + else + ConfirmDelete := True; + if Registry.ValueExists('OldPaletteFormat') then + OldPaletteFormat := Registry.ReadBool('OldPaletteFormat') + else + OldPaletteFormat := false; + if Registry.ValueExists('ConfirmExit') then + ConfirmExit := Registry.ReadBool('ConfirmExit') + else + ConfirmExit := True; + + if Registry.ValueExists('PreserveQuality') then + begin + PreserveQuality := Registry.ReadBool('PreserveQuality'); + end + else + begin + PreserveQuality := true; + end; + + if Registry.ValueExists('KeepBackground') then + begin + KeepBackground := Registry.ReadBool('KeepBackground'); + end + else + begin + KeepBackground := False; + end; + if Registry.ValueExists('NumTries') then + begin + NumTries := Registry.ReadInteger('NumTries'); + end + else + begin + NumTries := 10; + end; + if Registry.ValueExists('TryLength') then + begin + TryLength := Registry.ReadInteger('TryLength'); + end + else + begin + TryLength := 100000; + end; + + if Registry.ValueExists('MinTransforms') then + begin + randMinTransforms := Registry.ReadInteger('MinTransforms'); + if randMinTransforms <= 0 then randMinTransforms := 2; + end + else + begin + randMinTransforms := 2; + end; + if Registry.ValueExists('MaxTransforms') then + begin + randMaxTransforms := Registry.ReadInteger('MaxTransforms'); + if randMaxTransforms < randMinTransforms then randMaxTransforms := randMinTransforms; + end + else + begin + randMaxTransforms := randMinTransforms + 1; + end; + + if Registry.ValueExists('MutationMinTransforms') then + begin + mutantMinTransforms := Registry.ReadInteger('MutationMinTransforms'); + if mutantMinTransforms <= 0 then mutantMinTransforms := 2; + end + else + begin + mutantMinTransforms := 2; + end; + if Registry.ValueExists('MutationMaxTransforms') then + begin + mutantMaxTransforms := Registry.ReadInteger('MutationMaxTransforms'); + if mutantMaxTransforms < mutantMinTransforms then mutantMinTransforms := mutantMinTransforms; + end + else + begin + mutantMaxTransforms := mutantMinTransforms + 1; + end; + + if Registry.ValueExists('RandomGradient') then + begin + randGradient := Registry.ReadInteger('RandomGradient'); + end + else + begin + randGradient := 0; + end; + + if Registry.ValueExists('ParameterFolder3D') then + begin + ParamFolder := Registry.ReadString('ParameterFolder3D'); + end + else + if Registry.ValueExists('ParameterFolder') then + begin + ParamFolder := Registry.ReadString('ParameterFolder'); + end + else + begin + ParamFolder := DefaultPath + '\'; + end; + + if Registry.ValueExists('UPRPath') then + begin + UPRPath := Registry.ReadString('UPRPath'); + end + else + begin + UPRPath := DefaultPath + '\'; + end; + + if Registry.ValueExists('ImageFolder') then + begin + ImageFolder := Registry.ReadString('ImageFolder'); + end + else + begin + ImageFolder := DefaultPath + '\'; + end; + + if Registry.ValueExists('UPRWidth') then + begin + UPRWidth := Registry.ReadInteger('UPRWidth'); + end + else + begin + UPRWidth := 640; + end; + if Registry.ValueExists('UPRHeight') then + begin + UPRHeight := Registry.ReadInteger('UPRHeight'); + end + else + begin + UPRHeight := 480; + end; + + if Registry.ValueExists('BrowserPath') then + begin + BrowserPath := Registry.ReadString('BrowserPath'); + end + else + begin + BrowserPath := DefaultPath + '\'; + end; + if Registry.ValueExists('EditPreviewQaulity') then + begin + EditPrevQual := Registry.ReadInteger('EditPreviewQaulity'); + end + else + begin + EditPrevQual := 1; + end; + if Registry.ValueExists('MutatePreviewQaulity') then + begin + MutatePrevQual := Registry.ReadInteger('MutatePreviewQaulity'); + if MutatePrevQual <= 0 then MutatePrevQual := 1; + end + else + begin + MutatePrevQual := 1; + end; + if Registry.ValueExists('AdjustPreviewQaulity') then + begin + AdjustPrevQual := Registry.ReadInteger('AdjustPreviewQaulity'); + if AdjustPrevQual <= 0 then AdjustPrevQual := 1; + end + else + begin + AdjustPrevQual := 1; + end; + if Registry.ValueExists('RandomPrefix') then + begin + RandomPrefix := Registry.ReadString('RandomPrefix'); + end + else + begin + RandomPrefix := 'Apo3D-' + end; + if Registry.ValueExists('RandomDate') then + begin + RandomDate := Registry.ReadString('RandomDate'); + end + else + begin + RandomDate := '' + end; + if Registry.ValueExists('RandomIndex') then + begin + RandomIndex := Registry.ReadInteger('RandomIndex'); + end + else + begin + RandomIndex := 0; + end; + if Registry.ValueExists('SymmetryType') then + begin + SymmetryType := Registry.ReadInteger('SymmetryType'); + end + else + begin + SymmetryType := 0; + end; + if Registry.ValueExists('SymmetryOrder') then + begin + SymmetryOrder := Registry.ReadInteger('SymmetryOrder'); + end + else + begin + SymmetryOrder := 4; + end; + if Registry.ValueExists('SymmetryNVars') then + begin + SymmetryNVars := Registry.ReadInteger('SymmetryNVars'); + end + else + begin + SymmetryNVars := 12; + end; + + if Registry.ValueExists('VariationOptions') then + begin + VariationOptions := Registry.ReadInteger('VariationOptions'); + end + else + begin + VariationOptions := 262143; + end; + if Registry.ValueExists('VariationOptions2') then + begin + VariationOptions := VariationOptions or (int64(Registry.ReadInteger('VariationOptions2')) shl 32); + end; +// UnpackVariations(VariationOptions); + + if Registry.ValueExists('MinNodes') then + begin + MinNodes := Registry.ReadInteger('MinNodes'); + if MinNodes < 2 then MinNodes := 2; + end + else + begin + MinNodes := 2; + end; + if Registry.ValueExists('MinHue') then + begin + MinHue := Registry.ReadInteger('MinHue'); + end + else + begin + MinHue := 0; + end; + if Registry.ValueExists('MinSat') then + begin + MinSat := Registry.ReadInteger('MinSat'); + end + else + begin + MinSat := 0; + end; + if Registry.ValueExists('MinLum') then + begin + MinLum := Registry.ReadInteger('MinLum'); + end + else + begin + MinLum := 0; + end; + if Registry.ValueExists('MaxNodes') then + begin + MaxNodes := Registry.ReadInteger('MaxNodes'); + if MaxNodes < MinNodes then MaxNodes := MinNodes; + end + else + begin + MaxNodes := 10; + end; + if Registry.ValueExists('MaxHue') then + begin + MaxHue := Registry.ReadInteger('MaxHue'); + if MaxHue < 0 then MaxHue := 0; + end + else + begin + MaxHue := 600; + end; + if Registry.ValueExists('MaxSat') then + begin + MaxSat := Registry.ReadInteger('MaxSat'); + if MaxSat < 0 then MaxSat := 0; + end + else + begin + MaxSat := 100; + end; + if Registry.ValueExists('RandomGradientFile') then + begin + randGradientFile := Registry.ReadString('RandomGradientFile'); + end + else + begin + randGradientFile := '' + end; + +// if Registry.ValueExists('ReferenceMode') then +// ReferenceMode := Registry.ReadInteger('ReferenceMode') +// else ReferenceMode := 0; + + if Registry.ValueExists('RotationMode') then + MainForm_RotationMode := Registry.ReadInteger('RotationMode') + else MainForm_RotationMode := 0; + + if Registry.ValueExists('MaxLum') then + begin + MaxLum := Registry.ReadInteger('MaxLum'); + if MaxLum <= 0 then MaxLum := 100; + end + else + begin + MaxLum := 100; + end; + if Registry.ValueExists('BatchSize') then + begin + BatchSize := Registry.ReadInteger('BatchSize'); + if BatchSize <= 0 then BatchSize := 10; + end + else + begin + BatchSize := 100; + end; + if Registry.ValueExists('ScriptPath') then + begin + ScriptPath := Registry.ReadString('ScriptPath'); + end + else + begin + ScriptPath := DefaultPath + '\Scripts\'; + end; + if Registry.ValueExists('FunctionLibrary') then + begin + defLibrary := Registry.ReadString('FunctionLibrary'); + end + else + begin + defLibrary := ExtractFilePath(Application.ExeName) + 'Functions.asc'; + end; + if Registry.ValueExists('ExportFileFormat') then + begin + ExportFileFormat := Registry.ReadInteger('ExportFileFormat'); + end + else + begin + ExportFileFormat := 1; + end; + if Registry.ValueExists('ExportWidth') then + begin + ExportWidth := Registry.ReadInteger('ExportWidth'); + if ExportWidth <= 0 then ExportWidth := 640; + end + else + begin + ExportWidth := 640; + end; + if Registry.ValueExists('ExportHeight') then + begin + ExportHeight := Registry.ReadInteger('ExportHeight'); + if ExportHeight <= 0 then ExportHeight := 480; + end + else + begin + ExportHeight := 480; + end; + if Registry.ValueExists('ExportDensity') then + begin + ExportDensity := Registry.ReadFloat('ExportDensity'); + if ExportDensity <= 0 then ExportDensity := 100; + end + else + begin + ExportDensity := 100; + end; + if Registry.ValueExists('ExportOversample') then + begin + ExportOversample := Registry.ReadInteger('ExportOversample'); + if ExportOversample <= 0 then ExportOversample := 2; + end + else + begin + ExportOversample := 2; + end; + if Registry.ValueExists('ExportFilter') then + begin + ExportFilter := Registry.ReadFloat('ExportFilter'); + if ExportFilter <= 0 then ExportFilter := 0.6; + end + else + begin + ExportFilter := 0.6; + end; + if Registry.ValueExists('ExportBatches') then + begin + ExportBatches := Registry.ReadInteger('ExportBatches'); + if ExportBatches <= 0 then ExportBatches := 3; + end + else + begin + ExportBatches := 3; + end; + if Registry.ValueExists('Nick') then + begin + SheepNick := Registry.ReadString('Nick'); + end + else + begin + SheepNick := ''; + end; + if Registry.ValueExists('URL') then + begin + SheepURL := Registry.ReadString('URL'); + end + else + begin + SheepURL := ''; + end; + if Registry.ValueExists('Pass') then + begin + SheepPW := Registry.ReadString('Pass'); + end + else + begin + SheepPW := ''; + end; + if Registry.ValueExists('Renderer') then + begin + flam3Path := Registry.ReadString('Renderer'); + end + else + begin + flam3Path := ExtractFilePath(Application.ExeName) + 'flam3.exe'; + end; + if Registry.ValueExists('Server') then + begin + SheepServer := Registry.ReadString('Server'); + end + else + begin + SheepServer := 'http://v2d5.sheepserver.net/'; + end; + if Registry.ValueExists('ShowProgress') then + begin + ShowProgress := Registry.ReadBool('ShowProgress'); + end else begin + ShowProgress := true; + end; + if Registry.ValueExists('ToolBarWidth1') then + begin + TBWidth1 := Registry.ReadInteger('ToolBarWidth1'); + end else begin + TBWidth1 := 0; + end; + if Registry.ValueExists('ToolBarWidth2') then + begin + TBWidth2 := Registry.ReadInteger('ToolBarWidth2'); + end else begin + TBWidth2 := 0; + end; + if Registry.ValueExists('ToolBarWidth3') then + begin + TBWidth3 := Registry.ReadInteger('ToolBarWidth3'); + end else begin + TBWidth3 := 0; + end; + if Registry.ValueExists('ToolBarWidth4') then + begin + TBWidth4 := Registry.ReadInteger('ToolBarWidth4'); + end else begin + TBWidth4 := 0; + end; + if Registry.ValueExists('ToolBarWidth5') then + begin + TBWidth5 := Registry.ReadInteger('ToolBarWidth5'); + end else begin + TBWidth5 := 0; + end; + + if Registry.ValueExists('LineCenterColor') then + begin + LineCenterColor := Registry.ReadInteger('LineCenterColor'); + end else begin + LineCenterColor := $FFFFFF; + end; + if Registry.ValueExists('LineThirdsColor') then + begin + LineThirdsColor := Registry.ReadInteger('LineThirdsColor'); + end else begin + LineThirdsColor := $0000FF; + end; + if Registry.ValueExists('LineGRColor') then + begin + LineGRColor := Registry.ReadInteger('LineGRColor'); + end else begin + LineGRColor := $00FF00; + end; + if Registry.ValueExists('EnableGuides') then + begin + EnableGuides := Registry.ReadBool('EnableGuides'); + end else begin + EnableGuides := false; + end; + + { FormRender } + if Registry.ValueExists('SaveIncompleteRenders') then begin + SaveIncompleteRenders := Registry.ReadBool('SaveIncompleteRenders'); + end else begin + SaveIncompleteRenders := false; + end; + if Registry.ValueExists('ShowRenderStats') then begin + ShowRenderStats := Registry.ReadBool('ShowRenderStats'); + end else begin + ShowRenderStats := false; + end; + if Registry.ValueExists('LowerRenderPriority') then begin + LowerRenderPriority := Registry.ReadBool('LowerRenderPriority'); + end else begin + LowerRenderPriority := false; + end; + + if Registry.ValueExists('PNGTransparency') then begin + PNGTransparency := Registry.ReadInteger('PNGTransparency'); + + if PNGTransparency > 1 then PNGTransparency := 1; // tmp + + end else begin + PNGTransparency := 1 + end; + if Registry.ValueExists('ShowTransparency') then begin + ShowTransparency := Registry.ReadBool('ShowTransparency'); + end else begin + ShowTransparency := False; + end; + if Registry.ValueExists('ExtendMainPreview') then begin + ExtendMainPreview := Registry.ReadBool('ExtendMainPreview'); + end else begin + ExtendMainPreview := true; + end; + if Registry.ValueExists('MainPreviewScale') then begin + MainPreviewScale := Registry.ReadFloat('MainPreviewScale'); + if MainPreviewScale < 1 then MainPreviewScale := 1 + else if MainPreviewScale > 3 then MainPreviewScale := 3; + end else begin + MainPreviewScale := 1.2; + end; + + if Registry.ValueExists('NrTreads') then begin + NrTreads := Registry.ReadInteger('NrTreads'); + if NrTreads <= 0 then NrTreads := 1; + end else begin + NrTreads := 1; + end; + if Registry.ValueExists('UseNrThreads') then begin + UseNrThreads := Registry.ReadInteger('UseNrThreads'); + if UseNrThreads <= 0 then UseNrThreads := 1; + end else begin + UseNrThreads := 1; + end; + + if Registry.ValueExists('InternalBitsPerSample') then begin + InternalBitsPerSample := Registry.ReadInteger('InternalBitsPerSample'); + end else begin + InternalBitsPerSample := 0; + end; + + if Registry.ValueExists('AutoOpenLog') then begin + AutoOpenLog := Registry.ReadBool('AutoOpenLog'); + end else begin + AutoOpenLog := false; + end; + + if Registry.ValueExists('StartupCheckForUpdates') then begin + StartupCheckForUpdates := Registry.ReadBool('StartupCheckForUpdates'); + end else begin + StartupCheckForUpdates := true; + end; + + if Registry.ValueExists('ClassicListMode') then begin + ClassicListMode := Registry.ReadBool('ClassicListMode'); + end else begin + ClassicListMode := true; + end; + + if Registry.ValueExists('LastOpenFile') then begin + LastOpenFile := Registry.ReadString('LastOpenFile'); + end else begin + LastOpenFile := ''; + end; + + if Registry.ValueExists('LastOpenFileEntry') then begin + LastOpenFileEntry := Registry.ReadInteger('LastOpenFileEntry'); + end else begin + LastOpenFileEntry := 1; + end; + + if Registry.ValueExists('RememberLastOpenFile') then begin + RememberLastOpenFile := Registry.ReadBool('RememberLastOpenFile'); + end else begin + RememberLastOpenFile := false; + end; + + if Registry.ValueExists('UseSmallThumbnails') then begin + UseSmallThumbnails := Registry.ReadBool('UseSmallThumbnails'); + end else begin + UseSmallThumbnails := true; + end; + + if Registry.ValueExists('HelpPath') then begin + HelpPath := Registry.ReadString('HelpPath'); + end else begin + HelpPath := ExtractFilePath(Application.ExeName) + 'Apophysis 7X.chm'; + end; + end + else + begin + StartupCheckForUpdates := true; + AlwaysCreateBlankFlame := false; + MainForm_RotationMode := 0; + EditPrevQual := 1; + MutatePrevQual := 1; + AdjustPrevQual := 1; + GradientFile := ''; + defFlameFile := ''; + SavePath := DefaultPath + '\Flames.flame'; + EmbedThumbnails := false; + WarnOnMissingPlugin := true; + LanguageFile := ''; + HelpPath := ExtractFilePath(Application.ExeName) + 'Apophysis 7X.chm'; + defSmoothPaletteFile := DefaultPath + '\SmoothPalette.ugr'; + ConfirmDelete := True; + ConfirmExit := True; + OldPaletteFormat := false; + NumTries := 10; + TryLength := 100000; + randMinTransforms := 2; + randMaxTransforms := 3; + mutantMinTransforms := 2; + mutantMaxTransforms := 6; + randGradient := 0; + PreserveQuality := false; + KeepBackground := False; + UPRPath := DefaultPath + '\'; + ImageFolder := DefaultPath + '\'; + ParamFolder := DefaultPath + '\'; + UPRWidth := 640; + UPRHeight := 480; + RandomPrefix := 'Apo7X-'; + RandomIndex := 0; + RandomDate := ''; + SymmetryType := 0; + SymmetryOrder := 4; + SymmetryNVars := 12; + VariationOptions := 262143; +// UnpackVariations(VariationOptions); + MinNodes := 2; + MaxNodes := 10; + MinHue := 0; + MinSat := 0; + MinLum := 0; + MaxHue := 600; + MaxSat := 100; + MaxLum := 100; + randGradientFile := ''; + BatchSize := 100; + ScriptPath := DefaultPath + '\'; + defLibrary := ExtractFilePath(Application.ExeName) + 'Functions.asc'; + ExportFileFormat := 1; + ExportWidth := 640; + ExportHeight := 480; + ExportDensity := 100; + ExportOversample := 2; + ExportFilter := 0.6; + ExportBatches := 3; + SheepNick := ''; + SheepURL := ''; + SheepPW := ''; + flam3Path := ExtractFilePath(Application.ExeName) + 'flam3.exe'; + SheepServer := 'http://v2d5.sheepserver.net/'; + ShowProgress := true; + SaveIncompleteRenders := false; + LowerRenderPriority := false; + ShowRenderStats := false; + PNGTransparency := 1; + ShowTransparency := False; + MainPreviewScale := 1.2; + ExtendMainPreview := true; + NrTreads := 1; + UseNrThreads := 1; + InternalBitsPerSample := 0; + AutoOpenLog := false; + ClassicListMode := true; + LastOpenFile := ''; + LastOpenFileEntry := 1; + RememberLastOpenFile := false; + UseSmallThumbnails := true; + TBWidth1 := 0; + TBWidth2 := 0; + TBWidth3 := 0; + TBWidth4 := 0; + TBWidth5 := 0; + LineCenterColor := $FFFFFF; + LineThirdsColor := $0000FF; + LineGRColor := $00FF00; + EnableGuides := false; + end; + Registry.CloseKey; + + SetLength(Variations, NRVAR); + if Registry.OpenKey('Software\' + APP_NAME + '\Variations', False) then + begin + for i := 0 to NRVAR-1 do begin + if Registry.ValueExists(Varnames(i)) then + Variations[i] := Registry.ReadBool(Varnames(i)) + else + Variations[i] := false; + end; + end + else begin + if NRVAR >= 64 then maxVars := 63 + else maxVars := NRVAR-1; + for i := 0 to maxVars do + Variations[i] := boolean(VariationOptions shr i and 1); + end; + Registry.CloseKey; + + { Editor } // --Z-- moved from EditForm + if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Editor', False) then + begin + if Registry.ValueExists('UseTransformColors') then + UseTransformColors := Registry.ReadBool('UseTransformColors') + else + UseTransformColors := False; + if Registry.ValueExists('HelpersEnabled') then + HelpersEnabled := Registry.ReadBool('HelpersEnabled') + else + HelpersEnabled := true; + if Registry.ValueExists('ShowAllXforms') then + ShowAllXforms := Registry.ReadBool('ShowAllXforms') + else + ShowAllXforms := true; + if Registry.ValueExists('EnableEditorPreview') then + EnableEditorPreview := Registry.ReadBool('EnableEditorPreview') + else + EnableEditorPreview := false; + if Registry.ValueExists('EditorPreviewTransparency') then + EditorPreviewTransparency := Registry.ReadInteger('EditorPreviewTransparency') + else + EditorPreviewTransparency := 192; + + if Registry.ValueExists('BackgroundColor') then + EditorBkgColor := Registry.ReadInteger('BackgroundColor') + else + EditorBkgColor := integer(clBlack); + if Registry.ValueExists('GridColor1') then + GridColor1 := Registry.ReadInteger('GridColor1') + else + GridColor1 := $444444; + if Registry.ValueExists('GridColor2') then + GridColor2 := Registry.ReadInteger('GridColor2') + else + GridColor2 := $333333; + if Registry.ValueExists('HelpersColor') then + HelpersColor := Registry.ReadInteger('HelpersColor') + else + HelpersColor := $808080; + if Registry.ValueExists('ReferenceTriangleColor') then + ReferenceTriangleColor := Registry.ReadInteger('ReferenceTriangleColor') + else + ReferenceTriangleColor := $7f7f7f; + if Registry.ValueExists('ExtendedEdit') then + ExtEditEnabled := Registry.ReadBool('ExtendedEdit') + else ExtEditEnabled := true; + if Registry.ValueExists('LockTransformAxis') then + TransformAxisLock := Registry.ReadBool('LockTransformAxis') + else TransformAxisLock := true; + if Registry.ValueExists('RebuildXaosLinks') then + RebuildXaosLinks := Registry.ReadBool('RebuildXaosLinks') + else RebuildXaosLinks := true; + end + else begin + UseTransformColors := false; + HelpersEnabled := true; + ShowAllXforms := true; + EnableEditorPreview := false; + EditorPreviewTransparency := 192; + EditorBkgColor := $000000; + GridColor1 := $444444; + GridColor2 := $333333; + HelpersColor := $808080; + ReferenceTriangleColor := integer(clGray); + ExtEditEnabled := true; + TransformAxisLock := true; + RebuildXaosLinks := true; + end; + Registry.CloseKey; + + { Render } + if Registry.OpenKey('Software\' + APP_NAME + '\Render', False) then + begin + if Registry.ValueExists('Path') then + begin + RenderPath := Registry.ReadString('Path'); + end + else + begin + RenderPath := DefaultPath + '\'; + end; + if Registry.ValueExists('SampleDensity') then + begin + renderDensity := Registry.ReadFloat('SampleDensity'); + end + else + begin + renderDensity := 200; + end; + if Registry.ValueExists('FilterRadius') then + begin + renderFilterRadius := Registry.ReadFloat('FilterRadius'); + end + else + begin + renderFilterRadius := 0.4; + end; + if Registry.ValueExists('Oversample') then + begin + renderOversample := Registry.ReadInteger('Oversample'); + end + else + begin + renderOversample := 2; + end; + if Registry.ValueExists('Width') then + begin + renderWidth := Registry.ReadInteger('Width'); + end + else + begin + renderWidth := 1024; + end; + if Registry.ValueExists('Height') then + begin + renderHeight := Registry.ReadInteger('Height'); + end + else + begin + renderHeight := 768; + end; + if Registry.ValueExists('JPEGQuality') then + begin + JPEGQuality := Registry.ReadInteger('JPEGQuality'); + end + else + begin + JPEGQuality := 100; + end; + if Registry.ValueExists('FileFormat') then + begin + renderFileFormat := Registry.ReadInteger('FileFormat'); + end + else + begin + renderFileFormat := 3; + end; + if Registry.ValueExists('BitsPerSample') then + begin + renderBitsPerSample := Registry.ReadInteger('BitsPerSample'); + end + else + begin + renderBitsPerSample := 0; + end; + + if Registry.ValueExists('StoreEXIF') then begin + StoreEXIF := Registry.ReadBool('StoreEXIF'); + end else begin + StoreEXIF := false; + end; + if Registry.ValueExists('StoreParamsEXIF') then begin + StoreParamsEXIF := Registry.ReadBool('StoreParamsEXIF'); + end else begin + StoreParamsEXIF := false; + end; + if Registry.ValueExists('ExifAuthor') then begin + ExifAuthor := Registry.ReadString('ExifAuthor'); + end else begin + ExifAuthor := ''; + end; + + end + else + begin + renderFileFormat := 2; + JPEGQuality := 100; + renderPath := DefaultPath + '\'; + renderDensity := 200; + renderOversample := 2; + renderFilterRadius := 0.4; + renderWidth := 1024; + renderHeight := 768; + renderBitsPerSample := 0; + StoreEXIF := false; + ExifAuthor := ''; + StoreParamsEXIF := false; + end; + Registry.CloseKey; + + {UPR} + if Registry.OpenKey('Software\' + APP_NAME + '\UPR', False) then + begin + if Registry.ValueExists('FlameColoringFile') then + begin + UPRColoringFile := Registry.ReadString('FlameColoringFile'); + end + else + begin + UPRColoringFile := 'apophysis.ucl'; + end; + if Registry.ValueExists('FlameColoringIdent') then + begin + UPRColoringIdent := Registry.ReadString('FlameColoringIdent'); + end + else + begin + UPRColoringIdent := 'enr-flame-a'; + end; + if Registry.ValueExists('FlameFormulaFile') then + begin + UPRFormulaFile := Registry.ReadString('FlameFormulaFile'); + end + else + begin + UPRFormulaFile := 'mt.ufm'; + end; + if Registry.ValueExists('FlameFormulaIdent') then + begin + UPRFormulaIdent := Registry.ReadString('FlameFormulaIdent'); + end + else + begin + UPRFormulaIdent := 'mt-pixel'; + end; + if Registry.ValueExists('FlameIterDensity') then + begin + UPRSampleDensity := Registry.ReadInteger('FlameIterDensity'); + end + else + begin + UPRSampleDensity := 35; + end; + if Registry.ValueExists('FlameFilterRadius') then + begin + UPRFilterRadius := Registry.ReadFloat('FlameFilterRadius'); + end + else + begin + UPRFilterRadius := 0.7; + end; + if Registry.ValueExists('FlameOversample') then + begin + UPROversample := Registry.ReadInteger('FlameOversample'); + end + else + begin + UPROversample := 3; + end; + if Registry.ValueExists('FlameAdjustDensity') then + begin + UPRAdjustDensity := Registry.ReadBool('FlameAdjustDensity'); + end + else + begin + UPRAdjustDensity := true; + end; + end + else + begin + UPRColoringFile := 'apophysis.ucl'; + UPRColoringIdent := 'enr-flame-a'; + UPRFormulaFile := 'mt.ufm'; + UPRFormulaIdent := 'mt-pixel'; + UPRSampleDensity := 35; + UPRFilterRadius := 0.7; + UPROversample := 3; + UPRAdjustDensity := True; ; + end; + Registry.CloseKey; + + if Registry.OpenKey('Software\' + APP_NAME + '\Display', False) then + begin + if Registry.ValueExists('SampleDensity') then + begin + defSampleDensity := Registry.ReadFloat('SampleDensity'); + end + else + begin + defSampleDensity := 5; + end; + if Registry.ValueExists('Gamma') then + begin + defGamma := Registry.ReadFloat('Gamma'); + end + else + begin + defGamma := 4; + end; + if Registry.ValueExists('Brightness') then + begin + defBrightness := Registry.ReadFloat('Brightness'); + end + else + begin + defBrightness := 4; + end; + if Registry.ValueExists('Vibrancy') then + begin + defVibrancy := Registry.ReadFloat('Vibrancy'); + end + else + begin + defVibrancy := 1; + end; + if Registry.ValueExists('FilterRadius') then + begin + defFilterRadius := Registry.ReadFloat('FilterRadius'); + end + else + begin + defFilterRadius := 0.2; + end; + if Registry.ValueExists('GammaThreshold') then + begin + defGammaThreshold := Registry.ReadFloat('GammaThreshold'); + end + else + begin + defGammaThreshold := 0.01; + end; + if Registry.ValueExists('Oversample') then + begin + defOversample := Registry.ReadInteger('Oversample'); + end + else + begin + defOversample := 1; + end; + if Registry.ValueExists('PreviewDensity') then + begin + defPreviewDensity := Registry.ReadFloat('PreviewDensity'); + end + else + begin + defPreviewDensity := 0.5; + end; + if Registry.ValueExists('PreviewLowQuality') then + begin + prevLowQuality := Registry.ReadFloat('PreviewLowQuality'); + end + else + begin + prevLowQuality := 0.1; + end; + if Registry.ValueExists('PreviewMediumQuality') then + begin + prevMediumQuality := Registry.ReadFloat('PreviewMediumQuality'); + end + else + begin + prevMediumQuality := 1; + end; + if Registry.ValueExists('PreviewHighQuality') then + begin + prevHighQuality := Registry.ReadFloat('PreviewHighQuality'); + end + else + begin + prevHighQuality := 5; + end; + end + else + begin + defSampleDensity := 5; + defGamma := 4; + defBrightness := 4; + defVibrancy := 1; + defFilterRadius := 0.2; + defOversample := 1; + defGammaThreshold := 0.01; + defPreviewDensity := 0.5; + prevLowQuality := 0.1; + prevMediumQuality := 1; + prevHighQuality := 5; + end; + Registry.CloseKey; + + if Registry.OpenKey('Software\' + APP_NAME + '\Autosave', False) then + begin + if Registry.ValueExists('AutoSaveEnabled') then + begin + AutoSaveEnabled := Registry.ReadBool('AutoSaveEnabled'); + end + else + begin + AutoSaveEnabled := false; + end; + if Registry.ValueExists('AutoSaveFreq') then + begin + AutoSaveFreq := Registry.ReadInteger('AutoSaveFreq'); + end + else + begin + AutoSaveFreq := 2; + end; + if Registry.ValueExists('AutoSavePath') then + begin + AutoSavePath := Registry.ReadString('AutoSavePath'); + end + else + begin + AutoSavePath := GetEnvVarValue('USERPROFILE') + '\autosave.flame'; + end; + end else begin + AutoSaveEnabled := false; + AutoSaveFreq := 2; + AutoSavePath := GetEnvVarValue('USERPROFILE') + '\autosave.flame'; + end; + Registry.CloseKey; + finally + Registry.Free; + end; + + PluginPath := ReadPluginDir; +end; + +procedure SaveSettings; +var + Registry: TRegistry; + i: integer; +begin + SavePluginDir(PluginPath); + + Registry := TRegistry.Create; + try + Registry.RootKey := HKEY_CURRENT_USER; + { Defaults } + if Registry.OpenKey('\Software\' + APP_NAME + '\Defaults', True) then + begin + Registry.WriteBool('StartupCheckForUpdates', StartupCheckForUpdates); + Registry.WriteBool('AlwaysCreateBlankFlame', AlwaysCreateBlankFlame); + Registry.WriteString('GradientFile', GradientFile); + Registry.WriteString('HelpPath', HelpPath); + Registry.WriteString('SmoothPaletteFile', SmoothPaletteFile); + Registry.WriteBool('PlaySoundOnRenderComplete', PlaySoundOnRenderComplete); + Registry.WriteString('RenderCompleteSoundFile', RenderCompleteSoundFile); + Registry.WriteBool('AutoOpenLog', AutoOpenLog); + Registry.WriteBool('ClassicListMode', ClassicListMode); + Registry.WriteBool('EmbedThumbnails', EmbedThumbnails); + Registry.WriteBool('WarnOnMissingPlugin', WarnOnMissingPlugin); + Registry.WriteString('LanguageFile', LanguageFile); + Registry.WriteString('LastOpenFile', LastOpenFile); + Registry.WriteInteger('LastOpenFileEntry', LastOpenFileEntry); + Registry.WriteBool('RememberLastOpenFile', RememberLastOpenFile); + Registry.WriteBool('UseSmallThumbnails', UseSmallThumbnails); + Registry.WriteInteger('ToolBarWidth1', TBWidth1); + Registry.WriteInteger('ToolBarWidth2', TBWidth2); + Registry.WriteInteger('ToolBarWidth3', TBWidth3); + Registry.WriteInteger('ToolBarWidth4', TBWidth4); + Registry.WriteInteger('ToolBarWidth5', TBWidth5); + Registry.WriteInteger('LineCenterColor', LineCenterColor); + Registry.WriteInteger('LineThirdsColor', LineThirdsColor); + Registry.WriteInteger('LineGRColor', LineGRColor); + Registry.WriteBool('EnableGuides', EnableGuides); + + Registry.WriteBool('ConfirmDelete', ConfirmDelete); + Registry.WriteBool('OldPaletteFormat', OldPaletteFormat); + Registry.WriteBool('ConfirmExit', ConfirmExit); + Registry.WriteInteger('NumTries', NumTries); + Registry.WriteInteger('TryLength', TryLength); + Registry.WriteInteger('MinTransforms', randMinTransforms); + Registry.WriteInteger('MaxTransforms', randMaxTransforms); + Registry.WriteInteger('MutationMinTransforms', mutantMinTransforms); + Registry.WriteInteger('MutationMaxTransforms', mutantMaxTransforms); + Registry.WriteInteger('RandomGradient', randGradient); + Registry.WriteString('ParameterFolder3D', ParamFolder); + Registry.WriteString('UPRPath', UPRPath); + Registry.WriteString('ImageFolder', ImageFolder); + Registry.WriteString('SavePath3D', SavePath); + Registry.WriteInteger('UPRWidth', UPRWidth); + Registry.WriteInteger('UPRHeight', UPRHeight); + Registry.WriteString('BrowserPath', BrowserPath); + Registry.WriteInteger('EditPreviewQaulity', EditPrevQual); + Registry.WriteInteger('MutatePreviewQaulity', MutatePrevQual); + Registry.WriteInteger('AdjustPreviewQaulity', AdjustPrevQual); + Registry.WriteString('RandomPrefix', RandomPrefix); + Registry.WriteString('RandomDate', RandomDate); + Registry.WriteInteger('RandomIndex', RandomIndex); + Registry.WriteString('DefaultFlameFile3D', defFlameFile); + Registry.WriteString('SmoothPalettePath', SmoothPalettePath); + Registry.WriteString('GradientFile', GradientFile); + Registry.WriteInteger('TryLength', TryLength); + Registry.WriteInteger('NumTries', NumTries); + Registry.WriteString('SmoothPaletteFile', defSmoothPaletteFile); + Registry.WriteInteger('SymmetryType', SymmetryType); + Registry.WriteInteger('SymmetryOrder', SymmetryOrder); + Registry.WriteInteger('SymmetryNVars', SymmetryNVars); +// Registry.WriteInteger('VariationOptions', VariationOptions); +// Registry.WriteInteger('VariationOptions2', VariationOptions shr 32); +// Registry.WriteInteger('ReferenceMode', ReferenceMode); + Registry.WriteInteger('RotationMode', MainForm_RotationMode); + Registry.WriteInteger('MinNodes', MinNodes); + Registry.WriteInteger('MinHue', MinHue); + Registry.WriteInteger('MinSat', MinSat); + Registry.WriteInteger('MinLum', MinLum); + Registry.WriteInteger('MaxNodes', MaxNodes); + Registry.WriteInteger('MaxHue', MaxHue); + Registry.WriteInteger('MaxSat', MaxSat); + Registry.WriteInteger('MaxLum', MaxLum); + Registry.WriteString('RandomGradientFile', randGradientFile); + Registry.WriteInteger('BatchSize', BatchSize); + Registry.WriteString('ScriptPath', ScriptPath); + Registry.WriteInteger('ExportFileFormat', ExportFileFormat); + Registry.WriteInteger('ExportWidth', ExportWidth); + Registry.WriteInteger('ExportHeight', ExportHeight); + Registry.WriteFloat('ExportDensity', ExportDensity); + Registry.WriteFloat('ExportFilter', ExportFilter); + Registry.WriteInteger('ExportOversample', ExportOversample); + Registry.WriteInteger('ExportBatches', ExportBatches); + Registry.WriteString('Nick', SheepNick); + Registry.WriteString('URL', SheepURL); + Registry.WriteString('Renderer', flam3Path); + Registry.WriteString('Server', SheepServer); + Registry.WriteString('Pass', SheepPW); + Registry.WriteBool('ShowProgress', ShowProgress); + Registry.WriteBool('KeepBackground', KeepBackground); + Registry.WriteBool('PreserveQuality', PreserveQuality); + Registry.WriteString('FunctionLibrary', defLibrary); + + Registry.WriteBool('ShowTransparency', ShowTransparency); + Registry.WriteInteger('PNGTransparency', PNGTransparency); + Registry.WriteBool('ExtendMainPreview', ExtendMainPreview); + Registry.WriteFloat('MainPreviewScale', MainPreviewScale); + + Registry.WriteBool('SaveIncompleteRenders', SaveIncompleteRenders); + Registry.WriteBool('ShowRenderStats', ShowRenderStats); + Registry.WriteBool('LowerRenderPriority', LowerRenderPriority); + + Registry.WriteInteger('NrTreads', NrTreads); + Registry.WriteInteger('UseNrThreads', UseNrThreads); + Registry.WriteInteger('InternalBitsPerSample', InternalBitsPerSample); + end; + Registry.CloseKey; + + if Registry.OpenKey('\Software\' + APP_NAME + '\Variations', True) then + begin + for i := 0 to NRVAR-1 do begin + if Registry.ValueExists(Varnames(i)) then + if Registry.ReadBool(Varnames(i)) = Variations[i] then + continue; + Registry.WriteBool(Varnames(i), Variations[i]); + end; + end; + Registry.CloseKey; + + { Editor } + if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Editor', True) then + begin + Registry.WriteBool('UseTransformColors', UseTransformColors); + Registry.WriteBool('HelpersEnabled', HelpersEnabled); + Registry.WriteBool('ShowAllXforms', ShowAllXforms); + Registry.WriteBool('EnableEditorPreview', EnableEditorPreview); + Registry.WriteInteger('EditorPreviewTransparency', EditorPreviewTransparency); + Registry.WriteInteger('BackgroundColor', EditorBkgColor); + Registry.WriteInteger('GridColor1', GridColor1); + Registry.WriteInteger('GridColor2', GridColor2); + Registry.WriteInteger('HelpersColor', HelpersColor); + Registry.WriteInteger('ReferenceTriangleColor', ReferenceTriangleColor); + Registry.WriteBool('ExtendedEdit', ExtEditEnabled); + Registry.WriteBool('LockTransformAxis', TransformAxisLock); + Registry.WriteBool('RebuildXaosLinks', RebuildXaosLinks); + end; + Registry.CloseKey; + + { Display } + if Registry.OpenKey('\Software\' + APP_NAME + '\Display', True) then + begin + Registry.WriteFloat('SampleDensity', defSampleDensity); + Registry.WriteFloat('Gamma', defGamma); + Registry.WriteFloat('Brightness', defBrightness); + Registry.WriteFloat('Vibrancy', defVibrancy); + Registry.WriteFloat('FilterRadius', defFilterRadius); + Registry.WriteInteger('Oversample', defOversample); + Registry.WriteFloat('GammaThreshold', defGammaThreshold); + Registry.WriteFloat('PreviewDensity', defPreviewDensity); + Registry.WriteFloat('PreviewLowQuality', prevLowQuality); + Registry.WriteFloat('PreviewMediumQuality', prevMediumQuality); + Registry.WriteFloat('PreviewHighQuality', prevHighQuality); + end; + Registry.CloseKey; + + { UPR } + if Registry.OpenKey('\Software\' + APP_NAME + '\UPR', True) then + begin + Registry.WriteString('FlameColoringFile', UPRColoringFile); + Registry.WriteString('FlameColoringIdent', UPRColoringIdent); + Registry.WriteString('FlameFormulaFile', UPRFormulaFile); + Registry.WriteString('FlameFormulaIdent', UPRFormulaIdent); + Registry.WriteInteger('FlameIterDensity', UPRSampleDensity); + Registry.WriteFloat('FlameFilterRadius', UPRFilterRadius); + Registry.WriteInteger('FlameOversample', UPROversample); + Registry.WriteBool('FlameAdjustDensity', UPRAdjustDensity); + end; + Registry.CloseKey; + + if Registry.OpenKey('\Software\' + APP_NAME + '\Render', True) then + begin + Registry.WriteString('Path', renderPath); + Registry.WriteFloat('SampleDensity', renderDensity); + Registry.WriteInteger('Oversample', renderOversample); + Registry.WriteFloat('FilterRadius', renderFilterRadius); + Registry.WriteInteger('Width', renderWidth); + Registry.WriteInteger('Height', renderHeight); + Registry.WriteInteger('JPEGQuality', JPEGQuality); + Registry.WriteInteger('FileFormat', renderFileFormat); + Registry.WriteInteger('BitsPerSample', renderBitsPerSample); + Registry.WriteBool('StoreEXIF', StoreEXIF); + Registry.WriteBool('StoreParamsEXIF', StoreParamsEXIF); + Registry.WriteString('ExifAuthor', ExifAuthor); + end; + Registry.CloseKey; + + if Registry.OpenKey('\Software\' + APP_NAME + '\Autosave', True) then + begin + Registry.WriteBool('AutoSaveEnabled', AutoSaveEnabled); + Registry.WriteInteger('AutoSaveFreq', AutoSaveFreq); + Registry.WriteString('AutoSavePath', AutoSavePath); + end; + Registry.CloseKey; + finally + Registry.Free; + end; +end; + +end. + diff --git a/Plugin/barycentroid.c b/Plugin/barycentroid.c new file mode 100644 index 0000000..22e6544 --- /dev/null +++ b/Plugin/barycentroid.c @@ -0,0 +1,89 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double barycentroid_a, barycentroid_b, barycentroid_c, barycentroid_d; + double a, b, c, d; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("barycentroid"); + +APO_VARIABLES( + VAR_REAL(barycentroid_a, 1.0), + VAR_REAL(barycentroid_b, 0.0), + VAR_REAL(barycentroid_c, 0.0), + VAR_REAL(barycentroid_d, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + // alias + VAR(a) = VAR(barycentroid_a); + VAR(b) = VAR(barycentroid_b); + VAR(c) = VAR(barycentroid_c); + VAR(d) = VAR(barycentroid_d); + + return TRUE; +} + +inline double sgn(double v) { return v < 0 ? -1 : v > 0 ? 1 : 0; } + +int PluginVarCalc(Variation* vp) +{ + // helpers + + /* The code is supposed to be fast and you all can read it so I dont + create those aliases for readability in actual code: + + v0x = VAR(a) + v0y = VAR(b) + v1x = VAR(c) + v1y = VAR(d) + v2x = FTx + v2y = FTy + */ + + // compute dot products + double dot00 = VAR(a) * VAR(a) + VAR(b) * VAR(b); // v0 * v0 + double dot01 = VAR(a) * VAR(c) + VAR(b) * VAR(d); // v0 * v1 + double dot02 = VAR(a) * FTx + VAR(b) * FTy; // v0 * v2 + double dot11 = VAR(c) * VAR(c) + VAR(d) * VAR(d); // v1 * v1 + double dot12 = VAR(c) * FTx + VAR(d) * FTy; // v1 * v2 + + // compute inverse denomiator + double invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + + /* now we can pull [u,v] as the barycentric coordinates of the point + P in the triangle [A, B, C] + */ + double u = (dot11 * dot02 - dot01 * dot12) * invDenom; + double v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + // now combine with input + double um = sqrt(sqr(u) + sqr(FTx)) * sgn(u); + double vm = sqrt(sqr(v) + sqr(FTy)) * sgn(v); + + FPx += VVAR * um; + FPy += VVAR * vm; + FPz += VVAR * FTz; // just pass + + return TRUE; +} diff --git a/Plugin/bcircle.c b/Plugin/bcircle.c new file mode 100644 index 0000000..7495590 --- /dev/null +++ b/Plugin/bcircle.c @@ -0,0 +1,65 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double bcbw; + double bcircle_scale; + double bcircle_borderwidth; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("bcircle"); + +APO_VARIABLES( + VAR_REAL(bcircle_scale, 1.0), + VAR_REAL(bcircle_borderwidth, 0.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(bcbw) = fabs(VAR(bcircle_borderwidth)); + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + if ((FTx == 0) && (FTy == 0)) { + return TRUE; + } + double x = FTx * VAR(bcircle_scale); + double y = FTy * VAR(bcircle_scale); + double r = sqrt(x * x + y * y); + + if (r <= 1) { + FPx += VVAR * x; + FPy += VVAR * y; + } else { + if (VAR(bcbw) != 0) { + double ang = atan2(y, x); + double omega = (0.2 * VAR(bcbw) * random01()) + 1; + double px = omega * cos(ang); + double py = omega * sin(ang); + FPx += VVAR * px; + FPy += VVAR * py; + } + } + + return TRUE; +} diff --git a/Plugin/bent2.c b/Plugin/bent2.c new file mode 100644 index 0000000..6bfb84f --- /dev/null +++ b/Plugin/bent2.c @@ -0,0 +1,67 @@ +/* + Apophysis Plugin + + Copyright (C) 2008-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double bent2_x; + double bent2_y; + + + double vvarx; + double vvary; + //double bipilar_vvar; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("bent2"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(bent2_x, 1.0), + VAR_REAL(bent2_y, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(vvarx) = VVAR * VAR(bent2_x); + VAR(vvary) = VVAR * VAR(bent2_y); + //VAR(bipolar_vvar) = 1 + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + if(FTx >= 0.0) + FPx += VVAR * FTx; + else + FPx += VAR(vvarx) * FTx; + if(FTy >= 0.0) + FPy += VVAR * FTy; + else + FPy += VAR(vvary) * FTy; + + return TRUE; +} diff --git a/Plugin/blur_linear.c b/Plugin/blur_linear.c new file mode 100644 index 0000000..f9c98d5 --- /dev/null +++ b/Plugin/blur_linear.c @@ -0,0 +1,58 @@ +/* + Apophysis Plugin + + Copyright (C) 2009 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double blur_linear_length; + double blur_linear_angle; + + double s; + double c; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("blur_linear"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(blur_linear_length, 0.0), + VAR_REAL_CYCLE(blur_linear_angle, 0.0, M_2PI, 0.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + fsincos(VAR(blur_linear_angle), &VAR(s), &VAR(c)); + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double r = VAR(blur_linear_length) * random01(); + + FPx += VVAR * (FTx + r * VAR(c)); + FPy += VVAR * (FTy + r * VAR(s)); + + return TRUE; +} diff --git a/Plugin/blur_square.c b/Plugin/blur_square.c new file mode 100644 index 0000000..70baaf5 --- /dev/null +++ b/Plugin/blur_square.c @@ -0,0 +1,53 @@ +/* + Apophysis Plugin + + Copyright (C) 2009 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double v; +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("blur_square"); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(v) = VVAR * 2.0; + + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + + FPx += VAR(v) * (random01() - 0.5); + FPy += VAR(v) * (random01() - 0.5); + + return TRUE; + +} diff --git a/Plugin/boarders2.c b/Plugin/boarders2.c new file mode 100644 index 0000000..7839265 --- /dev/null +++ b/Plugin/boarders2.c @@ -0,0 +1,104 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double boarders2_c; + double boarders2_left; + double boarders2_right; + double c, cl, cr; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("boarders2"); +APO_VARIABLES( + VAR_REAL(boarders2_c, 0.5), + VAR_REAL(boarders2_left, 0.5), + VAR_REAL(boarders2_right, 0.5), +); + +inline double rint(double x) +{ + int temp; temp = (x >= 0. ? (int)(x + 0.5) : (int)(x - 0.5)); + return (double)temp; +} + +int PluginVarPrepare(Variation* vp) +{ + double c = fabs(VAR(boarders2_c)), + cl = fabs(VAR(boarders2_left)), + cr = fabs(VAR(boarders2_right)); + c = c==0?EPS:c; cl = cl==0?EPS:cl; cr = cr==0?EPS:cr; + VAR(c) = c; VAR(cl) = c*cl; VAR(cr) = c+(c*cr); + return TRUE; +} +int PluginVarCalc(Variation* vp) +{ + const double c = vp->var.c; + const double cl = vp->var.cl; + const double cr = vp->var.cr; + + double roundX, roundY, offsetX, offsetY; + + roundX = rint(FTx); + roundY = rint(FTy); + offsetX = FTx - roundX; + offsetY = FTy - roundY; + + if(random01() >= cr) + { + FPx += VVAR*(offsetX*c + roundX); + FPy += VVAR*(offsetY*c + roundY); + } + else + { + if(fabs(offsetX) >= fabs(offsetY)) + { + if(offsetX >= 0.0) + { + FPx += VVAR*(offsetX*c + roundX + cl); + FPy += VVAR*(offsetY*c + roundY + cl * offsetY / offsetX); + } + else + { + FPx += VVAR*(offsetX*c + roundX - cl); + FPy += VVAR*(offsetY*c + roundY - cl * offsetY / offsetX); + } + } + else + { + if(offsetY >= 0.0) + { + FPy += VVAR*(offsetY*c + roundY + cl); + FPx += VVAR*(offsetX*c + roundX + offsetX/offsetY*cl); + } + else + { + FPy += VVAR*(offsetY*c + roundY - cl); + FPx += VVAR*(offsetX*c + roundX - offsetX/offsetY*cl); + } + } + } + return TRUE; +} + diff --git a/Plugin/butterfly.c b/Plugin/butterfly.c new file mode 100644 index 0000000..6d9f8a9 --- /dev/null +++ b/Plugin/butterfly.c @@ -0,0 +1,54 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double v; +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("butterfly"); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(v) = VVAR * 4.0 / sqrt(3.0 * M_PI); + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double y2 = FTy * 2.0; + double r = VAR(v) * sqrt(fabs(FTy * FTx)/(EPS + sqr(FTx) + sqr(y2))); + + FPx += r * FTx; + FPy += r * y2; + + return TRUE; +} diff --git a/Plugin/cardiod.c b/Plugin/cardiod.c new file mode 100644 index 0000000..111132f --- /dev/null +++ b/Plugin/cardiod.c @@ -0,0 +1,52 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double cardioid_a; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("cardioid"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(cardioid_a, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double a = atan2(FTy, FTx); + double r = VVAR * sqrt(sqr(FTx) + sqr(FTy) + sin( a * VAR(cardioid_a)) + 1.0 ); + double s, c; + fsincos( a, &s, &c); + + FPx += r * c; + FPy += r * s; + return TRUE; +} diff --git a/Plugin/cell.c b/Plugin/cell.c new file mode 100644 index 0000000..8e678d5 --- /dev/null +++ b/Plugin/cell.c @@ -0,0 +1,92 @@ +/* + Apophysis Plugin + + Copyright (c) 2008 Joel Faber. All rights reserverd. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double cell_size; + + double inv_cell_size; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("cell"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(cell_size, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + if (VAR(cell_size) == 0) VAR(cell_size) = 1e-6; + VAR(inv_cell_size) = 1.0 / VAR(cell_size); + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + // calculate input cell + int x = floor(FTx*VAR(inv_cell_size)); + int y = floor(FTy*VAR(inv_cell_size)); + + // Offset from cell origin + double dx = FTx - x*VAR(cell_size); + double dy = FTy - y*VAR(cell_size); + + // interleave cells + if (y >= 0) + { + if (x >= 0) + { + y *= 2; + x *= 2; + } + else + { + y *= 2; + x = -(2*x+1); + } + } + else + { + if (x >= 0) + { + y = -(2*y+1); + x *= 2; + } + else + { + y = -(2*y+1); + x = -(2*x+1); + } + } + + // calculate output point from interleaved cell + FPx += VVAR * (dx + x*VAR(cell_size)); + FPy -= VVAR * (dy + y*VAR(cell_size)); + + return TRUE; +} diff --git a/Plugin/checks.c b/Plugin/checks.c new file mode 100644 index 0000000..21f92d0 --- /dev/null +++ b/Plugin/checks.c @@ -0,0 +1,101 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double checks_x; + double checks_y; + double checks_size; + double checks_rnd; + + double cs, cx, cy, ncx, ncy; + +} Variables; + +#include "apoplugin.h" + + +// Set the name of this plugin +APO_PLUGIN("checks"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(checks_x, 0.5), + VAR_REAL(checks_y, 0.5), + VAR_REAL(checks_size, 0.5), + VAR_REAL(checks_rnd, 0.0) +); + +inline double lrint(double x) +{ + long int temp; temp = (x >= 0. ? (long int)(x + 0.5) : (long int)(x - 0.5)); + return (double)temp; +} + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Multiplication is faster than division, so divide in precalc, multiply in calc. + VAR(cs) = 1.0 / (VAR(checks_size) + EPS); + + // -X- Copied the variables as we only need them for reading + // This is just for safety :-) + VAR(cx) = VAR(checks_x); VAR(cy) = VAR(checks_y); + // -X- Then precalculate -checkx_x, -checks_y + VAR(ncx) = VAR(checks_x) * -1.0; VAR(ncy) = VAR(checks_y) * -1.0; + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double dx, dy; + double x = FTx * VAR(cs); + double y = FTy * VAR(cs); + + int isXY = lrint(FTx * VAR(cs)) + + lrint(FTy * VAR(cs)); + + // -X- This is just for code readability, + // if there is any impact on performance, its minimal :-) + double rnx = VAR(checks_rnd) * random01(); + double rny = VAR(checks_rnd) * random01(); + + if (isXY % 2) + { + // -X- The -VAR(checks_#) stuff caused the error! + dx = VAR(ncx) + rnx; + dy = VAR(ncy); + } + else + { + dx = VAR(cx); + dy = VAR(cy) + rny; + } + + FPx += VVAR * (FTx + dx); + FPy += VVAR * (FTy + dy); + + // -X- and as a little goodie, I pass through FTz so that + // neat lil variation does not kill 3Dness in hack & 7X + FPz += VVAR * (FTz); + + return TRUE; +} diff --git a/Plugin/circlize.c b/Plugin/circlize.c new file mode 100644 index 0000000..268bdcf --- /dev/null +++ b/Plugin/circlize.c @@ -0,0 +1,93 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double circlize_hole; + double VVAR4_PI; + +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("circlize"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(circlize_hole, 0.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(VVAR4_PI) = VVAR / M_PI_4; + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double absx = fabs(FTx); + double absy = fabs(FTy); + double side; + double perimeter; + double r, sina, cosa; + + if (absx >= absy) + { + if (FTx >= absy) + { + perimeter = absx + FTy; + } + else + { + perimeter = 5.0 * absx - FTy; + } + + side = absx; + } + else + { + if (FTy >= absx) + { + perimeter = 3.0 * absy - FTx; + } + else + { + perimeter = 7.0 * absy + FTx; + } + + side = absy; + } + + // tsk tsk... hole is not scaled by vvar. + r = VAR(VVAR4_PI) * side + VAR(circlize_hole); + fsincos(M_PI_4 * perimeter / side - M_PI_4, &sina, &cosa); + + FPx += r * cosa; + FPy += r * sina; + + return TRUE; +} diff --git a/Plugin/coswrap.c b/Plugin/coswrap.c new file mode 100644 index 0000000..b13db0c --- /dev/null +++ b/Plugin/coswrap.c @@ -0,0 +1,75 @@ +/* + "Cosine Wrap" plugin for Apophysis 2.x + Copyright (C) 2010 Georg Kiehne + + Apophysis Fractal Flame Renderer + Copyright (C) 2001-2004 Mark Townsend + Copyright (C) 2005-2008 Peter Sdobnov, Piotr Borys, Ronald Hordijk + + flame - cosmic recursive fractal flames + Copyright (C) 1992-2007 Scott Draves + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + int coswrap_repeat; + double coswrap_amount_x, coswrap_amount_y; + double coswrap_phase_x, coswrap_phase_y; + double ax, ay, px, py, axn, ayn, fr, vv2; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +APO_PLUGIN("coswrap"); +APO_VARIABLES( + VAR_INTEGER_NONZERO(coswrap_repeat, 1.0), + VAR_REAL(coswrap_amount_x, 0.0), + VAR_REAL(coswrap_amount_y, 0.0), + VAR_REAL_CYCLE(coswrap_phase_x, -1.0, 1.0, 0.0), + VAR_REAL_CYCLE(coswrap_phase_y, -1.0, 1.0, 0.0) +); + +// why isn't this in apoplugin.h?? +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +int PluginVarPrepare(Variation* vp) +{ + VAR(ax) = M_2PI * fabs(VAR(coswrap_amount_x)); + VAR(ay) = M_2PI * fabs(VAR(coswrap_amount_y)); + VAR(px) = M_PI * VAR(coswrap_phase_x); + VAR(py) = M_PI * VAR(coswrap_phase_y); + VAR(fr) = fabs((double)VAR(coswrap_repeat)); + VAR(vv2)= 2.0 * VVAR; + return TRUE; +} + +inline double flerp(double a, double b, double p) { return (a+(b-a)*p); } +inline double fabsmod(double fintp) { double dummy; return modf(fintp, &dummy); } +inline double fosc(double p, double amp, double ph) { return 0.5-cos(p*amp+ph)*0.5; } +inline double foscn(double p, double ph) { return 0.5-cos(p+ph)*0.5; } + +int PluginVarCalc(Variation* vp) +{ + double x = 0.5 * FTx + 0.5, y = 0.5 * FTy + 0.5; + double bx = fabsmod(VAR(fr) * x), by = fabsmod(VAR(fr) * y); + double oscnapx = foscn(VAR(coswrap_amount_x), VAR(px)), + oscnapy = foscn(VAR(coswrap_amount_y), VAR(py)); + FPx = -1.0 + VAR(vv2) * flerp(flerp(x, fosc(x, 4.0, VAR(px)), oscnapx), fosc(bx, 4.0, VAR(px)), oscnapx); + FPy = -1.0 + VAR(vv2) * flerp(flerp(y, fosc(y, 4.0, VAR(py)), oscnapy), fosc(by, 4.0, VAR(py)), oscnapy); + return TRUE; +} diff --git a/Plugin/cpow.c b/Plugin/cpow.c new file mode 100644 index 0000000..62b7a76 --- /dev/null +++ b/Plugin/cpow.c @@ -0,0 +1,79 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double cpow_r; + double cpow_i; + int cpow_power; + + double c; + double d; + double ang; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("cpow"); + + +// Define the Variables +APO_VARIABLES( + VAR_REAL(cpow_r, 1.0), + VAR_REAL(cpow_i, 0.0), + VAR_INTEGER_NONZERO(cpow_power, 1) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(ang) = 2.0 * M_PI / ((double) VAR(cpow_power)); + VAR(c) = VAR(cpow_r) / ((double) VAR(cpow_power)); + VAR(d) = VAR(cpow_i) / ((double) VAR(cpow_power)); + return TRUE; // Always return TRUE. +} + +/* + z' = z^(cpow_r + i * cpow_i) + +Simplified using formula: + (a + i*b)^(c + i*d) = rho^c * e^(-d * theta) * [cos(c * theta + d * ln(rho) + i * sin(c * theta + d * ln(rho)], + where (rho, theta) is the polar coordinate equivalent of z=(x, y). +*/ + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double sn, cs; + double a = atan2(FTy, FTx); // Angular polar dimension + double lnr = 0.5 * log(FTx*FTx + FTy*FTy); // Natural logarithm of the radial polar dimension. + + double m = VVAR * exp(VAR(c) * lnr - VAR(d) * a); + + fsincos(VAR(c) * a + VAR(d) * lnr + VAR(ang) * (rand() % VAR(cpow_power)), &sn, &cs); + + FPx += m * cs; + FPy += m * sn; + + return TRUE; +} diff --git a/Plugin/cpow2.c b/Plugin/cpow2.c new file mode 100644 index 0000000..dc1114b --- /dev/null +++ b/Plugin/cpow2.c @@ -0,0 +1,84 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double cpow2_r, cpow2_a; + int cpow2_divisor; + int cpow2_spread; + + double c, half_c; + double d, half_d; + double ang; + double inv_spread, full_spread; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("cpow2"); + + +// Define the Variables +APO_VARIABLES( + VAR_REAL(cpow2_r, 1.0), + VAR_REAL(cpow2_a, 0.0), + VAR_INTEGER_NONZERO(cpow2_divisor, 1), + VAR_INTEGER_RANGE(cpow2_spread, 1, 0x7fffffff, 1), +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(ang) = 2*M_PI / ((double) VAR(cpow2_divisor)); + VAR(c) = VAR(cpow2_r) * cos(M_PI/2*VAR(cpow2_a)) / ((double) VAR(cpow2_divisor)); + VAR(d) = VAR(cpow2_r) * sin(M_PI/2*VAR(cpow2_a)) / ((double) VAR(cpow2_divisor)); + VAR(half_c) = VAR(c) / 2; + VAR(half_d) = VAR(d) / 2; + VAR(inv_spread) = 0.5 / VAR(cpow2_spread); + VAR(full_spread) = 2*M_PI*VAR(cpow2_spread); + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double sn, cs; + double a = atan2(FTy, FTx); + + int n = rand() % VAR(cpow2_spread); + if (a < 0) n++; + a += 2*M_PI*n; + if (cos(a*VAR(inv_spread)) < rand()*2.0/RAND_MAX - 1.0) + a -= VAR(full_spread); + + double lnr2 = log(FTx*FTx + FTy*FTy); // logarithm * 2 + + double r = VVAR * exp(VAR(half_c) * lnr2 - VAR(d) * a); + + fsincos(VAR(c) * a + VAR(half_d) * lnr2 + VAR(ang) * rand(), + &sn, &cs); + + FPx += r * cs; + FPy += r * sn; + + return TRUE; +} diff --git a/Plugin/crackle.c b/Plugin/crackle.c new file mode 100644 index 0000000..1bb462b --- /dev/null +++ b/Plugin/crackle.c @@ -0,0 +1,762 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// "Crackle" variation is a type of blur - it is not affected by incoming data, simply +// generates a texture. + +// These set cache size for cell centres, they take a lot of processing, so it's handy to +// keep values between calls +#define _USE_MATH_DEFINES +#define CACHE_NUM 10 +#define CACHE_WIDTH 21 +#define VORONOI_MAXPOINTS 25 + +// voronoi and noiseb are additional, not required in all Apophysis plugins +#define _x_ 0 +#define _y_ 1 +#define _z_ 2 + +double vratio( double P[2], double Q[2], double U[2] ); +int closest( double P[VORONOI_MAXPOINTS][2], int n, double U[2] ); +double voronoi( double P[VORONOI_MAXPOINTS][2], int n, int q, double U[2] ); +double simplexNoise3D( double V[3] ); +double perlinNoise3D( double V[3], double aScale, double fScale, int octaves ); + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double crackle_cellsize; + double crackle_power; + double crackle_distort; + double crackle_scale; + double crackle_z; + // P is a working list of points + double P[VORONOI_MAXPOINTS][2]; + // C is a cache of pre-calculated centres + double C[CACHE_WIDTH][CACHE_WIDTH][2]; +} Variables; + +#include "apoplugin.h" + +static int p[2050] = { +127, 71, 882, 898, 798, 463, 517, 451, 454, 634, 578, 695, 728, 742, 325, 350, 684, 153, 340, +311, 992, 706, 218, 285, 96, 486, 160, 98, 686, 288, 193, 119, 410, 246, 536, 415, 953, 417, +784, 573, 734, 1, 136, 381, 177, 678, 773, 22, 301, 51, 874, 844, 775, 744, 633, 468, 1019, +287, 475, 78, 294, 724, 519, 17, 323, 191, 187, 446, 262, 212, 170, 33, 7, 227, 566, 526, 264, +556, 717, 477, 815, 671, 225, 207, 692, 663, 969, 393, 658, 877, 353, 788, 128, 303, 614, 501, +490, 387, 53, 941, 951, 736, 539, 102, 163, 175, 584, 988, 35, 347, 442, 649, 642, 198, 727, +939, 913, 811, 894, 858, 181, 412, 307, 830, 154, 479, 704, 326, 681, 619, 698, 621, 552, 598, +74, 890, 299, 922, 701, 481, 867, 214, 817, 731, 768, 673, 315, 338, 576, 222, 484, 305, 623, +239, 269, 46, 748, 608, 546, 537, 125, 667, 998, 714, 529, 823, 247, 289, 771, 808, 973, 735, +516, 974, 702, 636, 357, 455, 600, 80, 336, 696, 963, 297, 92, 980, 670, 958, 625, 712, 406, +173, 19, 763, 470, 793, 283, 655, 59, 421, 1016, 219, 13, 105, 840, 111, 38, 408, 945, 242, +559, 206, 443, 331, 737, 580, 767, 1020, 220, 31, 968, 15, 527, 833, 139, 129, 859, 739, 418, +783, 933, 49, 789, 178, 124, 772, 627, 0, 23, 388, 950, 976, 940, 485, 685, 21, 523, 723, 244, +637, 488, 835, 379, 342, 452, 862, 295, 765, 897, 507, 370, 567, 416, 100, 914, 300, 120, 392, +694, 94, 265, 791, 171, 200, 787, 441, 868, 672, 769, 983, 911, 427, 82, 69, 224, 176, 920, +500, 462, 263, 513, 797, 293, 322, 645, 469, 635, 40, 215, 687, 960, 818, 826, 34, 603, 316, +994, 611, 511, 93, 899, 114, 73, 241, 585, 327, 674, 280, 957, 471, 24, 502, 355, 159, 1017, +855, 270, 538, 521, 162, 880, 334, 986, 740, 719, 266, 820, 97, 41, 52, 750, 893, 838, 616, 83, +896, 777, 464, 562, 183, 362, 411, 478, 398, 384, 912, 599, 587, 609, 822, 243, 504, 753, 857, +157, 964, 65, 261, 81, 371, 435, 924, 885, 884, 863, 613, 721, 669, 121, 639, 989, 487, 238, +448, 216, 852, 643, 713, 676, 277, 879, 133, 123, 304, 547, 396, 70, 141, 909, 848, 900, 318, +146, 356, 802, 4, 807, 558, 764, 545, 588, 872, 554, 467, 544, 505, 149, 62, 901, 64, 45, 813, +27, 109, 718, 803, 853, 996, 1014, 476, 575, 28, 199, 688, 6, 482, 703, 560, 395, 66, 341, 794, +422, 376, 601, 76, 14, 569, 480, 39, 1011, 1001, 854, 55, 89, 335, 761, 363, 419, 252, 799, +358, 324, 1012, 152, 312, 496, 235, 916, 582, 615, 979, 1005, 891, 1013, 641, 18, 148, 185, +512, 378, 58, 211, 495, 594, 87, 762, 366, 660, 449, 520, 424, 886, 819, 281, 147, 290, 390, +32, 572, 993, 720, 683, 309, 254, 607, 568, 256, 533, 394, 620, 429, 67, 831, 103, 423, 668, +693, 518, 551, 697, 253, 949, 54, 875, 116, 434, 743, 644, 590, 279, 843, 589, 11, 647, 586, +806, 549, 375, 226, 851, 499, 450, 978, 29, 982, 189, 107, 508, 373, 796, 20, 700, 110, 26, +461, 782, 591, 828, 57, 904, 847, 328, 122, 630, 711, 44, 397, 404, 209, 365, 84, 194, 1021, +675, 135, 965, 329, 557, 691, 79, 352, 498, 629, 869, 90, 921, 233, 622, 871, 755, 439, 955, +228, 63, 825, 43, 943, 438, 144, 961, 359, 330, 682, 626, 425, 259, 249, 801, 754, 1003, 230, +377, 217, 878, 1007, 313, 2, 915, 550, 271, 437, 846, 548, 145, 715, 346, 251, 372, 99, 543, +16, 47, 195, 679, 174, 905, 188, 804, 169, 785, 231, 726, 814, 339, 531, 420, 258, 1009, 134, +972, 458, 234, 690, 260, 666, 646, 142, 184, 91, 628, 987, 10, 210, 926, 348, 386, 161, 60, +409, 680, 204, 164, 444, 708, 276, 68, 383, 491, 382, 42, 816, 483, 699, 150, 9, 565, 555, 433, +593, 86, 952, 839, 618, 751, 889, 108, 361, 595, 677, 407, 856, 255, 604, 85, 648, 928, 824, +213, 192, 267, 902, 792, 656, 631, 403, 389, 493, 333, 756, 602, 925, 113, 632, 354, 37, 873, +577, 56, 278, 930, 367, 428, 332, 317, 530, 364, 800, 774, 497, 1023, 12, 137, 845, 653, 101, +888, 542, 167, 48, 158, 1002, 745, 292, 944, 456, 990, 574, 25, 1018, 937, 298, 966, 430, 400, +349, 860, 689, 320, 117, 778, 104, 314, 786, 205, 606, 440, 936, 457, 932, 934, 948, 168, 445, +931, 757, 291, 571, 919, 360, 284, 509, 296, 245, 836, 166, 3, 257, 50, 282, 151, 810, 344, +947, 236, 946, 865, 752, 77, 610, 967, 795, 131, 302, 760, 781, 190, 938, 61, 1022, 652, 138, +984, 832, 202, 140, 985, 5, 657, 997, 401, 319, 431, 662, 405, 275, 650, 651, 887, 310, 1004, +368, 208, 596, 248, 758, 8, 126, 730, 489, 343, 337, 506, 515, 432, 232, 250, 532, 954, 524, +115, 229, 522, 908, 729, 186, 561, 995, 156, 196, 118, 805, 399, 918, 991, 849, 273, 747, 640, +143, 321, 624, 268, 306, 30, 722, 540, 534, 710, 130, 155, 883, 716, 525, 426, 812, 345, 929, +975, 472, 837, 605, 664, 391, 581, 272, 746, 112, 659, 665, 780, 240, 841, 474, 563, 36, 579, +286, 436, 907, 369, 201, 402, 962, 106, 749, 172, 494, 88, 466, 473, 414, 597, 374, 942, 308, +766, 459, 821, 592, 881, 380, 759, 866, 779, 809, 876, 541, 829, 528, 999, 221, 661, 927, 413, +977, 182, 583, 733, 892, 741, 570, 351, 617, 956, 72, 709, 850, 732, 770, 870, 95, 935, 223, +179, 861, 917, 447, 385, 132, 827, 923, 75, 465, 612, 460, 725, 492, 553, 1008, 910, 981, 503, +165, 895, 834, 1000, 180, 638, 906, 510, 274, 776, 971, 564, 738, 903, 654, 864, 959, 1015, +453, 535, 237, 197, 1006, 790, 514, 842, 970, 705, 707, 1010, 203, + +// 1k Block repeats here + +127, 71, 882, 898, 798, 463, 517, 451, 454, 634, 578, 695, 728, 742, 325, 350, 684, 153, 340, +311, 992, 706, 218, 285, 96, 486, 160, 98, 686, 288, 193, 119, 410, 246, 536, 415, 953, 417, +784, 573, 734, 1, 136, 381, 177, 678, 773, 22, 301, 51, 874, 844, 775, 744, 633, 468, 1019, +287, 475, 78, 294, 724, 519, 17, 323, 191, 187, 446, 262, 212, 170, 33, 7, 227, 566, 526, 264, +556, 717, 477, 815, 671, 225, 207, 692, 663, 969, 393, 658, 877, 353, 788, 128, 303, 614, 501, +490, 387, 53, 941, 951, 736, 539, 102, 163, 175, 584, 988, 35, 347, 442, 649, 642, 198, 727, +939, 913, 811, 894, 858, 181, 412, 307, 830, 154, 479, 704, 326, 681, 619, 698, 621, 552, 598, +74, 890, 299, 922, 701, 481, 867, 214, 817, 731, 768, 673, 315, 338, 576, 222, 484, 305, 623, +239, 269, 46, 748, 608, 546, 537, 125, 667, 998, 714, 529, 823, 247, 289, 771, 808, 973, 735, +516, 974, 702, 636, 357, 455, 600, 80, 336, 696, 963, 297, 92, 980, 670, 958, 625, 712, 406, +173, 19, 763, 470, 793, 283, 655, 59, 421, 1016, 219, 13, 105, 840, 111, 38, 408, 945, 242, +559, 206, 443, 331, 737, 580, 767, 1020, 220, 31, 968, 15, 527, 833, 139, 129, 859, 739, 418, +783, 933, 49, 789, 178, 124, 772, 627, 0, 23, 388, 950, 976, 940, 485, 685, 21, 523, 723, 244, +637, 488, 835, 379, 342, 452, 862, 295, 765, 897, 507, 370, 567, 416, 100, 914, 300, 120, 392, +694, 94, 265, 791, 171, 200, 787, 441, 868, 672, 769, 983, 911, 427, 82, 69, 224, 176, 920, +500, 462, 263, 513, 797, 293, 322, 645, 469, 635, 40, 215, 687, 960, 818, 826, 34, 603, 316, +994, 611, 511, 93, 899, 114, 73, 241, 585, 327, 674, 280, 957, 471, 24, 502, 355, 159, 1017, +855, 270, 538, 521, 162, 880, 334, 986, 740, 719, 266, 820, 97, 41, 52, 750, 893, 838, 616, 83, +896, 777, 464, 562, 183, 362, 411, 478, 398, 384, 912, 599, 587, 609, 822, 243, 504, 753, 857, +157, 964, 65, 261, 81, 371, 435, 924, 885, 884, 863, 613, 721, 669, 121, 639, 989, 487, 238, +448, 216, 852, 643, 713, 676, 277, 879, 133, 123, 304, 547, 396, 70, 141, 909, 848, 900, 318, +146, 356, 802, 4, 807, 558, 764, 545, 588, 872, 554, 467, 544, 505, 149, 62, 901, 64, 45, 813, +27, 109, 718, 803, 853, 996, 1014, 476, 575, 28, 199, 688, 6, 482, 703, 560, 395, 66, 341, 794, +422, 376, 601, 76, 14, 569, 480, 39, 1011, 1001, 854, 55, 89, 335, 761, 363, 419, 252, 799, +358, 324, 1012, 152, 312, 496, 235, 916, 582, 615, 979, 1005, 891, 1013, 641, 18, 148, 185, +512, 378, 58, 211, 495, 594, 87, 762, 366, 660, 449, 520, 424, 886, 819, 281, 147, 290, 390, +32, 572, 993, 720, 683, 309, 254, 607, 568, 256, 533, 394, 620, 429, 67, 831, 103, 423, 668, +693, 518, 551, 697, 253, 949, 54, 875, 116, 434, 743, 644, 590, 279, 843, 589, 11, 647, 586, +806, 549, 375, 226, 851, 499, 450, 978, 29, 982, 189, 107, 508, 373, 796, 20, 700, 110, 26, +461, 782, 591, 828, 57, 904, 847, 328, 122, 630, 711, 44, 397, 404, 209, 365, 84, 194, 1021, +675, 135, 965, 329, 557, 691, 79, 352, 498, 629, 869, 90, 921, 233, 622, 871, 755, 439, 955, +228, 63, 825, 43, 943, 438, 144, 961, 359, 330, 682, 626, 425, 259, 249, 801, 754, 1003, 230, +377, 217, 878, 1007, 313, 2, 915, 550, 271, 437, 846, 548, 145, 715, 346, 251, 372, 99, 543, +16, 47, 195, 679, 174, 905, 188, 804, 169, 785, 231, 726, 814, 339, 531, 420, 258, 1009, 134, +972, 458, 234, 690, 260, 666, 646, 142, 184, 91, 628, 987, 10, 210, 926, 348, 386, 161, 60, +409, 680, 204, 164, 444, 708, 276, 68, 383, 491, 382, 42, 816, 483, 699, 150, 9, 565, 555, 433, +593, 86, 952, 839, 618, 751, 889, 108, 361, 595, 677, 407, 856, 255, 604, 85, 648, 928, 824, +213, 192, 267, 902, 792, 656, 631, 403, 389, 493, 333, 756, 602, 925, 113, 632, 354, 37, 873, +577, 56, 278, 930, 367, 428, 332, 317, 530, 364, 800, 774, 497, 1023, 12, 137, 845, 653, 101, +888, 542, 167, 48, 158, 1002, 745, 292, 944, 456, 990, 574, 25, 1018, 937, 298, 966, 430, 400, +349, 860, 689, 320, 117, 778, 104, 314, 786, 205, 606, 440, 936, 457, 932, 934, 948, 168, 445, +931, 757, 291, 571, 919, 360, 284, 509, 296, 245, 836, 166, 3, 257, 50, 282, 151, 810, 344, +947, 236, 946, 865, 752, 77, 610, 967, 795, 131, 302, 760, 781, 190, 938, 61, 1022, 652, 138, +984, 832, 202, 140, 985, 5, 657, 997, 401, 319, 431, 662, 405, 275, 650, 651, 887, 310, 1004, +368, 208, 596, 248, 758, 8, 126, 730, 489, 343, 337, 506, 515, 432, 232, 250, 532, 954, 524, +115, 229, 522, 908, 729, 186, 561, 995, 156, 196, 118, 805, 399, 918, 991, 849, 273, 747, 640, +143, 321, 624, 268, 306, 30, 722, 540, 534, 710, 130, 155, 883, 716, 525, 426, 812, 345, 929, +975, 472, 837, 605, 664, 391, 581, 272, 746, 112, 659, 665, 780, 240, 841, 474, 563, 36, 579, +286, 436, 907, 369, 201, 402, 962, 106, 749, 172, 494, 88, 466, 473, 414, 597, 374, 942, 308, +766, 459, 821, 592, 881, 380, 759, 866, 779, 809, 876, 541, 829, 528, 999, 221, 661, 927, 413, +977, 182, 583, 733, 892, 741, 570, 351, 617, 956, 72, 709, 850, 732, 770, 870, 95, 935, 223, +179, 861, 917, 447, 385, 132, 827, 923, 75, 465, 612, 460, 725, 492, 553, 1008, 910, 981, 503, +165, 895, 834, 1000, 180, 638, 906, 510, 274, 776, 971, 564, 738, 903, 654, 864, 959, 1015, +453, 535, 237, 197, 1006, 790, 514, 842, 970, 705, 707, 1010, 203, + +// 2k block overlaps by two items here . . . (to allow for over-runs caused by taking +// "next item in sequence") + +127, 71 +}; + + +// grad[][] contains gradient values that will be associated with grid points for +// the simplex code to interpolate. They are chosen using the hash codes +// from p[], above + +static double grad3[1024][3] = { +{0.79148875, 0.11986299, -0.59931496}, {0.51387411, -0.61170974, 0.60145208}, {-0.95395128, -0.21599571, 0.20814132}, {0.59830026, 0.67281067, 0.43515813}, +{-0.93971346, 0.16019818, -0.30211777}, {-0.74549699, -0.35758846, 0.56246309}, {-0.78850321, -0.29060783, 0.54204223}, {0.61332339, 0.38915256, 0.68730976}, +{-0.64370632, -0.40843865, 0.64716307}, {-0.23922684, 0.70399949, -0.66869667}, {-0.82882802, -0.00130741, 0.55950192}, {0.07987672, 0.62439350, -0.77701510}, +{-0.46863456, -0.57517073, 0.67049257}, {0.30792870, 0.42464616, -0.85138449}, {-0.06972001, 0.30439513, 0.94999091}, {0.58798450, -0.00151777, 0.80887077}, +{-0.32757867, 0.51578941, 0.79161449}, {-0.44745031, 0.86883688, 0.21192142}, {-0.38042636, 0.71222019, 0.58993066}, {-0.32616370, 0.61421101, -0.71858339}, +{0.45483340, 0.19928843, -0.86799234}, {-0.81020233, -0.05930352, 0.58314259}, {0.81994145, 0.39825895, 0.41120046}, {0.49257662, 0.74240487, 0.45409612}, +{0.95124863, -0.26667257, -0.15495734}, {-0.95745656, 0.09203090, -0.27350914}, {0.20842499, -0.82482150, -0.52557446}, {0.46829293, -0.47740985, -0.74349282}, +{-0.65000311, -0.74754355, 0.13665502}, {0.83566743, 0.53294928, -0.13275921}, {0.90454761, -0.35449497, -0.23691126}, {-0.64270969, 0.21532175, 0.73522839}, +{-0.39693478, -0.17553935, -0.90090439}, {0.45073049, 0.65155528, 0.61017845}, {0.69618384, -0.07989842, 0.71340333}, {0.09059934, 0.85274641, -0.51440773}, +{-0.00560267, 0.69197466, 0.72190005}, {0.23586856, -0.95830502, 0.16129945}, {0.20354340, -0.96925430, -0.13826128}, {-0.45516395, 0.63885905, 0.62022970}, +{0.80792021, 0.47917579, 0.34300946}, {0.40886670, -0.32579857, -0.85245722}, {-0.83819701, -0.30910810, 0.44930831}, {-0.57602641, -0.75801200, 0.30595978}, +{-0.16591524, -0.96579983, -0.19925569}, {0.27174061, 0.93638167, -0.22214053}, {-0.45758922, 0.73185326, -0.50497812}, {-0.18029934, -0.78067110, -0.59836843}, +{0.14087163, -0.39189764, -0.90915974}, {-0.03534787, -0.02750024, 0.99899663}, {0.91016878, 0.06772570, 0.40866370}, {0.70142578, 0.70903193, 0.07263332}, +{-0.49486157, -0.54111502, -0.67993129}, {-0.26972486, -0.84418773, -0.46324462}, {0.91931005, 0.03121901, 0.39229378}, {-0.15332070, -0.87495538, 0.45928842}, +{-0.59010107, -0.66883868, 0.45214549}, {0.51964273, -0.78565398, -0.33573688}, {-0.25845001, 0.87348329, -0.41259003}, {-0.64741807, -0.59846669, 0.47189773}, +{-0.79348688, -0.32782128, -0.51274923}, {-0.86280237, -0.14342378, -0.48476972}, {0.19469709, -0.76349966, 0.61576076}, {0.39371236, -0.70742193, -0.58697938}, +{0.62103834, -0.50000004, -0.60358209}, {-0.19652824, -0.51508695, 0.83430335}, {-0.96016549, -0.26826630, -0.07820118}, {0.52655683, 0.84118729, 0.12305219}, +{0.56222101, 0.70557745, -0.43135599}, {0.06395307, 0.99025162, -0.12374061}, {-0.65379289, 0.52521996, 0.54470070}, {0.81206590, -0.38643765, 0.43728128}, +{-0.69449067, -0.71926243, -0.01855435}, {0.33968533, 0.75504287, 0.56082452}, {-0.52402654, -0.70537870, -0.47732282}, {-0.65379327, -0.46369816, 0.59794512}, +{-0.08582021, -0.01217948, 0.99623619}, {-0.66287577, 0.49604924, 0.56083051}, {0.70911302, 0.68748287, -0.15660789}, {-0.58662137, -0.46475685, 0.66323181}, +{-0.76681755, 0.63310950, -0.10565607}, {0.68601816, -0.59353001, 0.42083395}, {0.64792478, -0.72668696, 0.22829704}, {0.68756542, -0.69062543, 0.22425499}, +{-0.46901797, -0.72307343, -0.50713604}, {-0.71418521, -0.11738817, 0.69004312}, {0.50880449, -0.80611081, 0.30216445}, {0.27793962, -0.58372922, -0.76289565}, +{-0.39417207, 0.91575060, -0.07764800}, {-0.84724113, -0.47860304, 0.23048124}, {0.67628991, 0.54362408, -0.49709638}, {0.65073821, -0.09420630, 0.75343544}, +{0.66910202, 0.73566783, -0.10533437}, {0.72191995, -0.00305613, 0.69196983}, {-0.00313125, 0.06634333, 0.99779194}, {-0.06908811, 0.28990653, -0.95455803}, +{0.17507626, 0.73870621, 0.65089280}, {-0.57470594, 0.75735703, 0.31003777}, {-0.91870733, 0.08883536, 0.38481830}, {-0.27399536, 0.39846316, 0.87530203}, +{0.99772699, -0.05473919, 0.03929993}, {0.22663907, 0.97393801, -0.00891541}, {0.62338001, 0.59656797, -0.50547405}, {0.59177247, 0.49473684, -0.63642816}, +{-0.24457664, -0.31345545, 0.91756632}, {-0.44691491, -0.89198404, -0.06805539}, {-0.83115967, -0.44685014, 0.33090566}, {-0.39940345, 0.67719937, -0.61796270}, +{0.55460272, -0.63265953, -0.54051619}, {0.82284412, 0.14794174, -0.54867185}, {-0.39887172, -0.82890906, -0.39218761}, {0.28591109, 0.71270085, 0.64055628}, +{-0.15438831, 0.66966606, 0.72643762}, {-0.75134796, 0.54289699, 0.37515211}, {0.32016243, 0.77691605, -0.54212311}, {0.50884942, 0.15171482, -0.84738119}, +{0.08945627, 0.73684807, 0.67011379}, {-0.68792851, -0.71885270, -0.10002580}, {0.02292266, -0.07249674, 0.99710520}, {0.94083723, -0.10191422, 0.32316993}, +{-0.81053204, 0.43703808, 0.38991733}, {-0.19558496, -0.07485841, 0.97782552}, {0.68911052, -0.49915226, -0.52533200}, {0.19796974, 0.93342057, 0.29922235}, +{-0.79540501, -0.26473293, 0.54520395}, {-0.27945416, -0.91288360, 0.29757168}, {0.82074194, 0.43648314, 0.36859889}, {-0.20594999, -0.70696486, -0.67659832}, +{-0.05687654, -0.70968577, 0.70221874}, {-0.26280466, 0.69993747, -0.66409430}, {-0.54551347, -0.78469719, 0.29438983}, {0.90609571, 0.39319111, 0.15617717}, +{0.69129692, 0.67317351, 0.26257571}, {0.98391565, -0.05206160, 0.17087883}, {0.63806303, 0.67740288, -0.36606134}, {-0.50096077, 0.83542684, -0.22605378}, +{0.65237128, 0.35509583, 0.66956603}, {-0.85711882, -0.19885856, 0.47518691}, {0.79383271, -0.12451513, 0.59525256}, {-0.63301076, 0.07907192, 0.77009416}, +{0.57925311, -0.49077742, 0.65084818}, {0.14070842, 0.97298117, 0.18305403}, {-0.59601232, 0.69646383, -0.39963413}, {-0.68205637, -0.47455943, 0.55641033}, +{0.47997775, -0.84805982, -0.22453484}, {0.83562547, -0.48273957, 0.26209270}, {0.59180830, 0.36411758, 0.71915320}, {0.66057023, -0.66033264, 0.35722231}, +{0.53319130, 0.75511965, 0.38144639}, {-0.21631797, -0.12712992, 0.96801060}, {-0.23971441, 0.89928294, -0.36582400}, {-0.72825564, 0.27377922, -0.62824252}, +{0.02135570, 0.73882696, 0.67355672}, {0.48112026, 0.78759215, 0.38499597}, {-0.58250985, -0.09956878, 0.80670213}, {0.21323385, 0.36856735, 0.90481459}, +{-0.36459960, -0.93062781, -0.03160697}, {-0.68684541, 0.17314748, -0.70587771}, {0.68032531, -0.07909205, -0.72863017}, {0.25007484, -0.61882132, 0.74466284}, +{0.77055613, 0.59380162, 0.23160935}, {0.67996118, -0.03835970, 0.73224403}, {0.43079959, 0.38901749, -0.81429547}, {0.76815116, -0.63831184, 0.05001794}, +{-0.13601015, 0.75596033, -0.64033211}, {0.36884321, -0.45188838, -0.81225093}, {0.79562623, -0.43647179, 0.42008485}, {-0.65875496, 0.39126701, -0.64261344}, +{-0.68899899, 0.44217527, 0.57424858}, {0.25292617, 0.96620732, -0.04971687}, {-0.68558843, -0.70460233, 0.18304118}, {0.86382379, 0.29507865, 0.40833448}, +{0.13627838, 0.31500179, 0.93925613}, {0.67187940, 0.64336667, 0.36695693}, {0.37977583, 0.31123423, 0.87115072}, {-0.03326050, -0.99451574, -0.09915731}, +{-0.66427749, -0.01424397, -0.74735033}, {0.68859558, 0.44744486, -0.57063931}, {-0.56738045, 0.30154774, -0.76625608}, {-0.58488004, 0.63357146, 0.50646080}, +{0.38842469, 0.92016339, 0.04925032}, {0.15316057, -0.97495961, -0.16123153}, {0.57623375, 0.51659393, 0.63331301}, {0.32392581, -0.79816566, -0.50794059}, +{0.73136440, -0.54179646, 0.41420129}, {-0.58929886, -0.58690534, -0.55521975}, {0.64030162, 0.32487137, -0.69604054}, {0.80502987, -0.00635101, 0.59320028}, +{0.46595373, 0.62005710, -0.63120227}, {0.83612498, 0.53677947, 0.11297261}, {-0.60753284, -0.29028728, -0.73934913}, {-0.45583848, 0.84488003, 0.27998037}, +{-0.27320563, -0.39709327, 0.87617100}, {0.84893256, -0.09000823, 0.52078021}, {-0.35708766, -0.73203774, 0.58018027}, {0.10507148, -0.71032871, 0.69598355}, +{0.68468508, 0.26788814, -0.67782172}, {-0.94602428, -0.13594737, -0.29420466}, {0.27104088, 0.95431757, 0.12575696}, {-0.55840113, 0.14909310, 0.81606337}, +{0.47553129, 0.80729730, 0.34948685}, {-0.01891509, -0.97526220, 0.22024047}, {-0.65760518, -0.45924250, -0.59720327}, {-0.70549425, 0.70862555, 0.01129989}, +{-0.88864223, 0.43707946, -0.13883994}, {0.49252849, -0.43814774, 0.75195894}, {-0.01398277, 0.69598571, 0.71791947}, {-0.67265622, 0.27228276, -0.68803758}, +{-0.91724038, -0.01083918, -0.39818663}, {-0.24468025, 0.75690032, 0.60599792}, {-0.49070434, -0.48530058, 0.72366608}, {0.67110346, -0.55453760, -0.49204492}, +{-0.95532877, -0.26328211, -0.13427388}, {-0.66012945, 0.41730904, 0.62456567}, {0.96822786, -0.03273592, 0.24791766}, {0.91952853, 0.23575545, -0.31446248}, +{0.63712542, 0.06762652, 0.76778763}, {-0.21680947, 0.65843559, 0.72073312}, {0.06143588, 0.47272235, -0.87906724}, {0.70541616, -0.21884659, 0.67416186}, +{-0.04396589, -0.67487644, -0.73661984}, {-0.65032618, 0.75012744, 0.11993615}, {-0.78840054, 0.58187068, -0.19962741}, {0.99318416, 0.11467779, 0.02083796}, +{0.76775820, 0.46845611, -0.43714554}, {-0.70891635, -0.54302381, -0.45006972}, {0.55548849, -0.71825576, -0.41897638}, {-0.62167600, 0.77500231, 0.11353575}, +{0.38413022, -0.79687865, 0.46629218}, {-0.56271512, 0.54186596, -0.62428597}, {0.62019121, -0.70563211, -0.34270424}, {0.85913131, 0.50529005, 0.08108862}, +{0.54973106, -0.66129569, -0.51037612}, {-0.74254469, -0.49670185, -0.44934914}, {-0.75780366, 0.59195518, -0.27444976}, {-0.40050287, 0.04302113, -0.91528500}, +{-0.60859484, 0.35063171, 0.71180736}, {-0.57297537, 0.81938865, -0.01736289}, {0.98721933, 0.09373543, -0.12888621}, {0.30397213, 0.87942861, 0.36634172}, +{0.32615126, -0.64515144, -0.69094498}, {0.83015604, 0.30783918, 0.46483974}, {0.42822875, -0.04288671, -0.90265213}, {0.16585965, 0.53714643, 0.82702133}, +{-0.37193298, 0.88497229, 0.28016051}, {0.73544877, 0.67744273, 0.01365471}, {-0.66150496, 0.09327263, -0.74411787}, {0.41664753, -0.23786298, -0.87739731}, +{-0.78513086, -0.42653313, 0.44904233}, {0.08029855, 0.84803303, 0.52382451}, {-0.09507221, 0.50524394, -0.85772364}, {0.66939507, -0.17805679, 0.72125309}, +{-0.76923153, 0.41652205, -0.48455364}, {0.51989556, 0.79632686, 0.30914743}, {0.85617969, -0.51024476, 0.08128121}, {0.71830013, 0.03208003, 0.69499337}, +{-0.96000528, -0.11640072, -0.25463844}, {0.66084196, -0.19355993, 0.72513617}, {-0.57661819, -0.54757438, 0.60636109}, {0.65123443, -0.64818909, -0.39464494}, +{0.36952748, -0.22540306, -0.90146708}, {0.34048182, -0.33515083, 0.87849078}, {0.11132435, -0.75280467, 0.64876191}, {0.67563520, 0.64934616, -0.34909404}, +{0.23316576, 0.69276343, -0.68243135}, {0.30368064, -0.87532007, 0.37628825}, {-0.27080673, -0.74246398, 0.61270789}, {-0.21655683, -0.49565083, -0.84109060}, +{-0.98776592, -0.14473189, 0.05806181}, {0.64562720, 0.38598860, 0.65892209}, {-0.63746045, -0.57205546, 0.51613635}, {0.06117405, -0.78423981, -0.61743474}, +{0.74829362, 0.59119862, 0.30090006}, {-0.42571462, 0.51302568, -0.74536683}, {-0.56331794, 0.48608227, -0.66812943}, {-0.75919788, -0.64885422, 0.05105673}, +{0.14385006, -0.53933953, 0.82971081}, {-0.77031548, -0.28344830, 0.57120148}, {-0.98358057, 0.17900745, 0.02292584}, {-0.25051205, 0.10358351, 0.96255606}, +{-0.32867861, -0.83176115, -0.44737430}, {-0.36281449, -0.92995082, -0.05964161}, {-0.53796595, -0.03614791, 0.84219117}, {0.92960703, 0.10461247, 0.35339354}, +{0.64021850, 0.61360003, 0.46218532}, {0.22343529, 0.69409296, 0.68433299}, {0.01781074, 0.89088149, 0.45388648}, {-0.63004672, -0.26934609, 0.72835007}, +{0.48560056, -0.35192051, -0.80021500}, {0.62050161, 0.57366872, 0.53467931}, {0.00265452, 0.71539198, -0.69871830}, {0.64229521, 0.41380752, 0.64515130}, +{0.23080049, -0.43573115, 0.86998247}, {0.14620517, 0.61171896, -0.77744708}, {-0.27436021, -0.61900378, 0.73590814}, {0.69959023, 0.71050058, 0.07591065}, +{0.70362024, 0.62044755, -0.34635731}, {-0.29622242, -0.71700405, -0.63099721}, {0.31094340, -0.84299864, -0.43893905}, {0.07704196, -0.46344069, -0.88277248}, +{-0.94533514, -0.04418570, 0.32309301}, {0.65845027, -0.36172634, -0.65999795}, {0.76069300, -0.18013255, 0.62361721}, {0.18607691, -0.45751624, -0.86951382}, +{-0.67626808, -0.39178398, -0.62383235}, {-0.58782719, 0.55645189, -0.58721418}, {0.37531624, 0.80640206, 0.45700485}, {0.32610790, -0.50457786, 0.79940905}, +{0.62915643, 0.76094546, -0.15850616}, {0.62803678, -0.75273385, -0.19738681}, {0.42539119, -0.89094420, 0.15893638}, {0.17668676, -0.40626331, 0.89651096}, +{0.02778178, -0.78957083, -0.61303024}, {-0.25950053, -0.16244258, 0.95198313}, {-0.44117714, 0.73727502, -0.51165249}, {-0.30827444, 0.94136275, 0.13712420}, +{0.97572111, -0.04258044, -0.21483768}, {0.55607688, 0.60474525, -0.57014181}, {-0.67430479, 0.12532345, 0.72774109}, {-0.31325824, -0.81393777, -0.48925921}, +{-0.34811982, -0.70956566, 0.61264114}, {0.22583632, 0.72502572, -0.65064250}, {0.76936493, 0.63742123, -0.04209247}, {-0.55303394, -0.38417341, -0.73929984}, +{-0.20953448, -0.92686077, -0.31148742}, {-0.18786352, 0.39920999, 0.89740664}, {0.46307517, -0.88470611, 0.05344618}, {-0.70328479, 0.30353783, 0.64284935}, +{0.85916171, 0.15710234, 0.48699077}, {-0.26398391, 0.42122173, 0.86768932}, {0.82468427, 0.55134621, 0.12614757}, {0.05993298, 0.63414584, 0.77088721}, +{-0.57291678, 0.81909656, -0.02910645}, {0.64075141, 0.74416542, -0.18882655}, {0.67112660, -0.55747979, -0.48867716}, {0.89932863, 0.23426637, -0.36922525}, +{0.59146340, -0.44386974, 0.67316469}, {0.46684506, 0.19781570, -0.86193076}, {0.18536399, 0.76259887, 0.61974443}, {0.84144446, -0.53500771, -0.07574940}, +{0.31212800, 0.82898453, -0.46406977}, {-0.88440729, -0.27020677, -0.38054178}, {0.20051055, 0.77523319, 0.59900670}, {0.48749115, 0.44082691, -0.75367368}, +{0.24971103, -0.88242146, 0.39871892}, {-0.29777449, -0.95158243, -0.07629705}, {-0.37776905, -0.58777023, 0.71541366}, {0.22179317, 0.14730715, -0.96390269}, +{0.58348153, 0.68630504, 0.43420582}, {-0.96759942, 0.14572096, 0.20619593}, {-0.15181654, 0.47495708, 0.86681458}, {0.26580537, 0.74350537, -0.61363447}, +{-0.39189499, 0.72950601, 0.56057051}, {-0.01888074, 0.73557245, -0.67718290}, {0.73486517, 0.20569655, -0.64626783}, {-0.26354754, -0.23595215, -0.93534447}, +{-0.62584298, -0.65116585, 0.42930594}, {-0.66666701, 0.61406968, 0.42246127}, {0.71799877, 0.67101619, 0.18497305}, {0.80098282, -0.45681211, -0.38697444}, +{0.13205975, 0.91574792, -0.37942847}, {0.68891728, 0.72389791, -0.03694308}, {0.50346408, 0.46323331, -0.72934136}, {0.84557323, 0.53378861, -0.00869685}, +{0.08666773, -0.81879883, 0.56750082}, {-0.50044423, 0.65858460, -0.56198033}, {0.35669785, 0.32248792, -0.87679427}, {-0.97346629, -0.22237373, -0.05397509}, +{-0.53358835, -0.29312069, -0.79332448}, {0.12615748, 0.47083230, 0.87315591}, {-0.97022570, 0.19065350, 0.14937651}, {-0.57777643, 0.36008023, 0.73247295}, +{0.60132454, 0.72398065, 0.33802488}, {0.19047827, -0.94729649, -0.25757988}, {-0.45904437, 0.69100108, 0.55838676}, {0.39148612, -0.51878308, 0.76000180}, +{0.04137949, -0.75662546, -0.65253786}, {0.20020542, -0.76439245, -0.61288006}, {0.07933739, -0.21074410, 0.97431643}, {-0.40807425, 0.80614533, 0.42849166}, +{-0.95397962, -0.09342040, -0.28494828}, {-0.31365384, 0.14377778, -0.93858895}, {0.84618575, -0.39191761, 0.36106822}, {-0.90177404, 0.07825801, -0.42506385}, +{-0.19689944, -0.97296956, 0.12066831}, {0.61145370, 0.51715369, -0.59889601}, {-0.57329050, -0.80450317, -0.15528251}, {-0.27749150, -0.76245284, 0.58452044}, +{-0.74877628, 0.66124357, 0.04572758}, {0.60284514, 0.58208119, 0.54567318}, {0.17695878, -0.67360184, 0.71759748}, {-0.83953853, 0.41240184, 0.35369447}, +{0.37802442, -0.60322405, 0.70229501}, {0.51050450, -0.42970396, 0.74480847}, {-0.48366785, -0.20902730, -0.84992529}, {-0.87971286, -0.14820690, -0.45181855}, +{-0.11520437, -0.59044778, -0.79881123}, {0.38877393, 0.92116844, -0.01742240}, {0.94330646, -0.27385756, -0.18754989}, {-0.66585548, 0.46928680, -0.58000550}, +{0.20659390, -0.97226278, -0.10965425}, {0.70114934, 0.70875543, -0.07781609}, {0.50683262, 0.81003447, 0.29489803}, {-0.75501572, 0.56485827, -0.33299610}, +{-0.43930454, -0.48824131, 0.75407688}, {-0.43442626, 0.51174617, 0.74120826}, {-0.97139119, -0.22722375, 0.06905442}, {-0.27189670, 0.51890879, -0.81043559}, +{0.34109465, 0.91412005, -0.21917797}, {0.23216825, -0.66497033, 0.70986785}, {0.87281521, 0.48669099, 0.03640737}, {-0.60266004, -0.34235001, -0.72083101}, +{-0.01994494, -0.52747354, 0.84933731}, {-0.27000504, -0.77679344, -0.56893693}, {-0.12330809, 0.85744248, -0.49958734}, {-0.69270982, 0.61145042, -0.38246763}, +{-0.60277814, 0.55015465, 0.57791727}, {0.64946165, -0.22132925, -0.72747023}, {0.24257305, 0.26557728, 0.93307397}, {-0.66814908, 0.64881591, -0.36416303}, +{-0.74538727, -0.44634982, -0.49514609}, {0.25115903, 0.38535072, -0.88793241}, {-0.61584597, -0.69782826, -0.36574509}, {0.13745929, 0.92666227, 0.34985995}, +{-0.50342245, -0.82980249, -0.24081874}, {0.11249648, 0.99333196, -0.02522230}, {0.83241096, 0.21922825, -0.50895085}, {0.50175590, 0.86108612, 0.08229039}, +{-0.35527286, -0.56925625, -0.74143679}, {0.31441654, -0.91653449, 0.24719782}, {0.62936968, 0.70222610, 0.33282475}, {0.77755375, -0.56236234, -0.28135169}, +{-0.80098254, -0.37712493, 0.46497715}, {0.59310190, -0.68181911, -0.42819720}, {0.15392285, -0.98282954, 0.10175390}, {-0.96618662, 0.25781497, 0.00385483}, +{0.33750940, -0.86020836, 0.38226820}, {-0.09597976, -0.40348179, -0.90993974}, {-0.70910783, 0.60681107, -0.35909108}, {0.41726791, -0.90380775, 0.09496860}, +{-0.03646000, 0.99581799, -0.08376873}, {0.35348135, -0.70899268, 0.61022972}, {0.66002017, 0.74115740, -0.12271547}, {0.18515044, 0.96534454, -0.18392727}, +{-0.29364182, -0.88826809, -0.35320572}, {0.99692330, 0.02436644, -0.07449968}, {-0.13529570, 0.35908874, 0.92344483}, {-0.76888326, -0.29702475, 0.56621095}, +{-0.31931644, 0.72859881, 0.60595444}, {0.52827199, -0.82385659, 0.20539968}, {-0.83281688, -0.27413556, 0.48090097}, {-0.76899198, 0.23377782, 0.59497837}, +{-0.60599231, 0.54438401, -0.58001670}, {-0.59616975, -0.18605791, 0.78100198}, {-0.83753036, 0.32458912, -0.43952794}, {0.62016934, 0.71285793, 0.32745011}, +{-0.62489231, 0.01790151, 0.78050570}, {-0.44050813, -0.31396367, 0.84105850}, {0.82831903, 0.51349534, 0.22407615}, {-0.54638365, -0.42878084, -0.71945250}, +{-0.30690837, -0.54588407, -0.77962673}, {-0.51419246, 0.49668914, 0.69921814}, {0.12759508, 0.79794754, 0.58906640}, {0.59812622, 0.53597438, 0.59579904}, +{0.75450428, 0.31026344, 0.57832507}, {-0.34806954, -0.09710281, 0.93242621}, {-0.40140375, -0.85287390, 0.33388792}, {0.57290191, 0.32347021, -0.75309390}, +{-0.53362688, -0.81285892, 0.23345818}, {-0.74679447, 0.64927639, 0.14400758}, {-0.80251380, -0.59638095, 0.01736004}, {-0.56868668, 0.61763086, -0.54325646}, +{-0.72976559, 0.04179896, -0.68241852}, {0.57244144, -0.09255805, -0.81470474}, {0.97741613, 0.07186077, -0.19873032}, {0.72298477, 0.06613486, 0.68769121}, +{-0.42596585, -0.65375247, -0.62542850}, {0.64840687, 0.16136696, -0.74399545}, {0.34352050, -0.92950264, 0.13423304}, {0.74687236, 0.45351768, -0.48631613}, +{-0.51873425, -0.73762481, -0.43223191}, {0.29790392, 0.44209023, 0.84605525}, {-0.67740274, 0.46717430, -0.56821977}, {-0.36224935, -0.42773177, 0.82814307}, +{-0.44192484, 0.73919980, 0.50821855}, {-0.92680658, -0.18163204, -0.32869343}, {-0.71384582, -0.70014113, 0.01505111}, {0.70600729, -0.70152253, 0.09705589}, +{0.90031692, -0.36943663, 0.23010002}, {0.25264659, -0.65121757, -0.71560141}, {0.96727807, 0.19056552, 0.16750499}, {-0.65770755, -0.65887301, 0.36511251}, +{0.05208955, -0.10417910, 0.99319353}, {-0.65282932, -0.40832320, 0.63803294}, {-0.00628739, -0.99502463, -0.09943061}, {-0.51900794, -0.62993523, 0.57776497}, +{0.83046729, -0.16527060, 0.53198657}, {0.66869945, -0.56606479, -0.48209097}, {-0.54299772, -0.48639669, -0.68452300}, {0.52407156, -0.42268239, 0.73938393}, +{0.71446999, -0.30844019, -0.62801057}, {-0.67320882, 0.39978543, 0.62206228}, {-0.53289859, -0.05079670, -0.84465306}, {0.67708925, -0.71979254, 0.15313018}, +{-0.61369683, 0.65230332, 0.44483321}, {-0.26453665, -0.69129417, -0.67240816}, {0.85045794, 0.03075140, 0.52514345}, {-0.76757885, -0.10940324, 0.63154861}, +{0.72754104, -0.17450402, -0.66350011}, {-0.34075755, -0.67303082, 0.65644026}, {0.70044829, 0.13095479, -0.70158609}, {0.43950040, -0.88211196, 0.16946353}, +{-0.35706397, 0.48041126, 0.80106825}, {-0.77687193, 0.33320308, -0.53427120}, {0.51274543, 0.77662232, 0.36599165}, {0.33380578, 0.79591657, 0.50506486}, +{-0.76587225, -0.03670574, 0.64194422}, {-0.23491078, 0.43695339, -0.86826762}, {0.25698923, -0.62346599, 0.73840822}, {0.13009757, -0.93331414, -0.33466303}, +{-0.54841950, 0.64297666, -0.53461861}, {0.69823865, 0.51710521, -0.49504039}, {-0.64058874, -0.76638614, -0.04794108}, {-0.99383538, 0.10829476, 0.02373760}, +{0.53702674, -0.26620457, -0.80046075}, {0.95618706, 0.14762618, 0.25280983}, {0.46882627, -0.32353926, -0.82190284}, {0.37771393, -0.17580406, -0.90907927}, +{-0.38046162, 0.14393199, -0.91352752}, {0.99319923, -0.09757638, -0.06351493}, {0.50851715, 0.83898531, 0.19368521}, {0.32506349, -0.66811447, 0.66929574}, +{-0.48035988, -0.63636898, -0.60356351}, {-0.06435942, 0.26733173, 0.96145286}, {0.60598929, -0.04278909, 0.79432114}, {-0.24869997, 0.88809619, -0.38656626}, +{0.37370464, 0.04464997, -0.92647246}, {-0.48971589, -0.59472073, 0.63756224}, {0.69752714, 0.12358938, 0.70581978}, {0.52787180, 0.64468756, -0.55292794}, +{-0.10489693, 0.16880171, -0.98005235}, {-0.63336451, -0.45121552, -0.62869226}, {0.54866356, 0.65678858, 0.51729785}, {-0.85968969, 0.49557488, -0.12385145}, +{-0.47320716, -0.15150042, 0.86782637}, {0.19900943, -0.10259966, 0.97461200}, {-0.52893938, 0.84740153, 0.04619294}, {0.65121421, -0.49243156, -0.57743503}, +{0.45693424, 0.73751862, 0.49726994}, {-0.47661222, -0.77374319, -0.41732752}, {-0.04808540, 0.90050093, 0.43218730}, {0.91129978, -0.31013948, 0.27082507}, +{0.58778939, -0.42668247, -0.68734686}, {0.82297839, -0.34772114, -0.44921773}, {0.29494223, -0.86544442, -0.40498769}, {-0.39161493, 0.79055212, 0.47081322}, +{0.79434783, -0.59398096, -0.12727195}, {0.77174313, 0.29796481, 0.56180915}, {0.78482345, -0.44974833, 0.42635500}, {-0.58988658, -0.54565594, 0.59522551}, +{-0.97115669, 0.13450224, 0.19688532}, {0.42988246, 0.15513097, -0.88945796}, {-0.30013401, -0.45617888, 0.83774722}, {0.50990724, -0.38026491, -0.77161727}, +{-0.68923129, 0.29274099, -0.66276914}, {-0.81531731, -0.42344291, -0.39490984}, {0.26048163, -0.96468719, -0.03908901}, {0.32147033, 0.32614689, -0.88897977}, +{0.70055924, -0.70700997, 0.09671429}, {-0.58890140, -0.17999683, 0.78790626}, {0.70222863, 0.69308083, -0.16283095}, {-0.75366081, -0.65098223, -0.09065052}, +{-0.19053922, -0.78772343, -0.58582130}, {-0.58846812, 0.34955220, 0.72905317}, {-0.60563594, -0.40529546, -0.68479244}, {-0.71315551, 0.69904447, 0.05240265}, +{-0.45479055, 0.81186703, -0.36611129}, {-0.29059626, 0.05377439, 0.95533352}, {0.56290473, 0.78501299, 0.25863657}, {-0.43010366, -0.47609705, 0.76703484}, +{0.63372606, -0.06214270, -0.77105744}, {0.28788198, -0.78226752, -0.55243234}, {-0.55506056, 0.67832002, -0.48144545}, {-0.47229498, 0.84794057, -0.24069533}, +{-0.27628326, 0.87423025, -0.39923556}, {0.97754921, -0.01429369, -0.21022189}, {-0.78483628, 0.30941478, -0.53693064}, {-0.35769150, -0.53057471, 0.76847073}, +{0.56804560, 0.59946775, -0.56388173}, {0.80328735, -0.57298006, -0.16255243}, {-0.34327107, -0.35133498, -0.87105034}, {0.80357102, -0.01979284, -0.59487970}, +{-0.87804782, 0.46346126, 0.11931336}, {-0.11872912, -0.93845057, 0.32436695}, {0.68065237, 0.69467363, 0.23268195}, {-0.71974506, -0.36713686, 0.58921776}, +{0.52822234, 0.82314813, -0.20834663}, {-0.67654042, -0.73158271, 0.08414148}, {-0.39062516, 0.89358947, -0.22115571}, {-0.62142505, 0.43386674, -0.65237302}, +{-0.48099381, -0.18611372, -0.85674188}, {0.05036514, -0.74987003, 0.65966528}, {-0.49984895, -0.80920390, -0.30877188}, {0.50496868, 0.85618105, 0.10936472}, +{-0.54084761, 0.24485715, 0.80469176}, {-0.81973873, -0.50777759, 0.26493457}, {0.72082268, -0.43713926, -0.53788839}, {0.91725234, -0.15187152, 0.36821621}, +{-0.17151325, 0.57985483, 0.79646192}, {-0.74076471, 0.06061813, -0.66902398}, {0.32541463, -0.08200506, 0.94200875}, {-0.10818362, 0.99402161, -0.01474260}, +{-0.61710380, -0.78296663, 0.07839742}, {-0.38878719, -0.57916742, 0.71652608}, {0.37911419, 0.92170992, 0.08199541}, {-0.60810067, -0.43108035, 0.66662082}, +{-0.11745691, 0.38395577, 0.91585034}, {0.47694470, -0.81050760, 0.34000174}, {0.40287244, 0.88894800, 0.21786522}, {0.46780815, -0.54966937, 0.69211207}, +{0.07109649, 0.79259959, -0.60558333}, {-0.52073054, -0.06778631, 0.85102569}, {-0.36866700, 0.77676019, -0.51061556}, {-0.71702100, -0.35727116, 0.59853004}, +{-0.59010862, -0.73536014, -0.33319257}, {-0.66875911, 0.58597660, 0.45759445}, {-0.59798034, -0.69169805, 0.40493619}, {-0.20490060, 0.79048994, 0.57718402}, +{0.48765302, 0.85851673, 0.15856717}, {0.88918101, 0.10371433, 0.44564612}, {0.48664272, 0.83596000, 0.25367252}, {-0.24554119, 0.50230038, -0.82909822}, +{0.03554055, -0.41884154, -0.90736356}, {-0.03701100, -0.61772404, 0.78552352}, {0.42824046, 0.20582938, -0.87991158}, {-0.06839464, -0.43555129, -0.89756183}, +{-0.40866952, -0.70331213, -0.58167111}, {-0.74822692, 0.38256599, 0.54203297}, {0.71541445, 0.51615594, 0.47091953}, {0.60759905, -0.70288934, -0.36982423}, +{-0.01648745, -0.13394229, -0.99085197}, {-0.64568452, -0.13342451, 0.75185730}, {-0.42008783, 0.33302268, 0.84416948}, {-0.63557180, -0.46817632, 0.61388877}, +{-0.82478405, -0.45636029, 0.33386606}, {-0.66628051, 0.24058840, 0.70582399}, {-0.60499178, -0.78374178, -0.14047697}, {0.63041860, -0.60894989, -0.48140672}, +{-0.07945150, -0.91288865, -0.40040202}, {-0.66942344, 0.18523930, 0.71941550}, {-0.00849762, -0.47038898, 0.88241827}, {0.66223413, -0.33585751, 0.66981019}, +{0.82512667, -0.23099667, -0.51556427}, {-0.75186864, 0.65450118, -0.07950940}, {0.87383910, 0.08193441, 0.47926192}, {-0.26554211, 0.78650504, 0.55758158}, +{-0.49574252, 0.70523568, 0.50683527}, {-0.49212635, -0.64694353, 0.58247381}, {0.32264136, 0.78159510, -0.53386482}, {0.71510371, -0.22498049, 0.66182359}, +{0.61434883, -0.51790453, 0.59527340}, {-0.82551670, -0.14228251, -0.54614821}, {-0.46251954, 0.64306734, -0.61036060}, {-0.52117891, -0.69061769, 0.50141773}, +{0.27468699, -0.88951139, -0.36512537}, {0.65713642, -0.75365863, -0.01305358}, {0.94136220, -0.21960140, -0.25614924}, {-0.85554460, 0.30842011, -0.41583708}, +{-0.35233681, -0.15379949, 0.92314922}, {-0.74432132, 0.44164975, -0.50093040}, {0.53994954, -0.79953954, -0.26304184}, {0.42964607, 0.11880600, 0.89514769}, +{-0.87921789, 0.18018271, 0.44103298}, {-0.80353079, 0.36514238, 0.47011628}, {0.50404538, 0.65465655, -0.56334986}, {-0.92083981, -0.30381360, -0.24444087}, +{0.13956423, -0.96009192, -0.24237437}, {-0.71698508, 0.68682212, 0.11919639}, {-0.76698836, 0.61675487, -0.17703754}, {-0.21874818, -0.57847904, -0.78581883}, +{0.55494484, -0.79971185, 0.22912262}, {0.79660662, -0.41090893, 0.44336412}, {0.66489466, 0.00947646, -0.74687703}, {-0.59920476, 0.36935905, 0.71030103}, +{-0.57524868, -0.51402380, -0.63629277}, {0.20536135, -0.69296940, 0.69110066}, {-0.05544564, -0.99802158, 0.02964287}, {0.13201661, 0.16519726, -0.97738502}, +{0.46510187, 0.64584669, -0.60544390}, {-0.80108393, -0.59762086, 0.03337417}, {-0.39806873, -0.44410006, -0.80269323}, {0.95136791, -0.21916666, -0.21648342}, +{-0.82086395, 0.17982074, 0.54207645}, {0.79513089, 0.37056075, 0.48005374}, {0.77112323, 0.56616567, 0.29124800}, {0.81176337, -0.24837815, 0.52853432}, +{-0.81842091, 0.50060656, 0.28209979}, {-0.38248924, -0.72602893, 0.57147525}, {0.46198573, 0.37950267, 0.80159024}, {-0.59524911, 0.04222053, 0.80243126}, +{-0.52273882, 0.79497643, -0.30782561}, {-0.79922245, 0.45390541, 0.39397125}, {0.38051244, -0.76512679, 0.51941436}, {0.83818590, 0.22605420, 0.49633043}, +{0.63218067, 0.48127057, 0.60722832}, {0.59242495, 0.18424992, -0.78427333}, {0.85249021, -0.48552132, 0.19372531}, {-0.43548364, -0.58439144, 0.68471939}, +{0.73179011, 0.29594379, -0.61392223}, {-0.45280534, -0.80755156, 0.37792566}, {0.55557939, 0.30092870, -0.77509578}, {0.42575514, 0.70893498, 0.56226662}, +{0.60528173, -0.51550786, 0.60653580}, {-0.51076670, 0.84729685, -0.14562083}, {-0.33474095, 0.69713420, -0.63399716}, {-0.48650711, 0.74561924, 0.45537104}, +{-0.41670009, -0.87381546, -0.25061440}, {0.92586094, -0.34254116, -0.15952140}, {-0.10682502, 0.59910669, 0.79351092}, {-0.44718479, -0.59299328, 0.66961536}, +{0.69862855, -0.48858264, 0.52269031}, {-0.74718902, 0.51933770, -0.41472512}, {-0.56931667, 0.42835158, 0.70170753}, {0.05154068, 0.16647211, 0.98469823}, +{0.74568360, -0.66371406, 0.05864824}, {0.64686641, 0.41668704, 0.63869849}, {0.27796256, -0.73021674, 0.62411563}, {0.77079499, -0.62615383, 0.11750087}, +{-0.06833979, 0.90160690, 0.42712371}, {-0.98003087, -0.09480635, 0.17478914}, {-0.85191651, 0.47279136, 0.22518122}, {0.52473004, -0.19693989, -0.82817454}, +{0.16081399, 0.75081437, -0.64063768}, {0.71441816, 0.52488995, -0.46270642}, {-0.23333515, -0.88652173, 0.39954216}, {0.54760612, -0.74897952, -0.37303782}, +{0.48186221, -0.57810371, 0.65848683}, {-0.21255857, -0.53489421, -0.81774509}, {0.77930308, 0.57549405, -0.24797842}, {0.60279872, -0.76604104, -0.22319235}, +{0.37230136, -0.52720909, 0.76383393}, {-0.13321231, -0.92277683, 0.36157627}, {-0.47833070, -0.49076061, -0.72825392}, {0.28828612, -0.93601402, 0.20191301}, +{-0.66460360, -0.65589055, 0.35792406}, {0.90686144, 0.30403802, 0.29182738}, {-0.00682204, 0.42199214, 0.90657382}, {-0.33221520, 0.26584830, -0.90496284}, +{-0.59515132, 0.55081686, 0.58514588}, {0.77123373, 0.59869357, -0.21625109}, {-0.69765329, -0.61042387, 0.37505011}, {0.02426772, -0.55656860, -0.83044715}, +{0.65180023, 0.75814507, 0.01930051}, {-0.01531784, -0.78276243, 0.62213209}, {0.63847163, 0.03936370, 0.76863807}, {0.40703600, -0.09783879, -0.90815707}, +{-0.46223121, -0.64783550, -0.60551753}, {0.82788442, -0.46539053, 0.31307993}, {-0.75467147, 0.24001984, 0.61062382}, {-0.70062375, -0.69087941, 0.17835919}, +{0.35457466, 0.88605939, -0.29862279}, {0.20159504, -0.88658663, -0.41632150}, {-0.32096612, 0.72494426, -0.60945597}, {0.14147986, 0.53949815, -0.83001518}, +{0.28297638, 0.93772862, 0.20146813}, {0.67192636, 0.43759891, -0.59751332}, {0.98497844, 0.01967209, 0.17155312}, {0.60388215, -0.68969665, 0.39955586}, +{0.41200242, 0.85002960, 0.32818240}, {-0.83375884, 0.39266173, -0.38815328}, {-0.70938505, -0.58502714, -0.39308535}, {-0.63048972, 0.77513872, 0.04053013}, +{0.10261233, -0.69355480, -0.71305852}, {0.65702752, -0.38976767, -0.64528753}, {-0.41388260, 0.33890875, 0.84489174}, {0.03028400, -0.46424256, -0.88519022}, +{0.45068344, -0.52775066, -0.71997478}, {0.48930093, 0.41323002, -0.76800101}, {0.28350070, 0.66390322, 0.69199701}, {0.42450922, -0.60916900, 0.66985450}, +{0.67306932, 0.51724488, -0.52861652}, {0.31095891, 0.94487804, -0.10251852}, {-0.25569777, 0.90632689, -0.33643754}, {-0.21431592, 0.07778980, -0.97366187}, +{0.27676605, -0.87464593, 0.39798876}, {0.00288072, -0.88726140, -0.46125796}, {0.51138622, 0.12353356, 0.85042554}, {0.59734197, 0.76052363, 0.25453168}, +{-0.43336730, -0.76588813, 0.47498227}, {0.34180565, -0.68750195, -0.64071052}, {-0.65078280, 0.51803512, 0.55508681}, {-0.89824124, 0.40466264, -0.17149586}, +{0.54253116, 0.81082175, -0.21960883}, {-0.53994336, 0.54836630, 0.63855741}, {0.68778819, 0.33483595, -0.64407475}, {-0.63530446, -0.39864092, 0.66141792}, +{0.80728009, -0.58358794, -0.08788616}, {0.94835277, 0.26419320, 0.17558181}, {-0.15823843, -0.51165316, 0.84449490}, {0.17510951, -0.22389002, 0.95875436}, +{0.13697442, -0.88598087, 0.44303037}, {-0.73457485, -0.23332652, -0.63714874}, {0.95521505, -0.11801760, 0.27135964}, {-0.40184319, -0.90170455, -0.15953355}, +{0.16857866, -0.70975159, -0.68398386}, {-0.55230772, 0.37144476, 0.74631426}, {0.29875717, -0.61848962, -0.72678383}, {0.62465217, -0.76131685, 0.17379963}, +{0.75759704, 0.19352541, 0.62337360}, {-0.10375594, 0.61563856, 0.78116827}, {0.52725731, 0.25296549, 0.81117704}, {-0.71292545, -0.53989924, -0.44748867}, +{0.78246146, 0.54867457, 0.29446609}, {0.31458005, 0.63401883, -0.70644145}, {-0.09360697, -0.99481997, -0.03963538}, {-0.59000956, 0.10880136, -0.80003186}, +{0.49713243, 0.77379744, -0.39255173}, {-0.92985377, 0.17383167, 0.32427537}, {0.73574353, -0.63730495, -0.22918086}, {-0.04383386, -0.80273910, -0.59471719}, +{0.68411849, 0.52929683, -0.50182344}, {-0.19561815, -0.57428906, -0.79493749}, {0.90257811, -0.06366895, -0.42579222}, {0.62294256, 0.39027502, -0.67795868}, +{-0.39046281, -0.70398950, 0.59324327}, {0.70990020, 0.62433400, -0.32595821}, {-0.99157404, 0.01300690, 0.12888658}, {-0.55765988, -0.46179257, 0.68975581}, +{-0.53736280, -0.34635255, -0.76894807}, {0.25083685, 0.44726649, -0.85850659}, {0.45758528, 0.86982087, -0.18446507}, {-0.18615519, 0.23441065, -0.95414773}, +{0.56359579, -0.41325118, -0.71525048}, {-0.48542469, 0.59678985, -0.63890903}, {-0.72243931, -0.40815930, 0.55811059}, {-0.23748605, 0.68466361, -0.68908354}, +{-0.69257361, 0.27959985, -0.66495543}, {-0.10352601, -0.17369566, -0.97934273}, {0.00192480, -0.09194122, 0.99576258}, {0.36297645, 0.86362173, 0.34986513}, +{-0.71118388, -0.10242990, 0.69550385}, {0.45146824, 0.43080300, 0.78139952}, {-0.13265094, -0.68773403, -0.71374059}, {0.56016516, -0.56270148, -0.60793259}, +{-0.95871022, -0.27465634, -0.07374694}, {-0.84169709, 0.06533746, -0.53598230}, {0.69711911, -0.61618111, -0.36653212}, {-0.01620384, 0.59778204, -0.80149490}, +{-0.34911215, 0.65899531, -0.66621760}, {-0.19279427, -0.50540811, -0.84106659}, {-0.60506152, 0.72292944, 0.33357695}, {0.79789244, -0.59553505, 0.09330415}, +{-0.48173680, -0.74189415, 0.46639331}, {0.84140763, 0.31839867, 0.43664115}, {0.79614481, 0.60391839, -0.03789486}, {0.19384456, 0.57096572, 0.79776089}, +{0.83441754, -0.25078854, -0.49076723}, {-0.62605441, 0.72550166, 0.28583776}, {0.55337866, -0.75558589, 0.35051679}, {0.80543476, -0.01571309, 0.59247611}, +{-0.00851542, 0.98991715, 0.14139139}, {-0.94076275, -0.29730096, -0.16302633}, {-0.75465549, -0.41353736, -0.50939371}, {0.37739255, -0.63080384, 0.67798332}, +{0.47325376, -0.73145333, -0.49092453}, {0.12930721, -0.49066326, -0.86170135}, {0.71173142, -0.11663112, 0.69270165}, {0.41952295, -0.63051086, -0.65303641}, +{0.85916103, 0.42641569, 0.28286390}, {0.54792224, -0.66418740, 0.50856299}, {0.28479416, 0.43856869, 0.85237890}, {-0.59050384, -0.68486024, -0.42693285}, +{0.54884141, 0.60847988, 0.57317130}, {0.87567478, 0.25649070, -0.40915304}, {0.02961573, 0.33496172, 0.94176619}, {0.67428181, 0.70665199, 0.21444580}, +{0.23609059, -0.51982231, 0.82100305}, {0.93726653, 0.00671493, 0.34854893}, {-0.39891590, -0.91536143, -0.05458531}, {0.93359117, -0.35793085, 0.01711843}, +{0.53572079, -0.56879583, 0.62407896}, {-0.61516933, -0.36856434, -0.69694119}, {0.74630703, -0.65946218, -0.09019675}, {0.50607373, -0.59204544, -0.62719342}, +{-0.89793356, 0.43675114, 0.05444050}, {-0.91682171, 0.07126199, 0.39288634}, {-0.61178292, -0.15203616, -0.77627744}, {-0.14028895, 0.63023583, 0.76362413}, +{0.71475895, -0.54060748, 0.44369268}, {-0.31764961, 0.92630790, -0.20261391}, {0.59833443, -0.58864018, -0.54359788}, {-0.81450219, 0.22699691, -0.53390879}, +{0.00452737, -0.06652318, 0.99777461}, {0.59311614, 0.19797584, -0.78039657}, {-0.71375488, -0.02586188, 0.69991795}, {-0.75600145, -0.26384588, -0.59903853}, +{0.25716644, 0.77480857, -0.57752671}, {0.71712423, 0.61984999, -0.31862018}, {-0.28194922, -0.55108799, 0.78537040}, {0.57068285, -0.67066160, 0.47385030}, +{0.48969101, -0.22604767, -0.84208382}, {-0.93763991, -0.34062289, 0.06933579}, {-0.67376035, 0.15110895, -0.72333469}, {-0.72414406, -0.65877431, -0.20403872}, +{-0.71204285, 0.41163046, -0.56881926}, {0.23641604, -0.86280490, 0.44685026}, {0.84208951, 0.19949878, -0.50108432}, {-0.67481860, 0.67904385, -0.28899707}, +{0.52167146, 0.66360202, 0.53618211}, {-0.49330390, -0.48590434, 0.72149029}, {-0.18240720, 0.04137646, -0.98235208}, {0.30714395, 0.55170433, 0.77542564}, +{-0.14577549, 0.95376355, -0.26283949}, {-0.54373260, -0.69781662, -0.46626905}, {0.01799205, -0.81833182, 0.57446437}, {0.51019037, -0.56615200, -0.64743934}, +{0.48463473, 0.59436639, 0.64176146}, {0.09115853, -0.52830175, -0.84414891}, {-0.62962436, -0.38408030, -0.67531880}, {0.50864721, -0.48401592, -0.71204396}, +{-0.69669235, -0.63427804, -0.33512853}, {0.60735178, -0.18339351, 0.77297518}, {0.74102699, 0.67064566, 0.03336744}, {-0.47352242, -0.76145583, -0.44267543}, +{0.47751531, -0.79737827, -0.36900816}, {0.74175025, -0.64892413, 0.16942269}, {0.65484829, -0.70924167, -0.26105549}, {0.60455058, -0.64392987, -0.46890608}, +{-0.61878613, -0.77223405, 0.14407742}, {-0.72376655, -0.65562529, 0.21521492}, {0.24420910, -0.52118606, -0.81775731}, {0.61291622, 0.39870471, -0.68217906}, +{0.67751893, 0.65970488, 0.32520389}, {-0.04366879, -0.96113671, 0.27259726}, {0.36541094, 0.62808212, 0.68701361}, {-0.92572867, 0.10611717, -0.36299528}, +{0.80766374, -0.02031352, -0.58929335}, {-0.82117076, 0.53034081, 0.21075390}, {-0.62778197, -0.51872129, 0.58036025}, {0.37696186, 0.57743439, -0.72420251}, +{-0.56818895, -0.47089866, -0.67484500}, {-0.61126182, -0.69853192, 0.37203783}, {0.57901952, 0.81284241, -0.06343191}, {-0.53287943, 0.70445351, 0.46881208}, +{0.22300157, -0.93258969, 0.28380764}, {-0.63832115, -0.40157013, -0.65672486}, {-0.22074780, 0.50999380, 0.83137040}, {-0.59081050, -0.13684815, -0.79511982}, +{-0.79824305, 0.52060475, -0.30295004}, {-0.56871170, 0.76435226, 0.30386284}, {0.12786983, -0.64236825, -0.75565358}, {-0.17631562, -0.76167939, -0.62350405}, +{0.34713709, 0.61125835, -0.71123770}, {-0.39238887, -0.52886732, 0.75254922}, {0.38116332, 0.71358998, -0.58779577}, {-0.72949527, -0.67040404, 0.13562844}, +{-0.62057913, 0.45165344, -0.64100757}, {-0.10668918, -0.98309252, -0.14881706}, {0.59490400, -0.46196716, -0.65778079}, {0.22433782, 0.49054463, 0.84204424}, +{0.77498791, -0.57220981, 0.26827165}, {0.26474565, 0.93986866, -0.21576987}, {-0.01328623, 0.99975439, 0.01773780}, {0.53097408, 0.47771884, 0.69989373}, +{0.24635212, -0.37499947, -0.89369236}, {0.31300988, -0.54171955, 0.78010560}, {0.77494650, -0.52634980, 0.34987684}, {0.65518408, 0.51410661, -0.55355958}, +{0.78000762, -0.61855443, -0.09475515}, {0.58176976, 0.62638121, 0.51883574}, {-0.62371886, -0.59433046, 0.50768699}, {0.85206333, 0.17478222, -0.49339564}, +{0.69974170, -0.42963013, 0.57077098}, {-0.44953934, 0.62956163, -0.63369277}, {0.63562255, 0.51965998, -0.57090935}, {-0.02766532, -0.52812789, -0.84871406}, +{0.78698609, 0.04742916, -0.61514500}, {0.37827449, 0.78614098, 0.48876454}, {0.90534508, -0.25600916, -0.33883565}, {-0.37701605, 0.47347359, -0.79604124}, +{-0.43802429, 0.40756165, -0.80126664}, {-0.87945568, -0.47372426, -0.04629300}, {-0.22787901, -0.82242670, 0.52123457}, {0.48721529, 0.74652617, -0.45312243}, +{-0.68473990, -0.68222429, 0.25632263}, {-0.33289944, 0.62102263, -0.70958358}, {-0.07838790, -0.85438083, -0.51370101}, {0.18575601, 0.96209034, 0.19969195}, +{0.09048656, -0.68256793, -0.72519874}, {0.29506068, -0.68306389, -0.66810397}, {-0.94937153, -0.17748927, 0.25921277}, {-0.38725072, 0.16372291, 0.90732116}, +{-0.02691563, 0.81898594, 0.57318198}, {-0.65244629, -0.52276924, -0.54865851}, {0.15270967, -0.00097578, 0.98827061}, {0.39108739, 0.55471383, -0.73439990}, +{0.85379797, -0.05140234, 0.51806064}, {0.31443713, 0.14998906, -0.93735403}, {-0.44277186, -0.56474741, -0.69642907}, {-0.31521736, 0.37268196, 0.87278071}, +{0.97997903, -0.16829529, 0.10638514}, {-0.25174419, -0.84939324, 0.46384910}, {0.03867740, -0.72044135, 0.69243651}, {-0.80207202, 0.48047131, 0.35472214}, +{0.48200634, -0.48413492, 0.73026246}, {-0.41800015, 0.44068588, -0.79440029}, {0.58661859, -0.43233611, 0.68480955}, {0.40830998, -0.53710845, 0.73810397}, +{0.61242611, -0.72220206, -0.32149407}, {-0.34159283, -0.62199145, -0.70458567}, {-0.29885191, 0.58492128, -0.75402562}, {-0.62924060, 0.77130626, -0.09561862}, +{0.91118189, 0.27762192, 0.30442344}, {0.08064464, -0.99213777, -0.09570315}, {0.93083382, -0.34928416, -0.10746612}, {0.66101659, -0.67569323, 0.32633681}, +{0.07148482, -0.97619739, -0.20476469}, {0.30440743, -0.78193565, -0.54397863}, {-0.35656518, -0.19962907, 0.91269355}, {0.82151650, -0.31061678, 0.47815045}, +{-0.69709423, -0.71173375, -0.08657198}, {-0.46044170, -0.78565215, -0.41321197}, {-0.70275364, -0.21121895, 0.67935548}, {0.38087769, 0.63933041, 0.66797366} }; + +// Simplex noise is evaluated on a tetrahedral grid, as opposed to a regular +// cube-based one. The two "skew factors" are used to convert between views +// of the grid so that calculations of which gridpoints to use are simpler. +// These numbers are straightforward for 3D, but the geometry is not so kind in +// 2D or 4D + +static const double skewF3 = 1.0/3.0; +static const double skewG3 = 1.0/6.0; + + +// simplexNoise3D - given a vector in (x,y,z) returns the noise value for the +// location +double simplexNoise3D( double V[3] ) { + double C[4][3]; // Co-ordinates of four simplex shape corners in (x,y,z) + double n = 0.0; // Noise total value + int gi[4]; // Hashed grid index for each corner, used to determine gradient + double* U; // Pointer to current gradient vector . . . + int corner; // Iterator for which corner is being processed + double t; // Temp double + + // Convert input co-ordinates ( x, y, z ) to + // integer-based simplex grid ( i, j, k ) + double skewIn = ( V[_x_] + V[_y_] + V[_z_] ) * skewF3; + int i = floor( V[_x_] + skewIn ); + int j = floor( V[_y_] + skewIn ); + int k = floor( V[_z_] + skewIn ); + t = (i + j + k) * skewG3; + + // Cell origin co-ordinates in input space (x,y,z) + double X0 = i - t; + double Y0 = j - t; + double Z0 = k - t; + // This value of t finished with, not used later . . . + + // Point offset within cell, in input space (x,y,z) + C[0][_x_] = V[_x_] - X0; + C[0][_y_] = V[_y_] - Y0; + C[0][_z_] = V[_z_] - Z0; + + // For the 3D case, the simplex shape is a slightly irregular tetrahedron. + // The nested logic determines which simplex we are in, and therefore in which + // order to get gradients for the four corners + + int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords + int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords + + // The fourth corner is always i3 = 1, j3 = 1, k3 = 1, so no need to + // calculate values + if ( C[0][_x_] >= C[0][_y_] ) { + if ( C[0][_y_] >= C[0][_z_] ) { + i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; + } else { // y0= C[0][_z_] ) { + i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; + } else { + i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; + } + } + } else { // x0 0.0) { + U = grad3[ gi[corner] ]; + t *= t; + n += t * t * ( U[_x_] * C[corner][_x_] + U[_y_] * C[corner][_y_] + U[_z_] * C[corner][_z_] ); + } + } + + // The result is scaled be fit -1.0 to 1.0 + return 32.0 * n; +} + +// The Perlin noise function is based on summing coherent noise in "octaves" +double perlinNoise3D(double V[3], double aScale, double fScale, int octaves) { + int i; // Iterator + double n = 0.0; // Sum of noise values + double U[3]; + double a = 1.0; + + U[_x_] = V[_x_]; + U[_y_] = V[_y_]; + U[_z_] = V[_z_]; + + for (i=0; i < octaves; i++) { + n += simplexNoise3D(U) / a; + // None of the below required for last octave . . . + a *= aScale; + U[_x_] *= fScale; + U[_y_] *= fScale; + U[_z_] *= fScale; + } + return n; +} + +double vratio( double P[2], double Q[2], double U[2] ) { + double PmQx, PmQy; + + PmQx = P[_x_] - Q[_x_]; + PmQy = P[_y_] - Q[_y_]; + + if ( 0.0 == PmQx && 0.0 == PmQy ) { + return 1.0; + } + + return 2.0 * ( ( U[_x_] - Q[_x_] ) * PmQx + ( U[_y_] - Q[_y_] ) * PmQy ) / ( PmQx * PmQx + PmQy * PmQy ); +} + +// Closest point to U from array P. +// P is an array of points +// n is number of points to check +// U is location to find closest +int closest( double P[VORONOI_MAXPOINTS][2], int n, double U[2] ) { + double d2; + double d2min = 1.0e100; + int i, j; + + for( i = 0; i < n; i++ ) { + d2 = (P[i][_x_] - U[_x_]) * (P[i][_x_] - U[_x_]) + (P[i][_y_] - U[_y_]) * (P[i][_y_] - U[_y_]); + if ( d2 < d2min ) { + d2min = d2; + j = i; + } + } + + return j; +} + +// Voronoi "value" is 0.0 (centre) to 1.0 (edge) if inside cell . . . higher values +// mean that point is not in the cell defined by chosen centre. +// P is an array of points defining cell centres +// n is number of points in array +// q is chosen centre to measure distance from +// U is point to test +double voronoi( double P[VORONOI_MAXPOINTS][2], int n, int q, double U[2] ) { + double ratio; + double ratiomax = -1.0e100; + int i; + + for( i = 0; i < n; i++ ) { + if ( i != q ) { + ratio = vratio( P[i], P[q], U ); + if ( ratio > ratiomax ) { + ratiomax = ratio; + } + } + } + + return ratiomax; +} + +// Waffle's cells are based on a simple square grid which is distorted using a noise function + +// position() calculates cell centre for cell (x, y), given plane slice z, scale factor s, distortion d +// and stores in supplied array +void position( int x, int y, double z, double s, double d, double V[2] ) { + double E[3], F[3]; + + // Values here are arbitrary, chosen simply to be far enough apart so they do not correlate + E[_x_] = x * 2.5; + E[_y_] = y * 2.5; + E[_z_] = z * 2.5; + // Cross-over between x and y is intentional + F[_x_] = y * 2.5 + 30.2; + F[_y_] = x * 2.5 - 12.1; + F[_z_] = z * 2.5 + 19.8; + + V[_x_] = ( x + d * simplexNoise3D( E ) ) * s; + V[_y_] = ( y + d * simplexNoise3D( F ) ) * s; +} + +// cached_position gives centre co-ordinates either from cache, or calculated from scratch if needed +void cached_position( double Cache[CACHE_WIDTH][CACHE_WIDTH][2], int x, int y, double z, double s, double d, double V[2] ) { + if ( abs(x) <= CACHE_NUM && abs(y) <= CACHE_NUM ) { + V[_x_] = Cache[x+CACHE_NUM][y+CACHE_NUM][_x_]; + V[_y_] = Cache[x+CACHE_NUM][y+CACHE_NUM][_y_]; + } else { + position( x,y,z,s,d,V ); + } +} + +// Set the name of this plugin +APO_PLUGIN("crackle"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(crackle_cellsize, 1.0), + VAR_REAL(crackle_power, 0.2), + VAR_REAL(crackle_distort, 0.0), + VAR_REAL(crackle_scale, 1.0), + VAR_REAL(crackle_z, 0.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Pre-calculate cache of grid centres, to save time later . . . + int x,y; + for ( x= -CACHE_NUM; x <= CACHE_NUM; x++ ) { for ( y= -CACHE_NUM; y <= CACHE_NUM; y++ ) { + position( x, y, VAR(crackle_z), VAR(crackle_cellsize) / 2.0, VAR(crackle_distort), VAR(C)[x+CACHE_NUM][y+CACHE_NUM] ); + } } + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double XCo, YCo, DXo, DYo, L, R, s, trgL; + double U[2]; + int XCv, YCv; + + // An infinite number of invisible cells? No thanks! + if ( 0.0 == VAR(crackle_cellsize) ) { + return TRUE; + } + + // Scaling factor + s = VAR(crackle_cellsize) / 2.0; + + // For a blur effect, base everything starting on a circle radius 1.0 + // (as opposed to reading the values from FTx and FTy) + double blurr = (random01() + random01()) / 2.0 + ( random01() - 0.5 ) / 4.0; + + double theta = 2 * M_PI * random01(); + U[_x_] = blurr * sin(theta); + U[_y_] = blurr * cos(theta); + + // Use integer values as Voronoi grid co-ordinates + XCv = (int) floor( U[_x_] / s ); + YCv = (int) floor( U[_y_] / s ); + + // Get a set of 9 square centre points, based around the one above + int di, dj; + int i = 0; + for (di = -1; di < 2; di++) { for (dj = -1; dj < 2; dj++) { + cached_position( VAR(C), XCv+di, YCv+dj, VAR(crackle_z), s, VAR(crackle_distort), VAR(P)[i] ); + i++; + } } + + int q = closest( VAR(P), 9, U ); + + int offset[9][2] = { { -1, -1}, { -1, 0}, { -1, 1}, + { 0, -1}, { 0, 0}, { 0, 1}, + { 1, -1}, { 1, 0}, { 1, 1} }; + + // Remake list starting from chosen square, ensure it is completely surrounded (total 9 points) + + // First adjust centres according to which one was found to be closest + XCv += offset[q][_x_]; + YCv += offset[q][_y_]; + + // Get a new set of 9 square centre points, based around the definite closest point + i=0; + for (di = -1; di < 2; di++) { for (dj = -1; dj < 2; dj++) { + cached_position( VAR(C), XCv+di, YCv+dj, VAR(crackle_z), s, VAR(crackle_distort), VAR(P)[i] ); + i++; + } } + + L = voronoi( VAR(P), 9, 4, U ); // index 4 is centre cell + + // Delta vector from centre + DXo = U[_x_] - VAR(P)[4][_x_]; + DYo = U[_y_] - VAR(P)[4][_y_]; + + ///////////////////////////////////////////////////////////////// + // Apply "interesting bit" to cell's DXo and DYo co-ordinates + + // trgL is the new value of L + trgL = pow(L + 1e-100, VAR(crackle_power)) * VAR(crackle_scale); // ( 0.9 ) + + R = trgL / ( L + 1e-100 ); + + DXo *= R; + DYo *= R; + + // Add cell centre co-ordinates back in + DXo += VAR(P)[4][_x_]; + DYo += VAR(P)[4][_y_]; + + // Finally add values in + FPx += VVAR * DXo; + FPy += VVAR * DYo; + + return TRUE; +} diff --git a/Plugin/curve.c b/Plugin/curve.c new file mode 100644 index 0000000..f3965bc --- /dev/null +++ b/Plugin/curve.c @@ -0,0 +1,73 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double curve_xamp; + double curve_xlength; + double curve_yamp; + double curve_ylength; + + // precalc values: + double pc_xamp; + double pc_yamp; + double pc_xlen; + double pc_ylen; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("curve"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(curve_xamp, 0.0), + VAR_REAL(curve_yamp, 0.0), + VAR_REAL(curve_xlength, 1.0), + VAR_REAL(curve_ylength, 1.0) +); + +inline double fmax(double a, double b) { + return a > b ? a : b; +} + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(pc_xamp) = VVAR * VAR(curve_xamp); + VAR(pc_yamp) = VVAR * VAR(curve_yamp); + VAR(pc_xlen) = 1.0 / fmax(VAR(curve_xlength) * VAR(curve_xlength), 1E-20); + VAR(pc_ylen) = 1.0 / fmax(VAR(curve_ylength) * VAR(curve_ylength), 1E-20); + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + FPx += VVAR * FTx + VAR(pc_xamp) * exp(-FTy * FTy * VAR(pc_xlen)); + FPy += VVAR * FTy + VAR(pc_yamp) * exp(-FTx * FTx * VAR(pc_ylen)); + + return TRUE; +} + diff --git a/Plugin/dc_boarders.c b/Plugin/dc_boarders.c new file mode 100644 index 0000000..952239e --- /dev/null +++ b/Plugin/dc_boarders.c @@ -0,0 +1,85 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define APO_NOVARIABLES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("dc_boarders"); + +inline double rint(double x) +{ + int temp; temp = (x >= 0. ? (int)(x + 0.5) : (int)(x - 0.5)); + return (double)temp; +} + + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double roundX, roundY, offsetX, offsetY; + + roundX = rint(FTx); + roundY = rint(FTy); + offsetX = FTx - roundX; + offsetY = FTy - roundY; + + if(random01() >= 0.75) + { + FPx += VVAR*(offsetX*0.5 + roundX); + FPy += VVAR*(offsetY*0.5 + roundY); + } + else + { + if(fabs(offsetX) >= fabs(offsetY)) + { + if(offsetX >= 0.0) + { + FPx += VVAR*(offsetX*0.5 + roundX + 0.25); + FPy += VVAR*(offsetY*0.5 + roundY + 0.25 * offsetY / offsetX); + } + else + { + FPx += VVAR*(offsetX*0.5 + roundX - 0.25); + FPy += VVAR*(offsetY*0.5 + roundY - 0.25 * offsetY / offsetX); + } + } + else + { + if(offsetY >= 0.0) + { + FPy += VVAR*(offsetY*0.5 + roundY + 0.25); + FPx += VVAR*(offsetX*0.5 + roundX + offsetX/offsetY*0.25); + } + else + { + FPy += VVAR*(offsetY*0.5 + roundY - 0.25); + FPx += VVAR*(offsetX*0.5 + roundX - offsetX/offsetY*0.25); + } + } + } + return TRUE; +} + diff --git a/Plugin/dc_bubble.c b/Plugin/dc_bubble.c new file mode 100644 index 0000000..e1fa44c --- /dev/null +++ b/Plugin/dc_bubble.c @@ -0,0 +1,55 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double dc_bubble_centerx; + double dc_bubble_centery; + double dc_bubble_scale; + + double bdcs; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("dc_bubble"); +APO_VARIABLES( + VAR_REAL(dc_bubble_centerx, 0.0), + VAR_REAL(dc_bubble_centery, 0.0), + VAR_REAL(dc_bubble_scale, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(bdcs) = 1.0 / (VAR(dc_bubble_scale) == 0.0 ? 10E-6 : VAR(dc_bubble_scale)); + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double r = (sqr(FTx) + sqr(FTy)); + double r4_1 = r / 4.0 + 1.0; + r4_1 = VVAR / r4_1; + FPx += FPx + r4_1 * FTx; + FPy += FPy + r4_1 * FTy; + FPz += FPz + VVAR * (2.0 / r4_1 - 1.0); + + TC = fmod(fabs(VAR(bdcs) * (sqr(FPx + VAR(dc_bubble_centerx)) + sqr(FPy + VAR(dc_bubble_centery)))), 1.0); + + return TRUE; +} diff --git a/Plugin/dc_cube.c b/Plugin/dc_cube.c new file mode 100644 index 0000000..4125afe --- /dev/null +++ b/Plugin/dc_cube.c @@ -0,0 +1,63 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double dc_cube_c1, dc_cube_c2, dc_cube_c3, + dc_cube_c4, dc_cube_c5, dc_cube_c6; + double dc_cube_x, dc_cube_y, dc_cube_z; + double c1, c2, c3, c4, c5, c6; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("dc_cube"); +APO_VARIABLES( + VAR_REAL(dc_cube_c1, 0.0), VAR_REAL(dc_cube_c2, 0.0), + VAR_REAL(dc_cube_c3, 0.0), VAR_REAL(dc_cube_c4, 0.0), + VAR_REAL(dc_cube_c5, 0.0), VAR_REAL(dc_cube_c6, 0.0), + VAR_REAL(dc_cube_x, 1.0), VAR_REAL(dc_cube_y, 1.0), + VAR_REAL(dc_cube_z, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(c1) = VAR(dc_cube_c1)<0?0:VAR(dc_cube_c1)>1?1:VAR(dc_cube_c1); + VAR(c2) = VAR(dc_cube_c2)<0?0:VAR(dc_cube_c2)>1?1:VAR(dc_cube_c2); + VAR(c3) = VAR(dc_cube_c3)<0?0:VAR(dc_cube_c3)>1?1:VAR(dc_cube_c3); + VAR(c4) = VAR(dc_cube_c4)<0?0:VAR(dc_cube_c4)>1?1:VAR(dc_cube_c4); + VAR(c5) = VAR(dc_cube_c5)<0?0:VAR(dc_cube_c5)>1?1:VAR(dc_cube_c5); + VAR(c6) = VAR(dc_cube_c6)<0?0:VAR(dc_cube_c6)>1?1:VAR(dc_cube_c6); + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double x, y, z; + double p = 2*random01()-1, q = 2*random01()-1; + int i = rand() % 3, j = rand() & 1; switch (i) { + case 0: x = VVAR * (j?-1:1); y = VVAR * p; z = VVAR * q; + if(j) TC=VAR(c1); else TC=VAR(c2); break; + case 1: x = VVAR * p; y = VVAR * (j?-1:1); z = VVAR * q; + if(j) TC=VAR(c3); else TC=VAR(c4); break; + case 2: x = VVAR * p; y = VVAR * q; z = VVAR * (j?-1:1); + if(j) TC=VAR(c5); else TC=VAR(c6); break; + } + FPx += x * VAR(dc_cube_x); FPy += y * VAR(dc_cube_y); FPz += z * VAR(dc_cube_z); + return TRUE; +} diff --git a/Plugin/dc_gridout.c b/Plugin/dc_gridout.c new file mode 100644 index 0000000..a5ade11 --- /dev/null +++ b/Plugin/dc_gridout.c @@ -0,0 +1,117 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2008 Michael Faber + Copyright (C) 2007-2008 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define APO_NOVARIABLES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("dc_gridout"); + +inline double rint(double x) +{ + int temp; temp = (x >= 0. ? (int)(x + 0.5) : (int)(x - 0.5)); + return (double)temp; +} + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double x = rint(FTx); + double y = rint(FTy); + double c = TC; + + if (y <= 0.0) + { + if (x > 0.0) + { + if (-y >= x) + { + FPx += VVAR * (FTx + 1.0); + FPy += VVAR * FTy; + c += 0.25; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy + 1.0); + c += 0.75; + } + } + else + { + if (y <= x) + { + FPx += VVAR * (FTx + 1.0); + FPy += VVAR * FTy; + c += 0.25; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy - 1.0); + c += 0.75; + } + } + } + else + { + if (x > 0.0) + { + if (y >= x) + { + FPx += VVAR * (FTx - 1.0); + FPy += VVAR * FTy; + c += 0.25; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy + 1.0); + c += 0.75; + } + } + else + { + if (y > -x) + { + FPx += VVAR * (FTx - 1.0); + FPy += VVAR * FTy; + c += 0.25; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy - 1.0); + c += 0.75; + } + } + } + + TC = fmod(c, 1.0); + + return TRUE; +} diff --git a/Plugin/dc_linear.c b/Plugin/dc_linear.c new file mode 100644 index 0000000..215fb8f --- /dev/null +++ b/Plugin/dc_linear.c @@ -0,0 +1,52 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double dc_linear_offset, dc_linear_angle, dc_linear_scale; + double ldcs, ldca; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +APO_PLUGIN("dc_linear"); +APO_VARIABLES( + VAR_REAL(dc_linear_offset, 0.0), + VAR_REAL(dc_linear_angle, 0.0), + VAR_REAL(dc_linear_scale, 1.0), +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(ldcs) = 1.0 / (VAR(dc_linear_scale) == 0.0 ? 10E-6 : VAR(dc_linear_scale)); + VAR(ldca) = VAR(dc_linear_offset) * M_PI; + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + FPx += VVAR * FTx; + FPy += VVAR * FTy; + FPz += VVAR * FTz; + + double c, s; fsincos(VAR(dc_linear_angle), &s, &c); + TC = fmod( fabs( 0.5 * (VAR(ldcs) * ((c * FPx + s * FPy + VAR(dc_linear_offset))) + 1.0) ), 1.0 ); + + return TRUE; +} diff --git a/Plugin/dc_mandelbrot.c b/Plugin/dc_mandelbrot.c new file mode 100644 index 0000000..037c9a6 --- /dev/null +++ b/Plugin/dc_mandelbrot.c @@ -0,0 +1,301 @@ +/* + Apophysis Plugin + + Mandelbrot Set Plugin v2 - Copyright 2008,2009 Jed Kelsey + Changed to work with Apophysis 7X / DC in 2010 by Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + int dcm_iter; + int dcm_miniter; + int dcm_smooth_iter; + int dcm_retries; + int dcm_mode; + int dcm_pow; + int dcm_color_method; + double dcm_invert; + double dcm_xmin; + double dcm_xmax; + double dcm_ymin; + double dcm_ymax; + double dcm_scatter; + double dcm_sx; + double dcm_sy; + double dcm_zscale; + + double x0, y0; + double zs, sc; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +APO_PLUGIN("dc_mandelbrot"); +APO_VARIABLES( + VAR_INTEGER_RANGE(dcm_iter, 5, INT_MAX, 25), + VAR_INTEGER_RANGE(dcm_miniter, 0, INT_MAX, 1), + VAR_INTEGER_RANGE(dcm_smooth_iter, 0, INT_MAX, 0), + VAR_INTEGER_RANGE(dcm_retries, 0, INT_MAX, 50), + VAR_INTEGER_RANGE(dcm_mode, 0, 5, 0), + VAR_INTEGER_RANGE(dcm_pow, -6, 6, 2), // TODO: negative powers + VAR_INTEGER_RANGE(dcm_color_method, 0, 7, 0), + VAR_REAL_RANGE(dcm_invert, 0.0, 1.0, 0.0), + VAR_REAL(dcm_xmin, -2.0), + VAR_REAL(dcm_xmax, 2.0), + VAR_REAL(dcm_ymin, -1.5), + VAR_REAL(dcm_ymax, 1.5), + VAR_REAL_RANGE(dcm_scatter, -1000.0, 1000.0, 0.0), + + // Following parameters don't affect iterations, just the output point positions. + VAR_REAL(dcm_sx, 0.0), + VAR_REAL(dcm_sy, 0.0), + VAR_REAL(dcm_zscale, 0.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(zs) = VVAR * VAR(dcm_zscale) / VAR(dcm_iter); + VAR(sc) = VAR(dcm_scatter) / 10.0; + return TRUE; +} + +inline double fmod2(double h, double q) { return fmod(fabs(h),q); } + +int PluginVarCalc(Variation* vp) +{ + double x=0.0, y=0.0, x1=0.0, y1=0.0, x2, y2, xtemp=0.0; + double cx=0.0, cy=0.0; + + int maxiter = VAR(dcm_iter); + int miniter = VAR(dcm_miniter); // = 0.1*(maxiter*(1-scatter)); + + double xmax = VAR(dcm_xmax); + double xmin = VAR(dcm_xmin); + double ymax = VAR(dcm_ymax); + double ymin = VAR(dcm_ymin); + + int maxRetries = VAR(dcm_retries); + int mode = VAR(dcm_mode); /* 0=Mandelbrot, 1=Julia, 3=Tricorn(Mandelbar) */ + + int color_method = VAR(dcm_color_method); + double xp = 0.0, yp = 0.0; + + int smooth_iter=0, max_smooth_iter=VAR(dcm_smooth_iter); + int inverted, iter=0, retries=0; + int isblur = (VAR(sc)>=0); + + double smoothed_iter = 0.0, inv_iter = 1.0; + double mag2 = 0.0; + + int m_power = VAR(dcm_pow); + int m_power_abs = ((m_power<0) ? -m_power : m_power); + + inverted = random01() < VAR(dcm_invert); + + if (!isblur) { + VAR(x0) = FTx; + VAR(y0) = FTy; + } + + do { + if (VAR(sc)==0) { + // Force selection of point at random + VAR(x0) = VAR(y0) = 0; + } + + if (VAR(x0)==0 && VAR(y0)==0) { + // Choose a point at random + VAR(x0) = (xmax-xmin)*random01() + xmin; + VAR(y0) = (ymax-ymin)*random01() + ymin; + } else { + // Choose a point close to previous point + VAR(x0) += VAR(sc)*(random01()-0.5); + VAR(y0) += VAR(sc)*(random01()-0.5); + } + + // default to Mandelbrot Set + cx = x1 = x = xp = VAR(x0); + cy = y1 = y = yp = VAR(y0); + + switch(mode) { + case 1: // Julia Set + cx = TM(e); + cy = TM(f); + break; + case 2: // tricorn (Mandelbar) + // leave as-is, handled below + break; + default: // Regular Mandelbrot set + // Leave as-is + break; + } + + iter = smooth_iter = 0; + + while ( (((x2=x*x) + (y2=y*y) < 4) && (iter < maxiter)) || (smooth_iter++0) && (iter0) { + x = x/xtemp; + y = -y/xtemp; + } + + iter++; + } + + iter -= (smooth_iter-1); + + // could probably bypass check and always select next point at random + if ( (miniter==0) || (!inverted && (iter>=maxiter)) /*|| (iter < miniter)*/ ) { + VAR(x0) = VAR(y0) = 0; // Random point next time + } else if ( (iter < miniter) || (inverted && (itermaxRetries-5) { + // VAR(x0) /= 100; + // VAR(y0) /= 100; + //} else + VAR(x0) = VAR(y0) = 0; + } + + if (++retries > maxRetries) + break; + + } while ((inverted && (iter < maxiter)) || (!inverted && ((iter >= maxiter) || ((miniter>0) && (iter < miniter))))); + + smoothed_iter = iter; + if (max_smooth_iter>0) { + // use Normalized Iteration Count Algorithm for smoothing + mag2 = x2 + y2; + if (mag2 > 1.1) //FIXME: change this back to if(mag2>4) ? + smoothed_iter += 1 - log(log(mag2)/2)/M_LN2; + } + if (smoothed_iter>0) + inv_iter = 1/smoothed_iter; + else + inv_iter = 1; + + // Adjust location of point according to sx,sy and final iterated point (x,y) + // (use of inv_iter reduces effect of factor near regions of high gradient + FPx += VVAR*(x1 + VAR(dcm_sx)*x*inv_iter); + FPy += VVAR*(y1 + VAR(dcm_sy)*y*inv_iter); + //FPx += VVAR*(x1 + VAR(dcm_sx)*x); + //FPy += VVAR*(y1 + VAR(dcm_sy)*y); + + // TODO: add check to see whether this Apo supports 3D? + if (VAR(dcm_zscale)) { + FPz += smoothed_iter * VAR(zs); + } + + // Allow plugin to influence coloring (-X- changed for Apo7X/DC) + + if (smoothed_iter<0) smoothed_iter=0; + if (smoothed_iter>maxiter) smoothed_iter=maxiter; + + switch (color_method) { + + case 1: + // scale colormap indexing extent by the final angle of the iterated point + // after the extra "smoothing" iterations complete + xtemp = 0.0; + if (y != 0.0) xtemp = atan2(x,y) * M_1_2PI; + TC = fmod2(xtemp, 1); + break; + case 2: + // scale colormap indexing extent by the angle of the iterated point at time of escape + xtemp = 0.0; + if (yp != 0.0) xtemp = atan2(xp,yp) * M_1_2PI; + TC = fmod2(xtemp, 1); + break; + case 3: + // combination of mode 4 and 2 + xtemp = 0.0; + if (y-yp != 0.0) xtemp = atan2(x-xp,y-yp) * M_1_2PI; + TC = fmod2((smoothed_iter/maxiter * xtemp), 1); + break; + case 4: + // scale colormap indexing extent by the product of the scaled iteration count and + // the angle of the iterated point at time of escape + xtemp = 0.0; + if (yp != 0.0) xtemp = atan2(xp,yp) * M_1_2PI; + TC = fmod2((smoothed_iter/maxiter * xtemp), 1); + break; + case 5: + // scale colormap indexing extent by a combination of scaled iteration count, + // the squared magnitude and adjusted angle of the iterated point at time of escape + xtemp = 0.0; + if (yp != 0.0) xtemp = (0.5 + atan2(xp,yp) * M_1_2PI) * (xp*xp+yp*yp); + TC = fmod2((smoothed_iter/maxiter * xtemp), 1); + break; + case 6: + // scale colormap indexing extent by a combination of scaled iteration count and + // the squared magnitude of the iterated point at time of escape + xtemp = xp*xp+yp*yp; + TC = fmod2((smoothed_iter/maxiter * xtemp), 1); + break; + case 7: + // scale colormap indexing extent by a combination of scaled iteration count and + // the squared magnitude of the iterated point at time of escape + // (slightly more relaxed color rolloff than case 6) + xtemp = sqrt(xp*xp+yp*yp); + TC = fmod2((smoothed_iter/maxiter * xtemp), 1); + break; + case 0: + // default coloring method: scale colormap indexing extent by the scaled "escape time" + // (iteration count) + default: + TC = fmod2(smoothed_iter/maxiter, 1); + break; + } + + return TRUE; +} diff --git a/Plugin/dc_triangle.c b/Plugin/dc_triangle.c new file mode 100644 index 0000000..2e05d02 --- /dev/null +++ b/Plugin/dc_triangle.c @@ -0,0 +1,102 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double dc_triangle_scatter_area, A; + int dc_triangle_zero_edges; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("dc_triangle"); +APO_VARIABLES( + VAR_REAL(dc_triangle_scatter_area, 0.0), + VAR_INTEGER_RANGE(dc_triangle_zero_edges, 0, 1, 0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(A) = VAR(dc_triangle_scatter_area) < -1 ? -1 : + VAR(dc_triangle_scatter_area) > 1 ? 1 : + VAR(dc_triangle_scatter_area); + return TRUE; +} + +/* This function is called during calculation. + You must call the argument "vp" +*/ +int PluginVarCalc(Variation* vp) +{ + // set up triangle + const double + xx = TM(a), xy = TM(b), // X + yx = TM(c) * -1, yy = TM(d) * -1, // Y + ox = TM(e), oy = TM(f), // O + px = FTx - ox, py = FTy - oy; // P + + // calculate dot products + const double dot00 = xx * xx + xy * xy; // X * X + const double dot01 = xx * yx + xy * yy; // X * Y + const double dot02 = xx * px + xy * py; // X * P + const double dot11 = yx * yx + yy * yy; // Y * Y + const double dot12 = yx * px + yy * py; // Y * P + + // calculate barycentric coordinates + const double denom = (dot00 * dot11 - dot01 * dot01); + const double num_u = (dot11 * dot02 - dot01 * dot12); + const double num_v = (dot00 * dot12 - dot01 * dot02); + + // u, v must not be constant + double u = num_u / denom; + double v = num_v / denom; + int inside = 0, f = 1; + + // case A - point escapes edge XY + if (u + v > 1) { f = -1; + if (u > v) { u = u>1?1:u; v = 1-u; } + else { v = v>1?1:v; u = 1-v; } } + + // case B - point escapes either edge OX or OY + else if ((u < 0) || (v < 0)) { + u = u<0?0:u>1?1:u; v = v<0?0:v>1?1:v; } + + // case C - point is in triangle + else inside = 1; + + // handle outside points + if (VAR(dc_triangle_zero_edges) && !inside) u = v = 0; + else if (!inside) { + u = (u + random01() * VAR(A) * f); + v = (v + random01() * VAR(A) * f); + u = u<-1?-1:u>1?1:u; v = v<-1?-1:v>1?1:v; + + if ((u + v > 1) && (VAR(A) > 0)) + if (u > v) { u = u>1?1:u; v = 1-u; } + else { v = v>1?1:v; u = 1-v; } + } + + // set output + FPx += VVAR * (ox + u * xx + v * yx); + FPy += VVAR * (oy + u * xy + v * yy); + FPz += VVAR * FTz; + TC = fmod(fabs(u+v),1.0); + + // done + return TRUE; +} diff --git a/Plugin/dc_ztransl.c b/Plugin/dc_ztransl.c new file mode 100644 index 0000000..058a018 --- /dev/null +++ b/Plugin/dc_ztransl.c @@ -0,0 +1,69 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Written by Georg Kiehne + --> http://xyrus-worx.net, http://xyrus02.deviantart.com + + If you find any bugs / nags - keep them :) +*/ + +typedef struct { + double dc_ztransl_x0; + double dc_ztransl_x1; + double dc_ztransl_factor; + double x0_, x1_, x1_m_x0; + int dc_ztransl_overwrite; + int dc_ztransl_clamp; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("dc_ztransl"); +APO_VARIABLES( + VAR_REAL_RANGE(dc_ztransl_x0, 0.0, 1.0, 0.0), + VAR_REAL_RANGE(dc_ztransl_x1, 0.0, 1.0, 1.0), + VAR_REAL(dc_ztransl_factor, 1.0), + VAR_INTEGER_RANGE(dc_ztransl_overwrite, 0, 1, 1), + VAR_INTEGER_RANGE(dc_ztransl_clamp, 0, 1, 0) +); + +int PluginVarPrepare(Variation* vp) +{ + vp->var.x0_ = vp->var.dc_ztransl_x0 < vp->var.dc_ztransl_x1 ? vp->var.dc_ztransl_x0 : vp->var.dc_ztransl_x1; + vp->var.x1_ = vp->var.dc_ztransl_x0 > vp->var.dc_ztransl_x1 ? vp->var.dc_ztransl_x0 : vp->var.dc_ztransl_x1; + vp->var.x1_m_x0 = vp->var.x1_ - vp->var.x0_ == 0 ? EPS : vp->var.x1_ - vp->var.x0_; + + return 1; +} + +inline double flip(double a, double b, double c){return (c*(b-a)+a);} + +int PluginVarCalc(Variation* vp) +{ + double zf = vp->var.dc_ztransl_factor * (*(vp->pColor) - vp->var.x0_) / vp->var.x1_m_x0; + if (vp->var.dc_ztransl_clamp != 0) + zf = zf < 0 ? 0 : zf > 1 ? 1 : zf; + + *(vp->pFPx) += vp->vvar*(*(vp->pFTx)); + *(vp->pFPy) += vp->vvar*(*(vp->pFTy)); + + if (vp->var.dc_ztransl_overwrite == 0) + *(vp->pFPz) += vp->vvar*(*(vp->pFTz))*zf; + else *(vp->pFPz) += vp->vvar*zf; + + return 1; +} diff --git a/Plugin/deltaA.c b/Plugin/deltaA.c new file mode 100644 index 0000000..eee50d1 --- /dev/null +++ b/Plugin/deltaA.c @@ -0,0 +1,57 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double v; + +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("deltaA"); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(v) = 0.5 * VVAR / M_PI; + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double avgr, avga; + double s, c; + + avgr = VVAR * (sqrt(sqr(FTy) + sqr(FTx + 1.0)) / sqrt(sqr(FTy) + sqr(FTx - 1.0))); + avga = (atan2( FTy, FTx - 1.0) - atan2(FTy, FTx + 1.0) )/ 2.0; + fsincos( avga, &s, &c); + + FPx += avgr * c; + FPy += avgr * s; + + + + return TRUE; +} diff --git a/Plugin/edisc.c b/Plugin/edisc.c new file mode 100644 index 0000000..98799ef --- /dev/null +++ b/Plugin/edisc.c @@ -0,0 +1,64 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double edisc_vvar; +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("edisc"); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(edisc_vvar) = VVAR / 11.57034632; + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double tmp = FTy * FTy + FTx * FTx + 1.0; + double tmp2 = 2.0 * FTx; + double r1 = sqrt(tmp + tmp2); + double r2 = sqrt(tmp - tmp2); + double xmax = (r1 + r2) * 0.5; + double snv, csv, snhu, cshu; + double expu, expuinv; + + fsincos(log(xmax + sqrt(xmax - 1.0)), &snv, &csv); + sinhcosh(-acos(FTx / xmax), &snhu, &cshu); + + if (FTy > 0.0) + snv = -snv; + + FPx += VAR(edisc_vvar) * cshu * csv; + FPy += VAR(edisc_vvar) * snhu * snv; + + return TRUE; +} diff --git a/Plugin/ex.c b/Plugin/ex.c new file mode 100644 index 0000000..36c83a8 --- /dev/null +++ b/Plugin/ex.c @@ -0,0 +1,53 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#include "apoplugin.h" + +/* SET PLUGIN NAME HERE: + e.g. name-me +*/ +APO_PLUGIN("ex"); + +/* DO PREPARE STUFF HERE: + You must call the argument "vp" +*/ +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +/* DO CALC STUFF HERE: + You must call the argument "vp" +*/ +int PluginVarCalc(Variation* vp) +{ + double FAngle = atan2(FTy, FTx); + double r = sqrt(FTx*FTx+FTy*FTy); + double n0 = sin(FAngle + r); + double n1 = cos(FAngle - r); + double m0 = sqr(n0) * n0; + double m1 = sqr(n1) * n1; + + r = r * VVAR; + FPx = FPx + r * (m0 + m1); + FPy = FPy + r * (m0 - m1); + + return TRUE; +} diff --git a/Plugin/expo.c b/Plugin/expo.c new file mode 100644 index 0000000..2058f85 --- /dev/null +++ b/Plugin/expo.c @@ -0,0 +1,92 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + // expo_real represents the real part of the base (a) + double expo_real; + // expo_imaginary represents the imaginary part of the base (b) + double expo_imaginary; + double expo_k; + double expo_t; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("expo"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(expo_real, -1.0), + VAR_REAL(expo_imaginary, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + double ereal = VAR(expo_real); + double eimag = VAR(expo_imaginary); + VAR(expo_k) = 0.5 * log(ereal * ereal + eimag * eimag + 1e-300); + VAR(expo_t) = atan2(eimag,ereal); + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double expor = exp(FTx * VAR(expo_k) - FTy * VAR(expo_t)); + double snv, csv; + + fsincos(FTx * VAR(expo_t) + FTy * VAR(expo_k), &snv, &csv); + + FPx += VVAR * expor * csv; + FPy += VVAR * expor * snv; + + return TRUE; +} + +// Given the equation (a + ib)^z, or c^z, where c = a + ib... +// We can rewrite it as e^(ln(c^z))... +// Using the laws of Logs, we get e^(z * ln(c))... + +// The ln of a complex number is ln(r) + itheta, where +// r is the radius and theta is the angle. Thus, we need +// the radius and angle of our base number c. + +// k is what I've used to represent the radius of the number +// c, or a + ib. t is used to represent the angle. +// Thus, expok is the radius of c and expot is the angle. + +// Now we have e^(z * (ln(k) + it)), or e^((x + iy) * (ln(k) + it)) +// Simplifying this down, we get... + +// e^(xln(k) - yt) * e^i(xt + yln(k)) + +// Because a Complex Number can be presented as +// r * e^itheta, where r is the radius and theta is the angle, +// We can say that r' = e^(xln(k) - yt) +// And that theta' = xt + yln(k) + +// For optimization (as recommended by Joel) we calculate k, +// the radius of our complex number, as the ln of k, +// because we never need k to be on its own (it is always +// logged before it is used). + +// That's the equation! diff --git a/Plugin/extrude.c b/Plugin/extrude.c new file mode 100644 index 0000000..e3a9828 --- /dev/null +++ b/Plugin/extrude.c @@ -0,0 +1,38 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct { + double extrude_root_face; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("extrude"); +APO_VARIABLES( + VAR_REAL(extrude_root_face, 0.5) +); + +int PluginVarPrepare(Variation* vp) { return TRUE; } + +int PluginVarCalc(Variation* vp) +{ + if ((((rand() ^ (rand()<<15)) & 0xfffffff) / (double) 0xfffffff) < vp->var.extrude_root_face) + FPz = (vp->vvar<0?0:vp->vvar); + else FPz = vp->vvar * (((rand() ^ (rand()<<15)) & 0xfffffff) / (double) 0xfffffff); + return TRUE; +} diff --git a/Plugin/fdisc.c b/Plugin/fdisc.c new file mode 100644 index 0000000..18ae29f --- /dev/null +++ b/Plugin/fdisc.c @@ -0,0 +1,48 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("fdisc"); + + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + + double c, s; + double a = M_2PI /(sqrt(sqr(FTx) + sqr(FTy)) + 1.0); + double r = (atan2(FTy, FTx) * M_1_PI + 1.0) * 0.5; + + fsincos( a, &s, &c); + + FPx += VVAR * r * c; + FPy += VVAR * r * s; + + return TRUE; +} diff --git a/Plugin/fibonacci.c b/Plugin/fibonacci.c new file mode 100644 index 0000000..eceee7d --- /dev/null +++ b/Plugin/fibonacci.c @@ -0,0 +1,81 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double ffive; + double fnatlog; +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("fibonacci"); + + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Updated to use the new constants. Still calculates + // invserse of root five and the nat log of the Golden Ratio. + // I'm not sure how many decimal places were appropriate, + // or how many C allows, and this isn't going to take + // up any noticeable amount of time. + VAR(ffive) = 1/M_SQRT5; + VAR(fnatlog) = log(M_PHI); + // Always return TRUE. + return TRUE; +} + +// p^z - (-p)^(-z) +// z' = ----------------- +// sqrt(5) +// +// Where p is the Golden Ratio. +// This function generates the fibonacci sequence +// for real integer values. +// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 < Real Value +// 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 < Fib Value +// +// Negative real integers produce the negative fibonacci sequence, +// which is the same as the normal one, except every +// other number is negative. +// 1 0 -1 -2 -3 -4 -5 -6 -7 -8 < Real Value +// 1 0 1 -1 3 -3 5 -8 13 -21 < Fib Value + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + + double snum1, cnum1, snum2, cnum2; + + fsincos(FTy * VAR(fnatlog), &snum1, &cnum1); + fsincos((FTx * M_PI + FTy * VAR(fnatlog)) * -1, &snum2, &cnum2); + + double eradius1 = exp(FTx * VAR(fnatlog)); + double eradius2 = exp((FTx * VAR(fnatlog) - FTy * M_PI) * -1); + + FPx += VVAR * (eradius1 * cnum1 - eradius2 * cnum2) * VAR(ffive); + FPy += VVAR * (eradius1 * snum1 - eradius2 * snum2) * VAR(ffive); + + return TRUE; +} + diff --git a/Plugin/fisheye.c b/Plugin/fisheye.c new file mode 100644 index 0000000..47436f5 --- /dev/null +++ b/Plugin/fisheye.c @@ -0,0 +1,45 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#include "apoplugin.h" + +/* SET PLUGIN NAME HERE: + e.g. name-me +*/ +APO_PLUGIN("fisheye"); + +/* DO PREPARE STUFF HERE: + You must call the argument "vp" +*/ +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +/* DO CALC STUFF HERE: + You must call the argument "vp" +*/ +int PluginVarCalc(Variation* vp) +{ + double r = 2 * VVAR / (sqrt(FTx * FTx + FTy * FTy) + 1); + FPx = FPx + r * FTy; + FPy = FPy + r * FTx; + return TRUE; +} diff --git a/Plugin/flux.c b/Plugin/flux.c new file mode 100644 index 0000000..114c913 --- /dev/null +++ b/Plugin/flux.c @@ -0,0 +1,81 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + 09-10-04 - Optimized by Xyrus02 +*/ + +typedef struct +{ + //double v; + double spr; + double flux_spread; + +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("flux"); + +APO_VARIABLES( + VAR_REAL(flux_spread, 0.0), +); + +int PluginVarPrepare(Variation* vp) +{ + // Why is this calculated? It isn't used... + //VAR(v) = 0.5 * VVAR / M_PI; + + // But we only use 2 + VAR(flux_spread) so we can precalculate that :-) + VAR(spr) = 2 + VAR(flux_spread); + + // We succeeded :-) + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double avgr, avga; + double s, c; + + // Avoid reduant calculations by precalculating everything what is used at least twice + double x = FTx, + y = FTy; + double xpv = FTx + VVAR, + xmv = FTx - VVAR; + double y2 = sqr(y); + + // We have a division by zero problem in the original flux + // (What if y + (x-vvar) == 0 ????) + double frac = sqrt(y2 + sqr(xmv)); + if (frac == 0) frac = 1.0; + + // This is a huge shitload of calculations :O + avgr = VVAR * (VAR(spr) * sqrt(sqrt(y2 + sqr(xpv) ) / frac)); + avga = (atan2(y , xmv) - atan2(y , xpv)) / 2.0; + fsincos(avga, &s, &c); + + FPx += avgr * c; + FPy += avgr * s; + + // Add 3D compatibility + FPz += FTz; + + // Report success! + return TRUE; +} diff --git a/Plugin/gdoffs.c b/Plugin/gdoffs.c new file mode 100644 index 0000000..940aaeb --- /dev/null +++ b/Plugin/gdoffs.c @@ -0,0 +1,99 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Written by Georg Kiehne + --> http://xyrus-worx.net, http://xyrus02.deviantart.com + + If you find any bugs / nags - keep them :) +*/ + +typedef struct { + double gdoffs_delta_x, gdoffs_delta_y; + double gdoffs_area_x, gdoffs_area_y; + double gdoffs_center_x, gdoffs_center_y; + int gdoffs_gamma, gdoffs_square; + + double gdodx, gdoax, gdocx; + double gdody, gdoay, gdocy; + double gdob; + int gdog, gdos; +} Variables; + +#include "apoplugin.h" + +// Fine tune stuff, try not to touch :) +const double __agdod = 0.1; +const double __agdoa = 2.0; +const double __agdoc = 1.0; + +APO_PLUGIN("gdoffs"); +APO_VARIABLES( + VAR_REAL_RANGE(gdoffs_delta_x, 0.0, 16.0, 0.0), + VAR_REAL_RANGE(gdoffs_delta_y, 0.0, 16.0, 0.0), + VAR_REAL(gdoffs_area_x, 2.0), + VAR_REAL(gdoffs_area_y, 2.0), + VAR_REAL(gdoffs_center_x, 0.0), + VAR_REAL(gdoffs_center_y, 0.0), + VAR_INTEGER_RANGE(gdoffs_gamma, 1, 6, 1), + VAR_INTEGER_RANGE(gdoffs_square, 0, 1, 0) +); + +int PluginVarPrepare(Variation* vp) +{ + vp->var.gdodx = (vp->var.gdoffs_delta_x) * __agdod; + vp->var.gdody = (vp->var.gdoffs_delta_y) * __agdod; + + vp->var.gdoax = ((fabs(vp->var.gdoffs_area_x) < 0.1) ? 0.1 : fabs(vp->var.gdoffs_area_x)) * __agdoa; + vp->var.gdoay = ((fabs(vp->var.gdoffs_area_y) < 0.1) ? 0.1 : fabs(vp->var.gdoffs_area_y)) * __agdoa; + + vp->var.gdocx = (vp->var.gdoffs_center_x) * __agdoc; + vp->var.gdocy = (vp->var.gdoffs_center_y) * __agdoc; + + vp->var.gdog = (vp->var.gdoffs_gamma); + vp->var.gdos = (vp->var.gdoffs_square); + + vp->var.gdob = (double)(vp->var.gdog) * __agdoa / (MAX(vp->var.gdoax, vp->var.gdoay)); + + return 1; +} + +inline double fcip(double a){return ((a<0)?-((int)(fabs(a))+1):0)+((a>1)?((int)(a)):0);} +inline double fclp(double a){return ((a<0)?-(fmod(fabs(a),1)):fmod(fabs(a),1));} +inline double fscl(double a){return fclp((a+1)/2); } +inline double fosc(double p, double a){return fscl(-1*cos(p*a*M_2PI));} +inline double flip(double a, double b, double c){return (c*(b-a)+a);} + +int PluginVarCalc(Variation* vp) +{ + double osc_x=fosc(vp->var.gdodx,1),osc_y=fosc(vp->var.gdody,1); + double in_x=(*(vp->pFTx)+vp->var.gdocx),in_y=(*(vp->pFTy)+vp->var.gdocy); + double out_x=0,out_y=0; + + if ((vp->var.gdos) != 0) { + out_x = flip(flip(in_x,fosc(in_x,4),osc_x),fosc(fclp(vp->var.gdob*in_x),4),osc_x); + out_y = flip(flip(in_y,fosc(in_y,4),osc_x),fosc(fclp(vp->var.gdob*in_y),4),osc_x); + } else { + out_x = flip(flip(in_x,fosc(in_x,4),osc_x),fosc(fclp(vp->var.gdob *in_x),4),osc_x); + out_y = flip(flip(in_y,fosc(in_y,4),osc_y),fosc(fclp(vp->var.gdob *in_y),4),osc_y); + } + + *(vp->pFPx) = vp->vvar*out_x; + *(vp->pFPy) = vp->vvar*out_y; + *(vp->pFPz) = vp->vvar*(*(vp->pFTz)); + + return 1; +} diff --git a/Plugin/glynnia.c b/Plugin/glynnia.c new file mode 100644 index 0000000..72a1ca9 --- /dev/null +++ b/Plugin/glynnia.c @@ -0,0 +1,87 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double vvar2; +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("glynnia"); + + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(vvar2) = VVAR * sqrt(2.0) / 2.0; + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double r = sqrt(sqr(FTx) + sqr(FTy)); + double d; + + + if( r > 1.0) + { + if( random01() > 0.5) + { + d = sqrt(r + FTx); + FPx += VAR(vvar2) * d; + FPy -= VAR(vvar2) / d * FTy; //+= VAR(vvar2) / d * FTy; + } + else + { + d = r + FTx; + r = VVAR / sqrt(r * ( sqr(FTy) + sqr(d))); + FPx += r * d; + FPy += r * FTy; //-= r * FTy; + } + } + else + { + if( random01() > 0.5) + { + d = sqrt(r + FTx); + FPx -= VAR(vvar2) * d; + FPy -= VAR(vvar2) / d * FTy; + } + else + { + d = r + FTx; + r = VVAR / sqrt(r * ( sqr(FTy) + sqr(d))); + FPx -= r * d; + FPy += r * FTy; + } + } + + + + return TRUE; +} diff --git a/Plugin/gridout.c b/Plugin/gridout.c new file mode 100644 index 0000000..8ac8eea --- /dev/null +++ b/Plugin/gridout.c @@ -0,0 +1,108 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2008 Michael Faber + Copyright (C) 2007-2008 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("gridout"); + +inline double rint(double x) +{ + int temp; temp = (x >= 0. ? (int)(x + 0.5) : (int)(x - 0.5)); + return (double)temp; +} + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double x = rint(FTx); + double y = rint(FTy); + + if (y <= 0.0) + { + if (x > 0.0) + { + if (-y >= x) + { + FPx += VVAR * (FTx + 1.0); + FPy += VVAR * FTy; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy + 1.0); + } + } + else + { + if (y <= x) + { + FPx += VVAR * (FTx + 1.0); + FPy += VVAR * FTy; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy - 1.0); + } + } + } + else + { + if (x > 0.0) + { + if (y >= x) + { + FPx += VVAR * (FTx - 1.0); + FPy += VVAR * FTy; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy + 1.0); + } + } + else + { + if (y > -x) + { + FPx += VVAR * (FTx - 1.0); + FPy += VVAR * FTy; + } + else + { + FPx += VVAR * FTx; + FPy += VVAR * (FTy - 1.0); + } + } + } + + return TRUE; +} diff --git a/Plugin/handkerchief.c b/Plugin/handkerchief.c new file mode 100644 index 0000000..92b1f11 --- /dev/null +++ b/Plugin/handkerchief.c @@ -0,0 +1,47 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#include "apoplugin.h" + +/* SET PLUGIN NAME HERE: + e.g. name-me +*/ +APO_PLUGIN("handkerchief"); + +/* DO PREPARE STUFF HERE: + You must call the argument "vp" +*/ +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +/* DO CALC STUFF HERE: + You must call the argument "vp" +*/ +int PluginVarCalc(Variation* vp) +{ + double r = sqrt(FTx*FTx + FTy*FTy); + double FAngle = atan2(FTy, FTx); + FPx = FPx + VVAR * sin(FAngle + r) * r; + FPy = FPy + VVAR * cos(FAngle - r) * r; + + return TRUE; +} diff --git a/Plugin/hexes.c b/Plugin/hexes.c new file mode 100644 index 0000000..489bedf --- /dev/null +++ b/Plugin/hexes.c @@ -0,0 +1,289 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// "Hexes" variation breaks plane into hexagonal cells and applies same +// power, scaling, rotation. + +// voronoi is additional, not required in all Apophysis plugins +#define VORONOI_MAXPOINTS 25 + +double vratio( double P[2], double Q[2], double U[2] ); +int closest( double P[VORONOI_MAXPOINTS][2], int n, double U[2] ); +double voronoi( double P[VORONOI_MAXPOINTS][2], int n, int q, double U[2] ); + +// Cheap and cheerful vector definitions for 3D :-) +// They just make reading vector code based on arrays +// slightly nicer for me! E.g. use V[_x_] instead of V[0]. + +#define _x_ 0 +#define _y_ 1 +#define _z_ 2 + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double hexes_cellsize; + double hexes_power; + double hexes_rotate; + double hexes_scale; + // P is a working list of points + double P[VORONOI_MAXPOINTS][2]; + + double rotSin; + double rotCos; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("hexes"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(hexes_cellsize, 1.0), + VAR_REAL(hexes_power, 1.0), + VAR_REAL(hexes_rotate, 0.166), + VAR_REAL(hexes_scale, 1.0) +); + +// Following are pre-calculated fixed multipliers for converting +// between "Hex" co-ordinates and "Original" co-ordinates. + +// Xh = (Xo + sqrt(3) * Yo) / (3 * l) +static const double AXhXo = 1.0/3.0; +static const double AXhYo = 1.7320508075688772935/3.0; +// Now: Xh = ( AXhXo * Xo + AXhYo * Yo ) / l; + +// Yh = (-Xo + sqrt(3) * Yo) / (3 * l) +static const double AYhXo = -1.0/3.0; +static const double AYhYo = 1.7320508075688772935/3.0; +// Now: Yh = ( AYhXo * Xo + AYhYo * Yo ) / l; + +// Xo = 3/2 * l * (Xh - Yh) +static const double AXoXh = 1.5; +static const double AXoYh = -1.5; +// Now: Xo = ( AXoXh * Xh + AXoYh * Yh ) * l; + +// Yo = sqrt(3)/2 * l * (Xh + Yh) +static const double AYoXh = 1.7320508075688772935/2.0; +static const double AYoYh = 1.7320508075688772935/2.0; +// Now: Yo = ( AYoXh * Xh + AYoYh * Yh ) * l; + +double vratio( double P[2], double Q[2], double U[2] ) { + double PmQx, PmQy; + + PmQx = P[_x_] - Q[_x_]; + PmQy = P[_y_] - Q[_y_]; + + if ( 0.0 == PmQx && 0.0 == PmQy ) { + return 1.0; + } + + return 2.0 * ( ( U[_x_] - Q[_x_] ) * PmQx + ( U[_y_] - Q[_y_] ) * PmQy ) / ( PmQx * PmQx + PmQy * PmQy ); +} + +// Closest point to U from array P. +// P is an array of points +// n is number of points to check +// U is location to find closest +int closest( double P[VORONOI_MAXPOINTS][2], int n, double U[2] ) { + double d2; + double d2min = 1.0e100; + int i, j; + + for( i = 0; i < n; i++ ) { + d2 = (P[i][_x_] - U[_x_]) * (P[i][_x_] - U[_x_]) + (P[i][_y_] - U[_y_]) * (P[i][_y_] - U[_y_]); + if ( d2 < d2min ) { + d2min = d2; + j = i; + } + } + + return j; +} + +// Voronoi "value" is 0.0 (centre) to 1.0 (edge) if inside cell . . . higher values +// mean that point is not in the cell defined by chosen centre. +// P is an array of points defining cell centres +// n is number of points in array +// q is chosen centre to measure distance from +// U is point to test +double voronoi( double P[VORONOI_MAXPOINTS][2], int n, int q, double U[2] ) { + double ratio; + double ratiomax = -1.0e100; + int i; + + for( i = 0; i < n; i++ ) { + if ( i != q ) { + ratio = vratio( P[i], P[q], U ); + if ( ratio > ratiomax ) { + ratiomax = ratio; + } + } + } + + return ratiomax; +} + + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Pre-calculate rotation matrix, to save time later . . . + VAR(rotSin) = sin( VAR(hexes_rotate) * 2 * M_PI ); + VAR(rotCos) = cos( VAR(hexes_rotate) * 2 * M_PI ); + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double XCh, YCh, XCo, YCo, DXo, DYo, L, L1, L2, R, R1, R2, s, trgL, Vx, Vy; + double U[2]; + + // For speed/convenience + s = VAR(hexes_cellsize); + + // Infinite number of small cells? No effect . . . + if ( 0.0 == s ) { + return TRUE; + } + + // Get co-ordinates, and convert to hex co-ordinates + U[_x_] = FTx; + U[_y_] = FTy; + + XCh = floor( ( AXhXo * U[_x_] + AXhYo * U[_y_] ) / s ); + YCh = floor( ( AYhXo * U[_x_] + AYhYo * U[_y_] ) / s ); + + // Get a set of 4 hex centre points, based around the one above + int i = 0; + double di, dj; + for (di = XCh; di < XCh + 1.1; di += 1.0) { + for (dj = YCh; dj < YCh + 1.1; dj += 1.0) { + VAR(P)[i][_x_] = (AXoXh * di + AXoYh * dj ) * s; + VAR(P)[i][_y_] = (AYoXh * di + AYoYh * dj ) * s; + i++; + } + } + + int q = closest( VAR(P), 4, U ); + + double offset[4][2] = { { 0.0, 0.0}, { 0.0, 1.0}, + { 1.0, 0.0}, { 1.0, 1.0} + }; + + // Remake list starting from chosen hex, ensure it is completely surrounded (total 7 points) + + // First adjust centres according to which one was found to be closest + XCh += offset[q][_x_]; + YCh += offset[q][_y_]; + + // First point is central/closest + + XCo = (AXoXh * XCh + AXoYh * YCh ) * s; + YCo = (AYoXh * XCh + AYoYh * YCh ) * s; + VAR(P)[0][_x_] = XCo; + VAR(P)[0][_y_] = YCo; + + // Next six points are based on hex graph (6 hexes around centre). As long as + // centre points are not too distorted from simple hex, this defines all possible edges + + // In hex co-ords, offsets are: (0,1) (1,1) (1,0) (0,-1) (-1,-1) (-1, 0) + VAR(P)[1][_x_] = XCo + ( AXoYh ) * s; + VAR(P)[1][_y_] = YCo + ( AYoYh ) * s; + + VAR(P)[2][_x_] = XCo + ( AXoXh + AXoYh ) * s; + VAR(P)[2][_y_] = YCo + ( AYoXh + AYoYh ) * s; + + VAR(P)[3][_x_] = XCo + ( AXoXh ) * s; + VAR(P)[3][_y_] = YCo + ( AYoXh ) * s; + + VAR(P)[4][_x_] = XCo - AXoYh * s; + VAR(P)[4][_y_] = YCo - AYoYh * s; + + VAR(P)[5][_x_] = XCo - ( AXoXh + AXoYh ) * s; + VAR(P)[5][_y_] = YCo - ( AYoXh + AYoYh ) * s; + + VAR(P)[6][_x_] = XCo - AXoXh * s; + VAR(P)[6][_y_] = YCo - AYoXh * s; + + L1 = voronoi( VAR(P), 7, 0, U ); + + // Delta vector from centre of hex + DXo = U[_x_] - VAR(P)[0][_x_]; + DYo = U[_y_] - VAR(P)[0][_y_]; + + ///////////////////////////////////////////////////////////////// + // Apply "interesting bit" to cell's DXo and DYo co-ordinates + + // trgL is the defined value of l, independent of any rotation + trgL = pow( L1 + 1e-100, VAR(hexes_power) ) * VAR(hexes_scale); + + // Rotate + Vx = DXo * VAR(rotCos) + DYo * VAR(rotSin); + Vy = -DXo * VAR(rotSin) + DYo * VAR(rotCos); + + ////////////////////////////////////////////////////////////////// + // Measure voronoi distance again + + U[_x_] = Vx + VAR(P)[0][_x_]; + U[_y_] = Vy + VAR(P)[0][_y_]; + L2 = voronoi( VAR(P), 7, 0, U ); + + ////////////////////////////////////////////////////////////////// + // Scale to meet target size . . . adjust according to how close + // we are to the edge + + // Code here attempts to remove the "rosette" effect caused by + // scaling between + + // L is maximum of L1 or L2 . . . + // When L = 0.8 or higher . . . match trgL/L2 exactly + // When L = 0.5 or less . . . match trgL/L1 exactly + + R1 = trgL / ( L1 + 1e-100 ); + R2 = trgL / ( L2 + 1e-100 ); + + L = ( L1 > L2 ) ? L1 : L2; + + if ( L < 0.5 ) { + R = trgL / L1; + } else { + if ( L > 0.8 ) { + R = trgL / L2; + } else { + R = ( ( trgL / L1 ) * ( 0.8 - L ) + ( trgL / L2 ) * ( L - 0.5 ) ) / 0.3; + } + } + + Vx *= R; + Vy *= R; + + // Add cell centre co-ordinates back in + Vx += VAR(P)[0][_x_]; + Vy += VAR(P)[0][_y_]; + + // Finally add values in + FPx += VVAR * Vx; + FPy += VVAR * Vy; + + return TRUE; +} diff --git a/Plugin/hole.c b/Plugin/hole.c new file mode 100644 index 0000000..289c99a --- /dev/null +++ b/Plugin/hole.c @@ -0,0 +1,114 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double hole_a; + int hole_inside; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("hole"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(hole_a, 1.0), + VAR_INTEGER_RANGE( hole_inside, 0, 1, 0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + +/* double a = atan2(FTy, FTx); + double r = VVAR * sqrt(sqr(FTx) + sqr(FTy) + pow( a/M_PI + 1.0, VAR(hole_a))); + double s, c; + fsincos( a, &s, &c); + + FPx += r * c; + FPy += r * s; + */ + + double a = atan2(FTy, FTx); + double delta = pow( a/M_PI + 1.0, VAR(hole_a)); + double r; + + if(VAR(hole_inside)) + { + r = VVAR * delta / ( sqrt(sqr(FTx) + sqr(FTy)) + delta ); + } + else + { + r = VVAR * sqrt(sqr(FTx) + sqr(FTy)) + delta ; + } + double s, c; + fsincos( a, &s, &c); + + FPx += r * c; + FPy += r * s; + + +/* heart 2 + double a = atan2(FTy, FTx); + double r = VVAR * sqrt(sqr(FTx) + sqr(FTy) + sqr(a) + 0.0 ); + double s, c; + fsincos( a, &s, &c); + + FPx += r * c; + FPy += r * s; + + + double a = atan2(FTy, FTx); + double r = VVAR * sqrt(sqr(FTx) + sqr(FTy) + fabs(tan(a)) ); + double s, c; + fsincos( a, &s, &c); + + FPx += r * c; + FPy += r * s; + + +/* heart + double a = atan2(FTy, FTx); + double r = VVAR * sqrt(sqr(FTx) + sqr(FTy) + sin(a) + 1.0 ); + double s, c; + fsincos( a, &s, &c); + + FPx += r * c; + FPy += r * s; +*/ +/* two hole + double a = atan2(FTy, FTx); + double r = VVAR * sqrt(sqr(FTx) + sqr(FTy) + sin(2.0 * a) + 1.0 ); + double s, c; + fsincos( a, &s, &c); + + FPx += r * c; + FPy += r * s; +*/ + return TRUE; +} diff --git a/Plugin/hypertile.c b/Plugin/hypertile.c new file mode 100644 index 0000000..0232fa0 --- /dev/null +++ b/Plugin/hypertile.c @@ -0,0 +1,79 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + int hypertile_p, hypertile_q, hypertile_n; + + double re, im; + +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("hypertile"); + + +// Define the Variables +APO_VARIABLES( + VAR_INTEGER_RANGE(hypertile_p, 3, 0x7fffffff, 3), + VAR_INTEGER_RANGE(hypertile_q, 3, 0x7fffffff, 7), + VAR_INTEGER(hypertile_n, 0), +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + double pa = 2*M_PI / VAR(hypertile_p), + qa = 2*M_PI / VAR(hypertile_q); + + double r = (1 - cos(pa)) / (cos(pa) + cos(qa)) + 1; + + if (r > 0) + r = 1 / sqrt(r); + else + r = 1; + + double a = VAR(hypertile_n) * pa; + + VAR(re) = r * cos(a); + VAR(im) = r * sin(a); + + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double a = FTx + VAR(re), + b = FTy - VAR(im); + + double c = VAR(re)*FTx - VAR(im)*FTy + 1, + d = VAR(re)*FTy + VAR(im)*FTx; + + double vr = VVAR / (sqr(c) + sqr(d)); + + FPx += vr * (a*c + b*d); + FPy += vr * (b*c - a*d); + + return TRUE; +} diff --git a/Plugin/idisc.c b/Plugin/idisc.c new file mode 100644 index 0000000..99e018f --- /dev/null +++ b/Plugin/idisc.c @@ -0,0 +1,55 @@ +/* + Apophysis Plugin + + Copyright (C) 2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double v; +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("idisc"); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(v) = VVAR * M_1_PI; + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double c, s; + double a = M_PI /(sqrt(sqr(FTx) + sqr(FTy)) + 1.0); + double r = atan2(FTy, FTx) * VAR(v); + + fsincos(a, &s, &c); + + FPx += r * c; + FPy += r * s; + + return TRUE; +} diff --git a/Plugin/julian2.c b/Plugin/julian2.c new file mode 100644 index 0000000..7af00e4 --- /dev/null +++ b/Plugin/julian2.c @@ -0,0 +1,74 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double julian2_a; + double julian2_b; + double julian2_c; + double julian2_d; + double julian2_e; + double julian2_f; + + int julian2_power; + double julian2_dist; + + int absN; + double cN; + double vvar2; + +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("julian2"); + +APO_VARIABLES( + VAR_INTEGER_NONZERO(julian2_power, 2), + VAR_REAL(julian2_dist, 1.0), + VAR_REAL(julian2_a, 1.0), + VAR_REAL(julian2_b, 0.0), + VAR_REAL(julian2_c, 0.0), + VAR_REAL(julian2_d, 1.0), + VAR_REAL(julian2_e, 0.0), + VAR_REAL(julian2_f, 0.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(absN) = (int)abs(VAR(julian2_power)); + VAR(cN) = VAR(julian2_dist) / VAR(julian2_power) / 2; + + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double x = VAR(julian2_a) * FTx + VAR(julian2_b) * FTy + VAR(julian2_e); + double y = VAR(julian2_c) * FTx + VAR(julian2_d) * FTy + VAR(julian2_f); + double sina = 0.0, cosa = 0.0; + + double angle = (atan2(y, x) + M_2PI * (rand() % (int)VAR(absN)))/ VAR(julian2_power); + double r = VVAR * pow(sqr(x) + sqr(y), VAR(cN)); + + fsincos(angle, &sina, &cosa); + FPx += r * cosa; + FPy += r * sina; + return TRUE; +} diff --git a/Plugin/juliaq.c b/Plugin/juliaq.c new file mode 100644 index 0000000..a688295 --- /dev/null +++ b/Plugin/juliaq.c @@ -0,0 +1,63 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + int juliaq_power, juliaq_divisor; + + double half_inv_power; + double inv_power, inv_power_2pi; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("juliaq"); + + +// Define the Variables +APO_VARIABLES( + VAR_INTEGER_NONZERO(juliaq_power, 3), + VAR_INTEGER_NONZERO(juliaq_divisor, 2), +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(half_inv_power) = 0.5 * VAR(juliaq_divisor) / (double)VAR(juliaq_power); + + VAR(inv_power) = VAR(juliaq_divisor) / (double)VAR(juliaq_power); + VAR(inv_power_2pi) = M_2PI / (double)VAR(juliaq_power); + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double sina, cosa; + fsincos( atan2(FTy, FTx)*VAR(inv_power) + rand()*VAR(inv_power_2pi), + &sina, &cosa); + double r = VVAR * pow(sqr(FTx) + sqr(FTy), VAR(half_inv_power)); + FPx += r * cosa; + FPy += r * sina; + + return TRUE; +} diff --git a/Plugin/modulus.c b/Plugin/modulus.c new file mode 100644 index 0000000..72ade0e --- /dev/null +++ b/Plugin/modulus.c @@ -0,0 +1,81 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double modulus_x; + double modulus_y; + + double xrange; + double yrange; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("modulus"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(modulus_x, 1.0), + VAR_REAL(modulus_y, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(xrange) = 2.0 * VAR(modulus_x); + VAR(yrange) = 2.0 * VAR(modulus_y); + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + if (FTx > VAR(modulus_x)) + { + FPx += VVAR * (-VAR(modulus_x) + fmod(FTx + VAR(modulus_x), VAR(xrange))); + } + else if (FTx < -VAR(modulus_x)) + { + FPx += VVAR * (VAR(modulus_x) - fmod(VAR(modulus_x) - FTx, VAR(xrange))); + } + else + { + FPx += VVAR * FTx; + } + + if (FTy > VAR(modulus_y)) + { + FPy += VVAR * (-VAR(modulus_y) + fmod(FTy + VAR(modulus_y), VAR(yrange))); + } + else if (FTy < -VAR(modulus_y)) + { + FPy += VVAR * (VAR(modulus_y) - fmod(VAR(modulus_y) - FTy, VAR(yrange))); + } + else + { + FPy += VVAR * FTy; + } + + return TRUE; +} + diff --git a/Plugin/murl.c b/Plugin/murl.c new file mode 100644 index 0000000..eeba03c --- /dev/null +++ b/Plugin/murl.c @@ -0,0 +1,71 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double murl_c; + int murl_power; + + double c, p2, vp; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("murl"); + + +// Define the Variables +APO_VARIABLES( + VAR_REAL(murl_c, 0.0), + VAR_INTEGER_RANGE(murl_power, 2, 0x7fffffff, 2), +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + if (VAR(murl_power) != 1) + VAR(c) = VAR(murl_c) / (VAR(murl_power) - 1); + else + VAR(c) = VAR(murl_c); + + VAR(p2) = VAR(murl_power) / 2.0; + VAR(vp) = VVAR * (VAR(c) + 1); + + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double sina, cosa; + fsincos(atan2(FTy, FTx) * VAR(murl_power), &sina, &cosa); + double r = VAR(c) * pow(sqr(FTx) + sqr(FTy), VAR(p2)); + + double re = r * cosa + 1; + double im = r * sina; + + double r1 = VAR(vp) / (sqr(re) + sqr(im)); + + FPx += r1 * (FTx*re + FTy*im); + FPy += r1 * (FTy*re - FTx*im); + + return TRUE; +} diff --git a/Plugin/murl2.c b/Plugin/murl2.c new file mode 100644 index 0000000..49844bf --- /dev/null +++ b/Plugin/murl2.c @@ -0,0 +1,75 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double murl2_c; + int murl2_power; + + double p2, invp, invp2, vp; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("murl2"); + + +// Define the Variables +APO_VARIABLES( + VAR_REAL_RANGE(murl2_c, -1.0, 1.0, 0.0), + VAR_INTEGER_NONZERO(murl2_power, 1), +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(p2) = VAR(murl2_power) / 2.0; + VAR(invp) = 1.0 / VAR(murl2_power); // (2/p)/2 + VAR(invp2) = 2.0 / VAR(murl2_power); + + if (VAR(murl2_c) == -1) VAR(vp) = 0; else + VAR(vp) = VVAR * pow(VAR(murl2_c) + 1, 2.0 / VAR(murl2_power)); + + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double sina, cosa; + fsincos(atan2(FTy, FTx) * VAR(murl2_power), &sina, &cosa); + double r = VAR(murl2_c) * pow(sqr(FTx) + sqr(FTy), VAR(p2)); + + double re = r*cosa + 1; + double im = r*sina; + + r = pow(sqr(re) + sqr(im), VAR(invp)); + fsincos(atan2(im, re) * VAR(invp2), &sina, &cosa); + re = r * cosa; + im = r * sina; + + double r1 = VAR(vp) / sqr(r); //(sqr(re) + sqr(im)); + + FPx += r1 * (FTx*re + FTy*im); + FPy += r1 * (FTy*re - FTx*im); + + return TRUE; +} diff --git a/Plugin/npolar.c b/Plugin/npolar.c new file mode 100644 index 0000000..1b2d6a3 --- /dev/null +++ b/Plugin/npolar.c @@ -0,0 +1,65 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double npolar_vvar; + double npolar_vvar_2; + + int npolar_n; + int npolar_nnz; + int npolar_parity; + int npolar_isodd; + + double npolar_cn; + double npolar_absn; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" +APO_PLUGIN("npolar"); +APO_VARIABLES( + VAR_INTEGER(npolar_parity, 0), + VAR_INTEGER(npolar_n, 1) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(npolar_nnz) = (VAR(npolar_n) == 0) ? 1 : VAR(npolar_n); + VAR(npolar_vvar) = VVAR / M_PI; + VAR(npolar_vvar_2) = VAR(npolar_vvar) * 0.5; + VAR(npolar_absn) = abs(VAR(npolar_nnz)); + VAR(npolar_cn) = 1.0 / VAR(npolar_nnz) / 2; + VAR(npolar_isodd) = abs(VAR(npolar_parity)) % 2; + return TRUE; +} +int PluginVarCalc(Variation* vp) +{ + double sina = 0.0, cosa = 0.0; + double x = (VAR(npolar_isodd) != 0) ? FTx : VAR(npolar_vvar) * atan2(FTx, FTy); + double y = (VAR(npolar_isodd) != 0) ? FTy : VAR(npolar_vvar_2) * log(FTx*FTx + FTy*FTy); + double angle = (atan2(y, x) + M_2PI * (rand() % (int)VAR(npolar_absn)))/ VAR(npolar_nnz); + double r = VVAR * pow(sqr(x) + sqr(y), VAR(npolar_cn)) * ((VAR(npolar_isodd) == 0) ? 1.0 : VAR(npolar_parity)); + + fsincos(angle, &sina, &cosa); cosa *= r; sina *= r; + x = (VAR(npolar_isodd) != 0) ? cosa : (VAR(npolar_vvar_2) * log(cosa*cosa + sina*sina)); + y = (VAR(npolar_isodd) != 0) ? sina : (VAR(npolar_vvar) * atan2(cosa, sina)); + FPx += x; FPy += y; + + return TRUE; +} diff --git a/Plugin/octapol.c b/Plugin/octapol.c new file mode 100644 index 0000000..cb84cfc --- /dev/null +++ b/Plugin/octapol.c @@ -0,0 +1,147 @@ +/* + Octapol plugin for Apophysis + Written by Georg K. (http://xyrus02.deviantart.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double x; + double y; +} double2; + +#define DOUBLE2(x,y) { x, y } +#define DENOM_SQRT2 0.707106781 + +typedef struct +{ + double rad, s, t, a; + double ax, ay, bx, by, cx, cy, + dx, dy, ex, ey, fx, fy, + gx, gy, hx, hy, ix, iy, + jx, jy, kx, ky, lx, ly; + + double octapol_polarweight; + double octapol_radius; + double octapol_s; + double octapol_t; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("octapol"); + +APO_VARIABLES( + VAR_REAL(octapol_polarweight, 0.0), + VAR_REAL(octapol_radius, 1.0), + VAR_REAL(octapol_s, 0.5), + VAR_REAL(octapol_t, 0.5) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(s) = fabs(VAR(octapol_s)); + VAR(t) = fabs(VAR(octapol_t)); + VAR(a) = VAR(s) * 0.5 + VAR(t); + + VAR(rad) = DENOM_SQRT2 * VAR(s) * fabs(VAR(octapol_radius)); + + VAR(ax) = -0.5 * VAR(s); VAR(ay) = 0.5 * VAR(s) + VAR(t); + VAR(bx) = 0.5 * VAR(s); VAR(by) = 0.5 * VAR(s) + VAR(t); + VAR(cx) = VAR(t); VAR(cy) = 0.5 * VAR(s); + VAR(dx) = VAR(t); VAR(dy) = -0.5 * VAR(s); + VAR(ex) = 0.5 * VAR(s); VAR(ey) = -0.5 * VAR(s) - VAR(t); + VAR(fx) = -0.5 * VAR(s); VAR(fy) = -0.5 * VAR(s) - VAR(t); + VAR(gx) = -VAR(t); VAR(gy) = -0.5 * VAR(s); + VAR(hx) = -VAR(t); VAR(hy) = 0.5 * VAR(s); + VAR(ix) = -0.5 * VAR(s); VAR(iy) = 0.5 * VAR(s); + VAR(jx) = 0.5 * VAR(s); VAR(jy) = 0.5 * VAR(s); + VAR(kx) = -0.5 * VAR(s); VAR(ky) = -0.5 * VAR(s); + VAR(lx) = 0.5 * VAR(s); VAR(ly) = -0.5 * VAR(s); + + return TRUE; +} + +inline double dot(double2 a, double2 b) { + return a.x * b.x + a.y * b.y; +} +inline double lerp(double a, double b, double p) { + return a + p * (b - a); +} +inline int hits_rect(double2 tl, double2 br, double2 p) { + return (p.x >= tl.x && p.y >= tl.y && p.x <= br.x && p.y <= br.y); +} +inline int hits_triangle(double2 a, double2 b, double2 c, double2 p, double* u, double* v) { + double2 v0 = DOUBLE2(c.x - a.x, c.y - a.y); + double2 v1 = DOUBLE2(b.x - a.x, b.y - a.y); + double2 v2 = DOUBLE2(p.x - a.x, p.y - a.y); + + double d00 = dot(v0, v0); + double d01 = dot(v0, v1); + double d02 = dot(v0, v2); + double d11 = dot(v1, v1); + double d12 = dot(v1, v2); + + double denom = (d00 * d11 - d01 * d01); + if (denom != 0) { + *u = (d11 * d02 - d01 * d12) / denom; + *v = (d00 * d12 - d01 * d02) / denom; + } else { + *u = *v = 0; + } + + return ((*u + *v) < 1.0) && (*u > 0) && (*v > 0); +} +inline int hits_square_around_origin(double a, double2 p) { + return (fabs(p.x) <= a && fabs(p.y) <= a); +} +inline int hits_circle_around_origin(double radius, double2 p, double* r) { + if (radius == 0.0) return TRUE; + *r = sqrt(sqr(p.x) + sqr(p.y)); + return (*r <= radius); +} + +int PluginVarCalc(Variation* vp) +{ + double x = FTx * 0.15, y = FTy * 0.15, z = FTz, r = 0, u = 0, v = 0, x2 = 0, y2 = 0; + double2 XY = DOUBLE2(x, y); + + double2 A = DOUBLE2(VAR(ax), VAR(ay)), B = DOUBLE2(VAR(bx), VAR(by)), C = DOUBLE2(VAR(cx), VAR(cy)), + D = DOUBLE2(VAR(dx), VAR(dy)), E = DOUBLE2(VAR(ex), VAR(ey)), F = DOUBLE2(VAR(fx), VAR(fy)), + G = DOUBLE2(VAR(gx), VAR(gy)), H = DOUBLE2(VAR(hx), VAR(hy)), I = DOUBLE2(VAR(ix), VAR(iy)), + J = DOUBLE2(VAR(jx), VAR(jy)), K = DOUBLE2(VAR(kx), VAR(ky)), L = DOUBLE2(VAR(lx), VAR(ly)); + + if ((VAR(rad) > 0) && hits_circle_around_origin(VAR(rad), XY, &r)) { + double rd = log(sqr(r / VAR(rad))); + double phi = atan2(y, x); + FPx += VVAR * lerp(x, phi, rd * VAR(octapol_polarweight)); + FPy += VVAR * lerp(y, r, rd * VAR(octapol_polarweight)); + } else if (hits_square_around_origin(VAR(a), XY)) { + if (hits_rect(H, K, XY) || hits_rect(J, D, XY) || + hits_rect(A, J, XY) || hits_rect(K, E, XY) || + hits_triangle(I, A, H, XY, &u, &v) || + hits_triangle(J, B, C, XY, &u, &v) || + hits_triangle(L, D, E, XY, &u, &v) || + hits_triangle(K, F, G, XY, &u, &v)) { + FPx += VVAR * x; FPy += VVAR * y; + } else FPx = FPy = 0; + } else FPx = FPy = 0; + + FPx += VVAR * x; + FPy += VVAR * y; + FPz += VVAR * z; + return TRUE; +} diff --git a/Plugin/ortho.c b/Plugin/ortho.c new file mode 100644 index 0000000..a8585c0 --- /dev/null +++ b/Plugin/ortho.c @@ -0,0 +1,131 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h + + +typedef struct +{ + double ortho_in; + double ortho_out; + +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + + +// Set the name of this plugin +APO_PLUGIN("ortho"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL_CYCLE(ortho_in, -M_PI, M_PI, 0.0), + VAR_REAL_CYCLE(ortho_out, -M_PI, M_PI, 0.0) + +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double r, a; + double xo; + double ro; + double c,s; + double x,y, tc, ts; + double theta; + + r = sqr(FTx) + sqr(FTy); + + if ( r < 1.0)// && FTx > 0.0 && FTy > 0.0) + { + if(FTx >= 0.0) + { + xo = (r + 1.0)/ (2.0 * FTx); + ro = sqrt(sqr(FTx - xo) + sqr(FTy)); + theta = atan2(1.0 , ro); + a = fmod( VAR(ortho_in)* theta + atan2(FTy, xo - FTx ) + theta, 2.0 * theta) - theta; + fsincos(a, &s, &c); + + FPx += VVAR * (xo - c * ro); + FPy += VVAR * s * ro; + } + else + { + xo = - (r + 1.0)/ (2.0 * FTx); + ro = sqrt(sqr(-FTx - xo) + sqr(FTy)); + theta = atan2(1.0 , ro); + a = fmod( VAR(ortho_in) * theta + atan2(FTy, xo + FTx ) + theta, 2.0 * theta) - theta; + fsincos(a, &s, &c); + + FPx -= VVAR * (xo - c * ro); + FPy += VVAR * s * ro; + } + } + else + { + r = 1.0 / sqrt(r); + fsincos( atan2(FTy, FTx), &ts, &tc); + x = r * tc; + y = r * ts; + + if(x >= 0.0) + { + xo = (sqr(x) + sqr(y) + 1.0)/ (2.0 * x); + ro = sqrt(sqr(x - xo) + sqr(y)); + theta = atan2(1.0 , ro); + a = fmod( VAR(ortho_out)* theta + atan2(y, xo - x ) + theta, 2.0 * theta) - theta; + fsincos(a, &s, &c); + + x = (xo - c * ro); + y = s * ro; + fsincos( atan2(y, x), &ts, &tc); + r = 1.0 / sqrt(sqr(x) + sqr(y)); + + FPx += VVAR * r * tc; + FPy += VVAR * r * ts; + } + else + { + xo = - (sqr(x) + sqr(y) + 1.0)/ (2.0 * x); + ro = sqrt(sqr(-x - xo) + sqr(y)); + theta = atan2(1.0 , ro); + a = fmod( VAR(ortho_out) * theta + atan2(y, xo + x ) + theta, 2.0 * theta) - theta; + fsincos(a, &s, &c); + + x = (xo - c * ro); + y = s * ro; + fsincos( atan2(y, x), &ts, &tc); + r = 1.0 / sqrt(sqr(x) + sqr(y)); + + FPx -= VVAR * r * tc; + FPy += VVAR * r * ts; + + } + } + + + + return TRUE; +} diff --git a/Plugin/oscilloscope.c b/Plugin/oscilloscope.c new file mode 100644 index 0000000..ec6a938 --- /dev/null +++ b/Plugin/oscilloscope.c @@ -0,0 +1,78 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double oscope_separation; + double oscope_frequency; + double oscope_amplitude; + double oscope_damping; + double TWO_PI_freq; + +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("oscilloscope"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(oscope_separation, 1.0), + VAR_REAL(oscope_frequency, M_PI), + VAR_REAL(oscope_amplitude, 1.0), + VAR_REAL(oscope_damping, 0.0) +); + + +int PluginVarPrepare(Variation* vp) +{ + VAR(TWO_PI_freq) = VAR(oscope_frequency) * M_PI*2; + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double t; + + if(VAR(oscope_damping) == 0) + { + t = VAR(oscope_amplitude)*cos(VAR(TWO_PI_freq)*FTx) + VAR(oscope_separation); + } + else + { + t = VAR(oscope_amplitude)*exp(-fabs(FTx)*VAR(oscope_damping))*cos(VAR(TWO_PI_freq)*FTx) + VAR(oscope_separation); + } + + if(fabs(FTy) <= t) + { + FPx += VVAR*FTx; + FPy -= VVAR*FTy; + } + else + { + FPx += VVAR*FTx; + FPy += VVAR*FTy; + } + return TRUE; +} + diff --git a/Plugin/pie.c b/Plugin/pie.c new file mode 100644 index 0000000..535bbe8 --- /dev/null +++ b/Plugin/pie.c @@ -0,0 +1,74 @@ +/* + Apophysis Plugin + Copyright (C) 2007-2008 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + int pie_slices; + double pie_thickness; + double pie_rotation; + + double pi2_slices; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("pie"); + +// Define the Variables +APO_VARIABLES( + VAR_INTEGER_NONZERO(pie_slices, 6), + VAR_REAL_RANGE(pie_thickness, 0.0, 1.0, 0.5), + VAR_REAL_CYCLE(pie_rotation, 0.0, 2.0 * M_PI, 0.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(pi2_slices) = 2 * M_PI / VAR(pie_slices); + + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + int sl; + double a, r; + double s, c; + + sl = rand() % VAR(pie_slices); // Pick a random slice. + + // Choose a random angle in the slice. + a = VAR(pie_rotation) + VAR(pi2_slices) * (sl + VAR(pie_thickness) * random01()); + + // Choose a random distance from the centre, scaled by VVAR. + r = VVAR * random01(); + + // Convert from polar coordinates to rectangular coordinates. + fsincos(a, &s, &c); + FPx += r * c; + FPy += r * s; + + return TRUE; +} + diff --git a/Plugin/poincare.c b/Plugin/poincare.c new file mode 100644 index 0000000..415f27e --- /dev/null +++ b/Plugin/poincare.c @@ -0,0 +1,79 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h + + +typedef struct +{ + double c1x; + double c1y; + double c2x; + double c2y; + double poincare_c1r; + double poincare_c2r; + double c1d; //r0 + r1 + double c2d; //r0 + r2 + double poincare_c1a; + double poincare_c2a; + +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + + +// Set the name of this plugin +APO_PLUGIN("poincare"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(poincare_c1r, 1.0), + VAR_REAL_CYCLE(poincare_c1a, -M_PI, M_PI, -1.0), + VAR_REAL(poincare_c2r, 1.0), + VAR_REAL_CYCLE(poincare_c2a, -M_PI, M_PI, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(c1d) = sqrt( 1.0 + sqr(VAR(poincare_c1r)) ); + VAR(c2d) = sqrt( 1.0 + sqr(VAR(poincare_c2r)) ); + + VAR(c1x) = VAR(c1d) * cos ( VAR(poincare_c1a)); + VAR(c1y) = VAR(c1d) * sin ( VAR(poincare_c1a)); + VAR(c2x) = VAR(c2d) * cos ( VAR(poincare_c2a)); + VAR(c2y) = VAR(c2d) * sin ( VAR(poincare_c2a)); + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double x, y; + + x = VAR(c1x) + ( sqr(VAR(poincare_c1r)) * ( FTx - VAR(c1x))) / ( sqr(FTx - VAR(c1x)) + sqr(FTy - VAR(c1y)) ); + y = VAR(c1y) + ( sqr(VAR(poincare_c1r)) * ( FTy - VAR(c1y))) / ( sqr(FTx - VAR(c1x)) + sqr(FTy - VAR(c1y)) ); + + FPx += VAR(c2x) + ( sqr(VAR(poincare_c2r)) * ( x - VAR(c2x))) / ( sqr(x - VAR(c2x)) + sqr(y - VAR(c2y)) ); + FPy += VAR(c2y) + ( sqr(VAR(poincare_c2r)) * ( y - VAR(c2y))) / ( sqr(x - VAR(c2x)) + sqr(y - VAR(c2y)) ); + + return TRUE; +} + diff --git a/Plugin/poincare3D.c b/Plugin/poincare3D.c new file mode 100644 index 0000000..34ed9ba --- /dev/null +++ b/Plugin/poincare3D.c @@ -0,0 +1,88 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double poincare3D_r, poincare3D_a, poincare3D_b; + + double cx, cy, cz; + double c2; + double c2x, c2y, c2z; + double s2x, s2y, s2z; + +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("poincare3D"); + + +// Define the Variables +APO_VARIABLES( + VAR_REAL(poincare3D_r, 0.0), + VAR_REAL(poincare3D_a, 0.0), + VAR_REAL(poincare3D_b, 0.0), +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(cx) = -VAR(poincare3D_r) * cos(VAR(poincare3D_a)*M_PI_2) * cos(VAR(poincare3D_b)*M_PI_2); + VAR(cy) = VAR(poincare3D_r) * sin(VAR(poincare3D_a)*M_PI_2) * cos(VAR(poincare3D_b)*M_PI_2); + VAR(cz) = -VAR(poincare3D_r) * sin(VAR(poincare3D_b)*M_PI_2); + + VAR(c2) = sqr(VAR(cx)) + sqr(VAR(cy)) + sqr(VAR(cz)); + + VAR(c2x) = 2 * VAR(cx); + VAR(c2y) = 2 * VAR(cy); + VAR(c2z) = 2 * VAR(cz); + + VAR(s2x) = sqr(VAR(cx)) - sqr(VAR(cy)) - sqr(VAR(cz)) + 1; + VAR(s2y) = sqr(VAR(cy)) - sqr(VAR(cx)) - sqr(VAR(cz)) + 1; + VAR(s2z) = sqr(VAR(cz)) - sqr(VAR(cy)) - sqr(VAR(cx)) + 1; + + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double r2 = sqr(FTx) + sqr(FTy) + sqr(FTz); + + double x2cx = VAR(c2x)*FTx, y2cy = VAR(c2y)*FTy, z2cz = VAR(c2z)*FTz; + + double d = VVAR / ( + VAR(c2) * r2 - x2cx - y2cy - z2cz + 1 + ); + + FPx += d * ( + FTx * VAR(s2x) + VAR(cx) * (y2cy + z2cz - r2 - 1) + ); + FPy += d * ( + FTy * VAR(s2y) + VAR(cy) * (x2cx + z2cz - r2 - 1) + ); + FPz += d * ( + FTz * VAR(s2z) + VAR(cz) * (y2cy + x2cx - r2 - 1) + ); + + return TRUE; +} diff --git a/Plugin/polynomial.c b/Plugin/polynomial.c new file mode 100644 index 0000000..d1f5507 --- /dev/null +++ b/Plugin/polynomial.c @@ -0,0 +1,56 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double polynomial_powx, polynomial_powy; + double polynomial_lcx, polynomial_lcy; + double polynomial_scx, polynomial_scy; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("polynomial"); + +APO_VARIABLES( + VAR_REAL(polynomial_powx, 1.0), + VAR_REAL(polynomial_powy, 1.0), + VAR_REAL(polynomial_lcx, 0.0), + VAR_REAL(polynomial_lcy, 0.0), + VAR_REAL(polynomial_scx, 0.0), + VAR_REAL(polynomial_scy, 0.0) +); + +int PluginVarPrepare(Variation* vp) +{ + return TRUE; +} + +inline double sgn(double v) { return (v < 0) ? -1 : (v > 0) ? 1 : 0; } +int PluginVarCalc(Variation* vp) +{ + double xp = pow(VVAR * fabs(FTx), VAR(polynomial_powx)); + double yp = pow(VVAR * fabs(FTy), VAR(polynomial_powy)); + double zp = VVAR * FTz; + + FPx += xp * sgn(FTx) + VAR(polynomial_lcx) * FTx + VAR(polynomial_scx); + FPy += yp * sgn(FTy) + VAR(polynomial_lcy) * FTy + VAR(polynomial_scy); + FPz += zp; + + return TRUE; +} diff --git a/Plugin/popcorn2.c b/Plugin/popcorn2.c new file mode 100644 index 0000000..e1a81b0 --- /dev/null +++ b/Plugin/popcorn2.c @@ -0,0 +1,55 @@ +/* + Apophysis Plugin + + Copyright (C) 2007 Gygrazok + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double popcorn2_x; + double popcorn2_y; + double popcorn2_c; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("popcorn2"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(popcorn2_x, 0.1), + VAR_REAL(popcorn2_y, 0.1), + VAR_REAL(popcorn2_c, 3.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + FPx += VVAR * (FTx + VAR(popcorn2_x) * sin(tan(VAR(popcorn2_c)*FTy))); + FPy += VVAR * (FTy + VAR(popcorn2_y) * sin(tan(VAR(popcorn2_c)*FTx))); + + return TRUE; +} diff --git a/Plugin/post_dcztransl.c b/Plugin/post_dcztransl.c new file mode 100644 index 0000000..514fe5a --- /dev/null +++ b/Plugin/post_dcztransl.c @@ -0,0 +1,69 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Written by Georg Kiehne + --> http://xyrus-worx.net, http://xyrus02.deviantart.com + + If you find any bugs / nags - keep them :) +*/ + +typedef struct { + double post_dcztransl_x0; + double post_dcztransl_x1; + double post_dcztransl_factor; + double x0_, x1_, x1_m_x0; + int post_dcztransl_overwrite; + int post_dcztransl_clamp; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("post_dcztransl"); +APO_VARIABLES( + VAR_REAL_RANGE(post_dcztransl_x0, 0.0, 1.0, 0.0), + VAR_REAL_RANGE(post_dcztransl_x1, 0.0, 1.0, 1.0), + VAR_REAL(post_dcztransl_factor, 1.0), + VAR_INTEGER_RANGE(post_dcztransl_overwrite, 0, 1, 1), + VAR_INTEGER_RANGE(post_dcztransl_clamp, 0, 1, 0) +); + +int PluginVarPrepare(Variation* vp) +{ + vp->var.x0_ = vp->var.post_dcztransl_x0 < vp->var.post_dcztransl_x1 ? vp->var.post_dcztransl_x0 : vp->var.post_dcztransl_x1; + vp->var.x1_ = vp->var.post_dcztransl_x0 > vp->var.post_dcztransl_x1 ? vp->var.post_dcztransl_x0 : vp->var.post_dcztransl_x1; + vp->var.x1_m_x0 = vp->var.x1_ - vp->var.x0_ == 0 ? EPS : vp->var.x1_ - vp->var.x0_; + + return 1; +} + +inline double flip(double a, double b, double c){return (c*(b-a)+a);} + +int PluginVarCalc(Variation* vp) +{ + double zf = vp->var.post_dcztransl_factor * (*(vp->pColor) - vp->var.x0_) / vp->var.x1_m_x0; + if (vp->var.post_dcztransl_clamp != 0) + zf = zf < 0 ? 0 : zf > 1 ? 1 : zf; + + *(vp->pFPx) = vp->vvar*(*(vp->pFPx)); + *(vp->pFPy) = vp->vvar*(*(vp->pFPy)); + + if (vp->var.post_dcztransl_overwrite == 0) + *(vp->pFPz) = vp->vvar*(*(vp->pFPz))*zf; + else *(vp->pFPz) = vp->vvar*zf; + + return 1; +} diff --git a/Plugin/post_mirror_x.c b/Plugin/post_mirror_x.c new file mode 100644 index 0000000..b86f22e --- /dev/null +++ b/Plugin/post_mirror_x.c @@ -0,0 +1,34 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define APO_NOVARIABLES +#include "apoplugin.h" + +APO_PLUGIN("post_mirror_x"); + +int PluginVarPrepare(Variation* vp) +{ + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + FPx = fabs(FPx); + if (rand() & 1) FPx = -FPx; + return TRUE; +} diff --git a/Plugin/post_mirror_y.c b/Plugin/post_mirror_y.c new file mode 100644 index 0000000..df3617b --- /dev/null +++ b/Plugin/post_mirror_y.c @@ -0,0 +1,34 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define APO_NOVARIABLES +#include "apoplugin.h" + +APO_PLUGIN("post_mirror_y"); + +int PluginVarPrepare(Variation* vp) +{ + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + FPy = fabs(FPy); + if (rand() & 1) FPy = -FPy; + return TRUE; +} diff --git a/Plugin/post_mirror_z.c b/Plugin/post_mirror_z.c new file mode 100644 index 0000000..e0a4d17 --- /dev/null +++ b/Plugin/post_mirror_z.c @@ -0,0 +1,34 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define APO_NOVARIABLES +#include "apoplugin.h" + +APO_PLUGIN("post_mirror_z"); + +int PluginVarPrepare(Variation* vp) +{ + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + FPz = fabs(FPz); + if (rand() & 1) FPz = -FPz; + return TRUE; +} diff --git a/Plugin/post_polar2.c b/Plugin/post_polar2.c new file mode 100644 index 0000000..9368e52 --- /dev/null +++ b/Plugin/post_polar2.c @@ -0,0 +1,50 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double post_polar2_vvar; + double post_polar2_vvar_2; +} Variables; + +#define M_PI 3.14159265358979323846 + +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("post_polar2"); + +int PluginVarPrepare(Variation* vp) +{ + VAR(post_polar2_vvar) = VVAR / M_PI; + VAR(post_polar2_vvar_2) = VAR(post_polar2_vvar) * 0.5; + return TRUE; +} +int PluginVarCalc(Variation* vp) +{ + FPy = VAR(post_polar2_vvar_2) * log(FPx*FPx + FPy*FPy); + FPx = VAR(post_polar2_vvar) * atan2(FPx, FPy); + + return TRUE; +} diff --git a/Plugin/post_rblur.c b/Plugin/post_rblur.c new file mode 100644 index 0000000..fb9ffea --- /dev/null +++ b/Plugin/post_rblur.c @@ -0,0 +1,51 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct { + double post_rblur_strength; + double post_rblur_offset; + double post_rblur_center_x; + double post_rblur_center_y; + + double s2; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("post_rblur"); +APO_VARIABLES( + VAR_REAL(post_rblur_strength, 1.0), + VAR_REAL(post_rblur_offset, 1.0), + VAR_REAL(post_rblur_center_x, 0.0), + VAR_REAL(post_rblur_center_y, 0.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(s2) = 2.0 * VAR(post_rblur_strength); + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double r = sqrt(sqr(FPx - VAR(post_rblur_center_x)) + sqr(FPy - VAR(post_rblur_center_y))) - VAR(post_rblur_offset); + r = r<0?0:r; r *= VAR(s2); + FPx = VVAR * (FPx + (random01() - 0.5) * r); + FPy = VVAR * (FPy + (random01() - 0.5) * r); + return TRUE; +} diff --git a/Plugin/pre_boarders2.c b/Plugin/pre_boarders2.c new file mode 100644 index 0000000..33ad8e3 --- /dev/null +++ b/Plugin/pre_boarders2.c @@ -0,0 +1,105 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double pre_boarders2_c; + double pre_boarders2_left; + double pre_boarders2_right; + double c, cl, cr; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +inline double rint(double x) +{ + int temp; temp = (x >= 0. ? (int)(x + 0.5) : (int)(x - 0.5)); + return (double)temp; +} + +APO_PLUGIN("pre_boarders2"); +APO_VARIABLES( + VAR_REAL(pre_boarders2_c, 0.5), + VAR_REAL(pre_boarders2_left, 0.5), + VAR_REAL(pre_boarders2_right, 0.5), +); + +int PluginVarPrepare(Variation* vp) +{ + double c = fabs(VAR(pre_boarders2_c)), + cl = fabs(VAR(pre_boarders2_left)), + cr = fabs(VAR(pre_boarders2_right)); + c = c==0?EPS:c; cl = cl==0?EPS:cl; cr = cr==0?EPS:cr; + VAR(c) = c; VAR(cl) = c*cl; VAR(cr) = c+(c*cr); + return TRUE; +} +int PluginVarCalc(Variation* vp) +{ + const double c = vp->var.c; + const double cl = vp->var.cl; + const double cr = vp->var.cr; + + double roundX, roundY, offsetX, offsetY; + + roundX = rint(FTx); + roundY = rint(FTy); + offsetX = FTx - roundX; + offsetY = FTy - roundY; + + if(random01() >= cr) + { + FTx = VVAR*(offsetX*c + roundX); + FTy = VVAR*(offsetY*c + roundY); + } + else + { + if(fabs(offsetX) >= fabs(offsetY)) + { + if(offsetX >= 0.0) + { + FTx = VVAR*(offsetX*c + roundX + cl); + FTy = VVAR*(offsetY*c + roundY + cl * offsetY / offsetX); + } + else + { + FTx = VVAR*(offsetX*c + roundX - cl); + FTy = VVAR*(offsetY*c + roundY - cl * offsetY / offsetX); + } + } + else + { + if(offsetY >= 0.0) + { + FTy = VVAR*(offsetY*c + roundY + cl); + FTx = VVAR*(offsetX*c + roundX + offsetX/offsetY*cl); + } + else + { + FTy = VVAR*(offsetY*c + roundY - cl); + FTx = VVAR*(offsetX*c + roundX - offsetX/offsetY*cl); + } + } + } + return TRUE; +} + diff --git a/Plugin/pre_dcztransl.c b/Plugin/pre_dcztransl.c new file mode 100644 index 0000000..3305899 --- /dev/null +++ b/Plugin/pre_dcztransl.c @@ -0,0 +1,68 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Written by Georg Kiehne + --> http://xyrus-worx.net, http://xyrus02.deviantart.com + + If you find any bugs / nags - keep them :) +*/ + +typedef struct { + double pre_dcztransl_x0; + double pre_dcztransl_x1; + double pre_dcztransl_factor; + double x0_, x1_, x1_m_x0; + int pre_dcztransl_overwrite; + int pre_ztransl_clamp; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("pre_dcztransl"); +APO_VARIABLES( + VAR_REAL_RANGE(pre_dcztransl_x0, 0.0, 1.0, 0.0), + VAR_REAL_RANGE(pre_dcztransl_x1, 0.0, 1.0, 1.0), + VAR_REAL(pre_dcztransl_factor, 1.0), + VAR_INTEGER_RANGE(pre_dcztransl_overwrite, 0, 1, 1), + VAR_INTEGER_RANGE(pre_ztransl_clamp, 0, 1, 0) +); + +int PluginVarPrepare(Variation* vp) +{ + vp->var.x0_ = vp->var.pre_dcztransl_x0 < vp->var.pre_dcztransl_x1 ? vp->var.pre_dcztransl_x0 : vp->var.pre_dcztransl_x1; + vp->var.x1_ = vp->var.pre_dcztransl_x0 > vp->var.pre_dcztransl_x1 ? vp->var.pre_dcztransl_x0 : vp->var.pre_dcztransl_x1; + vp->var.x1_m_x0 = vp->var.x1_ - vp->var.x0_ == 0 ? EPS : vp->var.x1_ - vp->var.x0_; + + return 1; +} + +inline double flip(double a, double b, double c){return (c*(b-a)+a);} +int PluginVarCalc(Variation* vp) +{ + double zf = vp->var.pre_dcztransl_factor * (*(vp->pColor) - vp->var.x0_) / vp->var.x1_m_x0; + if (vp->var.pre_ztransl_clamp != 0) + zf = zf < 0 ? 0 : zf > 1 ? 1 : zf; + + *(vp->pFTx) = vp->vvar*(*(vp->pFTx)); + *(vp->pFTy) = vp->vvar*(*(vp->pFTy)); + + if (vp->var.pre_dcztransl_overwrite == 0) + *(vp->pFTz) = vp->vvar*(*(vp->pFTz))*zf; + else *(vp->pFTz) = vp->vvar*zf; + + return 1; +} diff --git a/Plugin/psphere.c b/Plugin/psphere.c new file mode 100644 index 0000000..ebdff1a --- /dev/null +++ b/Plugin/psphere.c @@ -0,0 +1,59 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double vvar_pi; + double psphere_zscale; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +APO_PLUGIN("psphere"); + +APO_VARIABLES( + VAR_REAL(psphere_zscale, 0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(vvar_pi) = VVAR * M_PI; + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double c0 = FTx * VAR(vvar_pi); + double c1 = FTy * VAR(vvar_pi); + double c2 = FTz * VAR(vvar_pi); + + double sinc0, cosc0, sinc1, cosc1; + fsincos(c0, &sinc0, &cosc0); + fsincos(c1, &sinc1, &cosc1); + + double x = cosc0 * -sinc1; + double y = sinc0 * cosc1; + double z = cosc1 * VAR(psphere_zscale); + + FPx += x; + FPy += y; + FPz += z; + + return TRUE; +} diff --git a/Plugin/rational3.c b/Plugin/rational3.c new file mode 100644 index 0000000..2754f82 --- /dev/null +++ b/Plugin/rational3.c @@ -0,0 +1,113 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double rational3_vvar; + double rational3_t3; + double rational3_t2; + double rational3_t1; + double rational3_tc; + double rational3_b3; + double rational3_b2; + double rational3_b1; + double rational3_bc; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("rational3"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(rational3_t3, 1.0), + VAR_REAL(rational3_t2, 0.0), + VAR_REAL(rational3_t1, 0.0), + VAR_REAL(rational3_tc, 1.0), + VAR_REAL(rational3_b3, 0.0), + VAR_REAL(rational3_b2, 1.0), + VAR_REAL(rational3_b1, 0.0), + VAR_REAL(rational3_bc, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(rational3_vvar) = VVAR; + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + + + double xsqr = FTx * FTx; + double ysqr = FTy * FTy; + double xcb = FTx * FTx * FTx; + double ycb = FTy * FTy * FTy; + + double tr = VAR(rational3_t3) * (xcb - 3 * FTx * ysqr) + VAR(rational3_t2) * (xsqr - ysqr) + VAR(rational3_t1) * FTx + VAR(rational3_tc); + double ti = VAR(rational3_t3) * (3 * xsqr * FTy - ycb) + VAR(rational3_t2) * 2 * FTx * FTy + VAR(rational3_t1) * FTy; + + double br = VAR(rational3_b3) * (xcb - 3 * FTx * ysqr) + VAR(rational3_b2) * (xsqr - ysqr) + VAR(rational3_b1) * FTx + VAR(rational3_bc); + double bi = VAR(rational3_b3) * (3 * xsqr * FTy - ycb) + VAR(rational3_b2) * 2 * FTx * FTy + VAR(rational3_b1) * FTy; + + double r3den = 1/(br * br + bi * bi); + + FPx += VAR(rational3_vvar) * (tr * br + ti * bi) * r3den; + FPy += VAR(rational3_vvar) * (ti * br - tr * bi) * r3den; + +// FPx += VAR(rational3_vvar) * FTx * 2; +// FPy += VAR(rational3_vvar) * FTy * 2; + + return TRUE; + +} + +// Rational3 allows you to customize a rational function +// involving the complex variable z. It can be represented +// as the function... + +// az^3 + bz^2 + cz + d +// -------------------- division line +// ez^3 + fz^2 + gz + h + +// In this case, +// t3 = a (top z^3 coefficient) +// t2 = b +// t1 = c +// tc = d (top constant) +// b3 = e (bottom z^3 coefficient) +// b2 = f +// b1 = g +// bc = h (bottom constant) + +// This baby was a beast to work out, so please don't ask +// me to explain the whole thing. + +// This works sort of like Curl, except Curl uses the formula... + +// z +// ------------- +// bz^2 + az + 1 + +// Which is weird and abstract (one might say pointless, +// but that would be mean). diff --git a/Plugin/ripple.c b/Plugin/ripple.c new file mode 100644 index 0000000..c85b621 --- /dev/null +++ b/Plugin/ripple.c @@ -0,0 +1,101 @@ +typedef struct +{ + // variables + double ripple_frequency, + ripple_velocity, + ripple_amplitude, + ripple_centerx, + ripple_centery, + ripple_phase, + ripple_scale; + + // private stuff + double f, a, p, s, is, + vxp, pxa, pixa; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +APO_PLUGIN("ripple"); +APO_VARIABLES( + // wave function frequency + VAR_REAL(ripple_frequency, 2.0), + + // wave velocity + VAR_REAL(ripple_velocity, 1.0), + + // wave amplitude + VAR_REAL(ripple_amplitude, 0.5), + + // origin of the ripple (x,y) + VAR_REAL(ripple_centerx, 0.0), + VAR_REAL(ripple_centery, 0.0), + + // wave phase / interpolation coefficient + VAR_REAL(ripple_phase, 0.0), + + // ripple scale + VAR_REAL(ripple_scale, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + // some variables are settled in another range for edit comfort + // - transform them + VAR(f) = VAR(ripple_frequency) * 5; + VAR(a) = VAR(ripple_amplitude) * 0.01; + VAR(p) = VAR(ripple_phase) * M_2PI - M_PI; + + // scale must not be zero + VAR(s) = VAR(ripple_scale) == 0 ? EPS : VAR(ripple_scale); + + // we will need the inverse scale + VAR(is) = 1 / VAR(s); + + // pre-multiply velocity+phase, phase+amplitude and (PI-phase)+amplitude + VAR(vxp) = VAR(ripple_velocity) * VAR(p); + VAR(pxa) = VAR(p) * VAR(a); + VAR(pixa) = (M_PI - VAR(p)) * VAR(a); + + // done + return TRUE; +} + +inline double lerp(double a, double b, double p) { return a + (b - a) * p; } + +int PluginVarCalc(Variation* vp) +{ + //align input x, y to given center and multiply with scale + double x = (FTx * VAR(s)) - VAR(ripple_centerx), + y = (FTy * VAR(s)) + VAR(ripple_centery); + + // calculate distance from center but constrain it to EPS + double d = MAX(EPS, sqrt(sqr(x) * sqr(y))); + + // normalize (x,y) + double nx = x / d, + ny = y / d; + + // calculate cosine wave with given frequency, velocity + // and phase based on the distance to center + double wave = cos(VAR(f) * d - VAR(vxp)); + + // calculate the wave offsets + double d1 = wave * VAR(pxa) + d, + d2 = wave * VAR(pixa) + d; + + // we got two offsets, so we also got two new positions (u,v) + double u1 = (VAR(ripple_centerx) + nx * d1), + v1 = (-VAR(ripple_centery) + ny * d1); + double u2 = (VAR(ripple_centerx) + nx * d2), + v2 = (-VAR(ripple_centery) + ny * d2); + + // interpolate the two positions by the given phase and + // invert the multiplication with scale from before + FPx = VVAR * (lerp(u1, u2, VAR(p))) * VAR(is); + FPy = VVAR * (lerp(v1, v2, VAR(p))) * VAR(is); + + // done + return TRUE; +} diff --git a/Plugin/sigmoid.c b/Plugin/sigmoid.c new file mode 100644 index 0000000..515c167 --- /dev/null +++ b/Plugin/sigmoid.c @@ -0,0 +1,74 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double sigmoid_shiftx; + double sigmoid_shifty; + double sx, sy, ax, ay, vv; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("sigmoid"); + +APO_VARIABLES( + VAR_REAL(sigmoid_shiftx, 1.0), + VAR_REAL(sigmoid_shifty, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(ax) = 1.0; VAR(ay) = 1.0; + VAR(sx) = VAR(sigmoid_shiftx); VAR(sy) = VAR(sigmoid_shifty); + if (VAR(sx) < 1 && VAR(sx) > -1) { + if (VAR(sx) == 0) { + VAR(sx) = EPS; VAR(ax) = 1.0; + } else { + VAR(ax) = (VAR(sx) < 0 ? -1 : 1); + VAR(sx) = 1 / VAR(sx); + } + } + if (VAR(sy) < 1 && VAR(sy) > -1) { + if (VAR(sy) == 0) { + VAR(sy) = EPS; VAR(ay) = 1.0; + } else { + VAR(ay) = (VAR(sy) < 0 ? -1 : 1); + VAR(sy) = 1 / VAR(sy); + } + } + + VAR(sx) *= -5; + VAR(sy) *= -5; + + VAR(vv) = fabs(VVAR); + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double c0 = VAR(ax) / (1.0 + exp(VAR(sx) * FTx)); + double c1 = VAR(ay) / (1.0 + exp(VAR(sy) * FTy)); + double x = (2 * (c0 - 0.5)); + double y = (2 * (c1 - 0.5)); + + FPx += VAR(vv) * x; + FPy += VAR(vv) * y; + + return TRUE; +} diff --git a/Plugin/sinusgrid.c b/Plugin/sinusgrid.c new file mode 100644 index 0000000..bfc9c06 --- /dev/null +++ b/Plugin/sinusgrid.c @@ -0,0 +1,66 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double sinusgrid_ampx; + double sinusgrid_ampy; + double sinusgrid_freqx; + double sinusgrid_freqy; + + double fx, fy, ax, ay; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("sinusgrid"); + +APO_VARIABLES( + //VAR_REAL_CYCLE(sinusgrid_ampx, 0.0, 1.0, 0.5), + //VAR_REAL_CYCLE(sinusgrid_ampy, 0.0, 1.0, 0.5), + VAR_REAL(sinusgrid_ampx, 0.5), + VAR_REAL(sinusgrid_ampy, 0.5), + VAR_REAL(sinusgrid_freqx, 1.0), + VAR_REAL(sinusgrid_freqy, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(ax) = VAR(sinusgrid_ampx); + VAR(ay) = VAR(sinusgrid_ampy); + VAR(fx) = VAR(sinusgrid_freqx) * M_2PI; + VAR(fy) = VAR(sinusgrid_freqy) * M_2PI; + if (VAR(fx) == 0.0) VAR(fx) = EPS; + if (VAR(fy) == 0.0) VAR(fy) = EPS; + return TRUE; +} + +inline double lerp(double a, double b, double p) { return a + p * (b-a); } + +int PluginVarCalc(Variation* vp) +{ + double x = FTx, y = FTy; + double sx = -1.0 * cos(x * VAR(fx)); + double sy = -1.0 * cos(y * VAR(fy)); + double tx = lerp(FTx, sx, VAR(ax)), ty = lerp(FTy, sy, VAR(ay)), tz = FTz; + FPx += VVAR * tx; + FPy += VVAR * ty; + FPz += VVAR * tz; + return TRUE; +} + diff --git a/Plugin/split.c b/Plugin/split.c new file mode 100644 index 0000000..e39ce1a --- /dev/null +++ b/Plugin/split.c @@ -0,0 +1,68 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double split_xsize; + double split_ysize; + + // precacluated values + double xang; + double yang; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("split"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(split_xsize, 0.5), + VAR_REAL(split_ysize, 0.5) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(xang) = M_PI * VAR(split_xsize); + VAR(yang) = M_PI * VAR(split_ysize); + + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + if (cos(FTx * VAR(xang)) >= 0) + FPy += VVAR * FTy; + else + FPy -= VVAR * FTy; + + if (cos(FTy * VAR(yang)) >= 0) + FPx += VVAR * FTx; + else + FPx -= VVAR * FTx; + + return TRUE; +} + diff --git a/Plugin/stripes.c b/Plugin/stripes.c new file mode 100644 index 0000000..565a51d --- /dev/null +++ b/Plugin/stripes.c @@ -0,0 +1,69 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Joel Faber + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double stripes_space; + double stripes_warp; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("stripes"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL_RANGE(stripes_space, 0.0, 1.0, 0.5), + VAR_REAL(stripes_warp, 0.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Always return TRUE. + return TRUE; +} + +inline double rint(double x) +{ + int temp; temp = (x >= 0. ? (int)(x + 0.5) : (int)(x - 0.5)); + return (double)temp; +} + + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double roundx; + double offsetx; + + roundx = (double)rint(FTx); + offsetx = FTx - roundx; + + FPx += VVAR * ( offsetx * (1.0 - VAR(stripes_space)) + roundx); + FPy += VVAR * (FTy + offsetx * offsetx * VAR(stripes_warp)); + + return TRUE; +} + diff --git a/Plugin/stwins.c b/Plugin/stwins.c new file mode 100644 index 0000000..c8948f1 --- /dev/null +++ b/Plugin/stwins.c @@ -0,0 +1,62 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double swtin_distort; + +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("stwin"); + +APO_VARIABLES( + VAR_REAL(swtin_distort, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + // at multiplier=1 the function begins to overlap at 0.05 so we + // multiply with 0.05 + const double multiplier = 0.05; + + // then do the rest + double x = FTx * VVAR * multiplier; + double y = FTy * VVAR * multiplier; + double x2 = x * x; double y2 = y * y; + double x_plus_y = x + y; + double x2_minus_y2 = x2 - y2; + double x2_plus_y2 = x2 + y2; + + double result = x2_minus_y2 * sin(M_2PI * VAR(swtin_distort) * x_plus_y); + double divident = 1.0; + if (x2_plus_y2 != 0) divident = x2_plus_y2; + + result /= divident; + + FPx += VVAR * FTx + result; + FPy += VVAR * FTy + result; + + return TRUE; +} diff --git a/Plugin/synth.c b/Plugin/synth.c new file mode 100644 index 0000000..7153da9 --- /dev/null +++ b/Plugin/synth.c @@ -0,0 +1,1056 @@ +/* + Apophysis Plugin - Synth v2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + The Thing That Should Not Be + + A much neater way of providing the kind of felixibility and control + in Apophysis that I am aiming for with Synth would be to create + a node-based system of connected functions that allowed advanced users + to build their own routines for the Apophysis engine from simple + components. + + Many other graphic and audio engines use this concept very successfully. + + Such a system could make FX, PX, xaos etc redundant too. + + I've made Synth, because I cannot forsee that kind of development happening + with Apophysis. This is no sleight to the Apo developers - from Mark Townsend + onwards the project has been an inspiration and joy to many people. It is + more simply a recognition of how hard it would be to make such a change + to Apophysis as it stands. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double synth_a; + int synth_mode; + double synth_power; + double synth_mix; + int synth_smooth; + + double synth_b; + int synth_b_type; + double synth_b_frq; + double synth_b_skew; + double synth_b_phs; + int synth_b_layer; + + double synth_c; + int synth_c_type; + double synth_c_frq; + double synth_c_skew; + double synth_c_phs; + int synth_c_layer; + + double synth_d; + int synth_d_type; + double synth_d_frq; + double synth_d_skew; + double synth_d_phs; + int synth_d_layer; + + double synth_e; + int synth_e_type; + double synth_e_frq; + double synth_e_skew; + double synth_e_phs; + int synth_e_layer; + + double synth_f; + int synth_f_type; + double synth_f_frq; + double synth_f_skew; + double synth_f_phs; + int synth_f_layer; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("synth"); + +// Define the Variables +APO_VARIABLES( + + VAR_REAL(synth_a, 1.0), + VAR_INTEGER(synth_mode, 3), + VAR_REAL(synth_power, -2.0), + VAR_REAL(synth_mix, 1.0), + VAR_INTEGER(synth_smooth, 0), + + VAR_REAL(synth_b, 0.0), + VAR_INTEGER(synth_b_type, 0), + VAR_REAL(synth_b_skew, 0.0), + VAR_REAL(synth_b_frq, 1.0), + VAR_REAL(synth_b_phs, 0.0), + VAR_INTEGER(synth_b_layer, 0), + + VAR_REAL(synth_c, 0.0), + VAR_INTEGER(synth_c_type, 0), + VAR_REAL(synth_c_skew, 0.0), + VAR_REAL(synth_c_frq, 1.0), + VAR_REAL(synth_c_phs, 0.0), + VAR_INTEGER(synth_c_layer, 0), + + VAR_REAL(synth_d, 0.0), + VAR_INTEGER(synth_d_type, 0), + VAR_REAL(synth_d_skew, 0.0), + VAR_REAL(synth_d_frq, 1.0), + VAR_REAL(synth_d_phs, 0.0), + VAR_INTEGER(synth_d_layer, 0), + + VAR_REAL(synth_e, 0.0), + VAR_INTEGER(synth_e_type, 0), + VAR_REAL(synth_e_skew, 0.0), + VAR_REAL(synth_e_frq, 1.0), + VAR_REAL(synth_e_phs, 0.0), + VAR_INTEGER(synth_e_layer, 0), + + VAR_REAL(synth_f, 0.0), + VAR_INTEGER(synth_f_type, 0), + VAR_REAL(synth_f_skew, 0.0), + VAR_REAL(synth_f_frq, 1.0), + VAR_REAL(synth_f_phs, 0.0), + VAR_INTEGER(synth_f_layer, 0) + +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// ------------------------------------------------------------- +// Modes +// "Lagacy" modes from v1 +#define MODE_SPHERICAL 0 +#define MODE_BUBBLE 1 +#define MODE_BLUR_LEGACY 2 +// New modes in v2 +#define MODE_BLUR_NEW 3 +#define MODE_BLUR_ZIGZAG 4 +#define MODE_RAWCIRCLE 5 +#define MODE_RAWX 6 +#define MODE_RAWY 7 +#define MODE_RAWXY 8 +#define MODE_SHIFTX 9 +#define MODE_SHIFTY 10 +#define MODE_SHIFTXY 11 +#define MODE_SINUSOIDAL 12 +#define MODE_SWIRL 13 +#define MODE_HYPERBOLIC 14 +#define MODE_JULIA 15 +#define MODE_DISC 16 +#define MODE_RINGS 17 +#define MODE_CYLINDER 18 +#define MODE_BLUR_RING 19 +#define MODE_BLUR_RING2 20 +#define MODE_SHIFTTHETA 21 + +// ------------------------------------------------------------- +// Wave types +#define WAVE_SIN 0 +#define WAVE_COS 1 +#define WAVE_SQUARE 2 +#define WAVE_SAW 3 +#define WAVE_TRIANGLE 4 +#define WAVE_CONCAVE 5 +#define WAVE_CONVEX 6 +#define WAVE_NGON 7 +// New wave types in v2 +#define WAVE_INGON 8 + +// ------------------------------------------------------------- +// Layer types +#define LAYER_ADD 0 +#define LAYER_MULT 1 +#define LAYER_MAX 2 +#define LAYER_MIN 3 + +// ------------------------------------------------------------- +// Interpolation types +#define LERP_LINEAR 0 +#define LERP_BEZIER 1 + +// ------------------------------------------------------------- +// Sine/Cosine interpretation types +#define SINCOS_MULTIPLY 0 +#define SINCOS_MIXIN 1 + +// ------------------------------------------------------------- +// synth_value calculates the wave height y from theta, which is an abstract +// angle that could come from any other calculation - for circular modes +// it will be the angle between the positive y axis and the vector from +// the origin to the pont i.e. atan2(x,y) +// You must call the argument "vp". +inline double synth_value(Variation* vp, double theta) +{ + double theta_factor = VAR(synth_a); + double x,y,z; + + if ( VAR(synth_b) != 0.0 ) { + + z = VAR(synth_b_phs) + theta * VAR(synth_b_frq); + y = z / ( 2 * M_PI ); + y -= floor( y ); + + // y is in range 0 - 1. Now skew according to synth_b_skew + if ( VAR(synth_b_skew) != 0.0 ) { + z = 0.5 + 0.5 * VAR(synth_b_skew); + if ( y > z ) { + // y is 0.5 if equals z, up to 1.0 + y = 0.5 + 0.5 * (y - z)/(1.0 - z + EPS); + } + else { + // y is 0.5 if equals z, down to 0.0 + y = 0.5 - 0.5 * (z - y)/(z + EPS); + } + } + + switch ( VAR(synth_b_type) ) { + case WAVE_SIN: + x = sin( y * 2 * M_PI ); + break; + case WAVE_COS: + x = cos( y * 2 * M_PI ); + break; + case WAVE_SQUARE: + x = y > 0.5 ? 1.0 : -1.0; + break; + case WAVE_SAW: + x = 1.0 - 2.0 * y; + break; + case WAVE_TRIANGLE: + x = y > 0.5 ? 3.0 - 4.0 * y : 2.0 * y - 1.0; + break; + case WAVE_CONCAVE: + x = 8.0 * ( y - 0.5 ) * ( y - 0.5 ) - 1.0; + break; + case WAVE_CONVEX: + x = 2.0 * sqrt( y ) - 1.0; + break; + case WAVE_NGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_b_frq) ); + x = ( 1.0 / ( cos(y) + EPS ) - 1.0); + break; + case WAVE_INGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_b_frq) ); + z = cos(y); + x = z / ( 1.0 + EPS - z ); + break; + } + + switch ( VAR(synth_b_layer) ) { + case LAYER_ADD: + theta_factor += VAR(synth_b) * x; + break; + case LAYER_MULT: + theta_factor *= ( 1.0 + VAR(synth_b) * x ); + break; + case LAYER_MAX: + z = VAR(synth_a) + VAR(synth_b) * x; + theta_factor = ( theta_factor > z ? theta_factor : z ); + break; + case LAYER_MIN: + z = VAR(synth_a) + VAR(synth_b) * x; + theta_factor = ( theta_factor < z ? theta_factor : z ); + break; + } + } + + + if ( VAR(synth_c) != 0.0 ) { + + z = VAR(synth_c_phs) + theta * VAR(synth_c_frq); + y = z / ( 2 * M_PI ); + y -= floor( y ); + + // y is in range 0 - 1. Now skew according to synth_c_skew + if ( VAR(synth_c_skew) != 0.0 ) { + z = 0.5 + 0.5 * VAR(synth_c_skew); + if ( y > z ) { + // y is 0.5 if equals z, up to 1.0 + y = 0.5 + 0.5 * (y - z)/(1.0 - z + EPS); + } + else { + // y is 0.5 if equals z, down to 0.0 + y = 0.5 - 0.5 * (z - y)/(z + EPS); + } + } + + switch ( VAR(synth_c_type) ) { + case WAVE_SIN: + x = sin( y * 2 * M_PI ); + break; + case WAVE_COS: + x = cos( y * 2 * M_PI ); + break; + case WAVE_SQUARE: + x = y > 0.5 ? 1.0 : -1.0; + break; + case WAVE_SAW: + x = 1.0 - 2.0 * y; + break; + case WAVE_TRIANGLE: + x = y > 0.5 ? 3.0 - 4.0 * y : 2.0 * y - 1.0; + break; + case WAVE_CONCAVE: + x = 8.0 * ( y - 0.5 ) * ( y - 0.5 ) - 1.0; + break; + case WAVE_CONVEX: + x = 2.0 * sqrt( y ) - 1.0; + break; + case WAVE_NGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_c_frq) ); + x = ( 1.0 / ( cos(y) + EPS ) - 1.0); + break; + case WAVE_INGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_c_frq) ); + z = cos(y); + x = z / ( 1.0 + EPS - z ); + break; + } + + switch ( VAR(synth_c_layer) ) { + case LAYER_ADD: + theta_factor += VAR(synth_c) * x; + break; + case LAYER_MULT: + theta_factor *= ( 1.0 + VAR(synth_c) * x ); + break; + case LAYER_MAX: + z = VAR(synth_a) + VAR(synth_c) * x; + theta_factor = ( theta_factor > z ? theta_factor : z ); + break; + case LAYER_MIN: + z = VAR(synth_a) + VAR(synth_c) * x; + theta_factor = ( theta_factor < z ? theta_factor : z ); + break; + } + } + + + if ( VAR(synth_d) != 0.0 ) { + + z = VAR(synth_d_phs) + theta * VAR(synth_d_frq); + y = z / ( 2 * M_PI ); + y -= floor( y ); + + // y is in range 0 - 1. Now skew according to synth_d_skew + if ( VAR(synth_d_skew) != 0.0 ) { + z = 0.5 + 0.5 * VAR(synth_d_skew); + if ( y > z ) { + // y is 0.5 if equals z, up to 1.0 + y = 0.5 + 0.5 * (y - z)/(1.0 - z + EPS); + } + else { + // y is 0.5 if equals z, down to 0.0 + y = 0.5 - 0.5 * (z - y)/(z + EPS); + } + } + + switch ( VAR(synth_d_type) ) { + case WAVE_SIN: + x = sin( y * 2 * M_PI ); + break; + case WAVE_COS: + x = cos( y * 2 * M_PI ); + break; + case WAVE_SQUARE: + x = y > 0.5 ? 1.0 : -1.0; + break; + case WAVE_SAW: + x = 1.0 - 2.0 * y; + break; + case WAVE_TRIANGLE: + x = y > 0.5 ? 3.0 - 4.0 * y : 2.0 * y - 1.0; + break; + case WAVE_CONCAVE: + x = 8.0 * ( y - 0.5 ) * ( y - 0.5 ) - 1.0; + break; + case WAVE_CONVEX: + x = 2.0 * sqrt( y ) - 1.0; + break; + case WAVE_NGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_d_frq) ); + x = ( 1.0 / ( cos(y) + EPS ) - 1.0); + break; + case WAVE_INGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_d_frq) ); + z = cos(y); + x = z / ( 1.0 + EPS - z ); + break; + } + + switch ( VAR(synth_d_layer) ) { + case LAYER_ADD: + theta_factor += VAR(synth_d) * x; + break; + case LAYER_MULT: + theta_factor *= ( 1.0 + VAR(synth_d) * x ); + break; + case LAYER_MAX: + z = VAR(synth_a) + VAR(synth_d) * x; + theta_factor = ( theta_factor > z ? theta_factor : z ); + break; + case LAYER_MIN: + z = VAR(synth_a) + VAR(synth_d) * x; + theta_factor = ( theta_factor < z ? theta_factor : z ); + break; + } + } + + + if ( VAR(synth_e) != 0.0 ) { + + z = VAR(synth_e_phs) + theta * VAR(synth_e_frq); + y = z / ( 2 * M_PI ); + y -= floor( y ); + + // y is in range 0 - 1. Now skew according to synth_e_skew + if ( VAR(synth_e_skew) != 0.0 ) { + z = 0.5 + 0.5 * VAR(synth_e_skew); + if ( y > z ) { + // y is 0.5 if equals z, up to 1.0 + y = 0.5 + 0.5 * (y - z)/(1.0 - z + EPS); + } + else { + // y is 0.5 if equals z, down to 0.0 + y = 0.5 - 0.5 * (z - y)/(z + EPS); + } + } + + switch ( VAR(synth_e_type) ) { + case WAVE_SIN: + x = sin( y * 2 * M_PI ); + break; + case WAVE_COS: + x = cos( y * 2 * M_PI ); + break; + case WAVE_SQUARE: + x = y > 0.5 ? 1.0 : -1.0; + break; + case WAVE_SAW: + x = 1.0 - 2.0 * y; + break; + case WAVE_TRIANGLE: + x = y > 0.5 ? 3.0 - 4.0 * y : 2.0 * y - 1.0; + break; + case WAVE_CONCAVE: + x = 8.0 * ( y - 0.5 ) * ( y - 0.5 ) - 1.0; + break; + case WAVE_CONVEX: + x = 2.0 * sqrt( y ) - 1.0; + break; + case WAVE_NGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_e_frq) ); + x = ( 1.0 / ( cos(y) + EPS ) - 1.0); + break; + case WAVE_INGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_e_frq) ); + z = cos(y); + x = z / ( 1.0 + EPS - z ); + break; + + } + + switch ( VAR(synth_e_layer) ) { + case LAYER_ADD: + theta_factor += VAR(synth_e) * x; + break; + case LAYER_MULT: + theta_factor *= ( 1.0 + VAR(synth_e) * x ); + break; + case LAYER_MAX: + z = VAR(synth_a) + VAR(synth_e) * x; + theta_factor = ( theta_factor > z ? theta_factor : z ); + break; + case LAYER_MIN: + z = VAR(synth_a) + VAR(synth_e) * x; + theta_factor = ( theta_factor < z ? theta_factor : z ); + break; + } + } + + + if ( VAR(synth_f) != 0.0 ) { + + z = VAR(synth_f_phs) + theta * VAR(synth_f_frq); + y = z / ( 2 * M_PI ); + y -= floor( y ); + + // y is in range 0 - 1. Now skew according to synth_f_skew + if ( VAR(synth_f_skew) != 0.0 ) { + z = 0.5 + 0.5 * VAR(synth_f_skew); + if ( y > z ) { + // y is 0.5 if equals z, up to 1.0 + y = 0.5 + 0.5 * (y - z)/(1.0 - z + EPS); + } + else { + // y is 0.5 if equals z, down to 0.0 + y = 0.5 - 0.5 * (z - y)/(z + EPS); + } + } + + switch ( VAR(synth_f_type) ) { + case WAVE_SIN: + x = sin( y * 2 * M_PI ); + break; + case WAVE_COS: + x = cos( y * 2 * M_PI ); + break; + case WAVE_SQUARE: + x = y > 0.5 ? 1.0 : -1.0; + break; + case WAVE_SAW: + x = 1.0 - 2.0 * y; + break; + case WAVE_TRIANGLE: + x = y > 0.5 ? 3.0 - 4.0 * y : 2.0 * y - 1.0; + break; + case WAVE_CONCAVE: + x = 8.0 * ( y - 0.5 ) * ( y - 0.5 ) - 1.0; + break; + case WAVE_CONVEX: + x = 2.0 * sqrt( y ) - 1.0; + break; + case WAVE_NGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_f_frq) ); + x = ( 1.0 / ( cos(y) + EPS ) - 1.0); + break; + case WAVE_INGON: + y -= 0.5; + y *= (2.0 * M_PI / VAR(synth_f_frq) ); + z = cos(y); + x = z / ( 1.0 + EPS - z ); + break; + } + + switch ( VAR(synth_f_layer) ) { + case LAYER_ADD: + theta_factor += VAR(synth_f) * x; + break; + case LAYER_MULT: + theta_factor *= ( 1.0 + VAR(synth_f) * x ); + break; + case LAYER_MAX: + z = VAR(synth_a) + VAR(synth_f) * x; + theta_factor = ( theta_factor > z ? theta_factor : z ); + break; + case LAYER_MIN: + z = VAR(synth_a) + VAR(synth_f) * x; + theta_factor = ( theta_factor < z ? theta_factor : z ); + break; + } + } + + // Mix is applied here, assuming 1.0 to be the "flat" line for legacy support + return theta_factor * VAR(synth_mix) + ( 1.0 - VAR(synth_mix) ); +} + +// ------------------------------------------------------------- +// Mapping function y = fn(x) based on quadratic Bezier curves for smooth type 1 +// Returns close to y = x for high/low values of x, y = m when x = 1.0, and +// something in-between y = m*x and y = x lines when x is close-ish to 1.0 +// Function always has slope of 0.0 or greater, so no x' values "overlap" +inline double bezier_quad_map( double x, double m ) +{ + double a = 1.0; // a is used to control sign of result + double t = 0.0; // t is the Bezier curve parameter + + // Simply reflect in the y axis for negative values + if ( m < 0.0 ) { m = -m; a = -1.0; } + if ( x < 0.0 ) { x = -x; a = -a; } + + // iM is "inverse m" used in a few places below + double iM = 1e10; + if ( m > 1.0e-10 ) + { + iM = 1.0 / m; + } + + // L is the upper bound on our curves, where we have rejoined the y = x line + double L = iM < m * 2.0 ? m * 2.0 : iM; + + // "Non Curved" + // Covers x >= L, or always true if m == 1.0 + // y = x i.e. not distorted + if ( ( x > L ) || ( m == 1.0 ) ) + { + return a * x; + } + + if ( ( m < 1.0 ) && ( x <= 1.0 ) ) + { + // Bezier Curve #1 + // Covers 0 <= $m <= 1.0, 0 <= $x <= 1.0 + // Control points are (0,0), (m,m) and (1,m) + + t = x; // Special case when m == 0.5 + if ( abs(m-0.5) > 1e-10 ) + { + t = ( -1.0 * m + sqrt( m * m + ( 1.0 - 2.0 * m) * x ) ) / ( 1.0 - 2.0 * m ); + } + return a * ( x + ( m - 1.0 ) * t * t ); + } + + if ( ( 1.0 < m ) && ( x <= 1.0 ) ) + { + // Bezier Curve #2 + // Covers m >= 1.0, 0 <= x <= 1.0 + // Control points are (0,0), (iM,iM) and (1,m) + + t = x; // Special case when m == 2 + if ( abs(m-2.0) > 1e-10 ) + { + t = ( -1.0 * iM + sqrt( iM * iM + ( 1.0 - 2.0 * iM ) * x ) ) / ( 1 - 2 * iM ); + } + return a * ( x + ( m - 1.0 ) * t * t ); + } + + if ( m < 1.0 ) + { + // Bezier Curve #3 + // Covers 0 <= m <= 1.0, 1 <= x <= L + // Control points are (1,m), (1,1) and (L,L) + // (L is x value (>1) where we re-join y = x line, and is maximum( iM, 2 * m ) + + t = sqrt( ( x - 1.0 ) / ( L - 1.0 ) ); + return a * ( x + ( m - 1.0 ) * t * t + 2 * ( 1.0 - m ) * t + ( m - 1.0 ) ); + } + + // Curve #4 + // Covers 1.0 <= m, 1 <= x <= L + // Control points are (1,m), (m,m) and (L,L) + // (L is x value (>1) where we re-join y = x line, and is maximum( iM, 2 * m ) + + t = ( 1.0 - m ) + sqrt( ( m - 1.0 ) * ( m - 1.0 ) + ( x - 1.0 ) ); + return a * ( x + ( m - 1.0 ) * t * t - 2.0 * ( m - 1.0 ) * t + ( m - 1.0 ) ); +} + + +// Handle potentially many types of interpolation routine in future . . . +inline double interpolate( double x, double m, int lerp_type ) +{ + switch ( lerp_type ) + { + case LERP_LINEAR: + return x * m; + case LERP_BEZIER: + return bezier_quad_map( x, m ); + } + return x * m; +} + +inline void synthsincos( Variation* vp, double theta, double* s, double* c, int sine_type ) +{ + fsincos( theta, s, c ); + switch ( sine_type ) + { + case SINCOS_MULTIPLY: + *s = (*s) * synth_value( vp, theta ); + *c = (*c) * synth_value( vp, theta + M_PI/2.0 ); + break; + case SINCOS_MIXIN: + *s = ( 1.0 - VAR(synth_mix) ) * (*s) + ( synth_value( vp, theta ) - 1.0 ); + *c = ( 1.0 - VAR(synth_mix) ) * (*c) + ( synth_value( vp, theta + M_PI/2.0 ) - 1.0 ); + break; + } + return; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double Vx, Vy, radius, theta; // Position vector in cartesian and polar co-ords + double theta_factor; // Evaluation of synth() function for current point + double s, c, mu; // Handy temp variables, s & c => sine & cosine, mu = generic temp param + + switch( VAR(synth_mode) ) { + + case MODE_RAWCIRCLE: // Power NO, Smooth YES + // Get current radius and angle + Vx = FTx; + Vy = FTy; + radius = sqrt(Vx * Vx + Vy * Vy); + theta = atan2(Vx, Vy); + + // Calculate new radius + theta_factor = synth_value( vp, theta ); + radius = interpolate( radius, theta_factor, VAR(synth_smooth) ); + fsincos(theta, &s, &c); + + // Write to running totals for transform + FPx += VVAR * radius * s; + FPy += VVAR * radius * c; + break; + + + case MODE_RAWY: // Power NO, Smooth YES + // Use x and y values directly + Vx = FTx; + Vy = FTy; + + // y value will be mapped according to synth(x) value + theta_factor = synth_value( vp, Vx ); + + // Write to running totals for transform + FPx += VVAR * Vx; + FPy += VVAR * interpolate( Vy, theta_factor, VAR(synth_smooth) );; + break; + + + case MODE_RAWX: // Power NO, Smooth YES + // Use x and y values directly + Vx = FTx; + Vy = FTy; + + // x value will be mapped according to synth(y) value + theta_factor = synth_value( vp, Vy ); + + // Write to running totals for transform + FPx += VVAR * interpolate( Vx, theta_factor, VAR(synth_smooth) ); + FPy += VVAR * Vy; + break; + + + case MODE_RAWXY: // Power NO, Smooth YES + // Use x and y values directly + Vx = FTx; + Vy = FTy; + + // x value will be mapped according to synth(y) value + theta_factor = synth_value( vp, Vy ); + FPx += VVAR * interpolate( Vx, theta_factor, VAR(synth_smooth) ); + + // y value will be mapped according to synth(x) value + theta_factor = synth_value( vp, Vx ); + FPy += VVAR * interpolate( Vy, theta_factor, VAR(synth_smooth) ); + break; + + + case MODE_SPHERICAL: // Power YES, Smooth YES + // Re-write of spherical with synth tweak + Vx = FTx; + Vy = FTy; + radius = pow(Vx * Vx + Vy * Vy + EPS, ( VAR(synth_power) + 1.0 )/2.0); + + // Get angle and angular factor + theta = atan2(Vx, Vy); + theta_factor = synth_value( vp, theta ); + radius = interpolate( radius, theta_factor, VAR(synth_smooth) ); + fsincos(theta, &s, &c); + + // Write to running totals for transform + FPx += VVAR * radius * s; + FPy += VVAR * radius * c; + break; + + + case MODE_BUBBLE: // Power NO, Smooth YES + // Re-write of bubble with synth tweak + Vx = FTx; + Vy = FTy; + radius = sqrt(Vx * Vx + Vy * Vy) / ( (Vx * Vx + Vy * Vy)/4 + 1); + + // Get angle and angular factor + theta = atan2(Vx, Vy); + theta_factor = synth_value( vp, theta ); + radius = interpolate( radius, theta_factor, VAR(synth_smooth) ); + fsincos(theta, &s, &c); + + // Write to running totals for transform + FPx += VVAR * radius * s; + FPy += VVAR * radius * c; + break; + + + case MODE_BLUR_LEGACY: // Power YES, Smooth YES + // "old" blur style, has some problems with moire-style artefacts + radius = ( random01() + random01() + 0.002 * random01() ) / 2.002; + theta = 2.0 * M_PI * random01() - M_PI; + Vx = radius * sin(theta); + Vy = radius * cos(theta); + radius = pow( radius * radius + EPS, VAR(synth_power)/2.0); + + // Get angle and angular factor + theta_factor = synth_value( vp, theta ); + radius = VVAR * interpolate( radius, theta_factor, VAR(synth_smooth) ); + + // Write back to running totals for new vector + FPx += Vx * radius; + FPy += Vy * radius; + break; + + + case MODE_BLUR_NEW: // Power YES, Smooth YES + // Blur style, with normal smoothing function + + // Choose radius randomly, then adjust distribution using pow + radius = 0.5 * ( random01() + random01() ); + theta = 2 * M_PI * random01() - M_PI; + radius = pow( radius * radius + EPS, - VAR(synth_power)/2.0 ); + + // Get angular factor defining the shape + theta_factor = synth_value( vp, theta ); + + // Get final radius after synth applied + radius = interpolate( radius, theta_factor, VAR(synth_smooth) ); + fsincos(theta, &s, &c); + + // Write to running totals for transform + FPx += VVAR * radius * s; + FPy += VVAR * radius * c; + break; + + + case MODE_BLUR_RING: // Power YES, Smooth YES + // Blur style, with normal smoothing function + + radius = 1.0 + 0.1 * ( random01() + random01() - 1.0 ) * VAR(synth_power); + theta = 2 * M_PI * random01() - M_PI; + + // Get angular factor defining the shape + theta_factor = synth_value( vp, theta ); + + // Get final radius after synth applied + radius = interpolate( radius, theta_factor, VAR(synth_smooth) ); + fsincos(theta, &s, &c); + + // Write to running totals for transform + FPx += VVAR * radius * s; + FPy += VVAR * radius * c; + break; + + + case MODE_BLUR_RING2: // Power YES, Smooth NO + // Simple, same-thickness ring + + // Choose radius randomly, then adjust distribution using pow + theta = 2 * M_PI * random01() - M_PI; + + radius = pow( random01() + EPS, VAR(synth_power) ); + + // Get final radius after synth applied + radius = synth_value( vp, theta ) + 0.1 * radius; + fsincos(theta, &s, &c); + + // Write to running totals for transform + FPx += VVAR * radius * s; + FPy += VVAR * radius * c; + break; + + + case MODE_SHIFTTHETA: // Power YES, Smooth NO + // Use (adjusted) radius to move point around circle + Vx = FTx; + Vy = FTy; + + radius = pow(Vx * Vx + Vy * Vy + EPS, VAR(synth_power)/2.0 ); + + theta = atan2( Vx, Vy ) - 1.0 + synth_value( vp, radius ); + + fsincos(theta, &s, &c); + + // Write to running totals for transform + FPx += VVAR * radius * s; + FPy += VVAR * radius * c; + break; + + + case MODE_BLUR_ZIGZAG: // Power YES, Smooth YES + // Blur effect based on line segment + // theta is used as x value + // Vy is y value + Vy = 1.0 + 0.1 * ( random01() + random01() - 1.0 ) * VAR(synth_power); + theta = 2.0 * asin( (random01()- 0.5) * 2.0 ); + + // Get angular factor defining the shape + theta_factor = synth_value( vp, theta ); + + // Get new location + Vy = interpolate( Vy, theta_factor, VAR(synth_smooth) ); + + // Write to running totals for transform + FPx += VVAR * ( theta / M_PI ); + FPy += VVAR * ( Vy - 1.0 ); + break; + + + case MODE_SHIFTX: // Power NO, Smooth YES + // Use x and y values directly + Vx = FTx; + Vy = FTy; + + // Write to running totals for transform + FPx += VVAR * ( Vx + synth_value( vp, Vy ) - 1.0); + FPy += VVAR * Vy; + break; + + + case MODE_SHIFTY: // Power NO, Smooth NO + // Use x and y values directly + Vx = FTx; + Vy = FTy; + + // Write to running totals for transform + FPx += VVAR * Vx; + FPy += VVAR * ( Vy + synth_value( vp, Vx ) - 1.0); + + break; + + + case MODE_SHIFTXY: // Power NO, Smooth NO + // Use x and y values directly + Vx = FTx; + Vy = FTy; + + // Write to running totals for transform + FPx += VVAR * ( Vx + synth_value( vp, Vy ) - 1.0); + FPy += VVAR * ( Vy + synth_value( vp, Vx ) - 1.0); + + break; + + + case MODE_SINUSOIDAL: // Power NO, Smooth NO + Vx = FTx; + Vy = FTy; + + // The default mix=0 is same as normal sin + FPx += VVAR * ( synth_value( vp, Vx ) - 1.0 + (1.0-VAR(synth_mix)) * sin (Vx) ); + FPy += VVAR * ( synth_value( vp, Vy ) - 1.0 + (1.0-VAR(synth_mix)) * sin (Vy) ); + + break; + + + case MODE_SWIRL: // Power YES, Smooth WAVE + Vx = FTx; + Vy = FTy; + + radius = pow( Vx * Vx + Vy * Vy + EPS, VAR(synth_power)/2.0 ); + + // Synth-modified sine & cosine + synthsincos( vp, radius, &s, &c, VAR(synth_smooth) ); + + FPx += VVAR * (s * Vx - c * Vy); + FPy += VVAR * (c * Vx + s * Vy); + + break; + + + case MODE_HYPERBOLIC: // Power YES, Smooth WAVE + Vx = FTx; + Vy = FTy; + + radius = pow(Vx * Vx + Vy * Vy + EPS, VAR(synth_power)/2.0 ); + + theta = atan2( Vx, Vy ); + + // Synth-modified sine & cosine + synthsincos( vp, theta, &s, &c, VAR(synth_smooth) ); + + FPx += VVAR * s / radius; + FPy += VVAR * c * radius; + + break; + + + case MODE_JULIA: // Power YES, Smooth WAVE + Vx = FTx; + Vy = FTy; + + radius = pow(Vx * Vx + Vy * Vy + EPS, VAR(synth_power)/4.0 ); + + theta = atan2( Vx, Vy )/2.0; + + if ( random01() < 0.5 ) theta += M_PI; + + // Synth-modified sine & cosine + synthsincos( vp, theta, &s, &c, VAR(synth_smooth) ); + + FPx += VVAR * radius * c; + FPy += VVAR * radius * s; + + break; + + + case MODE_DISC: // Power YES, Smooth WAVE + Vx = FTx; + Vy = FTy; + + theta = atan2( Vx, Vy ) / M_PI; + + radius = M_PI * pow(Vx * Vx + Vy * Vy + EPS, VAR(synth_power)/2.0 ); + + // Synth-modified sine & cosine + synthsincos( vp, radius, &s, &c, VAR(synth_smooth) ); + + FPx = VVAR * s * theta; + FPy = VVAR * c * theta; + + break; + + + case MODE_RINGS: // Power PARAM, Smooth WAVE + + Vx = FTx; + Vy = FTy; + radius = sqrt( Vx * Vx + Vy * Vy ); + theta = atan2( Vx, Vy ); + + mu = VAR(synth_power) * VAR(synth_power) + EPS; + + radius += -2.0 * mu * (int)((radius + mu)/( 2.0 * mu )) + radius * ( 1.0 - mu ); + + synthsincos( vp, radius, &s, &c, VAR(synth_smooth) ); + + FPx += VVAR * s * radius; + FPy += VVAR * c * radius; + + break; + + + case MODE_CYLINDER: // Power YES, Smooth WAVE + Vx = FTx; + Vy = FTy; + radius = pow(Vx * Vx + Vy * Vy + EPS, VAR(synth_power)/2.0 ); + + // Modified sine only used here + synthsincos( vp, Vx, &s, &c, VAR(synth_smooth) ); + + FPx += VVAR * radius * s; + FPy += VVAR * radius * Vy; + + break; + } + + return TRUE; +} diff --git a/Plugin/tan.c b/Plugin/tan.c new file mode 100644 index 0000000..385e1dc --- /dev/null +++ b/Plugin/tan.c @@ -0,0 +1,53 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("tan"); + + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + + // Always return TRUE. + return TRUE; +} + +// Calculates the function z' = tan(z) = sin(z)/cos(z) + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double sinx, cosx, sinhy, coshy; + + fsincos(2 * FTx, &sinx, &cosx); + sinhcosh(2 * FTy, &sinhy, &coshy); + + double denom = VVAR / (cosx + coshy + EPS); + + FPx += sinx * denom; + FPy += sinhy * denom; + + return TRUE; +} + diff --git a/Plugin/twoface.c b/Plugin/twoface.c new file mode 100644 index 0000000..765bcb6 --- /dev/null +++ b/Plugin/twoface.c @@ -0,0 +1,47 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("twoface"); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + return TRUE; // Always return TRUE. +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double r = VVAR; + + if (FTx > 0.0) + { + r /= sqr(FTx) + sqr(FTy); + } + + FPx += r * FTx; + FPy += r * FTy; + + return TRUE; +} diff --git a/Plugin/unpolar.c b/Plugin/unpolar.c new file mode 100644 index 0000000..bee5cac --- /dev/null +++ b/Plugin/unpolar.c @@ -0,0 +1,54 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double unpolar_vvar; + double unpolar_vvar_2; +} Variables; + +#define _USE_MATH_DEFINES +#define APO_NOVARIABLES +#define APO_VIRTUALVAR +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("unpolar"); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + VAR(unpolar_vvar) = VVAR / M_PI; + VAR(unpolar_vvar_2) = VAR(unpolar_vvar) * 0.5; + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double r = exp(FTy); + double c, s; + fsincos(FTx, &s, &c); + + FPy += VAR(unpolar_vvar_2) * r * c; + FPx += VAR(unpolar_vvar_2) * r * s; + + return TRUE; +} diff --git a/Plugin/wavesn.c b/Plugin/wavesn.c new file mode 100644 index 0000000..374d6b8 --- /dev/null +++ b/Plugin/wavesn.c @@ -0,0 +1,66 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double wavesn_freqx, wavesn_freqy; + double wavesn_scalex, wavesn_scaley; + double wavesn_incx, wavesn_incy; + int wavesn_power; + + int absN; + double cN; +} Variables; + +#include "apoplugin.h" + +APO_PLUGIN("wavesn"); + +APO_VARIABLES( + VAR_REAL(wavesn_freqx, 2.0), VAR_REAL(wavesn_freqy, 2.0), + VAR_REAL(wavesn_scalex, 1.0), VAR_REAL(wavesn_scaley, 1.0), + VAR_REAL(wavesn_incx, 0.0), VAR_REAL(wavesn_incy, 0.0), + VAR_INTEGER_NONZERO(wavesn_power, 1.0) +); + +int PluginVarPrepare(Variation* vp) +{ + VAR(absN) = (int)abs(VAR(wavesn_power)); + if (VAR(wavesn_power) == 0) VAR(wavesn_power) = 2; + VAR(cN) = 1.0 / VAR(wavesn_power) / 2; + return TRUE; +} + +int PluginVarCalc(Variation* vp) +{ + double angle = (atan2(FTy, FTx) + M_2PI * (rand() % (int)VAR(absN)))/ VAR(wavesn_power); + double r = VVAR * pow(sqr(FTx) + sqr(FTy), VAR(cN)); + + double sina = 0, cosa = 0; + fsincos(angle, &sina, &cosa); + double xn = r * cosa; + double yn = r * sina; + + double siny = sin(VAR(wavesn_freqx) * yn); double sinx = sin(VAR(wavesn_freqy) * xn); + double dx = xn + 0.5 * (VAR(wavesn_scalex) * siny + fabs(xn) * VAR(wavesn_incx) * siny); + double dy = yn + 0.5 * (VAR(wavesn_scaley) * sinx + fabs(yn) * VAR(wavesn_incy) * sinx); + FPx += VVAR * dx; + FPy += VVAR * dy; + + return TRUE; +} diff --git a/Plugin/whorl.c b/Plugin/whorl.c new file mode 100644 index 0000000..3e38b01 --- /dev/null +++ b/Plugin/whorl.c @@ -0,0 +1,68 @@ +/* + Apophysis Plugin + + Copyright (C) 2007-2009 Michael Faber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + double whorl_inside; + double whorl_outside; +} Variables; + +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("whorl"); + +// Define the Variables +APO_VARIABLES( + VAR_REAL(whorl_inside, 1.0), + VAR_REAL(whorl_outside, 1.0) +); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + // Always return TRUE. + return TRUE; +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double a, r; + double sina, cosa; + + r = sqrt(FTx*FTx + FTy*FTy); + + if(r < VVAR) + { + a = atan2(FTy, FTx) + VAR(whorl_inside)/(VVAR - r); + } + else + { + a = atan2(FTy, FTx) + VAR(whorl_outside)/(VVAR - r); + } + fsincos(a, &sina, &cosa); + FPx += VVAR*r*cosa; + FPy += VVAR*r*sina; + + return TRUE; +} + diff --git a/Plugin/xheart.c b/Plugin/xheart.c new file mode 100644 index 0000000..916006a --- /dev/null +++ b/Plugin/xheart.c @@ -0,0 +1,66 @@ +/* + Apophysis Plugin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +typedef struct +{ + double cosa, sina, rat; + double xheart_angle; + double xheart_ratio; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +APO_PLUGIN("xheart"); + +APO_VARIABLES( + VAR_REAL(xheart_angle, 0.0), + VAR_REAL(xheart_ratio, 0.0) +); + +int PluginVarPrepare(Variation* vp) +{ + double c, s; double ang = M_PI_4 + (0.5 * M_PI_4 * VAR(xheart_angle)); + fsincos(ang, &s, &c); VAR(cosa) = c; VAR(sina) = s; + + double r = 6 + 2 * VAR(xheart_ratio); + VAR(rat) = r; + + return TRUE; +} + +inline double lerp(double a, double b, double x) { x=(x<0)?0:x; x=(x>1)?1:x;return x+(b-a)*x; } + +int PluginVarCalc(Variation* vp) +{ + double r2_4 = sqr(FTx) + sqr(FTy) + 4; + if (r2_4 == 0) r2_4 = 1; + double bx = 4 / r2_4, by = VAR(rat) / r2_4; + double x = VAR(cosa) * (bx*FTx) - VAR(sina) * (by*FTy); + double y = VAR(sina) * (bx*FTx) + VAR(cosa) * (by*FTy); + + if (x > 0) { + FPx += VVAR * x; + FPy += VVAR * y; + } else { + FPx += VVAR * x; + FPy += -VVAR * y; + } + + return TRUE; +} diff --git a/Plugin/xtrb.c b/Plugin/xtrb.c new file mode 100644 index 0000000..d70a33d --- /dev/null +++ b/Plugin/xtrb.c @@ -0,0 +1,295 @@ +/* +Apophysis Plugin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* +Some comments on TriBorders plugin structure. It builds dual tessellation +on triangle grid as Boarders variation does for square one and it uses +trilinear coordinates ([link]) +instead of usual Cartesian system (from where Tri Borders in plugin name). +Hex function doesn’t work correctly in general case because its second part +(determines nonlinear texture) doesn’t transform lines (passes from triangle vertex) +to itself for arbitrary triangle. +It possible to do and I’ve done main job but have not finished. +*/ + +// Must define this structure before we include apoplugin.h +typedef struct +{ + int xtrb_power; + double xtrb_dist; + double xtrb_radius, xtrb_width, xtrb_a, xtrb_b; + double angle_Ar, angle_Br, angle_Cr; + double sinA2, cosA2, sinB2, cosB2, sinC2, cosC2, sinC, cosC; + double a, b, c; + double Ha, Hb, Hc, S2; + double ab, ac, ba, bc, ca, cb, S2a, S2b, S2c, S2ab, S2ac, S2bc; + double width1, width2, width3; + double absN, cN; +} Variables; + +#define _USE_MATH_DEFINES +#include "apoplugin.h" + +// Set the name of this plugin +APO_PLUGIN("xtrb"); + +// Define the Variables +APO_VARIABLES( + VAR_INTEGER_NONZERO(xtrb_power, 2), + VAR_REAL(xtrb_radius, 1.0), + VAR_REAL(xtrb_width, 0.5), + VAR_REAL(xtrb_dist, 1.0), + VAR_REAL(xtrb_a, 1.0), + VAR_REAL(xtrb_b, 1.0) + ); + +// You must call the argument "vp". +int PluginVarPrepare(Variation* vp) +{ + //VAR(angle_B)= 60; + //VAR(angle_C)= 60; + + VAR(angle_Br) = 0.047 + VAR(xtrb_a);///180.0*M_PI; // angeles in radians + VAR(angle_Cr) = 0.047 + VAR(xtrb_b);///180.0*M_PI; + VAR(angle_Ar) =M_PI - VAR(angle_Br) - VAR(angle_Cr); + + fsincos(0.5*VAR(angle_Ar), &VAR(sinA2), &VAR(cosA2)); // its sin, cos + fsincos(0.5*VAR(angle_Br), &VAR(sinB2), &VAR(cosB2)); + fsincos(0.5*VAR(angle_Cr), &VAR(sinC2), &VAR(cosC2)); + fsincos( VAR(angle_Cr), &VAR(sinC), &VAR(cosC)); + + VAR(a) = VAR(xtrb_radius)*( VAR(sinC2)/VAR(cosC2)+ VAR(sinB2)/VAR(cosB2)); //sides + VAR(b) = VAR(xtrb_radius)*( VAR(sinC2)/VAR(cosC2)+ VAR(sinA2)/VAR(cosA2)); + VAR(c) = VAR(xtrb_radius)*( VAR(sinB2)/VAR(cosB2)+ VAR(sinA2)/VAR(cosA2)); + + VAR(width1) = 1 - VAR(xtrb_width); + VAR(width2) = 2* VAR(xtrb_width); + VAR(width3) = 1 - VAR(xtrb_width)*VAR(xtrb_width); + + VAR(S2) = VAR(xtrb_radius)*( VAR(a)+VAR(b) +VAR(c)); //square + + VAR(Ha) = VAR(S2)/VAR(a)/6.0; //Hight div on 6.0 + VAR(Hb) = VAR(S2)/VAR(b)/6.0; + VAR(Hc) = VAR(S2)/VAR(c)/6.0; + + VAR(ab) = VAR(a)/VAR(b);// a div on b + VAR(ac) = VAR(a)/VAR(c); + VAR(ba) = VAR(b)/VAR(a); + VAR(bc) = VAR(b)/VAR(c); + VAR(ca) = VAR(c)/VAR(a); + VAR(cb) = VAR(c)/VAR(b); + VAR(S2a) = 6.0*VAR(Ha); + VAR(S2b) = 6.0*VAR(Hb); + VAR(S2c) = 6.0*VAR(Hc); + VAR(S2bc) =VAR(S2)/(VAR(b)+VAR(c))/6.0; + VAR(S2ab) =VAR(S2)/(VAR(a)+VAR(b))/6.0; + VAR(S2ac) =VAR(S2)/(VAR(a)+VAR(c))/6.0; + + VAR(absN) = (int)abs(VAR(xtrb_power)); + VAR(cN) = VAR(xtrb_dist) / VAR(xtrb_power) / 2; + + + // Always return TRUE. + return TRUE; +} + +void DirectTrilinear(Variation* vp, double x, double y, double* Al, double* Be, double* Ga) +{ + double U = y + VAR(xtrb_radius); + double V = x * VAR(sinC) - y * VAR(cosC) + VAR(xtrb_radius); + *Al =U; + *Be =V; + *Ga = VAR(S2c) - VAR(ac) * U - VAR(bc) * V; +} + +void InverseTrilinear(Variation* vp, double Al, double Be, double* x, double* y) +{ + double inx = (Be - VAR(xtrb_radius) +(Al - VAR(xtrb_radius))* VAR(cosC))/ VAR(sinC); + double iny = Al - VAR(xtrb_radius); + + double sina = 0.0, cosa = 0.0; + + double angle = (atan2(iny, inx) + M_2PI * (rand() % (int)VAR(absN)))/ VAR(xtrb_power); + double r = VVAR * pow(sqr(inx) + sqr(iny), VAR(cN)); + + fsincos(angle, &sina, &cosa); + *x = r * cosa; + *y = r * sina; + //*x = 0; *y = 0; +} + +void Hex(Variation* vp, double Al, double Be, double Ga, double* Al1, double* Be1) // it's necessary + //to improve for correct work for any triangle +{ + double Ga1, De1, R; + R = random01(); + if (Be < Al) + { + if (Ga < Be) + { + if (R >= VAR(width3)) + { + De1 = VAR(xtrb_width) * Be; + Ga1 = VAR(xtrb_width) * Ga; + } + else + { + Ga1 = VAR(width1) * Ga + VAR(width2)*VAR(Hc)* Ga / Be; + De1 = VAR(width1)*Be+VAR(width2)*VAR(S2ab)*(3 -Ga / Be); + + } + *Al1 = VAR(S2a) - VAR(ba)* De1 - VAR(ca)* Ga1; + *Be1 = De1; + + } + else + { + if (Ga < Al) + { + if (R >= VAR(width3)) + { + Ga1 = VAR(xtrb_width) * Ga; + De1 = VAR(xtrb_width) * Be; + } + else + { + De1 = VAR(width1) * Be + VAR(width2)*VAR(Hb)* Be / Ga; + Ga1 = VAR(width1)*Ga+VAR(width2)*VAR(S2ac)*(3 -Be / Ga); + + } + *Al1 = VAR(S2a) - VAR(ba)* De1 - VAR(ca)* Ga1; + *Be1 = De1; + } + else + { + if (R >= VAR(width3)) + { + *Al1 = VAR(xtrb_width) * Al; + *Be1 = VAR(xtrb_width) * Be; + } + else + { + *Be1 = VAR(width1) * Be+VAR(width2)*VAR(Hb)* Be / Al; + *Al1 = VAR(width1) * Al+VAR(width2)*VAR(S2ac)*(3-Be /Al); + + } + + } + } + } + else + { + if (Ga < Al) + { + if (R >= VAR(width3)) + { + De1 = VAR(xtrb_width) * Al; + Ga1 = VAR(xtrb_width) * Ga; + + } + else + { + Ga1 = VAR(width1) * Ga+VAR(width2)*VAR(Hc)* Ga / Al; + De1 = VAR(width1) *Al+VAR(width2)*VAR(S2ab)*(3 -Ga /Al); + + } + *Be1 = VAR(S2b) - VAR(ab)* De1 - VAR(cb)* Ga1; + *Al1 = De1; + + } + else + { + if (Ga < Be) + { + if (R >= VAR(width3)) + { + Ga1 = VAR(xtrb_width) * Ga; + De1 = VAR(xtrb_width) * Al; + } + else + { + De1 = VAR(width1) * Al + VAR(width2)*VAR(Ha)* Al / Ga; + Ga1 = VAR(width1)*Ga + VAR(width2)*VAR(S2bc)*(3 -Al/Ga); + + } + *Be1 = VAR(S2b) - VAR(ab)* De1 - VAR(cb)* Ga1; + *Al1 = De1; + + } + else + { + if (R >= VAR(width3)) + { + *Be1 = VAR(xtrb_width) * Be; + *Al1 = VAR(xtrb_width) * Al; + } + else + { + *Al1 = VAR(width1) * Al + VAR(width2)*VAR(Ha)* Al / Be; + *Be1 = VAR(width1)*Be+VAR(width2)*VAR(S2bc)*(3-Al / Be); + + } + + } + } + } +} + +// You must call the argument "vp". +int PluginVarCalc(Variation* vp) +{ + double Alpha, Beta, Gamma, OffsetAl, OffsetBe, OffsetGa, X, Y; + int M, N; + + // transfer to trilinear coordinates, normalized to real distances from triangle sides + + DirectTrilinear(vp, FTx, FTy, &Alpha, &Beta, &Gamma); + + M = floor(Alpha/VAR(S2a)); + OffsetAl = Alpha - M*VAR(S2a); + N = floor(Beta/VAR(S2b)); + OffsetBe = Beta - N*VAR(S2b); + OffsetGa = VAR(S2c) - VAR(ac)*OffsetAl - VAR(bc)*OffsetBe; + + if ( OffsetGa > 0 ) + { + Hex(vp, OffsetAl, OffsetBe, OffsetGa, &Alpha, &Beta); + + } + + else + { + OffsetAl = VAR(S2a) - OffsetAl; + OffsetBe = VAR(S2b) - OffsetBe; + OffsetGa = - OffsetGa; + + Hex(vp, OffsetAl, OffsetBe, OffsetGa, &Alpha, &Beta); + + Alpha = VAR(S2a) - Alpha; + Beta = VAR(S2b) - Beta; + + } + Alpha = Alpha + M*VAR(S2a); + Beta = Beta + N*VAR(S2b); + + InverseTrilinear(vp, Alpha, Beta, &X, &Y); + FPx += VVAR * X; + FPy += VVAR * Y; + + return TRUE; +} diff --git a/Rendering/BucketFillerThread.pas b/Rendering/BucketFillerThread.pas new file mode 100644 index 0000000..c9aabc7 --- /dev/null +++ b/Rendering/BucketFillerThread.pas @@ -0,0 +1,109 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit BucketFillerThread; + +interface + +uses + Classes, Windows, ControlPoint, RenderingInterface, XForm; + +type + TBucketFillerThread = class(TThread) + + private + fcp: TControlPoint; + points: TPointsArray; + + public + nrbatches: integer; + batchcounter: Pinteger; + + ColorMap: TColorMapArray; + CriticalSection: TRTLCriticalSection; + + AddPointsProc: procedure (const points: TPointsArray) of object; + + constructor Create(cp: TControlPoint); + destructor Destroy; override; + + procedure Execute; override; + + end; + +implementation + +//uses SysUtils, FormRender; + +/////////////////////////////////////////////////////////////////////////////// +constructor TBucketFillerThread.Create(cp: TControlPoint); +begin + inherited Create(True); + //Self.FreeOnTerminate := True; + + Fcp := cp.Clone; + + SetLength(Points, SUB_BATCH_SIZE); + + fcp.Prepare; +end; + +/////////////////////////////////////////////////////////////////////////////// +destructor TBucketFillerThread.Destroy; +begin + FCP.Free; + + inherited; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBucketFillerThread.Execute; +var + bc: integer; +begin + inherited; + //RenderForm.Output.Lines.Add(' . . . > Filler thread #' + IntToStr(ThreadID) + ' Started'); + + bc := 0; + while (not Terminated) and (bc < Nrbatches) do begin + fcp.iterateXYC(SUB_BATCH_SIZE, points); + + try + EnterCriticalSection(CriticalSection); + + AddPointsProc(Points); + + Inc(batchcounter^); + bc := batchcounter^ + finally + LeaveCriticalSection(CriticalSection); + end; + end; + //RenderForm.Output.Lines.Add(' . . . > Filler thread #' + IntToStr(ThreadID) + ' Finished'); +end; + +/////////////////////////////////////////////////////////////////////////////// + +{ -- RENDER THREAD MUST *NOT* KNOW ANYTHING ABOUT BUCKETS!!! -- } + +end. diff --git a/Rendering/ImageMaker.pas b/Rendering/ImageMaker.pas new file mode 100644 index 0000000..01f7217 --- /dev/null +++ b/Rendering/ImageMaker.pas @@ -0,0 +1,849 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit ImageMaker; + +interface + +uses + Windows, Graphics, ControlPoint, RenderingCommon, PngImage, Bezier; + +type TPalette = record + logpal : TLogPalette; + colors: array[0..255] of TPaletteEntry; + end; + +type + TImageMaker = class + private + FOversample: Integer; + FFilterSize: Integer; + FFilter: array of array of double; + FParameters : String; + + FBitmap: TBitmap; + FAlphaBitmap: TBitmap; + AlphaPalette: TPalette; + FTransparentImage: TBitmap; + + comp_max_radius, comp_min_radius : double; + num_de_filters_d, num_de_filters : double; + de_max_ind, de_count_limit : double; + de_cutoff_val : double; + de_row_size, de_half_size, de_kernel_index : double; + de_filter_coefs, de_filter_widths : array of double; + + FCP: TControlPoint; + + FBucketHeight: integer; + FBucketWidth: integer; + FBuckets: TBucketArray; + FOnProgress: TOnProgress; + FGetBucket: function(x, y: integer): TBucket of object; + function GetBucket(x, y: integer): TBucket; + function SafeGetBucket(x, y: integer): TBucket; + + procedure CreateFilter; + procedure InitDE; + procedure NormalizeFilter; + + public + constructor Create; + destructor Destroy; override; + + function GetImage: TBitmap; + procedure GetImageAndDelete(target:tBitmap); + function GetTransparentImage: TPNGObject; + + procedure SetCP(CP: TControlPoint); + procedure Init; + procedure SetBucketData(const Buckets: pointer; BucketWidth, BucketHeight: integer; bits: integer); + + function GetFilterSize: Integer; + + procedure CreateImage(YOffset: integer = 0); + procedure SaveImage(FileName: String); + + procedure GetBucketStats(var Stats: TBucketStats); + + property OnProgress: TOnProgress +// read FOnProgress + write FOnProgress; + end; + +implementation + +uses + Math, SysUtils, JPEG, Global, Types; + +{ TImageMaker } + +type + TRGB = packed Record + blue: byte; + green: byte; + red: byte; + end; + + PByteArray = ^TByteArray; + TByteArray = array[0..0] of byte; +// PLongintArray = ^TLongintArray; +// TLongintArray = array[0..0] of Longint; + PRGBArray = ^TRGBArray; + TRGBArray = array[0..0] of TRGB; + +/////////////////////////////////////////////////////////////////////////////// +constructor TImageMaker.Create; +var + i: integer; +begin + AlphaPalette.logpal.palVersion := $300; + AlphaPalette.logpal.palNumEntries := 256; + for i := 0 to 255 do + with AlphaPalette.logpal.palPalEntry[i] do begin + peRed := i; + peGreen := i; + peBlue := i; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +destructor TImageMaker.Destroy; +begin + if assigned(FBitmap) then + FBitmap.Free; + + if assigned(FAlphaBitmap) then + FAlphaBitmap.Free; + + if assigned(FTransparentImage) then + FTransparentImage.Free; + + inherited; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TImageMaker.CreateFilter; +var + i, j: integer; + fw: integer; + adjust: double; + ii, jj: double; +begin + + FOversample := fcp.spatial_oversample; + fw := Trunc(2.0 * FILTER_CUTOFF * FOversample * fcp.spatial_filter_radius); + FFilterSize := fw + 1; + + // make sure it has same parity as oversample + if odd(FFilterSize + FOversample) then + inc(FFilterSize); + + if (fw > 0.0) then + adjust := (1.0 * FILTER_CUTOFF * FFilterSize) / fw + else + adjust := 1.0; + + setLength(FFilter, FFilterSize, FFilterSize); + if fcp.enable_de and false then InitDE; + + for i := 0 to FFilterSize - 1 do begin + for j := 0 to FFilterSize - 1 do begin + ii := ((2.0 * i + 1.0)/ FFilterSize - 1.0) * adjust; + jj := ((2.0 * j + 1.0)/ FFilterSize - 1.0) * adjust; + + FFilter[i, j] := exp(-2.0 * (ii * ii + jj * jj)); + end; + end; + + Normalizefilter; +end; + +procedure TImageMaker.InitDE; +var + e, em, ec : double; + filtloop : integer; + + de_filt_sum, de_filt_d, de_filt_h : double; + adjloop, sfx : double; + dej,dek, filter_coef_idx : integer; + sl : integer; +begin + de_filt_sum := 0; + + if (fcp.estimator < 0.0) then + e := 0 + else + e := fcp.estimator; + + if (fcp.estimator_min < 0.0) then + em := 0 + else + em := fcp.estimator_min; + + if (fcp.estimator_curve < 0.0) then + ec := 0 + else + ec := fcp.estimator_curve; + + if (e <= 0) then exit; + + comp_max_radius := e*Foversample + 1; + comp_min_radius := em*Foversample + 1; + + num_de_filters_d := power(comp_max_radius/comp_min_radius, (1.0/ec)); + num_de_filters := ceil(num_de_filters_d); + + if (num_de_filters>100) then begin + de_max_ind := ceil(100 + power(num_de_filters - 100, ec)) + 1; + de_count_limit := power(de_max_ind - 100, 1.0/ec) + 100; + end else begin + de_max_ind := num_de_filters; + de_count_limit := de_max_ind; + end; + + de_row_size := 2*ceil(comp_max_radius)-1; + de_half_size := (de_row_size-1)/2; + de_kernel_index := (de_half_size+1)*(2+de_half_size)/2; + + sl := Trunc(de_max_ind * de_kernel_index); + //assert(sl >= 0); + if (sl < 0) then sl := 0; + setLength(de_filter_coefs, sl); + + sl := Trunc(de_max_ind); + //assert(sl >= 0); + if (sl < 0) then sl := 0; + setLength(de_filter_widths, sl); + + de_cutoff_val := 0; + for filtloop := 0 to trunc(de_max_ind)-1 do begin + if (filtloop < 100) then + de_filt_h := (comp_max_radius / power(filtloop+1, ec)) + else begin + adjloop := power(filtloop - 100, (1/ec))+100; + de_filt_h := (comp_max_radius / power(adjloop+1, ec)) + end; + + if (de_filt_h <= comp_min_radius) then begin + de_filt_h := comp_min_radius; + de_cutoff_val := filtloop; + end; + + de_filter_widths[filtloop] := de_filt_h; + + for dej := -trunc(de_half_size) to trunc(de_half_size) do + for dek := -trunc(de_half_size) to trunc(de_half_size) do begin + de_filt_d := sqrt(dej * dej + dek * dek) / de_filt_h; + if (de_filt_d <= 1.0) then begin + sfx := 1.8 * de_filt_d; + de_filt_sum := de_filt_sum + (exp(-2.0*sfx*sfx)*0.7978845608); + end; // -X- ^^^ sqrt(2/PI) + end; + + filter_coef_idx := filtloop * trunc(de_kernel_index); + + for dej := 0 to trunc(de_half_size) do + for dek := 0 to dej-1 do begin + de_filt_d := sqrt(dej * dej + dek * dek) / de_filt_h; + if (de_filt_d>1.0) then begin + // -X- TODO fix... + if (filter_coef_idx >= 0) and (filter_coef_idx < Trunc(de_max_ind * de_kernel_index)) then + de_filter_coefs[filter_coef_idx] := 0 + end else begin + sfx := 1.8 * de_filt_d; + if (filter_coef_idx >= 0) and (filter_coef_idx < Trunc(de_max_ind * de_kernel_index)) then + de_filter_coefs[filter_coef_idx] := (exp(-2.0*sfx*sfx)*0.7978845608) / de_filt_sum; + end; + Inc(filter_coef_idx); + end; + + if (de_cutoff_val > 0) then break; + end; + + if (de_cutoff_val=0) then + de_cutoff_val := num_de_filters-1; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TImageMaker.NormalizeFilter; +var + i, j: integer; + t: double; +begin + t := 0; + for i := 0 to FFilterSize - 1 do + for j := 0 to FFilterSize - 1 do + t := t + FFilter[i, j]; + + for i := 0 to FFilterSize - 1 do + for j := 0 to FFilterSize - 1 do + FFilter[i, j] := FFilter[i, j] / t; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TImageMaker.GetFilterSize: Integer; +begin + Result := FFiltersize; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TImageMaker.GetImage: TBitmap; +begin +// if ShowTransparency then +// Result := GetTransparentImage +// else + Result := FBitmap; +end; + +procedure TImageMaker.GetImageAndDelete(target:tBitmap); +begin + assert(false); + //target.Assign(FBitmap); + //FBitmap.Free; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TImageMaker.Init; +begin + if not Assigned(FBitmap) then + FBitmap := TBitmap.Create; + + FBitmap.PixelFormat := pf24bit; + + FBitmap.Width := Fcp.Width; + FBitmap.Height := Fcp.Height; + + if not Assigned(FAlphaBitmap) then + FAlphaBitmap := TBitmap.Create; + + FAlphaBitmap.PixelFormat := pf8bit; + FAlphaBitmap.Width := Fcp.Width; + FAlphaBitmap.Height := Fcp.Height; + + CreateFilter; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TImageMaker.SetBucketData(const Buckets: pointer; BucketWidth, BucketHeight: integer; bits: integer); +begin + FBuckets := TBucketArray(Buckets); + + FBucketWidth := BucketWidth; + FBucketHeight := BucketHeight; + + FGetBucket := GetBucket; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TImageMaker.SetCP(CP: TControlPoint); +begin + Fcp := CP; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TImageMaker.CreateImage(YOffset: integer); +var + gamma: double; + i, j: integer; + alpha: double; + ri, gi, bi: Integer; + ai, ia: integer; + bgtot, zero_BG: TRGB; + ls: double; + ii, jj: integer; + fp: array[0..3] of double; + Row: PRGBArray; + AlphaRow: PbyteArray; + vib, notvib: Integer; + bgi: array[0..2] of Integer; +// bucketpos: Integer; + filterValue: double; +// filterpos: Integer; + lsa: array[0..1024] of double; + csa: array[0..3] of array[0..256] of double; + sample_density: extended; + gutter_width: integer; + k1, k2: double; + area: double; + frac, funcval: double; + f_select : double; + f_select_int, f_coef_idx : integer; + arr_filt_width : integer; + c : array of double; + ss : integer; + scf:boolean; + scfact : double; + acc : integer; + avg, fac: double; + curvesSet: boolean; + + GetBucket: function(x, y: integer): TBucket of object; + bucket: TBucket; + bx, by: integer; + label zero_alpha; +begin + SetLength(c, 4); + + if fcp.gamma = 0 then + gamma := fcp.gamma + else + gamma := 1 / fcp.gamma; + vib := round(fcp.vibrancy * 256.0); + notvib := 256 - vib; + + if fcp.gamma_threshold <> 0 then + funcval := power(fcp.gamma_threshold, gamma - 1) { / fcp.gamma_threshold; } + else funcval := 0; + + bgi[0] := round(fcp.background[0]); + bgi[1] := round(fcp.background[1]); + bgi[2] := round(fcp.background[2]); + bgtot.red := bgi[0]; + bgtot.green := bgi[1]; + bgtot.blue := bgi[2]; + zero_BG.red := 0; + zero_BG.green := 0; + zero_BG.blue := 0; + + curvesSet := true; + for i := 0 to 3 do + curvesSet := curvesSet and ( + ((fcp.curvePoints[i][0].x = 0) and (fcp.curvePoints[i][0].y = 0)) and + ((fcp.curvePoints[i][1].x = 0) and (fcp.curvePoints[i][1].y = 0)) and + ((fcp.curvePoints[i][2].x = 1) and (fcp.curvePoints[i][2].y = 1)) and + ((fcp.curvePoints[i][3].x = 1) and (fcp.curvePoints[i][3].y = 1)) + ); + curvesSet := not curvesSet; + + gutter_width := FBucketwidth - FOversample * fcp.Width; +// gutter_width := 2 * ((25 - Foversample) div 2); + if(FFilterSize <= gutter_width div 2) then // filter too big when 'post-processing' ? + GetBucket := FGetBucket + else + GetBucket := SafeGetBucket; + + FBitmap.PixelFormat := pf24bit; + + sample_density := fcp.actual_density * sqr( power(2, fcp.zoom) ); + if sample_density = 0 then sample_density := 0.001; + k1 := (fcp.Contrast * BRIGHT_ADJUST * fcp.brightness * 268 * PREFILTER_WHITE) / 256.0; + area := FBitmap.Width * FBitmap.Height / (fcp.ppux * fcp.ppuy); + k2 := (FOversample * FOversample) / (fcp.Contrast * area * fcp.White_level * sample_density); + + csa[0][0] := 0; csa[1][0] := 0; csa[2][0] := 0; csa[3][0] := 0; + for i := 0 to 1024 do begin + if i = 0 then lsa[0] := 0 + else lsa[i] := (k1 * log10(1 + fcp.White_level * i * k2)) / (fcp.White_level * i); + + if i <= 256 then begin + csa[0][i] := BezierFunc(i / 256.0, fcp.curvePoints[0], fcp.curveWeights[0]) * 256; + csa[1][i] := BezierFunc(i / 256.0, fcp.curvePoints[1], fcp.curveWeights[1]) * 256; + csa[2][i] := BezierFunc(i / 256.0, fcp.curvePoints[2], fcp.curveWeights[2]) * 256; + csa[3][i] := BezierFunc(i / 256.0, fcp.curvePoints[3], fcp.curveWeights[3]) * 256; + end; + end; + + ls := 0; + ai := 0; + + ss := Trunc(floor(FOversample / 2)); + scf := (trunc(FOversample) mod 2 = 0); + scfact := power(FOversample/(FOversample+1), 2); + + //bucketpos := 0; + by := 0; + for i := 0 to fcp.Height - 1 do begin + bx := 0; + + if (i and $3f = 0) and assigned(FOnProgress) then FOnProgress(i / fcp.Height); + + AlphaRow := PByteArray(FAlphaBitmap.scanline[YOffset + i]); + Row := PRGBArray(FBitmap.scanline[YOffset + i]); + for j := 0 to fcp.Width - 1 do begin + if FFilterSize > 1 then begin + fp[0] := 0; + fp[1] := 0; + fp[2] := 0; + fp[3] := 0; + + for ii := 0 to FFilterSize - 1 do begin + for jj := 0 to FFilterSize - 1 do begin + filterValue := FFilter[ii, jj]; + + bucket := GetBucket(bx + jj, by + ii); + if bucket.count < 1024 then + ls := lsa[Round(bucket.Count)] + else + ls := (k1 * log10(1 + fcp.White_level * bucket.count * k2)) / (fcp.White_level * bucket.count); + + fp[0] := fp[0] + filterValue * ls * bucket.Red; + fp[1] := fp[1] + filterValue * ls * bucket.Green; + fp[2] := fp[2] + filterValue * ls * bucket.Blue; + fp[3] := fp[3] + filterValue * ls * bucket.Count; + end; + end; + + fp[0] := fp[0] / PREFILTER_WHITE; + fp[1] := fp[1] / PREFILTER_WHITE; + fp[2] := fp[2] / PREFILTER_WHITE; + fp[3] := fcp.white_level * fp[3] / PREFILTER_WHITE; + end else begin + bucket := GetBucket(bx, by); + if bucket.count < 1024 then + ls := lsa[Round(bucket.count)] / PREFILTER_WHITE + else + ls := (k1 * log10(1 + fcp.White_level * bucket.count * k2)) / (fcp.White_level * bucket.count) / PREFILTER_WHITE; + + fp[0] := ls * bucket.Red; + fp[1] := ls * bucket.Green; + fp[2] := ls * bucket.Blue; + fp[3] := ls * bucket.Count * fcp.white_level; + end; + + if (num_de_filters > 0) and (fp[3] > 0) then begin + f_select := 0; + for ii := -ss to trunc(ss) + 1 do + for jj := -ss to trunc(ss) + 1 do begin + bucket := SafeGetBucket(bx + jj, by + ii); + f_select := f_select + (bucket.Count / 255.0); + end; + if (scf) then f_select := f_select * scfact; + + if (f_select > de_count_limit) then + f_select_int := trunc(de_cutoff_val) + else if (f_select <= 100) then + f_select_int := trunc(ceil(f_select)) - 1 + else + f_select_int := 100 + trunc(floor(power(f_select - 100, fcp.estimator_curve))); + + if (f_select_int >= de_cutoff_val) then + f_select_int := trunc(de_cutoff_val); + + f_coef_idx := trunc(f_select_int*de_kernel_index); + if (f_select_int >= 0) and (f_select_int < length(de_filter_widths)) then + arr_filt_width := trunc(floor(de_filter_widths[length(de_filter_widths) - 1 - f_select_int])) + else + arr_filt_width := 1; + + fp[0] := 0; + fp[1] := 0; + fp[2] := 0; + fp[3] := 0; + acc := 1; + + for jj := 0 to arr_filt_width do + for ii := 0 to arr_filt_width do begin + bucket := SafeGetBucket(bx+ii, by+jj); + + if (f_coef_idx < 0) or (f_coef_idx >= length(de_filter_coefs)) then continue; + if (de_filter_coefs[f_coef_idx]= 0) then begin + Inc(f_coef_idx); + continue; + end; + + if bucket.count < 1024 then + ls := lsa[Round(bucket.Count)] + else if bucket.count = 0 then + ls := 0 + else + ls := (k1 * log10(1 + fcp.White_level * bucket.count * k2)) / (fcp.White_level * bucket.count); + + fp[0] := fp[0] + bucket.Red * ls * de_filter_coefs[f_coef_idx]; + fp[1] := fp[1] + bucket.Green * ls * de_filter_coefs[f_coef_idx]; + fp[2] := fp[2] + bucket.Blue * ls * de_filter_coefs[f_coef_idx]; + fp[3] := fp[3] + bucket.Count * ls * de_filter_coefs[f_coef_idx]; + + Inc(acc); + Inc(f_coef_idx); + end; + + fp[0] := fp[0] * acc / PREFILTER_WHITE; + fp[1] := fp[1] * acc / PREFILTER_WHITE; + fp[2] := fp[2] * acc / PREFILTER_WHITE; + fp[3] := fcp.white_level * acc * fp[3] / PREFILTER_WHITE; + end; + + Inc(bx, FOversample); + + if fcp.Transparency then begin // -------------------------- Transparency + // gamma linearization + if (fp[3] > 0.0) then begin + if fp[3] <= fcp.gamma_threshold then begin + frac := fp[3] / fcp.gamma_threshold; + alpha := (1 - frac) * fp[3] * funcval + frac * power(fp[3], gamma); + end + else + alpha := power(fp[3], gamma); + + ls := vib * alpha / fp[3]; + ai := round(alpha * 256); + if (ai <= 0) then goto zero_alpha // ignore all if alpha = 0 + else if (ai > 255) then ai := 255; + //ia := 255 - ai; + end + else begin +zero_alpha: + Row[j] := zero_BG; + AlphaRow[j] := 0; + continue; + end; + + if (notvib > 0) then begin + ri := Round(ls * fp[0] + notvib * power(fp[0], gamma)); + gi := Round(ls * fp[1] + notvib * power(fp[1], gamma)); + bi := Round(ls * fp[2] + notvib * power(fp[2], gamma)); + end + else begin + ri := Round(ls * fp[0]); + gi := Round(ls * fp[1]); + bi := Round(ls * fp[2]); + end; + + // ignoring BG color in transparent renders.. + if (ri >= 0) and (ri <= 256) and (curvesSet) then ri := Round(csa[1][Round(csa[0][ri])]); + if (gi >= 0) and (gi <= 256) and (curvesSet) then gi := Round(csa[2][Round(csa[0][gi])]); + if (bi >= 0) and (bi <= 256) and (curvesSet) then bi := Round(csa[3][Round(csa[0][bi])]); + + ri := (ri * 255) div ai; // ai > 0 ! + if (ri < 0) then ri := 0 + else if (ri > 255) then ri := 255; + + gi := (gi * 255) div ai; + if (gi < 0) then gi := 0 + else if (gi > 255) then gi := 255; + + bi := (bi * 255) div ai; + if (bi < 0) then bi := 0 + else if (bi > 255) then bi := 255; + + Row[j].red := ri; + Row[j].green := gi; + Row[j].blue := bi; + AlphaRow[j] := ai; + end + else begin // ------------------------------------------- No transparency + if (fp[3] > 0.0) then begin + // gamma linearization + if fp[3] <= fcp.gamma_threshold then begin + frac := fp[3] / fcp.gamma_threshold; + alpha := (1 - frac) * fp[3] * funcval + frac * power(fp[3], gamma); + end + else + alpha := power(fp[3], gamma); + + ls := vib * alpha / fp[3]; + ai := round(alpha * 256); + if (ai < 0) then ai := 0 + else if (ai > 255) then ai := 255; + ia := 255 - ai; + end + else begin + // no intensity so simply set the BG; + Row[j] := bgtot; + continue; + end; + + if (notvib > 0) then begin + ri := Round(ls * fp[0] + notvib * power(fp[0], gamma)); + gi := Round(ls * fp[1] + notvib * power(fp[1], gamma)); + bi := Round(ls * fp[2] + notvib * power(fp[2], gamma)); + end + else begin + ri := Round(ls * fp[0]); + gi := Round(ls * fp[1]); + bi := Round(ls * fp[2]); + end; + + if (ri >= 0) and (ri <= 256) and (curvesSet) then ri := Round(csa[1][Round(csa[0][ri])]); + if (gi >= 0) and (gi <= 256) and (curvesSet) then gi := Round(csa[2][Round(csa[0][gi])]); + if (bi >= 0) and (bi <= 256) and (curvesSet) then bi := Round(csa[3][Round(csa[0][bi])]); + + ri := ri + (ia * bgi[0]) shr 8; + if (ri < 0) then ri := 0 + else if (ri > 255) then ri := 255; + + gi := gi + (ia * bgi[1]) shr 8; + if (gi < 0) then gi := 0 + else if (gi > 255) then gi := 255; + + bi := bi + (ia * bgi[2]) shr 8; + if (bi < 0) then bi := 0 + else if (bi > 255) then bi := 255; + + Row[j].red := ri; + Row[j].green := gi; + Row[j].blue := bi; + AlphaRow[j] := ai;//? + end + end; + + //Inc(bucketpos, gutter_width); + //Inc(bucketpos, (FOversample - 1) * FBucketWidth); + Inc(by, FOversample); + end; + + FBitmap.PixelFormat := pf24bit; + + if assigned(FOnProgress) then FOnProgress(1); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TImageMaker.SaveImage(FileName: String); +var + i,row: integer; + PngObject: TPngObject; + rowbm, rowpng: PByteArray; + JPEGImage: TJPEGImage; + PNGerror: boolean; + label BMPhack; +begin + if UpperCase(ExtractFileExt(FileName)) = '.PNG' then begin + pngError := false; + + PngObject := TPngObject.Create; + try + PngObject.Assign(FBitmap); + if fcp.Transparency then // PNGTransparency <> 0 + begin + PngObject.CreateAlpha; + for i:= 0 to FAlphaBitmap.Height - 1 do begin + rowbm := PByteArray(FAlphaBitmap.scanline[i]); + rowpng := PByteArray(PngObject.AlphaScanline[i]); + for row := 0 to FAlphaBitmap.Width -1 do begin + rowpng[row] := rowbm[row]; + end; + end; + end; + //else Exception.CreateFmt('Unexpected value of PNGTransparency [%d]', [PNGTransparency]); + + {if (FParameters <> '') then + PngObject.AddtEXt('Parameters', FParameters); } + PngObject.SaveToFile(FileName); + except + pngError := true; + end; + PngObject.Free; + + if pngError then begin + FileName := ChangeFileExt(FileName, '.bmp'); + goto BMPHack; + end; + + end else if UpperCase(ExtractFileExt(FileName)) = '.JPG' then begin + JPEGImage := TJPEGImage.Create; + JPEGImage.Assign(FBitmap); + JPEGImage.CompressionQuality := JPEGQuality; + JPEGImage.SaveToFile(FileName); + JPEGImage.Free; + +// with TLinearBitmap.Create do +// try +// Assign(Renderer.GetImage); +// JPEGLoader.Default.Quality := JPEGQuality; +// SaveToFile(RenderForm.FileName); +// finally +// Free; +// end; + end else begin // bitmap +BMPHack: + FBitmap.SaveToFile(FileName); + if fcp.Transparency then begin + FAlphaBitmap.Palette := CreatePalette(AlphaPalette.logpal); + FileName := ChangeFileExt(FileName, '_alpha.bmp'); + FAlphaBitmap.SaveToFile(FileName); + end; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TImageMaker.GetTransparentImage: TPngObject; +var + x, y: integer; + i, row: integer; + rowbm, rowpng: PByteArray; +begin + Result := TPngObject.Create; + Result.Assign(FBitmap); + + if ((fcp <> nil) and fcp.Transparency) then begin + Result.CreateAlpha; + for i:= 0 to FAlphaBitmap.Height - 1 do begin + rowbm := PByteArray(FAlphaBitmap.scanline[i]); + rowpng := PByteArray(Result.AlphaScanline[i]); + for row := 0 to FAlphaBitmap.Width - 1 do begin + rowpng[row] := rowbm[row]; + end; + end; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// + +function TImageMaker.GetBucket(x, y: integer): TBucket; +begin + with FBuckets[y][x] do begin + Result.Red := Red; + Result.Green := Green; + Result.Blue := Blue; + Result.Count := Count; + end; +end; + +function TImageMaker.SafeGetBucket(x, y: integer): TBucket; +begin + if x < 0 then x := 0 + else if x >= FBucketWidth then x := FBucketWidth-1; + if y < 0 then y := 0 + else if y >= FBucketHeight then y := FBucketHeight-1; + Result := FGetBucket(x, y); +end; + +/////////////////////////////////////////////////////////////////////////////// + +procedure TImageMaker.GetBucketStats(var Stats: TBucketStats); +var + bucketpos: integer; + x, y: integer; + b: TBucket; +begin + with Stats do begin + MaxR := 0; + MaxG := 0; + MaxB := 0; + MaxA := 0; + TotalA := 0; + + for y := 0 to FBucketHeight - 1 do + for x := 0 to FBucketWidth - 1 do begin + b := FGetBucket(x, y); + MaxR := max(MaxR, b.Red); + MaxG := max(MaxG, b.Green); + MaxB := max(MaxB, b.Blue); + MaxA := max(MaxA, b.Count); + TotalA := TotalA + b.Count + end; + end; +end; + +end. diff --git a/Rendering/RenderThread.pas b/Rendering/RenderThread.pas new file mode 100644 index 0000000..2fe6562 --- /dev/null +++ b/Rendering/RenderThread.pas @@ -0,0 +1,364 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit RenderThread; + +interface + +uses + Classes, Windows, Messages, Graphics, + ControlPoint, RenderingInterface, + Global, RenderingCommon, PngImage, + RenderingImplementation; + + //Disabled: + + //Render64, Render64MT, + //Render48, Render48MT, + //Render32f, Render32fMT; + +const + WM_THREAD_COMPLETE = WM_APP + 5437; + WM_THREAD_TERMINATE = WM_APP + 5438; + +type + TRenderThread = class(TThread) + private + FRenderer: TBaseRenderer; + + FOnProgress: TOnProgress; + FCP: TControlPoint; + FMaxMem: int64; + FNrThreads: Integer; + FBitsPerSample: integer; + FMinDensity: double; + FOutput: TStrings; + FExportBuffer: boolean; + + procedure CreateRenderer; + function GetNrSlices: integer; + function GetSlice: integer; + procedure SetBitsPerSample(const bits: Integer); + + function GetExportBuffer: boolean; + procedure SetExportBuffer(value: boolean); + + procedure Trace(const str: string); + + public + TargetHandle: HWND; + WaitForMore, More: boolean; + + constructor Create; + destructor Destroy; override; + + procedure SetCP(CP: TControlPoint); + function GetImage: TBitmap; + function GetTransparentImage: TPngObject; + procedure SaveImage(const FileName: String); + + procedure Execute; override; + function GetRenderer: TBaseRenderer; + + procedure Terminate; + procedure Suspend; + procedure Resume; + procedure BreakRender; + procedure HibernateRender(filePath: string); + procedure ResumeFromHibernation(filePath: string); + +// procedure GetBucketStats(var Stats: TBucketStats); + procedure ShowBigStats; + procedure ShowSmallStats; + + property OnProgress: TOnProgress +// read FOnProgress + write FOnProgress; + + property Slice: integer + read GetSlice; + property NrSlices: integer + read GetNrSlices; + property MaxMem: int64 + read FMaxMem + write FMaxMem; +// property compatibility: Integer read Fcompatibility write Fcompatibility; + property NrThreads: Integer + read FNrThreads + write FNrThreads; + property BitsPerSample: Integer + read FBitsPerSample + write SetBitsPerSample; + property Output: TStrings + write FOutput; + property MinDensity: double + write FMinDensity; + property ExportBuffer: boolean + read GetExportBuffer + write SetExportBuffer; + end; + +implementation + +uses + Math, SysUtils,Tracer; +{ TRenderThread } + +/////////////////////////////////////////////////////////////////////////////// +destructor TRenderThread.Destroy; +begin + if assigned(FRenderer) then + FRenderer.Free; + FRenderer := nil; + + if assigned(FCP) then FCP.Free; + + inherited; +end; + +function TRenderThread.GetExportBuffer: boolean; +begin + if assigned(FRenderer) then + Result := FRenderer.ExportBuffer + else Result := FExportBuffer; +end; +procedure TRenderThread.SetExportBuffer(value: boolean); +begin + if assigned(FRenderer) then + FRenderer.ExportBuffer := value; + FExportBuffer := value; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TRenderThread.GetImage: TBitmap; +begin + Result := nil; + if assigned(FRenderer) then + Result := FRenderer.GetImage; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TRenderThread.GetTransparentImage: TPngObject; +begin + Result := nil; + if assigned(FRenderer) then + Result := FRenderer.GetTransparentImage; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.SetCP(CP: TControlPoint); +begin + + FCP := CP.Clone; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TRenderThread.Create; +begin + MaxMem := 0; + BitsPerSample := InternalBitsPerSample; + FreeOnTerminate := false; + WaitForMore := false; + + inherited Create(True); // Create Suspended; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.CreateRenderer; +begin + if assigned(FRenderer) then begin + Trace('Destroying previous renderer (?)'); + FRenderer.Free; + end; + Trace('Creating renderer'); + + if NrThreads <= 1 then begin + if MaxMem = 0 then begin + FRenderer := TRenderWorkerST.Create; + end else begin + FRenderer := TRenderWorkerST_MM.Create; + FRenderer.MaxMem := MaxMem; + end; + end + else begin + if MaxMem = 0 then begin + FRenderer := TRenderWorkerMT.Create; + end else begin + FRenderer := TRenderWorkerMT_MM.Create; + FRenderer.MaxMem := MaxMem; + end; + FRenderer.NumThreads := NrThreads; + end; + + FRenderer.ExportBuffer := FExportbuffer; + FRenderer.SetCP(FCP); + FRenderer.MinDensity := FMinDensity; + FRenderer.OnProgress := FOnProgress; + FRenderer.Output := FOutput; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.Execute; +label RenderMore; +begin + CreateRenderer; + +RenderMore: + assert(assigned(FRenderer)); + + Trace('Rendering'); + FRenderer.Render; + + if Terminated or FRenderer.Failed then begin + Trace('Sending WM_THREAD_TERMINATE'); + PostMessage(TargetHandle, WM_THREAD_TERMINATE, 0, ThreadID); + Trace('Terminated'); + exit; + end + else begin + Trace('Sending WM_THREAD_COMPLETE'); + PostMessage(TargetHandle, WM_THREAD_COMPLETE, 0, ThreadID); + end; + + if WaitForMore and (FRenderer <> nil) then begin + FRenderer.RenderMore := true; + + Trace('Waiting for more'); + inherited Suspend; + + if WaitForMore then goto RenderMore; + end; + + Trace('Finished'); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.Terminate; +begin + try + if assigned(FRenderer) then + FRenderer.Stop; + except on EAccessViolation do + // nothing + end; + + WaitForMore := false; + + inherited Terminate; +end; + +procedure TRenderThread.Suspend; +begin + if assigned(FRenderer) then FRenderer.Pause; + + inherited; +end; + +procedure TRenderThread.Resume; +begin + if assigned(FRenderer) then FRenderer.UnPause; + + inherited; +end; + +procedure TRenderThread.BreakRender; +begin + if assigned(FRenderer) then + FRenderer.BreakRender; +end; + +procedure TRenderThread.HibernateRender(filePath: string); +begin + if assigned(FRenderer) then + FRenderer.Hibernate(filePath); +end; + +procedure TRenderThread.ResumeFromHibernation(filePath: string); +begin + if assigned(FRenderer) then + FRenderer.Stop; + FRenderer.Resume(filePath); + FRenderer.UnPause; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TRenderThread.GetNrSlices: integer; +begin + if assigned(FRenderer) then + Result := FRenderer.NrSlices + else + Result := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TRenderThread.GetSlice: integer; +begin + if assigned(FRenderer) then + Result := FRenderer.Slice + else + Result := 1; +end; + +////////////////////////////////////////////////////////////////////////////// +function TRenderThread.GetRenderer: TBaseRenderer; +begin + Result := FRenderer; + FRenderer := nil; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.SetBitsPerSample(const bits: Integer); +begin + if FRenderer = nil then FBitsPerSample := bits + else assert(false); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.SaveImage(const FileName: String); +begin + if assigned(FRenderer) then begin + FRenderer.SaveImage(FileName); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.Trace(const str: string); +begin + if assigned(FOutput) and (TraceLevel >= 2) then + FOutput.Add('. . > RenderThread #' + IntToStr(ThreadID) + ': ' + str); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderThread.ShowBigStats; +begin + if assigned(FRenderer) then + FRenderer.ShowBigStats; +end; + +procedure TRenderThread.ShowSmallStats; +begin + if assigned(FRenderer) then + FRenderer.ShowSmallStats; +end; +/////////////////////////////////////////////////////////////////////////////// + +end. diff --git a/Rendering/RenderingCommon.pas b/Rendering/RenderingCommon.pas new file mode 100644 index 0000000..c27d2e5 --- /dev/null +++ b/Rendering/RenderingCommon.pas @@ -0,0 +1,70 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit RenderingCommon; + +interface +type + TOnFinish = procedure of object; + TOnProgress = procedure(prog: double) of object; + + {$ifdef Apo7X64} + TBucket = Record + Red, + Green, + Blue, + Count: Double; + end; + {$else} + TBucket = Record + Red, + Green, + Blue, + Count: Single; + end; + {$endif} + PBucket = ^TBucket; + TBucketArray = array of array of TBucket; + TZBuffer = array of array of double; + + TBucketStats = record + MaxR, MaxG, MaxB, MaxA, + TotalA: double; + end; + +procedure TrimWorkingSet; + +implementation +uses Windows; + +procedure TrimWorkingSet; +var + hProcess: THandle; +begin + hProcess := OpenProcess(PROCESS_SET_QUOTA, false, GetCurrentProcessId); + + try SetProcessWorkingSetSize(hProcess, $FFFFFFFF, $FFFFFFFF); + finally CloseHandle(hProcess); + end; +end; + +end. diff --git a/Rendering/RenderingImplementation.pas b/Rendering/RenderingImplementation.pas new file mode 100644 index 0000000..1aa2c33 --- /dev/null +++ b/Rendering/RenderingImplementation.pas @@ -0,0 +1,718 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit RenderingImplementation; + +{$ifdef Apo7X64} +{$else} +// {$define _ASM_} +{$endif} + +interface + +uses +{$ifndef _ASM_} +{$else} +AsmRandom, +{$endif} + Windows, Classes, Forms, Graphics, Global, + RenderingInterface, Xform, Math, Translation, + Binary, RenderingCommon, ControlPoint, Sysutils, + BucketFillerThread; + +type + TBatchProc = procedure of object; + TRenderWorkerST = class(TBaseRenderer) + + protected + PropTable: array[0..PROP_TABLE_SIZE] of TXform; + finalXform: TXform; + UseFinalXform: boolean; + + procedure Prepare; override; + procedure SetPixels; override; + + protected + procedure IterateBatch; + procedure IterateBatchAngle; + procedure IterateBatchFX; + procedure IterateBatchAngleFX; +end; + +type + TRenderWorkerMT = class(TBaseRenderer) + + protected + batchcounter: Integer; + WorkingThreads: array of TBucketFillerThread; + CriticalSection: TRTLCriticalSection; + + function NewThread: TBucketFillerThread; + procedure Prepare; override; + procedure SetPixels; override; + + protected + procedure AddPointsToBuckets(const points: TPointsArray); + procedure AddPointsToBucketsAngle(const points: TPointsArray); + + public + procedure Stop; override; + procedure BreakRender; override; + + procedure Pause; override; + procedure UnPause; override; +end; + +type + TRenderWorkerST_MM = class(TRenderWorkerST) + protected + procedure CalcBufferSize; override; + public + procedure Render; override; + +end; + +type + TRenderWorkerMT_MM = class(TRenderWorkerMT) + protected + procedure CalcBufferSize; override; + public + procedure Render; override; +end; + +// ---------------------------------------------------------------------------- + +implementation + +//////////////////////////////////////////////////////////////////////////////// +// PREPARE +//////////////////////////////////////////////////////////////////////////////// +procedure TRenderWorkerST.Prepare; +var + i, n: Integer; + propsum: double; + LoopValue: double; + j: integer; + TotValue: double; +begin + totValue := 0; + n := fcp.NumXforms; + assert(n > 0); + + finalXform := fcp.xform[n]; + finalXform.Prepare; + useFinalXform := fcp.FinalXformEnabled and fcp.HasFinalXform; + + fcp.Prepare; +end; +procedure TRenderWorkerMT.Prepare; +begin + fcp.Prepare; +end; + +//////////////////////////////////////////////////////////////////////////////// +// SETPIXELS +//////////////////////////////////////////////////////////////////////////////// +procedure TRenderWorkerST.SetPixels; +var + i: integer; + nsamples: int64; + IterateBatchProc: procedure of object; +begin + if FNumSlices > 1 then + TimeTrace(Format(TextByKey('common-trace-rendering-multipleslices'), [FSlice + 1, FNumSlices])) + else + TimeTrace(TextByKey('common-trace-rendering-oneslice')); + + Randomize; + + if FCP.FAngle = 0 then begin + if UseFinalXform then + IterateBatchProc := IterateBatchFX + else + IterateBatchProc := IterateBatch; + end + else begin + if UseFinalXform then + IterateBatchProc := IterateBatchAngleFX + else + IterateBatchProc := IterateBatchAngle; + end; + + NSamples := Round(sample_density * NrSlices * bucketSize / (oversample * oversample)); + FNumBatches := Round(nsamples / (fcp.nbatches * SUB_BATCH_SIZE)); + if FNumBatches = 0 then FNumBatches := 1; + + FMinBatches := Round(FNumBatches * FMinDensity / fcp.sample_density); + if FMinBatches = 0 then FMinBatches := 1; + + for i := 0 to FNumBatches-1 do begin + if FStop <> 0 then begin + fcp.actual_density := fcp.actual_density + fcp.sample_density * i / FNumBatches; + FNumBatches := i; + exit; + end; + + if ((i and $1F) = 0) then Progress(i / FNumBatches); + + IterateBatchProc; + Inc(FBatch); + end; + + fcp.actual_density := fcp.actual_density + fcp.sample_density; + + Progress(1); +end; +procedure TRenderWorkerMT.SetPixels; +var + i: integer; + nSamples: Int64; + bc : integer; +begin + if FNumSlices > 1 then + TimeTrace(Format(TextByKey('common-trace-rendering-multipleslices'), [FSlice + 1, FNumSlices])) + else + TimeTrace(TextByKey('common-trace-rendering-oneslice')); + + nSamples := Round(sample_density * NrSlices * BucketSize / (oversample * oversample)); + FNumBatches := Round(nSamples / (fcp.nbatches * SUB_BATCH_SIZE)); + if FNumBatches = 0 then FNumBatches := 1; + FMinBatches := Round(FNumBatches * FMinDensity / fcp.sample_density); + + batchcounter := 1; + Randomize; + + InitializeCriticalSection(CriticalSection); + + SetLength(WorkingThreads, NumThreads); + for i := 0 to NumThreads - 1 do + WorkingThreads[i] := NewThread; + + for i := 0 to NumThreads - 1 do + WorkingThreads[i].Resume; + + bc := 1; + while (FStop = 0) and (bc <= FNumBatches) do begin + sleep(250); + try + EnterCriticalSection(CriticalSection); + + Progress(batchcounter / FNumBatches); + bc := batchcounter; + finally + LeaveCriticalSection(CriticalSection); + end; + end; + + for i := 0 to High(WorkingThreads) do begin + WorkingThreads[i].Terminate; + WorkingThreads[i].WaitFor; + WorkingThreads[i].Free; + end; + SetLength(WorkingThreads, 0); + + fcp.actual_density := fcp.actual_density + + fcp.sample_density * BatchCounter / FNumBatches; // actual quality of incomplete render + FNumBatches := BatchCounter; + + DeleteCriticalSection(CriticalSection); + Progress(1); +end; + +//////////////////////////////////////////////////////////////////////////////// +// MM OVERRIDES +//////////////////////////////////////////////////////////////////////////////// +procedure TRenderWorkerST_MM.CalcBufferSize; +begin + CalcBufferSizeMM; +end; +procedure TRenderWorkerST_MM.Render; +begin + RenderMM; +end; +procedure TRenderWorkerMT_MM.CalcBufferSize; +begin + CalcBufferSizeMM; +end; +procedure TRenderWorkerMT_MM.Render; +begin + RenderMM; +end; + +//////////////////////////////////////////////////////////////////////////////// +// BATCH ITERATION +//////////////////////////////////////////////////////////////////////////////// +procedure TRenderWorkerST.IterateBatch; +var + i: integer; + px, py: double; + Bucket: PBucket; + ZBufPos: PDouble; + MapColor: PColorMapColor; + + ix, iy: integer; + BmpColor: TColor; + + p, q: TCPPoint; + xf: TXForm; +begin +{$ifndef _ASM_} + p.x := 2 * random - 1; + p.y := 2 * random - 1; + p.c := random; +{$else} +asm + fld1 + call AsmRandExt + fadd st, st + fsub st, st(1) + fstp qword ptr [p.x] + call AsmRandExt + fadd st, st + fsubrp st(1), st + fstp qword ptr [p.y] + call AsmRandExt + fstp qword ptr [p.c] +end; +{$endif} + + try + xf := fcp.xform[0]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + end; + + for i := 0 to SUB_BATCH_SIZE-1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + + if random >= xf.transOpacity then continue; + + q := p; + fcp.ProjectionFunc(@q); // 3d hack + + px := q.x - camX0; + if (px < 0) or (px > camW) then continue; + py := q.y - camY0; + if (py < 0) or (py > camH) then continue; + + Bucket := @buckets[Round(bhs * py)][Round(bws * px)]; + MapColor := @ColorMap[Round(p.c * 255)]; + {$ifdef ENABLEZBUF} + ZBufPos := @zbuffer[Round(bhs * py)][Round(bws * px)]; + if (q.z < ZBufPos^) then + begin + ZBufPos^ := q.z; + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + end; + {$else} + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + {$endif} + end; + + except + on EMathError do begin + exit; + end; + end; +end; +procedure TRenderWorkerST.IterateBatchAngle; +var + i: integer; + px, py: double; + Bucket: PBucket; + MapColor: PColorMapColor; + ZBufPos: PDouble; + ix, iy: integer; + BmpColor: TColor; + + p, q: TCPPoint; + xf: TXForm; +begin +{$ifndef _ASM_} + p.x := 2 * random - 1; + p.y := 2 * random - 1; + p.c := random; +{$else} +asm + fld1 + call AsmRandExt + fadd st, st + fsub st, st(1) + fstp qword ptr [p.x] + call AsmRandExt + fadd st, st + fsubrp st(1), st + fstp qword ptr [p.y] + call AsmRandExt + fstp qword ptr [p.c] +end; +{$endif} + + try + xf := fcp.xform[0]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + end; + + for i := 0 to SUB_BATCH_SIZE-1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + + if random >= xf.transOpacity then continue; + + q := p; + fcp.ProjectionFunc(@q); + + px := q.x * cosa + q.y * sina + rcX; + if (px < 0) or (px > camW) then continue; + py := q.y * cosa - q.x * sina + rcY; + if (py < 0) or (py > camH) then continue; + + Bucket := @buckets[Round(bhs * py)][Round(bws * px)]; + MapColor := @ColorMap[Round(p.c * 255)]; + + {$ifdef ENABLEZBUF} + ZBufPos := @zbuffer[Round(bhs * py)][Round(bws * px)]; + if (q.z < ZBufPos^) then + begin + ZBufPos^ := q.z; + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + end; + {$else} + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + {$endif} + end; + + except + on EMathError do begin + exit; + end; + end; +end; +procedure TRenderWorkerST.IterateBatchFX; +var + i: integer; + px, py: double; + Bucket: PBucket; + MapColor: PColorMapColor; + ZbufPos: PDouble; + ix, iy: integer; + BmpColor: TColor; + + p, q: TCPPoint; + xf: TXForm; +begin +{$ifndef _ASM_} + p.x := 2 * random - 1; + p.y := 2 * random - 1; + p.c := random; +{$else} +asm + fld1 + call AsmRandExt + fadd st, st + fsub st, st(1) + fstp qword ptr [p.x] + call AsmRandExt + fadd st, st + fsubrp st(1), st + fstp qword ptr [p.y] + call AsmRandExt + fstp qword ptr [p.c] +end; +{$endif} + + try + xf := fcp.xform[0]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + end; + + for i := 0 to SUB_BATCH_SIZE-1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + + if random >= xf.transOpacity then continue; + + finalXform.NextPointTo(p, q); + fcp.ProjectionFunc(@q); + + px := q.x - camX0; + if (px < 0) or (px > camW) then continue; + py := q.y - camY0; + if (py < 0) or (py > camH) then continue; + + Bucket := @buckets[Round(bhs * py)][Round(bws * px)]; + MapColor := @ColorMap[Round(q.c * 255)]; + + {$ifdef ENABLEZBUF} + ZBufPos := @zbuffer[Round(bhs * py)][Round(bws * px)]; + if (q.z < ZBufPos^) then + begin + ZBufPos^ := q.z; + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + end; + {$else} + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + {$endif} + end; + + except + on EMathError do begin + exit; + end; + end; +end; +procedure TRenderWorkerST.IterateBatchAngleFX; +var + i: integer; + px, py: double; + Bucket: PBucket; + MapColor: PColorMapColor; + ZBufPos: PDouble; + ix, iy: integer; + BmpColor: TColor; + + p, q: TCPPoint; + xf: TXForm; +begin +{$ifndef _ASM_} + p.x := 2 * random - 1; + p.y := 2 * random - 1; + p.c := random; +{$else} +asm + fld1 + call AsmRandExt + fadd st, st + fsub st, st(1) + fstp qword ptr [p.x] + call AsmRandExt + fadd st, st + fsubrp st(1), st + fstp qword ptr [p.y] + call AsmRandExt + fstp qword ptr [p.c] +end; +{$endif} + + try + xf := fcp.xform[0]; + for i := 0 to FUSE do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + end; + + for i := 0 to SUB_BATCH_SIZE-1 do begin + xf := xf.PropTable[Random(PROP_TABLE_SIZE)]; + xf.NextPoint(p); + + if random >= xf.transOpacity then continue; + + finalXform.NextPointTo(p, q); + fcp.ProjectionFunc(@q); + + px := q.x * cosa + q.y * sina + rcX; + if (px < 0) or (px > camW) then continue; + py := q.y * cosa - q.x * sina + rcY; + if (py < 0) or (py > camH) then continue; + + Bucket := @buckets[Round(bhs * py)][Round(bws * px)]; + MapColor := @ColorMap[Round(q.c * 255)]; + + {$ifdef ENABLEZBUF} + ZBufPos := @zbuffer[Round(bhs * py)][Round(bws * px)]; + if (q.z < ZBufPos^) then + begin + ZBufPos^ := q.z; + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + end; + {$else} + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + {$endif} + end; + + except + on EMathError do begin + exit; + end; + end; +end; +procedure TRenderWorkerMT.AddPointsToBuckets(const points: TPointsArray); +var + i: integer; + px, py: double; + Bucket: PBucket; + ZBufPos: PDouble; + MapColor: PColorMapColor; +begin + for i := SUB_BATCH_SIZE - 1 downto 0 do begin + px := points[i].x - camX0; + if (px < 0) or (px > camW) then continue; + py := points[i].y - camY0; + if (py < 0) or (py > camH) then continue; + + Bucket := @buckets[Round(bhs * py)][Round(bws * px)]; + MapColor := @ColorMap[Round(points[i].c * 255)]; + + if random >= points[i].o then continue; + + {$ifdef ENABLEZBUF} + ZBufPos := @zbuffer[Round(bhs * py)][Round(bws * px)]; + if (points[i].z < ZBufPos^) then + begin + ZBufPos^ := points[i].z; + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + end; + {$else} + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + {$endif} + end; +end; +procedure TRenderWorkerMT.AddPointsToBucketsAngle(const points: TPointsArray); +var + i: integer; + px, py: double; + Bucket: PBucket; + MapColor: PColorMapColor; + ZBufPos: PDouble; +begin + for i := SUB_BATCH_SIZE - 1 downto 0 do begin + px := points[i].x * cosa + points[i].y * sina + rcX; + if (px < 0) or (px > camW) then continue; + py := points[i].y * cosa - points[i].x * sina + rcY; + if (py < 0) or (py > camH) then continue; + + Bucket := @buckets[Round(bhs * py)][Round(bws * px)]; + MapColor := @ColorMap[Round(points[i].c * 255)]; + + if random >= points[i].o then continue; + + {$ifdef ENABLEZBUF} + ZBufPos := @zbuffer[Round(bhs * py)][Round(bws * px)]; + if (points[i].z < ZBufPos^) then + begin + ZBufPos^ := points[i].z; + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + end; + {$else} + Bucket.Red := Bucket.Red + MapColor.Red; + Bucket.Green := Bucket.Green + MapColor.Green; + Bucket.Blue := Bucket.Blue + MapColor.Blue; + Bucket.Count := Bucket.Count + 1; + {$endif} + end; +end; + +//////////////////////////////////////////////////////////////////////////////// +// THREADING +//////////////////////////////////////////////////////////////////////////////// +procedure TRenderWorkerMT.Stop; +var + i: integer; +begin + for i := 0 to High(WorkingThreads) do + WorkingThreads[i].Terminate; + + inherited; +end; +procedure TRenderWorkerMT.BreakRender; +var + i: integer; +begin + inherited; + + for i := 0 to High(WorkingThreads) do + WorkingThreads[i].Terminate; +end; +procedure TRenderWorkerMT.Pause; +var + i: integer; +begin + inherited; + + for i := 0 to High(WorkingThreads) do + WorkingThreads[i].Suspend; +end; +procedure TRenderWorkerMT.UnPause; +var + i: integer; +begin + inherited; + + for i := 0 to High(WorkingThreads) do + WorkingThreads[i].Resume; +end; +function TRenderWorkerMT.NewThread: TBucketFillerThread; +begin + Result := TBucketFillerThread.Create(fcp); + assert(Result<>nil); + + if FCP.FAngle = 0 then + Result.AddPointsProc := self.AddPointsToBuckets + else + Result.AddPointsProc := self.AddPointsToBucketsAngle; + + Result.CriticalSection := CriticalSection; + Result.Nrbatches := FNumBatches; + Result.batchcounter := @batchcounter; +end; + +end. + diff --git a/Rendering/RenderingInterface.pas b/Rendering/RenderingInterface.pas new file mode 100644 index 0000000..6a9fcab --- /dev/null +++ b/Rendering/RenderingInterface.pas @@ -0,0 +1,1091 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit RenderingInterface; + +interface + +uses + Windows, Graphics, Classes, RenderingCommon, + Controlpoint, ImageMaker, PngImage, Translation; + +/////////////////////////////////////////////////////////////////////////////// +// +// { TBaseRenderer } +// +/////////////////////////////////////////////////////////////////////////////// + +const + opRendering: integer = 0; + opSampling: integer = 1; + opHibernating: integer = 2; + +type + TOnOutput = procedure(s: string) of object; + TOnOperation = procedure(op: integer) of object; + TCopyBufferCallback = procedure(tgr: Pointer; x, y: integer) of object; + +type + TColorMapColor = Record + Red, + Green, + Blue: + + {$ifdef Apo7X64} + double + {$else} + single + {$endif}; + end; + PColorMapColor = ^TColorMapColor; + TColorMapArray = array[0..255] of TColorMapColor; + + TPoint3D = Record + X, + Y, + Z, + W: Double; + end; + TPoint3DArray = array of TPoint3D; + +const + MAX_FILTER_WIDTH = 25; + +//const + //SizeOfBucket: array[0..3] of byte = (32, 32, 32, 32); + +function TimeToString(t: TDateTime): string; + +type + TBaseRenderer = class + private + FOnProgress: TOnProgress; + FOnOperation: TOnOperation; + FCopyBuffer: TCopyBufferCallback; + strOutput: TStrings; + + protected + Buckets: TBucketArray; + ZBuffer: TZBuffer; + + procedure AllocateBuckets; + procedure ClearBuckets; + procedure SetBucketsPtr(ptr: pointer); + function GetBucketsPtr: pointer; + + protected + camX0, camX1, camY0, camY1, // camera bounds + camW, camH, // camera sizes + bws, bhs, cosa, sina, rcX, rcY: double; + ppux, ppuy: extended; + + BucketWidth, BucketHeight: int64; + BucketSize: int64; + + sample_density: extended; + oversample: integer; + gutter_width: Integer; + max_gutter_width: Integer; + + FCP: TControlPoint; + FStop: integer;//boolean; + FHibernated: boolean; + + FImageMaker: TImageMaker; + + ColorMap: TColorMapArray; + + FMaxMem: integer; + FSlice, FNumSlices: integer; + image_Width, image_Height: Int64; + image_Center_X, image_Center_Y: double; + + FCompatibility: integer; + FNumThreads: integer; + FNumBatches: integer;//int64; + FBatch: integer; + FThreadPriority: TThreadPriority; + + FMinDensity: double; + FMinBatches: integer; + FRenderOver: boolean; + + FBufferPath: string; + FDoExportBuffer: boolean; + + StartTime, RenderTime, PauseTime: TDateTime; + + procedure Progress(value: double); + procedure Operation(op: integer); + + procedure SetMinDensity(const q: double); + + procedure CreateColorMap; virtual; + procedure CreateCamera; + procedure CreateCameraMM; + procedure Prepare; virtual; abstract; + procedure SetPixels; virtual; abstract; + + procedure CalcBufferSize; virtual; + procedure CalcBufferSizeMM; + + procedure InitBuffers; + procedure RenderMM; + + procedure Trace(const str: string); + procedure TimeTrace(const str: string); + public + constructor Create; virtual; + destructor Destroy; override; + + procedure Hibernate(filePath: string); + procedure Resume(filePath: string); + + procedure SetCP(CP: TControlPoint); + procedure Render; virtual; + procedure ProcessBuffer(density: double); + + function GetImage: TBitmap; virtual; + procedure GetImageAndDelete(target:tBitmap); virtual; + function GetTransparentImage: TPngObject; + procedure UpdateImage(CP: TControlPoint); + procedure SaveImage(const FileName: String); + + procedure Stop; virtual; + procedure BreakRender; virtual; + procedure Pause; virtual; + procedure UnPause; virtual; + procedure SetThreadPriority(p: TThreadPriority); virtual; + + function Failed: boolean; + function Hibernated: boolean; + + procedure ShowBigStats; + procedure ShowSmallStats; + + property CopyBufferCallback: TCopyBufferCallback + write FCopyBuffer; + property OnProgress: TOnProgress +// read FOnProgress + write FOnProgress; + property OnOperation: TOnOperation + write FOnOperation; + property MaxMem : integer + read FMaxMem + write FMaxMem; + property NrSlices: integer + read FNumSlices; + property Slice: integer + read FSlice; + property NumThreads: integer + read FNumThreads + write FNumThreads; + property Output: TStrings + write strOutput; + property MinDensity: double + write SetMinDensity; + property RenderMore: boolean + write FRenderOver; + property Batch: integer + read FBatch; + property NrBatches: integer + read FNumBatches; + property BufferPath: string + read FBufferPath + write FBufferPath; + property ExportBuffer: boolean + read FDoExportBuffer + write FDoExportBuffer; + end; + +/////////////////////////////////////////////////////////////////////////////// + + { TRenderer } + +/////////////////////////////////////////////////////////////////////////////// + +type + TRenderer = class + private + FRenderer: TBaseRenderer; + + FOnProgress: TOnProgress; + FOnOperation: TOnOperation; + FCopyBuffer: TCopyBufferCallback; + FCP: TControlPoint; + FMaxMem: int64; + FBufferPath: string; + FNrThreads: integer; + + function GetSlice: integer; + function GetNrSlices: integer; + function GetBatch: integer; + function GetNrBatches: integer; + function GetNrThreads: integer; + + procedure SetNrThreads(v: integer); + + public + destructor Destroy; override; + + procedure SetCP(CP: TControlPoint); + procedure Render; + procedure ProcessBuffer(density: double); + + function GetImage: TBitmap; + procedure GetImageAndDelete(target: TBitmap); + function GetTransparentImage: TPngObject; + procedure Stop; + + procedure IntermediateSample(imgmkr: TImageMaker); + + property CopyBufferCallback: TCopyBufferCallback + read FCopyBuffer + write FCopyBuffer; + property OnProgress: TOnProgress + read FOnProgress + write FOnProgress; + property OnOperation: TOnOperation + read FOnOperation + write FOnOperation; + + property Slice: integer + read GetSlice; + property NrSlices: integer + read GetNrSlices; + + property Batch: integer + read GetBatch; + property NrBatches: integer + read GetNrBatches; + property NrThreads: integer + read FNrThreads + write FNrThreads; + property BufferPath: string + read FBufferPath + write FBufferPath; + + procedure Hibernate(fileName: string); + end; + +implementation + +uses + Math, SysUtils, Forms, + RenderingImplementation, + Binary, Global; + +/////////////////////////////////////////////////////////////////////////////// +// +// { TBaseRenderer } +// +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.Hibernate(filePath: string); +begin + // todo +end; +procedure TBaseRenderer.Resume(filePath: string); +begin + // todo +end; +procedure TBaseRenderer.CalcBufferSizeMM; +begin + oversample := fcp.spatial_oversample; + gutter_width := (FImageMaker.GetFilterSize - oversample) div 2; + BucketHeight := oversample * image_height + 2 * gutter_width; + Bucketwidth := oversample * image_width + 2 * gutter_width; + BucketSize := BucketWidth * BucketHeight; +end; +procedure TBaseRenderer.RenderMM; +const + Dividers: array[0..15] of integer = (1, 2, 3, 4, 5, 6, 7, 8, 10, 16, 20, 32, 64, 128, 256, 512); +var + ApproxMemory, MaxMemory: int64; + i: integer; + zoom_scale, center_base, center_y: double; + t: TDateTime; +begin + FStop := 0; //False; + + image_Center_X := fcp.center[0]; + image_Center_Y := fcp.center[1]; + + image_Height := fcp.Height; + image_Width := fcp.Width; + oversample := fcp.spatial_oversample; + + // entered memory - imagesize + MaxMemory := FMaxMem * 1024 * 1024 - 4 * image_Height * int64(image_Width); + + if (SingleBuffer) then + ApproxMemory := 16 * sqr(oversample) * image_Height * int64(image_Width) + else + ApproxMemory := 32 * sqr(oversample) * image_Height * int64(image_Width); + + assert(MaxMemory > 0); + if MaxMemory <= 0 then exit; + + FNumSlices := 1 + ApproxMemory div MaxMemory; + + if FNumSlices > Dividers[High(Dividers)] then begin + for i := High(Dividers) downto 0 do begin + if image_height <> (image_height div dividers[i]) * dividers[i] then begin + FNumSlices := dividers[i]; + break; + end; + end; + end else begin + for i := 0 to High(Dividers) do begin + if image_height <> (image_height div dividers[i]) * dividers[i] then + continue; + if FNumSlices <= dividers[i] then begin + FNumSlices := dividers[i]; + break; + end; + end; + end; + + FImageMaker.SetCP(FCP); + FImageMaker.Init; + + fcp.height := fcp.height div FNumSlices; + center_y := fcp.center[1]; + zoom_scale := power(2.0, fcp.zoom); + center_base := center_y - ((FNumSlices - 1) * fcp.height) / (2 * fcp.pixels_per_unit * zoom_scale); + + image_height := fcp.Height; + image_Width := fcp.Width; + + InitBuffers; + CreateColorMap; + Prepare; + + RenderTime := 0; + for i := 0 to FNumSlices - 1 do begin + if FStop <> 0 then Exit; + + FSlice := i; + fcp.center[1] := center_base + fcp.height * slice / (fcp.pixels_per_unit * zoom_scale); + CreateCameraMM; + ClearBuckets; + fcp.actual_density := 0; + + t := Now; + SetPixels; + RenderTime := RenderTime + (Now - t); + + if FStop = 0 then begin + TimeTrace(TextByKey('common-trace-creating-simple')); + FImageMaker.OnProgress := FOnProgress; + FImageMaker.CreateImage(Slice * fcp.height); + end; + end; + + fcp.height := fcp.height * FNumSlices; +end; +procedure TBaseRenderer.AllocateBuckets; +var + i, j: integer; +begin + SetLength(buckets, BucketHeight, BucketWidth); + SetLength(zbuffer, BucketHeight, BucketWidth); + + for i := 0 to BucketHeight - 1 do + for j := 0 to BucketWidth - 1 do + begin + zbuffer[i, j] := 10e10; + end; +end; +procedure TBaseRenderer.ClearBuckets; +var + i, j: integer; +begin + for j := 0 to BucketHeight - 1 do + for i := 0 to BucketWidth - 1 do + with buckets[j][i] do begin + Red := 0; + Green := 0; + Blue := 0; + Count := 0; + end; +end; +procedure TBaseRenderer.SetBucketsPtr(ptr: pointer); +begin + Buckets := TBucketArray(ptr); +end; +function TBaseRenderer.GetBucketsPtr: pointer; +begin + Result := Buckets; +end; + +constructor TBaseRenderer.Create; +begin + inherited Create; + + FNumSlices := 1; + FSlice := 0; + FStop := 0; // False; + FThreadPriority := tpNormal; + + FImageMaker := TImageMaker.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +destructor TBaseRenderer.Destroy; +begin + FImageMaker.Free; + + SetLength(buckets, 1, 1); + SetLength(zbuffer, 1, 1); + + if assigned(FCP) then + FCP.Free; + + TrimWorkingSet; + + inherited; +end; + +procedure TBaseRenderer.Operation(op: integer); +begin + if assigned(FOnOperation) then + FOnOperation(op); +end; +function TRenderer.GetSlice: integer; +begin + Result := FRenderer.Slice; +end; +function TRenderer.GetNrSlices: integer; +begin + Result := FRenderer.NrSlices; +end; + +function TRenderer.GetBatch: integer; +begin + Result := FRenderer.Batch; +end; +function TRenderer.GetNrBatches: integer; +begin + Result := FRenderer.NrBatches; +end; + +function TRenderer.GetNrThreads: integer; +begin + Result := FRenderer.NumThreads; +end; +procedure TRenderer.SetNrThreads(v: integer); +begin + FRenderer.NumThreads := v; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.SetCP(CP: TControlPoint); +begin + if assigned(FCP) then + FCP.Free; + + FCP := Cp.Clone; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.Trace(const str: string); +begin + if assigned(strOutput) then + strOutput.Add(str); +end; + +procedure TBaseRenderer.TimeTrace(const str: string); +begin + if assigned(strOutput) then + strOutput.Add(TimeToStr(Now) + ' : ' + str); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.Pause; +begin + PauseTime := Now; + + TimeTrace(TextByKey('common-trace-pausing')); +end; + +procedure TBaseRenderer.UnPause; +var + tNow: TDateTime; +begin + tNow := Now; + RenderTime := RenderTime + (tNow - PauseTime); + + TimeTrace(TextByKey('common-trace-resuming')); +end; + +procedure TBaseRenderer.SetThreadPriority(p: TThreadPriority); +begin + FThreadPriority := p; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.Stop; +begin + TimeTrace(TextByKey('common-trace-terminating')); + + FStop := 1; //True; +end; + +procedure TBaseRenderer.BreakRender; +begin + TimeTrace(TextByKey('common-trace-stopping')); + + FStop := -1; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.Progress(value: double); +begin + if assigned(FOnprogress) then + FOnprogress(Value); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.SetMinDensity(const q: double); +begin + if q < fcp.sample_density then FMinDensity := q + else FMinDensity := fcp.sample_density; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TBaseRenderer.Failed: boolean; +begin + Result := (FStop > 0); +end; + +function TBaseRenderer.Hibernated: boolean; +begin + Result := FHibernated; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TBaseRenderer.GetImage: TBitmap; +begin + if FStop > 0 then begin + assert(false); + FImageMaker.OnProgress := FOnProgress; + FImageMaker.CreateImage; + end; + Result := FImageMaker.GetImage; +end; + +procedure TBaseRenderer.GetImageAndDelete(target:tBitmap); +begin + if FStop > 0 then begin + assert(false); + FImageMaker.OnProgress := FOnProgress; + FImageMaker.CreateImage; + end; + FImageMaker.GetImageAndDelete(target); +end; + +procedure TRenderer.GetImageAndDelete(target:tBitmap); +begin + FRenderer.GetImageAndDelete(target); +end; + +/////////////////////////////////////////////////////////////////////////////// +function TBaseRenderer.GetTransparentImage: TPngObject; +begin + if FStop > 0 then begin + // shouldn't happen. and if it does...WTF? + Result := nil; + end + else + Result := FImageMaker.GetTransparentImage; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.UpdateImage(CP: TControlPoint); +begin + FCP.background := cp.background; + FCP.spatial_filter_radius := cp.spatial_filter_radius; + FCP.gamma := cp.Gamma; + FCP.vibrancy := cp.vibrancy; + FCP.contrast := cp.contrast; + FCP.brightness := cp.brightness; + + FImageMaker.SetCP(FCP); + FImageMaker.Init; + + FImageMaker.OnProgress := FOnProgress; + FImageMaker.CreateImage; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.SaveImage(const FileName: String); +begin + if FStop > 0 then begin + TimeTrace(Format(TextByKey('common-trace-creating-detailed'), [fcp.actual_density])); + FImageMaker.OnProgress := FOnProgress; + FImageMaker.CreateImage; + end; + TimeTrace(TextByKey('common-trace-saving')); + FImageMaker.SaveImage(FileName); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.CreateColorMap; +var + i: integer; +begin + for i := 0 to 255 do + with ColorMap[i] do begin + Red := (fcp.CMap[i][0] * fcp.white_level) div 256; + Green := (fcp.CMap[i][1] * fcp.white_level) div 256; + Blue := (fcp.CMap[i][2] * fcp.white_level) div 256; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.CreateCamera; +var + scale: double; + t0, t1: double; + t2, t3: double; + corner_x, corner_y, Xsize, Ysize: double; + shift: Integer; +begin + scale := power(2, fcp.zoom); + sample_density := fcp.sample_density * scale * scale; + ppux := fcp.pixels_per_unit * scale; + ppuy := fcp.pixels_per_unit * scale; + shift := 0; + + corner_x := fcp.center[0] - fcp.Width / ppux / 2.0; + corner_y := fcp.center[1] - fcp.Height / ppuy / 2.0; + t0 := gutter_width / (oversample * ppux); + t1 := gutter_width / (oversample * ppuy); + t2 := (2 * max_gutter_width - gutter_width) / (oversample * ppux); + t3 := (2 * max_gutter_width - gutter_width) / (oversample * ppuy); + + camX0 := corner_x - t0; + camY0 := corner_y - t1 + shift; + camX1 := corner_x + fcp.Width / ppux + t2; + camY1 := corner_y + fcp.Height / ppuy + t3; //+ shift; + + camW := camX1 - camX0; + if abs(camW) > 0.01 then + Xsize := 1.0 / camW + else + Xsize := 1; + camH := camY1 - camY0; + if abs(camH) > 0.01 then + Ysize := 1.0 / camH + else + Ysize := 1; + bws := (BucketWidth - 0.5) * Xsize; + bhs := (BucketHeight - 0.5) * Ysize; + + if FCP.FAngle <> 0 then + begin + cosa := cos(FCP.FAngle); + sina := sin(FCP.FAngle); + rcX := FCP.Center[0]*(1 - cosa) - FCP.Center[1]*sina - camX0; + rcY := FCP.Center[1]*(1 - cosa) + FCP.Center[0]*sina - camY0; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.CreateCameraMM; +var + scale: double; + t0, t1: double; + corner_x, corner_y, Xsize, Ysize: double; + shift: Integer; +begin + scale := power(2, fcp.zoom); + sample_density := fcp.sample_density * scale * scale; + ppux := fcp.pixels_per_unit * scale; + ppuy := fcp.pixels_per_unit * scale; + // todo field stuff + shift := 0; + t0 := gutter_width / (oversample * ppux); + t1 := gutter_width / (oversample * ppuy); + corner_x := fcp.center[0] - image_width / ppux / 2.0; + corner_y := fcp.center[1] - image_height / ppuy / 2.0; + + camX0 := corner_x - t0; + camY0 := corner_y - t1 + shift; + camX1 := corner_x + image_width / ppux + t0; + camY1 := corner_y + image_height / ppuy + t1; //+ shift; + + camW := camX1 - camX0; + if abs(camW) > 0.01 then + Xsize := 1.0 / camW + else + Xsize := 1; + camH := camY1 - camY0; + if abs(camH) > 0.01 then + Ysize := 1.0 / camH + else + Ysize := 1; + bws := (BucketWidth - 0.5) * Xsize; + bhs := (BucketHeight - 0.5) * Ysize; + + if FCP.FAngle <> 0 then + begin + cosa := cos(FCP.FAngle); + sina := sin(FCP.FAngle); + rcX := image_Center_X*(1 - cosa) - image_Center_Y*sina - camX0; + rcY := image_Center_Y*(1 - cosa) + image_Center_X*sina - camY0; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.CalcBufferSize; +begin + oversample := fcp.spatial_oversample; + max_gutter_width := (MAX_FILTER_WIDTH - oversample) div 2; + gutter_width := (FImageMaker.GetFilterSize - oversample) div 2; + BucketWidth := oversample * fcp.Width + 2 * max_gutter_width; + BucketHeight := oversample * fcp.Height + 2 * max_gutter_width; + BucketSize := BucketWidth * BucketHeight; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TBaseRenderer.InitBuffers; +var + error_string : string; +begin + error_string := TextByKey('common-trace-notenoughmemory'); + + CalcBufferSize; + + try + FStop := 0; + TrimWorkingSet; + if SingleBuffer then + TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 16 / 1048576])) + else + TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 32 / 1048576])); + + AllocateBuckets; + + except + on EOutOfMemory do begin + if Assigned(strOutput) then + strOutput.Add(error_string); + FStop := 1; + TrimWorkingSet; + exit; + end; + end; + + // share the buffer with imagemaker + FImageMaker.SetBucketData(GetBucketsPtr, BucketWidth, BucketHeight, 64); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderer.IntermediateSample(imgmkr: TImageMaker); +begin + FCP.actual_density := FCP.sample_density * FRenderer.FBatch / FRenderer.FNumBatches; + imgmkr.SetCP(FCP); + imgmkr.Init; + imgmkr.SetBucketData(FRenderer.GetBucketsPtr, FRenderer.BucketWidth, FRenderer.BucketHeight, 64); + imgmkr.CreateImage; +end; + +procedure TBaseRenderer.Render; +begin + if fcp.NumXForms <= 0 then + begin + exit; + end; + FStop := 0; //False; + + FImageMaker.SetCP(FCP); + FImageMaker.Init; + + InitBuffers; + if FStop <> 0 then exit; // memory allocation error? + + CreateColorMap; + Prepare; + + CreateCamera; + if not FRenderOver then ClearBuckets; + + Operation(opRendering); + + StartTime := Now; + RenderTime := Now; + SetPixels; + RenderTime := Now - RenderTime; + + if FStop <= 0 then begin + if fcp.sample_density = fcp.actual_density then + TimeTrace(TextByKey('common-trace-creating-simple')) + else + TimeTrace(Format(TextByKey('common-trace-creating-detailed'), [fcp.actual_density])); + + if (FBufferPath <> '') then begin + Operation(opHibernating); + Hibernate(FBufferPath); + end; + + Operation(opSampling); + FImageMaker.OnProgress := FOnProgress; + FImageMaker.CreateImage; + end; +end; + +procedure TBaseRenderer.ProcessBuffer(density: double); +var + nsamples: int64; + x, y: integer; + bucket : TBucket; + ptr: TBucketArray; +begin + if fcp.NumXForms <= 0 then exit; + FStop := 0; //False; + + FImageMaker.SetCP(FCP); + FImageMaker.Init; + + InitBuffers; + if FStop <> 0 then exit; // memory allocation error? + + CreateColorMap; + Prepare; + + CreateCamera; + if not FRenderOver then ClearBuckets; + + Operation(opSampling); + + StartTime := Now; + RenderTime := Now; + //////////////// + Randomize; + + NSamples := Round(sample_density * NrSlices * bucketSize / (oversample * oversample)); + FNumBatches := Round(nsamples / (fcp.nbatches * SUB_BATCH_SIZE)); + if FNumBatches = 0 then FNumBatches := 1; + FMinBatches := Round(FNumBatches * FMinDensity / fcp.sample_density); + if FMinBatches = 0 then FMinBatches := 1; + + ptr := TBucketArray(GetBucketsPtr); + if (assigned(FCopyBuffer)) then begin + for y := 0 to BucketHeight - 1 do + for x := 0 to BucketWidth - 1 do + begin + FCopyBuffer(@bucket, x, y); + ptr[y, x].red := bucket.red; + ptr[y, x].green := bucket.green; + ptr[y, x].blue := bucket.blue; + ptr[y, x].count := bucket.count; + end; + + end; + FBatch := FNumBatches; + + fcp.actual_density := density; + + Progress(0); + //////////////// + RenderTime := Now - RenderTime; + + if FStop <= 0 then begin + if fcp.sample_density = fcp.actual_density then + TimeTrace(TextByKey('common-trace-creating-simple')) + else + TimeTrace(Format(TextByKey('common-trace-creating-detailed'), [fcp.actual_density])); + + //Operation(opSampling); + FImageMaker.OnProgress := FOnProgress; + FImageMaker.CreateImage; + end; + +end; + +/////////////////////////////////////////////////////////////////////////////// +// +// { TRenderer } +// +/////////////////////////////////////////////////////////////////////////////// + +destructor TRenderer.Destroy; +begin + if assigned(FRenderer) then + FRenderer.Free; + + inherited; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TRenderer.GetImage: TBitmap; +begin + Result := nil; + if assigned(FRenderer) then + Result := FRenderer.GetImage; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderer.SetCP(CP: TControlPoint); +begin + FCP := CP; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderer.ProcessBuffer(density: double); +begin + if assigned(FRenderer) then + FRenderer.Free; + + assert(Fmaxmem=0); + if FNrThreads <= 1 then + FRenderer := TRenderWorkerST.Create + else begin + FRenderer := TRenderWorkerMT.Create; + FRenderer.NumThreads := FNrThreads; + end; + + FRenderer.SetCP(FCP); + FRenderer.OnProgress := FOnProgress; + FRenderer.OnOperation := FOnOperation; + FRenderer.CopyBufferCallback := FCopyBuffer; + FRenderer.BufferPath := ''; + FRenderer.ProcessBuffer(density); +end; +procedure TRenderer.Render; +begin + if assigned(FRenderer) then + FRenderer.Free; + + assert(Fmaxmem=0); + if FNrThreads <= 1 then + FRenderer := TRenderWorkerST.Create + + else begin + FRenderer := TRenderWorkerMT.Create; + FRenderer.NumThreads := FNrThreads; + end; + + FRenderer.SetCP(FCP); + FRenderer.OnProgress := FOnProgress; + FRenderer.OnOperation := FOnOperation; + FRenderer.BufferPath := FBufferPath; + FRenderer.Render; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderer.Stop; +begin + if assigned(FRenderer) then + FRenderer.Stop; +end; + +procedure TRenderer.Hibernate(fileName: string); +begin + FRenderer.Hibernate(fileName); +end; + +function TRenderer.GetTransparentImage: TPngObject; +begin + Result := FRenderer.GetTransparentImage; +end; + +function TimeToString(t: TDateTime): string; +var + n: integer; +begin + n := Trunc(t); + Result := ''; + if n > 0 then begin + Result := Result + Format(' %d ' + TextByKey('common-days'), [n]); + //if n <> 1 then Result := Result + 's'; + end; + t := t * 24; + n := Trunc(t) mod 24; + if n > 0 then begin + Result := Result + Format(' %d ' + TextByKey('common-hours'), [n]); + //if n <> 1 then Result := Result + 's'; + end; + t := t * 60; + n := Trunc(t) mod 60; + if n > 0 then begin + Result := Result + Format(' %d ' + TextByKey('common-minutes'), [n]); + //if n <> 1 then Result := Result + 's'; + end; + t := t * 60; + t := t - (Trunc(t) div 60) * 60; + Result := Result + Format(' %.2f ' + TextByKey('common-seconds'), [t]); +end; +procedure TBaseRenderer.ShowBigStats; +var + Stats: TBucketStats; + TotalSamples: int64; + + Rbits, Gbits, Bbits, Abits: double; +begin + if not assigned(strOutput) then exit; + + strOutput.Add(''); + if NrSlices = 1 then + strOutput.Add(TextByKey('common-statistics-title-oneslice')) + else + strOutput.Add(TextByKey('common-statistics-title-multipleslices')); // not really useful :-\ + + TotalSamples := int64(FNumBatches) * SUB_BATCH_SIZE; // * fcp.nbatches ? + if TotalSamples <= 0 then begin + //strOutput.Add(' Nothing to talk about!'); // normally shouldn't happen + exit; + end; + strOutput.Add(Format(' ' + TextByKey('common-statistics-maxpossiblebits'), [8 + log2(TotalSamples)])); + FImageMaker.GetBucketStats(Stats); + with Stats do begin + if MaxR > 0 then Rbits := log2(MaxR) else Rbits := 0; + if MaxG > 0 then Gbits := log2(MaxG) else Gbits := 0; + if MaxB > 0 then Bbits := log2(MaxB) else Bbits := 0; + if MaxA > 0 then Abits := log2(MaxA) else Abits := 0; + strOutput.Add(Format(' ' + TextByKey('common-statistics-maxred'), [Rbits])); + strOutput.Add(Format(' ' + TextByKey('common-statistics-maxgreen'), [Gbits])); + strOutput.Add(Format(' ' + TextByKey('common-statistics-maxblue'), [Bbits])); + strOutput.Add(Format(' ' + TextByKey('common-statistics-maxcounter'), [Abits])); + strOutput.Add(Format(' ' + TextByKey('common-statistics-pointhitratio'), [100.0*(TotalA/TotalSamples)])); + if RenderTime > 0 then // hmm + strOutput.Add(Format(' ' + TextByKey('common-statistics-averagespeed'), [TotalSamples / (RenderTime * 24 * 60 * 60)])); + strOutput.Add(' ' + TextByKey('common-statistics-purerenderingtime') + TimeToString(RenderTime)); + end; +end; + +procedure TBaseRenderer.ShowSmallStats; +var + TotalSamples: int64; +begin + if not assigned(strOutput) then exit; + + TotalSamples := int64(FNumBatches) * SUB_BATCH_SIZE; // * fcp.nbatches ? + if RenderTime > 0 then // hmm + strOutput.Add(Format(' ' + TextByKey('common-statistics-averagespeed'), [TotalSamples / (RenderTime * 24 * 60 * 60)])); + strOutput.Add(' ' + TextByKey('common-statistics-purerenderingtime') + TimeToString(RenderTime)); +end; + + +end. + diff --git a/Resources/ARROW_BLACK.cur b/Resources/ARROW_BLACK.cur new file mode 100644 index 0000000..378969b Binary files /dev/null and b/Resources/ARROW_BLACK.cur differ diff --git a/Resources/ARROW_WHITE.cur b/Resources/ARROW_WHITE.cur new file mode 100644 index 0000000..1574c3c Binary files /dev/null and b/Resources/ARROW_WHITE.cur differ diff --git a/Resources/MAINICON.ico b/Resources/MAINICON.ico new file mode 100644 index 0000000..3347702 Binary files /dev/null and b/Resources/MAINICON.ico differ diff --git a/Resources/MOVE_BLACK.cur b/Resources/MOVE_BLACK.cur new file mode 100644 index 0000000..1dd9d1a Binary files /dev/null and b/Resources/MOVE_BLACK.cur differ diff --git a/Resources/MOVE_WB.cur b/Resources/MOVE_WB.cur new file mode 100644 index 0000000..22a3478 Binary files /dev/null and b/Resources/MOVE_WB.cur differ diff --git a/Resources/MOVE_WHITE.cur b/Resources/MOVE_WHITE.cur new file mode 100644 index 0000000..13040d8 Binary files /dev/null and b/Resources/MOVE_WHITE.cur differ diff --git a/Resources/ROTATE_BLACK.cur b/Resources/ROTATE_BLACK.cur new file mode 100644 index 0000000..7020049 Binary files /dev/null and b/Resources/ROTATE_BLACK.cur differ diff --git a/Resources/ROTATE_WB.cur b/Resources/ROTATE_WB.cur new file mode 100644 index 0000000..870a99f Binary files /dev/null and b/Resources/ROTATE_WB.cur differ diff --git a/Resources/ROTATE_WHITE.cur b/Resources/ROTATE_WHITE.cur new file mode 100644 index 0000000..c057d60 Binary files /dev/null and b/Resources/ROTATE_WHITE.cur differ diff --git a/Resources/SCALE_BLACK.cur b/Resources/SCALE_BLACK.cur new file mode 100644 index 0000000..dd3af34 Binary files /dev/null and b/Resources/SCALE_BLACK.cur differ diff --git a/Resources/SCALE_WB.cur b/Resources/SCALE_WB.cur new file mode 100644 index 0000000..611e7e8 Binary files /dev/null and b/Resources/SCALE_WB.cur differ diff --git a/Resources/SCALE_WHITE.cur b/Resources/SCALE_WHITE.cur new file mode 100644 index 0000000..d3e05ca Binary files /dev/null and b/Resources/SCALE_WHITE.cur differ diff --git a/Resources/SplashScreen.bmp b/Resources/SplashScreen.bmp new file mode 100644 index 0000000..c2a93fb Binary files /dev/null and b/Resources/SplashScreen.bmp differ diff --git a/Resources/THUMB_PLACEHOLDER.bmp b/Resources/THUMB_PLACEHOLDER.bmp new file mode 100644 index 0000000..4edf777 Binary files /dev/null and b/Resources/THUMB_PLACEHOLDER.bmp differ diff --git a/Resources/Unicode.res b/Resources/Unicode.res new file mode 100644 index 0000000..0106564 Binary files /dev/null and b/Resources/Unicode.res differ diff --git a/Resources/apophysis7x.rc b/Resources/apophysis7x.rc new file mode 100644 index 0000000..c03791b --- /dev/null +++ b/Resources/apophysis7x.rc @@ -0,0 +1,42 @@ +ARROW_BLACK CURSOR "ARROW_BLACK.cur" +ARROW_WHITE CURSOR "ARROW_WHITE.cur" +MOVE_BLACK CURSOR "MOVE_BLACK.cur" +MOVE_WB CURSOR "MOVE_WB.cur" +MOVE_WHITE CURSOR "MOVE_WHITE.cur" +ROTATE_BLACK CURSOR "ROTATE_BLACK.cur" +ROTATE_WB CURSOR "ROTATE_WB.cur" +ROTATE_WHITE CURSOR "ROTATE_WHITE.cur" +SCALE_BLACK CURSOR "SCALE_BLACK.cur" +SCALE_WB CURSOR "SCALE_WB.cur" +SCALE_WHITE CURSOR "SCALE_WHITE.cur" +THUMB_PLACEHOLDER BITMAP "THUMB_PLACEHOLDER.bmp" + +MAINICON ICON "MAINICON.ico" +1 VERSIONINFO + FILEVERSION 2,1,0,1500 + PRODUCTVERSION 2,1,0,1500 + FILEOS 0x00000004 + FILETYPE 0x00000001 + FILESUBTYPE 0x00000000 + FILEFLAGSMASK 0x00000000 + FILEFLAGS 0x00000000 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904e4" + { + VALUE "CompanyName", "Apophysis Developers Team" + VALUE "FileDescription", "Apophysis 7X" + VALUE "FileVersion", "2.1.0.1500" + VALUE "InternalName", "2.09.7x15-1500" + VALUE "LegalCopyright", "Copyright (c) 2005-2010 Apophysis Developers Team" + VALUE "OriginalFilename", "Apophysis7X.exe" + VALUE "ProductName", "Apophysis" + VALUE "ProductVersion", "2.1.0.1500" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 0x04E4 + } +} diff --git a/Resources/apophysis7x.res b/Resources/apophysis7x.res new file mode 100644 index 0000000..b296cbe Binary files /dev/null and b/Resources/apophysis7x.res differ diff --git a/Resources/resource.h b/Resources/resource.h new file mode 100644 index 0000000..88919df --- /dev/null +++ b/Resources/resource.h @@ -0,0 +1,4 @@ +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif + diff --git a/System/AsmRandom.pas b/System/AsmRandom.pas new file mode 100644 index 0000000..f2ca2d8 --- /dev/null +++ b/System/AsmRandom.pas @@ -0,0 +1,95 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This module is (c) Jed Kelsey and originally created for Apophysis JK 2.10. +} + +unit AsmRandom; + +interface + +procedure AsmRandInt; +procedure AsmRandExt; +procedure AsmRandomize; + +var + RandSeed: Longint = 0; { Base for random number generator } + +implementation + +const + advapi32 = 'advapi32.dll'; + kernel = 'kernel32.dll'; + +function QueryPerformanceCounter(var lpPerformanceCount: Int64): LongBool; stdcall; + external kernel name 'QueryPerformanceCounter'; + +function GetTickCount: Cardinal; + external kernel name 'GetTickCount'; + + +procedure AsmRandomize; +{$IFDEF LINUX} +begin + RandSeed := _time(nil); +end; +{$ENDIF} +{$IFDEF MSWINDOWS} +var + Counter: Int64; +begin + if QueryPerformanceCounter(Counter) then + RandSeed := Counter + else + RandSeed := GetTickCount; +end; +{$ENDIF} + +procedure AsmRandInt; +asm +{ ->EAX Range } +{ <-EAX Result } + IMUL EDX,RandSeed,08088405H + INC EDX + MOV RandSeed,EDX + MUL EDX + MOV EAX,EDX +end; + +procedure AsmRandExt; +const two2neg32: double = ((1.0/$10000) / $10000); // 2^-32 +asm +{ FUNCTION _RandExt: Extended; } + + IMUL EDX,RandSeed,08088405H + INC EDX + MOV RandSeed,EDX + + FLD two2neg32 + PUSH 0 + PUSH EDX + FILD qword ptr [ESP] + ADD ESP,8 + FMULP ST(1), ST(0) +end; + +end. diff --git a/System/CurvesControl.dfm b/System/CurvesControl.dfm new file mode 100644 index 0000000..1c6d903 --- /dev/null +++ b/System/CurvesControl.dfm @@ -0,0 +1,23 @@ +object CurvesControl: TCurvesControl + Left = 0 + Top = 0 + Width = 542 + Height = 440 + DoubleBuffered = True + Color = clBlack + ParentBackground = False + ParentColor = False + ParentDoubleBuffered = False + TabOrder = 0 + object Host: TPanel + Left = 0 + Top = 0 + Width = 542 + Height = 440 + Align = alClient + BevelOuter = bvNone + Color = clBlack + ParentBackground = False + TabOrder = 0 + end +end diff --git a/System/CurvesControl.pas b/System/CurvesControl.pas new file mode 100644 index 0000000..bdb6d73 --- /dev/null +++ b/System/CurvesControl.pas @@ -0,0 +1,384 @@ +unit CurvesControl; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Math, ControlPoint, + Graphics, Controls, Forms, Bezier, CustomDrawControl, Vcl.ExtCtrls; + +const + point_size: double = 8; + accurancy: double = 3; + channel_count: integer = 4; + padding = 3; + +const + MAX_CHANNEL = 3; + +type + TCurvesChannel = (ccAll = 0, ccRed = 1, ccGreen = 2, ccBlue = 3); + TCurvesControl = class(TFrame) + Host: TPanel; + private + FRect: BezierRect; + + FPoints: array [0..3] of BezierPoints; + FWeights: array [0..3] of BezierWeights; + + FDragging: boolean; + FDragIndex: integer; + + FActiveChannel : TCurvesChannel; + FChannelIndex : integer; + + FFrame : TCustomDrawControl; + FCP: TControlPoint; + + p: array [0..MAX_CHANNEL] of BezierPoints; + w: array [0..MAX_CHANNEL] of BezierWeights; + wsum: array [0..MAX_CHANNEL] of double; + + procedure SetChannel(value: TCurvesChannel); + procedure SetWeightLeft(value: double); + procedure SetWeightRight(value: double); + + function GetChannel: TCurvesChannel; + function GetWeightLeft: double; + function GetWeightRight: double; + + procedure FrameMouseLeave(Sender: TObject); + procedure FrameMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); + procedure FrameMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure FrameMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure FrameResize(Sender: TObject); + procedure FramePaint(Sender: TObject); + procedure FrameCreate; + + procedure PaintCurve(Bitmap: TBitmap; c: integer; p: BezierPoints; w: BezierWeights; widgets: boolean); + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + property WeightLeft : double read GetWeightLeft write SetWeightLeft; + property WeightRight : double read GetWeightRight write SetWeightRight; + property ActiveChannel : TCurvesChannel read GetChannel write SetChannel; + + procedure SetCp(cp: TControlPoint); + procedure UpdateFlame; + end; + +implementation + +{$R *.DFM} + +uses Main, Editor, Mutate, Adjust; + +constructor TCurvesControl.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FFrame := TCustomDrawControl.Create(self); + FFrame.TabStop := True; + FFrame.TabOrder := 0; + FFrame.Parent := Host; + FFrame.Align := alClient; + FFrame.Visible := True; + + FFrame.OnPaint := FramePaint; + FFrame.OnMouseDown := FrameMouseDown; + FFrame.OnMouseMove := FrameMouseMove; + FFrame.OnMouseUp := FrameMouseUp; + FFrame.OnMouseLeave := FrameMouseLeave; + + FCP := TControlPoint.Create; + + FrameCreate; +end; +destructor TCurvesControl.Destroy; +begin + FCP.Destroy; + inherited Destroy; +end; + +procedure TCurvesControl.SetCp(cp: TControlPoint); +var i, j: integer; +begin + FCP.Copy(cp, true); + for i := 0 to 3 do + for j := 0 to 3 do begin + FWeights[i,j] := FCP.curveWeights[i,j]; + FPoints[i,j].x := FCP.curvePoints[i,j].x; + FPoints[i,j].y := FCP.curvePoints[i,j].y; + end; + Invalidate; + FFrame.Invalidate; +end; +procedure TCurvesControl.UpdateFlame; +begin + MainForm.StopThread; + MainForm.UpdateUndo; + MainCp.Copy(FCP, true); + + if EditForm.Visible then EditForm.UpdateDisplay; + if MutateForm.Visible then MutateForm.UpdateDisplay; + if AdjustForm.Visible then AdjustForm.UpdateDisplay(true); + + MainForm.RedrawTimer.enabled := true; +end; + +procedure TCurvesControl.FrameMouseLeave(Sender: TObject); +begin + FrameMouseUp(nil, mbLeft, [], 0, 0); +end; +procedure TCurvesControl.FrameMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +var + ps_half: double; + i, n: integer; + p: BezierPoints; +begin + BezierCopy(FPoints[FChannelIndex], p); + BezierSetRect(p, true, FRect); + + FDragIndex := -1; + FDragging := false; + + n := Length(p); + for i := 1 to n - 2 do if + (X >= p[i].x - point_size) and (X <= p[i].x + point_size) and + (Y >= p[i].y - point_size) and (Y <= p[i].y + point_size) then + begin + FDragging := true; + FDragIndex := i; + Break; + end; +end; +procedure TCurvesControl.FrameMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); +var + m: BezierPoints; + tmp: BezierPoint; + i: Integer; + j: Integer; +begin + + if (y < 0) then Exit; + if (x < 0) then Exit; + + m[0].x := x; m[0].y := y; + BezierUnsetRect(m, true, FRect); + + if FDragging then + begin + FPoints[FChannelIndex][FDragIndex] := m[0]; + if (FPoints[FChannelIndex][FDragIndex].x <= 0) + then FPoints[FChannelIndex][FDragIndex].x := 0; + if (FPoints[FChannelIndex][FDragIndex].y <= 0) + then FPoints[FChannelIndex][FDragIndex].y := 0; + if (FPoints[FChannelIndex][FDragIndex].x >= 1) + then FPoints[FChannelIndex][FDragIndex].x := 1; + if (FPoints[FChannelIndex][FDragIndex].y >= 1) + then FPoints[FChannelIndex][FDragIndex].y := 1; + + if (FPoints[FChannelIndex][1].x > FPoints[FChannelIndex][2].x) then + begin + tmp := FPoints[FChannelIndex][1]; + FPoints[FChannelIndex][1] := FPoints[FChannelIndex][2]; + FPoints[FChannelIndex][2] := tmp; + if (FDragIndex = 1) then FDragIndex := 2 + else FDragIndex := 1; + end; + + for i := 0 to 3 do + for j := 0 to 3 do begin + FCP.curveWeights[i,j] := FWeights[i,j]; + FCP.curvePoints[i,j].x := FPoints[i,j].x; + FCP.curvePoints[i,j].y := FPoints[i,j].y; + end; + + + FFrame.Refresh; + end; +end; +procedure TCurvesControl.FrameMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + FDragIndex := -1; + FDragging := false; + + if (sender <> nil) then UpdateFlame; +end; + +procedure TCurvesControl.FrameCreate; +var i: integer; +begin + for i := 0 to channel_count - 1 do + begin + FPoints[i][0].x := 0.00; FPoints[i][0].y := 0.00; FWeights[i][0] := 1; + FPoints[i][1].x := 0.00; FPoints[i][1].y := 0.00; FWeights[i][1] := 1; + FPoints[i][2].x := 1.00; FPoints[i][2].y := 1.00; FWeights[i][2] := 1; + FPoints[i][3].x := 1.00; FPoints[i][3].y := 1.00; FWeights[i][3] := 1; + end; + + FDragIndex := -1; + FDragging := false; +end; +procedure TCurvesControl.FrameResize(Sender: TObject); +begin + FRect.x0 := 0; FRect.y0 := 0; + FRect.x1 := self.Width - 1; + FRect.y1 := self.Height - 1; +end; +procedure TCurvesControl.FramePaint(Sender: TObject); +var + clientRect: TRect; + i, j, x, y, sx, sy: integer; + bitmap: TBitMap; +begin + if (FFrame.Width <= 0) or (FFrame.Height <= 0) then Exit; + FrameResize(Sender); + + Bitmap := TBitmap.Create; + Bitmap.Width := FFrame.Width; + Bitmap.Height := FFrame.Height; + + sx := Bitmap.Width; + sy := Bitmap.Height; + + try + with Bitmap.Canvas do + begin + Brush.Color := $000000; + FillRect(Rect(0, 0, sx, sy)); + + Pen.Color := $555555; + Pen.Style := psSolid; + Pen.Width := 1; + + for x := 1 to 7 do begin + MoveTo(Round(0.125 * x * FRect.x1), Round(FRect.y0)); + LineTo(Round(0.125 * x * FRect.x1), Round(FRect.y1)); + end; + for y := 1 to 3 do begin + MoveTo(Round(FRect.x0), Round(0.25 * y * FRect.y1)); + LineTo(Round(FRect.x1), Round(0.25 * y * FRect.y1)); + end; + + for i := 0 to channel_count - 1 do begin + for j := 0 to 3 do + wsum[i] := wsum[i] + FWeights[i][j]; + for j := 0 to 3 do + w[i][j] := FWeights[i][j] / wsum[i]; + + BezierCopy(FPoints[i], p[i]); + BezierSetRect(p[i], true, FRect); + + if i <> FChannelIndex then PaintCurve(Bitmap, i, p[i], w[i], false); + end; + PaintCurve(Bitmap, FChannelIndex, p[FChannelIndex], w[FChannelIndex], true); + + FFrame.Canvas.Draw(0, 0, Bitmap); + end; + finally + Bitmap.Free; + end; +end; + +procedure TCurvesControl.PaintCurve(Bitmap: TBitmap; c: integer; p: BezierPoints; w: BezierWeights; widgets: boolean); +var + pos0, pos1: BezierPoint; + t, step: Double; + r, g, b: array [0 .. MAX_CHANNEL] of integer; + rgbv: integer; +begin + with Bitmap.Canvas do + begin + if c <> FChannelIndex then begin + r[0] := $aa; r[1] := $aa; r[2] := $40; r[3] := $40; + g[0] := $aa; g[1] := $40; g[2] := $aa; g[3] := $40; + b[0] := $aa; b[1] := $40; b[2] := $40; b[3] := $aa; + end else begin + r[0] := $ff; r[1] := $ff; r[2] := $80; r[3] := $80; + g[0] := $ff; g[1] := $80; g[2] := $ff; g[3] := $80; + b[0] := $ff; b[1] := $80; b[2] := $80; b[3] := $ff; + end; + + rgbv := RGB(r[c], g[c], b[c]); + + t := 0; + step := 0.001; + + BezierSolve(0, p, w, pos1); + pos0.x := 0; pos0.y := pos1.y; + + if widgets then begin + Pen.Color := $808080; Pen.Width := 1; + MoveTo(Round(p[1].x), Round(p[1].y)); + LineTo(Round(p[2].x), Round(p[2].y)); + MoveTo(Round(FRect.x0), Round(FRect.y1)); + LineTo(Round(p[1].x), Round(p[1].y)); + MoveTo(Round(FRect.x1), Round(FRect.y0)); + LineTo(Round(p[2].x), Round(p[2].y)); + end; + + while t < 1 do begin + BezierSolve(t, p, w, pos1); + Pen.Color := rgbv; + Pen.Width := 1; + MoveTo(Round(pos0.x), Round(pos0.y)); + LineTo(Round(pos1.x), Round(pos1.y)); + t := t + step; + pos0 := pos1; + end; + + MoveTo(Round(pos0.x), Round(pos0.y)); + LineTo(Round(FRect.x1), Round(pos0.y)); + + if widgets then begin + Brush.Color := rgbv; + Ellipse( + Round(p[1].x - point_size / 2.0), + Round(p[1].y - point_size / 2.0), + Round(p[1].x + point_size / 2.0), + Round(p[1].y + point_size / 2.0) + ); + Ellipse( + Round(p[2].x - point_size / 2.0), + Round(p[2].y - point_size / 2.0), + Round(p[2].x + point_size / 2.0), + Round(p[2].y + point_size / 2.0) + ); + end; + end; +end; + +procedure TCurvesControl.SetChannel(value: TCurvesChannel); +begin + FActiveChannel := value; + FChannelIndex := Integer(value); + FFrame.Refresh; +end; +procedure TCurvesControl.SetWeightLeft(value: double); +begin + FWeights[FChannelIndex][1] := value; + FCP.curveWeights[FChannelIndex][1] := value; + FFrame.Refresh; +end; +procedure TCurvesControl.SetWeightRight(value: double); +begin + FWeights[FChannelIndex][2] := value; + FCP.curveWeights[FChannelIndex][2] := value; + FFrame.Refresh; +end; + +function TCurvesControl.GetChannel: TCurvesChannel; +begin + Result := FActiveChannel; +end; +function TCurvesControl.GetWeightLeft: double; +begin + Result := FWeights[FChannelIndex][1]; +end; +function TCurvesControl.GetWeightRight: double; +begin + Result := FWeights[FChannelIndex][2]; +end; + +end. diff --git a/System/CustomDrawControl.pas b/System/CustomDrawControl.pas new file mode 100644 index 0000000..18d3e22 --- /dev/null +++ b/System/CustomDrawControl.pas @@ -0,0 +1,99 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit CustomDrawControl; + +interface + +uses + Classes, Controls, Messages, Windows, Graphics; + +type + TCustomDrawControl = class(TCustomControl) + private + FOnPaint: TNotifyEvent; + FOnLeave: TNotifyEvent; + + procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND; + procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS; + procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS; + procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE; + procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; + protected + + public + procedure Paint; override; + + property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; + property Canvas; + + property OnDblClick; + property OnKeyDown; +// property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; +// property OnMouseWheelDown; +// property OnMouseWheelUp; + property OnEnter; + property OnExit; + property OnMouseLeave: TNotifyEvent read FOnLeave write FOnLeave; + end; + +implementation + +procedure TCustomDrawControl.WMEraseBkgnd(var Message: TWMEraseBkgnd); +begin + Message.Result := 1; +end; + +procedure TCustomDrawControl.WMSetFocus(var Message: TWMSetFocus); +begin + Invalidate; +end; + +procedure TCustomDrawControl.WMKillFocus(var Message: TWMKillFocus); +begin + if assigned(OnExit) then OnExit(self); + Invalidate; +end; + +procedure TCustomDrawControl.WMGetDlgCode(var Message: TMessage); +begin + inherited; + Message.Result := Message.Result or DLGC_WANTARROWS; +end; + +procedure TCustomDrawControl.CMMouseLeave(var Message: TMessage); +begin + if Assigned(FOnLeave) then FOnLeave(Self); +end; + +procedure TCustomDrawControl.Paint; +begin + if Assigned(FOnPaint) then FOnPaint(Self); +end; + +end. diff --git a/System/FastMM4.pas b/System/FastMM4.pas new file mode 100644 index 0000000..ae03dbf --- /dev/null +++ b/System/FastMM4.pas @@ -0,0 +1,11170 @@ +(* + +Fast Memory Manager 4.99 + +Description: + A fast replacement memory manager for Embarcadero Delphi Win32 applications + that scales well under multi-threaded usage, is not prone to memory + fragmentation, and supports shared memory without the use of external .DLL + files. + +Homepage: + http://fastmm.sourceforge.net + +Advantages: + - Fast + - Low overhead. FastMM is designed for an average of 5% and maximum of 10% + overhead per block. + - Supports up to 3GB of user mode address space under Windows 32-bit and 4GB + under Windows 64-bit. Add the "$SetPEFlags $20" option (in curly braces) + to your .dpr to enable this. + - Highly aligned memory blocks. Can be configured for either 8-byte or 16-byte + alignment. + - Good scaling under multi-threaded applications + - Intelligent reallocations. Avoids slow memory move operations through + not performing unneccesary downsizes and by having a minimum percentage + block size growth factor when an in-place block upsize is not possible. + - Resistant to address space fragmentation + - No external DLL required when sharing memory between the application and + external libraries (provided both use this memory manager) + - Optionally reports memory leaks on program shutdown. (This check can be set + to be performed only if Delphi is currently running on the machine, so end + users won't be bothered by the error message.) + - Supports Delphi 4 (or later), C++ Builder 4 (or later), Kylix 3. + +Usage: + Delphi: + Place this unit as the very first unit under the "uses" section in your + project's .dpr file. When sharing memory between an application and a DLL + (e.g. when passing a long string or dynamic array to a DLL function), both the + main application and the DLL must be compiled using this memory manager (with + the required conditional defines set). There are some conditional defines + (inside FastMM4Options.inc) that may be used to tweak the memory manager. To + enable support for a user mode address space greater than 2GB you will have to + use the EditBin* tool to set the LARGE_ADDRESS_AWARE flag in the EXE header. + This informs Windows x64 or Windows 32-bit (with the /3GB option set) that the + application supports an address space larger than 2GB (up to 4GB). In Delphi 6 + and later you can also specify this flag through the compiler directive + {$SetPEFlags $20} + *The EditBin tool ships with the MS Visual C compiler. + C++ Builder 6: + Refer to the instructions inside FastMM4BCB.cpp. + +License: + This work is copyright Professional Software Development / Pierre le Riche. It + is released under a dual license, and you may choose to use it under either the + Mozilla Public License 1.1 (MPL 1.1, available from + http://www.mozilla.org/MPL/MPL-1.1.html) or the GNU Lesser General Public + License 2.1 (LGPL 2.1, available from + http://www.opensource.org/licenses/lgpl-license.php). If you find FastMM useful + or you would like to support further development, a donation would be much + appreciated. My banking details are: + Country: South Africa + Bank: ABSA Bank Ltd + Branch: Somerset West + Branch Code: 334-712 + Account Name: PSD (Distribution) + Account No.: 4041827693 + Swift Code: ABSAZAJJ + My PayPal account is: + bof@psd.co.za + +Contact Details: + My contact details are shown below if you would like to get in touch with me. + If you use this memory manager I would like to hear from you: please e-mail me + your comments - good and bad. + Snailmail: + PO Box 2514 + Somerset West + 7129 + South Africa + E-mail: + plr@psd.co.za + +Support: + If you have trouble using FastMM, you are welcome to drop me an e-mail at the + address above, or you may post your questions in the BASM newsgroup on the + Embarcadero news server (which is where I hang out quite frequently). + +Disclaimer: + FastMM has been tested extensively with both single and multithreaded + applications on various hardware platforms, but unfortunately I am not in a + position to make any guarantees. Use it at your own risk. + +Acknowledgements (for version 4): + - Eric Grange for his RecyclerMM on which the earlier versions of FastMM were + based. RecyclerMM was what inspired me to try and write my own memory + manager back in early 2004. + - Primoz Gabrijelcic for helping to track down various bugs. + - Dennis Christensen for his tireless efforts with the Fastcode project: + helping to develop, optimize and debug the growing Fastcode library. + - JiYuan Xie for implementing the leak reporting code for C++ Builder. + - Pierre Y. for his suggestions regarding the extension of the memory leak + checking options. + - Hanspeter Widmer for his suggestion to have an option to display install and + uninstall debug messages and moving options to a separate file, as well as + the new usage tracker. + - Anders Isaksson and Greg for finding and identifying the "DelphiIsRunning" + bug under Delphi 5. + - Francois Malan for various suggestions and bug reports. + - Craig Peterson for helping me identify the cache associativity issues that + could arise due to medium blocks always being an exact multiple of 256 bytes. + Also for various other bug reports and enhancement suggestions. + - Jarek Karciarz, Vladimir Ulchenko (Vavan) and Bob Gonder for their help in + implementing the BCB support. + - Ben Taylor for his suggestion to display the object class of all memory + leaks. + - Jean Marc Eber and Vincent Mahon (the Memcheck guys) for the call stack + trace code and also the method used to catch virtual method calls on freed + objects. + - Nahan Hyn for the suggestion to be able to enable or disable memory leak + reporting through a global variable (the "ManualLeakReportingControl" + option.) + - Leonel Togniolli for various suggestions with regard to enhancing the bug + tracking features of FastMM and other helpful advice. + - Joe Bain and Leonel Togniolli for the workaround to QC#10922 affecting + compilation under Delphi 2005. + - Robert Marquardt for the suggestion to make localisation of FastMM easier by + having all string constants together. + - Simon Kissel and Fikret Hasovic for their help in implementing Kylix support. + - Matthias Thoma, Petr Vones, Robert Rossmair and the rest of the JCL team for + their debug info library used in the debug info support DLL and also the + code used to check for a valid call site in the "raw" stack trace code. + - Andreas Hausladen for the suggestion to use an external DLL to enable the + reporting of debug information. + - Alexander Tabakov for various good suggestions regarding the debugging + facilities of FastMM. + - M. Skloff for some useful suggestions and bringing to my attention some + compiler warnings. + - Martin Aignesberger for the code to use madExcept instead of the JCL library + inside the debug info support DLL. + - Diederik and Dennis Passmore for the suggestion to be able to register + expected leaks. + - Dario Tiraboschi and Mark Gebauer for pointing out the problems that occur + when range checking and complete boolean evaluation is turned on. + - Arthur Hoornweg for notifying me of the image base being incorrect for + borlndmm.dll. + - Theo Carr-Brion and Hanspeter Widmer for finding the false alarm error + message "Block Header Has Been Corrupted" bug in FullDebugMode. + - Danny Heijl for reporting the compiler error in "release" mode. + - Omar Zelaya for reporting the BCB support regression bug. + - Dan Miser for various good suggestions, e.g. not logging expected leaks to + file, enhancements the stack trace and messagebox functionality, etc. + - Arjen de Ruijter for fixing the bug in GetMemoryLeakType that caused it + to not properly detect expected leaks registered by class when in + "FullDebugMode". + - Aleksander Oven for reporting the installation problem when trying to use + FastMM in an application together with libraries that all use runtime + packages. + - Kristofer Skaug for reporting the bug that sometimes causes the leak report + to be shown, even when all the leaks have been registered as expected leaks. + Also for some useful enhancement suggestions. + - Günther Schoch for the "RequireDebuggerPresenceForLeakReporting" option. + - Jan Schlüter for the "ForceMMX" option. + - Hallvard Vassbotn for various good enhancement suggestions. + - Mark Edington for some good suggestions and bug reports. + - Paul Ishenin for reporting the compilation error when the NoMessageBoxes + option is set and also the missing call stack entries issue when "raw" stack + traces are enabled, as well as for the Russian translation. + - Cristian Nicola for reporting the compilation bug when the + CatchUseOfFreedInterfaces option was enabled (4.40). + - Mathias Rauen (madshi) for improving the support for madExcept in the debug + info support DLL. + - Roddy Pratt for the BCB5 support code. + - Rene Mihula for the Czech translation and the suggestion to have dynamic + loading of the FullDebugMode DLL as an option. + - Artur Redzko for the Polish translation. + - Bart van der Werf for helping me solve the DLL unload order problem when + using the debug mode borlndmm.dll library, as well as various other + suggestions. + - JRG ("The Delphi Guy") for the Spanish translation. + - Justus Janssen for Delphi 4 support. + - Vadim Lopushansky and Charles Vinal for reporting the Delphi 5 compiler + error in version 4.50. + - Johni Jeferson Capeletto for the Brazilian Portuguese translation. + - Kurt Fitzner for reporting the BCb6 compiler error in 4.52. + - Michal Niklas for reporting the Kylix compiler error in 4.54. + - Thomas Speck and Uwe Queisser for German translations. + - Zaenal Mutaqin for the Indonesian translation. + - Carlos Macao for the Portuguese translation. + - Michael Winter for catching the performance issue when reallocating certain + block sizes. + - dzmitry[li] for the Belarussian translation. + - Marcelo Montenegro for the updated Spanish translation. + - Jud Cole for finding and reporting the bug which may trigger a read access + violation when upsizing certain small block sizes together with the + "UseCustomVariableSizeMoveRoutines" option. + - Zdenek Vasku for reporting and fixing the memory manager sharing bug + affecting Windows 95/98/Me. + - RB Winston for suggesting the improvement to GExperts "backup" support. + - Thomas Schulz for reporting the bug affecting large address space support + under FullDebugMode, as well as the recursive call bug when attempting to + report memory leaks when EnableMemoryLeakReporting is disabled. + - Luigi Sandon for the Italian translation. + - Werner Bochtler for various suggestions and bug reports. + - Markus Beth for suggesting the "NeverSleepOnThreadContention" option. + - JiYuan Xie for the Simplified Chinese translation. + - Andrey Shtukaturov for the updated Russian translation, as well as the + Ukrainian translation. + - Dimitry Timokhov for finding two elusive bugs in the memory leak class + detection code. + - Paulo Moreno for fixing the AllocMem bug in FullDebugMode that prevented + large blocks from being cleared. + - Vladimir Bochkarev for the suggestion to remove some unnecessary code if the + MM sharing mechanism is disabled. + - Loris Luise for the version constant suggestion. + - J.W. de Bokx for the MessageBox bugfix. + - Igor Lindunen for reporting the bug that caused the Align16Bytes option to + not work in FullDebugMode. + - Ionut Muntean for the Romanian translation. + - Florent Ouchet for the French translation. + - Marcus Mönnig for the ScanMemoryPoolForCorruptions suggestion and the + suggestion to have the option to scan the memory pool before every + operation when in FullDebugMode. + - Francois Piette for bringing under my attention that + ScanMemoryPoolForCorruption was not thread safe. + - Michael Rabatscher for reporting some compiler warnings. + - QianYuan Wang for the Simplified Chinese translation of FastMM4Options.inc. + - Maurizio Lotauro and Christian-W. Budde for reporting some Delphi 5 + compiler errors. + - Patrick van Logchem for the DisableLoggingOfMemoryDumps option. + - Norbert Spiegel for the BCB4 support code. + - Uwe Schuster for the improved string leak detection code. + - Murray McGowan for improvements to the usage tracker. + - Michael Hieke for the SuppressFreeMemErrorsInsideException option as well + as a bugfix to GetMemoryMap. + - Richard Bradbrook for fixing the Windows 95 FullDebugMode support that was + broken in version 4.94. + - Zach Saw for the suggestion to (optionally) use SwitchToThread when + waiting for a lock on a shared resource to be released. + - Everyone who have made donations. Thanks! + - Any other Fastcoders or supporters that I have forgotten, and also everyone + that helped with the older versions. + +Change log: + Version 1.00 (28 June 2004): + - First version (called PSDMemoryManager). Based on RecyclerMM (free block + stack approach) by Eric Grange. + Version 2.00 (3 November 2004): + - Complete redesign and rewrite from scratch. Name changed to FastMM to + reflect this fact. Uses a linked-list approach. Is faster, has less memory + overhead, and will now catch most bad pointers on FreeMem calls. + Version 3.00 (1 March 2005): + - Another rewrite. Reduced the memory overhead by: (a) not having a separate + memory area for the linked list of free blocks (uses space inside free + blocks themselves) (b) batch managers are allocated as part of chunks (c) + block size lookup table size reduced. This should make FastMM more CPU + cache friendly. + Version 4.00 (7 June 2005): + - Yet another rewrite. FastMM4 is in fact three memory managers in one: Small + blocks (up to a few KB) are managed through the binning model in the same + way as previous versions, medium blocks (from a few KB up to approximately + 256K) are allocated in a linked-list fashion, and large blocks are grabbed + directly from the system through VirtualAlloc. This 3-layered design allows + very fast operation with the most frequently used block sizes (small + blocks), while also minimizing fragmentation and imparting significant + overhead savings with blocks larger than a few KB. + Version 4.01 (8 June 2005): + - Added the options "RequireDebugInfoForLeakReporting" and + "RequireIDEPresenceForLeakReporting" as suggested by Pierre Y. + - Fixed the "DelphiIsRunning" function not working under Delphi 5, and + consequently no leak checking. (Reported by Anders Isaksson and Greg.) + Version 4.02 (8 June 2005): + - Fixed the compilation error when both the "AssumeMultiThreaded" and + "CheckHeapForCorruption options were set. (Reported by Francois Malan.) + Version 4.03 (9 June 2005): + - Added descriptive error messages when FastMM4 cannot be installed because + another MM has already been installed or memory has already been allocated. + Version 4.04 (13 June 2005): + - Added a small fixed offset to the size of medium blocks (previously always + exact multiples of 256 bytes). This makes performance problems due to CPU + cache associativity limitations much less likely. (Reported by Craig + Peterson.) + Version 4.05 (17 June 2005): + - Added the Align16Bytes option. Disable this option to drop the 16 byte + alignment restriction and reduce alignment to 8 bytes for the smallest + block sizes. Disabling Align16Bytes should lower memory consumption at the + cost of complicating the use of aligned SSE move instructions. (Suggested + by Craig Peterson.) + - Added a support unit for C++ Builder 6 - Add FastMM4BCB.cpp and + FastMM4.pas to your BCB project to use FastMM instead of the RTL MM. Memory + leak checking is not supported because (unfortunately) once an MM is + installed under BCB you cannot uninstall it... at least not without + modifying the RTL code in exit.c or patching the RTL code runtime. (Thanks + to Jarek Karciarz, Vladimir Ulchenko and Bob Gonder.) + Version 4.06 (22 June 2005): + - Displays the class of all leaked objects on the memory leak report and also + tries to identify leaked long strings. Previously it only displayed the + sizes of all leaked blocks. (Suggested by Ben Taylor.) + - Added support for displaying the sizes of medium and large block memory + leaks. Previously it only displayed details for small block leaks. + Version 4.07 (22 June 2005): + - Fixed the detection of the class of leaked objects not working under + Windows 98/Me. + Version 4.08 (27 June 2005): + - Added a BorlndMM.dpr project to allow you to build a borlndmm.dll that uses + FastMM4 instead of the default memory manager. You may replace the old + DLL in the Delphi \Bin directory to make the IDE use this memory manager + instead. + Version 4.09 (30 June 2005): + - Included a patch fix for the bug affecting replacement borlndmm.dll files + with Delphi 2005 (QC#14007). Compile the patch, close Delphi, and run it + once to patch your vclide90.bpl. You will now be able to use the + replacement borlndmm.dll to speed up the Delphi 2005 IDE as well. + Version 4.10 (7 July 2005): + - Due to QC#14070 ("Delphi IDE attempts to free memory after the shutdown + code of borlndmm.dll has been called"), FastMM cannot be uninstalled + safely when used inside a replacement borlndmm.dll for the IDE. Added a + conditional define "NeverUninstall" for this purpose. + - Added the "FullDebugMode" option to pad all blocks with a header and footer + to help you catch memory overwrite bugs in your applications. All blocks + returned to freemem are also zeroed out to help catch bugs involving the + use of previously freed blocks. Also catches attempts at calling virtual + methods of freed objects provided the block in question has not been reused + since the object was freed. Displays stack traces on error to aid debugging. + - Added the "LogErrorsToFile" option to log all errors to a text file in the + same folder as the application. + - Added the "ManualLeakReportingControl" option (suggested by Nahan Hyn) to + enable control over whether the memory leak report should be done or not + via a global variable. + Version 4.11 (7 July 2005): + - Fixed a compilation error under Delphi 2005 due to QC#10922. (Thanks to Joe + Bain and Leonel Togniolli.) + - Fixed leaked object classes not displaying in the leak report in + "FullDebugMode". + Version 4.12 (8 July 2005): + - Moved all the string constants to one place to make it easier to do + translations into other languages. (Thanks to Robert Marquardt.) + - Added support for Kylix. Some functionality is currently missing: No + support for detecting the object class on leaks and also no MM sharing. + (Thanks to Simon Kissel and Fikret Hasovic). + Version 4.13 (11 July 2005): + - Added the FastMM_DebugInfo.dll support library to display debug info for + stack traces. + - Stack traces for the memory leak report is now logged to the log file in + "FullDebugMode". + Version 4.14 (14 July 2005): + - Fixed string leaks not being detected as such in "FullDebugMode". (Thanks + to Leonel Togniolli.) + - Fixed the compilation error in "FullDebugMode" when "LogErrorsToFile" is + not set. (Thanks to Leonel Togniolli.) + - Added a "Release" option to allow the grouping of various options and to + make it easier to make debug and release builds. (Thanks to Alexander + Tabakov.) + - Added a "HideMemoryLeakHintMessage" option to not display the hint below + the memory leak message. (Thanks to Alexander Tabakov.) + - Changed the fill character for "FullDebugMode" from zero to $80 to be able + to differentiate between invalid memory accesses using nil pointers to + invalid memory accesses using fields of freed objects. FastMM tries to + reserve the 64K block starting at $80800000 at startup to ensure that an + A/V will occur when this block is accessed. (Thanks to Alexander Tabakov.) + - Fixed some compiler warnings. (Thanks to M. Skloff) + - Fixed some display bugs in the memory leak report. (Thanks to Leonel + Togniolli.) + - Added a "LogMemoryLeakDetailToFile" option. Some applications leak a lot of + memory and can make the log file grow very large very quickly. + - Added the option to use madExcept instead of the JCL Debug library in the + debug info support DLL. (Thanks to Martin Aignesberger.) + - Added procedures "GetMemoryManagerState" and "GetMemoryMap" to retrieve + statistics about the current state of the memory manager and memory pool. + (A usage tracker form together with a demo is also available.) + Version 4.15 (14 July 2005): + - Fixed a false 4GB(!) memory leak reported in some instances. + Version 4.16 (15 July 2005): + - Added the "CatchUseOfFreedInterfaces" option to catch the use of interfaces + of freed objects. This option is not compatible with checking that a freed + block has not been modified, so enable this option only when hunting an + invalid interface reference. (Only relevant if "FullDebugMode" is set.) + - During shutdown FastMM now checks that all free blocks have not been + modified since being freed. (Only when "FullDebugMode" is set and + "CatchUseOfFreedInterfaces" is disabled.) + Version 4.17 (15 July 2005): + - Added the AddExpectedMemoryLeaks and RemoveExpectedMemoryLeaks procedures to + register/unregister expected leaks, thus preventing the leak report from + displaying if only expected leaks occurred. (Thanks to Diederik and Dennis + Passmore for the suggestion.) (Note: these functions were renamed in later + versions.) + - Fixed the "LogMemoryLeakDetailToFile" not logging memory leak detail to file + as it is supposed to. (Thanks to Leonel Togniolli.) + Version 4.18 (18 July 2005): + - Fixed some issues when range checking or complete boolean evaluation is + switched on. (Thanks to Dario Tiraboschi and Mark Gebauer.) + - Added the "OutputInstallUninstallDebugString" option to display a message when + FastMM is installed or uninstalled. (Thanks to Hanspeter Widmer.) + - Moved the options to a separate include file. (Thanks to Hanspeter Widmer.) + - Moved message strings to a separate file for easy translation. + Version 4.19 (19 July 2005): + - Fixed Kylix support that was broken in 4.14. + Version 4.20 (20 July 2005): + - Fixed a false memory overwrite report at shutdown in "FullDebugMode". If you + consistently got a "Block Header Has Been Corrupted" error message during + shutdown at address $xxxx0070 then it was probably a false alarm. (Thanks to + Theo Carr-Brion and Hanspeter Widmer.} + Version 4.21 (27 July 2005): + - Minor change to the block header flags to make it possible to immediately + tell whether a medium block is being used as a small block pool or not. + (Simplifies the leak checking and status reporting code.) + - Expanded the functionality around the management of expected memory leaks. + - Added the "ClearLogFileOnStartup" option. Deletes the log file during + initialization. (Thanks to M. Skloff.) + - Changed "OutputInstallUninstallDebugString" to use OutputDebugString instead + of MessageBox. (Thanks to Hanspeter Widmer.) + Version 4.22 (1 August 2005): + - Added a FastAllocMem function that avoids an unnecessary FillChar call with + large blocks. + - Changed large block resizing behavior to be a bit more conservative. Large + blocks will be downsized if the new size is less than half of the old size + (the threshold was a quarter previously). + Version 4.23 (6 August 2005): + - Fixed BCB6 support (Thanks to Omar Zelaya). + - Renamed "OutputInstallUninstallDebugString" to "UseOutputDebugString", and + added debug string output on memory leak or error detection. + Version 4.24 (11 August 2005): + - Added the "NoMessageBoxes" option to suppress the display of message boxes, + which is useful for services that should not be interrupted. (Thanks to Dan + Miser). + - Changed the stack trace code to return the line number of the caller and not + the line number of the return address. (Thanks to Dan Miser). + Version 4.25 (15 August 2005): + - Fixed GetMemoryLeakType not detecting expected leaks registered by class + when in "FullDebugMode". (Thanks to Arjen de Ruijter). + Version 4.26 (18 August 2005): + - Added a "UseRuntimePackages" option that allows FastMM to be used in a main + application together with DLLs that all use runtime packages. (Thanks to + Aleksander Oven.) + Version 4.27 (24 August 2005): + - Fixed a bug that sometimes caused the leak report to be shown even though all + leaks were registered as expected leaks. (Thanks to Kristofer Skaug.) + Version 4.29 (30 September 2005): + - Added the "RequireDebuggerPresenceForLeakReporting" option to only display + the leak report if the application is run inside the IDE. (Thanks to Günther + Schoch.) + - Added the "ForceMMX" option, which when disabled will check the CPU for + MMX compatibility before using MMX. (Thanks to Jan Schlüter.) + - Added the module name to the title of error dialogs to more easily identify + which application caused the error. (Thanks to Kristofer Skaug.) + - Added an ASCII dump to the "FullDebugMode" memory dumps. (Thanks to Hallvard + Vassbotn.) + - Added the option "HideExpectedLeaksRegisteredByPointer" to suppress the + display and logging of expected memory leaks that were registered by pointer. + (Thanks to Dan Miser.) Leaks registered by size or class are often ambiguous, + so these expected leaks are always logged to file (in FullDebugMode) and are + never hidden from the leak display (only displayed if there is at least one + unexpected leak). + - Added a procedure "GetRegisteredMemoryLeaks" to return a list of all + registered memory leaks. (Thanks to Dan Miser.) + - Added the "RawStackTraces" option to perform "raw" stack traces, negating + the need for stack frames. This will usually result in more complete stack + traces in FullDebugMode error reports, but it is significantly slower. + (Thanks to Hallvard Vassbotn, Dan Miser and the JCL team.) + Version 4.31 (2 October 2005): + - Fixed the crash bug when both "RawStackTraces" and "FullDebugMode" were + enabled. (Thanks to Dan Miser and Mark Edington.) + Version 4.33 (6 October 2005): + - Added a header corruption check to all memory blocks that are identified as + leaks in FullDebugMode. This allows better differentiation between memory + pool corruption bugs and actual memory leaks. + - Fixed the stack overflow bug when using "RawStackTraces". + Version 4.35 (6 October 2005): + - Fixed a compilation error when the "NoMessageBoxes" option is set. (Thanks + to Paul Ishenin.) + - Before performing a "raw" stack trace, FastMM now checks whether exception + handling is in place. If exception handling is not in place FastMM falls + back to stack frame tracing. (Exception handling is required to handle the + possible A/Vs when reading invalid call addresses. Exception handling is + usually always available except when SysUtils hasn't been initialized yet or + after SysUtils has been finalized.) + Version 4.37 (8 October 2005): + - Fixed the missing call stack trace entry issue when dynamically loading DLLs. + (Thanks to Paul Ishenin.) + Version 4.39 (12 October 2005): + - Restored the performance with "RawStackTraces" enabled back to the level it + was in 4.35. + - Fixed the stack overflow error when using "RawStackTraces" that I thought I + had fixed in 4.31, but unfortunately didn't. (Thanks to Craig Peterson.) + Version 4.40 (13 October 2005): + - Improved "RawStackTraces" to have less incorrect extra entries. (Thanks to + Craig Peterson.) + - Added the Russian (by Paul Ishenin) and Afrikaans translations of + FastMM4Messages.pas. + Version 4.42 (13 October 2005): + - Fixed the compilation error when "CatchUseOfFreedInterfaces" is enabled. + (Thanks to Cristian Nicola.) + Version 4.44 (25 October 2005): + - Implemented a FastGetHeapStatus function in analogy with GetHeapStatus. + (Suggested by Cristian Nicola.) + - Shifted more of the stack trace code over to the support dll to allow third + party vendors to make available their own stack tracing and stack trace + logging facilities. + - Mathias Rauen (madshi) improved the support for madExcept in the debug info + support DLL. Thanks! + - Added support for BCB5. (Thanks to Roddy Pratt.) + - Added the Czech translation by Rene Mihula. + - Added the "DetectMMOperationsAfterUninstall" option. This will catch + attempts to use the MM after FastMM has been uninstalled, and is useful for + debugging. + Version 4.46 (26 October 2005): + - Renamed FastMM_DebugInfo.dll to FastMM_FullDebugMode.dll and made the + dependency on this library a static one. This solves a DLL unload order + problem when using FullDebugMode together with the replacement + borlndmm.dll. (Thanks to Bart van der Werf.) + - Added the Polish translation by Artur Redzko. + Version 4.48 (10 November 2005): + - Fixed class detection for objects leaked in dynamically loaded DLLs that + were relocated. + - Fabio Dell'Aria implemented support for EurekaLog in the FullDebugMode + support DLL. Thanks! + - Added the Spanish translation by JRG ("The Delphi Guy"). + Version 4.49 (10 November 2005): + - Implemented support for installing replacement AllocMem and leak + registration mechanisms for Delphi/BCB versions that support it. + - Added support for Delphi 4. (Thanks to Justus Janssen.) + Version 4.50 (5 December 2005): + - Renamed the ReportMemoryLeaks global variable to ReportMemoryLeaksOnShutdown + to be more consistent with the Delphi 2006 memory manager. + - Improved the handling of large blocks. Large blocks can now consist of + several consecutive segments allocated through VirtualAlloc. This + significantly improves speed when frequently resizing large blocks, since + these blocks can now often be upsized in-place. + Version 4.52 (7 December 2005): + - Fixed the compilation error with Delphi 5. (Thanks to Vadim Lopushansky and + Charles Vinal for reporting the error.) + Version 4.54 (15 December 2005): + - Added the Brazilian Portuguese translation by Johni Jeferson Capeletto. + - Fixed the compilation error with BCB6. (Thanks to Kurt Fitzner.) + Version 4.56 (20 December 2005): + - Fixed the Kylix compilation problem. (Thanks to Michal Niklas.) + Version 4.58 (1 February 2006): + - Added the German translations by Thomas Speck and Uwe Queisser. + - Added the Indonesian translation by Zaenal Mutaqin. + - Added the Portuguese translation by Carlos Macao. + Version 4.60 (21 February 2006): + - Fixed a performance issue due to an unnecessary block move operation when + allocating a block in the range 1261-1372 bytes and then reallocating it in + the range 1373-1429 bytes twice. (Thanks to Michael Winter.) + - Added the Belarussian translation by dzmitry[li]. + - Added the updated Spanish translation by Marcelo Montenegro. + - Added a new option "EnableSharingWithDefaultMM". This option allows FastMM + to be shared with the default MM of Delphi 2006. It is on by default, but + MM sharing has to be enabled otherwise it has no effect (refer to the + documentation for the "ShareMM" and "AttemptToUseSharedMM" options). + Version 4.62 (22 February 2006): + - Fixed a possible read access violation in the MoveX16LP routine when the + UseCustomVariableSizeMoveRoutines option is enabled. (Thanks to Jud Cole for + some great detective work in finding this bug.) + - Improved the downsizing behaviour of medium blocks to better correlate with + the reallocation behaviour of small blocks. This change reduces the number + of transitions between small and medium block types when reallocating blocks + in the 0.7K to 2.6K range. It cuts down on the number of memory move + operations and improves performance. + Version 4.64 (31 March 2006): + - Added the following functions for use with FullDebugMode (and added the + exports to the replacement BorlndMM.dll): SetMMLogFileName, + GetCurrentAllocationGroup, PushAllocationGroup, PopAllocationGroup and + LogAllocatedBlocksToFile. The purpose of these functions are to allow you to + identify and log related memory leaks while your application is still + running. + - Fixed a bug in the memory manager sharing mechanism affecting Windows + 95/98/ME. (Thanks to Zdenek Vasku.) + Version 4.66 (9 May 2006): + - Added a hint comment in this file so that FastMM4Messages.pas will also be + backed up by GExperts. (Thanks to RB Winston.) + - Fixed a bug affecting large address space (> 2GB) support under + FullDebugMode. (Thanks to Thomas Schulz.) + Version 4.68 (3 July 2006): + - Added the Italian translation by Luigi Sandon. + - If FastMM is used inside a DLL it will now use the name of the DLL as base + for the log file name. (Previously it always used the name of the main + application executable file.) + - Fixed a rare A/V when both the FullDebugMode and RawStackTraces options were + enabled. (Thanks to Primoz Gabrijelcic.) + - Added the "NeverSleepOnThreadContention" option. This option may improve + performance if the ratio of the the number of active threads to the number + of CPU cores is low (typically < 2). This option is only useful for 4+ CPU + systems, it almost always hurts performance on single and dual CPU systems. + (Thanks to Werner Bochtler and Markus Beth.) + Version 4.70 (4 August 2006): + - Added the Simplified Chinese translation by JiYuan Xie. + - Added the updated Russian as well as the Ukrainian translation by Andrey + Shtukaturov. + - Fixed two bugs in the leak class detection code that would sometimes fail + to detect the class of leaked objects and strings, and report them as + 'unknown'. (Thanks to Dimitry Timokhov) + Version 4.72 (24 September 2006): + - Fixed a bug that caused AllocMem to not clear blocks > 256K in + FullDebugMode. (Thanks to Paulo Moreno.) + Version 4.74 (9 November 2006): + - Fixed a bug in the segmented large block functionality that could lead to + an application freeze when upsizing blocks greater than 256K in a + multithreaded application (one of those "what the heck was I thinking?" + type bugs). + Version 4.76 (12 January 2007): + - Changed the RawStackTraces code in the FullDebugMode DLL + to prevent it from modifying the Windows "GetLastError" error code. + (Thanks to Primoz Gabrijelcic.) + - Fixed a threading issue when the "CheckHeapForCorruption" option was + enabled, but the "FullDebugMode" option was disabled. (Thanks to Primoz + Gabrijelcic.) + - Removed some unnecessary startup code when the MM sharing mechanism is + disabled. (Thanks to Vladimir Bochkarev.) + - In FullDebugMode leaked blocks would sometimes be reported as belonging to + the class "TFreedObject" if they were allocated but never used. Such blocks + will now be reported as "unknown". (Thanks to Francois Malan.) + - In recent versions the replacement borlndmm.dll created a log file (when + enabled) that used the "borlndmm" prefix instead of the application name. + It is now fixed to use the application name, however if FastMM is used + inside other DLLs the name of those DLLs will be used. (Thanks to Bart van + der Werf.) + - Added a "FastMMVersion" constant. (Suggested by Loris Luise.) + - Fixed an issue with error message boxes not displaying under certain + configurations. (Thanks to J.W. de Bokx.) + - FastMM will now display only one error message at a time. If many errors + occur in quick succession, only the first error will be shown (but all will + be logged). This avoids a stack overflow with badly misbehaved programs. + (Thanks to Bart van der Werf.) + - Added a LoadDebugDLLDynamically option to be used in conjunction with + FullDebugMode. In this mode FastMM_FullDebugMode.dll is loaded dynamically. + If the DLL cannot be found, stack traces will not be available. (Thanks to + Rene Mihula.) + Version 4.78 (1 March 2007): + - The MB_DEFAULT_DESKTOP_ONLY constant that is used when displaying messages + boxes since 4.76 is not defined under Kylix, and the source would thus not + compile. That constant is now defined. (Thanks to Werner Bochtler.) + - Moved the medium block locking code that was duplicated in several places + to a subroutine to reduce code size. (Thanks to Hallvard Vassbotn.) + - Fixed a bug in the leak registration code that sometimes caused registered + leaks to be reported erroneously. (Thanks to Primoz Gabrijelcic.) + - Added the NoDebugInfo option (on by default) that suppresses the generation + of debug info for the FastMM4.pas unit. This will prevent the integrated + debugger from stepping into the memory manager. (Thanks to Primoz + Gabrijelcic.) + - Increased the default stack trace depth in FullDebugMode from 9 to 10 to + ensure that the Align16Bytes setting works in FullDebugMode. (Thanks to + Igor Lindunen.) + - Updated the Czech translation. (Thanks to Rene Mihula.) + Version 4.84 (7 July 2008): + - Added the Romanian translation. (Thanks to Ionut Muntean.) + - Optimized the GetMemoryMap procedure to improve speed. + - Added the GetMemoryManagerUsageSummary function that returns a summary of + the GetMemoryManagerState call. (Thanks to Hallvard Vassbotn.) + - Added the French translation. (Thanks to Florent Ouchet.) + - Added the "AlwaysAllocateTopDown" FullDebugMode option to help with + catching bad pointer arithmetic code in an address space > 2GB. This option + is enabled by default. + - Added the "InstallOnlyIfRunningInIDE" option. Enable this option to + only install FastMM as the memory manager when the application is run + inside the Delphi IDE. This is useful when you want to deploy the same EXE + that you use for testing, but only want the debugging features active on + development machines. When this option is enabled and the application is + not being run inside the IDE, then the default Delphi memory manager will + be used (which, since Delphi 2006, is FastMM without FullDebugMode.) This + option is off by default. + - Added the "FullDebugModeInIDE" option. This is a convenient shorthand for + enabling FullDebugMode, InstallOnlyIfRunningInIDE and + LoadDebugDLLDynamically. This causes FastMM to be used in FullDebugMode + when the application is being debugged on development machines, and the + default memory manager when the same executable is deployed. This allows + the debugging and deployment of an application without having to compile + separate executables. This option is off by default. + - Added a ScanMemoryPoolForCorruptions procedure that checks the entire + memory pool for corruptions and raises an exception if one is found. It can + be called at any time, but is only available in FullDebugMode. (Thanks to + Marcus Mönnig.) + - Added a global variable "FullDebugModeScanMemoryPoolBeforeEveryOperation". + When this variable is set to true and FullDebugMode is enabled, then the + entire memory pool is checked for consistency before every GetMem, FreeMem + and ReallocMem operation. An "Out of Memory" error is raised if a + corruption is found (and this variable is set to false to prevent recursive + errors). This obviously incurs a massive performance hit, so enable it only + when hunting for elusive memory corruption bugs. (Thanks to Marcus Mönnig.) + - Fixed a bug in AllocMem that caused the FPU stack to be shifted by one + position. + - Changed the default for option "EnableMMX" to false, since using MMX may + cause unexpected behaviour in code that passes parameters on the FPU stack + (like some "compiler magic" routines, e.g. VarFromReal). + - Removed the "EnableSharingWithDefaultMM" option. This is now the default + behaviour and cannot be disabled. (FastMM will always try to share memory + managers between itself and the default memory manager when memory manager + sharing is enabled.) + - Introduced a new memory manager sharing mechanism based on memory mapped + files. This solves compatibility issues with console and service + applications. This sharing mechanism currently runs in parallel with the + old mechanism, but the old mechanism can be disabled by undefining + "EnableBackwardCompatibleMMSharing" in FastMM4Options.inc. + - Fixed the recursive call error when the EnableMemoryLeakReporting option + is disabled and an attempt is made to register a memory leak under Delphi + 2006 or later. (Thanks to Thomas Schulz.) + - Added a global variable "SuppressMessageBoxes" to enable or disable + messageboxes at runtime. (Thanks to Craig Peterson.) + - Added the leak reporting code for C++ Builder, as well as various other + C++ Builder bits written by JiYuan Xie. (Thank you!) + - Added the new Usage Tracker written by Hanspeter Widmer. (Thank you!) + Version 4.86 (31 July 2008): + - Tweaked the string detection algorithm somewhat to be less strict, and + allow non-class leaks to be more often categorized as strings. + - Fixed a compilation error under Delphi 5. + - Made LogAllocatedBlocksToFile and ScanMemoryPoolForCorruptions thread + safe. (Thanks to Francois Piette.) + Version 4.88 (13 August 2008): + - Fixed compiler warnings in NoOpRegisterExpectedMemoryLeak and + NoOpUnRegisterExpectedMemoryLeak. (Thanks to Michael Rabatscher.) + - Added the Simplified Chinese translation of FastMM4Options.inc by + QianYuan Wang. (Thank you!) + - Included the updated C++ Builder files with support for BCB6 without + update 4 applied. (Submitted by JiYuan Xie. Thanks!) + - Fixed a compilation error under Delphi 5. + - Made LogAllocatedBlocksToFile and ScanMemoryPoolForCorruptions thread + safe - for real this time. (Thanks to Francois Piette.) + Version 4.90 (9 September 2008): + - Added logging of the thread ID when capturing and displaying stack + traces. (Suggested by Allen Bauer and Mark Edington.) + - Fixed a Delphi 5 compiler error under FullDebugMode. (Thanks to Maurizio + Lotauro and Christian-W. Budde.) + - Changed a default setting in FastMM4Options.inc: RawStackTraces is now + off by default due to the high number of support requests I receive with + regards to the false postives it may cause. I recommend compiling debug + builds of applications with the "Stack Frames" option enabled. + - Fixed a compilation error under Kylix. (Thanks to Werner Bochtler.) + - Official support for Delphi 2009. + Version 4.92 (25 November 2008): + - Added the DisableLoggingOfMemoryDumps option under FullDebugMode. When + this option is set, memory dumps will not be logged for memory leaks or + errors. (Thanks to Patrick van Logchem.) + - Exposed the class and string type detection code in the interface section + for use in application code (if required). (Requested by Patrick van + Logchem.) + - Fixed a bug in SetMMLogFileName that could cause the log file name to be + set incorrectly. + - Added BCB4 support. (Thanks to Norbert Spiegel.) + - Included the updated Czech translation by Rene Mihula. + - When FastMM raises an error due to a freed block being modified, it now + logs detail about which bytes in the block were modified. + Version 4.94 (28 August 2009): + - Added the DoNotInstallIfDLLMissing option that prevents FastMM from + installing itself if the FastMM_FullDebugMode.dll library is not + available. (Only applicable when FullDebugMode and LoadDebugDLLDynamically + are both enabled.) This is useful when the same executable will be used for + both debugging and deployment - when the debug support DLL is available + FastMM will be installed in FullDebugMode, and otherwise the default memory + manager will be used. + - Added the FullDebugModeWhenDLLAvailable option that combines the + FullDebugMode, LoadDebugDLLDynamically and DoNotInstallIfDLLMissing options. + - Re-enabled RawStackTraces by default. The frame based stack traces (even + when compiling with stack frames enabled) are generally too incomplete. + - Improved the speed of large block operations under FullDebugMode: Since + large blocks are never reused, there is no point in clearing them before + and after use (so it does not do that anymore). + - If an error occurs in FullDebugMode and FastMM is unable to append to the + log file, it will attempt to write to a log file of the same name in the + "My Documents" folder. This feature is helpful when the executable resides + in a read-only location and the default log file, which is derived from the + executable name, would thus not be writeable. + - Added support for controlling the error log file location through an + environment variable. If the 'FastMMLogFilePath' environment variable is + set then any generated error logs will be written to the specified folder + instead of the default location (which is the same folder as the + application). + - Improved the call instruction detection code in the FastMM_FullDebugMode + library. (Thanks to the JCL team.) + - Improved the string leak detection and reporting code. (Thanks to Uwe + Schuster.) + - New FullDebugMode feature: Whenever FreeMem or ReallocMem is called, FastMM + will check that the block was actually allocated through the same FastMM + instance. This is useful for tracking down memory manager sharing issues. + - Compatible with Delphi 2010. + Version 4.96 (31 August 2010): + - Reduced the minimum block size to 4 bytes from the previous value of 12 + bytes (only applicable to 8 byte alignment). This reduces memory usage if + the application allocates many blocks <= 4 bytes in size. + - Added colour-coded change indication to the FastMM usage tracker, making + it easier to spot changes in the memory usage grid. (Thanks to Murray + McGowan.) + - Added the SuppressFreeMemErrorsInsideException FullDebugMode option: If + FastMM encounters a problem with a memory block inside the FullDebugMode + FreeMem handler then an "invalid pointer operation" exception will usually + be raised. If the FreeMem occurs while another exception is being handled + (perhaps in the try.. finally code) then the original exception will be + lost. With this option set FastMM will ignore errors inside FreeMem when an + exception is being handled, thus allowing the original exception to + propagate. This option is on by default. (Thanks to Michael Hieke.) + - Fixed Windows 95 FullDebugMode support that was broken in 4.94. (Thanks to + Richard Bradbrook.) + - Fixed a bug affecting GetMemoryMap performance and accuracy of measurements + above 2GB if a large address space is not enabled for the project. (Thanks + to Michael Hieke.) + - Added the FullDebugModeRegisterAllAllocsAsExpectedMemoryLeak boolean flag. + When set, all allocations are automatically registered as expected memory + leaks. Only available in FullDebugMode. (Thanks to Brian Cook.) + - Compatible with Delphi XE. + Version 4.97 (30 September 2010): + - Fixed a crash bug (that crept in in 4.96) that may manifest itself when + resizing a block to 4 bytes or less. + - Added the UseSwitchToThread option. Set this option to call SwitchToThread + instead of sitting in a "busy waiting" loop when a thread contention + occurs. This is used in conjunction with the NeverSleepOnThreadContention + option, and has no effect unless NeverSleepOnThreadContention is also + defined. This option may improve performance with many CPU cores and/or + threads of different priorities. Note that the SwitchToThread API call is + only available on Windows 2000 and later. (Thanks to Zach Saw.) + Version 4.98 (23 September 2011): + - Added the FullDebugModeCallBacks define which adds support for memory + manager event callbacks. This allows the application to be notified of + memory allocations, frees and reallocations as they occur. (Thanks to + Jeroen Pluimers.) + - Added security options ClearMemoryBeforeReturningToOS and + AlwaysClearFreedMemory to force the clearing of memory blocks after being + freed. This could possibly provide some protection against information + theft, but at a significant performance penalty. (Thanks to Andrey + Sozonov.) + - Shifted the code in the initialization section to a procedure + RunInitializationCode. This allows the startup code to be called before + InitUnits, which is required by some software protection tools. + - Added support for Delphi XE2 (Windows 32-bit and Windows 64-bit platforms + only). + Version 4.99 (6 November 2011): + - Fixed crashes in the 64-bit BASM codepath when more than 4GB of memory is + allocated. + - Fixed bad record alignment under 64-bit that affected performance. + - Fixed compilation errors with some older compilers. + +*) + +unit FastMM4; + +interface + +{$Include FastMM4Options.inc} + +{$RANGECHECKS OFF} +{$BOOLEVAL OFF} +{$OVERFLOWCHECKS OFF} +{$OPTIMIZATION ON} +{$TYPEDADDRESS OFF} +{$LONGSTRINGS ON} + +{Compiler version defines} +{$ifndef BCB} + {$ifdef ver120} + {$define Delphi4or5} + {$endif} + {$ifdef ver130} + {$define Delphi4or5} + {$endif} + {$ifdef ver140} + {$define Delphi6} + {$endif} + {$ifdef ver150} + {$define Delphi7} + {$endif} + {$ifdef ver170} + {$define Delphi2005} + {$endif} +{$else} + {for BCB4, use the Delphi 5 codepath} + {$ifdef ver120} + {$define Delphi4or5} + {$define BCB4} + {$endif} + {for BCB5, use the Delphi 5 codepath} + {$ifdef ver130} + {$define Delphi4or5} + {$endif} +{$endif} +{$ifdef ver180} + {$define BDS2006} +{$endif} +{$define 32Bit} +{$ifndef Delphi4or5} + {$if SizeOf(Pointer) = 8} + {$define 64Bit} + {$undef 32Bit} + {$ifend} + {$if CompilerVersion >= 23} + {$define XE2AndUp} + {$ifend} + {$define BCB6OrDelphi6AndUp} + {$ifndef BCB} + {$define Delphi6AndUp} + {$endif} + {$ifndef Delphi6} + {$define BCB6OrDelphi7AndUp} + {$ifndef BCB} + {$define Delphi7AndUp} + {$endif} + {$ifndef BCB} + {$ifndef Delphi7} + {$ifndef Delphi2005} + {$define BDS2006AndUp} + {$endif} + {$endif} + {$endif} + {$endif} +{$endif} + +{$ifdef 64Bit} + {Under 64 bit memory blocks must always be 16-byte aligned} + {$define Align16Bytes} + {No need for MMX under 64-bit, since SSE2 is available} + {$undef EnableMMX} + {There is little need for raw stack traces under 64-bit, since frame based + stack traces are much more accurate than under 32-bit. (And frame based + stack tracing is much faster.)} + {$undef RawStackTraces} +{$endif} + +{IDE debug mode always enables FullDebugMode and dynamic loading of the FullDebugMode DLL.} +{$ifdef FullDebugModeInIDE} + {$define InstallOnlyIfRunningInIDE} + {$define FullDebugMode} + {$define LoadDebugDLLDynamically} +{$endif} + +{Install in FullDebugMode only when the DLL is available?} +{$ifdef FullDebugModeWhenDLLAvailable} + {$define FullDebugMode} + {$define LoadDebugDLLDynamically} + {$define DoNotInstallIfDLLMissing} +{$endif} + +{Some features not currently supported under Kylix} +{$ifdef Linux} + {$undef FullDebugMode} + {$undef LogErrorsToFile} + {$undef LogMemoryLeakDetailToFile} + {$undef ShareMM} + {$undef AttemptToUseSharedMM} + {$undef RequireIDEPresenceForLeakReporting} + {$undef UseOutputDebugString} + {$ifdef PIC} + {BASM version does not support position independent code} + {$undef ASMVersion} + {$endif} +{$endif} + +{Do we require debug info for leak checking?} +{$ifdef RequireDebugInfoForLeakReporting} + {$ifopt D-} + {$undef EnableMemoryLeakReporting} + {$endif} +{$endif} + +{Enable heap checking and leak reporting in full debug mode} +{$ifdef FullDebugMode} + {$STACKFRAMES ON} + {$define CheckHeapForCorruption} + {$ifndef CatchUseOfFreedInterfaces} + {$define CheckUseOfFreedBlocksOnShutdown} + {$endif} +{$else} + {Error logging requires FullDebugMode} + {$undef LogErrorsToFile} + {$undef CatchUseOfFreedInterfaces} + {$undef RawStackTraces} + {$undef AlwaysAllocateTopDown} +{$endif} + +{Set defines for security options} +{$ifdef FullDebugMode} + {In FullDebugMode small and medium blocks are always cleared when calling + FreeMem. Large blocks are always returned to the OS immediately.} + {$ifdef ClearMemoryBeforeReturningToOS} + {$define ClearLargeBlocksBeforeReturningToOS} + {$endif} + {$ifdef AlwaysClearFreedMemory} + {$define ClearLargeBlocksBeforeReturningToOS} + {$endif} +{$else} + {If memory blocks are cleared in FreeMem then they do not need to be cleared + before returning the memory to the OS.} + {$ifdef AlwaysClearFreedMemory} + {$define ClearSmallAndMediumBlocksInFreeMem} + {$define ClearLargeBlocksBeforeReturningToOS} + {$else} + {$ifdef ClearMemoryBeforeReturningToOS} + {$define ClearMediumBlockPoolsBeforeReturningToOS} + {$define ClearLargeBlocksBeforeReturningToOS} + {$endif} + {$endif} +{$endif} + +{Only the Pascal version supports extended heap corruption checking.} +{$ifdef CheckHeapForCorruption} + {$undef ASMVersion} +{$endif} + +{For BASM bits that are not implemented in 64-bit.} +{$ifdef 32Bit} + {$ifdef ASMVersion} + {$define Use32BitAsm} + {$endif} +{$endif} + +{$ifdef UseRuntimePackages} + {$define AssumeMultiThreaded} +{$endif} + +{$ifdef BCB6OrDelphi6AndUp} + {$WARN SYMBOL_PLATFORM OFF} + {$WARN SYMBOL_DEPRECATED OFF} +{$endif} + +{Leak detail logging requires error logging} +{$ifndef LogErrorsToFile} + {$undef LogMemoryLeakDetailToFile} + {$undef ClearLogFileOnStartup} +{$endif} + +{$ifndef EnableMemoryLeakReporting} + {Manual leak reporting control requires leak reporting to be enabled} + {$undef ManualLeakReportingControl} +{$endif} + +{$ifndef EnableMMX} + {$undef ForceMMX} +{$endif} + +{Are any of the MM sharing options enabled?} +{$ifdef ShareMM} + {$define MMSharingEnabled} +{$endif} +{$ifdef AttemptToUseSharedMM} + {$define MMSharingEnabled} +{$endif} + +{Instruct GExperts to back up the messages file as well.} +{#BACKUP FastMM4Messages.pas} + +{Should debug info be disabled?} +{$ifdef NoDebugInfo} + {$DEBUGINFO OFF} +{$endif} + +{$ifdef BCB} + {$ifdef borlndmmdll} + {$OBJEXPORTALL OFF} + {$endif} + {$ifndef PatchBCBTerminate} + {Cannot uninstall safely under BCB} + {$define NeverUninstall} + {Disable memory leak reporting} + {$undef EnableMemoryLeakReporting} + {$endif} +{$endif} + +{-------------------------Public constants-----------------------------} +const + {The current version of FastMM} + FastMMVersion = '4.99'; + {The number of small block types} +{$ifdef Align16Bytes} + NumSmallBlockTypes = 46; +{$else} + NumSmallBlockTypes = 56; +{$endif} + +{----------------------------Public types------------------------------} +type + + {Make sure all the required types are available} +{$ifdef BCB6OrDelphi6AndUp} + {$if CompilerVersion < 20} + PByte = PAnsiChar; + {$ifend} + {$if CompilerVersion < 23} + NativeInt = Integer; + NativeUInt = Cardinal; + PNativeUInt = ^Cardinal; + IntPtr = Integer; + UIntPtr = Cardinal; + {$ifend} +{$else} + PByte = PAnsiChar; + NativeInt = Integer; + NativeUInt = Cardinal; + PNativeUInt = ^Cardinal; + IntPtr = Integer; + UIntPtr = Cardinal; +{$endif} + + TSmallBlockTypeState = record + {The internal size of the block type} + InternalBlockSize: Cardinal; + {Useable block size: The number of non-reserved bytes inside the block.} + UseableBlockSize: Cardinal; + {The number of allocated blocks} + AllocatedBlockCount: NativeUInt; + {The total address space reserved for this block type (both allocated and + free blocks)} + ReservedAddressSpace: NativeUInt; + end; + TSmallBlockTypeStates = array[0..NumSmallBlockTypes - 1] of TSmallBlockTypeState; + + TMemoryManagerState = record + {Small block type states} + SmallBlockTypeStates: TSmallBlockTypeStates; + {Medium block stats} + AllocatedMediumBlockCount: Cardinal; + TotalAllocatedMediumBlockSize: NativeUInt; + ReservedMediumBlockAddressSpace: NativeUInt; + {Large block stats} + AllocatedLargeBlockCount: Cardinal; + TotalAllocatedLargeBlockSize: NativeUInt; + ReservedLargeBlockAddressSpace: NativeUInt; + end; + + TMemoryManagerUsageSummary = record + {The total number of bytes allocated by the application.} + AllocatedBytes: NativeUInt; + {The total number of address space bytes used by control structures, or + lost due to fragmentation and other overhead.} + OverheadBytes: NativeUInt; + {The efficiency of the memory manager expressed as a percentage. This is + 100 * AllocatedBytes / (AllocatedBytes + OverheadBytes).} + EfficiencyPercentage: Double; + end; + + {Memory map} + TChunkStatus = (csUnallocated, csAllocated, csReserved, csSysAllocated, + csSysReserved); + TMemoryMap = array[0..65535] of TChunkStatus; + +{$ifdef EnableMemoryLeakReporting} + {List of registered leaks} + TRegisteredMemoryLeak = record + LeakAddress: Pointer; + LeakedClass: TClass; + {$ifdef CheckCppObjectTypeEnabled} + LeakedCppTypeIdPtr: Pointer; + {$endif} + LeakSize: NativeInt; + LeakCount: Integer; + end; + TRegisteredMemoryLeaks = array of TRegisteredMemoryLeak; +{$endif} + + {Used by the DetectStringData routine to detect whether a leaked block + contains string data.} + TStringDataType = (stUnknown, stAnsiString, stUnicodeString); + +{--------------------------Public variables----------------------------} +var + {If this variable is set to true and FullDebugMode is enabled, then the + entire memory pool is checked for consistency before every memory + operation. Note that this incurs a massive performance hit on top of + the already significant FullDebugMode overhead, so enable this option + only when absolutely necessary.} + FullDebugModeScanMemoryPoolBeforeEveryOperation: Boolean = False; + FullDebugModeRegisterAllAllocsAsExpectedMemoryLeak: Boolean = False; +{$ifdef ManualLeakReportingControl} + {Variable is declared in system.pas in newer Delphi versions.} + {$ifndef BDS2006AndUp} + ReportMemoryLeaksOnShutdown: Boolean; + {$endif} +{$endif} + {If set to True, disables the display of all messageboxes} + SuppressMessageBoxes: Boolean; + +{-------------------------Public procedures----------------------------} +{Executes the code normally run in the initialization section. Running it + earlier may be required with e.g. some software protection tools.} +procedure RunInitializationCode; +{Installation procedures must be exposed for the BCB helper unit FastMM4BCB.cpp} +{$ifdef BCB} +procedure InitializeMemoryManager; +function CheckCanInstallMemoryManager: Boolean; +procedure InstallMemoryManager; + +{$ifdef FullDebugMode} +(*$HPPEMIT '#define FullDebugMode' *) + +{$ifdef ClearLogFileOnStartup} +(*$HPPEMIT ' #define ClearLogFileOnStartup' *) +procedure DeleteEventLog; +{$endif} + +{$ifdef LoadDebugDLLDynamically} +(*$HPPEMIT ' #define LoadDebugDLLDynamically' *) +{$endif} + +{$ifdef RawStackTraces} +(*$HPPEMIT ' #define RawStackTraces' *) +{$endif} + +{$endif} + +{$ifdef PatchBCBTerminate} +(*$HPPEMIT ''#13#10 *) +(*$HPPEMIT '#define PatchBCBTerminate' *) + +{$ifdef EnableMemoryLeakReporting} +(*$HPPEMIT ''#13#10 *) +(*$HPPEMIT '#define EnableMemoryLeakReporting' *) +{$endif} + +{$ifdef DetectMMOperationsAfterUninstall} +(*$HPPEMIT ''#13#10 *) +(*$HPPEMIT '#define DetectMMOperationsAfterUninstall' *) +{$endif} + +{Called in FastMM4BCB.cpp, should contain codes of original "finalization" section} +procedure FinalizeMemoryManager; + +{For completion of "RequireDebuggerPresenceForLeakReporting" checking in "FinalizeMemoryManager"} +var + pCppDebugHook: ^Integer = nil; //PInteger not defined in BCB5 + +{$ifdef CheckCppObjectTypeEnabled} +(*$HPPEMIT ''#13#10 *) +(*$HPPEMIT '#define CheckCppObjectTypeEnabled' *) + +type + TGetCppVirtObjSizeByTypeIdPtrFunc = function(APointer: Pointer): Cardinal; + TGetCppVirtObjTypeIdPtrFunc = function(APointer: Pointer; ASize: Cardinal): Pointer; + TGetCppVirtObjTypeNameFunc = function(APointer: Pointer; ASize: Cardinal): PAnsiChar; + TGetCppVirtObjTypeNameByTypeIdPtrFunc = function (APointer: Pointer): PAnsiChar; + TGetCppVirtObjTypeNameByVTablePtrFunc = function(AVTablePtr: Pointer; AVTablePtrOffset: Cardinal): PAnsiChar; +var + {Return virtual object's size from typeId pointer} + GetCppVirtObjSizeByTypeIdPtrFunc: TGetCppVirtObjSizeByTypeIdPtrFunc = nil; + {Retrieve virtual object's typeId pointer} + GetCppVirtObjTypeIdPtrFunc: TGetCppVirtObjTypeIdPtrFunc = nil; + {Retrieve virtual object's type name} + GetCppVirtObjTypeNameFunc: TGetCppVirtObjTypeNameFunc = nil; + {Return virtual object's type name from typeId pointer} + GetCppVirtObjTypeNameByTypeIdPtrFunc: TGetCppVirtObjTypeNameByTypeIdPtrFunc = nil; + {Retrieve virtual object's typeId pointer from it's virtual table pointer} + GetCppVirtObjTypeNameByVTablePtrFunc: TGetCppVirtObjTypeNameByVTablePtrFunc = nil; +{$endif} +{$endif} +{$endif} + +{$ifndef FullDebugMode} +{The standard memory manager functions} +function FastGetMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +function FastFreeMem(APointer: Pointer): Integer; +function FastReallocMem(APointer: Pointer; ANewSize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +function FastAllocMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Cardinal{$endif}): Pointer; +{$else} +{The FullDebugMode memory manager functions} +function DebugGetMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +function DebugFreeMem(APointer: Pointer): Integer; +function DebugReallocMem(APointer: Pointer; ANewSize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +function DebugAllocMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Cardinal{$endif}): Pointer; +{Scans the memory pool for any corruptions. If a corruption is encountered an "Out of Memory" exception is + raised.} +procedure ScanMemoryPoolForCorruptions; +{Specify the full path and name for the filename to be used for logging memory + errors, etc. If ALogFileName is nil or points to an empty string it will + revert to the default log file name.} +procedure SetMMLogFileName(ALogFileName: PAnsiChar = nil); +{Returns the current "allocation group". Whenever a GetMem request is serviced + in FullDebugMode, the current "allocation group" is stored in the block header. + This may help with debugging. Note that if a block is subsequently reallocated + that it keeps its original "allocation group" and "allocation number" (all + allocations are also numbered sequentially).} +function GetCurrentAllocationGroup: Cardinal; +{Allocation groups work in a stack like fashion. Group numbers are pushed onto + and popped off the stack. Note that the stack size is limited, so every push + should have a matching pop.} +procedure PushAllocationGroup(ANewCurrentAllocationGroup: Cardinal); +procedure PopAllocationGroup; +{Logs detail about currently allocated memory blocks for the specified range of + allocation groups. if ALastAllocationGroupToLog is less than + AFirstAllocationGroupToLog or it is zero, then all allocation groups are + logged. This routine also checks the memory pool for consistency at the same + time, raising an "Out of Memory" error if the check fails.} +procedure LogAllocatedBlocksToFile(AFirstAllocationGroupToLog, ALastAllocationGroupToLog: Cardinal); +{$endif} + +{Releases all allocated memory (use with extreme care)} +procedure FreeAllMemory; + +{Returns summarised information about the state of the memory manager. (For + backward compatibility.)} +function FastGetHeapStatus: THeapStatus; +{Returns statistics about the current state of the memory manager} +procedure GetMemoryManagerState(var AMemoryManagerState: TMemoryManagerState); +{Returns a summary of the information returned by GetMemoryManagerState} +procedure GetMemoryManagerUsageSummary( + var AMemoryManagerUsageSummary: TMemoryManagerUsageSummary); +{$ifndef Linux} +{Gets the state of every 64K block in the 4GB address space} +procedure GetMemoryMap(var AMemoryMap: TMemoryMap); +{$endif} + +{$ifdef EnableMemoryLeakReporting} +{Registers expected memory leaks. Returns true on success. The list of leaked + blocks is limited, so failure is possible if the list is full.} +function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; overload; +function RegisterExpectedMemoryLeak(ALeakedObjectClass: TClass; ACount: Integer = 1): Boolean; overload; +function RegisterExpectedMemoryLeak(ALeakedBlockSize: NativeInt; ACount: Integer = 1): Boolean; overload; +{$ifdef CheckCppObjectTypeEnabled} +{Registers expected memory leaks by virtual object's typeId pointer. + Usage: RegisterExpectedMemoryLeak(typeid(ACppObject).tpp, Count);} +function RegisterExpectedMemoryLeak(ALeakedCppVirtObjTypeIdPtr: Pointer; ACount: Integer): boolean; overload; +{$endif} +{Removes expected memory leaks. Returns true on success.} +function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; overload; +function UnregisterExpectedMemoryLeak(ALeakedObjectClass: TClass; ACount: Integer = 1): Boolean; overload; +function UnregisterExpectedMemoryLeak(ALeakedBlockSize: NativeInt; ACount: Integer = 1): Boolean; overload; +{$ifdef CheckCppObjectTypeEnabled} +{Usage: UnregisterExpectedMemoryLeak(typeid(ACppObject).tpp, Count);} +function UnregisterExpectedMemoryLeak(ALeakedCppVirtObjTypeIdPtr: Pointer; ACount: Integer): boolean; overload; +{$endif} +{Returns a list of all expected memory leaks} +function GetRegisteredMemoryLeaks: TRegisteredMemoryLeaks; +{$endif} + +{Returns the class for a memory block. Returns nil if it is not a valid class. + Used by the leak detection code.} +function DetectClassInstance(APointer: Pointer): TClass; +{Detects the probable string data type for a memory block. Used by the leak + classification code when a block cannot be identified as a known class + instance.} +function DetectStringData(APMemoryBlock: Pointer; + AAvailableSpaceInBlock: NativeInt): TStringDataType; + +{$ifdef FullDebugMode} +{-------------FullDebugMode constants---------------} +const + {The stack trace depth. (Must be an *uneven* number to ensure that the + Align16Bytes option works in FullDebugMode.)} + StackTraceDepth = 11; + {The number of entries in the allocation group stack} + AllocationGroupStackSize = 1000; + {The number of fake VMT entries - used to track virtual method calls on + freed objects. Do not change this value without also updating TFreedObject.GetVirtualMethodIndex} + MaxFakeVMTEntries = 200; + {The pattern used to fill unused memory} + DebugFillByte = $80; +{$ifdef 32Bit} + DebugFillPattern = $01010101 * Cardinal(DebugFillByte); + {The address that is reserved so that accesses to the address of the fill + pattern will result in an A/V. (Not used under 64-bit, since the upper half + of the address space is always reserved by the OS.)} + DebugReservedAddress = $01010000 * Cardinal(DebugFillByte); +{$else} + DebugFillPattern = $8080808080808080; +{$endif} + +{-------------------------FullDebugMode structures--------------------} +type + PStackTrace = ^TStackTrace; + TStackTrace = array[0..StackTraceDepth - 1] of NativeUInt; + + TBlockOperation = (boBlockCheck, boGetMem, boFreeMem, boReallocMem); + + {The header placed in front of blocks in FullDebugMode (just after the + standard header). Must be a multiple of 16 bytes in size otherwise the + Align16Bytes option will not work. Current size = 128 bytes under 32-bit, + and 240 bytes under 64-bit.} + PFullDebugBlockHeader = ^TFullDebugBlockHeader; + TFullDebugBlockHeader = record + {Space used by the medium block manager for previous/next block management. + If a medium block is binned then these two fields will be modified.} + Reserved1: Pointer; + Reserved2: Pointer; + {Is the block currently allocated? If it is allocated this will be the + address of the getmem routine through which it was allocated, otherwise it + will be nil.} + AllocatedByRoutine: Pointer; + {The allocation group: Can be used in the debugging process to group + related memory leaks together} + AllocationGroup: Cardinal; + {The allocation number: All new allocations are numbered sequentially. This + number may be useful in memory leak analysis. If it reaches 4G it wraps + back to 0.} + AllocationNumber: Cardinal; + {The call stack when the block was allocated} + AllocationStackTrace: TStackTrace; + {The thread that allocated the block} + AllocatedByThread: Cardinal; + {The thread that freed the block} + FreedByThread: Cardinal; + {The call stack when the block was freed} + FreeStackTrace: TStackTrace; + {The user requested size for the block. 0 if this is the first time the + block is used.} + UserSize: NativeUInt; + {The object class this block was used for the previous time it was + allocated. When a block is freed, the pointer that would normally be in the + space of the class pointer is copied here, so if it is detected that + the block was used after being freed we have an idea what class it is.} + PreviouslyUsedByClass: NativeUInt; + {The sum of all the dwords(32-bit)/qwords(64-bit) in this structure + excluding the initial two reserved fields and this field.} + HeaderCheckSum: NativeUInt; + end; + {The NativeUInt following the user area of the block is the inverse of + HeaderCheckSum. This is used to catch buffer overrun errors.} + + {The class used to catch attempts to execute a virtual method of a freed + object} + TFreedObject = class + public + procedure GetVirtualMethodIndex; + procedure VirtualMethodError; +{$ifdef CatchUseOfFreedInterfaces} + procedure InterfaceError; +{$endif} + end; + +{$ifdef FullDebugModeCallBacks} + {FullDebugMode memory manager event callbacks. Note that APHeaderFreedBlock in the TOnDebugFreeMemFinish + will not be valid for large (>260K) blocks.} + TOnDebugGetMemFinish = procedure(APHeaderNewBlock: PFullDebugBlockHeader; ASize: NativeInt); + TOnDebugFreeMemStart = procedure(APHeaderBlockToFree: PFullDebugBlockHeader); + TOnDebugFreeMemFinish = procedure(APHeaderFreedBlock: PFullDebugBlockHeader; AResult: Integer); + TOnDebugReallocMemStart = procedure(APHeaderBlockToReallocate: PFullDebugBlockHeader; ANewSize: NativeInt); + TOnDebugReallocMemFinish = procedure(APHeaderReallocatedBlock: PFullDebugBlockHeader; ANewSize: NativeInt); + +var + {Note: FastMM will not catch exceptions inside these hooks, so make sure your hook code runs without + exceptions.} + OnDebugGetMemFinish: TOnDebugGetMemFinish = nil; + OnDebugFreeMemStart: TOnDebugFreeMemStart = nil; + OnDebugFreeMemFinish: TOnDebugFreeMemFinish = nil; + OnDebugReallocMemStart: TOnDebugReallocMemStart = nil; + OnDebugReallocMemFinish: TOnDebugReallocMemFinish = nil; +{$endif} +{$endif} + +implementation + +uses +{$ifndef Linux} + Windows, + {$ifdef FullDebugMode} + {$ifdef Delphi4or5} + ShlObj, + {$else} + SHFolder, + {$endif} + {$endif} +{$else} + Libc, +{$endif} + FastMM4Messages; + +{Fixed size move procedures. The 64-bit versions assume 16-byte alignment.} +procedure Move4(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move12(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move20(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move28(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move36(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move44(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move52(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move60(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move68(const ASource; var ADest; ACount: NativeInt); forward; +{$ifdef 64Bit} +{These are not needed and thus unimplemented under 32-bit} +procedure Move8(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move24(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move40(const ASource; var ADest; ACount: NativeInt); forward; +procedure Move56(const ASource; var ADest; ACount: NativeInt); forward; +{$endif} + +{$ifdef DetectMMOperationsAfterUninstall} +{Invalid handlers to catch MM operations after uninstall} +function InvalidFreeMem(APointer: Pointer): Integer; forward; +function InvalidGetMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; forward; +function InvalidReallocMem(APointer: Pointer; ANewSize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; forward; +function InvalidAllocMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Cardinal{$endif}): Pointer; forward; +function InvalidRegisterAndUnRegisterMemoryLeak(APointer: Pointer): Boolean; forward; +{$endif} + +{-------------------------Private constants----------------------------} +const + {The size of a medium block pool. This is allocated through VirtualAlloc and + is used to serve medium blocks. The size must be a multiple of 16 and at + least 4 bytes less than a multiple of 4K (the page size) to prevent a + possible read access violation when reading past the end of a memory block + in the optimized move routine (MoveX16LP). In Full Debug mode we leave a + trailing 256 bytes to be able to safely do a memory dump.} + MediumBlockPoolSize = 20 * 64 * 1024{$ifndef FullDebugMode} - 16{$else} - 256{$endif}; + {The granularity of small blocks} +{$ifdef Align16Bytes} + SmallBlockGranularity = 16; +{$else} + SmallBlockGranularity = 8; +{$endif} + {The granularity of medium blocks. Newly allocated medium blocks are + a multiple of this size plus MediumBlockSizeOffset, to avoid cache line + conflicts} + MediumBlockGranularity = 256; + MediumBlockSizeOffset = 48; + {The granularity of large blocks} + LargeBlockGranularity = 65536; + {The maximum size of a small block. Blocks Larger than this are either + medium or large blocks.} + MaximumSmallBlockSize = 2608; + {The smallest medium block size. (Medium blocks are rounded up to the nearest + multiple of MediumBlockGranularity plus MediumBlockSizeOffset)} + MinimumMediumBlockSize = 11 * 256 + MediumBlockSizeOffset; + {The number of bins reserved for medium blocks} + MediumBlockBinsPerGroup = 32; + MediumBlockBinGroupCount = 32; + MediumBlockBinCount = MediumBlockBinGroupCount * MediumBlockBinsPerGroup; + {The maximum size allocatable through medium blocks. Blocks larger than this + fall through to VirtualAlloc ( = large blocks).} + MaximumMediumBlockSize = MinimumMediumBlockSize + (MediumBlockBinCount - 1) * MediumBlockGranularity; + {The target number of small blocks per pool. The actual number of blocks per + pool may be much greater for very small sizes and less for larger sizes. The + cost of allocating the small block pool is amortized across all the small + blocks in the pool, however the blocks may not all end up being used so they + may be lying idle.} + TargetSmallBlocksPerPool = 48; + {The minimum number of small blocks per pool. Any available medium block must + have space for roughly this many small blocks (or more) to be useable as a + small block pool.} + MinimumSmallBlocksPerPool = 12; + {The lower and upper limits for the optimal small block pool size} + OptimalSmallBlockPoolSizeLowerLimit = 29 * 1024 - MediumBlockGranularity + MediumBlockSizeOffset; + OptimalSmallBlockPoolSizeUpperLimit = 64 * 1024 - MediumBlockGranularity + MediumBlockSizeOffset; + {The maximum small block pool size. If a free block is this size or larger + then it will be split.} + MaximumSmallBlockPoolSize = OptimalSmallBlockPoolSizeUpperLimit + MinimumMediumBlockSize; + {-------------Block type flags--------------} + {The lower 3 bits in the dword header of small blocks (4 bits in medium and + large blocks) are used as flags to indicate the state of the block} + {Set if the block is not in use} + IsFreeBlockFlag = 1; + {Set if this is a medium block} + IsMediumBlockFlag = 2; + {Set if it is a medium block being used as a small block pool. Only valid if + IsMediumBlockFlag is set.} + IsSmallBlockPoolInUseFlag = 4; + {Set if it is a large block. Only valid if IsMediumBlockFlag is not set.} + IsLargeBlockFlag = 4; + {Is the medium block preceding this block available? (Only used by medium + blocks)} + PreviousMediumBlockIsFreeFlag = 8; + {Is this large block segmented? I.e. is it actually built up from more than + one chunk allocated through VirtualAlloc? (Only used by large blocks.)} + LargeBlockIsSegmented = 8; + {The flags masks for small blocks} + DropSmallFlagsMask = -8; + ExtractSmallFlagsMask = 7; + {The flags masks for medium and large blocks} + DropMediumAndLargeFlagsMask = -16; + ExtractMediumAndLargeFlagsMask = 15; + {-------------Block resizing constants---------------} + SmallBlockDownsizeCheckAdder = 64; + SmallBlockUpsizeAdder = 32; + {When a medium block is reallocated to a size smaller than this, then it must + be reallocated to a small block and the data moved. If not, then it is + shrunk in place down to MinimumMediumBlockSize. Currently the limit is set + at a quarter of the minimum medium block size.} + MediumInPlaceDownsizeLimit = MinimumMediumBlockSize div 4; + {-------------Memory leak reporting constants---------------} + ExpectedMemoryLeaksListSize = 64 * 1024; + {-------------Other constants---------------} +{$ifndef NeverSleepOnThreadContention} + {Sleep time when a resource (small/medium/large block manager) is in use} + InitialSleepTime = 0; + {Used when the resource is still in use after the first sleep} + AdditionalSleepTime = 1; +{$endif} + {Hexadecimal characters} + HexTable: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + {Copyright message - not used anywhere in the code} + Copyright: AnsiString = 'FastMM4 (c) 2004 - 2011 Pierre le Riche / Professional Software Development'; +{$ifdef FullDebugMode} + {Virtual Method Called On Freed Object Errors} + StandardVirtualMethodNames: array[1 + vmtParent div SizeOf(Pointer) .. -1] of PAnsiChar = ( +{$ifdef BCB6OrDelphi6AndUp} + {$if RTLVersion >= 20} + 'Equals', + 'GetHashCode', + 'ToString', + {$ifend} +{$endif} + 'SafeCallException', + 'AfterConstruction', + 'BeforeDestruction', + 'Dispatch', + 'DefaultHandler', + 'NewInstance', + 'FreeInstance', + 'Destroy'); + {The name of the FullDebugMode support DLL. The support DLL implements stack + tracing and the conversion of addresses to unit and line number information.} +{$ifdef 32Bit} + FullDebugModeLibraryName = FullDebugModeLibraryName32Bit; +{$else} + FullDebugModeLibraryName = FullDebugModeLibraryName64Bit; +{$endif} +{$endif} + +{-------------------------Private types----------------------------} +type + +{$ifdef Delphi4or5} + {Delphi 5 Compatibility} + PCardinal = ^Cardinal; + PPointer = ^Pointer; +{$endif} +{$ifdef BCB4} + {Define some additional types for BCB4} + PInteger = ^Integer; +{$endif} + + {Move procedure type} + TMoveProc = procedure(const ASource; var ADest; ACount: NativeInt); + + {Registers structure (for GetCPUID)} + TRegisters = record + RegEAX, RegEBX, RegECX, RegEDX: Integer; + end; + + {The layout of a string allocation. Used to detect string leaks.} + PStrRec = ^StrRec; + StrRec = packed record +{$ifdef 64Bit} + _Padding: Integer; +{$endif} +{$ifdef BCB6OrDelphi6AndUp} + {$if RTLVersion >= 20} + codePage: Word; + elemSize: Word; + {$ifend} +{$endif} + refCnt: Integer; + length: Integer; + end; + +{$ifdef EnableMemoryLeakReporting} + {Different kinds of memory leaks} + TMemoryLeakType = (mltUnexpectedLeak, mltExpectedLeakRegisteredByPointer, + mltExpectedLeakRegisteredByClass, mltExpectedLeakRegisteredBySize); +{$endif} + + {---------------Small block structures-------------} + + {Pointer to the header of a small block pool} + PSmallBlockPoolHeader = ^TSmallBlockPoolHeader; + + {Small block type (Size = 32 bytes for 32-bit, 64 bytes for 64-bit).} + PSmallBlockType = ^TSmallBlockType; + TSmallBlockType = record + {True = Block type is locked} + BlockTypeLocked: Boolean; + {Bitmap indicating which of the first 8 medium block groups contain blocks + of a suitable size for a block pool.} + AllowedGroupsForBlockPoolBitmap: Byte; + {The block size for this block type} + BlockSize: Word; + {The minimum and optimal size of a small block pool for this block type} + MinimumBlockPoolSize: Word; + OptimalBlockPoolSize: Word; + {The first partially free pool for the given small block. This field must + be at the same offset as TSmallBlockPoolHeader.NextPartiallyFreePool.} + NextPartiallyFreePool: PSmallBlockPoolHeader; + {The last partially free pool for the small block type. This field must + be at the same offset as TSmallBlockPoolHeader.PreviousPartiallyFreePool.} + PreviousPartiallyFreePool: PSmallBlockPoolHeader; + {The offset of the last block that was served sequentially. The field must + be at the same offset as TSmallBlockPoolHeader.FirstFreeBlock.} + NextSequentialFeedBlockAddress: Pointer; + {The last block that can be served sequentially.} + MaxSequentialFeedBlockAddress: Pointer; + {The pool that is current being used to serve blocks in sequential order} + CurrentSequentialFeedPool: PSmallBlockPoolHeader; +{$ifdef UseCustomFixedSizeMoveRoutines} + {The fixed size move procedure used to move data for this block size when + it is upsized. When a block is downsized (which usually does not occur + that often) the variable size move routine is used.} + UpsizeMoveProcedure: TMoveProc; +{$else} + Reserved1: Pointer; +{$endif} +{$ifdef 64Bit} + {Pad to 64 bytes for 64-bit} + Reserved2: Pointer; +{$endif} + end; + + {Small block pool (Size = 32 bytes for 32-bit, 48 bytes for 64-bit).} + TSmallBlockPoolHeader = record + {BlockType} + BlockType: PSmallBlockType; +{$ifdef 32Bit} + {Align the next fields to the same fields in TSmallBlockType and pad this + structure to 32 bytes for 32-bit} + Reserved1: Cardinal; +{$endif} + {The next and previous pool that has free blocks of this size. Do not + change the position of these two fields: They must be at the same offsets + as the fields in TSmallBlockType of the same name.} + NextPartiallyFreePool: PSmallBlockPoolHeader; + PreviousPartiallyFreePool: PSmallBlockPoolHeader; + {Pointer to the first free block inside this pool. This field must be at + the same offset as TSmallBlockType.NextSequentialFeedBlockAddress.} + FirstFreeBlock: Pointer; + {The number of blocks allocated in this pool.} + BlocksInUse: Cardinal; + {Padding} + Reserved2: Cardinal; + {The pool pointer and flags of the first block} + FirstBlockPoolPointerAndFlags: NativeUInt; + end; + + {Small block layout: + At offset -SizeOf(Pointer) = Flags + address of the small block pool. + At offset BlockSize - SizeOf(Pointer) = Flags + address of the small block + pool for the next small block. + } + + {------------------------Medium block structures------------------------} + + {The medium block pool from which medium blocks are drawn. Size = 16 bytes + for 32-bit and 32 bytes for 64-bit.} + PMediumBlockPoolHeader = ^TMediumBlockPoolHeader; + TMediumBlockPoolHeader = record + {Points to the previous and next medium block pools. This circular linked + list is used to track memory leaks on program shutdown.} + PreviousMediumBlockPoolHeader: PMediumBlockPoolHeader; + NextMediumBlockPoolHeader: PMediumBlockPoolHeader; + {Padding} + Reserved1: NativeUInt; + {The block size and flags of the first medium block in the block pool} + FirstMediumBlockSizeAndFlags: NativeUInt; + end; + + {Medium block layout: + Offset: -2 * SizeOf(Pointer) = Previous Block Size (only if the previous block is free) + Offset: -SizeOf(Pointer) = This block size and flags + Offset: 0 = User data / Previous Free Block (if this block is free) + Offset: SizeOf(Pointer) = Next Free Block (if this block is free) + Offset: BlockSize - 2*SizeOf(Pointer) = Size of this block (if this block is free) + Offset: BlockSize - SizeOf(Pointer) = Size of the next block and flags + + {A medium block that is unused} + PMediumFreeBlock = ^TMediumFreeBlock; + TMediumFreeBlock = record + PreviousFreeBlock: PMediumFreeBlock; + NextFreeBlock: PMediumFreeBlock; + end; + + {-------------------------Large block structures------------------------} + + {Large block header record (Size = 16 for 32-bit, 32 for 64-bit)} + PLargeBlockHeader = ^TLargeBlockHeader; + TLargeBlockHeader = record + {Points to the previous and next large blocks. This circular linked + list is used to track memory leaks on program shutdown.} + PreviousLargeBlockHeader: PLargeBlockHeader; + NextLargeBlockHeader: PLargeBlockHeader; + {The user allocated size of the Large block} + UserAllocatedSize: NativeUInt; + {The size of this block plus the flags} + BlockSizeAndFlags: NativeUInt; + end; + + {-------------------------Expected Memory Leak Structures--------------------} +{$ifdef EnableMemoryLeakReporting} + + {The layout of an expected leak. All fields may not be specified, in which + case it may be harder to determine which leaks are expected and which are + not.} + PExpectedMemoryLeak = ^TExpectedMemoryLeak; + PPExpectedMemoryLeak = ^PExpectedMemoryLeak; + TExpectedMemoryLeak = record + {Linked list pointers} + PreviousLeak, NextLeak: PExpectedMemoryLeak; + {Information about the expected leak} + LeakAddress: Pointer; + LeakedClass: TClass; + {$ifdef CheckCppObjectTypeEnabled} + LeakedCppTypeIdPtr: Pointer; + {$endif} + LeakSize: NativeInt; + LeakCount: Integer; + end; + + TExpectedMemoryLeaks = record + {The number of entries used in the expected leaks buffer} + EntriesUsed: Integer; + {Freed entries} + FirstFreeSlot: PExpectedMemoryLeak; + {Entries with the address specified} + FirstEntryByAddress: PExpectedMemoryLeak; + {Entries with no address specified, but with the class specified} + FirstEntryByClass: PExpectedMemoryLeak; + {Entries with only size specified} + FirstEntryBySizeOnly: PExpectedMemoryLeak; + {The expected leaks buffer (Need to leave space for this header)} + ExpectedLeaks: array[0..(ExpectedMemoryLeaksListSize - 64) div SizeOf(TExpectedMemoryLeak) - 1] of TExpectedMemoryLeak; + end; + PExpectedMemoryLeaks = ^TExpectedMemoryLeaks; + +{$endif} + +{-------------------------Private constants----------------------------} +const +{$ifndef BCB6OrDelphi7AndUp} + reOutOfMemory = 1; + reInvalidPtr = 2; +{$endif} + {The size of the block header in front of small and medium blocks} + BlockHeaderSize = SizeOf(Pointer); + {The size of a small block pool header} + SmallBlockPoolHeaderSize = SizeOf(TSmallBlockPoolHeader); + {The size of a medium block pool header} + MediumBlockPoolHeaderSize = SizeOf(TMediumBlockPoolHeader); + {The size of the header in front of Large blocks} + LargeBlockHeaderSize = SizeOf(TLargeBlockHeader); +{$ifdef FullDebugMode} + {We need space for the header, the trailer checksum and the trailing block + size (only used by freed medium blocks).} + FullDebugBlockOverhead = SizeOf(TFullDebugBlockHeader) + SizeOf(NativeUInt) + SizeOf(Pointer); +{$endif} + +{-------------------------Private variables----------------------------} +var + {-----------------Small block management------------------} + {The small block types. Sizes include the leading header. Sizes are + picked to limit maximum wastage to about 10% or 256 bytes (whichever is + less) where possible.} + SmallBlockTypes: array[0..NumSmallBlockTypes - 1] of TSmallBlockType =( + {8/16 byte jumps} +{$ifndef Align16Bytes} + (BlockSize: 8 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: Move4{$endif}), +{$endif} + (BlockSize: 16 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: {$ifdef 32Bit}Move12{$else}Move8{$endif}{$endif}), +{$ifndef Align16Bytes} + (BlockSize: 24 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: Move20{$endif}), +{$endif} + (BlockSize: 32 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: {$ifdef 32Bit}Move28{$else}Move24{$endif}{$endif}), +{$ifndef Align16Bytes} + (BlockSize: 40 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: Move36{$endif}), +{$endif} + (BlockSize: 48 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: {$ifdef 32Bit}Move44{$else}Move40{$endif}{$endif}), +{$ifndef Align16Bytes} + (BlockSize: 56 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: Move52{$endif}), +{$endif} + (BlockSize: 64 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: {$ifdef 32Bit}Move60{$else}Move56{$endif}{$endif}), +{$ifndef Align16Bytes} + (BlockSize: 72 {$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: Move68{$endif}), +{$endif} + (BlockSize: 80), +{$ifndef Align16Bytes} + (BlockSize: 88), +{$endif} + (BlockSize: 96), +{$ifndef Align16Bytes} + (BlockSize: 104), +{$endif} + (BlockSize: 112), +{$ifndef Align16Bytes} + (BlockSize: 120), +{$endif} + (BlockSize: 128), +{$ifndef Align16Bytes} + (BlockSize: 136), +{$endif} + (BlockSize: 144), +{$ifndef Align16Bytes} + (BlockSize: 152), +{$endif} + (BlockSize: 160), + {16 byte jumps} + (BlockSize: 176), + (BlockSize: 192), + (BlockSize: 208), + (BlockSize: 224), + (BlockSize: 240), + (BlockSize: 256), + (BlockSize: 272), + (BlockSize: 288), + (BlockSize: 304), + (BlockSize: 320), + {32 byte jumps} + (BlockSize: 352), + (BlockSize: 384), + (BlockSize: 416), + (BlockSize: 448), + (BlockSize: 480), + {48 byte jumps} + (BlockSize: 528), + (BlockSize: 576), + (BlockSize: 624), + (BlockSize: 672), + {64 byte jumps} + (BlockSize: 736), + (BlockSize: 800), + {80 byte jumps} + (BlockSize: 880), + (BlockSize: 960), + {96 byte jumps} + (BlockSize: 1056), + (BlockSize: 1152), + {112 byte jumps} + (BlockSize: 1264), + (BlockSize: 1376), + {128 byte jumps} + (BlockSize: 1504), + {144 byte jumps} + (BlockSize: 1648), + {160 byte jumps} + (BlockSize: 1808), + {176 byte jumps} + (BlockSize: 1984), + {192 byte jumps} + (BlockSize: 2176), + {208 byte jumps} + (BlockSize: 2384), + {224 byte jumps} + (BlockSize: MaximumSmallBlockSize), + {The last block size occurs three times. If, during a GetMem call, the + requested block size is already locked by another thread then up to two + larger block sizes may be used instead. Having the last block size occur + three times avoids the need to have a size overflow check.} + (BlockSize: MaximumSmallBlockSize), + (BlockSize: MaximumSmallBlockSize)); + {Size to small block type translation table} + AllocSize2SmallBlockTypeIndX4: array[0..(MaximumSmallBlockSize - 1) div SmallBlockGranularity] of Byte; + {-----------------Medium block management------------------} + {A dummy medium block pool header: Maintains a circular list of all medium + block pools to enable memory leak detection on program shutdown.} + MediumBlockPoolsCircularList: TMediumBlockPoolHeader; + {Are medium blocks locked?} + MediumBlocksLocked: Boolean; + {The sequential feed medium block pool.} + LastSequentiallyFedMediumBlock: Pointer; + MediumSequentialFeedBytesLeft: Cardinal; + {The medium block bins are divided into groups of 32 bins. If a bit + is set in this group bitmap, then at least one bin in the group has free + blocks.} + MediumBlockBinGroupBitmap: Cardinal; + {The medium block bins: total of 32 * 32 = 1024 bins of a certain + minimum size.} + MediumBlockBinBitmaps: array[0..MediumBlockBinGroupCount - 1] of Cardinal; + {The medium block bins. There are 1024 LIFO circular linked lists each + holding blocks of a specified minimum size. The sizes vary in size from + MinimumMediumBlockSize to MaximumMediumBlockSize. The bins are treated as + type TMediumFreeBlock to avoid pointer checks.} + MediumBlockBins: array[0..MediumBlockBinCount - 1] of TMediumFreeBlock; + {-----------------Large block management------------------} + {Are large blocks locked?} + LargeBlocksLocked: Boolean; + {A dummy large block header: Maintains a list of all allocated large blocks + to enable memory leak detection on program shutdown.} + LargeBlocksCircularList: TLargeBlockHeader; + {-------------------------Expected Memory Leak Structures--------------------} +{$ifdef EnableMemoryLeakReporting} + {The expected memory leaks} + ExpectedMemoryLeaks: PExpectedMemoryLeaks; + ExpectedMemoryLeaksListLocked: Boolean; +{$endif} + {---------------------Full Debug Mode structures--------------------} +{$ifdef FullDebugMode} + {The allocation group stack} + AllocationGroupStack: array[0..AllocationGroupStackSize - 1] of Cardinal; + {The allocation group stack top (it is an index into AllocationGroupStack)} + AllocationGroupStackTop: Cardinal; + {The last allocation number used} + CurrentAllocationNumber: Cardinal; + {This is a count of the number of threads currently inside any of the + FullDebugMode GetMem, Freemem or ReallocMem handlers. If this value + is negative then a block scan is in progress and no thread may + allocate, free or reallocate any block or modify any FullDebugMode + block header or footer.} + ThreadsInFullDebugModeRoutine: Integer; + {The current log file name} + MMLogFileName: array[0..1023] of AnsiChar; + {The 64K block of reserved memory used to trap invalid memory accesses using + fields in a freed object.} + ReservedBlock: Pointer; + {The virtual method index count - used to get the virtual method index for a + virtual method call on a freed object.} + VMIndex: Integer; + {The fake VMT used to catch virtual method calls on freed objects.} + FreedObjectVMT: packed record + VMTData: array[vmtSelfPtr .. vmtParent + SizeOf(Pointer) - 1] of byte; + VMTMethods: array[SizeOf(Pointer) + vmtParent .. vmtParent + MaxFakeVMTEntries * SizeOf(Pointer) + SizeOf(Pointer) - 1] of Byte; + end; + {$ifdef CatchUseOfFreedInterfaces} + VMTBadInterface: array[0..MaxFakeVMTEntries - 1] of Pointer; + {$endif} +{$endif} + {--------------Other info--------------} + {The memory manager that was replaced} + OldMemoryManager: {$ifndef BDS2006AndUp}TMemoryManager{$else}TMemoryManagerEx{$endif}; + {The replacement memory manager} + NewMemoryManager: {$ifndef BDS2006AndUp}TMemoryManager{$else}TMemoryManagerEx{$endif}; +{$ifdef DetectMMOperationsAfterUninstall} + {Invalid handlers to catch MM operations after uninstall} + InvalidMemoryManager: {$ifndef BDS2006AndUp}TMemoryManager{$else}TMemoryManagerEx{$endif} = ( + GetMem: InvalidGetMem; + FreeMem: InvalidFreeMem; + ReallocMem: InvalidReallocMem + {$ifdef BDS2006AndUp}; + AllocMem: InvalidAllocMem; + RegisterExpectedMemoryLeak: InvalidRegisterAndUnRegisterMemoryLeak; + UnRegisterExpectedMemoryLeak: InvalidRegisterAndUnRegisterMemoryLeak; + {$endif} + ); +{$endif} + +{$ifdef MMSharingEnabled} + {A string uniquely identifying the current process (for sharing the memory + manager between DLLs and the main application)} + MappingObjectName: array[0..25] of AnsiChar = ('L', 'o', 'c', 'a', 'l', '\', + 'F', 'a', 's', 't', 'M', 'M', '_', 'P', 'I', 'D', '_', '?', '?', '?', '?', + '?', '?', '?', '?', #0); +{$ifdef EnableBackwardCompatibleMMSharing} + UniqueProcessIDString: array[1..20] of AnsiChar = ('?', '?', '?', '?', '?', + '?', '?', '?', '_', 'P', 'I', 'D', '_', 'F', 'a', 's', 't', 'M', 'M', #0); + UniqueProcessIDStringBE: array[1..23] of AnsiChar = ('?', '?', '?', '?', '?', + '?', '?', '?', '_', 'P', 'I', 'D', '_', 'F', 'a', 's', 't', 'M', 'M', '_', + 'B', 'E', #0); + {The handle of the MM window} + MMWindow: HWND; + {The handle of the MM window (for default MM of Delphi 2006 compatibility)} + MMWindowBE: HWND; +{$endif} + {The handle of the memory mapped file} + MappingObjectHandle: NativeUInt; +{$endif} + {Has FastMM been installed?} + FastMMIsInstalled: Boolean; + {Is the MM in place a shared memory manager?} + IsMemoryManagerOwner: Boolean; + {Must MMX be used for move operations?} +{$ifdef EnableMMX} + {$ifndef ForceMMX} + UseMMX: Boolean; + {$endif} +{$endif} + {Is a MessageBox currently showing? If so, do not show another one.} + ShowingMessageBox: Boolean; + {True if RunInitializationCode has been called already.} + InitializationCodeHasRun: Boolean = False; + +{----------------Utility Functions------------------} + +{A copy of StrLen in order to avoid the SysUtils unit, which would have + introduced overhead like exception handling code.} +function StrLen(const AStr: PAnsiChar): NativeUInt; +{$ifndef Use32BitAsm} +begin + Result := 0; + while AStr[Result] <> #0 do + Inc(Result); +end; +{$else} +asm + {Check the first byte} + cmp byte ptr [eax], 0 + je @ZeroLength + {Get the negative of the string start in edx} + mov edx, eax + neg edx + {Word align} + add eax, 1 + and eax, -2 +@ScanLoop: + mov cx, [eax] + add eax, 2 + test cl, ch + jnz @ScanLoop + test cl, cl + jz @ReturnLess2 + test ch, ch + jnz @ScanLoop + lea eax, [eax + edx - 1] + ret +@ReturnLess2: + lea eax, [eax + edx - 2] + ret +@ZeroLength: + xor eax, eax +end; +{$endif} + +{$ifdef EnableMMX} +{$ifndef ForceMMX} +{Returns true if the CPUID instruction is supported} +function CPUID_Supported: Boolean; +asm + pushfd + pop eax + mov edx, eax + xor eax, $200000 + push eax + popfd + pushfd + pop eax + xor eax, edx + setnz al +end; + +{Gets the CPUID} +function GetCPUID(AInfoRequired: Integer): TRegisters; +asm + push ebx + push esi + mov esi, edx + {cpuid instruction} +{$ifdef Delphi4or5} + db $0f, $a2 +{$else} + cpuid +{$endif} + {Save registers} + mov TRegisters[esi].RegEAX, eax + mov TRegisters[esi].RegEBX, ebx + mov TRegisters[esi].RegECX, ecx + mov TRegisters[esi].RegEDX, edx + pop esi + pop ebx +end; + +{Returns true if the CPU supports MMX} +function MMX_Supported: Boolean; +var + LReg: TRegisters; +begin + if CPUID_Supported then + begin + {Get the CPUID} + LReg := GetCPUID(1); + {Bit 23 must be set for MMX support} + Result := LReg.RegEDX and $800000 <> 0; + end + else + Result := False; +end; +{$endif} +{$endif} + +{Compare [AAddress], CompareVal: + If Equal: [AAddress] := NewVal and result = CompareVal + If Unequal: Result := [AAddress]} +function LockCmpxchg(CompareVal, NewVal: Byte; AAddress: PByte): Byte; +asm +{$ifdef 32Bit} + {On entry: + al = CompareVal, + dl = NewVal, + ecx = AAddress} + {$ifndef Linux} + lock cmpxchg [ecx], dl + {$else} + {Workaround for Kylix compiler bug} + db $F0, $0F, $B0, $11 + {$endif} +{$else} + {On entry: + cl = CompareVal + dl = NewVal + r8 = AAddress} + .noframe + mov rax, rcx + lock cmpxchg [r8], dl +{$endif} +end; + +{$ifndef ASMVersion} +{Gets the first set bit in the 32-bit number, returning the bit index} +function FindFirstSetBit(ACardinal: Cardinal): Cardinal; +asm +{$ifdef 64Bit} + .noframe + mov rax, rcx +{$endif} + bsf eax, eax +end; +{$endif} + +{Writes the module filename to the specified buffer and returns the number of + characters written.} +function AppendModuleFileName(ABuffer: PAnsiChar): Integer; +var + LModuleHandle: HModule; +begin + {Get the module handle} +{$ifndef borlndmmdll} + if IsLibrary then + LModuleHandle := HInstance + else +{$endif} + LModuleHandle := 0; + {Get the module name} +{$ifndef Linux} + Result := GetModuleFileNameA(LModuleHandle, ABuffer, 512); +{$else} + Result := GetModuleFileName(LModuleHandle, ABuffer, 512); +{$endif} +end; + +{Copies the name of the module followed by the given string to the buffer, + returning the pointer following the buffer.} +function AppendStringToModuleName(AString, ABuffer: PAnsiChar): PAnsiChar; +var + LModuleNameLength: Cardinal; + LCopyStart: PAnsiChar; +begin + {Get the name of the application} + LModuleNameLength := AppendModuleFileName(ABuffer); + {Replace the last few characters} + if LModuleNameLength > 0 then + begin + {Find the last backslash} + LCopyStart := PAnsiChar(PByte(ABuffer) + LModuleNameLength - 1); + LModuleNameLength := 0; + while (UIntPtr(LCopyStart) >= UIntPtr(ABuffer)) + and (LCopyStart^ <> '\') do + begin + Inc(LModuleNameLength); + Dec(LCopyStart); + end; + {Copy the name to the start of the buffer} + Inc(LCopyStart); + System.Move(LCopyStart^, ABuffer^, LModuleNameLength); + Inc(ABuffer, LModuleNameLength); + ABuffer^ := ':'; + Inc(ABuffer); + ABuffer^ := ' '; + Inc(ABuffer); + end; + {Append the string} + while AString^ <> #0 do + begin + ABuffer^ := AString^; + Inc(ABuffer); + {Next char} + Inc(AString); + end; + ABuffer^ := #0; + Result := ABuffer; +end; + +{----------------Faster Move Procedures-------------------} + +{Fixed size move operations ignore the size parameter. All moves are assumed to + be non-overlapping.} + +procedure Move4(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + mov eax, [eax] + mov [edx], eax +{$else} +.noframe + mov eax, [rcx] + mov [rdx], eax +{$endif} +end; + +{$ifdef 64Bit} +procedure Move8(const ASource; var ADest; ACount: NativeInt); +asm + mov rax, [rcx] + mov [rdx], rax +end; +{$endif} + +procedure Move12(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + mov ecx, [eax] + mov [edx], ecx + mov ecx, [eax + 4] + mov eax, [eax + 8] + mov [edx + 4], ecx + mov [edx + 8], eax +{$else} +.noframe + mov rax, [rcx] + mov ecx, [rcx + 8] + mov [rdx], rax + mov [rdx + 8], ecx +{$endif} +end; + +procedure Move20(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + mov ecx, [eax] + mov [edx], ecx + mov ecx, [eax + 4] + mov [edx + 4], ecx + mov ecx, [eax + 8] + mov [edx + 8], ecx + mov ecx, [eax + 12] + mov eax, [eax + 16] + mov [edx + 12], ecx + mov [edx + 16], eax +{$else} +.noframe + movdqa xmm0, [rcx] + mov ecx, [rcx + 16] + movdqa [rdx], xmm0 + mov [rdx + 16], ecx +{$endif} +end; + +{$ifdef 64Bit} +procedure Move24(const ASource; var ADest; ACount: NativeInt); +asm + movdqa xmm0, [rcx] + mov r8, [rcx + 16] + movdqa [rdx], xmm0 + mov [rdx + 16], r8 +end; +{$endif} + +procedure Move28(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + mov ecx, [eax] + mov [edx], ecx + mov ecx, [eax + 4] + mov [edx + 4], ecx + mov ecx, [eax + 8] + mov [edx + 8], ecx + mov ecx, [eax + 12] + mov [edx + 12], ecx + mov ecx, [eax + 16] + mov [edx + 16], ecx + mov ecx, [eax + 20] + mov eax, [eax + 24] + mov [edx + 20], ecx + mov [edx + 24], eax +{$else} +.noframe + movdqa xmm0, [rcx] + mov r8, [rcx + 16] + mov ecx, [rcx + 24] + movdqa [rdx], xmm0 + mov [rdx + 16], r8 + mov [rdx + 24], ecx +{$endif} +end; + +procedure Move36(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + fild qword ptr [eax] + fild qword ptr [eax + 8] + fild qword ptr [eax + 16] + fild qword ptr [eax + 24] + mov ecx, [eax + 32] + mov [edx + 32], ecx + fistp qword ptr [edx + 24] + fistp qword ptr [edx + 16] + fistp qword ptr [edx + 8] + fistp qword ptr [edx] +{$else} +.noframe + movdqa xmm0, [rcx] + movdqa xmm1, [rcx + 16] + mov ecx, [rcx + 32] + movdqa [rdx], xmm0 + movdqa [rdx + 16], xmm1 + mov [rdx + 32], ecx +{$endif} +end; + +{$ifdef 64Bit} +procedure Move40(const ASource; var ADest; ACount: NativeInt); +asm + movdqa xmm0, [rcx] + movdqa xmm1, [rcx + 16] + mov r8, [rcx + 32] + movdqa [rdx], xmm0 + movdqa [rdx + 16], xmm1 + mov [rdx + 32], r8 +end; +{$endif} + +procedure Move44(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + fild qword ptr [eax] + fild qword ptr [eax + 8] + fild qword ptr [eax + 16] + fild qword ptr [eax + 24] + fild qword ptr [eax + 32] + mov ecx, [eax + 40] + mov [edx + 40], ecx + fistp qword ptr [edx + 32] + fistp qword ptr [edx + 24] + fistp qword ptr [edx + 16] + fistp qword ptr [edx + 8] + fistp qword ptr [edx] +{$else} +.noframe + movdqa xmm0, [rcx] + movdqa xmm1, [rcx + 16] + mov r8, [rcx + 32] + mov ecx, [rcx + 40] + movdqa [rdx], xmm0 + movdqa [rdx + 16], xmm1 + mov [rdx + 32], r8 + mov [rdx + 40], ecx +{$endif} +end; + +procedure Move52(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + fild qword ptr [eax] + fild qword ptr [eax + 8] + fild qword ptr [eax + 16] + fild qword ptr [eax + 24] + fild qword ptr [eax + 32] + fild qword ptr [eax + 40] + mov ecx, [eax + 48] + mov [edx + 48], ecx + fistp qword ptr [edx + 40] + fistp qword ptr [edx + 32] + fistp qword ptr [edx + 24] + fistp qword ptr [edx + 16] + fistp qword ptr [edx + 8] + fistp qword ptr [edx] +{$else} +.noframe + movdqa xmm0, [rcx] + movdqa xmm1, [rcx + 16] + movdqa xmm2, [rcx + 32] + mov ecx, [rcx + 48] + movdqa [rdx], xmm0 + movdqa [rdx + 16], xmm1 + movdqa [rdx + 32], xmm2 + mov [rdx + 48], ecx +{$endif} +end; + +{$ifdef 64Bit} +procedure Move56(const ASource; var ADest; ACount: NativeInt); +asm + movdqa xmm0, [rcx] + movdqa xmm1, [rcx + 16] + movdqa xmm2, [rcx + 32] + mov r8, [rcx + 48] + movdqa [rdx], xmm0 + movdqa [rdx + 16], xmm1 + movdqa [rdx + 32], xmm2 + mov [rdx + 48], r8 +end; +{$endif} + +procedure Move60(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + fild qword ptr [eax] + fild qword ptr [eax + 8] + fild qword ptr [eax + 16] + fild qword ptr [eax + 24] + fild qword ptr [eax + 32] + fild qword ptr [eax + 40] + fild qword ptr [eax + 48] + mov ecx, [eax + 56] + mov [edx + 56], ecx + fistp qword ptr [edx + 48] + fistp qword ptr [edx + 40] + fistp qword ptr [edx + 32] + fistp qword ptr [edx + 24] + fistp qword ptr [edx + 16] + fistp qword ptr [edx + 8] + fistp qword ptr [edx] +{$else} +.noframe + movdqa xmm0, [rcx] + movdqa xmm1, [rcx + 16] + movdqa xmm2, [rcx + 32] + mov r8, [rcx + 48] + mov ecx, [rcx + 56] + movdqa [rdx], xmm0 + movdqa [rdx + 16], xmm1 + movdqa [rdx + 32], xmm2 + mov [rdx + 48], r8 + mov [rdx + 56], ecx +{$endif} +end; + +procedure Move68(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + fild qword ptr [eax] + fild qword ptr [eax + 8] + fild qword ptr [eax + 16] + fild qword ptr [eax + 24] + fild qword ptr [eax + 32] + fild qword ptr [eax + 40] + fild qword ptr [eax + 48] + fild qword ptr [eax + 56] + mov ecx, [eax + 64] + mov [edx + 64], ecx + fistp qword ptr [edx + 56] + fistp qword ptr [edx + 48] + fistp qword ptr [edx + 40] + fistp qword ptr [edx + 32] + fistp qword ptr [edx + 24] + fistp qword ptr [edx + 16] + fistp qword ptr [edx + 8] + fistp qword ptr [edx] +{$else} +.noframe + movdqa xmm0, [rcx] + movdqa xmm1, [rcx + 16] + movdqa xmm2, [rcx + 32] + movdqa xmm3, [rcx + 48] + mov ecx, [rcx + 64] + movdqa [rdx], xmm0 + movdqa [rdx + 16], xmm1 + movdqa [rdx + 32], xmm2 + movdqa [rdx + 48], xmm3 + mov [rdx + 64], ecx +{$endif} +end; + +{Variable size move procedure: Rounds ACount up to the next multiple of 16 less + SizeOf(Pointer). Important note: Always moves at least 16 - SizeOf(Pointer) + bytes (the minimum small block size with 16 byte alignment), irrespective of + ACount.} +procedure MoveX16LP(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + {Make the counter negative based: The last 12 bytes are moved separately} + sub ecx, 12 + add eax, ecx + add edx, ecx +{$ifdef EnableMMX} + {$ifndef ForceMMX} + cmp UseMMX, True + jne @FPUMove + {$endif} + {Make the counter negative based: The last 12 bytes are moved separately} + neg ecx + jns @MMXMoveLast12 +@MMXMoveLoop: + {Move a 16 byte block} + {$ifdef Delphi4or5} + {Delphi 5 compatibility} + db $0f, $6f, $04, $01 + db $0f, $6f, $4c, $01, $08 + db $0f, $7f, $04, $11 + db $0f, $7f, $4c, $11, $08 + {$else} + movq mm0, [eax + ecx] + movq mm1, [eax + ecx + 8] + movq [edx + ecx], mm0 + movq [edx + ecx + 8], mm1 + {$endif} + {Are there another 16 bytes to move?} + add ecx, 16 + js @MMXMoveLoop +@MMXMoveLast12: + {Do the last 12 bytes} + {$ifdef Delphi4or5} + {Delphi 5 compatibility} + db $0f, $6f, $04, $01 + {$else} + movq mm0, [eax + ecx] + {$endif} + mov eax, [eax + ecx + 8] + {$ifdef Delphi4or5} + {Delphi 5 compatibility} + db $0f, $7f, $04, $11 + {$else} + movq [edx + ecx], mm0 + {$endif} + mov [edx + ecx + 8], eax + {Exit MMX state} + {$ifdef Delphi4or5} + {Delphi 5 compatibility} + db $0f, $77 + {$else} + emms + {$endif} + {$ifndef ForceMMX} + ret + {$endif} +{$endif} +{FPU code is only used if MMX is not forced} +{$ifndef ForceMMX} +@FPUMove: + neg ecx + jns @FPUMoveLast12 +@FPUMoveLoop: + {Move a 16 byte block} + fild qword ptr [eax + ecx] + fild qword ptr [eax + ecx + 8] + fistp qword ptr [edx + ecx + 8] + fistp qword ptr [edx + ecx] + {Are there another 16 bytes to move?} + add ecx, 16 + js @FPUMoveLoop +@FPUMoveLast12: + {Do the last 12 bytes} + fild qword ptr [eax + ecx] + fistp qword ptr [edx + ecx] + mov eax, [eax + ecx + 8] + mov [edx + ecx + 8], eax +{$endif} +{$else} +.noframe + {Make the counter negative based: The last 8 bytes are moved separately} + sub r8, 8 + add rcx, r8 + add rdx, r8 + neg r8 + jns @MoveLast12 +@MoveLoop: + {Move a 16 byte block} + movdqa xmm0, [rcx + r8] + movdqa [rdx + r8], xmm0 + {Are there another 16 bytes to move?} + add r8, 16 + js @MoveLoop +@MoveLast12: + {Do the last 8 bytes} + mov r9, [rcx + r8] + mov [rdx + r8], r9 +{$endif} +end; + +{Variable size move procedure: Rounds ACount up to the next multiple of 8 less + SizeOf(Pointer). Important note: Always moves at least 8 - SizeOf(Pointer) + bytes (the minimum small block size with 8 byte alignment), irrespective of + ACount.} +procedure MoveX8LP(const ASource; var ADest; ACount: NativeInt); +asm +{$ifdef 32Bit} + {Make the counter negative based: The last 4 bytes are moved separately} + sub ecx, 4 + {4 bytes or less? -> Use the Move4 routine.} + jle @FourBytesOrLess + add eax, ecx + add edx, ecx + neg ecx +{$ifdef EnableMMX} + {$ifndef ForceMMX} + cmp UseMMX, True + jne @FPUMoveLoop + {$endif} +@MMXMoveLoop: + {Move an 8 byte block} +{$ifdef Delphi4or5} + {Delphi 5 compatibility} + db $0f, $6f, $04, $01 + db $0f, $7f, $04, $11 +{$else} + movq mm0, [eax + ecx] + movq [edx + ecx], mm0 +{$endif} + {Are there another 8 bytes to move?} + add ecx, 8 + js @MMXMoveLoop + {Exit MMX state} +{$ifdef Delphi4or5} + {Delphi 5 compatibility} + db $0f, $77 +{$else} + emms +{$endif} + {Do the last 4 bytes} + mov eax, [eax + ecx] + mov [edx + ecx], eax + ret +{$endif} +{FPU code is only used if MMX is not forced} +{$ifndef ForceMMX} +@FPUMoveLoop: + {Move an 8 byte block} + fild qword ptr [eax + ecx] + fistp qword ptr [edx + ecx] + {Are there another 8 bytes to move?} + add ecx, 8 + js @FPUMoveLoop + {Do the last 4 bytes} + mov eax, [eax + ecx] + mov [edx + ecx], eax + ret +{$endif} +@FourBytesOrLess: + {Four or less bytes to move} + mov eax, [eax] + mov [edx], eax +{$else} +.noframe + {Make the counter negative based} + add rcx, r8 + add rdx, r8 + neg r8 +@MoveLoop: + {Move an 8 byte block} + mov r9, [rcx + r8] + mov [rdx + r8], r9 + {Are there another 8 bytes to move?} + add r8, 8 + js @MoveLoop +{$endif} +end; + +{----------------Windows Emulation Functions for Kylix Support-----------------} + +{$ifdef Linux} + +const + {Messagebox constants} + MB_OK = 0; + MB_ICONERROR = $10; + MB_TASKMODAL = $2000; + MB_DEFAULT_DESKTOP_ONLY = $20000; + {Virtual memory constants} + MEM_COMMIT = $1000; + MEM_RELEASE = $8000; + MEM_TOP_DOWN = $100000; + PAGE_READWRITE = 4; + +procedure MessageBoxA(hWnd: Cardinal; AMessageText, AMessageTitle: PAnsiChar; uType: Cardinal); stdcall; +begin + writeln(AMessageText); +end; + +function VirtualAlloc(lpvAddress: Pointer; dwSize, flAllocationType, flProtect: Cardinal): Pointer; stdcall; +begin + Result := valloc(dwSize); +end; + +function VirtualFree(lpAddress: Pointer; dwSize, dwFreeType: Cardinal): LongBool; stdcall; +begin + free(lpAddress); + Result := True; +end; + +{$ifndef NeverSleepOnThreadContention} +procedure Sleep(dwMilliseconds: Cardinal); stdcall; +begin + {Convert to microseconds (more or less)} + usleep(dwMilliseconds shl 10); +end; +{$endif} +{$endif} + +{-----------------Debugging Support Functions and Procedures------------------} + +{$ifdef FullDebugMode} + +{Returns the current thread ID} +function GetThreadID: Cardinal; +{$ifdef 32Bit} +asm + mov eax, FS:[$24] +end; +{$else} +begin + Result := GetCurrentThreadId; +end; +{$endif} + +{Fills a block of memory with the given dword (32-bit) or qword (64-bit). + Always fills a multiple of SizeOf(Pointer) bytes} +procedure DebugFillMem(var AAddress; AByteCount: NativeInt; AFillValue: NativeUInt); +asm +{$ifdef 32Bit} + {On Entry: + eax = AAddress + edx = AByteCount + ecx = AFillValue} + add eax, edx + neg edx + jns @Done +@FillLoop: + mov [eax + edx], ecx + add edx, 4 + js @FillLoop +@Done: +{$else} + {On Entry: + rcx = AAddress + rdx = AByteCount + r8 = AFillValue} + add rcx, rdx + neg rdx + jns @Done +@FillLoop: + mov [rcx + rdx], r8 + add rdx, 8 + js @FillLoop +@Done: +{$endif} +end; + + {$ifndef LoadDebugDLLDynamically} + +{The stack trace procedure. The stack trace module is external since it may + raise handled access violations that result in the creation of exception + objects and the stack trace code is not re-entrant.} +procedure GetStackTrace(AReturnAddresses: PNativeUInt; + AMaxDepth, ASkipFrames: Cardinal); external FullDebugModeLibraryName + name {$ifdef RawStackTraces}'GetRawStackTrace'{$else}'GetFrameBasedStackTrace'{$endif}; + +{The exported procedure in the FastMM_FullDebugMode.dll library used to convert + the return addresses of a stack trace to a text string.} +function LogStackTrace(AReturnAddresses: PNativeUInt; + AMaxDepth: Cardinal; ABuffer: PAnsiChar): PAnsiChar; external FullDebugModeLibraryName + name 'LogStackTrace'; + + {$else} + + {Default no-op stack trace and logging handlers} + procedure NoOpGetStackTrace(AReturnAddresses: PNativeUInt; + AMaxDepth, ASkipFrames: Cardinal); + begin + DebugFillMem(AReturnAddresses^, AMaxDepth * SizeOf(Pointer), 0); + end; + + function NoOpLogStackTrace(AReturnAddresses: PNativeUInt; + AMaxDepth: Cardinal; ABuffer: PAnsiChar): PAnsiChar; + begin + Result := ABuffer; + end; + +var + + {Handle to the FullDebugMode DLL} + FullDebugModeDLL: HMODULE; + + GetStackTrace: procedure (AReturnAddresses: PNativeUInt; + AMaxDepth, ASkipFrames: Cardinal) = NoOpGetStackTrace; + + LogStackTrace: function (AReturnAddresses: PNativeUInt; + AMaxDepth: Cardinal; ABuffer: PAnsiChar): PAnsiChar = NoOpLogStackTrace; + + {$endif} + +{$endif} + +{$ifndef Linux} +function DelphiIsRunning: Boolean; +begin + Result := FindWindowA('TAppBuilder', nil) <> 0; +end; +{$endif} + +{Converts an unsigned integer to string at the buffer location, returning the + new buffer position. Note: The 32-bit asm version only supports numbers up to + 2^31 - 1.} +function NativeUIntToStrBuf(ANum: NativeUInt; APBuffer: PAnsiChar): PAnsiChar; +{$ifndef Use32BitAsm} +const + MaxDigits = 20; +var + LDigitBuffer: array[0..MaxDigits - 1] of AnsiChar; + LCount: Cardinal; + LDigit: NativeUInt; +begin + {Generate the digits in the local buffer} + LCount := 0; + repeat + LDigit := ANum; + ANum := ANum div 10; + LDigit := LDigit - ANum * 10; + Inc(LCount); + LDigitBuffer[MaxDigits - LCount] := AnsiChar(Ord('0') + LDigit); + until ANum = 0; + {Copy the digits to the output buffer and advance it} + System.Move(LDigitBuffer[MaxDigits - LCount], APBuffer^, LCount); + Result := APBuffer + LCount; +end; +{$else} +asm + {On entry: eax = ANum, edx = ABuffer} + push edi + mov edi, edx //Pointer to the first character in edi + {Calculate leading digit: divide the number by 1e9} + add eax, 1 //Increment the number + mov edx, $89705F41 //1e9 reciprocal + mul edx //Multplying with reciprocal + shr eax, 30 //Save fraction bits + mov ecx, edx //First digit in bits <31:29> + and edx, $1FFFFFFF //Filter fraction part edx<28:0> + shr ecx, 29 //Get leading digit into accumulator + lea edx, [edx + 4 * edx] //Calculate ... + add edx, eax //... 5*fraction + mov eax, ecx //Copy leading digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #2} + mov eax, edx //Point format such that 1.0 = 2^28 + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 28 //Next digit + and edx, $0fffffff //Fraction part edx<27:0> + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #3} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:27> + lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<26:0> + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 27 //Next digit + and edx, $07ffffff //Fraction part + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #4} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:26> + lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<25:0> + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 26 //Next digit + and edx, $03ffffff //Fraction part + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #5} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:25> + lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<24:0> + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 25 //Next digit + and edx, $01ffffff //Fraction part + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #6} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:24> + lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<23:0> + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 24 //Next digit + and edx, $00ffffff //Fraction part + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #7} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:23> + lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<31:23> + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 23 //Next digit + and edx, $007fffff //Fraction part + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #8} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:22> + lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<22:0> + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 22 //Next digit + and edx, $003fffff //Fraction part + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #9} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:21> + lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<21:0> + cmp ecx, 1 //Any non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 21 //Next digit + and edx, $001fffff //Fraction part + or ecx, eax //Accumulate next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store digit out to memory + {Calculate digit #10} + lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:20> + cmp ecx, 1 //Any-non-zero digit yet ? + sbb edi, -1 //Yes->increment ptr, No->keep old ptr + shr eax, 20 //Next digit + or eax, '0' //Convert digit to ASCII + mov [edi], al //Store last digit and end marker out to memory + {Return a pointer to the next character} + lea eax, [edi + 1] + {Restore edi} + pop edi +end; +{$endif} + +{Converts an unsigned integer to a hexadecimal string at the buffer location, + returning the new buffer position.} +function NativeUIntToHexBuf(ANum: NativeUInt; APBuffer: PAnsiChar): PAnsiChar; +{$ifndef Use32BitAsm} +const + MaxDigits = 16; +var + LDigitBuffer: array[0..MaxDigits - 1] of AnsiChar; + LCount: Cardinal; + LDigit: NativeUInt; +begin + {Generate the digits in the local buffer} + LCount := 0; + repeat + LDigit := ANum; + ANum := ANum div 16; + LDigit := LDigit - ANum * 16; + Inc(LCount); + LDigitBuffer[MaxDigits - LCount] := HexTable[LDigit]; + until ANum = 0; + {Copy the digits to the output buffer and advance it} + System.Move(LDigitBuffer[MaxDigits - LCount], APBuffer^, LCount); + Result := APBuffer + LCount; +end; +{$else} +asm + {On entry: + eax = ANum + edx = ABuffer} + push ebx + push edi + {Save ANum in ebx} + mov ebx, eax + {Get a pointer to the first character in edi} + mov edi, edx + {Get the number in ecx as well} + mov ecx, eax + {Keep the low nibbles in ebx and the high nibbles in ecx} + and ebx, $0f0f0f0f + and ecx, $f0f0f0f0 + {Swap the bytes into the right order} + ror ebx, 16 + ror ecx, 20 + {Get nibble 7} + movzx eax, ch + mov dl, ch + mov al, byte ptr HexTable[eax] + mov [edi], al + cmp dl, 1 + sbb edi, -1 + {Get nibble 6} + movzx eax, bh + or dl, bh + mov al, byte ptr HexTable[eax] + mov [edi], al + cmp dl, 1 + sbb edi, -1 + {Get nibble 5} + movzx eax, cl + or dl, cl + mov al, byte ptr HexTable[eax] + mov [edi], al + cmp dl, 1 + sbb edi, -1 + {Get nibble 4} + movzx eax, bl + or dl, bl + mov al, byte ptr HexTable[eax] + mov [edi], al + cmp dl, 1 + sbb edi, -1 + {Rotate ecx and ebx so we get access to the rest} + shr ebx, 16 + shr ecx, 16 + {Get nibble 3} + movzx eax, ch + or dl, ch + mov al, byte ptr HexTable[eax] + mov [edi], al + cmp dl, 1 + sbb edi, -1 + {Get nibble 2} + movzx eax, bh + or dl, bh + mov al, byte ptr HexTable[eax] + mov [edi], al + cmp dl, 1 + sbb edi, -1 + {Get nibble 1} + movzx eax, cl + or dl, cl + mov al, byte ptr HexTable[eax] + mov [edi], al + cmp dl, 1 + sbb edi, -1 + {Get nibble 0} + movzx eax, bl + mov al, byte ptr HexTable[eax] + mov [edi], al + {Return a pointer to the end of the string} + lea eax, [edi + 1] + {Restore registers} + pop edi + pop ebx +end; +{$endif} + +{Appends the source text to the destination and returns the new destination + position} +function AppendStringToBuffer(const ASource, ADestination: PAnsiChar; ACount: Cardinal): PAnsiChar; +begin + System.Move(ASource^, ADestination^, ACount); + Result := Pointer(PByte(ADestination) + ACount); +end; + +{Appends the name of the class to the destination buffer and returns the new + destination position} +function AppendClassNameToBuffer(AClass: TClass; ADestination: PAnsiChar): PAnsiChar; +var + LPClassName: PShortString; +begin + {Get a pointer to the class name} + if AClass <> nil then + begin + LPClassName := PShortString(PPointer(PByte(AClass) + vmtClassName)^); + {Append the class name} + Result := AppendStringToBuffer(@LPClassName^[1], ADestination, Length(LPClassName^)); + end + else + begin + Result := AppendStringToBuffer(UnknownClassNameMsg, ADestination, Length(UnknownClassNameMsg)); + end; +end; + +{Shows a message box if the program is not showing one already.} +procedure ShowMessageBox(AText, ACaption: PAnsiChar); +begin + if (not ShowingMessageBox) and (not SuppressMessageBoxes) then + begin + ShowingMessageBox := True; + MessageBoxA(0, AText, ACaption, + MB_OK or MB_ICONERROR or MB_TASKMODAL or MB_DEFAULT_DESKTOP_ONLY); + ShowingMessageBox := False; + end; +end; + +{Returns the class for a memory block. Returns nil if it is not a valid class} +function DetectClassInstance(APointer: Pointer): TClass; +{$ifndef Linux} +var + LMemInfo: TMemoryBasicInformation; + + {Checks whether the given address is a valid address for a VMT entry.} + function IsValidVMTAddress(APAddress: Pointer): Boolean; + begin + {Do some basic pointer checks: Must be dword aligned and beyond 64K} + if (UIntPtr(APAddress) > 65535) + and (UIntPtr(APAddress) and 3 = 0) then + begin + {Do we need to recheck the virtual memory?} + if (UIntPtr(LMemInfo.BaseAddress) > UIntPtr(APAddress)) + or ((UIntPtr(LMemInfo.BaseAddress) + LMemInfo.RegionSize) < (UIntPtr(APAddress) + 4)) then + begin + {Get the VM status for the pointer} + LMemInfo.RegionSize := 0; + VirtualQuery(APAddress, LMemInfo, SizeOf(LMemInfo)); + end; + {Check the readability of the memory address} + Result := (LMemInfo.RegionSize >= 4) + and (LMemInfo.State = MEM_COMMIT) + and (LMemInfo.Protect and (PAGE_READONLY or PAGE_READWRITE or PAGE_EXECUTE or PAGE_EXECUTE_READ or PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_WRITECOPY) <> 0) + and (LMemInfo.Protect and PAGE_GUARD = 0); + end + else + Result := False; + end; + + {Returns true if AClassPointer points to a class VMT} + function InternalIsValidClass(AClassPointer: Pointer; ADepth: Integer = 0): Boolean; + var + LParentClassSelfPointer: PPointer; + begin + {Check that the self pointer as well as parent class self pointer addresses + are valid} + if (ADepth < 1000) + and IsValidVMTAddress(Pointer(PByte(AClassPointer) + vmtSelfPtr)) + and IsValidVMTAddress(Pointer(PByte(AClassPointer) + vmtParent)) then + begin + {Get a pointer to the parent class' self pointer} + LParentClassSelfPointer := PPointer(PByte(AClassPointer) + vmtParent)^; + {Check that the self pointer as well as the parent class is valid} + Result := (PPointer(PByte(AClassPointer) + vmtSelfPtr)^ = AClassPointer) + and ((LParentClassSelfPointer = nil) + or (IsValidVMTAddress(LParentClassSelfPointer) + and InternalIsValidClass(LParentClassSelfPointer^, ADepth + 1))); + end + else + Result := False; + end; + +begin + {Get the class pointer from the (suspected) object} + Result := TClass(PPointer(APointer)^); + {No VM info yet} + LMemInfo.RegionSize := 0; + {Check the block} + if (not InternalIsValidClass(Pointer(Result), 0)) +{$ifdef FullDebugMode} + or (Result = @FreedObjectVMT.VMTMethods[0]) +{$endif} + then + Result := nil; +end; +{$else} +begin + {Not currently supported under Linux} + Result := nil; +end; +{$endif} + +{Gets the available size inside a block} +function GetAvailableSpaceInBlock(APointer: Pointer): NativeUInt; +var + LBlockHeader: NativeUInt; + LPSmallBlockPool: PSmallBlockPoolHeader; +begin + LBlockHeader := PNativeUInt(PByte(APointer) - BlockHeaderSize)^; + if LBlockHeader and (IsMediumBlockFlag or IsLargeBlockFlag) = 0 then + begin + LPSmallBlockPool := PSmallBlockPoolHeader(LBlockHeader and DropSmallFlagsMask); + Result := LPSmallBlockPool.BlockType.BlockSize - BlockHeaderSize; + end + else + begin + Result := (LBlockHeader and DropMediumAndLargeFlagsMask) - BlockHeaderSize; + if (LBlockHeader and IsMediumBlockFlag) = 0 then + Dec(Result, LargeBlockHeaderSize); + end; +end; + +{-----------------Small Block Management------------------} + +{Locks all small block types} +procedure LockAllSmallBlockTypes; +var + LInd: Cardinal; +begin + {Lock the medium blocks} +{$ifndef AssumeMultiThreaded} + if IsMultiThread then +{$endif} + begin + for LInd := 0 to NumSmallBlockTypes - 1 do + begin + while LockCmpxchg(0, 1, @SmallBlockTypes[LInd].BlockTypeLocked) <> 0 do + begin +{$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} +{$else} + Sleep(InitialSleepTime); + if LockCmpxchg(0, 1, @SmallBlockTypes[LInd].BlockTypeLocked) = 0 then + Break; + Sleep(AdditionalSleepTime); +{$endif} + end; + end; + end; +end; + +{Gets the first and last block pointer for a small block pool} +procedure GetFirstAndLastSmallBlockInPool(APSmallBlockPool: PSmallBlockPoolHeader; + var AFirstPtr, ALastPtr: Pointer); +var + LBlockSize: NativeUInt; +begin + {Get the pointer to the first block} + AFirstPtr := Pointer(PByte(APSmallBlockPool) + SmallBlockPoolHeaderSize); + {Get a pointer to the last block} + if (APSmallBlockPool.BlockType.CurrentSequentialFeedPool <> APSmallBlockPool) + or (UIntPtr(APSmallBlockPool.BlockType.NextSequentialFeedBlockAddress) > UIntPtr(APSmallBlockPool.BlockType.MaxSequentialFeedBlockAddress)) then + begin + {Not the sequential feed - point to the end of the block} + LBlockSize := PNativeUInt(PByte(APSmallBlockPool) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask; + ALastPtr := Pointer(PByte(APSmallBlockPool) + LBlockSize - APSmallBlockPool.BlockType.BlockSize); + end + else + begin + {The sequential feed pool - point to before the next sequential feed block} + ALastPtr := Pointer(PByte(APSmallBlockPool.BlockType.NextSequentialFeedBlockAddress) - 1); + end; +end; + +{-----------------Medium Block Management------------------} + +{Advances to the next medium block. Returns nil if the end of the medium block + pool has been reached} +function NextMediumBlock(APMediumBlock: Pointer): Pointer; +var + LBlockSize: NativeUInt; +begin + {Get the size of this block} + LBlockSize := PNativeUInt(PByte(APMediumBlock) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask; + {Advance the pointer} + Result := Pointer(PByte(APMediumBlock) + LBlockSize); + {Is the next block the end of medium pool marker?} + LBlockSize := PNativeUInt(PByte(Result) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask; + if LBlockSize = 0 then + Result := nil; +end; + +{Gets the first medium block in the medium block pool} +function GetFirstMediumBlockInPool(APMediumBlockPoolHeader: PMediumBlockPoolHeader): Pointer; +begin + if (MediumSequentialFeedBytesLeft = 0) + or (UIntPtr(LastSequentiallyFedMediumBlock) < UIntPtr(APMediumBlockPoolHeader)) + or (UIntPtr(LastSequentiallyFedMediumBlock) > UIntPtr(APMediumBlockPoolHeader) + MediumBlockPoolSize) then + begin + Result := Pointer(PByte(APMediumBlockPoolHeader) + MediumBlockPoolHeaderSize); + end + else + begin + {Is the sequential feed pool empty?} + if MediumSequentialFeedBytesLeft <> MediumBlockPoolSize - MediumBlockPoolHeaderSize then + Result := LastSequentiallyFedMediumBlock + else + Result := nil; + end; +end; + +{Locks the medium blocks. Note that the 32-bit asm version is assumed to + preserve all registers except eax.} +{$ifndef Use32BitAsm} +procedure LockMediumBlocks; +begin + {Lock the medium blocks} +{$ifndef AssumeMultiThreaded} + if IsMultiThread then +{$endif} + begin + while LockCmpxchg(0, 1, @MediumBlocksLocked) <> 0 do + begin +{$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} +{$else} + Sleep(InitialSleepTime); + if LockCmpxchg(0, 1, @MediumBlocksLocked) = 0 then + Break; + Sleep(AdditionalSleepTime); +{$endif} + end; + end; +end; +{$else} +procedure LockMediumBlocks; +asm + {Note: This routine is assumed to preserve all registers except eax} +@MediumBlockLockLoop: + mov eax, $100 + {Attempt to lock the medium blocks} + lock cmpxchg MediumBlocksLocked, ah + je @Done +{$ifdef NeverSleepOnThreadContention} + {Pause instruction (improves performance on P4)} + rep nop + {$ifdef UseSwitchToThread} + push ecx + push edx + call SwitchToThread + pop edx + pop ecx + {$endif} + {Try again} + jmp @MediumBlockLockLoop +{$else} + {Couldn't lock the medium blocks - sleep and try again} + push ecx + push edx + push InitialSleepTime + call Sleep + pop edx + pop ecx + {Try again} + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg MediumBlocksLocked, ah + je @Done + {Couldn't lock the medium blocks - sleep and try again} + push ecx + push edx + push AdditionalSleepTime + call Sleep + pop edx + pop ecx + {Try again} + jmp @MediumBlockLockLoop +{$endif} +@Done: +end; +{$endif} + +{Removes a medium block from the circular linked list of free blocks. + Does not change any header flags. Medium blocks should be locked + before calling this procedure.} +procedure RemoveMediumFreeBlock(APMediumFreeBlock: PMediumFreeBlock); +{$ifndef ASMVersion} +var + LPreviousFreeBlock, LNextFreeBlock: PMediumFreeBlock; + LBinNumber, LBinGroupNumber: Cardinal; +begin + {Get the current previous and next blocks} + LNextFreeBlock := APMediumFreeBlock.NextFreeBlock; + LPreviousFreeBlock := APMediumFreeBlock.PreviousFreeBlock; + {Remove this block from the linked list} + LPreviousFreeBlock.NextFreeBlock := LNextFreeBlock; + LNextFreeBlock.PreviousFreeBlock := LPreviousFreeBlock; + {Is this bin now empty? If the previous and next free block pointers are + equal, they must point to the bin.} + if LPreviousFreeBlock = LNextFreeBlock then + begin + {Get the bin number for this block size} + LBinNumber := (UIntPtr(LNextFreeBlock) - UIntPtr(@MediumBlockBins)) div SizeOf(TMediumFreeBlock); + LBinGroupNumber := LBinNumber div 32; + {Flag this bin as empty} + MediumBlockBinBitmaps[LBinGroupNumber] := MediumBlockBinBitmaps[LBinGroupNumber] + and (not (1 shl (LBinNumber and 31))); + {Is the group now entirely empty?} + if MediumBlockBinBitmaps[LBinGroupNumber] = 0 then + begin + {Flag this group as empty} + MediumBlockBinGroupBitmap := MediumBlockBinGroupBitmap + and (not (1 shl LBinGroupNumber)); + end; + end; +end; +{$else} +{$ifdef 32Bit} +asm + {On entry: eax = APMediumFreeBlock} + {Get the current previous and next blocks} + mov ecx, TMediumFreeBlock[eax].NextFreeBlock + mov edx, TMediumFreeBlock[eax].PreviousFreeBlock + {Is this bin now empty? If the previous and next free block pointers are + equal, they must point to the bin.} + cmp ecx, edx + {Remove this block from the linked list} + mov TMediumFreeBlock[ecx].PreviousFreeBlock, edx + mov TMediumFreeBlock[edx].NextFreeBlock, ecx + {Is this bin now empty? If the previous and next free block pointers are + equal, they must point to the bin.} + je @BinIsNowEmpty +@Done: + ret + {Align branch target} + nop +@BinIsNowEmpty: + {Get the bin number for this block size in ecx} + sub ecx, offset MediumBlockBins + mov edx, ecx + shr ecx, 3 + {Get the group number in edx} + movzx edx, dh + {Flag this bin as empty} + mov eax, -2 + rol eax, cl + and dword ptr [MediumBlockBinBitmaps + edx * 4], eax + jnz @Done + {Flag this group as empty} + mov eax, -2 + mov ecx, edx + rol eax, cl + and MediumBlockBinGroupBitmap, eax +end; +{$else} +asm + {On entry: rcx = APMediumFreeBlock} + mov rax, rcx + {Get the current previous and next blocks} + mov rcx, TMediumFreeBlock[rax].NextFreeBlock + mov rdx, TMediumFreeBlock[rax].PreviousFreeBlock + {Is this bin now empty? If the previous and next free block pointers are + equal, they must point to the bin.} + cmp rcx, rdx + {Remove this block from the linked list} + mov TMediumFreeBlock[rcx].PreviousFreeBlock, rdx + mov TMediumFreeBlock[rdx].NextFreeBlock, rcx + {Is this bin now empty? If the previous and next free block pointers are + equal, they must point to the bin.} + jne @Done + {Get the bin number for this block size in rcx} + lea r8, MediumBlockBins + sub rcx, r8 + mov edx, ecx + shr ecx, 4 + {Get the group number in edx} + shr edx, 9 + {Flag this bin as empty} + mov eax, -2 + rol eax, cl + lea r8, MediumBlockBinBitmaps + and dword ptr [r8 + rdx * 4], eax + jnz @Done + {Flag this group as empty} + mov eax, -2 + mov ecx, edx + rol eax, cl + and MediumBlockBinGroupBitmap, eax +@Done: +end; +{$endif} +{$endif} + +{Inserts a medium block into the appropriate medium block bin.} +procedure InsertMediumBlockIntoBin(APMediumFreeBlock: PMediumFreeBlock; AMediumBlockSize: Cardinal); +{$ifndef ASMVersion} +var + LBinNumber, LBinGroupNumber: Cardinal; + LPBin, LPFirstFreeBlock: PMediumFreeBlock; +begin + {Get the bin number for this block size. Get the bin that holds blocks of at + least this size.} + LBinNumber := (AMediumBlockSize - MinimumMediumBlockSize) div MediumBlockGranularity; + if LBinNumber >= MediumBlockBinCount then + LBinNumber := MediumBlockBinCount - 1; + {Get the bin} + LPBin := @MediumBlockBins[LBinNumber]; + {Bins are LIFO, se we insert this block as the first free block in the bin} + LPFirstFreeBlock := LPBin.NextFreeBlock; + APMediumFreeBlock.PreviousFreeBlock := LPBin; + APMediumFreeBlock.NextFreeBlock := LPFirstFreeBlock; + LPFirstFreeBlock.PreviousFreeBlock := APMediumFreeBlock; + LPBin.NextFreeBlock := APMediumFreeBlock; + {Was this bin empty?} + if LPFirstFreeBlock = LPBin then + begin + {Get the group number} + LBinGroupNumber := LBinNumber div 32; + {Flag this bin as used} + MediumBlockBinBitmaps[LBinGroupNumber] := MediumBlockBinBitmaps[LBinGroupNumber] + or (1 shl (LBinNumber and 31)); + {Flag the group as used} + MediumBlockBinGroupBitmap := MediumBlockBinGroupBitmap + or (1 shl LBinGroupNumber); + end; +end; +{$else} +{$ifdef 32Bit} +asm + {On entry: eax = APMediumFreeBlock, edx = AMediumBlockSize} + {Get the bin number for this block size. Get the bin that holds blocks of at + least this size.} + sub edx, MinimumMediumBlockSize + shr edx, 8 + {Validate the bin number} + sub edx, MediumBlockBinCount - 1 + sbb ecx, ecx + and edx, ecx + add edx, MediumBlockBinCount - 1 + {Get the bin in ecx} + lea ecx, [MediumBlockBins + edx * 8] + {Bins are LIFO, se we insert this block as the first free block in the bin} + mov edx, TMediumFreeBlock[ecx].NextFreeBlock + {Was this bin empty?} + cmp edx, ecx + mov TMediumFreeBlock[eax].PreviousFreeBlock, ecx + mov TMediumFreeBlock[eax].NextFreeBlock, edx + mov TMediumFreeBlock[edx].PreviousFreeBlock, eax + mov TMediumFreeBlock[ecx].NextFreeBlock, eax + {Was this bin empty?} + je @BinWasEmpty + ret + {Align branch target} + nop + nop +@BinWasEmpty: + {Get the bin number in ecx} + sub ecx, offset MediumBlockBins + mov edx, ecx + shr ecx, 3 + {Get the group number in edx} + movzx edx, dh + {Flag this bin as not empty} + mov eax, 1 + shl eax, cl + or dword ptr [MediumBlockBinBitmaps + edx * 4], eax + {Flag the group as not empty} + mov eax, 1 + mov ecx, edx + shl eax, cl + or MediumBlockBinGroupBitmap, eax +end; +{$else} +asm + {On entry: rax = APMediumFreeBlock, edx = AMediumBlockSize} + mov rax, rcx + {Get the bin number for this block size. Get the bin that holds blocks of at + least this size.} + sub edx, MinimumMediumBlockSize + shr edx, 8 + {Validate the bin number} + sub edx, MediumBlockBinCount - 1 + sbb ecx, ecx + and edx, ecx + add edx, MediumBlockBinCount - 1 + mov r9, rdx + {Get the bin address in rcx} + lea rcx, MediumBlockBins + shl edx, 4 + add rcx, rdx + {Bins are LIFO, se we insert this block as the first free block in the bin} + mov rdx, TMediumFreeBlock[rcx].NextFreeBlock + {Was this bin empty?} + cmp rdx, rcx + mov TMediumFreeBlock[rax].PreviousFreeBlock, rcx + mov TMediumFreeBlock[rax].NextFreeBlock, rdx + mov TMediumFreeBlock[rdx].PreviousFreeBlock, rax + mov TMediumFreeBlock[rcx].NextFreeBlock, rax + {Was this bin empty?} + jne @Done + {Get the bin number in ecx} + mov rcx, r9 + {Get the group number in edx} + mov rdx, r9 + shr edx, 5 + {Flag this bin as not empty} + mov eax, 1 + shl eax, cl + lea r8, MediumBlockBinBitmaps + or dword ptr [r8 + rdx * 4], eax + {Flag the group as not empty} + mov eax, 1 + mov ecx, edx + shl eax, cl + or MediumBlockBinGroupBitmap, eax +@Done: +end; +{$endif} +{$endif} + +{Bins what remains in the current sequential feed medium block pool. Medium + blocks must be locked.} +procedure BinMediumSequentialFeedRemainder; +{$ifndef ASMVersion} +var + LSequentialFeedFreeSize, LNextBlockSizeAndFlags: NativeUInt; + LPRemainderBlock, LNextMediumBlock: Pointer; +begin + LSequentialFeedFreeSize := MediumSequentialFeedBytesLeft; + if LSequentialFeedFreeSize > 0 then + begin + {Get the block after the open space} + LNextMediumBlock := LastSequentiallyFedMediumBlock; + LNextBlockSizeAndFlags := PNativeUInt(PByte(LNextMediumBlock) - BlockHeaderSize)^; + {Point to the remainder} + LPRemainderBlock := Pointer(PByte(LNextMediumBlock) - LSequentialFeedFreeSize); +{$ifndef FullDebugMode} + {Can the next block be combined with the remainder?} + if (LNextBlockSizeAndFlags and IsFreeBlockFlag) <> 0 then + begin + {Increase the size of this block} + Inc(LSequentialFeedFreeSize, LNextBlockSizeAndFlags and DropMediumAndLargeFlagsMask); + {Remove the next block as well} + if (LNextBlockSizeAndFlags and DropMediumAndLargeFlagsMask) >= MinimumMediumBlockSize then + RemoveMediumFreeBlock(LNextMediumBlock); + end + else + begin +{$endif} + {Set the "previous block is free" flag of the next block} + PNativeUInt(PByte(LNextMediumBlock) - BlockHeaderSize)^ := LNextBlockSizeAndFlags or PreviousMediumBlockIsFreeFlag; +{$ifndef FullDebugMode} + end; +{$endif} + {Store the size of the block as well as the flags} + PNativeUInt(PByte(LPRemainderBlock) - BlockHeaderSize)^ := LSequentialFeedFreeSize or IsMediumBlockFlag or IsFreeBlockFlag; + {Store the trailing size marker} + PNativeUInt(PByte(LPRemainderBlock) + LSequentialFeedFreeSize - BlockHeaderSize * 2)^ := LSequentialFeedFreeSize; +{$ifdef FullDebugMode} + {In full debug mode the sequential feed remainder will never be too small to + fit a full debug header.} + {Clear the user area of the block} + DebugFillMem(Pointer(PByte(LPRemainderBlock) + SizeOf(TFullDebugBlockHeader) + SizeOf(NativeUInt))^, + LSequentialFeedFreeSize - FullDebugBlockOverhead - SizeOf(NativeUInt), + {$ifndef CatchUseOfFreedInterfaces}DebugFillPattern{$else}NativeUInt(@VMTBadInterface){$endif}); + {We need to set a valid debug header and footer in the remainder} + PFullDebugBlockHeader(LPRemainderBlock).HeaderCheckSum := NativeUInt(LPRemainderBlock); + PNativeUInt(PByte(LPRemainderBlock) + SizeOf(TFullDebugBlockHeader))^ := not NativeUInt(LPRemainderBlock); +{$endif} + {Bin this medium block} + if LSequentialFeedFreeSize >= MinimumMediumBlockSize then + InsertMediumBlockIntoBin(LPRemainderBlock, LSequentialFeedFreeSize); + end; +end; +{$else} +{$ifdef 32Bit} +asm + cmp MediumSequentialFeedBytesLeft, 0 + jne @MustBinMedium + {Nothing to bin} + ret + {Align branch target} + nop + nop +@MustBinMedium: + {Get a pointer to the last sequentially allocated medium block} + mov eax, LastSequentiallyFedMediumBlock + {Is the block that was last fed sequentially free?} + test byte ptr [eax - 4], IsFreeBlockFlag + jnz @LastBlockFedIsFree + {Set the "previous block is free" flag in the last block fed} + or dword ptr [eax - 4], PreviousMediumBlockIsFreeFlag + {Get the remainder in edx} + mov edx, MediumSequentialFeedBytesLeft + {Point eax to the start of the remainder} + sub eax, edx +@BinTheRemainder: + {Status: eax = start of remainder, edx = size of remainder} + {Store the size of the block as well as the flags} + lea ecx, [edx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [eax - 4], ecx + {Store the trailing size marker} + mov [eax + edx - 8], edx + {Bin this medium block} + cmp edx, MinimumMediumBlockSize + jnb InsertMediumBlockIntoBin + ret + {Align branch target} + nop + nop +@LastBlockFedIsFree: + {Drop the flags} + mov edx, DropMediumAndLargeFlagsMask + and edx, [eax - 4] + {Free the last block fed} + cmp edx, MinimumMediumBlockSize + jb @DontRemoveLastFed + {Last fed block is free - remove it from its size bin} + call RemoveMediumFreeBlock + {Re-read eax and edx} + mov eax, LastSequentiallyFedMediumBlock + mov edx, DropMediumAndLargeFlagsMask + and edx, [eax - 4] +@DontRemoveLastFed: + {Get the number of bytes left in ecx} + mov ecx, MediumSequentialFeedBytesLeft + {Point eax to the start of the remainder} + sub eax, ecx + {edx = total size of the remainder} + add edx, ecx + jmp @BinTheRemainder +@Done: +end; +{$else} +asm + .params 2 + xor eax, eax + cmp MediumSequentialFeedBytesLeft, eax + je @Done + {Get a pointer to the last sequentially allocated medium block} + mov rax, LastSequentiallyFedMediumBlock + {Is the block that was last fed sequentially free?} + test byte ptr [rax - BlockHeaderSize], IsFreeBlockFlag + jnz @LastBlockFedIsFree + {Set the "previous block is free" flag in the last block fed} + or qword ptr [rax - BlockHeaderSize], PreviousMediumBlockIsFreeFlag + {Get the remainder in edx} + mov edx, MediumSequentialFeedBytesLeft + {Point eax to the start of the remainder} + sub rax, rdx +@BinTheRemainder: + {Status: rax = start of remainder, edx = size of remainder} + {Store the size of the block as well as the flags} + lea rcx, [rdx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [rax - BlockHeaderSize], rcx + {Store the trailing size marker} + mov [rax + rdx - 2 * BlockHeaderSize], rdx + {Bin this medium block} + cmp edx, MinimumMediumBlockSize + jb @Done + mov rcx, rax + call InsertMediumBlockIntoBin + jmp @Done +@LastBlockFedIsFree: + {Drop the flags} + mov rdx, DropMediumAndLargeFlagsMask + and rdx, [rax - BlockHeaderSize] + {Free the last block fed} + cmp edx, MinimumMediumBlockSize + jb @DontRemoveLastFed + {Last fed block is free - remove it from its size bin} + mov rcx, rax + call RemoveMediumFreeBlock + {Re-read rax and rdx} + mov rax, LastSequentiallyFedMediumBlock + mov rdx, DropMediumAndLargeFlagsMask + and rdx, [rax - BlockHeaderSize] +@DontRemoveLastFed: + {Get the number of bytes left in ecx} + mov ecx, MediumSequentialFeedBytesLeft + {Point rax to the start of the remainder} + sub rax, rcx + {edx = total size of the remainder} + add edx, ecx + jmp @BinTheRemainder +@Done: +end; +{$endif} +{$endif} + +{Allocates a new sequential feed medium block pool and immediately splits off a + block of the requested size. The block size must be a multiple of 16 and + medium blocks must be locked.} +function AllocNewSequentialFeedMediumPool(AFirstBlockSize: Cardinal): Pointer; +var + LOldFirstMediumBlockPool: PMediumBlockPoolHeader; + LNewPool: Pointer; +begin + {Bin the current sequential feed remainder} + BinMediumSequentialFeedRemainder; + {Allocate a new sequential feed block pool} + LNewPool := VirtualAlloc(nil, MediumBlockPoolSize, + MEM_COMMIT{$ifdef AlwaysAllocateTopDown} or MEM_TOP_DOWN{$endif}, PAGE_READWRITE); + if LNewPool <> nil then + begin + {Insert this block pool into the list of block pools} + LOldFirstMediumBlockPool := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader; + PMediumBlockPoolHeader(LNewPool).PreviousMediumBlockPoolHeader := @MediumBlockPoolsCircularList; + MediumBlockPoolsCircularList.NextMediumBlockPoolHeader := LNewPool; + PMediumBlockPoolHeader(LNewPool).NextMediumBlockPoolHeader := LOldFirstMediumBlockPool; + LOldFirstMediumBlockPool.PreviousMediumBlockPoolHeader := LNewPool; + {Store the sequential feed pool trailer} + PNativeUInt(PByte(LNewPool) + MediumBlockPoolSize - BlockHeaderSize)^ := IsMediumBlockFlag; + {Get the number of bytes still available} + MediumSequentialFeedBytesLeft := (MediumBlockPoolSize - MediumBlockPoolHeaderSize) - AFirstBlockSize; + {Get the result} + Result := Pointer(PByte(LNewPool) + MediumBlockPoolSize - AFirstBlockSize); + LastSequentiallyFedMediumBlock := Result; + {Store the block header} + PNativeUInt(PByte(Result) - BlockHeaderSize)^ := AFirstBlockSize or IsMediumBlockFlag; + end + else + begin + {Out of memory} + MediumSequentialFeedBytesLeft := 0; + Result := nil; + end; +end; + +{-----------------Large Block Management------------------} + +{Locks the large blocks} +procedure LockLargeBlocks; +begin + {Lock the large blocks} +{$ifndef AssumeMultiThreaded} + if IsMultiThread then +{$endif} + begin + while LockCmpxchg(0, 1, @LargeBlocksLocked) <> 0 do + begin +{$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} +{$else} + Sleep(InitialSleepTime); + if LockCmpxchg(0, 1, @LargeBlocksLocked) = 0 then + Break; + Sleep(AdditionalSleepTime); +{$endif} + end; + end; +end; + +{Allocates a Large block of at least ASize (actual size may be larger to + allow for alignment etc.). ASize must be the actual user requested size. This + procedure will pad it to the appropriate page boundary and also add the space + required by the header.} +function AllocateLargeBlock(ASize: NativeUInt): Pointer; +var + LLargeUsedBlockSize: NativeUInt; + LOldFirstLargeBlock: PLargeBlockHeader; +begin + {Pad the block size to include the header and granularity. We also add a + SizeOf(Pointer) overhead so a huge block size is a multiple of 16 bytes less + SizeOf(Pointer) (so we can use a single move function for reallocating all + block types)} + LLargeUsedBlockSize := (ASize + LargeBlockHeaderSize + LargeBlockGranularity - 1 + BlockHeaderSize) + and -LargeBlockGranularity; + {Get the Large block} + Result := VirtualAlloc(nil, LLargeUsedBlockSize, MEM_COMMIT or MEM_TOP_DOWN, + PAGE_READWRITE); + {Set the Large block fields} + if Result <> nil then + begin + {Set the large block size and flags} + PLargeBlockHeader(Result).UserAllocatedSize := ASize; + PLargeBlockHeader(Result).BlockSizeAndFlags := LLargeUsedBlockSize or IsLargeBlockFlag; + {Insert the large block into the linked list of large blocks} + LockLargeBlocks; + LOldFirstLargeBlock := LargeBlocksCircularList.NextLargeBlockHeader; + PLargeBlockHeader(Result).PreviousLargeBlockHeader := @LargeBlocksCircularList; + LargeBlocksCircularList.NextLargeBlockHeader := Result; + PLargeBlockHeader(Result).NextLargeBlockHeader := LOldFirstLargeBlock; + LOldFirstLargeBlock.PreviousLargeBlockHeader := Result; + LargeBlocksLocked := False; + {Add the size of the header} + Inc(PByte(Result), LargeBlockHeaderSize); +{$ifdef FullDebugMode} + {Since large blocks are never reused, the user area is not initialized to + the debug fill pattern, but the debug header and footer must be set.} + PFullDebugBlockHeader(Result).HeaderCheckSum := NativeUInt(Result); + PNativeUInt(PByte(Result) + SizeOf(TFullDebugBlockHeader))^ := not NativeUInt(Result); +{$endif} + end; +end; + +{Frees a large block, returning 0 on success, -1 otherwise} +function FreeLargeBlock(APointer: Pointer): Integer; +var + LPreviousLargeBlockHeader, LNextLargeBlockHeader: PLargeBlockHeader; +{$ifndef Linux} + LRemainingSize: NativeUInt; + LCurrentSegment: Pointer; + LMemInfo: TMemoryBasicInformation; +{$endif} +begin +{$ifdef ClearLargeBlocksBeforeReturningToOS} + FillChar(APointer^, + (PLargeBlockHeader(PByte(APointer) - LargeBlockHeaderSize).BlockSizeAndFlags + and DropMediumAndLargeFlagsMask) - LargeBlockHeaderSize, 0); +{$endif} + {Point to the start of the large block} + APointer := Pointer(PByte(APointer) - LargeBlockHeaderSize); + {Get the previous and next large blocks} + LockLargeBlocks; + LPreviousLargeBlockHeader := PLargeBlockHeader(APointer).PreviousLargeBlockHeader; + LNextLargeBlockHeader := PLargeBlockHeader(APointer).NextLargeBlockHeader; +{$ifndef Linux} + {Is the large block segmented?} + if PLargeBlockHeader(APointer).BlockSizeAndFlags and LargeBlockIsSegmented = 0 then + begin +{$endif} + {Single segment large block: Try to free it} + if VirtualFree(APointer, 0, MEM_RELEASE) then + Result := 0 + else + Result := -1; +{$ifndef Linux} + end + else + begin + {The large block is segmented - free all segments} + LCurrentSegment := APointer; + LRemainingSize := PLargeBlockHeader(APointer).BlockSizeAndFlags and DropMediumAndLargeFlagsMask; + Result := 0; + while True do + begin + {Get the size of the current segment} + VirtualQuery(LCurrentSegment, LMemInfo, SizeOf(LMemInfo)); + {Free the segment} + if not VirtualFree(LCurrentSegment, 0, MEM_RELEASE) then + begin + Result := -1; + Break; + end; + {Done?} + if NativeUInt(LMemInfo.RegionSize) >= LRemainingSize then + Break; + {Decrement the remaining size} + Dec(LRemainingSize, NativeUInt(LMemInfo.RegionSize)); + Inc(PByte(LCurrentSegment), NativeUInt(LMemInfo.RegionSize)); + end; + end; +{$endif} + {Success?} + if Result = 0 then + begin + {Remove the large block from the linked list} + LNextLargeBlockHeader.PreviousLargeBlockHeader := LPreviousLargeBlockHeader; + LPreviousLargeBlockHeader.NextLargeBlockHeader := LNextLargeBlockHeader; + end; + {Unlock the large blocks} + LargeBlocksLocked := False; +end; + +{$ifndef FullDebugMode} +{Reallocates a large block to at least the requested size. Returns the new + pointer, or nil on error} +function ReallocateLargeBlock(APointer: Pointer; ANewSize: NativeUInt): Pointer; +var + LOldAvailableSize, LBlockHeader, LOldUserSize, LMinimumUpsize, + LNewAllocSize: NativeUInt; +{$ifndef Linux} + LNewSegmentSize: NativeUInt; + LNextSegmentPointer: Pointer; + LMemInfo: TMemoryBasicInformation; +{$endif} +begin + {Get the block header} + LBlockHeader := PNativeUInt(PByte(APointer) - BlockHeaderSize)^; + {Large block - size is (16 + 4) less than the allocated size} + LOldAvailableSize := (LBlockHeader and DropMediumAndLargeFlagsMask) - (LargeBlockHeaderSize + BlockHeaderSize); + {Is it an upsize or a downsize?} + if ANewSize > LOldAvailableSize then + begin + {This pointer is being reallocated to a larger block and therefore it is + logical to assume that it may be enlarged again. Since reallocations are + expensive, there is a minimum upsize percentage to avoid unnecessary + future move operations.} + {Add 25% for large block upsizes} + LMinimumUpsize := LOldAvailableSize + (LOldAvailableSize shr 2); + if ANewSize < LMinimumUpsize then + LNewAllocSize := LMinimumUpsize + else + LNewAllocSize := ANewSize; +{$ifndef Linux} + {Can another large block segment be allocated directly after this segment, + thus negating the need to move the data?} + LNextSegmentPointer := Pointer(PByte(APointer) - LargeBlockHeaderSize + (LBlockHeader and DropMediumAndLargeFlagsMask)); + VirtualQuery(LNextSegmentPointer, LMemInfo, SizeOf(LMemInfo)); + if LMemInfo.State = MEM_FREE then + begin + {Round the region size to the previous 64K} + LMemInfo.RegionSize := LMemInfo.RegionSize and -LargeBlockGranularity; + {Enough space to grow in place?} + if NativeUInt(LMemInfo.RegionSize) > (ANewSize - LOldAvailableSize) then + begin + {There is enough space after the block to extend it - determine by how + much} + LNewSegmentSize := (LNewAllocSize - LOldAvailableSize + LargeBlockGranularity - 1) and -LargeBlockGranularity; + if LNewSegmentSize > LMemInfo.RegionSize then + LNewSegmentSize := LMemInfo.RegionSize; + {Attempy to reserve the address range (which will fail if another + thread has just reserved it) and commit it immediately afterwards.} + if (VirtualAlloc(LNextSegmentPointer, LNewSegmentSize, MEM_RESERVE, PAGE_READWRITE) <> nil) + and (VirtualAlloc(LNextSegmentPointer, LNewSegmentSize, MEM_COMMIT, PAGE_READWRITE) <> nil) then + begin + {Update the requested size} + PLargeBlockHeader(PByte(APointer) - LargeBlockHeaderSize).UserAllocatedSize := ANewSize; + PLargeBlockHeader(PByte(APointer) - LargeBlockHeaderSize).BlockSizeAndFlags := + (PLargeBlockHeader(PByte(APointer) - LargeBlockHeaderSize).BlockSizeAndFlags + LNewSegmentSize) + or LargeBlockIsSegmented; + {Success} + Result := APointer; + Exit; + end; + end; + end; +{$endif} + {Could not resize in place: Allocate the new block} + Result := FastGetMem(LNewAllocSize); + if Result <> nil then + begin + {If it's a large block - store the actual user requested size (it may + not be if the block that is being reallocated from was previously + downsized)} + if LNewAllocSize > (MaximumMediumBlockSize - BlockHeaderSize) then + PLargeBlockHeader(PByte(Result) - LargeBlockHeaderSize).UserAllocatedSize := ANewSize; + {The user allocated size is stored for large blocks} + LOldUserSize := PLargeBlockHeader(PByte(APointer) - LargeBlockHeaderSize).UserAllocatedSize; + {The number of bytes to move is the old user size.} +{$ifdef UseCustomVariableSizeMoveRoutines} + MoveX16LP(APointer^, Result^, LOldUserSize); +{$else} + System.Move(APointer^, Result^, LOldUserSize); +{$endif} + {Free the old block} + FastFreeMem(APointer); + end; + end + else + begin + {It's a downsize: do we need to reallocate? Only if the new size is less + than half the old size} + if ANewSize >= (LOldAvailableSize shr 1) then + begin + {No need to reallocate} + Result := APointer; + {Update the requested size} + PLargeBlockHeader(PByte(APointer) - LargeBlockHeaderSize).UserAllocatedSize := ANewSize; + end + else + begin + {The block is less than half the old size, and the current size is + greater than the minimum block size allowing a downsize: reallocate} + Result := FastGetMem(ANewSize); + if Result <> nil then + begin + {Still a large block? -> Set the user size} + if ANewSize > (MaximumMediumBlockSize - BlockHeaderSize) then + PLargeBlockHeader(PByte(APointer) - LargeBlockHeaderSize).UserAllocatedSize := ANewSize; + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} +{$ifdef Align16Bytes} + MoveX16LP(APointer^, Result^, ANewSize); +{$else} + MoveX8LP(APointer^, Result^, ANewSize); +{$endif} +{$else} + System.Move(APointer^, Result^, ANewSize); +{$endif} + {Free the old block} + FastFreeMem(APointer); + end; + end; + end; +end; +{$endif} + +{---------------------Replacement Memory Manager Interface---------------------} + +{Replacement for SysGetMem} + +function FastGetMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +{$ifndef ASMVersion} +var + LMediumBlock{$ifndef FullDebugMode}, LNextFreeBlock, LSecondSplit{$endif}: PMediumFreeBlock; + LNextMediumBlockHeader: PNativeUInt; + LBlockSize, LAvailableBlockSize{$ifndef FullDebugMode}, LSecondSplitSize{$endif}, + LSequentialFeedFreeSize: NativeUInt; + LPSmallBlockType: PSmallBlockType; + LPSmallBlockPool, LPNewFirstPool: PSmallBlockPoolHeader; + LNewFirstFreeBlock: Pointer; + LPMediumBin: PMediumFreeBlock; + LBinNumber, {$ifndef FullDebugMode}LBinGroupsMasked, {$endif}LBinGroupMasked, + LBinGroupNumber: Cardinal; +begin + {Is it a small block? -> Take the header size into account when + determining the required block size} + if NativeUInt(ASize) <= (MaximumSmallBlockSize - BlockHeaderSize) then + begin + {-------------------------Allocate a small block---------------------------} + {Get the block type from the size} + LPSmallBlockType := PSmallBlockType(AllocSize2SmallBlockTypeIndX4[ + (NativeUInt(ASize) + (BlockHeaderSize - 1)) div SmallBlockGranularity] + * (SizeOf(TSmallBlockType) div 4) + + UIntPtr(@SmallBlockTypes)); + {Lock the block type} +{$ifndef AssumeMultiThreaded} + if IsMultiThread then +{$endif} + begin + while True do + begin + {Try to lock the small block type} + if LockCmpxchg(0, 1, @LPSmallBlockType.BlockTypeLocked) = 0 then + Break; + {Try the next block type} + Inc(PByte(LPSmallBlockType), SizeOf(TSmallBlockType)); + if LockCmpxchg(0, 1, @LPSmallBlockType.BlockTypeLocked) = 0 then + Break; + {Try up to two sizes past the requested size} + Inc(PByte(LPSmallBlockType), SizeOf(TSmallBlockType)); + if LockCmpxchg(0, 1, @LPSmallBlockType.BlockTypeLocked) = 0 then + Break; + {All three sizes locked - given up and sleep} + Dec(PByte(LPSmallBlockType), 2 * SizeOf(TSmallBlockType)); +{$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} +{$else} + {Both this block type and the next is in use: sleep} + Sleep(InitialSleepTime); + {Try the lock again} + if LockCmpxchg(0, 1, @LPSmallBlockType.BlockTypeLocked) = 0 then + Break; + {Sleep longer} + Sleep(AdditionalSleepTime); +{$endif} + end; + end; + {Get the first pool with free blocks} + LPSmallBlockPool := LPSmallBlockType.NextPartiallyFreePool; + {Is the pool valid?} + if UIntPtr(LPSmallBlockPool) <> UIntPtr(LPSmallBlockType) then + begin + {Get the first free offset} + Result := LPSmallBlockPool.FirstFreeBlock; + {Get the new first free block} + LNewFirstFreeBlock := PPointer(PByte(Result) - BlockHeaderSize)^; +{$ifdef CheckHeapForCorruption} + {The block should be free} + if (NativeUInt(LNewFirstFreeBlock) and ExtractSmallFlagsMask) <> IsFreeBlockFlag then + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} +{$endif} + LNewFirstFreeBlock := Pointer(UIntPtr(LNewFirstFreeBlock) and DropSmallFlagsMask); + {Increment the number of used blocks} + Inc(LPSmallBlockPool.BlocksInUse); + {Set the new first free block} + LPSmallBlockPool.FirstFreeBlock := LNewFirstFreeBlock; + {Is the pool now full?} + if LNewFirstFreeBlock = nil then + begin + {Pool is full - remove it from the partially free list} + LPNewFirstPool := LPSmallBlockPool.NextPartiallyFreePool; + LPSmallBlockType.NextPartiallyFreePool := LPNewFirstPool; + LPNewFirstPool.PreviousPartiallyFreePool := PSmallBlockPoolHeader(LPSmallBlockType); + end; + end + else + begin + {Try to feed a small block sequentially} + Result := LPSmallBlockType.NextSequentialFeedBlockAddress; + {Can another block fit?} + if UIntPtr(Result) <= UIntPtr(LPSmallBlockType.MaxSequentialFeedBlockAddress) then + begin + {Get the sequential feed block pool} + LPSmallBlockPool := LPSmallBlockType.CurrentSequentialFeedPool; + {Increment the number of used blocks in the sequential feed pool} + Inc(LPSmallBlockPool.BlocksInUse); + {Store the next sequential feed block address} + LPSmallBlockType.NextSequentialFeedBlockAddress := Pointer(PByte(Result) + LPSmallBlockType.BlockSize); + end + else + begin + {Need to allocate a pool: Lock the medium blocks} + LockMediumBlocks; +{$ifndef FullDebugMode} + {Are there any available blocks of a suitable size?} + LBinGroupsMasked := MediumBlockBinGroupBitmap and ($ffffff00 or LPSmallBlockType.AllowedGroupsForBlockPoolBitmap); + if LBinGroupsMasked <> 0 then + begin + {Get the bin group with free blocks} + LBinGroupNumber := FindFirstSetBit(LBinGroupsMasked); + {Get the bin in the group with free blocks} + LBinNumber := FindFirstSetBit(MediumBlockBinBitmaps[LBinGroupNumber]) + + LBinGroupNumber * 32; + LPMediumBin := @MediumBlockBins[LBinNumber]; + {Get the first block in the bin} + LMediumBlock := LPMediumBin.NextFreeBlock; + {Remove the first block from the linked list (LIFO)} + LNextFreeBlock := LMediumBlock.NextFreeBlock; + LPMediumBin.NextFreeBlock := LNextFreeBlock; + LNextFreeBlock.PreviousFreeBlock := LPMediumBin; + {Is this bin now empty?} + if LNextFreeBlock = LPMediumBin then + begin + {Flag this bin as empty} + MediumBlockBinBitmaps[LBinGroupNumber] := MediumBlockBinBitmaps[LBinGroupNumber] + and (not (1 shl (LBinNumber and 31))); + {Is the group now entirely empty?} + if MediumBlockBinBitmaps[LBinGroupNumber] = 0 then + begin + {Flag this group as empty} + MediumBlockBinGroupBitmap := MediumBlockBinGroupBitmap + and (not (1 shl LBinGroupNumber)); + end; + end; + {Get the size of the available medium block} + LBlockSize := PNativeUInt(PByte(LMediumBlock) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask; + {$ifdef CheckHeapForCorruption} + {Check that this block is actually free and the next and previous blocks + are both in use.} + if ((PNativeUInt(PByte(LMediumBlock) - BlockHeaderSize)^ and ExtractMediumAndLargeFlagsMask) <> (IsMediumBlockFlag or IsFreeBlockFlag)) + or ((PNativeUInt(PByte(LMediumBlock) + (PNativeUInt(PByte(LMediumBlock) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask) - BlockHeaderSize)^ and IsFreeBlockFlag) <> 0) + then + begin + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} + end; + {$endif} + {Should the block be split?} + if LBlockSize >= MaximumSmallBlockPoolSize then + begin + {Get the size of the second split} + LSecondSplitSize := LBlockSize - LPSmallBlockType.OptimalBlockPoolSize; + {Adjust the block size} + LBlockSize := LPSmallBlockType.OptimalBlockPoolSize; + {Split the block in two} + LSecondSplit := PMediumFreeBlock(PByte(LMediumBlock) + LBlockSize); + PNativeUInt(PByte(LSecondSplit) - BlockHeaderSize)^ := LSecondSplitSize or (IsMediumBlockFlag or IsFreeBlockFlag); + {Store the size of the second split as the second last dword/qword} + PNativeUInt(PByte(LSecondSplit) + LSecondSplitSize - 2 * BlockHeaderSize)^ := LSecondSplitSize; + {Put the remainder in a bin (it will be big enough)} + InsertMediumBlockIntoBin(LSecondSplit, LSecondSplitSize); + end + else + begin + {Mark this block as used in the block following it} + LNextMediumBlockHeader := PNativeUInt(PByte(LMediumBlock) + LBlockSize - BlockHeaderSize); + LNextMediumBlockHeader^ := LNextMediumBlockHeader^ and (not PreviousMediumBlockIsFreeFlag); + end; + end + else + begin +{$endif} + {Check the sequential feed medium block pool for space} + LSequentialFeedFreeSize := MediumSequentialFeedBytesLeft; + if LSequentialFeedFreeSize >= LPSmallBlockType.MinimumBlockPoolSize then + begin + {Enough sequential feed space: Will the remainder be usable?} + if LSequentialFeedFreeSize >= (LPSmallBlockType.OptimalBlockPoolSize + MinimumMediumBlockSize) then + begin + LBlockSize := LPSmallBlockType.OptimalBlockPoolSize; + end + else + LBlockSize := LSequentialFeedFreeSize; + {Get the block} + LMediumBlock := Pointer(PByte(LastSequentiallyFedMediumBlock) - LBlockSize); + {Update the sequential feed parameters} + LastSequentiallyFedMediumBlock := LMediumBlock; + MediumSequentialFeedBytesLeft := LSequentialFeedFreeSize - LBlockSize; + end + else + begin + {Need to allocate a new sequential feed medium block pool: use the + optimal size for this small block pool} + LBlockSize := LPSmallBlockType.OptimalBlockPoolSize; + {Allocate the medium block pool} + LMediumBlock := AllocNewSequentialFeedMediumPool(LBlockSize); + if LMediumBlock = nil then + begin + {Out of memory} + {Unlock the medium blocks} + MediumBlocksLocked := False; + {Unlock the block type} + LPSmallBlockType.BlockTypeLocked := False; + {Failed} + Result := nil; + {done} + Exit; + end; + end; +{$ifndef FullDebugMode} + end; +{$endif} + {Mark this block as in use} + {Set the size and flags for this block} + PNativeUInt(PByte(LMediumBlock) - BlockHeaderSize)^ := LBlockSize or IsMediumBlockFlag or IsSmallBlockPoolInUseFlag; + {Unlock medium blocks} + MediumBlocksLocked := False; + {Set up the block pool} + LPSmallBlockPool := PSmallBlockPoolHeader(LMediumBlock); + LPSmallBlockPool.BlockType := LPSmallBlockType; + LPSmallBlockPool.FirstFreeBlock := nil; + LPSmallBlockPool.BlocksInUse := 1; + {Set it up for sequential block serving} + LPSmallBlockType.CurrentSequentialFeedPool := LPSmallBlockPool; + Result := Pointer(PByte(LPSmallBlockPool) + SmallBlockPoolHeaderSize); + LPSmallBlockType.NextSequentialFeedBlockAddress := Pointer(PByte(Result) + LPSmallBlockType.BlockSize); + LPSmallBlockType.MaxSequentialFeedBlockAddress := Pointer(PByte(LPSmallBlockPool) + LBlockSize - LPSmallBlockType.BlockSize); + end; +{$ifdef FullDebugMode} + {Clear the user area of the block} + DebugFillMem(Pointer(PByte(Result) + (SizeOf(TFullDebugBlockHeader) + SizeOf(NativeUInt)))^, + LPSmallBlockType.BlockSize - FullDebugBlockOverhead - SizeOf(NativeUInt), + {$ifndef CatchUseOfFreedInterfaces}DebugFillPattern{$else}NativeUInt(@VMTBadInterface){$endif}); + {Block was fed sequentially - we need to set a valid debug header. Use + the block address.} + PFullDebugBlockHeader(Result).HeaderCheckSum := NativeUInt(Result); + PNativeUInt(PByte(Result) + SizeOf(TFullDebugBlockHeader))^ := not NativeUInt(Result); +{$endif} + end; + {Unlock the block type} + LPSmallBlockType.BlockTypeLocked := False; + {Set the block header} + PNativeUInt(PByte(Result) - BlockHeaderSize)^ := UIntPtr(LPSmallBlockPool); + end + else + begin + {Medium block or Large block?} + if NativeUInt(ASize) <= (MaximumMediumBlockSize - BlockHeaderSize) then + begin + {------------------------Allocate a medium block--------------------------} + {Get the block size and bin number for this block size. Block sizes are + rounded up to the next bin size.} + LBlockSize := ((NativeUInt(ASize) + (MediumBlockGranularity - 1 + BlockHeaderSize - MediumBlockSizeOffset)) + and -MediumBlockGranularity) + MediumBlockSizeOffset; + {Get the bin number} + LBinNumber := (LBlockSize - MinimumMediumBlockSize) div MediumBlockGranularity; + {Lock the medium blocks} + LockMediumBlocks; + {Calculate the bin group} + LBinGroupNumber := LBinNumber div 32; + {Is there a suitable block inside this group?} + LBinGroupMasked := MediumBlockBinBitmaps[LBinGroupNumber] and -(1 shl (LBinNumber and 31)); + if LBinGroupMasked <> 0 then + begin + {Get the actual bin number} + LBinNumber := FindFirstSetBit(LBinGroupMasked) + LBinGroupNumber * 32; + end + else + begin +{$ifndef FullDebugMode} + {Try all groups greater than this group} + LBinGroupsMasked := MediumBlockBinGroupBitmap and -(2 shl LBinGroupNumber); + if LBinGroupsMasked <> 0 then + begin + {There is a suitable group with space: get the bin number} + LBinGroupNumber := FindFirstSetBit(LBinGroupsMasked); + {Get the bin in the group with free blocks} + LBinNumber := FindFirstSetBit(MediumBlockBinBitmaps[LBinGroupNumber]) + + LBinGroupNumber * 32; + end + else + begin +{$endif} + {There are no bins with a suitable block: Sequentially feed the required block} + LSequentialFeedFreeSize := MediumSequentialFeedBytesLeft; + if LSequentialFeedFreeSize >= LBlockSize then + begin +{$ifdef FullDebugMode} + {In full debug mode a medium block must have enough bytes to fit + all the debug info, so we must make sure there are no tiny medium + blocks at the start of the pool.} + if LSequentialFeedFreeSize - LBlockSize < (FullDebugBlockOverhead + BlockHeaderSize) then + LBlockSize := LSequentialFeedFreeSize; +{$endif} + {Block can be fed sequentially} + Result := Pointer(PByte(LastSequentiallyFedMediumBlock) - LBlockSize); + {Store the last sequentially fed block} + LastSequentiallyFedMediumBlock := Result; + {Store the remaining bytes} + MediumSequentialFeedBytesLeft := LSequentialFeedFreeSize - LBlockSize; + {Set the flags for the block} + PNativeUInt(PByte(Result) - BlockHeaderSize)^ := LBlockSize or IsMediumBlockFlag; + end + else + begin + {Need to allocate a new sequential feed block} + Result := AllocNewSequentialFeedMediumPool(LBlockSize); + end; +{$ifdef FullDebugMode} + {Block was fed sequentially - we need to set a valid debug header} + if Result <> nil then + begin + PFullDebugBlockHeader(Result).HeaderCheckSum := NativeUInt(Result); + PNativeUInt(PByte(Result) + SizeOf(TFullDebugBlockHeader))^ := not NativeUInt(Result); + {Clear the user area of the block} + DebugFillMem(Pointer(PByte(Result) + SizeOf(TFullDebugBlockHeader) + SizeOf(NativeUInt))^, + LBlockSize - FullDebugBlockOverhead - SizeOf(NativeUInt), + {$ifndef CatchUseOfFreedInterfaces}DebugFillPattern{$else}NativeUInt(@VMTBadInterface){$endif}); + end; +{$endif} + {Done} + MediumBlocksLocked := False; + Exit; +{$ifndef FullDebugMode} + end; +{$endif} + end; + {If we get here we have a valid LBinGroupNumber and LBinNumber: + Use the first block in the bin, splitting it if necessary} + {Get a pointer to the bin} + LPMediumBin := @MediumBlockBins[LBinNumber]; + {Get the result} + Result := LPMediumBin.NextFreeBlock; +{$ifdef CheckHeapForCorruption} + {Check that this block is actually free and the next and previous blocks + are both in use (except in full debug mode).} + if ((PNativeUInt(PByte(Result) - BlockHeaderSize)^ and {$ifndef FullDebugMode}ExtractMediumAndLargeFlagsMask{$else}(IsMediumBlockFlag or IsFreeBlockFlag){$endif}) <> (IsFreeBlockFlag or IsMediumBlockFlag)) + {$ifndef FullDebugMode} + or ((PNativeUInt(PByte(Result) + (PNativeUInt(PByte(Result) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask) - BlockHeaderSize)^ and (ExtractMediumAndLargeFlagsMask - IsSmallBlockPoolInUseFlag)) <> (IsMediumBlockFlag or PreviousMediumBlockIsFreeFlag)) + {$endif} + then + begin + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} + end; +{$endif} + {Remove the block from the bin containing it} + RemoveMediumFreeBlock(Result); + {Get the block size} + LAvailableBlockSize := PNativeUInt(PByte(Result) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask; +{$ifndef FullDebugMode} + {Is it an exact fit or not?} + LSecondSplitSize := LAvailableBlockSize - LBlockSize; + if LSecondSplitSize <> 0 then + begin + {Split the block in two} + LSecondSplit := PMediumFreeBlock(PByte(Result) + LBlockSize); + {Set the size of the second split} + PNativeUInt(PByte(LSecondSplit) - BlockHeaderSize)^ := LSecondSplitSize or (IsMediumBlockFlag or IsFreeBlockFlag); + {Store the size of the second split} + PNativeUInt(PByte(LSecondSplit) + LSecondSplitSize - 2 * BlockHeaderSize)^ := LSecondSplitSize; + {Put the remainder in a bin if it is big enough} + if LSecondSplitSize >= MinimumMediumBlockSize then + InsertMediumBlockIntoBin(LSecondSplit, LSecondSplitSize); + end + else + begin +{$else} + {In full debug mode blocks are never split or coalesced} + LBlockSize := LAvailableBlockSize; +{$endif} + {Mark this block as used in the block following it} + LNextMediumBlockHeader := Pointer(PByte(Result) + LBlockSize - BlockHeaderSize); +{$ifndef FullDebugMode} + {$ifdef CheckHeapForCorruption} + {The next block must be in use} + if (LNextMediumBlockHeader^ and (ExtractMediumAndLargeFlagsMask - IsSmallBlockPoolInUseFlag)) <> (IsMediumBlockFlag or PreviousMediumBlockIsFreeFlag) then + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} + {$endif} +{$endif} + LNextMediumBlockHeader^ := + LNextMediumBlockHeader^ and (not PreviousMediumBlockIsFreeFlag); +{$ifndef FullDebugMode} + end; + {Set the size and flags for this block} + PNativeUInt(PByte(Result) - BlockHeaderSize)^ := LBlockSize or IsMediumBlockFlag; +{$else} + {In full debug mode blocks are never split or coalesced} + Dec(PNativeUInt(PByte(Result) - BlockHeaderSize)^, IsFreeBlockFlag); +{$endif} + {Unlock the medium blocks} + MediumBlocksLocked := False; + end + else + begin + {Allocate a Large block} + if ASize > 0 then + Result := AllocateLargeBlock(ASize) + else + Result := nil; + end; + end; +end; +{$else} +{$ifdef 32Bit} +asm + {On entry: + eax = ASize} + {Since most allocations are for small blocks, determine the small block type + index so long} + lea edx, [eax + BlockHeaderSize - 1] +{$ifdef Align16Bytes} + shr edx, 4 +{$else} + shr edx, 3 +{$endif} + {Is it a small block?} + cmp eax, (MaximumSmallBlockSize - BlockHeaderSize) + {Save ebx} + push ebx + {Get the IsMultiThread variable so long} +{$ifndef AssumeMultiThreaded} + mov cl, IsMultiThread +{$endif} + {Is it a small block?} + ja @NotASmallBlock + {Do we need to lock the block type?} +{$ifndef AssumeMultiThreaded} + test cl, cl +{$endif} + {Get the small block type in ebx} + movzx eax, byte ptr [AllocSize2SmallBlockTypeIndX4 + edx] + lea ebx, [SmallBlockTypes + eax * 8] + {Do we need to lock the block type?} +{$ifndef AssumeMultiThreaded} + jnz @LockBlockTypeLoop +{$else} + jmp @LockBlockTypeLoop + {Align branch target} + nop + nop +{$endif} +@GotLockOnSmallBlockType: + {Find the next free block: Get the first pool with free blocks in edx} + mov edx, TSmallBlockType[ebx].NextPartiallyFreePool + {Get the first free block (or the next sequential feed address if edx = ebx)} + mov eax, TSmallBlockPoolHeader[edx].FirstFreeBlock + {Get the drop flags mask in ecx so long} + mov ecx, DropSmallFlagsMask + {Is there a pool with free blocks?} + cmp edx, ebx + je @TrySmallSequentialFeed + {Increment the number of used blocks} + add TSmallBlockPoolHeader[edx].BlocksInUse, 1 + {Get the new first free block} + and ecx, [eax - 4] + {Set the new first free block} + mov TSmallBlockPoolHeader[edx].FirstFreeBlock, ecx + {Set the block header} + mov [eax - 4], edx + {Is the chunk now full?} + jz @RemoveSmallPool + {Unlock the block type} + mov TSmallBlockType[ebx].BlockTypeLocked, False + {Restore ebx} + pop ebx + {All done} + ret + {Align branch target} +{$ifndef AssumeMultiThreaded} + nop + nop +{$endif} + nop +@TrySmallSequentialFeed: + {Try to feed a small block sequentially: Get the sequential feed block pool} + mov edx, TSmallBlockType[ebx].CurrentSequentialFeedPool + {Get the next sequential feed address so long} + movzx ecx, TSmallBlockType[ebx].BlockSize + add ecx, eax + {Can another block fit?} + cmp eax, TSmallBlockType[ebx].MaxSequentialFeedBlockAddress + ja @AllocateSmallBlockPool + {Increment the number of used blocks in the sequential feed pool} + add TSmallBlockPoolHeader[edx].BlocksInUse, 1 + {Store the next sequential feed block address} + mov TSmallBlockType[ebx].NextSequentialFeedBlockAddress, ecx + {Unlock the block type} + mov TSmallBlockType[ebx].BlockTypeLocked, False + {Set the block header} + mov [eax - 4], edx + {Restore ebx} + pop ebx + {All done} + ret + {Align branch target} + nop + nop + nop +@RemoveSmallPool: + {Pool is full - remove it from the partially free list} + mov ecx, TSmallBlockPoolHeader[edx].NextPartiallyFreePool + mov TSmallBlockPoolHeader[ecx].PreviousPartiallyFreePool, ebx + mov TSmallBlockType[ebx].NextPartiallyFreePool, ecx + {Unlock the block type} + mov TSmallBlockType[ebx].BlockTypeLocked, False + {Restore ebx} + pop ebx + {All done} + ret + {Align branch target} + nop + nop +@LockBlockTypeLoop: + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([ebx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Try the next size} + add ebx, Type(TSmallBlockType) + mov eax, $100 + lock cmpxchg TSmallBlockType([ebx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Try the next size (up to two sizes larger)} + add ebx, Type(TSmallBlockType) + mov eax, $100 + lock cmpxchg TSmallBlockType([ebx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Block type and two sizes larger are all locked - give up and sleep} + sub ebx, 2 * Type(TSmallBlockType) +{$ifdef NeverSleepOnThreadContention} + {Pause instruction (improves performance on P4)} + rep nop + {$ifdef UseSwitchToThread} + call SwitchToThread + {$endif} + {Try again} + jmp @LockBlockTypeLoop + {Align branch target} + nop + {$ifndef UseSwitchToThread} + nop + {$endif} +{$else} + {Couldn't grab the block type - sleep and try again} + push InitialSleepTime + call Sleep + {Try again} + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([ebx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Couldn't grab the block type - sleep and try again} + push AdditionalSleepTime + call Sleep + {Try again} + jmp @LockBlockTypeLoop + {Align branch target} + nop + nop + nop +{$endif} +@AllocateSmallBlockPool: + {save additional registers} + push esi + push edi + {Do we need to lock the medium blocks?} +{$ifndef AssumeMultiThreaded} + cmp IsMultiThread, False + je @MediumBlocksLockedForPool +{$endif} + call LockMediumBlocks +@MediumBlocksLockedForPool: + {Are there any available blocks of a suitable size?} + movsx esi, TSmallBlockType[ebx].AllowedGroupsForBlockPoolBitmap + and esi, MediumBlockBinGroupBitmap + jz @NoSuitableMediumBlocks + {Get the bin group number with free blocks in eax} + bsf eax, esi + {Get the bin number in ecx} + lea esi, [eax * 8] + mov ecx, dword ptr [MediumBlockBinBitmaps + eax * 4] + bsf ecx, ecx + lea ecx, [ecx + esi * 4] + {Get a pointer to the bin in edi} + lea edi, [MediumBlockBins + ecx * 8] + {Get the free block in esi} + mov esi, TMediumFreeBlock[edi].NextFreeBlock + {Remove the first block from the linked list (LIFO)} + mov edx, TMediumFreeBlock[esi].NextFreeBlock + mov TMediumFreeBlock[edi].NextFreeBlock, edx + mov TMediumFreeBlock[edx].PreviousFreeBlock, edi + {Is this bin now empty?} + cmp edi, edx + jne @MediumBinNotEmpty + {eax = bin group number, ecx = bin number, edi = @bin, esi = free block, ebx = block type} + {Flag this bin as empty} + mov edx, -2 + rol edx, cl + and dword ptr [MediumBlockBinBitmaps + eax * 4], edx + jnz @MediumBinNotEmpty + {Flag the group as empty} + btr MediumBlockBinGroupBitmap, eax +@MediumBinNotEmpty: + {esi = free block, ebx = block type} + {Get the size of the available medium block in edi} + mov edi, DropMediumAndLargeFlagsMask + and edi, [esi - 4] + cmp edi, MaximumSmallBlockPoolSize + jb @UseWholeBlock + {Split the block: get the size of the second part, new block size is the + optimal size} + mov edx, edi + movzx edi, TSmallBlockType[ebx].OptimalBlockPoolSize + sub edx, edi + {Split the block in two} + lea eax, [esi + edi] + lea ecx, [edx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [eax - 4], ecx + {Store the size of the second split as the second last dword} + mov [eax + edx - 8], edx + {Put the remainder in a bin (it will be big enough)} + call InsertMediumBlockIntoBin + jmp @GotMediumBlock + {Align branch target} +{$ifdef AssumeMultiThreaded} + nop +{$endif} +@NoSuitableMediumBlocks: + {Check the sequential feed medium block pool for space} + movzx ecx, TSmallBlockType[ebx].MinimumBlockPoolSize + mov edi, MediumSequentialFeedBytesLeft + cmp edi, ecx + jb @AllocateNewSequentialFeed + {Get the address of the last block that was fed} + mov esi, LastSequentiallyFedMediumBlock + {Enough sequential feed space: Will the remainder be usable?} + movzx ecx, TSmallBlockType[ebx].OptimalBlockPoolSize + lea edx, [ecx + MinimumMediumBlockSize] + cmp edi, edx + jb @NotMuchSpace + mov edi, ecx +@NotMuchSpace: + sub esi, edi + {Update the sequential feed parameters} + sub MediumSequentialFeedBytesLeft, edi + mov LastSequentiallyFedMediumBlock, esi + {Get the block pointer} + jmp @GotMediumBlock + {Align branch target} +@AllocateNewSequentialFeed: + {Need to allocate a new sequential feed medium block pool: use the + optimal size for this small block pool} + movzx eax, TSmallBlockType[ebx].OptimalBlockPoolSize + mov edi, eax + {Allocate the medium block pool} + call AllocNewSequentialFeedMediumPool + mov esi, eax + test eax, eax + jnz @GotMediumBlock + mov MediumBlocksLocked, al + mov TSmallBlockType[ebx].BlockTypeLocked, al + pop edi + pop esi + pop ebx + ret + {Align branch target} +@UseWholeBlock: + {esi = free block, ebx = block type, edi = block size} + {Mark this block as used in the block following it} + and byte ptr [esi + edi - 4], not PreviousMediumBlockIsFreeFlag +@GotMediumBlock: + {esi = free block, ebx = block type, edi = block size} + {Set the size and flags for this block} + lea ecx, [edi + IsMediumBlockFlag + IsSmallBlockPoolInUseFlag] + mov [esi - 4], ecx + {Unlock medium blocks} + xor eax, eax + mov MediumBlocksLocked, al + {Set up the block pool} + mov TSmallBlockPoolHeader[esi].BlockType, ebx + mov TSmallBlockPoolHeader[esi].FirstFreeBlock, eax + mov TSmallBlockPoolHeader[esi].BlocksInUse, 1 + {Set it up for sequential block serving} + mov TSmallBlockType[ebx].CurrentSequentialFeedPool, esi + {Return the pointer to the first block} + lea eax, [esi + SmallBlockPoolHeaderSize] + movzx ecx, TSmallBlockType[ebx].BlockSize + lea edx, [eax + ecx] + mov TSmallBlockType[ebx].NextSequentialFeedBlockAddress, edx + add edi, esi + sub edi, ecx + mov TSmallBlockType[ebx].MaxSequentialFeedBlockAddress, edi + {Unlock the small block type} + mov TSmallBlockType[ebx].BlockTypeLocked, False + {Set the small block header} + mov [eax - 4], esi + {Restore registers} + pop edi + pop esi + pop ebx + {Done} + ret +{-------------------Medium block allocation-------------------} + {Align branch target} + nop +@NotASmallBlock: + cmp eax, (MaximumMediumBlockSize - BlockHeaderSize) + ja @IsALargeBlockRequest + {Get the bin size for this block size. Block sizes are + rounded up to the next bin size.} + lea ebx, [eax + MediumBlockGranularity - 1 + BlockHeaderSize - MediumBlockSizeOffset] + and ebx, -MediumBlockGranularity + add ebx, MediumBlockSizeOffset + {Do we need to lock the medium blocks?} +{$ifndef AssumeMultiThreaded} + test cl, cl + jz @MediumBlocksLocked +{$endif} + call LockMediumBlocks +@MediumBlocksLocked: + {Get the bin number in ecx and the group number in edx} + lea edx, [ebx - MinimumMediumBlockSize] + mov ecx, edx + shr edx, 8 + 5 + shr ecx, 8 + {Is there a suitable block inside this group?} + mov eax, -1 + shl eax, cl + and eax, dword ptr [MediumBlockBinBitmaps + edx * 4] + jz @GroupIsEmpty + {Get the actual bin number} + and ecx, -32 + bsf eax, eax + or ecx, eax + jmp @GotBinAndGroup + {Align branch target} + nop +@GroupIsEmpty: + {Try all groups greater than this group} + mov eax, -2 + mov ecx, edx + shl eax, cl + and eax, MediumBlockBinGroupBitmap + jz @TrySequentialFeedMedium + {There is a suitable group with space: get the bin number} + bsf edx, eax + {Get the bin in the group with free blocks} + mov eax, dword ptr [MediumBlockBinBitmaps + edx * 4] + bsf ecx, eax + mov eax, edx + shl eax, 5 + or ecx, eax + jmp @GotBinAndGroup + {Align branch target} + nop +@TrySequentialFeedMedium: + mov ecx, MediumSequentialFeedBytesLeft + {Block can be fed sequentially?} + sub ecx, ebx + jc @AllocateNewSequentialFeedForMedium + {Get the block address} + mov eax, LastSequentiallyFedMediumBlock + sub eax, ebx + mov LastSequentiallyFedMediumBlock, eax + {Store the remaining bytes} + mov MediumSequentialFeedBytesLeft, ecx + {Set the flags for the block} + or ebx, IsMediumBlockFlag + mov [eax - 4], ebx + jmp @MediumBlockGetDone + {Align branch target} +@AllocateNewSequentialFeedForMedium: + mov eax, ebx + call AllocNewSequentialFeedMediumPool +@MediumBlockGetDone: + mov MediumBlocksLocked, False + pop ebx + ret + {Align branch target} +@GotBinAndGroup: + {ebx = block size, ecx = bin number, edx = group number} + push esi + push edi + {Get a pointer to the bin in edi} + lea edi, [MediumBlockBins + ecx * 8] + {Get the free block in esi} + mov esi, TMediumFreeBlock[edi].NextFreeBlock + {Remove the first block from the linked list (LIFO)} + mov eax, TMediumFreeBlock[esi].NextFreeBlock + mov TMediumFreeBlock[edi].NextFreeBlock, eax + mov TMediumFreeBlock[eax].PreviousFreeBlock, edi + {Is this bin now empty?} + cmp edi, eax + jne @MediumBinNotEmptyForMedium + {eax = bin group number, ecx = bin number, edi = @bin, esi = free block, ebx = block size} + {Flag this bin as empty} + mov eax, -2 + rol eax, cl + and dword ptr [MediumBlockBinBitmaps + edx * 4], eax + jnz @MediumBinNotEmptyForMedium + {Flag the group as empty} + btr MediumBlockBinGroupBitmap, edx +@MediumBinNotEmptyForMedium: + {esi = free block, ebx = block size} + {Get the size of the available medium block in edi} + mov edi, DropMediumAndLargeFlagsMask + and edi, [esi - 4] + {Get the size of the second split in edx} + mov edx, edi + sub edx, ebx + jz @UseWholeBlockForMedium + {Split the block in two} + lea eax, [esi + ebx] + lea ecx, [edx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [eax - 4], ecx + {Store the size of the second split as the second last dword} + mov [eax + edx - 8], edx + {Put the remainder in a bin} + cmp edx, MinimumMediumBlockSize + jb @GotMediumBlockForMedium + call InsertMediumBlockIntoBin + jmp @GotMediumBlockForMedium + {Align branch target} + nop + nop + nop +@UseWholeBlockForMedium: + {Mark this block as used in the block following it} + and byte ptr [esi + edi - 4], not PreviousMediumBlockIsFreeFlag +@GotMediumBlockForMedium: + {Set the size and flags for this block} + lea ecx, [ebx + IsMediumBlockFlag] + mov [esi - 4], ecx + {Unlock medium blocks} + mov MediumBlocksLocked, False + mov eax, esi + pop edi + pop esi + pop ebx + ret +{-------------------Large block allocation-------------------} + {Align branch target} +@IsALargeBlockRequest: + pop ebx + test eax, eax + jns AllocateLargeBlock + xor eax, eax +end; +{$else} +{64-bit BASM implementation} +asm + {On entry: + rcx = ASize} + .params 2 + .pushnv rbx + .pushnv rsi + .pushnv rdi + {Since most allocations are for small blocks, determine the small block type + index so long} + lea edx, [ecx + BlockHeaderSize - 1] +{$ifdef Align16Bytes} + shr edx, 4 +{$else} + shr edx, 3 +{$endif} + {Preload the addresses of some small block structures} + lea r8, AllocSize2SmallBlockTypeIndX4 + lea rbx, SmallBlockTypes +{$ifndef AssumeMultiThreaded} + {Get the IsMultiThread variable so long} + movzx esi, IsMultiThread +{$endif} + {Is it a small block?} + cmp rcx, (MaximumSmallBlockSize - BlockHeaderSize) + ja @NotASmallBlock + {Get the small block type pointer in rbx} + movzx ecx, byte ptr [r8 + rdx] + shl ecx, 4 //SizeOf(TSmallBlockType) = 64 + add rbx, rcx + {Do we need to lock the block type?} +{$ifndef AssumeMultiThreaded} + test esi, esi + jnz @LockBlockTypeLoop +{$else} + jmp @LockBlockTypeLoop +{$endif} +@GotLockOnSmallBlockType: + {Find the next free block: Get the first pool with free blocks in rdx} + mov rdx, TSmallBlockType[rbx].NextPartiallyFreePool + {Get the first free block (or the next sequential feed address if rdx = rbx)} + mov rax, TSmallBlockPoolHeader[rdx].FirstFreeBlock + {Get the drop flags mask in rcx so long} + mov rcx, DropSmallFlagsMask + {Is there a pool with free blocks?} + cmp rdx, rbx + je @TrySmallSequentialFeed + {Increment the number of used blocks} + add TSmallBlockPoolHeader[rdx].BlocksInUse, 1 + {Get the new first free block} + and rcx, [rax - BlockHeaderSize] + {Set the new first free block} + mov TSmallBlockPoolHeader[rdx].FirstFreeBlock, rcx + {Set the block header} + mov [rax - BlockHeaderSize], rdx + {Is the chunk now full?} + jz @RemoveSmallPool + {Unlock the block type} + mov TSmallBlockType[rbx].BlockTypeLocked, False + jmp @Done +@TrySmallSequentialFeed: + {Try to feed a small block sequentially: Get the sequential feed block pool} + mov rdx, TSmallBlockType[rbx].CurrentSequentialFeedPool + {Get the next sequential feed address so long} + movzx ecx, TSmallBlockType[rbx].BlockSize + add rcx, rax + {Can another block fit?} + cmp rax, TSmallBlockType[rbx].MaxSequentialFeedBlockAddress + ja @AllocateSmallBlockPool + {Increment the number of used blocks in the sequential feed pool} + add TSmallBlockPoolHeader[rdx].BlocksInUse, 1 + {Store the next sequential feed block address} + mov TSmallBlockType[rbx].NextSequentialFeedBlockAddress, rcx + {Unlock the block type} + mov TSmallBlockType[rbx].BlockTypeLocked, False + {Set the block header} + mov [rax - BlockHeaderSize], rdx + jmp @Done +@RemoveSmallPool: + {Pool is full - remove it from the partially free list} + mov rcx, TSmallBlockPoolHeader[rdx].NextPartiallyFreePool + mov TSmallBlockPoolHeader[rcx].PreviousPartiallyFreePool, rbx + mov TSmallBlockType[rbx].NextPartiallyFreePool, rcx + {Unlock the block type} + mov TSmallBlockType[rbx].BlockTypeLocked, False + jmp @Done +@LockBlockTypeLoop: + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([rbx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Try the next size} + add rbx, Type(TSmallBlockType) + mov eax, $100 + lock cmpxchg TSmallBlockType([rbx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Try the next size (up to two sizes larger)} + add rbx, Type(TSmallBlockType) + mov eax, $100 + lock cmpxchg TSmallBlockType([rbx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Block type and two sizes larger are all locked - give up and sleep} + sub rbx, 2 * Type(TSmallBlockType) +{$ifdef NeverSleepOnThreadContention} + {Pause instruction (improves performance on P4)} + pause + {$ifdef UseSwitchToThread} + call SwitchToThread + {$endif} + {Try again} + jmp @LockBlockTypeLoop +{$else} + {Couldn't grab the block type - sleep and try again} + mov ecx, InitialSleepTime + call Sleep + {Try again} + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([rbx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Couldn't grab the block type - sleep and try again} + mov ecx, AdditionalSleepTime + call Sleep + {Try again} + jmp @LockBlockTypeLoop +{$endif} +@AllocateSmallBlockPool: + {Do we need to lock the medium blocks?} +{$ifndef AssumeMultiThreaded} + test esi, esi + jz @MediumBlocksLockedForPool +{$endif} + call LockMediumBlocks +@MediumBlocksLockedForPool: + {Are there any available blocks of a suitable size?} + movsx esi, TSmallBlockType[rbx].AllowedGroupsForBlockPoolBitmap + and esi, MediumBlockBinGroupBitmap + jz @NoSuitableMediumBlocks + {Get the bin group number with free blocks in eax} + bsf eax, esi + {Get the bin number in ecx} + lea r8, MediumBlockBinBitmaps + lea r9, [rax * 4] + mov ecx, [r8 + r9] + bsf ecx, ecx + lea ecx, [ecx + r9d * 8] + {Get a pointer to the bin in edi} + lea rdi, MediumBlockBins + lea esi, [ecx * 8] + lea rdi, [rdi + rsi * 2] //SizeOf(TMediumBlockBin) = 16 + {Get the free block in rsi} + mov rsi, TMediumFreeBlock[rdi].NextFreeBlock + {Remove the first block from the linked list (LIFO)} + mov rdx, TMediumFreeBlock[rsi].NextFreeBlock + mov TMediumFreeBlock[rdi].NextFreeBlock, rdx + mov TMediumFreeBlock[rdx].PreviousFreeBlock, rdi + {Is this bin now empty?} + cmp rdi, rdx + jne @MediumBinNotEmpty + {r8 = @MediumBlockBinBitmaps, eax = bin group number, + r9 = bin group number * 4, ecx = bin number, edi = @bin, esi = free block, + ebx = block type} + {Flag this bin as empty} + mov edx, -2 + rol edx, cl + and [r8 + r9], edx + jnz @MediumBinNotEmpty + {Flag the group as empty} + btr MediumBlockBinGroupBitmap, eax +@MediumBinNotEmpty: + {esi = free block, ebx = block type} + {Get the size of the available medium block in edi} + mov rdi, DropMediumAndLargeFlagsMask + and rdi, [rsi - BlockHeaderSize] + cmp edi, MaximumSmallBlockPoolSize + jb @UseWholeBlock + {Split the block: get the size of the second part, new block size is the + optimal size} + mov edx, edi + movzx edi, TSmallBlockType[rbx].OptimalBlockPoolSize + sub edx, edi + {Split the block in two} + lea rcx, [rsi + rdi] + lea rax, [rdx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [rcx - BlockHeaderSize], rax + {Store the size of the second split as the second last qword} + mov [rcx + rdx - BlockHeaderSize * 2], rdx + {Put the remainder in a bin (it will be big enough)} + call InsertMediumBlockIntoBin + jmp @GotMediumBlock +@NoSuitableMediumBlocks: + {Check the sequential feed medium block pool for space} + movzx ecx, TSmallBlockType[rbx].MinimumBlockPoolSize + mov edi, MediumSequentialFeedBytesLeft + cmp edi, ecx + jb @AllocateNewSequentialFeed + {Get the address of the last block that was fed} + mov rsi, LastSequentiallyFedMediumBlock + {Enough sequential feed space: Will the remainder be usable?} + movzx ecx, TSmallBlockType[rbx].OptimalBlockPoolSize + lea edx, [ecx + MinimumMediumBlockSize] + cmp edi, edx + jb @NotMuchSpace + mov edi, ecx +@NotMuchSpace: + sub rsi, rdi + {Update the sequential feed parameters} + sub MediumSequentialFeedBytesLeft, edi + mov LastSequentiallyFedMediumBlock, rsi + {Get the block pointer} + jmp @GotMediumBlock + {Align branch target} +@AllocateNewSequentialFeed: + {Need to allocate a new sequential feed medium block pool: use the + optimal size for this small block pool} + movzx ecx, TSmallBlockType[rbx].OptimalBlockPoolSize + mov edi, ecx + {Allocate the medium block pool} + call AllocNewSequentialFeedMediumPool + mov rsi, rax + test rax, rax + jnz @GotMediumBlock + mov MediumBlocksLocked, al + mov TSmallBlockType[rbx].BlockTypeLocked, al + jmp @Done +@UseWholeBlock: + {rsi = free block, rbx = block type, edi = block size} + {Mark this block as used in the block following it} + and byte ptr [rsi + rdi - BlockHeaderSize], not PreviousMediumBlockIsFreeFlag +@GotMediumBlock: + {rsi = free block, rbx = block type, edi = block size} + {Set the size and flags for this block} + lea ecx, [edi + IsMediumBlockFlag + IsSmallBlockPoolInUseFlag] + mov [rsi - BlockHeaderSize], rcx + {Unlock medium blocks} + xor eax, eax + mov MediumBlocksLocked, al + {Set up the block pool} + mov TSmallBlockPoolHeader[rsi].BlockType, rbx + mov TSmallBlockPoolHeader[rsi].FirstFreeBlock, rax + mov TSmallBlockPoolHeader[rsi].BlocksInUse, 1 + {Set it up for sequential block serving} + mov TSmallBlockType[rbx].CurrentSequentialFeedPool, rsi + {Return the pointer to the first block} + lea rax, [rsi + SmallBlockPoolHeaderSize] + movzx ecx, TSmallBlockType[rbx].BlockSize + lea rdx, [rax + rcx] + mov TSmallBlockType[rbx].NextSequentialFeedBlockAddress, rdx + add rdi, rsi + sub rdi, rcx + mov TSmallBlockType[rbx].MaxSequentialFeedBlockAddress, rdi + {Unlock the small block type} + mov TSmallBlockType[rbx].BlockTypeLocked, False + {Set the small block header} + mov [rax - BlockHeaderSize], rsi + jmp @Done +{-------------------Medium block allocation-------------------} +@NotASmallBlock: + cmp rcx, (MaximumMediumBlockSize - BlockHeaderSize) + ja @IsALargeBlockRequest + {Get the bin size for this block size. Block sizes are + rounded up to the next bin size.} + lea ebx, [ecx + MediumBlockGranularity - 1 + BlockHeaderSize - MediumBlockSizeOffset] + and ebx, -MediumBlockGranularity + add ebx, MediumBlockSizeOffset + {Do we need to lock the medium blocks?} +{$ifndef AssumeMultiThreaded} + test esi, esi + jz @MediumBlocksLocked +{$endif} + call LockMediumBlocks +@MediumBlocksLocked: + {Get the bin number in ecx and the group number in edx} + lea edx, [ebx - MinimumMediumBlockSize] + mov ecx, edx + shr edx, 8 + 5 + shr ecx, 8 + {Is there a suitable block inside this group?} + mov eax, -1 + shl eax, cl + lea r8, MediumBlockBinBitmaps + and eax, [r8 + rdx * 4] + jz @GroupIsEmpty + {Get the actual bin number} + and ecx, -32 + bsf eax, eax + or ecx, eax + jmp @GotBinAndGroup +@GroupIsEmpty: + {Try all groups greater than this group} + mov eax, -2 + mov ecx, edx + shl eax, cl + and eax, MediumBlockBinGroupBitmap + jz @TrySequentialFeedMedium + {There is a suitable group with space: get the bin number} + bsf edx, eax + {Get the bin in the group with free blocks} + mov eax, [r8 + rdx * 4] + bsf ecx, eax + mov eax, edx + shl eax, 5 + or ecx, eax + jmp @GotBinAndGroup +@TrySequentialFeedMedium: + mov ecx, MediumSequentialFeedBytesLeft + {Block can be fed sequentially?} + sub ecx, ebx + jc @AllocateNewSequentialFeedForMedium + {Get the block address} + mov rax, LastSequentiallyFedMediumBlock + sub rax, rbx + mov LastSequentiallyFedMediumBlock, rax + {Store the remaining bytes} + mov MediumSequentialFeedBytesLeft, ecx + {Set the flags for the block} + or rbx, IsMediumBlockFlag + mov [rax - BlockHeaderSize], rbx + jmp @MediumBlockGetDone +@AllocateNewSequentialFeedForMedium: + mov ecx, ebx + call AllocNewSequentialFeedMediumPool +@MediumBlockGetDone: + xor cl, cl + mov MediumBlocksLocked, cl //workaround for QC99023 + jmp @Done +@GotBinAndGroup: + {ebx = block size, ecx = bin number, edx = group number} + {Get a pointer to the bin in edi} + lea rdi, MediumBlockBins + lea eax, [ecx + ecx] + lea rdi, [rdi + rax * 8] + {Get the free block in esi} + mov rsi, TMediumFreeBlock[rdi].NextFreeBlock + {Remove the first block from the linked list (LIFO)} + mov rax, TMediumFreeBlock[rsi].NextFreeBlock + mov TMediumFreeBlock[rdi].NextFreeBlock, rax + mov TMediumFreeBlock[rax].PreviousFreeBlock, rdi + {Is this bin now empty?} + cmp rdi, rax + jne @MediumBinNotEmptyForMedium + {edx = bin group number, ecx = bin number, rdi = @bin, rsi = free block, ebx = block size} + {Flag this bin as empty} + mov eax, -2 + rol eax, cl + lea r8, MediumBlockBinBitmaps + and [r8 + rdx * 4], eax + jnz @MediumBinNotEmptyForMedium + {Flag the group as empty} + btr MediumBlockBinGroupBitmap, edx +@MediumBinNotEmptyForMedium: + {rsi = free block, ebx = block size} + {Get the size of the available medium block in edi} + mov rdi, DropMediumAndLargeFlagsMask + and rdi, [rsi - BlockHeaderSize] + {Get the size of the second split in edx} + mov edx, edi + sub edx, ebx + jz @UseWholeBlockForMedium + {Split the block in two} + lea rcx, [rsi + rbx] + lea rax, [rdx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [rcx - BlockHeaderSize], rax + {Store the size of the second split as the second last dword} + mov [rcx + rdx - BlockHeaderSize * 2], rdx + {Put the remainder in a bin} + cmp edx, MinimumMediumBlockSize + jb @GotMediumBlockForMedium + call InsertMediumBlockIntoBin + jmp @GotMediumBlockForMedium +@UseWholeBlockForMedium: + {Mark this block as used in the block following it} + and byte ptr [rsi + rdi - BlockHeaderSize], not PreviousMediumBlockIsFreeFlag +@GotMediumBlockForMedium: + {Set the size and flags for this block} + lea rcx, [rbx + IsMediumBlockFlag] + mov [rsi - BlockHeaderSize], rcx + {Unlock medium blocks} + xor cl, cl + mov MediumBlocksLocked, cl //workaround for QC99023 + mov rax, rsi + jmp @Done +{-------------------Large block allocation-------------------} +@IsALargeBlockRequest: + xor rax, rax + test rcx, rcx + js @Done + call AllocateLargeBlock +@Done: +end; +{$endif} +{$endif} + +{$ifndef ASMVersion} +{Frees a medium block, returning 0 on success, -1 otherwise} +function FreeMediumBlock(APointer: Pointer): Integer; +var + LNextMediumBlock{$ifndef FullDebugMode}, LPreviousMediumBlock{$endif}: PMediumFreeBlock; + LNextMediumBlockSizeAndFlags: NativeUInt; + LBlockSize{$ifndef FullDebugMode}, LPreviousMediumBlockSize{$endif}: Cardinal; +{$ifndef FullDebugMode} + LPPreviousMediumBlockPoolHeader, LPNextMediumBlockPoolHeader: PMediumBlockPoolHeader; +{$endif} + LBlockHeader: NativeUInt; +begin + {Get the block header} + LBlockHeader := PNativeUInt(PByte(APointer) - BlockHeaderSize)^; + {Get the medium block size} + LBlockSize := LBlockHeader and DropMediumAndLargeFlagsMask; + {Lock the medium blocks} + LockMediumBlocks; + {Can we combine this block with the next free block?} + LNextMediumBlock := PMediumFreeBlock(PByte(APointer) + LBlockSize); + LNextMediumBlockSizeAndFlags := PNativeUInt(PByte(LNextMediumBlock) - BlockHeaderSize)^; +{$ifndef FullDebugMode} +{$ifdef CheckHeapForCorruption} + {Check that this block was flagged as in use in the next block} + if (LNextMediumBlockSizeAndFlags and PreviousMediumBlockIsFreeFlag) <> 0 then +{$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); +{$else} + System.RunError(reInvalidPtr); +{$endif} +{$endif} + if (LNextMediumBlockSizeAndFlags and IsFreeBlockFlag) <> 0 then + begin + {Increase the size of this block} + Inc(LBlockSize, LNextMediumBlockSizeAndFlags and DropMediumAndLargeFlagsMask); + {Remove the next block as well} + if LNextMediumBlockSizeAndFlags >= MinimumMediumBlockSize then + RemoveMediumFreeBlock(LNextMediumBlock); + end + else + begin +{$endif} + {Reset the "previous in use" flag of the next block} + PNativeUInt(PByte(LNextMediumBlock) - BlockHeaderSize)^ := LNextMediumBlockSizeAndFlags or PreviousMediumBlockIsFreeFlag; +{$ifndef FullDebugMode} + end; + {Can we combine this block with the previous free block? We need to + re-read the flags since it could have changed before we could lock the + medium blocks.} + if (PNativeUInt(PByte(APointer) - BlockHeaderSize)^ and PreviousMediumBlockIsFreeFlag) <> 0 then + begin + {Get the size of the free block just before this one} + LPreviousMediumBlockSize := PNativeUInt(PByte(APointer) - 2 * BlockHeaderSize)^; + {Get the start of the previous block} + LPreviousMediumBlock := PMediumFreeBlock(PByte(APointer) - LPreviousMediumBlockSize); +{$ifdef CheckHeapForCorruption} + {Check that the previous block is actually free} + if (PNativeUInt(PByte(LPreviousMediumBlock) - BlockHeaderSize)^ and ExtractMediumAndLargeFlagsMask) <> (IsMediumBlockFlag or IsFreeBlockFlag) then +{$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); +{$else} + System.RunError(reInvalidPtr); +{$endif} +{$endif} + {Set the new block size} + Inc(LBlockSize, LPreviousMediumBlockSize); + {This is the new current block} + APointer := LPreviousMediumBlock; + {Remove the previous block from the linked list} + if LPreviousMediumBlockSize >= MinimumMediumBlockSize then + RemoveMediumFreeBlock(LPreviousMediumBlock); + end; +{$ifdef CheckHeapForCorruption} + {Check that the previous block is currently flagged as in use} + if (PNativeUInt(PByte(APointer) - BlockHeaderSize)^ and PreviousMediumBlockIsFreeFlag) <> 0 then +{$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); +{$else} + System.RunError(reInvalidPtr); +{$endif} +{$endif} + {Is the entire medium block pool free, and there are other free blocks + that can fit the largest possible medium block? -> free it. (Except in + full debug mode where medium pools are never freed.)} + if (LBlockSize <> (MediumBlockPoolSize - MediumBlockPoolHeaderSize)) then + begin + {Store the size of the block as well as the flags} + PNativeUInt(PByte(APointer) - BlockHeaderSize)^ := LBlockSize or (IsMediumBlockFlag or IsFreeBlockFlag); +{$else} + {Mark the block as free} + Inc(PNativeUInt(PByte(APointer) - BlockHeaderSize)^, IsFreeBlockFlag); +{$endif} + {Store the trailing size marker} + PNativeUInt(PByte(APointer) + LBlockSize - 2 * BlockHeaderSize)^ := LBlockSize; + {Insert this block back into the bins: Size check not required here, + since medium blocks that are in use are not allowed to be + shrunk smaller than MinimumMediumBlockSize} + InsertMediumBlockIntoBin(APointer, LBlockSize); +{$ifndef FullDebugMode} +{$ifdef CheckHeapForCorruption} + {Check that this block is actually free and the next and previous blocks are both in use.} + if ((PNativeUInt(PByte(APointer) - BlockHeaderSize)^ and ExtractMediumAndLargeFlagsMask) <> (IsMediumBlockFlag or IsFreeBlockFlag)) + or ((PNativeUInt(PByte(APointer) + (PNativeUInt(PByte(APointer) - BlockHeaderSize)^ and DropMediumAndLargeFlagsMask) - BlockHeaderSize)^ and IsFreeBlockFlag) <> 0) then + begin +{$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); +{$else} + System.RunError(reInvalidPtr); +{$endif} + end; +{$endif} +{$endif} + {Unlock medium blocks} + MediumBlocksLocked := False; + {All OK} + Result := 0; +{$ifndef FullDebugMode} + end + else + begin + {Should this become the new sequential feed?} + if MediumSequentialFeedBytesLeft <> MediumBlockPoolSize - MediumBlockPoolHeaderSize then + begin + {Bin the current sequential feed} + BinMediumSequentialFeedRemainder; + {Set this medium pool up as the new sequential feed pool: + Store the sequential feed pool trailer} + PNativeUInt(PByte(APointer) + LBlockSize - BlockHeaderSize)^ := IsMediumBlockFlag; + {Store the number of bytes available in the sequential feed chunk} + MediumSequentialFeedBytesLeft := MediumBlockPoolSize - MediumBlockPoolHeaderSize; + {Set the last sequentially fed block} + LastSequentiallyFedMediumBlock := Pointer(PByte(APointer) + LBlockSize); + {Unlock medium blocks} + MediumBlocksLocked := False; + {Success} + Result := 0; + end + else + begin + {Remove this medium block pool from the linked list} + Dec(PByte(APointer), MediumBlockPoolHeaderSize); + LPPreviousMediumBlockPoolHeader := PMediumBlockPoolHeader(APointer).PreviousMediumBlockPoolHeader; + LPNextMediumBlockPoolHeader := PMediumBlockPoolHeader(APointer).NextMediumBlockPoolHeader; + LPPreviousMediumBlockPoolHeader.NextMediumBlockPoolHeader := LPNextMediumBlockPoolHeader; + LPNextMediumBlockPoolHeader.PreviousMediumBlockPoolHeader := LPPreviousMediumBlockPoolHeader; + {Unlock medium blocks} + MediumBlocksLocked := False; +{$ifdef ClearMediumBlockPoolsBeforeReturningToOS} + FillChar(APointer^, MediumBlockPoolSize, 0); +{$endif} + {Free the medium block pool} + if VirtualFree(APointer, 0, MEM_RELEASE) then + Result := 0 + else + Result := -1; + end; + end; +{$endif} +end; +{$endif} + +{Replacement for SysFreeMem} +function FastFreeMem(APointer: Pointer): Integer; +{$ifndef ASMVersion} +var + LPSmallBlockPool{$ifndef FullDebugMode}, LPPreviousPool, LPNextPool{$endif}, + LPOldFirstPool: PSmallBlockPoolHeader; + LPSmallBlockType: PSmallBlockType; + LOldFirstFreeBlock: Pointer; + LBlockHeader: NativeUInt; +begin + {Get the small block header: Is it actually a small block?} + LBlockHeader := PNativeUInt(PByte(APointer) - BlockHeaderSize)^; + {Is it a small block that is in use?} + if LBlockHeader and (IsFreeBlockFlag or IsMediumBlockFlag or IsLargeBlockFlag) = 0 then + begin + {Get a pointer to the block pool} + LPSmallBlockPool := PSmallBlockPoolHeader(LBlockHeader); + {Get the block type} + LPSmallBlockType := LPSmallBlockPool.BlockType; +{$ifdef ClearSmallAndMediumBlocksInFreeMem} + FillChar(APointer^, LPSmallBlockType.BlockSize - BlockHeaderSize, 0); +{$endif} + {Lock the block type} +{$ifndef AssumeMultiThreaded} + if IsMultiThread then +{$endif} + begin + while (LockCmpxchg(0, 1, @LPSmallBlockType.BlockTypeLocked) <> 0) do + begin +{$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} +{$else} + Sleep(InitialSleepTime); + if LockCmpxchg(0, 1, @LPSmallBlockType.BlockTypeLocked) = 0 then + Break; + Sleep(AdditionalSleepTime); +{$endif} + end; + end; + {Get the old first free block} + LOldFirstFreeBlock := LPSmallBlockPool.FirstFreeBlock; + {Was the pool manager previously full?} + if LOldFirstFreeBlock = nil then + begin + {Insert this as the first partially free pool for the block size} + LPOldFirstPool := LPSmallBlockType.NextPartiallyFreePool; + LPSmallBlockPool.NextPartiallyFreePool := LPOldFirstPool; + LPOldFirstPool.PreviousPartiallyFreePool := LPSmallBlockPool; + LPSmallBlockPool.PreviousPartiallyFreePool := PSmallBlockPoolHeader(LPSmallBlockType); + LPSmallBlockType.NextPartiallyFreePool := LPSmallBlockPool; + end; + {Store the old first free block} + PNativeUInt(PByte(APointer) - BlockHeaderSize)^ := UIntPtr(LOldFirstFreeBlock) or IsFreeBlockFlag; + {Store this as the new first free block} + LPSmallBlockPool.FirstFreeBlock := APointer; + {Decrement the number of allocated blocks} + Dec(LPSmallBlockPool.BlocksInUse); + {Small block pools are never freed in full debug mode. This increases the + likehood of success in catching objects still being used after being + destroyed.} +{$ifndef FullDebugMode} + {Is the entire pool now free? -> Free it.} + if LPSmallBlockPool.BlocksInUse = 0 then + begin + {Get the previous and next chunk managers} + LPPreviousPool := LPSmallBlockPool.PreviousPartiallyFreePool; + LPNextPool := LPSmallBlockPool.NextPartiallyFreePool; + {Remove this manager} + LPPreviousPool.NextPartiallyFreePool := LPNextPool; + LPNextPool.PreviousPartiallyFreePool := LPPreviousPool; + {Is this the sequential feed pool? If so, stop sequential feeding} + if (LPSmallBlockType.CurrentSequentialFeedPool = LPSmallBlockPool) then + LPSmallBlockType.MaxSequentialFeedBlockAddress := nil; + {Unlock this block type} + LPSmallBlockType.BlockTypeLocked := False; + {Free the block pool} + FreeMediumBlock(LPSmallBlockPool); + end + else + begin +{$endif} + {Unlock this block type} + LPSmallBlockType.BlockTypeLocked := False; +{$ifndef FullDebugMode} + end; +{$endif} + {No error} + Result := 0; + end + else + begin + {Is this a medium block or a large block?} + if LBlockHeader and (IsFreeBlockFlag or IsLargeBlockFlag) = 0 then + begin +{$ifdef ClearSmallAndMediumBlocksInFreeMem} + {Get the block header, extract the block size and clear the block it.} + LBlockHeader := PNativeUInt(PByte(APointer) - BlockHeaderSize)^; + FillChar(APointer^, + (LBlockHeader and DropMediumAndLargeFlagsMask) - BlockHeaderSize, 0); +{$endif} + Result := FreeMediumBlock(APointer); + end + else + begin + {Validate: Is this actually a Large block, or is it an attempt to free an + already freed small block?} + if LBlockHeader and (IsFreeBlockFlag or IsMediumBlockFlag) = 0 then + Result := FreeLargeBlock(APointer) + else + Result := -1; + end; + end; +end; +{$else} +{$ifdef 32Bit} +asm + {Get the block header in edx} + mov edx, [eax - 4] + {Is it a small block in use?} + test dl, IsFreeBlockFlag + IsMediumBlockFlag + IsLargeBlockFlag + {Save the pointer in ecx} + mov ecx, eax + {Save ebx} + push ebx + {Get the IsMultiThread variable in bl} +{$ifndef AssumeMultiThreaded} + mov bl, IsMultiThread +{$endif} + {Is it a small block that is in use?} + jnz @NotSmallBlockInUse +{$ifdef ClearSmallAndMediumBlocksInFreeMem} + push edx + push ecx + mov edx, TSmallBlockPoolHeader[edx].BlockType + movzx edx, TSmallBlockType(edx).BlockSize + sub edx, BlockHeaderSize + xor ecx, ecx + call System.@FillChar + pop ecx + pop edx +{$endif} + {Do we need to lock the block type?} +{$ifndef AssumeMultiThreaded} + test bl, bl +{$endif} + {Get the small block type in ebx} + mov ebx, TSmallBlockPoolHeader[edx].BlockType + {Do we need to lock the block type?} +{$ifndef AssumeMultiThreaded} + jnz @LockBlockTypeLoop +{$else} + jmp @LockBlockTypeLoop + {Align branch target} + nop +{$endif} +@GotLockOnSmallBlockType: + {Current state: edx = @SmallBlockPoolHeader, ecx = APointer, ebx = @SmallBlockType} + {Decrement the number of blocks in use} + sub TSmallBlockPoolHeader[edx].BlocksInUse, 1 + {Get the old first free block} + mov eax, TSmallBlockPoolHeader[edx].FirstFreeBlock + {Is the pool now empty?} + jz @PoolIsNowEmpty + {Was the pool full?} + test eax, eax + {Store this as the new first free block} + mov TSmallBlockPoolHeader[edx].FirstFreeBlock, ecx + {Store the previous first free block as the block header} + lea eax, [eax + IsFreeBlockFlag] + mov [ecx - 4], eax + {Insert the pool back into the linked list if it was full} + jz @SmallPoolWasFull + {All ok} + xor eax, eax + {Unlock the block type} + mov TSmallBlockType[ebx].BlockTypeLocked, al + {Restore registers} + pop ebx + {Done} + ret + {Align branch target} +{$ifndef AssumeMultiThreaded} + nop +{$endif} +@SmallPoolWasFull: + {Insert this as the first partially free pool for the block size} + mov ecx, TSmallBlockType[ebx].NextPartiallyFreePool + mov TSmallBlockPoolHeader[edx].PreviousPartiallyFreePool, ebx + mov TSmallBlockPoolHeader[edx].NextPartiallyFreePool, ecx + mov TSmallBlockPoolHeader[ecx].PreviousPartiallyFreePool, edx + mov TSmallBlockType[ebx].NextPartiallyFreePool, edx + {Unlock the block type} + mov TSmallBlockType[ebx].BlockTypeLocked, False + {All ok} + xor eax, eax + {Restore registers} + pop ebx + {Done} + ret + {Align branch target} + nop + nop +@PoolIsNowEmpty: + {Was this pool actually in the linked list of pools with space? If not, it + can only be the sequential feed pool (it is the only pool that may contain + only one block, i.e. other blocks have not been split off yet)} + test eax, eax + jz @IsSequentialFeedPool + {Pool is now empty: Remove it from the linked list and free it} + mov eax, TSmallBlockPoolHeader[edx].PreviousPartiallyFreePool + mov ecx, TSmallBlockPoolHeader[edx].NextPartiallyFreePool + {Remove this manager} + mov TSmallBlockPoolHeader[eax].NextPartiallyFreePool, ecx + mov TSmallBlockPoolHeader[ecx].PreviousPartiallyFreePool, eax + {Zero out eax} + xor eax, eax + {Is this the sequential feed pool? If so, stop sequential feeding} + cmp TSmallBlockType[ebx].CurrentSequentialFeedPool, edx + jne @NotSequentialFeedPool +@IsSequentialFeedPool: + mov TSmallBlockType[ebx].MaxSequentialFeedBlockAddress, eax +@NotSequentialFeedPool: + {Unlock the block type} + mov TSmallBlockType[ebx].BlockTypeLocked, al + {Release this pool} + mov eax, edx + mov edx, [edx - 4] +{$ifndef AssumeMultiThreaded} + mov bl, IsMultiThread +{$endif} + jmp @FreeMediumBlock + {Align branch target} +{$ifndef AssumeMultiThreaded} + nop + nop +{$endif} + nop +@LockBlockTypeLoop: + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([ebx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType +{$ifdef NeverSleepOnThreadContention} + {Pause instruction (improves performance on P4)} + rep nop + {$ifdef UseSwitchToThread} + push ecx + push edx + call SwitchToThread + pop edx + pop ecx + {$endif} + {Try again} + jmp @LockBlockTypeLoop + {Align branch target} + {$ifndef UseSwitchToThread} + nop + {$endif} +{$else} + {Couldn't grab the block type - sleep and try again} + push ecx + push edx + push InitialSleepTime + call Sleep + pop edx + pop ecx + {Try again} + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([ebx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Couldn't grab the block type - sleep and try again} + push ecx + push edx + push AdditionalSleepTime + call Sleep + pop edx + pop ecx + {Try again} + jmp @LockBlockTypeLoop + {Align branch target} + nop + nop +{$endif} + {---------------------Medium blocks------------------------------} + {Align branch target} +@NotSmallBlockInUse: + {Not a small block in use: is it a medium or large block?} + test dl, IsFreeBlockFlag + IsLargeBlockFlag + jnz @NotASmallOrMediumBlock +@FreeMediumBlock: +{$ifdef ClearSmallAndMediumBlocksInFreeMem} + push eax + push edx + and edx, DropMediumAndLargeFlagsMask + sub edx, BlockHeaderSize + xor ecx, ecx + call System.@FillChar + pop edx + pop eax +{$endif} + {Drop the flags} + and edx, DropMediumAndLargeFlagsMask + {Free the medium block pointed to by eax, header in edx, bl = IsMultiThread} +{$ifndef AssumeMultiThreaded} + {Do we need to lock the medium blocks?} + test bl, bl +{$endif} + {Block size in ebx} + mov ebx, edx + {Save registers} + push esi + {Pointer in esi} + mov esi, eax + {Do we need to lock the medium blocks?} +{$ifndef AssumeMultiThreaded} + jz @MediumBlocksLocked +{$endif} + call LockMediumBlocks +@MediumBlocksLocked: + {Can we combine this block with the next free block?} + test dword ptr [esi + ebx - 4], IsFreeBlockFlag + {Get the next block size and flags in ecx} + mov ecx, [esi + ebx - 4] + jnz @NextBlockIsFree + {Set the "PreviousIsFree" flag in the next block} + or ecx, PreviousMediumBlockIsFreeFlag + mov [esi + ebx - 4], ecx +@NextBlockChecked: + {Can we combine this block with the previous free block? We need to + re-read the flags since it could have changed before we could lock the + medium blocks.} + test byte ptr [esi - 4], PreviousMediumBlockIsFreeFlag + jnz @PreviousBlockIsFree +@PreviousBlockChecked: + {Is the entire medium block pool free, and there are other free blocks + that can fit the largest possible medium block -> free it.} + cmp ebx, (MediumBlockPoolSize - MediumBlockPoolHeaderSize) + je @EntireMediumPoolFree +@BinFreeMediumBlock: + {Store the size of the block as well as the flags} + lea eax, [ebx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [esi - 4], eax + {Store the trailing size marker} + mov [esi + ebx - 8], ebx + {Insert this block back into the bins: Size check not required here, + since medium blocks that are in use are not allowed to be + shrunk smaller than MinimumMediumBlockSize} + mov eax, esi + mov edx, ebx + {Insert into bin} + call InsertMediumBlockIntoBin + {Unlock medium blocks} + mov MediumBlocksLocked, False; + {All OK} + xor eax, eax + {Restore registers} + pop esi + pop ebx + {Return} + ret + {Align branch target} +@NextBlockIsFree: + {Get the next block address in eax} + lea eax, [esi + ebx] + {Increase the size of this block} + and ecx, DropMediumAndLargeFlagsMask + add ebx, ecx + {Was the block binned?} + cmp ecx, MinimumMediumBlockSize + jb @NextBlockChecked + call RemoveMediumFreeBlock + jmp @NextBlockChecked + {Align branch target} + nop +@PreviousBlockIsFree: + {Get the size of the free block just before this one} + mov ecx, [esi - 8] + {Include the previous block} + sub esi, ecx + {Set the new block size} + add ebx, ecx + {Remove the previous block from the linked list} + cmp ecx, MinimumMediumBlockSize + jb @PreviousBlockChecked + mov eax, esi + call RemoveMediumFreeBlock + jmp @PreviousBlockChecked + {Align branch target} +@EntireMediumPoolFree: + {Should we make this the new sequential feed medium block pool? If the + current sequential feed pool is not entirely free, we make this the new + sequential feed pool.} + cmp MediumSequentialFeedBytesLeft, MediumBlockPoolSize - MediumBlockPoolHeaderSize + jne @MakeEmptyMediumPoolSequentialFeed + {Point esi to the medium block pool header} + sub esi, MediumBlockPoolHeaderSize + {Remove this medium block pool from the linked list} + mov eax, TMediumBlockPoolHeader[esi].PreviousMediumBlockPoolHeader + mov edx, TMediumBlockPoolHeader[esi].NextMediumBlockPoolHeader + mov TMediumBlockPoolHeader[eax].NextMediumBlockPoolHeader, edx + mov TMediumBlockPoolHeader[edx].PreviousMediumBlockPoolHeader, eax + {Unlock medium blocks} + mov MediumBlocksLocked, False; +{$ifdef ClearMediumBlockPoolsBeforeReturningToOS} + mov eax, esi + mov edx, MediumBlockPoolSize + xor ecx, ecx + call System.@FillChar +{$endif} + {Free the medium block pool} + push MEM_RELEASE + push 0 + push esi + call VirtualFree + {VirtualFree returns >0 if all is ok} + cmp eax, 1 + {Return 0 on all ok} + sbb eax, eax + {Restore registers} + pop esi + pop ebx + ret + {Align branch target} + nop + nop + nop +@MakeEmptyMediumPoolSequentialFeed: + {Get a pointer to the end-marker block} + lea ebx, [esi + MediumBlockPoolSize - MediumBlockPoolHeaderSize] + {Bin the current sequential feed pool} + call BinMediumSequentialFeedRemainder + {Set this medium pool up as the new sequential feed pool: + Store the sequential feed pool trailer} + mov dword ptr [ebx - BlockHeaderSize], IsMediumBlockFlag + {Store the number of bytes available in the sequential feed chunk} + mov MediumSequentialFeedBytesLeft, MediumBlockPoolSize - MediumBlockPoolHeaderSize + {Set the last sequentially fed block} + mov LastSequentiallyFedMediumBlock, ebx + {Unlock medium blocks} + mov MediumBlocksLocked, False; + {Success} + xor eax, eax + {Restore registers} + pop esi + pop ebx + ret + {Align branch target} + nop + nop +@NotASmallOrMediumBlock: + {Restore ebx} + pop ebx + {Is it in fact a large block?} + test dl, IsFreeBlockFlag + IsMediumBlockFlag + jz FreeLargeBlock + {Attempt to free an already free block} + mov eax, -1 +end; + +{$else} + +{---------------64-bit BASM FastFreeMem---------------} +asm + .params 3 + .pushnv rbx + .pushnv rsi + {Get the block header in rdx} + mov rdx, [rcx - BlockHeaderSize] + {Is it a small block in use?} + test dl, IsFreeBlockFlag + IsMediumBlockFlag + IsLargeBlockFlag + {Get the IsMultiThread variable in bl} +{$ifndef AssumeMultiThreaded} + mov bl, IsMultiThread +{$endif} + {Is it a small block that is in use?} + jnz @NotSmallBlockInUse +{$ifdef ClearSmallAndMediumBlocksInFreeMem} + mov rsi, rcx + mov rdx, TSmallBlockPoolHeader[rdx].BlockType + movzx edx, TSmallBlockType(rdx).BlockSize + sub edx, BlockHeaderSize + xor r8, r8 + call System.@FillChar + mov rcx, rsi + mov rdx, [rcx - BlockHeaderSize] +{$endif} + {Do we need to lock the block type?} +{$ifndef AssumeMultiThreaded} + test bl, bl +{$endif} + {Get the small block type in rbx} + mov rbx, TSmallBlockPoolHeader[rdx].BlockType + {Do we need to lock the block type?} +{$ifndef AssumeMultiThreaded} + jnz @LockBlockTypeLoop +{$else} + jmp @LockBlockTypeLoop +{$endif} +@GotLockOnSmallBlockType: + {Current state: rdx = @SmallBlockPoolHeader, rcx = APointer, rbx = @SmallBlockType} + {Decrement the number of blocks in use} + sub TSmallBlockPoolHeader[rdx].BlocksInUse, 1 + {Get the old first free block} + mov rax, TSmallBlockPoolHeader[rdx].FirstFreeBlock + {Is the pool now empty?} + jz @PoolIsNowEmpty + {Was the pool full?} + test rax, rax + {Store this as the new first free block} + mov TSmallBlockPoolHeader[rdx].FirstFreeBlock, rcx + {Store the previous first free block as the block header} + lea rax, [rax + IsFreeBlockFlag] + mov [rcx - BlockHeaderSize], rax + {Insert the pool back into the linked list if it was full} + jz @SmallPoolWasFull + {All ok} + xor eax, eax + {Unlock the block type} + mov TSmallBlockType[rbx].BlockTypeLocked, al + jmp @Done +@SmallPoolWasFull: + {Insert this as the first partially free pool for the block size} + mov rcx, TSmallBlockType[rbx].NextPartiallyFreePool + mov TSmallBlockPoolHeader[rdx].PreviousPartiallyFreePool, rbx + mov TSmallBlockPoolHeader[rdx].NextPartiallyFreePool, rcx + mov TSmallBlockPoolHeader[rcx].PreviousPartiallyFreePool, rdx + mov TSmallBlockType[rbx].NextPartiallyFreePool, rdx + {Unlock the block type} + mov TSmallBlockType[rbx].BlockTypeLocked, False + {All ok} + xor eax, eax + jmp @Done +@PoolIsNowEmpty: + {Was this pool actually in the linked list of pools with space? If not, it + can only be the sequential feed pool (it is the only pool that may contain + only one block, i.e. other blocks have not been split off yet)} + test rax, rax + jz @IsSequentialFeedPool + {Pool is now empty: Remove it from the linked list and free it} + mov rax, TSmallBlockPoolHeader[rdx].PreviousPartiallyFreePool + mov rcx, TSmallBlockPoolHeader[rdx].NextPartiallyFreePool + {Remove this manager} + mov TSmallBlockPoolHeader[rax].NextPartiallyFreePool, rcx + mov TSmallBlockPoolHeader[rcx].PreviousPartiallyFreePool, rax + {Zero out eax} + xor rax, rax + {Is this the sequential feed pool? If so, stop sequential feeding} + cmp TSmallBlockType[rbx].CurrentSequentialFeedPool, rdx + jne @NotSequentialFeedPool +@IsSequentialFeedPool: + mov TSmallBlockType[rbx].MaxSequentialFeedBlockAddress, rax +@NotSequentialFeedPool: + {Unlock the block type} + mov TSmallBlockType[rbx].BlockTypeLocked, al + {Release this pool} + mov rcx, rdx + mov rdx, [rdx - BlockHeaderSize] +{$ifndef AssumeMultiThreaded} + mov bl, IsMultiThread +{$endif} + jmp @FreeMediumBlock +@LockBlockTypeLoop: + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([rbx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType +{$ifdef NeverSleepOnThreadContention} + {Pause instruction (improves performance on P4)} + pause + {$ifdef UseSwitchToThread} + mov rsi, rcx + call SwitchToThread + mov rcx, rsi + mov rdx, [rcx - BlockHeaderSize] + {$endif} + {Try again} + jmp @LockBlockTypeLoop +{$else} + {Couldn't grab the block type - sleep and try again} + mov rsi, rcx + mov ecx, InitialSleepTime + call Sleep + mov rcx, rsi + mov rdx, [rcx - BlockHeaderSize] + {Try again} + mov eax, $100 + {Attempt to grab the block type} + lock cmpxchg TSmallBlockType([rbx]).BlockTypeLocked, ah + je @GotLockOnSmallBlockType + {Couldn't grab the block type - sleep and try again} + mov rsi, rcx + mov ecx, AdditionalSleepTime + call Sleep + mov rcx, rsi + mov rdx, [rcx - BlockHeaderSize] + {Try again} + jmp @LockBlockTypeLoop +{$endif} + {---------------------Medium blocks------------------------------} +@NotSmallBlockInUse: + {Not a small block in use: is it a medium or large block?} + test dl, IsFreeBlockFlag + IsLargeBlockFlag + jnz @NotASmallOrMediumBlock +@FreeMediumBlock: +{$ifdef ClearSmallAndMediumBlocksInFreeMem} + mov rsi, rcx + and rdx, DropMediumAndLargeFlagsMask + sub rdx, BlockHeaderSize + xor r8, r8 + call System.@FillChar + mov rcx, rsi + mov rdx, [rcx - BlockHeaderSize] +{$endif} + {Drop the flags} + and rdx, DropMediumAndLargeFlagsMask + {Free the medium block pointed to by eax, header in edx, bl = IsMultiThread} +{$ifndef AssumeMultiThreaded} + {Do we need to lock the medium blocks?} + test bl, bl +{$endif} + {Block size in rbx} + mov rbx, rdx + {Pointer in rsi} + mov rsi, rcx + {Do we need to lock the medium blocks?} +{$ifndef AssumeMultiThreaded} + jz @MediumBlocksLocked +{$endif} + call LockMediumBlocks +@MediumBlocksLocked: + {Can we combine this block with the next free block?} + test qword ptr [rsi + rbx - BlockHeaderSize], IsFreeBlockFlag + {Get the next block size and flags in rcx} + mov rcx, [rsi + rbx - BlockHeaderSize] + jnz @NextBlockIsFree + {Set the "PreviousIsFree" flag in the next block} + or rcx, PreviousMediumBlockIsFreeFlag + mov [rsi + rbx - BlockHeaderSize], rcx +@NextBlockChecked: + {Can we combine this block with the previous free block? We need to + re-read the flags since it could have changed before we could lock the + medium blocks.} + test byte ptr [rsi - BlockHeaderSize], PreviousMediumBlockIsFreeFlag + jnz @PreviousBlockIsFree +@PreviousBlockChecked: + {Is the entire medium block pool free, and there are other free blocks + that can fit the largest possible medium block -> free it.} + cmp ebx, (MediumBlockPoolSize - MediumBlockPoolHeaderSize) + je @EntireMediumPoolFree +@BinFreeMediumBlock: + {Store the size of the block as well as the flags} + lea rax, [rbx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [rsi - BlockHeaderSize], rax + {Store the trailing size marker} + mov [rsi + rbx - 2 * BlockHeaderSize], rbx + {Insert this block back into the bins: Size check not required here, + since medium blocks that are in use are not allowed to be + shrunk smaller than MinimumMediumBlockSize} + mov rcx, rsi + mov rdx, rbx + {Insert into bin} + call InsertMediumBlockIntoBin + {All OK} + xor eax, eax + {Unlock medium blocks} + mov MediumBlocksLocked, al + jmp @Done +@NextBlockIsFree: + {Get the next block address in rax} + lea rax, [rsi + rbx] + {Increase the size of this block} + and rcx, DropMediumAndLargeFlagsMask + add rbx, rcx + {Was the block binned?} + cmp rcx, MinimumMediumBlockSize + jb @NextBlockChecked + mov rcx, rax + call RemoveMediumFreeBlock + jmp @NextBlockChecked +@PreviousBlockIsFree: + {Get the size of the free block just before this one} + mov rcx, [rsi - 2 * BlockHeaderSize] + {Include the previous block} + sub rsi, rcx + {Set the new block size} + add rbx, rcx + {Remove the previous block from the linked list} + cmp ecx, MinimumMediumBlockSize + jb @PreviousBlockChecked + mov rcx, rsi + call RemoveMediumFreeBlock + jmp @PreviousBlockChecked +@EntireMediumPoolFree: + {Should we make this the new sequential feed medium block pool? If the + current sequential feed pool is not entirely free, we make this the new + sequential feed pool.} + lea r8, MediumSequentialFeedBytesLeft + cmp dword ptr [r8], MediumBlockPoolSize - MediumBlockPoolHeaderSize //workaround for QC99023 + jne @MakeEmptyMediumPoolSequentialFeed + {Point esi to the medium block pool header} + sub rsi, MediumBlockPoolHeaderSize + {Remove this medium block pool from the linked list} + mov rax, TMediumBlockPoolHeader[rsi].PreviousMediumBlockPoolHeader + mov rdx, TMediumBlockPoolHeader[rsi].NextMediumBlockPoolHeader + mov TMediumBlockPoolHeader[rax].NextMediumBlockPoolHeader, rdx + mov TMediumBlockPoolHeader[rdx].PreviousMediumBlockPoolHeader, rax + {Unlock medium blocks} + xor eax, eax + mov MediumBlocksLocked, al +{$ifdef ClearMediumBlockPoolsBeforeReturningToOS} + mov rcx, rsi + mov edx, MediumBlockPoolSize + xor r8, r8 + call System.@FillChar +{$endif} + {Free the medium block pool} + mov rcx, rsi + xor edx, edx + mov r8d, MEM_RELEASE + call VirtualFree + {VirtualFree returns >0 if all is ok} + cmp eax, 1 + {Return 0 on all ok} + sbb eax, eax + jmp @Done +@MakeEmptyMediumPoolSequentialFeed: + {Get a pointer to the end-marker block} + lea rbx, [rsi + MediumBlockPoolSize - MediumBlockPoolHeaderSize] + {Bin the current sequential feed pool} + call BinMediumSequentialFeedRemainder + {Set this medium pool up as the new sequential feed pool: + Store the sequential feed pool trailer} + mov qword ptr [rbx - BlockHeaderSize], IsMediumBlockFlag + {Store the number of bytes available in the sequential feed chunk} + lea rax, MediumSequentialFeedBytesLeft + mov dword ptr [rax], MediumBlockPoolSize - MediumBlockPoolHeaderSize //QC99023 workaround + {Set the last sequentially fed block} + mov LastSequentiallyFedMediumBlock, rbx + {Success} + xor eax, eax + {Unlock medium blocks} + mov MediumBlocksLocked, al + jmp @Done +@NotASmallOrMediumBlock: + {Attempt to free an already free block?} + mov eax, -1 + {Is it in fact a large block?} + test dl, IsFreeBlockFlag + IsMediumBlockFlag + jnz @Done + call FreeLargeBlock +@Done: +end; +{$endif} +{$endif} + +{$ifndef FullDebugMode} +{Replacement for SysReallocMem} +function FastReallocMem(APointer: Pointer; ANewSize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +{$ifndef ASMVersion} +var + LBlockHeader, LNextBlockSizeAndFlags, LNewAllocSize, LBlockFlags, + LOldAvailableSize, LNextBlockSize, LNewAvailableSize, LMinimumUpsize, + LSecondSplitSize, LNewBlockSize: NativeUInt; + LPSmallBlockType: PSmallBlockType; + LPNextBlock, LPNextBlockHeader: Pointer; + + {Upsizes a large block in-place. The following variables are assumed correct: + LBlockFlags, LOldAvailableSize, LPNextBlock, LNextBlockSizeAndFlags, + LNextBlockSize, LNewAvailableSize. Medium blocks must be locked on entry if + required.} + procedure MediumBlockInPlaceUpsize; + begin + {Remove the next block} + if LNextBlockSizeAndFlags >= MinimumMediumBlockSize then + RemoveMediumFreeBlock(LPNextBlock); + {Add 25% for medium block in-place upsizes} + LMinimumUpsize := LOldAvailableSize + (LOldAvailableSize shr 2); + if NativeUInt(ANewSize) < LMinimumUpsize then + LNewAllocSize := LMinimumUpsize + else + LNewAllocSize := NativeUInt(ANewSize); + {Round up to the nearest block size granularity} + LNewBlockSize := ((LNewAllocSize + (BlockHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset)) + and -MediumBlockGranularity) + MediumBlockSizeOffset; + {Calculate the size of the second split} + LSecondSplitSize := LNewAvailableSize + BlockHeaderSize - LNewBlockSize; + {Does it fit?} + if NativeInt(LSecondSplitSize) <= 0 then + begin + {The block size is the full available size plus header} + LNewBlockSize := LNewAvailableSize + BlockHeaderSize; + {Grab the whole block: Mark it as used in the block following it} + LPNextBlockHeader := Pointer(PByte(APointer) + LNewAvailableSize); + PNativeUInt(LPNextBlockHeader)^ := + PNativeUInt(LPNextBlockHeader)^ and (not PreviousMediumBlockIsFreeFlag); + end + else + begin + {Split the block in two} + LPNextBlock := PMediumFreeBlock(PByte(APointer) + LNewBlockSize); + {Set the size of the second split} + PNativeUInt(PByte(LPNextBlock) - BlockHeaderSize)^ := LSecondSplitSize or (IsMediumBlockFlag or IsFreeBlockFlag); + {Store the size of the second split before the header of the next block} + PNativeUInt(PByte(LPNextBlock) + LSecondSplitSize - 2 * BlockHeaderSize)^ := LSecondSplitSize; + {Put the remainder in a bin if it is big enough} + if LSecondSplitSize >= MinimumMediumBlockSize then + InsertMediumBlockIntoBin(LPNextBlock, LSecondSplitSize); + end; + {Set the size and flags for this block} + PNativeUInt(PByte(APointer) - BlockHeaderSize)^ := LNewBlockSize or LBlockFlags; + end; + + {In-place downsize of a medium block. On entry Size must be less than half of + LOldAvailableSize.} + procedure MediumBlockInPlaceDownsize; + begin + {Round up to the next medium block size} + LNewBlockSize := ((ANewSize + (BlockHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset)) + and -MediumBlockGranularity) + MediumBlockSizeOffset; + {Get the size of the second split} + LSecondSplitSize := (LOldAvailableSize + BlockHeaderSize) - LNewBlockSize; + {Lock the medium blocks} + LockMediumBlocks; + {Set the new size} + PNativeUInt(PByte(APointer) - BlockHeaderSize)^ := + (PNativeUInt(PByte(APointer) - BlockHeaderSize)^ and ExtractMediumAndLargeFlagsMask) + or LNewBlockSize; + {Is the next block in use?} + LPNextBlock := PNativeUInt(PByte(APointer) + LOldAvailableSize + BlockHeaderSize); + LNextBlockSizeAndFlags := PNativeUInt(PByte(LPNextBlock) - BlockHeaderSize)^; + if LNextBlockSizeAndFlags and IsFreeBlockFlag = 0 then + begin + {The next block is in use: flag its previous block as free} + PNativeUInt(PByte(LPNextBlock) - BlockHeaderSize)^ := + LNextBlockSizeAndFlags or PreviousMediumBlockIsFreeFlag; + end + else + begin + {The next block is free: combine it} + LNextBlockSizeAndFlags := LNextBlockSizeAndFlags and DropMediumAndLargeFlagsMask; + Inc(LSecondSplitSize, LNextBlockSizeAndFlags); + if LNextBlockSizeAndFlags >= MinimumMediumBlockSize then + RemoveMediumFreeBlock(LPNextBlock); + end; + {Set the split} + LPNextBlock := PNativeUInt(PByte(APointer) + LNewBlockSize); + {Store the free part's header} + PNativeUInt(PByte(LPNextBlock) - BlockHeaderSize)^ := LSecondSplitSize or (IsMediumBlockFlag or IsFreeBlockFlag); + {Store the trailing size field} + PNativeUInt(PByte(LPNextBlock) + LSecondSplitSize - 2 * BlockHeaderSize)^ := LSecondSplitSize; + {Bin this free block} + if LSecondSplitSize >= MinimumMediumBlockSize then + InsertMediumBlockIntoBin(LPNextBlock, LSecondSplitSize); + {Unlock the medium blocks} + MediumBlocksLocked := False; + end; + +begin + {Get the block header: Is it actually a small block?} + LBlockHeader := PNativeUInt(PByte(APointer) - BlockHeaderSize)^; + {Is it a small block that is in use?} + if LBlockHeader and (IsFreeBlockFlag or IsMediumBlockFlag or IsLargeBlockFlag) = 0 then + begin + {-----------------------------------Small block-------------------------------------} + {The block header is a pointer to the block pool: Get the block type} + LPSmallBlockType := PSmallBlockPoolHeader(LBlockHeader).BlockType; + {Get the available size inside blocks of this type.} + LOldAvailableSize := LPSmallBlockType.BlockSize - BlockHeaderSize; + {Is it an upsize or a downsize?} + if LOldAvailableSize >= NativeUInt(ANewSize) then + begin + {It's a downsize. Do we need to allocate a smaller block? Only if the new + block size is less than a quarter of the available size less + SmallBlockDownsizeCheckAdder bytes} + if (NativeUInt(ANewSize) * 4 + SmallBlockDownsizeCheckAdder) >= LOldAvailableSize then + begin + {In-place downsize - return the pointer} + Result := APointer; + Exit; + end + else + begin + {Allocate a smaller block} + Result := FastGetMem(ANewSize); + {Allocated OK?} + if Result <> nil then + begin + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} + {$ifdef Align16Bytes} + MoveX16LP(APointer^, Result^, ANewSize); + {$else} + MoveX8LP(APointer^, Result^, ANewSize); + {$endif} +{$else} + System.Move(APointer^, Result^, ANewSize); +{$endif} + {Free the old pointer} + FastFreeMem(APointer); + end; + end; + end + else + begin + {This pointer is being reallocated to a larger block and therefore it is + logical to assume that it may be enlarged again. Since reallocations are + expensive, there is a minimum upsize percentage to avoid unnecessary + future move operations.} + {Must grow with at least 100% + x bytes} + LNewAllocSize := LOldAvailableSize * 2 + SmallBlockUpsizeAdder; + {Still not large enough?} + if LNewAllocSize < NativeUInt(ANewSize) then + LNewAllocSize := NativeUInt(ANewSize); + {Allocate the new block} + Result := FastGetMem(LNewAllocSize); + {Allocated OK?} + if Result <> nil then + begin + {Do we need to store the requested size? Only large blocks store the + requested size.} + if LNewAllocSize > (MaximumMediumBlockSize - BlockHeaderSize) then + PLargeBlockHeader(PByte(Result) - LargeBlockHeaderSize).UserAllocatedSize := ANewSize; + {Move the data across} +{$ifdef UseCustomFixedSizeMoveRoutines} + LPSmallBlockType.UpsizeMoveProcedure(APointer^, Result^, LOldAvailableSize); +{$else} + System.Move(APointer^, Result^, LOldAvailableSize); +{$endif} + {Free the old pointer} + FastFreeMem(APointer); + end; + end; + end + else + begin + {Is this a medium block or a large block?} + if LBlockHeader and (IsFreeBlockFlag or IsLargeBlockFlag) = 0 then + begin + {-------------------------------Medium block--------------------------------------} + {What is the available size in the block being reallocated?} + LOldAvailableSize := (LBlockHeader and DropMediumAndLargeFlagsMask); + {Get a pointer to the next block} + LPNextBlock := PNativeUInt(PByte(APointer) + LOldAvailableSize); + {Subtract the block header size from the old available size} + Dec(LOldAvailableSize, BlockHeaderSize); + {Is it an upsize or a downsize?} + if NativeUInt(ANewSize) > LOldAvailableSize then + begin + {Can we do an in-place upsize?} + LNextBlockSizeAndFlags := PNativeUInt(PByte(LPNextBlock) - BlockHeaderSize)^; + {Is the next block free?} + if LNextBlockSizeAndFlags and IsFreeBlockFlag <> 0 then + begin + LNextBlockSize := LNextBlockSizeAndFlags and DropMediumAndLargeFlagsMask; + {The available size including the next block} + LNewAvailableSize := LOldAvailableSize + LNextBlockSize; + {Can the block fit?} + if NativeUInt(ANewSize) <= LNewAvailableSize then + begin + {The next block is free and there is enough space to grow this + block in place.} +{$ifndef AssumeMultiThreaded} + if IsMultiThread then + begin +{$endif} + {Multi-threaded application - lock medium blocks and re-read the + information on the blocks.} + LockMediumBlocks; + {Re-read the info for this block} + LBlockFlags := PNativeUInt(PByte(APointer) - BlockHeaderSize)^ and ExtractMediumAndLargeFlagsMask; + {Re-read the info for the next block} + LNextBlockSizeAndFlags := PNativeUInt(PByte(LPNextBlock) - BlockHeaderSize)^; + {Recalculate the next block size} + LNextBlockSize := LNextBlockSizeAndFlags and DropMediumAndLargeFlagsMask; + {The available size including the next block} + LNewAvailableSize := LOldAvailableSize + LNextBlockSize; + {Is the next block still free and the size still sufficient?} + if (LNextBlockSizeAndFlags and IsFreeBlockFlag <> 0) + and (NativeUInt(ANewSize) <= LNewAvailableSize) then + begin + {Upsize the block in-place} + MediumBlockInPlaceUpsize; + {Unlock the medium blocks} + MediumBlocksLocked := False; + {Return the result} + Result := APointer; + {Done} + Exit; + end; + {Couldn't use the block: Unlock the medium blocks} + MediumBlocksLocked := False; +{$ifndef AssumeMultiThreaded} + end + else + begin + {Extract the block flags} + LBlockFlags := ExtractMediumAndLargeFlagsMask and LBlockHeader; + {Upsize the block in-place} + MediumBlockInPlaceUpsize; + {Return the result} + Result := APointer; + {Done} + Exit; + end; +{$endif} + end; + end; + {Couldn't upsize in place. Grab a new block and move the data across: + If we have to reallocate and move medium blocks, we grow by at + least 25%} + LMinimumUpsize := LOldAvailableSize + (LOldAvailableSize shr 2); + if NativeUInt(ANewSize) < LMinimumUpsize then + LNewAllocSize := LMinimumUpsize + else + LNewAllocSize := NativeUInt(ANewSize); + {Allocate the new block} + Result := FastGetMem(LNewAllocSize); + if Result <> nil then + begin + {If it's a large block - store the actual user requested size} + if LNewAllocSize > (MaximumMediumBlockSize - BlockHeaderSize) then + PLargeBlockHeader(PByte(Result) - LargeBlockHeaderSize).UserAllocatedSize := ANewSize; + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} + MoveX16LP(APointer^, Result^, LOldAvailableSize); +{$else} + System.Move(APointer^, Result^, LOldAvailableSize); +{$endif} + {Free the old block} + FastFreeMem(APointer); + end; + end + else + begin + {Must be less than half the current size or we don't bother resizing.} + if NativeUInt(ANewSize * 2) >= LOldAvailableSize then + begin + Result := APointer; + end + else + begin + {In-place downsize? Balance the cost of moving the data vs. the cost + of fragmenting the memory pool. Medium blocks in use may never be + smaller than MinimumMediumBlockSize.} + if NativeUInt(ANewSize) >= (MinimumMediumBlockSize - BlockHeaderSize) then + begin + MediumBlockInPlaceDownsize; + Result := APointer; + end + else + begin + {The requested size is less than the minimum medium block size. If + the requested size is less than the threshold value (currently a + quarter of the minimum medium block size), move the data to a small + block, otherwise shrink the medium block to the minimum allowable + medium block size.} + if NativeUInt(ANewSize) >= MediumInPlaceDownsizeLimit then + begin + {The request is for a size smaller than the minimum medium block + size, but not small enough to justify moving data: Reduce the + block size to the minimum medium block size} + ANewSize := MinimumMediumBlockSize - BlockHeaderSize; + {Is it already at the minimum medium block size?} + if LOldAvailableSize > NativeUInt(ANewSize) then + MediumBlockInPlaceDownsize; + Result := APointer; + end + else + begin + {Allocate the new block} + Result := FastGetMem(ANewSize); + if Result <> nil then + begin + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} + {$ifdef Align16Bytes} + MoveX16LP(APointer^, Result^, ANewSize); + {$else} + MoveX8LP(APointer^, Result^, ANewSize); + {$endif} +{$else} + System.Move(APointer^, Result^, ANewSize); +{$endif} + {Free the old block} + FastFreeMem(APointer); + end; + end; + end; + end; + end; + end + else + begin + {Is this a valid large block?} + if LBlockHeader and (IsFreeBlockFlag or IsMediumBlockFlag) = 0 then + begin + {-----------------------Large block------------------------------} + Result := ReallocateLargeBlock(APointer, ANewSize); + end + else + begin + {-----------------------Invalid block------------------------------} + {Bad pointer: probably an attempt to reallocate a free memory block.} + Result := nil; + end; + end; + end; +end; +{$else} +{$ifdef 32Bit} +asm + {On entry: eax = APointer; edx = ANewSize} + {Get the block header: Is it actually a small block?} + mov ecx, [eax - 4] + {Is it a small block?} + test cl, IsFreeBlockFlag + IsMediumBlockFlag + IsLargeBlockFlag + {Save ebx} + push ebx + {Save esi} + push esi + {Save the original pointer in esi} + mov esi, eax + {Is it a small block?} + jnz @NotASmallBlock + {-----------------------------------Small block-------------------------------------} + {Get the block type in ebx} + mov ebx, TSmallBlockPoolHeader[ecx].BlockType + {Get the available size inside blocks of this type.} + movzx ecx, TSmallBlockType[ebx].BlockSize + sub ecx, 4 + {Is it an upsize or a downsize?} + cmp ecx, edx + jb @SmallUpsize + {It's a downsize. Do we need to allocate a smaller block? Only if the new + size is less than a quarter of the available size less + SmallBlockDownsizeCheckAdder bytes} + lea ebx, [edx * 4 + SmallBlockDownsizeCheckAdder] + cmp ebx, ecx + jb @NotSmallInPlaceDownsize + {In-place downsize - return the original pointer} + pop esi + pop ebx + ret + {Align branch target} + nop +@NotSmallInPlaceDownsize: + {Save the requested size} + mov ebx, edx + {Allocate a smaller block} + mov eax, edx + call FastGetMem + {Allocated OK?} + test eax, eax + jz @SmallDownsizeDone + {Move data across: count in ecx} + mov ecx, ebx + {Destination in edx} + mov edx, eax + {Save the result in ebx} + mov ebx, eax + {Original pointer in eax} + mov eax, esi + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} + {$ifdef Align16Bytes} + call MoveX16LP + {$else} + call MoveX8LP + {$endif} +{$else} + call System.Move +{$endif} + {Free the original pointer} + mov eax, esi + call FastFreeMem + {Return the pointer} + mov eax, ebx +@SmallDownsizeDone: + pop esi + pop ebx + ret + {Align branch target} + nop + nop +@SmallUpsize: + {State: esi = APointer, edx = ANewSize, ecx = Current Block Size, ebx = Current Block Type} + {This pointer is being reallocated to a larger block and therefore it is + logical to assume that it may be enlarged again. Since reallocations are + expensive, there is a minimum upsize percentage to avoid unnecessary + future move operations.} + {Small blocks always grow with at least 100% + SmallBlockUpsizeAdder bytes} + lea ecx, [ecx + ecx + SmallBlockUpsizeAdder] + {save edi} + push edi + {Save the requested size in edi} + mov edi, edx + {New allocated size is the maximum of the requested size and the minimum + upsize} + xor eax, eax + sub ecx, edx + adc eax, -1 + and eax, ecx + add eax, edx + {Allocate the new block} + call FastGetMem + {Allocated OK?} + test eax, eax + jz @SmallUpsizeDone + {Do we need to store the requested size? Only large blocks store the + requested size.} + cmp edi, MaximumMediumBlockSize - BlockHeaderSize + jbe @NotSmallUpsizeToLargeBlock + {Store the user requested size} + mov [eax - 8], edi +@NotSmallUpsizeToLargeBlock: + {Get the size to move across} + movzx ecx, TSmallBlockType[ebx].BlockSize + sub ecx, BlockHeaderSize + {Move to the new block} + mov edx, eax + {Save the result in edi} + mov edi, eax + {Move from the old block} + mov eax, esi + {Move the data across} +{$ifdef UseCustomFixedSizeMoveRoutines} + call TSmallBlockType[ebx].UpsizeMoveProcedure +{$else} + call System.Move +{$endif} + {Free the old pointer} + mov eax, esi + call FastFreeMem + {Done} + mov eax, edi +@SmallUpsizeDone: + pop edi + pop esi + pop ebx + ret + {Align branch target} + nop +@NotASmallBlock: + {Is this a medium block or a large block?} + test cl, IsFreeBlockFlag + IsLargeBlockFlag + jnz @PossibleLargeBlock + {-------------------------------Medium block--------------------------------------} + {Status: ecx = Current Block Size + Flags, eax/esi = APointer, + edx = Requested Size} + mov ebx, ecx + {Drop the flags from the header} + and ecx, DropMediumAndLargeFlagsMask + {Save edi} + push edi + {Get a pointer to the next block in edi} + lea edi, [eax + ecx] + {Subtract the block header size from the old available size} + sub ecx, BlockHeaderSize + {Get the complete flags in ebx} + and ebx, ExtractMediumAndLargeFlagsMask + {Is it an upsize or a downsize?} + cmp edx, ecx + {Save ebp} + push ebp + {Is it an upsize or a downsize?} + ja @MediumBlockUpsize + {Status: ecx = Current Block Size - 4, bl = Current Block Flags, + edi = @Next Block, eax/esi = APointer, edx = Requested Size} + {Must be less than half the current size or we don't bother resizing.} + lea ebp, [edx + edx] + cmp ebp, ecx + jb @MediumMustDownsize +@MediumNoResize: + {Restore registers} + pop ebp + pop edi + pop esi + pop ebx + {Return} + ret + {Align branch target} + nop + nop + nop +@MediumMustDownsize: + {In-place downsize? Balance the cost of moving the data vs. the cost of + fragmenting the memory pool. Medium blocks in use may never be smaller + than MinimumMediumBlockSize.} + cmp edx, MinimumMediumBlockSize - BlockHeaderSize + jae @MediumBlockInPlaceDownsize + {The requested size is less than the minimum medium block size. If the + requested size is less than the threshold value (currently a quarter of the + minimum medium block size), move the data to a small block, otherwise shrink + the medium block to the minimum allowable medium block size.} + cmp edx, MediumInPlaceDownsizeLimit + jb @MediumDownsizeRealloc + {The request is for a size smaller than the minimum medium block size, but + not small enough to justify moving data: Reduce the block size to the + minimum medium block size} + mov edx, MinimumMediumBlockSize - BlockHeaderSize + {Is it already at the minimum medium block size?} + cmp ecx, edx + jna @MediumNoResize +@MediumBlockInPlaceDownsize: + {Round up to the next medium block size} + lea ebp, [edx + BlockHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset] + and ebp, -MediumBlockGranularity; + add ebp, MediumBlockSizeOffset + {Get the size of the second split} + add ecx, BlockHeaderSize + sub ecx, ebp + {Lock the medium blocks} +{$ifndef AssumeMultiThreaded} + cmp IsMultiThread, False + je @DoMediumInPlaceDownsize +{$endif} +@DoMediumLockForDownsize: + {Lock the medium blocks (ecx *must* be preserved)} + call LockMediumBlocks + {Reread the flags - they may have changed before medium blocks could be + locked.} + mov ebx, ExtractMediumAndLargeFlagsMask + and ebx, [esi - 4] +@DoMediumInPlaceDownsize: + {Set the new size} + or ebx, ebp + mov [esi - 4], ebx + {Get the second split size in ebx} + mov ebx, ecx + {Is the next block in use?} + mov edx, [edi - 4] + test dl, IsFreeBlockFlag + jnz @MediumDownsizeNextBlockFree + {The next block is in use: flag its previous block as free} + or edx, PreviousMediumBlockIsFreeFlag + mov [edi - 4], edx + jmp @MediumDownsizeDoSplit + {Align branch target} + nop + nop +{$ifdef AssumeMultiThreaded} + nop +{$endif} +@MediumDownsizeNextBlockFree: + {The next block is free: combine it} + mov eax, edi + and edx, DropMediumAndLargeFlagsMask + add ebx, edx + add edi, edx + cmp edx, MinimumMediumBlockSize + jb @MediumDownsizeDoSplit + call RemoveMediumFreeBlock +@MediumDownsizeDoSplit: + {Store the trailing size field} + mov [edi - 8], ebx + {Store the free part's header} + lea eax, [ebx + IsMediumBlockFlag + IsFreeBlockFlag]; + mov [esi + ebp - 4], eax + {Bin this free block} + cmp ebx, MinimumMediumBlockSize + jb @MediumBlockDownsizeDone + lea eax, [esi + ebp] + mov edx, ebx + call InsertMediumBlockIntoBin +@MediumBlockDownsizeDone: + {Unlock the medium blocks} + mov MediumBlocksLocked, False + {Result = old pointer} + mov eax, esi + {Restore registers} + pop ebp + pop edi + pop esi + pop ebx + {Return} + ret + {Align branch target} +@MediumDownsizeRealloc: + {Save the requested size} + mov edi, edx + mov eax, edx + {Allocate the new block} + call FastGetMem + test eax, eax + jz @MediumBlockDownsizeExit + {Save the result} + mov ebp, eax + mov edx, eax + mov eax, esi + mov ecx, edi + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} + {$ifdef Align16Bytes} + call MoveX16LP + {$else} + call MoveX8LP + {$endif} +{$else} + call System.Move +{$endif} + mov eax, esi + call FastFreeMem + {Return the result} + mov eax, ebp +@MediumBlockDownsizeExit: + pop ebp + pop edi + pop esi + pop ebx + ret + {Align branch target} +@MediumBlockUpsize: + {Status: ecx = Current Block Size - 4, bl = Current Block Flags, + edi = @Next Block, eax/esi = APointer, edx = Requested Size} + {Can we do an in-place upsize?} + mov eax, [edi - 4] + test al, IsFreeBlockFlag + jz @CannotUpsizeMediumBlockInPlace + {Get the total available size including the next block} + and eax, DropMediumAndLargeFlagsMask + {ebp = total available size including the next block (excluding the header)} + lea ebp, [eax + ecx] + {Can the block fit?} + cmp edx, ebp + ja @CannotUpsizeMediumBlockInPlace + {The next block is free and there is enough space to grow this + block in place.} +{$ifndef AssumeMultiThreaded} + cmp IsMultiThread, False + je @DoMediumInPlaceUpsize +{$endif} +@DoMediumLockForUpsize: + {Lock the medium blocks (ecx and edx *must* be preserved} + call LockMediumBlocks + {Re-read the info for this block (since it may have changed before the medium + blocks could be locked)} + mov ebx, ExtractMediumAndLargeFlagsMask + and ebx, [esi - 4] + {Re-read the info for the next block} + mov eax, [edi - 4] + {Next block still free?} + test al, IsFreeBlockFlag + jz @NextMediumBlockChanged + {Recalculate the next block size} + and eax, DropMediumAndLargeFlagsMask + {The available size including the next block} + lea ebp, [eax + ecx] + {Can the block still fit?} + cmp edx, ebp + ja @NextMediumBlockChanged +@DoMediumInPlaceUpsize: + {Is the next block binnable?} + cmp eax, MinimumMediumBlockSize + {Remove the next block} + jb @MediumInPlaceNoNextRemove + mov eax, edi + push ecx + push edx + call RemoveMediumFreeBlock + pop edx + pop ecx +@MediumInPlaceNoNextRemove: + {Medium blocks grow a minimum of 25% in in-place upsizes} + mov eax, ecx + shr eax, 2 + add eax, ecx + {Get the maximum of the requested size and the minimum growth size} + xor edi, edi + sub eax, edx + adc edi, -1 + and eax, edi + {Round up to the nearest block size granularity} + lea eax, [eax + edx + BlockHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset] + and eax, -MediumBlockGranularity + add eax, MediumBlockSizeOffset + {Calculate the size of the second split} + lea edx, [ebp + BlockHeaderSize] + sub edx, eax + {Does it fit?} + ja @MediumInPlaceUpsizeSplit + {Grab the whole block: Mark it as used in the block following it} + and dword ptr [esi + ebp], not PreviousMediumBlockIsFreeFlag + {The block size is the full available size plus header} + add ebp, 4 + {Upsize done} + jmp @MediumUpsizeInPlaceDone + {Align branch target} +{$ifndef AssumeMultiThreaded} + nop + nop + nop +{$endif} +@MediumInPlaceUpsizeSplit: + {Store the size of the second split as the second last dword} + mov [esi + ebp - 4], edx + {Set the second split header} + lea edi, [edx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [esi + eax - 4], edi + mov ebp, eax + cmp edx, MinimumMediumBlockSize + jb @MediumUpsizeInPlaceDone + add eax, esi + call InsertMediumBlockIntoBin +@MediumUpsizeInPlaceDone: + {Set the size and flags for this block} + or ebp, ebx + mov [esi - 4], ebp + {Unlock the medium blocks} + mov MediumBlocksLocked, False + {Result = old pointer} + mov eax, esi +@MediumBlockResizeDone2: + {Restore registers} + pop ebp + pop edi + pop esi + pop ebx + {Return} + ret + {Align branch target for "@CannotUpsizeMediumBlockInPlace"} + nop + nop +@NextMediumBlockChanged: + {The next medium block changed while the medium blocks were being locked} + mov MediumBlocksLocked, False +@CannotUpsizeMediumBlockInPlace: + {Couldn't upsize in place. Grab a new block and move the data across: + If we have to reallocate and move medium blocks, we grow by at + least 25%} + mov eax, ecx + shr eax, 2 + add eax, ecx + {Get the maximum of the requested size and the minimum growth size} + xor edi, edi + sub eax, edx + adc edi, -1 + and eax, edi + add eax, edx + {Save the size to allocate} + mov ebp, eax + {Save the size to move across} + mov edi, ecx + {Get the block} + push edx + call FastGetMem + pop edx + {Success?} + test eax, eax + jz @MediumBlockResizeDone2 + {If it's a Large block - store the actual user requested size} + cmp ebp, MaximumMediumBlockSize - BlockHeaderSize + jbe @MediumUpsizeNotLarge + mov [eax - 8], edx +@MediumUpsizeNotLarge: + {Save the result} + mov ebp, eax + {Move the data across} + mov edx, eax + mov eax, esi + mov ecx, edi +{$ifdef UseCustomVariableSizeMoveRoutines} + call MoveX16LP +{$else} + call System.Move +{$endif} + {Free the old block} + mov eax, esi + call FastFreeMem + {Restore the result} + mov eax, ebp + {Restore registers} + pop ebp + pop edi + pop esi + pop ebx + {Return} + ret + {Align branch target} + nop +@PossibleLargeBlock: + {-----------------------Large block------------------------------} + {Restore registers} + pop esi + pop ebx + {Is this a valid large block?} + test cl, IsFreeBlockFlag + IsMediumBlockFlag + jz ReallocateLargeBlock + {-----------------------Invalid block------------------------------} + xor eax, eax +end; + +{$else} + +{-----------------64-bit BASM FastReallocMem-----------------} +asm + .params 3 + .pushnv rbx + .pushnv rsi + .pushnv rdi + .pushnv r14 + .pushnv r15 + {On entry: rcx = APointer; rdx = ANewSize} + {Save the original pointer in rsi} + mov rsi, rcx + {Get the block header} + mov rcx, [rcx - BlockHeaderSize] + {Is it a small block?} + test cl, IsFreeBlockFlag + IsMediumBlockFlag + IsLargeBlockFlag + jnz @NotASmallBlock + {-----------------------------------Small block-------------------------------------} + {Get the block type in rbx} + mov rbx, TSmallBlockPoolHeader[rcx].BlockType + {Get the available size inside blocks of this type.} + movzx ecx, TSmallBlockType[rbx].BlockSize + sub ecx, BlockHeaderSize + {Is it an upsize or a downsize?} + cmp rcx, rdx + jb @SmallUpsize + {It's a downsize. Do we need to allocate a smaller block? Only if the new + size is less than a quarter of the available size less + SmallBlockDownsizeCheckAdder bytes} + lea ebx, [edx * 4 + SmallBlockDownsizeCheckAdder] + cmp ebx, ecx + jb @NotSmallInPlaceDownsize + {In-place downsize - return the original pointer} + mov rax, rsi + jmp @Done +@NotSmallInPlaceDownsize: + {Save the requested size} + mov rbx, rdx + {Allocate a smaller block} + mov rcx, rdx + call FastGetMem + {Allocated OK?} + test rax, rax + jz @Done + {Move data across: count in r8} + mov r8, rbx + {Destination in edx} + mov rdx, rax + {Save the result in ebx} + mov rbx, rax + {Original pointer in ecx} + mov rcx, rsi + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} + {$ifdef Align16Bytes} + call MoveX16LP + {$else} + call MoveX8LP + {$endif} +{$else} + call System.Move +{$endif} + {Free the original pointer} + mov rcx, rsi + call FastFreeMem + {Return the pointer} + mov rax, rbx + jmp @Done +@SmallUpsize: + {State: rsi = APointer, rdx = ANewSize, rcx = Current Block Size, rbx = Current Block Type} + {This pointer is being reallocated to a larger block and therefore it is + logical to assume that it may be enlarged again. Since reallocations are + expensive, there is a minimum upsize percentage to avoid unnecessary + future move operations.} + {Small blocks always grow with at least 100% + SmallBlockUpsizeAdder bytes} + lea ecx, [ecx + ecx + SmallBlockUpsizeAdder] + {Save the requested size in rdi} + mov rdi, rdx + {New allocated size is the maximum of the requested size and the minimum + upsize} + xor rax, rax + sub rcx, rdx + adc rax, -1 + and rcx, rax + add rcx, rdx + {Allocate the new block} + call FastGetMem + {Allocated OK?} + test rax, rax + jz @Done + {Do we need to store the requested size? Only large blocks store the + requested size.} + cmp rdi, MaximumMediumBlockSize - BlockHeaderSize + jbe @NotSmallUpsizeToLargeBlock + {Store the user requested size} + mov [rax - 2 * BlockHeaderSize], rdi +@NotSmallUpsizeToLargeBlock: + {Get the size to move across} + movzx r8d, TSmallBlockType[rbx].BlockSize + sub r8d, BlockHeaderSize + {Move to the new block} + mov rdx, rax + {Save the result in edi} + mov rdi, rax + {Move from the old block} + mov rcx, rsi + {Move the data across} +{$ifdef UseCustomFixedSizeMoveRoutines} + call TSmallBlockType[rbx].UpsizeMoveProcedure +{$else} + call System.Move +{$endif} + {Free the old pointer} + mov rcx, rsi + call FastFreeMem + {Done} + mov rax, rdi + jmp @Done +@NotASmallBlock: + {Is this a medium block or a large block?} + test cl, IsFreeBlockFlag + IsLargeBlockFlag + jnz @PossibleLargeBlock + {-------------------------------Medium block--------------------------------------} + {Status: rcx = Current Block Size + Flags, rsi = APointer, + rdx = Requested Size} + mov rbx, rcx + {Drop the flags from the header} + and ecx, DropMediumAndLargeFlagsMask + {Get a pointer to the next block in rdi} + lea rdi, [rsi + rcx] + {Subtract the block header size from the old available size} + sub ecx, BlockHeaderSize + {Get the complete flags in ebx} + and ebx, ExtractMediumAndLargeFlagsMask + {Is it an upsize or a downsize?} + cmp rdx, rcx + ja @MediumBlockUpsize + {Status: ecx = Current Block Size - BlockHeaderSize, bl = Current Block Flags, + rdi = @Next Block, rsi = APointer, rdx = Requested Size} + {Must be less than half the current size or we don't bother resizing.} + lea r15, [rdx + rdx] + cmp r15, rcx + jb @MediumMustDownsize +@MediumNoResize: + mov rax, rsi + jmp @Done +@MediumMustDownsize: + {In-place downsize? Balance the cost of moving the data vs. the cost of + fragmenting the memory pool. Medium blocks in use may never be smaller + than MinimumMediumBlockSize.} + cmp edx, MinimumMediumBlockSize - BlockHeaderSize + jae @MediumBlockInPlaceDownsize + {The requested size is less than the minimum medium block size. If the + requested size is less than the threshold value (currently a quarter of the + minimum medium block size), move the data to a small block, otherwise shrink + the medium block to the minimum allowable medium block size.} + cmp edx, MediumInPlaceDownsizeLimit + jb @MediumDownsizeRealloc + {The request is for a size smaller than the minimum medium block size, but + not small enough to justify moving data: Reduce the block size to the + minimum medium block size} + mov edx, MinimumMediumBlockSize - BlockHeaderSize + {Is it already at the minimum medium block size?} + cmp ecx, edx + jna @MediumNoResize +@MediumBlockInPlaceDownsize: + {Round up to the next medium block size} + lea r15, [rdx + BlockHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset] + and r15, -MediumBlockGranularity + add r15, MediumBlockSizeOffset + {Get the size of the second split} + add ecx, BlockHeaderSize + sub ecx, r15d + {Lock the medium blocks} +{$ifndef AssumeMultiThreaded} + lea r8, IsMultiThread + cmp byte ptr [r8], False + je @DoMediumInPlaceDownsize +{$endif} +@DoMediumLockForDownsize: + {Lock the medium blocks} + mov ebx, ecx + call LockMediumBlocks + mov ecx, ebx + {Reread the flags - they may have changed before medium blocks could be + locked.} + mov rbx, ExtractMediumAndLargeFlagsMask + and rbx, [rsi - BlockHeaderSize] +@DoMediumInPlaceDownsize: + {Set the new size} + or rbx, r15 + mov [rsi - BlockHeaderSize], rbx + {Get the second split size in ebx} + mov ebx, ecx + {Is the next block in use?} + mov rdx, [rdi - BlockHeaderSize] + test dl, IsFreeBlockFlag + jnz @MediumDownsizeNextBlockFree + {The next block is in use: flag its previous block as free} + or rdx, PreviousMediumBlockIsFreeFlag + mov [rdi - BlockHeaderSize], rdx + jmp @MediumDownsizeDoSplit +@MediumDownsizeNextBlockFree: + {The next block is free: combine it} + mov rcx, rdi + and rdx, DropMediumAndLargeFlagsMask + add rbx, rdx + add rdi, rdx + cmp edx, MinimumMediumBlockSize + jb @MediumDownsizeDoSplit + call RemoveMediumFreeBlock +@MediumDownsizeDoSplit: + {Store the trailing size field} + mov [rdi - 2 * BlockHeaderSize], rbx + {Store the free part's header} + lea rcx, [rbx + IsMediumBlockFlag + IsFreeBlockFlag]; + mov [rsi + r15 - BlockHeaderSize], rcx + {Bin this free block} + cmp rbx, MinimumMediumBlockSize + jb @MediumBlockDownsizeDone + lea rcx, [rsi + r15] + mov rdx, rbx + call InsertMediumBlockIntoBin +@MediumBlockDownsizeDone: + {Unlock the medium blocks} + lea rax, MediumBlocksLocked + mov byte ptr [rax], False + {Result = old pointer} + mov rax, rsi + jmp @Done +@MediumDownsizeRealloc: + {Save the requested size} + mov rdi, rdx + mov rcx, rdx + {Allocate the new block} + call FastGetMem + test rax, rax + jz @Done + {Save the result} + mov r15, rax + mov rdx, rax + mov rcx, rsi + mov r8, rdi + {Move the data across} +{$ifdef UseCustomVariableSizeMoveRoutines} + {$ifdef Align16Bytes} + call MoveX16LP + {$else} + call MoveX8LP + {$endif} +{$else} + call System.Move +{$endif} + mov rcx, rsi + call FastFreeMem + {Return the result} + mov rax, r15 + jmp @Done +@MediumBlockUpsize: + {Status: ecx = Current Block Size - BlockHeaderSize, bl = Current Block Flags, + rdi = @Next Block, rsi = APointer, rdx = Requested Size} + {Can we do an in-place upsize?} + mov rax, [rdi - BlockHeaderSize] + test al, IsFreeBlockFlag + jz @CannotUpsizeMediumBlockInPlace + {Get the total available size including the next block} + and rax, DropMediumAndLargeFlagsMask + {r15 = total available size including the next block (excluding the header)} + lea r15, [rax + rcx] + {Can the block fit?} + cmp rdx, r15 + ja @CannotUpsizeMediumBlockInPlace + {The next block is free and there is enough space to grow this + block in place.} +{$ifndef AssumeMultiThreaded} + lea r8, IsMultiThread + cmp byte ptr [r8], False + je @DoMediumInPlaceUpsize +{$endif} +@DoMediumLockForUpsize: + {Lock the medium blocks.} + mov rbx, rcx + mov r15, rdx + call LockMediumBlocks + mov rcx, rbx + mov rdx, r15 + {Re-read the info for this block (since it may have changed before the medium + blocks could be locked)} + mov rbx, ExtractMediumAndLargeFlagsMask + and rbx, [rsi - BlockHeaderSize] + {Re-read the info for the next block} + mov rax, [rdi - BlockheaderSize] + {Next block still free?} + test al, IsFreeBlockFlag + jz @NextMediumBlockChanged + {Recalculate the next block size} + and eax, DropMediumAndLargeFlagsMask + {The available size including the next block} + lea r15, [rax + rcx] + {Can the block still fit?} + cmp rdx, r15 + ja @NextMediumBlockChanged +@DoMediumInPlaceUpsize: + {Is the next block binnable?} + cmp eax, MinimumMediumBlockSize + {Remove the next block} + jb @MediumInPlaceNoNextRemove + mov r14, rcx + mov rcx, rdi + mov rdi, rdx + call RemoveMediumFreeBlock + mov rcx, r14 + mov rdx, rdi +@MediumInPlaceNoNextRemove: + {Medium blocks grow a minimum of 25% in in-place upsizes} + mov eax, ecx + shr eax, 2 + add eax, ecx + {Get the maximum of the requested size and the minimum growth size} + xor edi, edi + sub eax, edx + adc edi, -1 + and eax, edi + {Round up to the nearest block size granularity} + lea eax, [eax + edx + BlockHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset] + and eax, -MediumBlockGranularity + add eax, MediumBlockSizeOffset + {Calculate the size of the second split} + lea rdx, [r15 + BlockHeaderSize] + sub edx, eax + {Does it fit?} + ja @MediumInPlaceUpsizeSplit + {Grab the whole block: Mark it as used in the block following it} + and qword ptr [rsi + r15], not PreviousMediumBlockIsFreeFlag + {The block size is the full available size plus header} + add r15, BlockHeaderSize + {Upsize done} + jmp @MediumUpsizeInPlaceDone +@MediumInPlaceUpsizeSplit: + {Store the size of the second split as the second last dword} + mov [rsi + r15 - BlockHeaderSize], rdx + {Set the second split header} + lea edi, [edx + IsMediumBlockFlag + IsFreeBlockFlag] + mov [rsi + rax - BlockHeaderSize], rdi + mov r15, rax + cmp edx, MinimumMediumBlockSize + jb @MediumUpsizeInPlaceDone + lea rcx, [rsi + rax] + call InsertMediumBlockIntoBin +@MediumUpsizeInPlaceDone: + {Set the size and flags for this block} + or r15, rbx + mov [rsi - BlockHeaderSize], r15 + {Unlock the medium blocks} + lea rax, MediumBlocksLocked + mov byte ptr [rax], False + {Result = old pointer} + mov rax, rsi + jmp @Done +@NextMediumBlockChanged: + {The next medium block changed while the medium blocks were being locked} + lea rax, MediumBlocksLocked + mov byte ptr [rax], False +@CannotUpsizeMediumBlockInPlace: + {Couldn't upsize in place. Grab a new block and move the data across: + If we have to reallocate and move medium blocks, we grow by at + least 25%} + mov eax, ecx + shr eax, 2 + add eax, ecx + {Get the maximum of the requested size and the minimum growth size} + xor rdi, rdi + sub rax, rdx + adc rdi, -1 + and rax, rdi + add rax, rdx + {Save the size to allocate} + mov r15, rax + {Save the size to move across} + mov edi, ecx + {Save the requested size} + mov rbx, rdx + {Get the block} + mov rcx, rax + call FastGetMem + mov rdx, rbx + {Success?} + test eax, eax + jz @Done + {If it's a Large block - store the actual user requested size} + cmp r15, MaximumMediumBlockSize - BlockHeaderSize + jbe @MediumUpsizeNotLarge + mov [rax - 2 * BlockHeaderSize], rdx +@MediumUpsizeNotLarge: + {Save the result} + mov r15, rax + {Move the data across} + mov rdx, rax + mov rcx, rsi + mov r8, rdi +{$ifdef UseCustomVariableSizeMoveRoutines} + call MoveX16LP +{$else} + call System.Move +{$endif} + {Free the old block} + mov rcx, rsi + call FastFreeMem + {Restore the result} + mov rax, r15 + jmp @Done +@PossibleLargeBlock: + {-----------------------Large block------------------------------} + {Is this a valid large block?} + test cl, IsFreeBlockFlag + IsMediumBlockFlag + jnz @Error + mov rcx, rsi + call ReallocateLargeBlock + jmp @Done + {-----------------------Invalid block------------------------------} +@Error: + xor eax, eax +@Done: +end; +{$endif} +{$endif} +{$endif} + +{Allocates a block and fills it with zeroes} +function FastAllocMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Cardinal{$endif}): Pointer; +{$ifndef ASMVersion} +begin + Result := FastGetMem(ASize); + {Large blocks are already zero filled} + if (Result <> nil) and (ASize <= (MaximumMediumBlockSize - BlockHeaderSize)) then + FillChar(Result^, ASize, 0); +end; +{$else} +{$ifdef 32Bit} +asm + push ebx + {Get the size rounded down to the previous multiple of 4 into ebx} + lea ebx, [eax - 1] + and ebx, -4 + {Get the block} + call FastGetMem + {Could a block be allocated? ecx = 0 if yes, $ffffffff if no} + cmp eax, 1 + sbb ecx, ecx + {Point edx to the last dword} + lea edx, [eax + ebx] + {ebx = $ffffffff if no block could be allocated, otherwise size rounded down + to previous multiple of 4. If ebx = 0 then the block size is 1..4 bytes and + the FPU based clearing loop should not be used (since it clears 8 bytes per + iteration).} + or ebx, ecx + jz @ClearLastDWord + {Large blocks are already zero filled} + cmp ebx, MaximumMediumBlockSize - BlockHeaderSize + jae @Done + {Make the counter negative based} + neg ebx + {Load zero into st(0)} + fldz + {Clear groups of 8 bytes. Block sizes are always four less than a multiple + of 8.} +@FillLoop: + fst qword ptr [edx + ebx] + add ebx, 8 + js @FillLoop + {Clear st(0)} + ffree st(0) + {Correct the stack top} + fincstp + {Clear the last four bytes} +@ClearLastDWord: + mov [edx], ecx +@Done: + pop ebx +end; + +{$else} + +{---------------64-bit BASM FastAllocMem---------------} +asm + .params 1 + .pushnv rbx + {Get the size rounded down to the previous multiple of SizeOf(Pointer) into + ebx} + lea rbx, [rcx - 1] + and rbx, -8 + {Get the block} + call FastGetMem + {Could a block be allocated? rcx = 0 if yes, -1 if no} + cmp rax, 1 + sbb rcx, rcx + {Point rdx to the last dword} + lea rdx, [rax + rbx] + {rbx = -1 if no block could be allocated, otherwise size rounded down + to previous multiple of 8. If rbx = 0 then the block size is 1..8 bytes and + the SSE2 based clearing loop should not be used (since it clears 16 bytes per + iteration).} + or rbx, rcx + jz @ClearLastQWord + {Large blocks are already zero filled} + cmp rbx, MaximumMediumBlockSize - BlockHeaderSize + jae @Done + {Make the counter negative based} + neg rbx + {Load zero into xmm0} + pxor xmm0, xmm0 + {Clear groups of 16 bytes. Block sizes are always 8 less than a multiple of + 16.} +@FillLoop: + movdqa [rdx + rbx], xmm0 + add rbx, 16 + js @FillLoop + {Clear the last 8 bytes} +@ClearLastQWord: + xor rcx, rcx + mov [rdx], rcx +@Done: +end; +{$endif} +{$endif} + +{-----------------Post Uninstall GetMem/FreeMem/ReallocMem-------------------} + +{$ifdef DetectMMOperationsAfterUninstall} + +function InvalidGetMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +{$ifndef NoMessageBoxes} +var + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} +begin +{$ifdef UseOutputDebugString} + OutputDebugStringA(InvalidGetMemMsg); +{$endif} +{$ifndef NoMessageBoxes} + AppendStringToModuleName(InvalidOperationTitle, LErrorMessageTitle); + ShowMessageBox(InvalidGetMemMsg, LErrorMessageTitle); +{$endif} + Result := nil; +end; + +function InvalidFreeMem(APointer: Pointer): Integer; +{$ifndef NoMessageBoxes} +var + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} +begin +{$ifdef UseOutputDebugString} + OutputDebugStringA(InvalidFreeMemMsg); +{$endif} +{$ifndef NoMessageBoxes} + AppendStringToModuleName(InvalidOperationTitle, LErrorMessageTitle); + ShowMessageBox(InvalidFreeMemMsg, LErrorMessageTitle); +{$endif} + Result := -1; +end; + +function InvalidReallocMem(APointer: Pointer; ANewSize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +{$ifndef NoMessageBoxes} +var + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} +begin +{$ifdef UseOutputDebugString} + OutputDebugStringA(InvalidReallocMemMsg); +{$endif} +{$ifndef NoMessageBoxes} + AppendStringToModuleName(InvalidOperationTitle, LErrorMessageTitle); + ShowMessageBox(InvalidReallocMemMsg, LErrorMessageTitle); +{$endif} + Result := nil; +end; + +function InvalidAllocMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Cardinal{$endif}): Pointer; +{$ifndef NoMessageBoxes} +var + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} +begin +{$ifdef UseOutputDebugString} + OutputDebugStringA(InvalidAllocMemMsg); +{$endif} +{$ifndef NoMessageBoxes} + AppendStringToModuleName(InvalidOperationTitle, LErrorMessageTitle); + ShowMessageBox(InvalidAllocMemMsg, LErrorMessageTitle); +{$endif} + Result := nil; +end; + +function InvalidRegisterAndUnRegisterMemoryLeak(APointer: Pointer): Boolean; +begin + Result := False; +end; + +{$endif} + +{-----------------Full Debug Mode Memory Manager Interface--------------------} + +{$ifdef FullDebugMode} + +{Compare [AAddress], CompareVal: + If Equal: [AAddress] := NewVal and result = CompareVal + If Unequal: Result := [AAddress]} +function LockCmpxchg32(CompareVal, NewVal: Integer; AAddress: PInteger): Integer; +asm +{$ifdef 32Bit} + {On entry: + eax = CompareVal, + edx = NewVal, + ecx = AAddress} + lock cmpxchg [ecx], edx +{$else} +.noframe + {On entry: + ecx = CompareVal, + edx = NewVal, + r8 = AAddress} + mov eax, ecx + lock cmpxchg [r8], edx +{$endif} +end; + +{Called by DebugGetMem, DebugFreeMem and DebugReallocMem in order to block a + free block scan operation while the memory pool is being modified.} +procedure StartChangingFullDebugModeBlock; +var + LOldCount: Integer; +begin + while True do + begin + {Get the old thread count} + LOldCount := ThreadsInFullDebugModeRoutine; + if (LOldCount >= 0) + and (LockCmpxchg32(LOldCount, LOldCount + 1, @ThreadsInFullDebugModeRoutine) = LOldCount) then + begin + Break; + end; + {$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} + {$else} + Sleep(InitialSleepTime); + {Try again} + LOldCount := ThreadsInFullDebugModeRoutine; + if (LOldCount >= 0) + and (LockCmpxchg32(LOldCount, LOldCount + 1, @ThreadsInFullDebugModeRoutine) = LOldCount) then + begin + Break; + end; + Sleep(AdditionalSleepTime); + {$endif} + end; +end; + +procedure DoneChangingFullDebugModeBlock; +asm +{$ifdef 32Bit} + lock dec ThreadsInFullDebugModeRoutine +{$else} +.noframe + lea rax, ThreadsInFullDebugModeRoutine + lock dec dword ptr [rax] +{$endif} +end; + +{Increments the allocation number} +procedure IncrementAllocationNumber; +asm +{$ifdef 32Bit} + lock inc CurrentAllocationNumber +{$else} +.noframe + lea rax, CurrentAllocationNumber + lock inc dword ptr [rax] +{$endif} +end; + +{Called by a routine wanting to lock the entire memory pool in FullDebugMode, e.g. before scanning the memory + pool for corruptions.} +procedure BlockFullDebugModeMMRoutines; +begin + while True do + begin + {Get the old thread count} + if LockCmpxchg32(0, -1, @ThreadsInFullDebugModeRoutine) = 0 then + Break; +{$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} +{$else} + Sleep(InitialSleepTime); + {Try again} + if LockCmpxchg32(0, -1, @ThreadsInFullDebugModeRoutine) = 0 then + Break; + Sleep(AdditionalSleepTime); +{$endif} + end; +end; + +procedure UnblockFullDebugModeMMRoutines; +begin + {Currently blocked? If so, unblock the FullDebugMode routines.} + if ThreadsInFullDebugModeRoutine = -1 then + ThreadsInFullDebugModeRoutine := 0; +end; + +procedure DeleteEventLog; +begin + {Delete the file} + DeleteFileA(MMLogFileName); +end; + +{Finds the start and length of the file name given a full path.} +procedure ExtractFileName(APFullPath: PAnsiChar; var APFileNameStart: PAnsiChar; var AFileNameLength: Integer); +var + LChar: AnsiChar; +begin + {Initialize} + APFileNameStart := APFullPath; + AFileNameLength := 0; + {Find the file } + while True do + begin + {Get the next character} + LChar := APFullPath^; + {End of the path string?} + if LChar = #0 then + Break; + {Advance the buffer position} + Inc(APFullPath); + {Found a backslash? -> May be the start of the file name} + if LChar = '\' then + APFileNameStart := APFullPath; + end; + {Calculate the length of the file name} + AFileNameLength := IntPtr(APFullPath) - IntPtr(APFileNameStart); +end; + +procedure AppendEventLog(ABuffer: Pointer; ACount: Cardinal); +const + {Declared here, because it is not declared in the SHFolder.pas unit of some older Delphi versions.} + SHGFP_TYPE_CURRENT = 0; +var + LFileHandle, LBytesWritten: Cardinal; + LEventHeader: array[0..1023] of AnsiChar; + LAlternateLogFileName: array[0..2047] of AnsiChar; + LPathLen, LNameLength: Integer; + LMsgPtr, LPFileName: PAnsiChar; + LSystemTime: TSystemTime; +begin + {Try to open the log file in read/write mode.} + LFileHandle := CreateFileA(MMLogFileName, GENERIC_READ or GENERIC_WRITE, + 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + {Did log file creation fail? If so, the destination folder is perhaps read-only: + Try to redirect logging to a file in the user's "My Documents" folder.} + if (LFileHandle = INVALID_HANDLE_VALUE) +{$ifdef Delphi4or5} + and SHGetSpecialFolderPathA(0, @LAlternateLogFileName, CSIDL_PERSONAL, True) then +{$else} + and (SHGetFolderPathA(0, CSIDL_PERSONAL or CSIDL_FLAG_CREATE, 0, + SHGFP_TYPE_CURRENT, @LAlternateLogFileName) = S_OK) then +{$endif} + begin + {Extract the filename part from MMLogFileName and append it to the path of + the "My Documents" folder.} + LPathLen := StrLen(LAlternateLogFileName); + {Ensure that there is a trailing backslash in the path} + if (LPathLen = 0) or (LAlternateLogFileName[LPathLen - 1] <> '\') then + begin + LAlternateLogFileName[LPathLen] := '\'; + Inc(LPathLen); + end; + {Add the filename to the path} + ExtractFileName(@MMLogFileName, LPFileName, LNameLength); + System.Move(LPFileName^, LAlternateLogFileName[LPathLen], LNameLength + 1); + {Try to open the alternate log file} + LFileHandle := CreateFileA(LAlternateLogFileName, GENERIC_READ or GENERIC_WRITE, + 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + end; + {Was the log file opened/created successfully?} + if LFileHandle <> INVALID_HANDLE_VALUE then + begin + {Seek to the end of the file} + SetFilePointer(LFileHandle, 0, nil, FILE_END); + {Set the separator} + LMsgPtr := AppendStringToBuffer(CRLF, @LEventHeader[0], Length(CRLF)); + LMsgPtr := AppendStringToBuffer(EventSeparator, LMsgPtr, Length(EventSeparator)); + {Set the date & time} + GetLocalTime(LSystemTime); + LMsgPtr := NativeUIntToStrBuf(LSystemTime.wYear, LMsgPtr); + LMsgPtr^ := '/'; + Inc(LMsgPtr); + LMsgPtr := NativeUIntToStrBuf(LSystemTime.wMonth, LMsgPtr); + LMsgPtr^ := '/'; + Inc(LMsgPtr); + LMsgPtr := NativeUIntToStrBuf(LSystemTime.wDay, LMsgPtr); + LMsgPtr^ := ' '; + Inc(LMsgPtr); + LMsgPtr := NativeUIntToStrBuf(LSystemTime.wHour, LMsgPtr); + LMsgPtr^ := ':'; + Inc(LMsgPtr); + if LSystemTime.wMinute < 10 then + begin + LMsgPtr^ := '0'; + Inc(LMsgPtr); + end; + LMsgPtr := NativeUIntToStrBuf(LSystemTime.wMinute, LMsgPtr); + LMsgPtr^ := ':'; + Inc(LMsgPtr); + if LSystemTime.wSecond < 10 then + begin + LMsgPtr^ := '0'; + Inc(LMsgPtr); + end; + LMsgPtr := NativeUIntToStrBuf(LSystemTime.WSecond, LMsgPtr); + {Write the header} + LMsgPtr := AppendStringToBuffer(EventSeparator, LMsgPtr, Length(EventSeparator)); + LMsgPtr := AppendStringToBuffer(CRLF, LMsgPtr, Length(CRLF)); + WriteFile(LFileHandle, LEventHeader[0], NativeUInt(LMsgPtr) - NativeUInt(@LEventHeader[0]), LBytesWritten, nil); + {Write the data} + WriteFile(LFileHandle, ABuffer^, ACount, LBytesWritten, nil); + {Close the file} + CloseHandle(LFileHandle); + end; +end; + +{Sets the default log filename} +procedure SetDefaultMMLogFileName; +const + LogFileExtAnsi: PAnsiChar = LogFileExtension; +var + LEnvVarLength, LModuleNameLength: Cardinal; + LPathOverride: array[0..2047] of AnsiChar; + LPFileName: PAnsiChar; + LFileNameLength: Integer; +begin + {Get the name of the application} + LModuleNameLength := AppendModuleFileName(@MMLogFileName[0]); + {Replace the last few characters of the module name, and optionally override + the path.} + if LModuleNameLength > 0 then + begin + {Change the filename} + System.Move(LogFileExtAnsi^, MMLogFileName[LModuleNameLength - 4], + StrLen(LogFileExtAnsi) + 1); + {Try to read the FastMMLogFilePath environment variable} + LEnvVarLength := GetEnvironmentVariableA('FastMMLogFilePath', + @LPathOverride, 1023); + {Does the environment variable exist? If so, override the log file path.} + if LEnvVarLength > 0 then + begin + {Ensure that there's a trailing backslash.} + if LPathOverride[LEnvVarLength - 1] <> '\' then + begin + LPathOverride[LEnvVarLength] := '\'; + Inc(LEnvVarLength); + end; + {Add the filename to the path override} + ExtractFileName(@MMLogFileName[0], LPFileName, LFileNameLength); + System.Move(LPFileName^, LPathOverride[LEnvVarLength], LFileNameLength + 1); + {Copy the override path back to the filename buffer} + System.Move(LPathOverride, MMLogFileName, SizeOf(MMLogFileName) - 1); + end; + end; +end; + +{Specify the full path and name for the filename to be used for logging memory + errors, etc. If ALogFileName is nil or points to an empty string it will + revert to the default log file name.} +procedure SetMMLogFileName(ALogFileName: PAnsiChar = nil); +var + LLogFileNameLen: Integer; +begin + {Is ALogFileName valid?} + if (ALogFileName <> nil) and (ALogFileName^ <> #0) then + begin + LLogFileNameLen := StrLen(ALogFileName); + if LLogFileNameLen < Length(MMLogFileName) then + begin + {Set the log file name} + System.Move(ALogFileName^, MMLogFileName, LLogFileNameLen + 1); + Exit; + end; + end; + {Invalid log file name} + SetDefaultMMLogFileName; +end; + +{Returns the current "allocation group". Whenever a GetMem request is serviced + in FullDebugMode, the current "allocation group" is stored in the block header. + This may help with debugging. Note that if a block is subsequently reallocated + that it keeps its original "allocation group" and "allocation number" (all + allocations are also numbered sequentially).} +function GetCurrentAllocationGroup: Cardinal; +begin + Result := AllocationGroupStack[AllocationGroupStackTop]; +end; + +{Allocation groups work in a stack like fashion. Group numbers are pushed onto + and popped off the stack. Note that the stack size is limited, so every push + should have a matching pop.} +procedure PushAllocationGroup(ANewCurrentAllocationGroup: Cardinal); +begin + if AllocationGroupStackTop < AllocationGroupStackSize - 1 then + begin + Inc(AllocationGroupStackTop); + AllocationGroupStack[AllocationGroupStackTop] := ANewCurrentAllocationGroup; + end + else + begin + {Raise a runtime error if the stack overflows} + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} + end; +end; + +procedure PopAllocationGroup; +begin + if AllocationGroupStackTop > 0 then + begin + Dec(AllocationGroupStackTop); + end + else + begin + {Raise a runtime error if the stack underflows} + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} + end; +end; + +{Sums all the dwords starting at the given address. ACount must be > 0 and a + multiple of SizeOf(Pointer).} +function SumNativeUInts(AStartValue: NativeUInt; APointer: PNativeUInt; + ACount: NativeUInt): NativeUInt; +asm +{$ifdef 32Bit} + {On entry: eax = AStartValue, edx = APointer; ecx = ACount} + add edx, ecx + neg ecx +@AddLoop: + add eax, [edx + ecx] + add ecx, 4 + js @AddLoop +{$else} + {On entry: rcx = AStartValue, rdx = APointer; r8 = ACount} + add rdx, r8 + neg r8 + mov rax, rcx +@AddLoop: + add rax, [rdx + r8] + add r8, 8 + js @AddLoop +{$endif} +end; + +{Checks the memory starting at the given address for the fill pattern. + Returns True if all bytes are all valid. ACount must be >0 and a multiple of + SizeOf(Pointer).} +function CheckFillPattern(APointer: Pointer; ACount: NativeUInt; + AFillPattern: NativeUInt): Boolean; +asm +{$ifdef 32Bit} + {On entry: eax = APointer; edx = ACount; ecx = AFillPattern} + add eax, edx + neg edx +@CheckLoop: + cmp [eax + edx], ecx + jne @Done + add edx, 4 + js @CheckLoop +@Done: + sete al +{$else} + {On entry: rcx = APointer; rdx = ACount; r8 = AFillPattern} + add rcx, rdx + neg rdx +@CheckLoop: + cmp [rcx + rdx], r8 + jne @Done + add rdx, 8 + js @CheckLoop +@Done: + sete al +{$endif} +end; + +{Calculates the checksum for the debug header. Adds all dwords in the debug + header to the start address of the block.} +function CalculateHeaderCheckSum(APointer: PFullDebugBlockHeader): NativeUInt; +begin + Result := SumNativeUInts( + NativeUInt(APointer), + PNativeUInt(PByte(APointer) + 2 * SizeOf(Pointer)), + SizeOf(TFullDebugBlockHeader) - 2 * SizeOf(Pointer) - SizeOf(NativeUInt)); +end; + +procedure UpdateHeaderAndFooterCheckSums(APointer: PFullDebugBlockHeader); +var + LHeaderCheckSum: NativeUInt; +begin + LHeaderCheckSum := CalculateHeaderCheckSum(APointer); + APointer.HeaderCheckSum := LHeaderCheckSum; + PNativeUInt(PByte(APointer) + SizeOf(TFullDebugBlockHeader) + APointer.UserSize)^ := not LHeaderCheckSum; +end; + +function LogCurrentThreadAndStackTrace(ASkipFrames: Cardinal; ABuffer: PAnsiChar): PAnsiChar; +var + LCurrentStackTrace: TStackTrace; +begin + {Get the current call stack} + GetStackTrace(@LCurrentStackTrace[0], StackTraceDepth, ASkipFrames); + {Log the thread ID} + Result := AppendStringToBuffer(CurrentThreadIDMsg, ABuffer, Length(CurrentThreadIDMsg)); + Result := NativeUIntToHexBuf(GetThreadID, Result); + {List the stack trace} + Result := AppendStringToBuffer(CurrentStackTraceMsg, Result, Length(CurrentStackTraceMsg)); + Result := LogStackTrace(@LCurrentStackTrace, StackTraceDepth, Result); +end; + +{$ifndef DisableLoggingOfMemoryDumps} +function LogMemoryDump(APointer: PFullDebugBlockHeader; ABuffer: PAnsiChar): PAnsiChar; +var + LByteNum, LVal: Cardinal; + LDataPtr: PByte; +begin + Result := AppendStringToBuffer(MemoryDumpMsg, ABuffer, Length(MemoryDumpMsg)); + Result := NativeUIntToHexBuf(NativeUInt(APointer) + SizeOf(TFullDebugBlockHeader), Result); + Result^ := ':'; + Inc(Result); + {Add the bytes} + LDataPtr := PByte(PByte(APointer) + SizeOf(TFullDebugBlockHeader)); + for LByteNum := 0 to 255 do + begin + if LByteNum and 31 = 0 then + begin + Result^ := #13; + Inc(Result); + Result^ := #10; + Inc(Result); + end + else + begin + Result^ := ' '; + Inc(Result); + end; + {Set the hex data} + LVal := Byte(LDataPtr^); + Result^ := HexTable[LVal shr 4]; + Inc(Result); + Result^ := HexTable[LVal and $f]; + Inc(Result); + {Next byte} + Inc(LDataPtr); + end; + {Dump ASCII} + LDataPtr := PByte(PByte(APointer) + SizeOf(TFullDebugBlockHeader)); + for LByteNum := 0 to 255 do + begin + if LByteNum and 31 = 0 then + begin + Result^ := #13; + Inc(Result); + Result^ := #10; + Inc(Result); + end + else + begin + Result^ := ' '; + Inc(Result); + Result^ := ' '; + Inc(Result); + end; + {Set the hex data} + LVal := Byte(LDataPtr^); + if LVal < 32 then + Result^ := '.' + else + Result^ := AnsiChar(LVal); + Inc(Result); + {Next byte} + Inc(LDataPtr); + end; +end; +{$endif} + +{Rotates AValue ABitCount bits to the right} +function RotateRight(AValue, ABitCount: NativeUInt): NativeUInt; +asm +{$ifdef 32Bit} + mov ecx, edx + ror eax, cl +{$else} + mov rax, rcx + mov rcx, rdx + ror rax, cl +{$endif} +end; + +{Determines whether a byte in the user portion of the freed block has been modified. Does not work beyond + the end of the user portion (i.e. footer and beyond).} +function FreeBlockByteWasModified(APointer: PFullDebugBlockHeader; AUserOffset: NativeUInt): Boolean; +var + LFillPattern: NativeUInt; +begin + {Get the expected fill pattern} + if AUserOffset < SizeOf(Pointer) then + begin + LFillPattern := NativeUInt(@FreedObjectVMT.VMTMethods[0]); + end + else + begin +{$ifndef CatchUseOfFreedInterfaces} + LFillPattern := DebugFillPattern; +{$else} + LFillPattern := NativeUInt(@VMTBadInterface); +{$endif} + end; + {Compare the byte value} + Result := Byte(PByte(PByte(APointer) + SizeOf(TFullDebugBlockHeader) + AUserOffset)^) <> + Byte(RotateRight(LFillPattern, (AUserOffset and (SizeOf(Pointer) - 1)) * 8)); +end; + +function LogBlockChanges(APointer: PFullDebugBlockHeader; ABuffer: PAnsiChar): PAnsiChar; +var + LOffset, LChangeStart, LCount: NativeUInt; + LLogCount: Integer; +begin + {No errors logged so far} + LLogCount := 0; + {Log a maximum of 32 changes} + LOffset := 0; + while (LOffset < APointer.UserSize) and (LLogCount < 32) do + begin + {Has the byte been modified?} + if FreeBlockByteWasModified(APointer, LOffset) then + begin + {Found the start of a changed block, now find the length} + LChangeStart := LOffset; + LCount := 0; + while True do + begin + Inc(LCount); + Inc(LOffset); + if (LOffset >= APointer.UserSize) + or (not FreeBlockByteWasModified(APointer, LOffset)) then + begin + Break; + end; + end; + {Got the offset and length, now log it.} + if LLogCount = 0 then + begin + ABuffer := AppendStringToBuffer(FreeModifiedDetailMsg, ABuffer, Length(FreeModifiedDetailMsg)); + end + else + begin + ABuffer^ := ','; + Inc(ABuffer); + ABuffer^ := ' '; + Inc(ABuffer); + end; + ABuffer := NativeUIntToStrBuf(LChangeStart, ABuffer); + ABuffer^ := '('; + Inc(ABuffer); + ABuffer := NativeUIntToStrBuf(LCount, ABuffer); + ABuffer^ := ')'; + Inc(ABuffer); + {Increment the log count} + Inc(LLogCount); + end; + {Next byte} + Inc(LOffset); + end; + {Return the current buffer position} + Result := ABuffer; +end; + +procedure LogBlockError(APointer: PFullDebugBlockHeader; AOperation: TBlockOperation; LHeaderValid, LFooterValid: Boolean); +var + LMsgPtr: PAnsiChar; + LErrorMessage: array[0..32767] of AnsiChar; +{$ifndef NoMessageBoxes} + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} + LClass: TClass; + {$ifdef CheckCppObjectTypeEnabled} + LCppObjectTypeName: PAnsiChar; + {$endif} +begin + {Display the error header and the operation type.} + LMsgPtr := AppendStringToBuffer(ErrorMsgHeader, @LErrorMessage[0], Length(ErrorMsgHeader)); + case AOperation of + boGetMem: LMsgPtr := AppendStringToBuffer(GetMemMsg, LMsgPtr, Length(GetMemMsg)); + boFreeMem: LMsgPtr := AppendStringToBuffer(FreeMemMsg, LMsgPtr, Length(FreeMemMsg)); + boReallocMem: LMsgPtr := AppendStringToBuffer(ReallocMemMsg, LMsgPtr, Length(ReallocMemMsg)); + boBlockCheck: LMsgPtr := AppendStringToBuffer(BlockCheckMsg, LMsgPtr, Length(BlockCheckMsg)); + end; + LMsgPtr := AppendStringToBuffer(OperationMsg, LMsgPtr, Length(OperationMsg)); + {Is the header still intact?} + if LHeaderValid then + begin + {Is the footer still valid?} + if LFooterValid then + begin + {A freed block has been modified, a double free has occurred, or an + attempt was made to free a memory block allocated by a different + instance of FastMM.} + if AOperation <= boGetMem then + begin + LMsgPtr := AppendStringToBuffer(FreeModifiedErrorMsg, LMsgPtr, Length(FreeModifiedErrorMsg)); + {Log the exact changes that caused the error.} + LMsgPtr := LogBlockChanges(APointer, LMsgPtr); + end + else + begin + {It is either a double free, or an attempt was made to free a block + that was allocated via a different memory manager.} + if APointer.AllocatedByRoutine = nil then + LMsgPtr := AppendStringToBuffer(DoubleFreeErrorMsg, LMsgPtr, Length(DoubleFreeErrorMsg)) + else + LMsgPtr := AppendStringToBuffer(WrongMMFreeErrorMsg, LMsgPtr, Length(WrongMMFreeErrorMsg)); + end; + end + else + begin + LMsgPtr := AppendStringToBuffer(BlockFooterCorruptedMsg, LMsgPtr, Length(BlockFooterCorruptedMsg)) + end; + {Set the block size message} + if AOperation <= boGetMem then + LMsgPtr := AppendStringToBuffer(PreviousBlockSizeMsg, LMsgPtr, Length(PreviousBlockSizeMsg)) + else + LMsgPtr := AppendStringToBuffer(CurrentBlockSizeMsg, LMsgPtr, Length(CurrentBlockSizeMsg)); + LMsgPtr := NativeUIntToStrBuf(APointer.UserSize, LMsgPtr); + {The header is still intact - display info about the this/previous allocation} + if APointer.AllocationStackTrace[0] <> 0 then + begin + if AOperation <= boGetMem then + LMsgPtr := AppendStringToBuffer(ThreadIDPrevAllocMsg, LMsgPtr, Length(ThreadIDPrevAllocMsg)) + else + LMsgPtr := AppendStringToBuffer(ThreadIDAtAllocMsg, LMsgPtr, Length(ThreadIDAtAllocMsg)); + LMsgPtr := NativeUIntToHexBuf(APointer.AllocatedByThread, LMsgPtr); + LMsgPtr := AppendStringToBuffer(StackTraceMsg, LMsgPtr, Length(StackTraceMsg)); + LMsgPtr := LogStackTrace(@APointer.AllocationStackTrace, StackTraceDepth, LMsgPtr); + end; + {Get the class this block was used for previously} + LClass := DetectClassInstance(@APointer.PreviouslyUsedByClass); + if (LClass <> nil) and (IntPtr(LClass) <> IntPtr(@FreedObjectVMT.VMTMethods[0])) then + begin + LMsgPtr := AppendStringToBuffer(PreviousObjectClassMsg, LMsgPtr, Length(PreviousObjectClassMsg)); + LMsgPtr := AppendClassNameToBuffer(LClass, LMsgPtr); + end; + {$ifdef CheckCppObjectTypeEnabled} + if (LClass = nil) and Assigned(GetCppVirtObjTypeNameByVTablePtrFunc) then + begin + LCppObjectTypeName := GetCppVirtObjTypeNameByVTablePtrFunc(Pointer(APointer.PreviouslyUsedByClass), 0); + if Assigned(LCppObjectTypeName) then + begin + LMsgPtr := AppendStringToBuffer(PreviousObjectClassMsg, LMsgPtr, Length(PreviousObjectClassMsg)); + LMsgPtr := AppendStringToBuffer(LCppObjectTypeName, LMsgPtr, StrLen(LCppObjectTypeName)); + end; + end; + {$endif} + {Get the current class for this block} + if (AOperation > boGetMem) and (APointer.AllocatedByRoutine <> nil) then + begin + LMsgPtr := AppendStringToBuffer(CurrentObjectClassMsg, LMsgPtr, Length(CurrentObjectClassMsg)); + LClass := DetectClassInstance(Pointer(PByte(APointer) + SizeOf(TFullDebugBlockHeader))); + if IntPtr(LClass) = IntPtr(@FreedObjectVMT.VMTMethods[0]) then + LClass := nil; + {$ifndef CheckCppObjectTypeEnabled} + LMsgPtr := AppendClassNameToBuffer(LClass, LMsgPtr); + {$else} + if (LClass = nil) and Assigned(GetCppVirtObjTypeNameFunc) then + begin + LCppObjectTypeName := GetCppVirtObjTypeNameFunc(Pointer(PByte(APointer) + SizeOf(TFullDebugBlockHeader)), + APointer.UserSize); + if LCppObjectTypeName <> nil then + LMsgPtr := AppendStringToBuffer(LCppObjectTypeName, LMsgPtr, StrLen(LCppObjectTypeName)) + else + LMsgPtr := AppendClassNameToBuffer(LClass, LMsgPtr); + end + else + begin + LMsgPtr := AppendClassNameToBuffer(LClass, LMsgPtr); + end; + {$endif} + {Log the allocation group} + if APointer.AllocationGroup > 0 then + begin + LMsgPtr := AppendStringToBuffer(CurrentAllocationGroupMsg, LMsgPtr, Length(CurrentAllocationGroupMsg)); + LMsgPtr := NativeUIntToStrBuf(APointer.AllocationGroup, LMsgPtr); + end; + {Log the allocation number} + LMsgPtr := AppendStringToBuffer(CurrentAllocationNumberMsg, LMsgPtr, Length(CurrentAllocationNumberMsg)); + LMsgPtr := NativeUIntToStrBuf(APointer.AllocationNumber, LMsgPtr); + end + else + begin + {Log the allocation group} + if APointer.AllocationGroup > 0 then + begin + LMsgPtr := AppendStringToBuffer(PreviousAllocationGroupMsg, LMsgPtr, Length(PreviousAllocationGroupMsg)); + LMsgPtr := NativeUIntToStrBuf(APointer.AllocationGroup, LMsgPtr); + end; + {Log the allocation number} + LMsgPtr := AppendStringToBuffer(PreviousAllocationNumberMsg, LMsgPtr, Length(PreviousAllocationNumberMsg)); + LMsgPtr := NativeUIntToStrBuf(APointer.AllocationNumber, LMsgPtr); + end; + {Get the call stack for the previous free} + if APointer.FreeStackTrace[0] <> 0 then + begin + LMsgPtr := AppendStringToBuffer(ThreadIDAtFreeMsg, LMsgPtr, Length(ThreadIDAtFreeMsg)); + LMsgPtr := NativeUIntToHexBuf(APointer.FreedByThread, LMsgPtr); + LMsgPtr := AppendStringToBuffer(StackTraceMsg, LMsgPtr, Length(StackTraceMsg)); + LMsgPtr := LogStackTrace(@APointer.FreeStackTrace, StackTraceDepth, LMsgPtr); + end; + end + else + begin + {Header has been corrupted} + LMsgPtr := AppendStringToBuffer(BlockHeaderCorruptedMsg, LMsgPtr, Length(BlockHeaderCorruptedMsg)); + end; + {Add the current stack trace} + LMsgPtr := LogCurrentThreadAndStackTrace(3 + Ord(AOperation <> boGetMem) + Ord(AOperation = boReallocMem), LMsgPtr); +{$ifndef DisableLoggingOfMemoryDumps} + {Add the memory dump} + LMsgPtr := LogMemoryDump(APointer, LMsgPtr); +{$endif} + {Trailing CRLF} + LMsgPtr^ := #13; + Inc(LMsgPtr); + LMsgPtr^ := #10; + Inc(LMsgPtr); + {Trailing #0} + LMsgPtr^ := #0; +{$ifdef LogErrorsToFile} + {Log the error} + AppendEventLog(@LErrorMessage[0], NativeUInt(LMsgPtr) - NativeUInt(@LErrorMessage[0])); +{$endif} +{$ifdef UseOutputDebugString} + OutputDebugStringA(LErrorMessage); +{$endif} + {Show the message} +{$ifndef NoMessageBoxes} + AppendStringToModuleName(BlockErrorMsgTitle, LErrorMessageTitle); + ShowMessageBox(LErrorMessage, LErrorMessageTitle); +{$endif} +end; + +{Logs the stack traces for a memory leak to file} +procedure LogMemoryLeakOrAllocatedBlock(APointer: PFullDebugBlockHeader; IsALeak: Boolean); +var + LHeaderValid: Boolean; + LMsgPtr: PAnsiChar; + LErrorMessage: array[0..32767] of AnsiChar; + LClass: TClass; + {$ifdef CheckCppObjectTypeEnabled} + LCppObjectTypeName: PAnsiChar; + {$endif} +begin + {Display the error header and the operation type.} + if IsALeak then + LMsgPtr := AppendStringToBuffer(LeakLogHeader, @LErrorMessage[0], Length(LeakLogHeader)) + else + LMsgPtr := AppendStringToBuffer(BlockScanLogHeader, @LErrorMessage[0], Length(BlockScanLogHeader)); + LMsgPtr := NativeUIntToStrBuf(GetAvailableSpaceInBlock(APointer) - FullDebugBlockOverhead, LMsgPtr); + {Is the debug info surrounding the block valid?} + LHeaderValid := CalculateHeaderCheckSum(APointer) = APointer.HeaderCheckSum; + {Is the header still intact?} + if LHeaderValid then + begin + {The header is still intact - display info about this/previous allocation} + if APointer.AllocationStackTrace[0] <> 0 then + begin + LMsgPtr := AppendStringToBuffer(ThreadIDAtAllocMsg, LMsgPtr, Length(ThreadIDAtAllocMsg)); + LMsgPtr := NativeUIntToHexBuf(APointer.AllocatedByThread, LMsgPtr); + LMsgPtr := AppendStringToBuffer(StackTraceMsg, LMsgPtr, Length(StackTraceMsg)); + LMsgPtr := LogStackTrace(@APointer.AllocationStackTrace, StackTraceDepth, LMsgPtr); + end; + LMsgPtr := AppendStringToBuffer(CurrentObjectClassMsg, LMsgPtr, Length(CurrentObjectClassMsg)); + {Get the current class for this block} + LClass := DetectClassInstance(Pointer(PByte(APointer) + SizeOf(TFullDebugBlockHeader))); + if IntPtr(LClass) = IntPtr(@FreedObjectVMT.VMTMethods[0]) then + LClass := nil; + {$ifndef CheckCppObjectTypeEnabled} + if LClass <> nil then + begin + LMsgPtr := AppendClassNameToBuffer(LClass, LMsgPtr); + end + else + begin + case DetectStringData(Pointer(PByte(APointer) + SizeOf(TFullDebugBlockHeader)), APointer.UserSize) of + stUnknown: LMsgPtr := AppendClassNameToBuffer(nil, LMsgPtr); + stAnsiString: LMsgPtr := AppendStringToBuffer(AnsiStringBlockMessage, LMsgPtr, Length(AnsiStringBlockMessage)); + stUnicodeString: LMsgPtr := AppendStringToBuffer(UnicodeStringBlockMessage, LMsgPtr, Length(UnicodeStringBlockMessage)); + end; + end; + {$else} + if (LClass = nil) and Assigned(GetCppVirtObjTypeNameFunc) then + begin + LCppObjectTypeName := GetCppVirtObjTypeNameFunc(Pointer(PByte(APointer) + SizeOf(TFullDebugBlockHeader)), + APointer.UserSize); + if LCppObjectTypeName <> nil then + LMsgPtr := AppendStringToBuffer(LCppObjectTypeName, LMsgPtr, StrLen(LCppObjectTypeName)) + else + begin + case DetectStringData(Pointer(PByte(APointer) + SizeOf(TFullDebugBlockHeader)), APointer.UserSize) of + stUnknown: LMsgPtr := AppendClassNameToBuffer(nil, LMsgPtr); + stAnsiString: LMsgPtr := AppendStringToBuffer(AnsiStringBlockMessage, LMsgPtr, Length(AnsiStringBlockMessage)); + stUnicodeString: LMsgPtr := AppendStringToBuffer(UnicodeStringBlockMessage, LMsgPtr, Length(UnicodeStringBlockMessage)); + end; + end; + end + else + LMsgPtr := AppendClassNameToBuffer(LClass, LMsgPtr); + {$endif} + {Log the allocation group} + if APointer.AllocationGroup > 0 then + begin + LMsgPtr := AppendStringToBuffer(CurrentAllocationGroupMsg, LMsgPtr, Length(CurrentAllocationGroupMsg)); + LMsgPtr := NativeUIntToStrBuf(APointer.AllocationGroup, LMsgPtr); + end; + {Log the allocation number} + LMsgPtr := AppendStringToBuffer(CurrentAllocationNumberMsg, LMsgPtr, Length(CurrentAllocationNumberMsg)); + LMsgPtr := NativeUIntToStrBuf(APointer.AllocationNumber, LMsgPtr); + end + else + begin + {Header has been corrupted} + LMsgPtr^ := '.'; + Inc(LMsgPtr); + LMsgPtr^ := ' '; + Inc(LMsgPtr); + LMsgPtr := AppendStringToBuffer(BlockHeaderCorruptedMsg, LMsgPtr, Length(BlockHeaderCorruptedMsg)); + end; +{$ifndef DisableLoggingOfMemoryDumps} + {Add the memory dump} + LMsgPtr := LogMemoryDump(APointer, LMsgPtr); +{$endif} + {Trailing CRLF} + LMsgPtr^ := #13; + Inc(LMsgPtr); + LMsgPtr^ := #10; + Inc(LMsgPtr); + {Trailing #0} + LMsgPtr^ := #0; + {Log the error} + AppendEventLog(@LErrorMessage[0], NativeUInt(LMsgPtr) - NativeUInt(@LErrorMessage[0])); +end; + +{Checks that a free block is unmodified} +function CheckFreeBlockUnmodified(APBlock: PFullDebugBlockHeader; ABlockSize: NativeUInt; + AOperation: TBlockOperation): Boolean; +var + LHeaderCheckSum: NativeUInt; + LHeaderValid, LFooterValid, LBlockUnmodified: Boolean; +begin + LHeaderCheckSum := CalculateHeaderCheckSum(APBlock); + LHeaderValid := LHeaderCheckSum = APBlock.HeaderCheckSum; + {Is the footer itself still in place} + LFooterValid := LHeaderValid + and (PNativeUInt(PByte(APBlock) + SizeOf(TFullDebugBlockHeader) + APBlock.UserSize)^ = (not LHeaderCheckSum)); + {Is the footer and debug VMT in place? The debug VMT is only valid if the user size is greater than the size of a pointer.} + if LFooterValid + and (APBlock.UserSize < SizeOf(Pointer)) or (PNativeUInt(PByte(APBlock) + SizeOf(TFullDebugBlockHeader))^ = NativeUInt(@FreedObjectVMT.VMTMethods[0])) then + begin + {Store the debug fill pattern in place of the footer in order to simplify + checking for block modifications.} + PNativeUInt(PByte(APBlock) + SizeOf(TFullDebugBlockHeader) + APBlock.UserSize)^ := + {$ifndef CatchUseOfFreedInterfaces} + DebugFillPattern; + {$else} + RotateRight(NativeUInt(@VMTBadInterface), (APBlock.UserSize and (SizeOf(Pointer) - 1)) * 8); + {$endif} + {Check that all the filler bytes are valid inside the block, except for + the "dummy" class header} + LBlockUnmodified := CheckFillPattern(PNativeUInt(PByte(APBlock) + (SizeOf(TFullDebugBlockHeader) + SizeOf(Pointer))), + ABlockSize - (FullDebugBlockOverhead + SizeOf(Pointer)), + {$ifndef CatchUseOfFreedInterfaces}DebugFillPattern{$else}NativeUInt(@VMTBadInterface){$endif}); + {Reset the old footer} + PNativeUInt(PByte(APBlock) + SizeOf(TFullDebugBlockHeader) + APBlock.UserSize)^ := not LHeaderCheckSum; + end + else + LBlockUnmodified := False; + if (not LHeaderValid) or (not LFooterValid) or (not LBlockUnmodified) then + begin + LogBlockError(APBlock, AOperation, LHeaderValid, LFooterValid); + Result := False; + end + else + Result := True; +end; + +function DebugGetMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +begin + {Scan the entire memory pool first?} + if FullDebugModeScanMemoryPoolBeforeEveryOperation then + ScanMemoryPoolForCorruptions; + {Enter the memory manager: block scans may not be performed now} + StartChangingFullDebugModeBlock; + try + {We need extra space for (a) The debug header, (b) the block debug trailer + and (c) the trailing block size pointer for free blocks} + Result := FastGetMem(ASize + FullDebugBlockOverhead); + if Result <> nil then + begin + {Large blocks are always newly allocated (and never reused), so checking + for a modify-after-free is not necessary.} + if (ASize > (MaximumMediumBlockSize - BlockHeaderSize - FullDebugBlockOverhead)) + or CheckFreeBlockUnmodified(Result, GetAvailableSpaceInBlock(Result) + BlockHeaderSize, boGetMem) then + begin + {Set the allocation call stack} + GetStackTrace(@PFullDebugBlockHeader(Result).AllocationStackTrace, StackTraceDepth, 1); + {Set the thread ID of the thread that allocated the block} + PFullDebugBlockHeader(Result).AllocatedByThread := GetThreadID; + {Block is now in use: It was allocated by this routine} + PFullDebugBlockHeader(Result).AllocatedByRoutine := @DebugGetMem; + {Set the group number} + PFullDebugBlockHeader(Result).AllocationGroup := AllocationGroupStack[AllocationGroupStackTop]; + {Set the allocation number} + IncrementAllocationNumber; + PFullDebugBlockHeader(Result).AllocationNumber := CurrentAllocationNumber; + {Clear the previous block trailer} + PNativeUInt(PByte(Result) + SizeOf(TFullDebugBlockHeader) + PFullDebugBlockHeader(Result).UserSize)^ := + {$ifndef CatchUseOfFreedInterfaces} + DebugFillPattern; + {$else} + RotateRight(NativeUInt(@VMTBadInterface), (PFullDebugBlockHeader(Result).UserSize and (SizeOf(Pointer) - 1)) * 8); + {$endif} + {Set the user size for the block} + PFullDebugBlockHeader(Result).UserSize := ASize; + {Set the checksums} + UpdateHeaderAndFooterCheckSums(Result); + {$ifdef FullDebugModeCallBacks} + if Assigned(OnDebugGetMemFinish) then + OnDebugGetMemFinish(PFullDebugBlockHeader(Result), ASize); + {$endif} + {Return the start of the actual block} + Result := Pointer(PByte(Result) + SizeOf(TFullDebugBlockHeader)); + {Should this block be marked as an expected leak automatically?} + if FullDebugModeRegisterAllAllocsAsExpectedMemoryLeak then + RegisterExpectedMemoryLeak(Result); + end + else + begin + Result := nil; + end; + end; + finally + {Leaving the memory manager routine: Block scans may be performed again.} + DoneChangingFullDebugModeBlock; + end; +end; + +function CheckBlockBeforeFreeOrRealloc(APBlock: PFullDebugBlockHeader; + AOperation: TBlockOperation): Boolean; +var + LHeaderValid, LFooterValid: Boolean; + LPFooter: PNativeUInt; +{$ifndef CatchUseOfFreedInterfaces} + LBlockSize: NativeUInt; + LPTrailingByte, LPFillPatternEnd: PByte; +{$endif} +begin + {Is the checksum for the block header valid?} + LHeaderValid := CalculateHeaderCheckSum(APBlock) = APBlock.HeaderCheckSum; + {If the header is corrupted then the footer is assumed to be corrupt too.} + if LHeaderValid then + begin + {Check the footer checksum: The footer checksum should equal the header + checksum with all bits inverted.} + LPFooter := PNativeUInt(PByte(APBlock) + SizeOf(TFullDebugBlockHeader) + PFullDebugBlockHeader(APBlock).UserSize); + if APBlock.HeaderCheckSum = (not (LPFooter^)) then + begin + LFooterValid := True; +{$ifndef CatchUseOfFreedInterfaces} + {Large blocks do not have the debug fill pattern, since they are never reused.} + if PNativeUInt(PByte(APBlock) - BlockHeaderSize)^ and (IsMediumBlockFlag or IsLargeBlockFlag) <> IsLargeBlockFlag then + begin + {Check that the application has not modified bytes beyond the block + footer. The $80 fill pattern should extend up to 2 nativeints before + the start of the next block (leaving space for the free block size and + next block header.)} + LBlockSize := GetAvailableSpaceInBlock(APBlock); + LPFillPatternEnd := PByte(PByte(APBlock) + LBlockSize - SizeOf(Pointer)); + LPTrailingByte := PByte(PByte(LPFooter) + SizeOf(NativeUInt)); + while UIntPtr(LPTrailingByte) < UIntPtr(LPFillPatternEnd) do + begin + if Byte(LPTrailingByte^) <> DebugFillByte then + begin + LFooterValid := False; + Break; + end; + Inc(LPTrailingByte); + end; + end; +{$endif} + end + else + LFooterValid := False; + end + else + LFooterValid := False; + {The header and footer must be intact and the block must have been allocated + by this memory manager instance.} + if LFooterValid and (APBlock.AllocatedByRoutine = @DebugGetMem) then + begin + Result := True; + end + else + begin + {Log the error} + LogBlockError(APBlock, AOperation, LHeaderValid, LFooterValid); + {Return an error} + Result := False; + end; +end; + +function DebugFreeMem(APointer: Pointer): Integer; +var + LActualBlock: PFullDebugBlockHeader; + LBlockHeader: NativeUInt; +begin + {Scan the entire memory pool first?} + if FullDebugModeScanMemoryPoolBeforeEveryOperation then + ScanMemoryPoolForCorruptions; + {Get a pointer to the start of the actual block} + LActualBlock := PFullDebugBlockHeader(PByte(APointer) + - SizeOf(TFullDebugBlockHeader)); + {Is the debug info surrounding the block valid?} + if CheckBlockBeforeFreeOrRealloc(LActualBlock, boFreeMem) then + begin + {Enter the memory manager: block scans may not be performed now} + StartChangingFullDebugModeBlock; + try + {$ifdef FullDebugModeCallBacks} + if Assigned(OnDebugFreeMemStart) then + OnDebugFreeMemStart(LActualBlock); + {$endif} + {Large blocks are never reused, so there is no point in updating their + headers and fill pattern.} + LBlockHeader := PNativeUInt(PByte(LActualBlock) - BlockHeaderSize)^; + if LBlockHeader and (IsFreeBlockFlag or IsMediumBlockFlag or IsLargeBlockFlag) <> IsLargeBlockFlag then + begin + {Get the class the block was used for} + LActualBlock.PreviouslyUsedByClass := PNativeUInt(APointer)^; + {Set the free call stack} + GetStackTrace(@LActualBlock.FreeStackTrace, StackTraceDepth, 1); + {Set the thread ID of the thread that freed the block} + LActualBlock.FreedByThread := GetThreadID; + {Block is now free} + LActualBlock.AllocatedByRoutine := nil; + {Clear the user area of the block} + DebugFillMem(APointer^, LActualBlock.UserSize, + {$ifndef CatchUseOfFreedInterfaces}DebugFillPattern{$else}NativeUInt(@VMTBadInterface){$endif}); + {Set a pointer to the dummy VMT} + PNativeUInt(APointer)^ := NativeUInt(@FreedObjectVMT.VMTMethods[0]); + {Recalculate the checksums} + UpdateHeaderAndFooterCheckSums(LActualBlock); + end; + {Automatically deregister the expected memory leak?} + if FullDebugModeRegisterAllAllocsAsExpectedMemoryLeak then + UnregisterExpectedMemoryLeak(APointer); + {Free the actual block} + Result := FastFreeMem(LActualBlock); + {$ifdef FullDebugModeCallBacks} + if Assigned(OnDebugFreeMemFinish) then + OnDebugFreeMemFinish(LActualBlock, Result); + {$endif} + finally + {Leaving the memory manager routine: Block scans may be performed again.} + DoneChangingFullDebugModeBlock; + end; + end + else + begin +{$ifdef SuppressFreeMemErrorsInsideException} + if {$ifdef BDS2006AndUp}ExceptObject{$else}RaiseList{$endif} <> nil then + Result := 0 + else +{$endif} + Result := -1; + end; +end; + +function DebugReallocMem(APointer: Pointer; ANewSize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): Pointer; +var + LMoveSize, LBlockSpace: NativeUInt; + LActualBlock, LNewActualBlock: PFullDebugBlockHeader; +begin + {Scan the entire memory pool first?} + if FullDebugModeScanMemoryPoolBeforeEveryOperation then + ScanMemoryPoolForCorruptions; + {Get a pointer to the start of the actual block} + LActualBlock := PFullDebugBlockHeader(PByte(APointer) + - SizeOf(TFullDebugBlockHeader)); + {Is the debug info surrounding the block valid?} + if CheckBlockBeforeFreeOrRealloc(LActualBlock, boReallocMem) then + begin + {Get the current block size} + LBlockSpace := GetAvailableSpaceInBlock(LActualBlock); + {Can the block fit? We need space for the debug overhead and the block header + of the next block} + if LBlockSpace < (NativeUInt(ANewSize) + FullDebugBlockOverhead) then + begin + {Get a new block of the requested size.} + Result := DebugGetMem(ANewSize); + if Result <> nil then + begin + {Block scans may not be performed now} + StartChangingFullDebugModeBlock; + try + {$ifdef FullDebugModeCallBacks} + if Assigned(OnDebugReallocMemStart) then + OnDebugReallocMemStart(LActualBlock, ANewSize); + {$endif} + {We reuse the old allocation number. Since DebugGetMem always bumps + CurrentAllocationGroup, there may be gaps in the sequence of + allocation numbers.} + LNewActualBlock := PFullDebugBlockHeader(PByte(Result) + - SizeOf(TFullDebugBlockHeader)); + LNewActualBlock.AllocationGroup := LActualBlock.AllocationGroup; + LNewActualBlock.AllocationNumber := LActualBlock.AllocationNumber; + {Recalculate the header and footer checksums} + UpdateHeaderAndFooterCheckSums(LNewActualBlock); + {$ifdef FullDebugModeCallBacks} + if Assigned(OnDebugReallocMemFinish) then + OnDebugReallocMemFinish(LNewActualBlock, ANewSize); + {$endif} + finally + {Block scans can again be performed safely} + DoneChangingFullDebugModeBlock; + end; + {How many bytes to move?} + LMoveSize := LActualBlock.UserSize; + if LMoveSize > NativeUInt(ANewSize) then + LMoveSize := ANewSize; + {Move the data across} + System.Move(APointer^, Result^, LMoveSize); + {Free the old block} + DebugFreeMem(APointer); + end + else + begin + Result := nil; + end; + end + else + begin + {Block scans may not be performed now} + StartChangingFullDebugModeBlock; + try + {$ifdef FullDebugModeCallBacks} + if Assigned(OnDebugReallocMemStart) then + OnDebugReallocMemStart(LActualBlock, ANewSize); + {$endif} + {Clear all data after the new end of the block up to the old end of the + block, including the trailer.} + DebugFillMem(Pointer(PByte(APointer) + NativeUInt(ANewSize) + SizeOf(NativeUInt))^, + NativeInt(LActualBlock.UserSize) - ANewSize, +{$ifndef CatchUseOfFreedInterfaces} + DebugFillPattern); +{$else} + RotateRight(NativeUInt(@VMTBadInterface), (ANewSize and (SizeOf(Pointer) - 1)) * 8)); +{$endif} + {Update the user size} + LActualBlock.UserSize := ANewSize; + {Set the new checksums} + UpdateHeaderAndFooterCheckSums(LActualBlock); + {$ifdef FullDebugModeCallBacks} + if Assigned(OnDebugReallocMemFinish) then + OnDebugReallocMemFinish(LActualBlock, ANewSize); + {$endif} + finally + {Block scans can again be performed safely} + DoneChangingFullDebugModeBlock; + end; + {Return the old pointer} + Result := APointer; + end; + end + else + begin + Result := nil; + end; +end; + +{Allocates a block and fills it with zeroes} +function DebugAllocMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Cardinal{$endif}): Pointer; +begin + Result := DebugGetMem(ASize); + {Clear the block} + if Result <> nil then + FillChar(Result^, ASize, 0); +end; + +{Raises a runtime error if a memory corruption was encountered. Subroutine for + InternalScanMemoryPool and InternalScanSmallBlockPool.} +procedure RaiseMemoryCorruptionError; +begin + {Disable exhaustive checking in order to prevent recursive exceptions.} + FullDebugModeScanMemoryPoolBeforeEveryOperation := False; + {Unblock the memory manager in case the creation of the exception below + causes an attempt to be made to allocate memory.} + UnblockFullDebugModeMMRoutines; + {Raise the runtime error} +{$ifdef BCB6OrDelphi7AndUp} + System.Error(reOutOfMemory); +{$else} + System.RunError(reOutOfMemory); +{$endif} +end; + +{Subroutine for InternalScanMemoryPool: Checks the given small block pool for + allocated blocks} +procedure InternalScanSmallBlockPool(APSmallBlockPool: PSmallBlockPoolHeader; + AFirstAllocationGroupToLog, ALastAllocationGroupToLog: Cardinal); +var + LCurPtr, LEndPtr: Pointer; +begin + {Get the first and last pointer for the pool} + GetFirstAndLastSmallBlockInPool(APSmallBlockPool, LCurPtr, LEndPtr); + {Step through all blocks} + while UIntPtr(LCurPtr) <= UIntPtr(LEndPtr) do + begin + {Is this block in use? If so, is the debug info intact?} + if ((PNativeUInt(PByte(LCurPtr) - BlockHeaderSize)^ and IsFreeBlockFlag) = 0) then + begin + if CheckBlockBeforeFreeOrRealloc(LCurPtr, boBlockCheck) then + begin + if (PFullDebugBlockHeader(LCurPtr).AllocationGroup >= AFirstAllocationGroupToLog) + and (PFullDebugBlockHeader(LCurPtr).AllocationGroup <= ALastAllocationGroupToLog) then + begin + LogMemoryLeakOrAllocatedBlock(LCurPtr, False); + end; + end + else + RaiseMemoryCorruptionError; + end + else + begin + {Check that the block has not been modified since being freed} + if not CheckFreeBlockUnmodified(LCurPtr, APSmallBlockPool.BlockType.BlockSize, boBlockCheck) then + RaiseMemoryCorruptionError; + end; + {Next block} + Inc(PByte(LCurPtr), APSmallBlockPool.BlockType.BlockSize); + end; +end; + +{Subroutine for LogAllocatedBlocksToFile and ScanMemoryPoolForCorruptions: + Scans the memory pool for corruptions and optionally logs allocated blocks + in the allocation group range.} +procedure InternalScanMemoryPool(AFirstAllocationGroupToLog, ALastAllocationGroupToLog: Cardinal); +var + LPLargeBlock: PLargeBlockHeader; + LPMediumBlock: Pointer; + LPMediumBlockPoolHeader: PMediumBlockPoolHeader; + LMediumBlockHeader: NativeUInt; +begin + {Block all the memory manager routines while performing the scan. No memory + block may be allocated or freed, and no FullDebugMode block header or + footer may be modified, while the scan is in progress.} + BlockFullDebugModeMMRoutines; + try + {Step through all the medium block pools} + LPMediumBlockPoolHeader := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader; + while LPMediumBlockPoolHeader <> @MediumBlockPoolsCircularList do + begin + LPMediumBlock := GetFirstMediumBlockInPool(LPMediumBlockPoolHeader); + while LPMediumBlock <> nil do + begin + LMediumBlockHeader := PNativeUInt(PByte(LPMediumBlock) - BlockHeaderSize)^; + {Is the block in use?} + if LMediumBlockHeader and IsFreeBlockFlag = 0 then + begin + {Block is in use: Is it a medium block or small block pool?} + if (LMediumBlockHeader and IsSmallBlockPoolInUseFlag) <> 0 then + begin + {Get all the leaks for the small block pool} + InternalScanSmallBlockPool(LPMediumBlock, AFirstAllocationGroupToLog, ALastAllocationGroupToLog); + end + else + begin + if CheckBlockBeforeFreeOrRealloc(LPMediumBlock, boBlockCheck) then + begin + if (PFullDebugBlockHeader(LPMediumBlock).AllocationGroup >= AFirstAllocationGroupToLog) + and (PFullDebugBlockHeader(LPMediumBlock).AllocationGroup <= ALastAllocationGroupToLog) then + begin + LogMemoryLeakOrAllocatedBlock(LPMediumBlock, False); + end; + end + else + RaiseMemoryCorruptionError; + end; + end + else + begin + {Check that the block has not been modified since being freed} + if not CheckFreeBlockUnmodified(LPMediumBlock, LMediumBlockHeader and DropMediumAndLargeFlagsMask, boBlockCheck) then + RaiseMemoryCorruptionError; + end; + {Next medium block} + LPMediumBlock := NextMediumBlock(LPMediumBlock); + end; + {Get the next medium block pool} + LPMediumBlockPoolHeader := LPMediumBlockPoolHeader.NextMediumBlockPoolHeader; + end; + {Scan large blocks} + LPLargeBlock := LargeBlocksCircularList.NextLargeBlockHeader; + while LPLargeBlock <> @LargeBlocksCircularList do + begin + if CheckBlockBeforeFreeOrRealloc(Pointer(PByte(LPLargeBlock) + LargeBlockHeaderSize), boBlockCheck) then + begin + if (PFullDebugBlockHeader(PByte(LPLargeBlock) + LargeBlockHeaderSize).AllocationGroup >= AFirstAllocationGroupToLog) + and (PFullDebugBlockHeader(PByte(LPLargeBlock) + LargeBlockHeaderSize).AllocationGroup <= ALastAllocationGroupToLog) then + begin + LogMemoryLeakOrAllocatedBlock(Pointer(PByte(LPLargeBlock) + LargeBlockHeaderSize), False); + end; + end + else + RaiseMemoryCorruptionError; + {Get the next large block} + LPLargeBlock := LPLargeBlock.NextLargeBlockHeader; + end; + finally + {Unblock the FullDebugMode memory manager routines.} + UnblockFullDebugModeMMRoutines; + end; +end; + +{Logs detail about currently allocated memory blocks for the specified range of + allocation groups. if ALastAllocationGroupToLog is less than + AFirstAllocationGroupToLog or it is zero, then all allocation groups are + logged. This routine also checks the memory pool for consistency at the same + time, raising an "Out of Memory" error if the check fails.} +procedure LogAllocatedBlocksToFile(AFirstAllocationGroupToLog, ALastAllocationGroupToLog: Cardinal); +begin + {Validate input} + if (ALastAllocationGroupToLog = 0) or (ALastAllocationGroupToLog < AFirstAllocationGroupToLog) then + begin + {Bad input: log all groups} + AFirstAllocationGroupToLog := 0; + ALastAllocationGroupToLog := $ffffffff; + end; + {Scan the memory pool, logging allocated blocks in the requested range.} + InternalScanMemoryPool(AFirstAllocationGroupToLog, ALastAllocationGroupToLog); +end; + +{Scans the memory pool for any corruptions. If a corruption is encountered an "Out of Memory" exception is + raised.} +procedure ScanMemoryPoolForCorruptions; +begin + {Scan the memory pool for corruptions, but don't log any allocated blocks} + InternalScanMemoryPool($ffffffff, 0); +end; + +{-----------------------Invalid Virtual Method Calls-------------------------} + +{ TFreedObject } + +{Used to determine the index of the virtual method call on the freed object. + Do not change this without updating MaxFakeVMTEntries. Currently 200.} +procedure TFreedObject.GetVirtualMethodIndex; +asm + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); Inc(VMIndex); + + jmp TFreedObject.VirtualMethodError +end; + +procedure TFreedObject.VirtualMethodError; +var + LVMOffset: Integer; + LMsgPtr: PAnsiChar; + LErrorMessage: array[0..32767] of AnsiChar; +{$ifndef NoMessageBoxes} + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} + LClass: TClass; + LActualBlock: PFullDebugBlockHeader; +begin + {Get the offset of the virtual method} + LVMOffset := (MaxFakeVMTEntries - VMIndex) * SizeOf(Pointer) + vmtParent + SizeOf(Pointer); + {Reset the index for the next error} + VMIndex := 0; + {Get the address of the actual block} + LActualBlock := PFullDebugBlockHeader(PByte(Self) - SizeOf(TFullDebugBlockHeader)); + {Display the error header} + LMsgPtr := AppendStringToBuffer(VirtualMethodErrorHeader, @LErrorMessage[0], Length(VirtualMethodErrorHeader)); + {Is the debug info surrounding the block valid?} + if CalculateHeaderCheckSum(LActualBlock) = LActualBlock.HeaderCheckSum then + begin + {Get the class this block was used for previously} + LClass := DetectClassInstance(@LActualBlock.PreviouslyUsedByClass); + if (LClass <> nil) and (IntPtr(LClass) <> IntPtr(@FreedObjectVMT.VMTMethods[0])) then + begin + LMsgPtr := AppendStringToBuffer(FreedObjectClassMsg, LMsgPtr, Length(FreedObjectClassMsg)); + LMsgPtr := AppendClassNameToBuffer(LClass, LMsgPtr); + end; + {Get the virtual method name} + LMsgPtr := AppendStringToBuffer(VirtualMethodName, LMsgPtr, Length(VirtualMethodName)); + if LVMOffset < 0 then + begin + LMsgPtr := AppendStringToBuffer(StandardVirtualMethodNames[LVMOffset div SizeOf(Pointer)], LMsgPtr, Length(StandardVirtualMethodNames[LVMOffset div SizeOf(Pointer)])); + end + else + begin + LMsgPtr := AppendStringToBuffer(VirtualMethodOffset, LMsgPtr, Length(VirtualMethodOffset)); + LMsgPtr := NativeUIntToStrBuf(LVMOffset, LMsgPtr); + end; + {Virtual method address} + if (LClass <> nil) and (IntPtr(LClass) <> IntPtr(@FreedObjectVMT.VMTMethods[0])) then + begin + LMsgPtr := AppendStringToBuffer(VirtualMethodAddress, LMsgPtr, Length(VirtualMethodAddress)); + LMsgPtr := NativeUIntToHexBuf(PNativeUInt(PByte(LClass) + LVMOffset)^, LMsgPtr); + end; + {Log the allocation group} + if LActualBlock.AllocationGroup > 0 then + begin + LMsgPtr := AppendStringToBuffer(PreviousAllocationGroupMsg, LMsgPtr, Length(PreviousAllocationGroupMsg)); + LMsgPtr := NativeUIntToStrBuf(LActualBlock.AllocationGroup, LMsgPtr); + end; + {Log the allocation number} + LMsgPtr := AppendStringToBuffer(PreviousAllocationNumberMsg, LMsgPtr, Length(PreviousAllocationNumberMsg)); + LMsgPtr := NativeUIntToStrBuf(LActualBlock.AllocationNumber, LMsgPtr); + {The header is still intact - display info about the this/previous allocation} + if LActualBlock.AllocationStackTrace[0] <> 0 then + begin + LMsgPtr := AppendStringToBuffer(ThreadIDAtObjectAllocMsg, LMsgPtr, Length(ThreadIDAtObjectAllocMsg)); + LMsgPtr := NativeUIntToHexBuf(LActualBlock.AllocatedByThread, LMsgPtr); + LMsgPtr := AppendStringToBuffer(StackTraceMsg, LMsgPtr, Length(StackTraceMsg)); + LMsgPtr := LogStackTrace(@LActualBlock.AllocationStackTrace, StackTraceDepth, LMsgPtr); + end; + {Get the call stack for the previous free} + if LActualBlock.FreeStackTrace[0] <> 0 then + begin + LMsgPtr := AppendStringToBuffer(ThreadIDAtObjectFreeMsg, LMsgPtr, Length(ThreadIDAtObjectFreeMsg)); + LMsgPtr := NativeUIntToHexBuf(LActualBlock.FreedByThread, LMsgPtr); + LMsgPtr := AppendStringToBuffer(StackTraceMsg, LMsgPtr, Length(StackTraceMsg)); + LMsgPtr := LogStackTrace(@LActualBlock.FreeStackTrace, StackTraceDepth, LMsgPtr); + end; + end + else + begin + {Header has been corrupted} + LMsgPtr := AppendStringToBuffer(BlockHeaderCorruptedNoHistoryMsg, LMsgPtr, Length(BlockHeaderCorruptedNoHistoryMsg)); + end; + {Add the current stack trace} + LMsgPtr := LogCurrentThreadAndStackTrace(2, LMsgPtr); +{$ifndef DisableLoggingOfMemoryDumps} + {Add the pointer address} + LMsgPtr := LogMemoryDump(LActualBlock, LMsgPtr); +{$endif} + {Trailing CRLF} + LMsgPtr^ := #13; + Inc(LMsgPtr); + LMsgPtr^ := #10; + Inc(LMsgPtr); + {Trailing #0} + LMsgPtr^ := #0; +{$ifdef LogErrorsToFile} + {Log the error} + AppendEventLog(@LErrorMessage[0], NativeUInt(LMsgPtr) - NativeUInt(@LErrorMessage[0])); +{$endif} +{$ifdef UseOutputDebugString} + OutputDebugStringA(LErrorMessage); +{$endif} +{$ifndef NoMessageBoxes} + {Show the message} + AppendStringToModuleName(BlockErrorMsgTitle, LErrorMessageTitle); + ShowMessageBox(LErrorMessage, LErrorMessageTitle); +{$endif} + {Raise an access violation} + RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, nil); +end; + +{$ifdef CatchUseOfFreedInterfaces} +procedure TFreedObject.InterfaceError; +var + LMsgPtr: PAnsiChar; +{$ifndef NoMessageBoxes} + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} + LErrorMessage: array[0..4000] of AnsiChar; +begin + {Display the error header} + LMsgPtr := AppendStringToBuffer(InterfaceErrorHeader, @LErrorMessage[0], Length(InterfaceErrorHeader)); + {Add the current stack trace} + LMsgPtr := LogCurrentThreadAndStackTrace(2, LMsgPtr); + {Trailing CRLF} + LMsgPtr^ := #13; + Inc(LMsgPtr); + LMsgPtr^ := #10; + Inc(LMsgPtr); + {Trailing #0} + LMsgPtr^ := #0; +{$ifdef LogErrorsToFile} + {Log the error} + AppendEventLog(@LErrorMessage[0], NativeUInt(LMsgPtr) - NativeUInt(@LErrorMessage[0])); +{$endif} +{$ifdef UseOutputDebugString} + OutputDebugStringA(LErrorMessage); +{$endif} +{$ifndef NoMessageBoxes} + {Show the message} + AppendStringToModuleName(BlockErrorMsgTitle, LErrorMessageTitle); + ShowMessageBox(LErrorMessage, LErrorMessageTitle); +{$endif} + {Raise an access violation} + RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, nil); +end; +{$endif} + +{$endif} + +{----------------------------Memory Leak Checking-----------------------------} + +{$ifdef EnableMemoryLeakReporting} + +{Adds a leak to the specified list} +function UpdateExpectedLeakList(APLeakList: PPExpectedMemoryLeak; + APNewEntry: PExpectedMemoryLeak; AExactSizeMatch: Boolean = True): Boolean; +var + LPInsertAfter, LPNewEntry: PExpectedMemoryLeak; +begin + {Default to error} + Result := False; + {Find the insertion spot} + LPInsertAfter := APLeakList^; + while LPInsertAfter <> nil do + begin + {Too big?} + if LPInsertAfter.LeakSize > APNewEntry.LeakSize then + begin + LPInsertAfter := LPInsertAfter.PreviousLeak; + Break; + end; + {Find a matching entry. If an exact size match is not required and the leak + is larger than the current entry, use it if the expected size of the next + entry is too large.} + if (IntPtr(LPInsertAfter.LeakAddress) = IntPtr(APNewEntry.LeakAddress)) + and ((IntPtr(LPInsertAfter.LeakedClass) = IntPtr(APNewEntry.LeakedClass)) + {$ifdef CheckCppObjectTypeEnabled} + or (LPInsertAfter.LeakedCppTypeIdPtr = APNewEntry.LeakedCppTypeIdPtr) + {$endif} + ) + and ((LPInsertAfter.LeakSize = APNewEntry.LeakSize) + or ((not AExactSizeMatch) + and (LPInsertAfter.LeakSize < APNewEntry.LeakSize) + and ((LPInsertAfter.NextLeak = nil) + or (LPInsertAfter.NextLeak.LeakSize > APNewEntry.LeakSize)) + )) then + begin + if (LPInsertAfter.LeakCount + APNewEntry.LeakCount) >= 0 then + begin + Inc(LPInsertAfter.LeakCount, APNewEntry.LeakCount); + {Is the count now 0?} + if LPInsertAfter.LeakCount = 0 then + begin + {Delete the entry} + if LPInsertAfter.NextLeak <> nil then + LPInsertAfter.NextLeak.PreviousLeak := LPInsertAfter.PreviousLeak; + if LPInsertAfter.PreviousLeak <> nil then + LPInsertAfter.PreviousLeak.NextLeak := LPInsertAfter.NextLeak + else + APLeakList^ := LPInsertAfter.NextLeak; + {Insert it as the first free slot} + LPInsertAfter.NextLeak := ExpectedMemoryLeaks.FirstFreeSlot; + ExpectedMemoryLeaks.FirstFreeSlot := LPInsertAfter; + end; + Result := True; + end; + Exit; + end; + {Next entry} + if LPInsertAfter.NextLeak <> nil then + LPInsertAfter := LPInsertAfter.NextLeak + else + Break; + end; + if APNewEntry.LeakCount > 0 then + begin + {Get a position for the entry} + LPNewEntry := ExpectedMemoryLeaks.FirstFreeSlot; + if LPNewEntry <> nil then + begin + ExpectedMemoryLeaks.FirstFreeSlot := LPNewEntry.NextLeak; + end + else + begin + if ExpectedMemoryLeaks.EntriesUsed < Length(ExpectedMemoryLeaks.ExpectedLeaks) then + begin + LPNewEntry := @ExpectedMemoryLeaks.ExpectedLeaks[ExpectedMemoryLeaks.EntriesUsed]; + Inc(ExpectedMemoryLeaks.EntriesUsed); + end + else + begin + {No more space} + Exit; + end; + end; + {Set the entry} + LPNewEntry^ := APNewEntry^; + {Insert it into the list} + LPNewEntry.PreviousLeak := LPInsertAfter; + if LPInsertAfter <> nil then + begin + LPNewEntry.NextLeak := LPInsertAfter.NextLeak; + if LPNewEntry.NextLeak <> nil then + LPNewEntry.NextLeak.PreviousLeak := LPNewEntry; + LPInsertAfter.NextLeak := LPNewEntry; + end + else + begin + LPNewEntry.NextLeak := APLeakList^; + if LPNewEntry.NextLeak <> nil then + LPNewEntry.NextLeak.PreviousLeak := LPNewEntry; + APLeakList^ := LPNewEntry; + end; + Result := True; + end; +end; + +{Locks the expected leaks. Returns false if the list could not be allocated.} +function LockExpectedMemoryLeaksList: Boolean; +begin + {Lock the expected leaks list} +{$ifndef AssumeMultiThreaded} + if IsMultiThread then +{$endif} + begin + while LockCmpxchg(0, 1, @ExpectedMemoryLeaksListLocked) <> 0 do + begin +{$ifdef NeverSleepOnThreadContention} + {$ifdef UseSwitchToThread} + SwitchToThread; + {$endif} +{$else} + Sleep(InitialSleepTime); + if LockCmpxchg(0, 1, @ExpectedMemoryLeaksListLocked) = 0 then + Break; + Sleep(AdditionalSleepTime); +{$endif} + end; + end; + {Allocate the list if it does not exist} + if ExpectedMemoryLeaks = nil then + ExpectedMemoryLeaks := VirtualAlloc(nil, ExpectedMemoryLeaksListSize, MEM_COMMIT, PAGE_READWRITE); + {Done} + Result := ExpectedMemoryLeaks <> nil; +end; + +{Registers expected memory leaks. Returns true on success. The list of leaked + blocks is limited, so failure is possible if the list is full.} +function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; overload; +var + LNewEntry: TExpectedMemoryLeak; +begin + {Fill out the structure} +{$ifndef FullDebugMode} + LNewEntry.LeakAddress := ALeakedPointer; +{$else} + LNewEntry.LeakAddress := Pointer(PByte(ALeakedPointer) - SizeOf(TFullDebugBlockHeader)); +{$endif} + LNewEntry.LeakedClass := nil; + {$ifdef CheckCppObjectTypeEnabled} + LNewEntry.LeakedCppTypeIdPtr := nil; + {$endif} + LNewEntry.LeakSize := 0; + LNewEntry.LeakCount := 1; + {Add it to the correct list} + Result := LockExpectedMemoryLeaksList + and UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryByAddress, @LNewEntry); + ExpectedMemoryLeaksListLocked := False; +end; + +function RegisterExpectedMemoryLeak(ALeakedObjectClass: TClass; ACount: Integer = 1): Boolean; overload; +var + LNewEntry: TExpectedMemoryLeak; +begin + {Fill out the structure} + LNewEntry.LeakAddress := nil; + LNewEntry.LeakedClass := ALeakedObjectClass; + {$ifdef CheckCppObjectTypeEnabled} + LNewEntry.LeakedCppTypeIdPtr := nil; + {$endif} + LNewEntry.LeakSize := ALeakedObjectClass.InstanceSize; + LNewEntry.LeakCount := ACount; + {Add it to the correct list} + Result := LockExpectedMemoryLeaksList + and UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryByClass, @LNewEntry); + ExpectedMemoryLeaksListLocked := False; +end; + +{$ifdef CheckCppObjectTypeEnabled} +function RegisterExpectedMemoryLeak(ALeakedCppVirtObjTypeIdPtr: Pointer; ACount: Integer): Boolean; overload; +var + LNewEntry: TExpectedMemoryLeak; +begin + {Fill out the structure} + if Assigned(GetCppVirtObjSizeByTypeIdPtrFunc) then + begin + //Return 0 if not a proper type + LNewEntry.LeakSize := GetCppVirtObjSizeByTypeIdPtrFunc(ALeakedCppVirtObjTypeIdPtr); + if LNewEntry.LeakSize > 0 then + begin + LNewEntry.LeakAddress := nil; + LNewEntry.LeakedClass := nil; + LNewEntry.LeakedCppTypeIdPtr := ALeakedCppVirtObjTypeIdPtr; + LNewEntry.LeakCount := ACount; + {Add it to the correct list} + Result := LockExpectedMemoryLeaksList + and UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryByClass, @LNewEntry); + ExpectedMemoryLeaksListLocked := False; + end + else + begin + Result := False; + end; + end + else + begin + Result := False; + end; +end; +{$endif} + +function RegisterExpectedMemoryLeak(ALeakedBlockSize: NativeInt; ACount: Integer = 1): Boolean; overload; +var + LNewEntry: TExpectedMemoryLeak; +begin + {Fill out the structure} + LNewEntry.LeakAddress := nil; + LNewEntry.LeakedClass := nil; + {$ifdef CheckCppObjectTypeEnabled} + LNewEntry.LeakedCppTypeIdPtr := nil; + {$endif} + LNewEntry.LeakSize := ALeakedBlockSize; + LNewEntry.LeakCount := ACount; + {Add it to the correct list} + Result := LockExpectedMemoryLeaksList + and UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryBySizeOnly, @LNewEntry); + ExpectedMemoryLeaksListLocked := False; +end; + +function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; overload; +var + LNewEntry: TExpectedMemoryLeak; +begin + {Fill out the structure} +{$ifndef FullDebugMode} + LNewEntry.LeakAddress := ALeakedPointer; +{$else} + LNewEntry.LeakAddress := Pointer(PByte(ALeakedPointer) - SizeOf(TFullDebugBlockHeader)); +{$endif} + LNewEntry.LeakedClass := nil; + {$ifdef CheckCppObjectTypeEnabled} + LNewEntry.LeakedCppTypeIdPtr := nil; + {$endif} + LNewEntry.LeakSize := 0; + LNewEntry.LeakCount := -1; + {Remove it from the list} + Result := LockExpectedMemoryLeaksList + and UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryByAddress, @LNewEntry); + ExpectedMemoryLeaksListLocked := False; +end; + +function UnregisterExpectedMemoryLeak(ALeakedObjectClass: TClass; ACount: Integer = 1): Boolean; overload; +begin + Result := RegisterExpectedMemoryLeak(ALeakedObjectClass, - ACount); +end; + +{$ifdef CheckCppObjectTypeEnabled} +function UnregisterExpectedMemoryLeak(ALeakedCppVirtObjTypeIdPtr: Pointer; ACount: Integer): Boolean; overload; +begin + Result := RegisterExpectedMemoryLeak(ALeakedCppVirtObjTypeIdPtr, - ACount); +end; +{$endif} + +function UnregisterExpectedMemoryLeak(ALeakedBlockSize: NativeInt; ACount: Integer = 1): Boolean; overload; +begin + Result := RegisterExpectedMemoryLeak(ALeakedBlockSize, - ACount); +end; + +{Returns a list of all expected memory leaks} +function GetRegisteredMemoryLeaks: TRegisteredMemoryLeaks; + + procedure AddEntries(AEntry: PExpectedMemoryLeak); + var + LInd: Integer; + begin + while AEntry <> nil do + begin + LInd := Length(Result); + SetLength(Result, LInd + 1); + {Add the entry} +{$ifndef FullDebugMode} + Result[LInd].LeakAddress := AEntry.LeakAddress; +{$else} + Result[LInd].LeakAddress := Pointer(PByte(AEntry.LeakAddress) + SizeOf(TFullDebugBlockHeader)); +{$endif} + Result[LInd].LeakedClass := AEntry.LeakedClass; +{$ifdef CheckCppObjectTypeEnabled} + Result[LInd].LeakedCppTypeIdPtr := AEntry.LeakedCppTypeIdPtr; +{$endif} + Result[LInd].LeakSize := AEntry.LeakSize; + Result[LInd].LeakCount := AEntry.LeakCount; + {Next entry} + AEntry := AEntry.NextLeak; + end; + end; + +begin + SetLength(Result, 0); + if (ExpectedMemoryLeaks <> nil) and LockExpectedMemoryLeaksList then + begin + {Add all entries} + AddEntries(ExpectedMemoryLeaks.FirstEntryByAddress); + AddEntries(ExpectedMemoryLeaks.FirstEntryByClass); + AddEntries(ExpectedMemoryLeaks.FirstEntryBySizeOnly); + {Unlock the list} + ExpectedMemoryLeaksListLocked := False; + end; +end; + +{$else} + {$ifdef BDS2006AndUp} +function NoOpRegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; +begin + {Do nothing. Used when memory leak reporting is disabled under Delphi 2006 and later.} + Result := False; +end; + +function NoOpUnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; +begin + {Do nothing. Used when memory leak reporting is disabled under Delphi 2006 and later.} + Result := False; +end; + {$endif} +{$endif} + +{Detects the probable string data type for a memory block.} +function DetectStringData(APMemoryBlock: Pointer; + AAvailableSpaceInBlock: NativeInt): TStringDataType; +const + {If the string reference count field contains a value greater than this, + then it is assumed that the block is not a string.} + MaxRefCount = 255; + {The lowest ASCII character code considered valid string data. If there are + any characters below this code point then the data is assumed not to be a + string. #9 = Tab.} + MinCharCode = #9; +var + LStringLength, LElemSize, LCharInd: Integer; + LPAnsiStr: PAnsiChar; + LPUniStr: PWideChar; +begin + {Check that the reference count is within a reasonable range} + if PStrRec(APMemoryBlock).refCnt > MaxRefCount then + begin + Result := stUnknown; + Exit; + end; +{$ifdef BCB6OrDelphi6AndUp} + {$if RTLVersion >= 20} + LElemSize := PStrRec(APMemoryBlock).elemSize; + {Element size must be either 1 (Ansi) or 2 (Unicode)} + if (LElemSize <> 1) and (LElemSize <> 2) then + begin + Result := stUnknown; + Exit; + end; + {$ifend} + {$if RTLVersion < 20} + LElemSize := 1; + {$ifend} +{$else} + LElemSize := 1; +{$endif} + {Get the string length} + LStringLength := PStrRec(APMemoryBlock).length; + {Does the string fit?} + if (LStringLength <= 0) + or (LStringLength >= (AAvailableSpaceInBlock - SizeOf(StrRec)) div LElemSize) then + begin + Result := stUnknown; + Exit; + end; + {Check for no characters outside the expected range. If there are, + then it is probably not a string.} + if LElemSize = 1 then + begin + {Check that all characters are in the range considered valid.} + LPAnsiStr := PAnsiChar(PByte(APMemoryBlock) + SizeOf(StrRec)); + for LCharInd := 1 to LStringLength do + begin + if LPAnsiStr^ < MinCharCode then + begin + Result := stUnknown; + Exit; + end; + Inc(LPAnsiStr); + end; + {Must have a trailing #0} + if LPAnsiStr^ = #0 then + Result := stAnsiString + else + Result := stUnknown; + end + else + begin + {Check that all characters are in the range considered valid.} + LPUniStr := PWideChar(PByte(APMemoryBlock) + SizeOf(StrRec)); + for LCharInd := 1 to LStringLength do + begin + if LPUniStr^ < MinCharCode then + begin + Result := stUnknown; + Exit; + end; + Inc(LPUniStr); + end; + {Must have a trailing #0} + if LPUniStr^ = #0 then + Result := stUnicodeString + else + Result := stUnknown; + end; +end; + +{Checks blocks for modification after free and also for memory leaks} +procedure CheckBlocksOnShutdown(ACheckForLeakedBlocks: Boolean); +{$ifdef EnableMemoryLeakReporting} +type + {Leaked class type} + TLeakedClass = record + ClassPointer: TClass; + {$ifdef CheckCppObjectTypeEnabled} + CppTypeIdPtr: Pointer; + {$endif} + NumLeaks: Cardinal; + end; + TLeakedClasses = array[0..255] of TLeakedClass; + PLeakedClasses = ^TLeakedClasses; + {Leak statistics for a small block type} + TSmallBlockLeaks = array[0..NumSmallBlockTypes - 1] of TLeakedClasses; + {A leaked medium or large block} + TMediumAndLargeBlockLeaks = array[0..4095] of NativeUInt; +{$endif} +var +{$ifdef EnableMemoryLeakReporting} + {The leaked classes for small blocks} + LSmallBlockLeaks: TSmallBlockLeaks; + LLeakType: TMemoryLeakType; + {$ifdef CheckCppObjectTypeEnabled} + LLeakedCppTypeIdPtr: Pointer; + LCppTypeName: PAnsiChar; + {$endif} + LMediumAndLargeBlockLeaks: TMediumAndLargeBlockLeaks; + LNumMediumAndLargeLeaks: Integer; + LPLargeBlock: PLargeBlockHeader; + LLeakMessage: array[0..32767] of AnsiChar; + {$ifndef NoMessageBoxes} + LMessageTitleBuffer: array[0..1023] of AnsiChar; + {$endif} + LMsgPtr: PAnsiChar; + LExpectedLeaksOnly, LSmallLeakHeaderAdded, LBlockSizeHeaderAdded: Boolean; + LBlockTypeInd, LClassInd, LBlockInd: Cardinal; + LMediumBlockSize, LPreviousBlockSize, LLargeBlockSize, LThisBlockSize: NativeUInt; +{$endif} + LPMediumBlock: Pointer; + LPMediumBlockPoolHeader: PMediumBlockPoolHeader; + LMediumBlockHeader: NativeUInt; + +{$ifdef EnableMemoryLeakReporting} + {Tries to account for a memory leak. Returns true if the leak is expected and + removes the leak from the list} + function GetMemoryLeakType(AAddress: Pointer; ASpaceInsideBlock: NativeUInt): TMemoryLeakType; + var + LLeak: TExpectedMemoryLeak; + begin + {Default to not found} + Result := mltUnexpectedLeak; + if ExpectedMemoryLeaks <> nil then + begin + {Check by pointer address} + LLeak.LeakAddress := AAddress; + LLeak.LeakedClass := nil; + {$ifdef CheckCppObjectTypeEnabled} + LLeak.LeakedCppTypeIdPtr := nil; + {$endif} + LLeak.LeakSize := 0; + LLeak.LeakCount := -1; + if UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryByAddress, @LLeak, False) then + begin + Result := mltExpectedLeakRegisteredByPointer; + Exit; + end; + {Check by class} + LLeak.LeakAddress := nil; + {$ifdef FullDebugMode} + LLeak.LeakedClass := TClass(PNativeUInt(PByte(AAddress)+ SizeOf(TFullDebugBlockHeader))^); + {$else} + LLeak.LeakedClass := TClass(PNativeUInt(AAddress)^); + {$endif} + {$ifdef CheckCppObjectTypeEnabled} + if Assigned(GetCppVirtObjTypeIdPtrFunc) then + begin + {$ifdef FullDebugMode} + LLeak.LeakedCppTypeIdPtr := GetCppVirtObjTypeIdPtrFunc(Pointer(PByte(AAddress) + + SizeOf(TFullDebugBlockHeader)), ASpaceInsideBlock); + {$else} + LLeak.LeakedCppTypeIdPtr := GetCppVirtObjTypeIdPtrFunc(AAddress, ASpaceInsideBlock); + {$endif} + end; + LLeakedCppTypeIdPtr := LLeak.LeakedCppTypeIdPtr; + {$endif} + LLeak.LeakSize := ASpaceInsideBlock; + if UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryByClass, @LLeak, False) then + begin + Result := mltExpectedLeakRegisteredByClass; + Exit; + end; + {Check by size: the block must be large enough to hold the leak} + LLeak.LeakedClass := nil; + if UpdateExpectedLeakList(@ExpectedMemoryLeaks.FirstEntryBySizeOnly, @LLeak, False) then + Result := mltExpectedLeakRegisteredBySize; + end; + end; + + {Checks the small block pool for leaks.} + procedure CheckSmallBlockPoolForLeaks(APSmallBlockPool: PSmallBlockPoolHeader); + var + LLeakedClass: TClass; + {$ifdef CheckCppObjectTypeEnabled} + LLeakedCppObjectTypeId: Pointer; + {$endif} + LSmallBlockLeakType: TMemoryLeakType; + LClassIndex: Integer; + LCurPtr, LEndPtr, LDataPtr: Pointer; + LBlockTypeIndex: Cardinal; + LPLeakedClasses: PLeakedClasses; + LSmallBlockSize: Cardinal; + begin + {Get the useable size inside a block} + LSmallBlockSize := APSmallBlockPool.BlockType.BlockSize - BlockHeaderSize; + {$ifdef FullDebugMode} + Dec(LSmallBlockSize, FullDebugBlockOverhead); + {$endif} + {Get the block type index} + LBlockTypeIndex := (UIntPtr(APSmallBlockPool.BlockType) - UIntPtr(@SmallBlockTypes[0])) div SizeOf(TSmallBlockType); + LPLeakedClasses := @LSmallBlockLeaks[LBlockTypeIndex]; + {Get the first and last pointer for the pool} + GetFirstAndLastSmallBlockInPool(APSmallBlockPool, LCurPtr, LEndPtr); + {Step through all blocks} + while UIntPtr(LCurPtr) <= UIntPtr(LEndPtr) do + begin + {Is this block in use? If so, is the debug info intact?} + if ((PNativeUInt(PByte(LCurPtr) - BlockHeaderSize)^ and IsFreeBlockFlag) = 0) then + begin + {$ifdef FullDebugMode} + if CheckBlockBeforeFreeOrRealloc(LCurPtr, boBlockCheck) then + {$endif} + begin + {$ifdef CheckCppObjectTypeEnabled} + LLeakedCppTypeIdPtr := nil; + {$endif} + {Get the leak type} + LSmallBlockLeakType := GetMemoryLeakType(LCurPtr, LSmallBlockSize); + {$ifdef LogMemoryLeakDetailToFile} + {$ifdef HideExpectedLeaksRegisteredByPointer} + if LSmallBlockLeakType <> mltExpectedLeakRegisteredByPointer then + {$endif} + LogMemoryLeakOrAllocatedBlock(LCurPtr, True); + {$endif} + {Only expected leaks?} + LExpectedLeaksOnly := LExpectedLeaksOnly and (LSmallBlockLeakType <> mltUnexpectedLeak); + {$ifdef HideExpectedLeaksRegisteredByPointer} + if LSmallBlockLeakType <> mltExpectedLeakRegisteredByPointer then + {$endif} + begin + {Get a pointer to the user data} + {$ifndef FullDebugMode} + LDataPtr := LCurPtr; + {$else} + LDataPtr := Pointer(PByte(LCurPtr) + SizeOf(TFullDebugBlockHeader)); + {$endif} + {Default to an unknown block} + LClassIndex := 0; + {Get the class contained by the block} + LLeakedClass := DetectClassInstance(LDataPtr); + {Not a Delphi class? -> is it perhaps a string or C++ object type?} + if LLeakedClass = nil then + begin + {$ifdef CheckCppObjectTypeEnabled} + LLeakedCppObjectTypeId := LLeakedCppTypeIdPtr; + if (LLeakedCppObjectTypeId = nil) and (ExpectedMemoryLeaks = nil) then + begin + if Assigned(GetCppVirtObjTypeIdPtrFunc) then + begin + LLeakedCppObjectTypeId := GetCppVirtObjTypeIdPtrFunc(LDataPtr, LSmallBlockSize); + end; + end; + if Assigned(LLeakedCppObjectTypeId) then + begin + LClassIndex := 3; + while LClassIndex <= High(TLeakedClasses) do + begin + if (Pointer(LPLeakedClasses[LClassIndex].CppTypeIdPtr) = LLeakedCppObjectTypeId) + or ((LPLeakedClasses[LClassIndex].CppTypeIdPtr = nil) + and (LPLeakedClasses[LClassIndex].ClassPointer = nil)) then + begin + Break; + end; + Inc(LClassIndex); + end; + if LClassIndex <= High(TLeakedClasses) then + Pointer(LPLeakedClasses[LClassIndex].CppTypeIdPtr) := LLeakedCppObjectTypeId + else + LClassIndex := 0; + end + else + begin + {$endif} + {Not a known class: Is it perhaps string data?} + case DetectStringData(LDataPtr, APSmallBlockPool.BlockType.BlockSize - (BlockHeaderSize {$ifdef FullDebugMode} + FullDebugBlockOverhead{$endif})) of + stAnsiString: LClassIndex := 1; + stUnicodeString: LClassIndex := 2; + end; + {$ifdef CheckCppObjectTypeEnabled} + end; + {$endif} + end + else + begin + LClassIndex := 3; + while LClassIndex <= High(TLeakedClasses) do + begin + if (LPLeakedClasses[LClassIndex].ClassPointer = LLeakedClass) + or ((LPLeakedClasses[LClassIndex].ClassPointer = nil) + {$ifdef CheckCppObjectTypeEnabled} + and (LPLeakedClasses[LClassIndex].CppTypeIdPtr = nil) + {$endif} + ) then + begin + Break; + end; + Inc(LClassIndex); + end; + if LClassIndex <= High(TLeakedClasses) then + LPLeakedClasses[LClassIndex].ClassPointer := LLeakedClass + else + LClassIndex := 0; + end; + {Add to the number of leaks for the class} + Inc(LPLeakedClasses[LClassIndex].NumLeaks); + end; + end; + end + else + begin + {$ifdef CheckUseOfFreedBlocksOnShutdown} + {Check that the block has not been modified since being freed} + CheckFreeBlockUnmodified(LCurPtr, APSmallBlockPool.BlockType.BlockSize, boBlockCheck); + {$endif} + end; + {Next block} + Inc(PByte(LCurPtr), APSmallBlockPool.BlockType.BlockSize); + end; + end; +{$endif} + +begin +{$ifdef EnableMemoryLeakReporting} + {Clear the leak arrays} + FillChar(LSmallBlockLeaks, SizeOf(LSmallBlockLeaks), 0); + FillChar(LMediumAndLargeBlockLeaks, SizeOf(LMediumAndLargeBlockLeaks), 0); + {Step through all the medium block pools} + LNumMediumAndLargeLeaks := 0; + {No unexpected leaks so far} + LExpectedLeaksOnly := True; +{$endif} + {Step through all the medium block pools} + LPMediumBlockPoolHeader := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader; + while LPMediumBlockPoolHeader <> @MediumBlockPoolsCircularList do + begin + LPMediumBlock := GetFirstMediumBlockInPool(LPMediumBlockPoolHeader); + while LPMediumBlock <> nil do + begin + LMediumBlockHeader := PNativeUInt(PByte(LPMediumBlock) - BlockHeaderSize)^; + {Is the block in use?} + if LMediumBlockHeader and IsFreeBlockFlag = 0 then + begin +{$ifdef EnableMemoryLeakReporting} + if ACheckForLeakedBlocks then + begin + if (LMediumBlockHeader and IsSmallBlockPoolInUseFlag) <> 0 then + begin + {Get all the leaks for the small block pool} + CheckSmallBlockPoolForLeaks(LPMediumBlock); + end + else + begin + if (LNumMediumAndLargeLeaks < Length(LMediumAndLargeBlockLeaks)) + {$ifdef FullDebugMode} + and CheckBlockBeforeFreeOrRealloc(LPMediumBlock, boBlockCheck) + {$endif} + then + begin + LMediumBlockSize := (LMediumBlockHeader and DropMediumAndLargeFlagsMask) - BlockHeaderSize; + {$ifdef FullDebugMode} + Dec(LMediumBlockSize, FullDebugBlockOverhead); + {$endif} + {Get the leak type} + LLeakType := GetMemoryLeakType(LPMediumBlock, LMediumBlockSize); + {Is it an expected leak?} + LExpectedLeaksOnly := LExpectedLeaksOnly and (LLeakType <> mltUnexpectedLeak); + {$ifdef LogMemoryLeakDetailToFile} + {$ifdef HideExpectedLeaksRegisteredByPointer} + if LLeakType <> mltExpectedLeakRegisteredByPointer then + {$endif} + LogMemoryLeakOrAllocatedBlock(LPMediumBlock, True); + {$endif} + {$ifdef HideExpectedLeaksRegisteredByPointer} + if LLeakType <> mltExpectedLeakRegisteredByPointer then + {$endif} + begin + {Add the leak to the list} + LMediumAndLargeBlockLeaks[LNumMediumAndLargeLeaks] := LMediumBlockSize; + Inc(LNumMediumAndLargeLeaks); + end; + end; + end; + end; +{$endif} + end + else + begin +{$ifdef CheckUseOfFreedBlocksOnShutdown} + {Check that the block has not been modified since being freed} + CheckFreeBlockUnmodified(LPMediumBlock, LMediumBlockHeader and DropMediumAndLargeFlagsMask, boBlockCheck); +{$endif} + end; + {Next medium block} + LPMediumBlock := NextMediumBlock(LPMediumBlock); + end; + {Get the next medium block pool} + LPMediumBlockPoolHeader := LPMediumBlockPoolHeader.NextMediumBlockPoolHeader; + end; +{$ifdef EnableMemoryLeakReporting} + if ACheckForLeakedBlocks then + begin + {Get all leaked large blocks} + LPLargeBlock := LargeBlocksCircularList.NextLargeBlockHeader; + while LPLargeBlock <> @LargeBlocksCircularList do + begin + if (LNumMediumAndLargeLeaks < length(LMediumAndLargeBlockLeaks)) + {$ifdef FullDebugMode} + and CheckBlockBeforeFreeOrRealloc(Pointer(PByte(LPLargeBlock) + LargeBlockHeaderSize), boBlockCheck) + {$endif} + then + begin + LLargeBlockSize := (LPLargeBlock.BlockSizeAndFlags and DropMediumAndLargeFlagsMask) - BlockHeaderSize - LargeBlockHeaderSize; + {$ifdef FullDebugMode} + Dec(LLargeBlockSize, FullDebugBlockOverhead); + {$endif} + {Get the leak type} + LLeakType := GetMemoryLeakType(Pointer(PByte(LPLargeBlock) + LargeBlockHeaderSize), LLargeBlockSize); + {Is it an expected leak?} + LExpectedLeaksOnly := LExpectedLeaksOnly and (LLeakType <> mltUnexpectedLeak); + {$ifdef LogMemoryLeakDetailToFile} + {$ifdef HideExpectedLeaksRegisteredByPointer} + if LLeakType <> mltExpectedLeakRegisteredByPointer then + {$endif} + LogMemoryLeakOrAllocatedBlock(Pointer(PByte(LPLargeBlock) + LargeBlockHeaderSize), True); + {$endif} + {$ifdef HideExpectedLeaksRegisteredByPointer} + if LLeakType <> mltExpectedLeakRegisteredByPointer then + {$endif} + begin + {Add the leak} + LMediumAndLargeBlockLeaks[LNumMediumAndLargeLeaks] := LLargeBlockSize; + Inc(LNumMediumAndLargeLeaks); + end; + end; + {Get the next large block} + LPLargeBlock := LPLargeBlock.NextLargeBlockHeader; + end; + {Display the leak message if required} + if not LExpectedLeaksOnly then + begin + {Small leak header has not been added} + LSmallLeakHeaderAdded := False; + LPreviousBlockSize := 0; + {Set up the leak message header so long} + LMsgPtr := AppendStringToBuffer(LeakMessageHeader, @LLeakMessage[0], length(LeakMessageHeader)); + {Step through all the small block types} + for LBlockTypeInd := 0 to NumSmallBlockTypes - 1 do + begin + LThisBlockSize := SmallBlockTypes[LBlockTypeInd].BlockSize - BlockHeaderSize; + {$ifdef FullDebugMode} + Dec(LThisBlockSize, FullDebugBlockOverhead); + if NativeInt(LThisBlockSize) < 0 then + LThisBlockSize := 0; + {$endif} + LBlockSizeHeaderAdded := False; + {Any leaks?} + for LClassInd := High(LSmallBlockLeaks[LBlockTypeInd]) downto 0 do + begin + {Is there still space in the message buffer? Reserve space for the message + footer.} + if LMsgPtr > @LLeakMessage[High(LLeakMessage) - 2048] then + Break; + {Check the count} + if LSmallBlockLeaks[LBlockTypeInd][LClassInd].NumLeaks > 0 then + begin + {Need to add the header?} + if not LSmallLeakHeaderAdded then + begin + LMsgPtr := AppendStringToBuffer(SmallLeakDetail, LMsgPtr, Length(SmallLeakDetail)); + LSmallLeakHeaderAdded := True; + end; + {Need to add the size header?} + if not LBlockSizeHeaderAdded then + begin + LMsgPtr^ := #13; + Inc(LMsgPtr); + LMsgPtr^ := #10; + Inc(LMsgPtr); + LMsgPtr := NativeUIntToStrBuf(LPreviousBlockSize + 1, LMsgPtr); + LMsgPtr^ := ' '; + Inc(LMsgPtr); + LMsgPtr^ := '-'; + Inc(LMsgPtr); + LMsgPtr^ := ' '; + Inc(LMsgPtr); + LMsgPtr := NativeUIntToStrBuf(LThisBlockSize, LMsgPtr); + LMsgPtr := AppendStringToBuffer(BytesMessage, LMsgPtr, Length(BytesMessage)); + LBlockSizeHeaderAdded := True; + end + else + begin + LMsgPtr^ := ','; + Inc(LMsgPtr); + LMsgPtr^ := ' '; + Inc(LMsgPtr); + end; + {Show the count} + case LClassInd of + {Unknown} + 0: + begin + LMsgPtr := AppendStringToBuffer(UnknownClassNameMsg, LMsgPtr, Length(UnknownClassNameMsg)); + end; + {AnsiString} + 1: + begin + LMsgPtr := AppendStringToBuffer(AnsiStringBlockMessage, LMsgPtr, Length(AnsiStringBlockMessage)); + end; + {UnicodeString} + 2: + begin + LMsgPtr := AppendStringToBuffer(UnicodeStringBlockMessage, LMsgPtr, Length(UnicodeStringBlockMessage)); + end; + {Classes} + else + begin + {$ifdef CheckCppObjectTypeEnabled} + if LSmallBlockLeaks[LBlockTypeInd][LClassInd].CppTypeIdPtr <> nil then + begin + if Assigned(GetCppVirtObjTypeNameByTypeIdPtrFunc) then + begin + LCppTypeName := GetCppVirtObjTypeNameByTypeIdPtrFunc(LSmallBlockLeaks[LBlockTypeInd][LClassInd].CppTypeIdPtr); + LMsgPtr := AppendStringToBuffer(LCppTypeName, LMsgPtr, StrLen(LCppTypeName)); + end + else + LMsgPtr := AppendClassNameToBuffer(nil, LMsgPtr); + end + else + begin + {$endif} + LMsgPtr := AppendClassNameToBuffer(LSmallBlockLeaks[LBlockTypeInd][LClassInd].ClassPointer, LMsgPtr); + {$ifdef CheckCppObjectTypeEnabled} + end; + {$endif} + end; + end; + {Add the count} + LMsgPtr^ := ' '; + Inc(LMsgPtr); + LMsgPtr^ := 'x'; + Inc(LMsgPtr); + LMsgPtr^ := ' '; + Inc(LMsgPtr); + LMsgPtr := NativeUIntToStrBuf(LSmallBlockLeaks[LBlockTypeInd][LClassInd].NumLeaks, LMsgPtr); + end; + end; + LPreviousBlockSize := LThisBlockSize; + end; + {Add the medium/large block leak message} + if LNumMediumAndLargeLeaks > 0 then + begin + {Any non-small leaks?} + if LSmallLeakHeaderAdded then + begin + LMsgPtr^ := #13; + Inc(LMsgPtr); + LMsgPtr^ := #10; + Inc(LMsgPtr); + LMsgPtr^ := #13; + Inc(LMsgPtr); + LMsgPtr^ := #10; + Inc(LMsgPtr); + end; + {Add the medium/large block leak message} + LMsgPtr := AppendStringToBuffer(LargeLeakDetail, LMsgPtr, Length(LargeLeakDetail)); + {List all the blocks} + for LBlockInd := 0 to LNumMediumAndLargeLeaks - 1 do + begin + if LBlockInd <> 0 then + begin + LMsgPtr^ := ','; + Inc(LMsgPtr); + LMsgPtr^ := ' '; + Inc(LMsgPtr); + end; + LMsgPtr := NativeUIntToStrBuf(LMediumAndLargeBlockLeaks[LBlockInd], LMsgPtr); + {Is there still space in the message buffer? Reserve space for the + message footer.} + if LMsgPtr > @LLeakMessage[High(LLeakMessage) - 2048] then + Break; + end; + end; + {$ifdef LogErrorsToFile} + {Set the message footer} + LMsgPtr := AppendStringToBuffer(LeakMessageFooter, LMsgPtr, Length(LeakMessageFooter)); + {Append the message to the memory errors file} + AppendEventLog(@LLeakMessage[0], UIntPtr(LMsgPtr) - UIntPtr(@LLeakMessage[1])); + {$else} + {Set the message footer} + AppendStringToBuffer(LeakMessageFooter, LMsgPtr, Length(LeakMessageFooter)); + {$endif} + {$ifdef UseOutputDebugString} + OutputDebugStringA(LLeakMessage); + {$endif} + {$ifndef NoMessageBoxes} + {Show the message} + AppendStringToModuleName(LeakMessageTitle, LMessageTitleBuffer); + ShowMessageBox(LLeakMessage, LMessageTitleBuffer); + {$endif} + end; + end; +{$endif} +end; + +{Returns statistics about the current state of the memory manager} +procedure GetMemoryManagerState(var AMemoryManagerState: TMemoryManagerState); +var + LPMediumBlockPoolHeader: PMediumBlockPoolHeader; + LPMediumBlock: Pointer; + LInd: Integer; + LBlockTypeIndex, LMediumBlockSize: Cardinal; + LMediumBlockHeader, LLargeBlockSize: NativeUInt; + LPLargeBlock: PLargeBlockHeader; +begin + {Clear the structure} + FillChar(AMemoryManagerState, SizeOf(AMemoryManagerState), 0); + {Set the small block size stats} + for LInd := 0 to NumSmallBlockTypes - 1 do + begin + AMemoryManagerState.SmallBlockTypeStates[LInd].InternalBlockSize := + SmallBlockTypes[LInd].BlockSize; + AMemoryManagerState.SmallBlockTypeStates[LInd].UseableBlockSize := + SmallBlockTypes[LInd].BlockSize - BlockHeaderSize{$ifdef FullDebugMode} - FullDebugBlockOverhead{$endif}; + if NativeInt(AMemoryManagerState.SmallBlockTypeStates[LInd].UseableBlockSize) < 0 then + AMemoryManagerState.SmallBlockTypeStates[LInd].UseableBlockSize := 0; + end; + {Lock all small block types} + LockAllSmallBlockTypes; + {Lock the medium blocks} + LockMediumBlocks; + {Step through all the medium block pools} + LPMediumBlockPoolHeader := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader; + while LPMediumBlockPoolHeader <> @MediumBlockPoolsCircularList do + begin + {Add to the medium block used space} + Inc(AMemoryManagerState.ReservedMediumBlockAddressSpace, MediumBlockPoolSize); + LPMediumBlock := GetFirstMediumBlockInPool(LPMediumBlockPoolHeader); + while LPMediumBlock <> nil do + begin + LMediumBlockHeader := PNativeUInt(PByte(LPMediumBlock) - BlockHeaderSize)^; + {Is the block in use?} + if LMediumBlockHeader and IsFreeBlockFlag = 0 then + begin + {Get the block size} + LMediumBlockSize := LMediumBlockHeader and DropMediumAndLargeFlagsMask; + if (LMediumBlockHeader and IsSmallBlockPoolInUseFlag) <> 0 then + begin + {Get the block type index} + LBlockTypeIndex := (UIntPtr(PSmallBlockPoolHeader(LPMediumBlock).BlockType) - UIntPtr(@SmallBlockTypes[0])) div SizeOf(TSmallBlockType); + {Subtract from medium block usage} + Dec(AMemoryManagerState.ReservedMediumBlockAddressSpace, LMediumBlockSize); + {Add it to the reserved space for the block size} + Inc(AMemoryManagerState.SmallBlockTypeStates[LBlockTypeIndex].ReservedAddressSpace, LMediumBlockSize); + {Add the usage for the pool} + Inc(AMemoryManagerState.SmallBlockTypeStates[LBlockTypeIndex].AllocatedBlockCount, + PSmallBlockPoolHeader(LPMediumBlock).BlocksInUse); + end + else + begin +{$ifdef FullDebugMode} + Dec(LMediumBlockSize, FullDebugBlockOverhead); +{$endif} + Inc(AMemoryManagerState.AllocatedMediumBlockCount); + Inc(AMemoryManagerState.TotalAllocatedMediumBlockSize, LMediumBlockSize - BlockHeaderSize); + end; + end; + {Next medium block} + LPMediumBlock := NextMediumBlock(LPMediumBlock); + end; + {Get the next medium block pool} + LPMediumBlockPoolHeader := LPMediumBlockPoolHeader.NextMediumBlockPoolHeader; + end; + {Unlock medium blocks} + MediumBlocksLocked := False; + {Unlock all the small block types} + for LInd := 0 to NumSmallBlockTypes - 1 do + SmallBlockTypes[LInd].BlockTypeLocked := False; + {Step through all the large blocks} + LockLargeBlocks; + LPLargeBlock := LargeBlocksCircularList.NextLargeBlockHeader; + while LPLargeBlock <> @LargeBlocksCircularList do + begin + LLargeBlockSize := LPLargeBlock.BlockSizeAndFlags and DropMediumAndLargeFlagsMask; + Inc(AMemoryManagerState.AllocatedLargeBlockCount); + Inc(AMemoryManagerState.ReservedLargeBlockAddressSpace, LLargeBlockSize); + Inc(AMemoryManagerState.TotalAllocatedLargeBlockSize, LPLargeBlock.UserAllocatedSize); + {Get the next large block} + LPLargeBlock := LPLargeBlock.NextLargeBlockHeader; + end; + LargeBlocksLocked := False; +end; + +{Returns a summary of the information returned by GetMemoryManagerState} +procedure GetMemoryManagerUsageSummary( + var AMemoryManagerUsageSummary: TMemoryManagerUsageSummary); +var + LMMS: TMemoryManagerState; + LAllocatedBytes, LReservedBytes: NativeUInt; + LSBTIndex: Integer; +begin + {Get the memory manager state} + GetMemoryManagerState(LMMS); + {Add up the totals} + LAllocatedBytes := LMMS.TotalAllocatedMediumBlockSize + + LMMS.TotalAllocatedLargeBlockSize; + LReservedBytes := LMMS.ReservedMediumBlockAddressSpace + + LMMS.ReservedLargeBlockAddressSpace; + for LSBTIndex := 0 to NumSmallBlockTypes - 1 do + begin + Inc(LAllocatedBytes, LMMS.SmallBlockTypeStates[LSBTIndex].UseableBlockSize + * LMMS.SmallBlockTypeStates[LSBTIndex].AllocatedBlockCount); + Inc(LReservedBytes, LMMS.SmallBlockTypeStates[LSBTIndex].ReservedAddressSpace); + end; + {Set the structure values} + AMemoryManagerUsageSummary.AllocatedBytes := LAllocatedBytes; + AMemoryManagerUsageSummary.OverheadBytes := LReservedBytes - LAllocatedBytes; + if LReservedBytes > 0 then + begin + AMemoryManagerUsageSummary.EfficiencyPercentage := + LAllocatedBytes / LReservedBytes * 100; + end + else + AMemoryManagerUsageSummary.EfficiencyPercentage := 100; +end; + +{$ifndef Linux} +{Gets the state of every 64K block in the 4GB address space. Under 64-bit this + returns only the state for the low 4GB.} +procedure GetMemoryMap(var AMemoryMap: TMemoryMap); +var + LPMediumBlockPoolHeader: PMediumBlockPoolHeader; + LPLargeBlock: PLargeBlockHeader; + LInd, LChunkIndex, LNextChunk, LLargeBlockSize: NativeUInt; + LMBI: TMemoryBasicInformation; +begin + {Clear the map} + FillChar(AMemoryMap, SizeOf(AMemoryMap), Ord(csUnallocated)); + {Step through all the medium block pools} + LockMediumBlocks; + LPMediumBlockPoolHeader := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader; + while LPMediumBlockPoolHeader <> @MediumBlockPoolsCircularList do + begin + {Add to the medium block used space} + LChunkIndex := NativeUInt(LPMediumBlockPoolHeader) shr 16; + for LInd := 0 to (MediumBlockPoolSize - 1) shr 16 do + begin + if (LChunkIndex + LInd) > High(AMemoryMap) then + Break; + AMemoryMap[LChunkIndex + LInd] := csAllocated; + end; + {Get the next medium block pool} + LPMediumBlockPoolHeader := LPMediumBlockPoolHeader.NextMediumBlockPoolHeader; + end; + MediumBlocksLocked := False; + {Step through all the large blocks} + LockLargeBlocks; + LPLargeBlock := LargeBlocksCircularList.NextLargeBlockHeader; + while LPLargeBlock <> @LargeBlocksCircularList do + begin + LChunkIndex := UIntPtr(LPLargeBlock) shr 16; + LLargeBlockSize := LPLargeBlock.BlockSizeAndFlags and DropMediumAndLargeFlagsMask; + for LInd := 0 to (LLargeBlockSize - 1) shr 16 do + begin + if (LChunkIndex + LInd) > High(AMemoryMap) then + Break; + AMemoryMap[LChunkIndex + LInd] := csAllocated; + end; + {Get the next large block} + LPLargeBlock := LPLargeBlock.NextLargeBlockHeader; + end; + LargeBlocksLocked := False; + {Fill in the rest of the map} + LInd := 0; + while LInd <= 65535 do + begin + {If the chunk is not allocated by this MM, what is its status?} + if AMemoryMap[LInd] = csUnallocated then + begin + {Query the address space starting at the chunk boundary} + if VirtualQuery(Pointer(LInd * 65536), LMBI, SizeOf(LMBI)) = 0 then + begin + {VirtualQuery may fail for addresses >2GB if a large address space is + not enabled.} + FillChar(AMemoryMap[LInd], 65536 - LInd, csSysReserved); + Break; + end; + {Get the chunk number after the region} + LNextChunk := (LMBI.RegionSize - 1) shr 16 + LInd + 1; + {Validate} + if LNextChunk > 65536 then + LNextChunk := 65536; + {Set the status of all the chunks in the region} + if LMBI.State = MEM_COMMIT then + begin + FillChar(AMemoryMap[LInd], LNextChunk - LInd, csSysAllocated); + end + else + begin + if LMBI.State = MEM_RESERVE then + FillChar(AMemoryMap[LInd], LNextChunk - LInd, csSysReserved); + end; + {Point to the start of the next chunk} + LInd := LNextChunk; + end + else + begin + {Next chunk} + Inc(LInd); + end; + end; +end; +{$endif} + +{Returns summarised information about the state of the memory manager. (For + backward compatibility.)} +function FastGetHeapStatus: THeapStatus; +var + LPMediumBlockPoolHeader: PMediumBlockPoolHeader; + LPMediumBlock: Pointer; + LBlockTypeIndex, LMediumBlockSize: Cardinal; + LSmallBlockUsage, LSmallBlockOverhead, LMediumBlockHeader, LLargeBlockSize: NativeUInt; + LInd: Integer; + LPLargeBlock: PLargeBlockHeader; +begin + {Clear the structure} + FillChar(Result, SizeOf(Result), 0); + {Lock all small block types} + LockAllSmallBlockTypes; + {Lock the medium blocks} + LockMediumBlocks; + {Step through all the medium block pools} + LPMediumBlockPoolHeader := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader; + while LPMediumBlockPoolHeader <> @MediumBlockPoolsCircularList do + begin + {Add to the total and committed address space} + Inc(Result.TotalAddrSpace, ((MediumBlockPoolSize + $ffff) and $ffff0000)); + Inc(Result.TotalCommitted, ((MediumBlockPoolSize + $ffff) and $ffff0000)); + {Add the medium block pool overhead} + Inc(Result.Overhead, (((MediumBlockPoolSize + $ffff) and $ffff0000) + - MediumBlockPoolSize + MediumBlockPoolHeaderSize)); + {Get the first medium block in the pool} + LPMediumBlock := GetFirstMediumBlockInPool(LPMediumBlockPoolHeader); + while LPMediumBlock <> nil do + begin + {Get the block header} + LMediumBlockHeader := PNativeUInt(PByte(LPMediumBlock) - BlockHeaderSize)^; + {Get the block size} + LMediumBlockSize := LMediumBlockHeader and DropMediumAndLargeFlagsMask; + {Is the block in use?} + if LMediumBlockHeader and IsFreeBlockFlag = 0 then + begin + if (LMediumBlockHeader and IsSmallBlockPoolInUseFlag) <> 0 then + begin + {Get the block type index} + LBlockTypeIndex := (UIntPtr(PSmallBlockPoolHeader(LPMediumBlock).BlockType) - UIntPtr(@SmallBlockTypes[0])) div SizeOf(TSmallBlockType); + {Get the usage in the block} + LSmallBlockUsage := PSmallBlockPoolHeader(LPMediumBlock).BlocksInUse + * SmallBlockTypes[LBlockTypeIndex].BlockSize; + {Get the total overhead for all the small blocks} + LSmallBlockOverhead := PSmallBlockPoolHeader(LPMediumBlock).BlocksInUse + * (BlockHeaderSize{$ifdef FullDebugMode} + FullDebugBlockOverhead{$endif}); + {Add to the totals} + Inc(Result.FreeSmall, LMediumBlockSize - LSmallBlockUsage - BlockHeaderSize); + Inc(Result.Overhead, LSmallBlockOverhead + BlockHeaderSize); + Inc(Result.TotalAllocated, LSmallBlockUsage - LSmallBlockOverhead); + end + else + begin +{$ifdef FullDebugMode} + Dec(LMediumBlockSize, FullDebugBlockOverhead); + Inc(Result.Overhead, FullDebugBlockOverhead); +{$endif} + {Add to the result} + Inc(Result.TotalAllocated, LMediumBlockSize - BlockHeaderSize); + Inc(Result.Overhead, BlockHeaderSize); + end; + end + else + begin + {The medium block is free} + Inc(Result.FreeBig, LMediumBlockSize); + end; + {Next medium block} + LPMediumBlock := NextMediumBlock(LPMediumBlock); + end; + {Get the next medium block pool} + LPMediumBlockPoolHeader := LPMediumBlockPoolHeader.NextMediumBlockPoolHeader; + end; + {Add the sequential feed unused space} + Inc(Result.Unused, MediumSequentialFeedBytesLeft); + {Unlock the medium blocks} + MediumBlocksLocked := False; + {Unlock all the small block types} + for LInd := 0 to NumSmallBlockTypes - 1 do + SmallBlockTypes[LInd].BlockTypeLocked := False; + {Step through all the large blocks} + LockLargeBlocks; + LPLargeBlock := LargeBlocksCircularList.NextLargeBlockHeader; + while LPLargeBlock <> @LargeBlocksCircularList do + begin + LLargeBlockSize := LPLargeBlock.BlockSizeAndFlags and DropMediumAndLargeFlagsMask; + Inc(Result.TotalAddrSpace, LLargeBlockSize); + Inc(Result.TotalCommitted, LLargeBlockSize); + Inc(Result.TotalAllocated, LPLargeBlock.UserAllocatedSize + {$ifdef FullDebugMode} - FullDebugBlockOverhead{$endif}); + Inc(Result.Overhead, LLargeBlockSize - LPLargeBlock.UserAllocatedSize + {$ifdef FullDebugMode} + FullDebugBlockOverhead{$endif}); + {Get the next large block} + LPLargeBlock := LPLargeBlock.NextLargeBlockHeader; + end; + LargeBlocksLocked := False; + {Set the total number of free bytes} + Result.TotalFree := Result.FreeSmall + Result.FreeBig + Result.Unused; +end; + +{Frees all allocated memory. Does not support segmented large blocks (yet).} +procedure FreeAllMemory; +var + LPMediumBlockPoolHeader, LPNextMediumBlockPoolHeader: PMediumBlockPoolHeader; + LPMediumFreeBlock: PMediumFreeBlock; + LPLargeBlock, LPNextLargeBlock: PLargeBlockHeader; + LInd: Integer; +begin + {Free all block pools} + LPMediumBlockPoolHeader := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader; + while LPMediumBlockPoolHeader <> @MediumBlockPoolsCircularList do + begin + {Get the next medium block pool so long} + LPNextMediumBlockPoolHeader := LPMediumBlockPoolHeader.NextMediumBlockPoolHeader; +{$ifdef ClearMediumBlockPoolsBeforeReturningToOS} + FillChar(LPMediumBlockPoolHeader^, MediumBlockPoolSize, 0); +{$else} + {$ifdef ClearSmallAndMediumBlocksInFreeMem} + FillChar(LPMediumBlockPoolHeader^, MediumBlockPoolSize, 0); + {$endif} +{$endif} + {Free this pool} + VirtualFree(LPMediumBlockPoolHeader, 0, MEM_RELEASE); + {Next pool} + LPMediumBlockPoolHeader := LPNextMediumBlockPoolHeader; + end; + {Clear all small block types} + for LInd := 0 to High(SmallBlockTypes) do + begin + SmallBlockTypes[Lind].PreviousPartiallyFreePool := @SmallBlockTypes[Lind]; + SmallBlockTypes[Lind].NextPartiallyFreePool := @SmallBlockTypes[Lind]; + SmallBlockTypes[Lind].NextSequentialFeedBlockAddress := Pointer(1); + SmallBlockTypes[Lind].MaxSequentialFeedBlockAddress := nil; + end; + {Clear all medium block pools} + MediumBlockPoolsCircularList.PreviousMediumBlockPoolHeader := @MediumBlockPoolsCircularList; + MediumBlockPoolsCircularList.NextMediumBlockPoolHeader := @MediumBlockPoolsCircularList; + {All medium bins are empty} + for LInd := 0 to High(MediumBlockBins) do + begin + LPMediumFreeBlock := @MediumBlockBins[LInd]; + LPMediumFreeBlock.PreviousFreeBlock := LPMediumFreeBlock; + LPMediumFreeBlock.NextFreeBlock := LPMediumFreeBlock; + end; + MediumBlockBinGroupBitmap := 0; + FillChar(MediumBlockBinBitmaps, SizeOf(MediumBlockBinBitmaps), 0); + MediumSequentialFeedBytesLeft := 0; + {Free all large blocks} + LPLargeBlock := LargeBlocksCircularList.NextLargeBlockHeader; + while LPLargeBlock <> @LargeBlocksCircularList do + begin + {Get the next large block} + LPNextLargeBlock := LPLargeBlock.NextLargeBlockHeader; +{$ifdef ClearLargeBlocksBeforeReturningToOS} + FillChar(LPLargeBlock^, + LPLargeBlock.BlockSizeAndFlags and DropMediumAndLargeFlagsMask, 0); +{$endif} + {Free this large block} + VirtualFree(LPLargeBlock, 0, MEM_RELEASE); + {Next large block} + LPLargeBlock := LPNextLargeBlock; + end; + {There are no large blocks allocated} + LargeBlocksCircularList.PreviousLargeBlockHeader := @LargeBlocksCircularList; + LargeBlocksCircularList.NextLargeBlockHeader := @LargeBlocksCircularList; +end; + +{----------------------------Memory Manager Setup-----------------------------} + +{Checks that no other memory manager has been installed after the RTL MM and + that there are currently no live pointers allocated through the RTL MM.} +function CheckCanInstallMemoryManager: Boolean; +{$ifndef NoMessageBoxes} +var + LErrorMessageTitle: array[0..1023] of AnsiChar; +{$endif} +begin + {Default to error} + Result := False; +{$ifdef FullDebugMode} + {$ifdef LoadDebugDLLDynamically} + {$ifdef DoNotInstallIfDLLMissing} + {Should FastMM be installed only if the FastMM_FullDebugMode.dll file is + available?} + if FullDebugModeDLL = 0 then + Exit; + {$endif} + {$endif} +{$endif} + {Is FastMM already installed?} + if FastMMIsInstalled then + begin +{$ifdef UseOutputDebugString} + OutputDebugStringA(AlreadyInstalledMsg); +{$endif} +{$ifndef NoMessageBoxes} + AppendStringToModuleName(AlreadyInstalledTitle, LErrorMessageTitle); + ShowMessageBox(AlreadyInstalledMsg, LErrorMessageTitle); +{$endif} + Exit; + end; + {Has another MM been set, or has the Embarcadero MM been used? If so, this + file is not the first unit in the uses clause of the project's .dpr file.} + if IsMemoryManagerSet then + begin + {When using runtime packages, another library may already have installed + FastMM: Silently ignore the installation request.} +{$ifndef UseRuntimePackages} + {Another memory manager has been set.} + {$ifdef UseOutputDebugString} + OutputDebugStringA(OtherMMInstalledMsg); + {$endif} + {$ifndef NoMessageBoxes} + AppendStringToModuleName(OtherMMInstalledTitle, LErrorMessageTitle); + ShowMessageBox(OtherMMInstalledMsg, LErrorMessageTitle); + {$endif} +{$endif} + Exit; + end; +{$ifndef Linux} + if GetHeapStatus.TotalAllocated <> 0 then + begin + {Memory has been already been allocated with the RTL MM} +{$ifdef UseOutputDebugString} + OutputDebugStringA(MemoryAllocatedMsg); +{$endif} + {$ifndef NoMessageBoxes} + AppendStringToModuleName(MemoryAllocatedTitle, LErrorMessageTitle); + ShowMessageBox(MemoryAllocatedMsg, LErrorMessageTitle); + {$endif} + Exit; + end; +{$endif} + {All OK} + Result := True; +end; + +{Initializes the lookup tables for the memory manager} +procedure InitializeMemoryManager; +const + {The size of the Inc(VMTIndex) code in TFreedObject.GetVirtualMethodIndex} + VMTIndexIncCodeSize = 6; +var + LInd, LSizeInd, LMinimumPoolSize, LOptimalPoolSize, LGroupNumber, + LBlocksPerPool, LPreviousBlockSize: Cardinal; + LPMediumFreeBlock: PMediumFreeBlock; +begin +{$ifdef FullDebugMode} + {$ifdef LoadDebugDLLDynamically} + {Attempt to load the FullDebugMode DLL dynamically.} + FullDebugModeDLL := LoadLibrary(FullDebugModeLibraryName); + if FullDebugModeDLL <> 0 then + begin + GetStackTrace := GetProcAddress(FullDebugModeDLL, + {$ifdef RawStackTraces}'GetRawStackTrace'{$else}'GetFrameBasedStackTrace'{$endif}); + LogStackTrace := GetProcAddress(FullDebugModeDLL, 'LogStackTrace'); + end; + {$endif} +{$endif} +{$ifdef EnableMMX} + {$ifndef ForceMMX} + UseMMX := MMX_Supported; + {$endif} +{$endif} + {Initialize the memory manager} + {-------------Set up the small block types-------------} + LPreviousBlockSize := 0; + for LInd := 0 to High(SmallBlockTypes) do + begin + {Set the move procedure} +{$ifdef UseCustomFixedSizeMoveRoutines} + {The upsize move procedure may move chunks in 16 bytes even with 8-byte + alignment, since the new size will always be at least 8 bytes bigger than + the old size.} + if not Assigned(SmallBlockTypes[LInd].UpsizeMoveProcedure) then + {$ifdef UseCustomVariableSizeMoveRoutines} + SmallBlockTypes[LInd].UpsizeMoveProcedure := MoveX16LP; + {$else} + SmallBlockTypes[LInd].UpsizeMoveProcedure := @System.Move; + {$endif} +{$endif} + {Set the first "available pool" to the block type itself, so that the + allocation routines know that there are currently no pools with free + blocks of this size.} + SmallBlockTypes[LInd].PreviousPartiallyFreePool := @SmallBlockTypes[LInd]; + SmallBlockTypes[LInd].NextPartiallyFreePool := @SmallBlockTypes[LInd]; + {Set the block size to block type index translation table} + for LSizeInd := (LPreviousBlockSize div SmallBlockGranularity) to ((SmallBlockTypes[LInd].BlockSize - 1) div SmallBlockGranularity) do + AllocSize2SmallBlockTypeIndX4[LSizeInd] := LInd * 4; + {Cannot sequential feed yet: Ensure that the next address is greater than + the maximum address} + SmallBlockTypes[LInd].MaxSequentialFeedBlockAddress := Pointer(0); + SmallBlockTypes[LInd].NextSequentialFeedBlockAddress := Pointer(1); + {Get the mask to use for finding a medium block suitable for a block pool} + LMinimumPoolSize := + ((SmallBlockTypes[LInd].BlockSize * MinimumSmallBlocksPerPool + + SmallBlockPoolHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset) + and -MediumBlockGranularity) + MediumBlockSizeOffset; + if LMinimumPoolSize < MinimumMediumBlockSize then + LMinimumPoolSize := MinimumMediumBlockSize; + {Get the closest group number for the minimum pool size} + LGroupNumber := (LMinimumPoolSize - MinimumMediumBlockSize + MediumBlockBinsPerGroup * MediumBlockGranularity div 2) + div (MediumBlockBinsPerGroup * MediumBlockGranularity); + {Too large?} + if LGroupNumber > 7 then + LGroupNumber := 7; + {Set the bitmap} + SmallBlockTypes[LInd].AllowedGroupsForBlockPoolBitmap := Byte(-(1 shl LGroupNumber)); + {Set the minimum pool size} + SmallBlockTypes[LInd].MinimumBlockPoolSize := MinimumMediumBlockSize + LGroupNumber * (MediumBlockBinsPerGroup * MediumBlockGranularity); + {Get the optimal block pool size} + LOptimalPoolSize := ((SmallBlockTypes[LInd].BlockSize * TargetSmallBlocksPerPool + + SmallBlockPoolHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset) + and -MediumBlockGranularity) + MediumBlockSizeOffset; + {Limit the optimal pool size to within range} + if LOptimalPoolSize < OptimalSmallBlockPoolSizeLowerLimit then + LOptimalPoolSize := OptimalSmallBlockPoolSizeLowerLimit; + if LOptimalPoolSize > OptimalSmallBlockPoolSizeUpperLimit then + LOptimalPoolSize := OptimalSmallBlockPoolSizeUpperLimit; + {How many blocks will fit in the adjusted optimal size?} + LBlocksPerPool := (LOptimalPoolSize - SmallBlockPoolHeaderSize) div SmallBlockTypes[LInd].BlockSize; + {Recalculate the optimal pool size to minimize wastage due to a partial + last block.} + SmallBlockTypes[LInd].OptimalBlockPoolSize := + ((LBlocksPerPool * SmallBlockTypes[LInd].BlockSize + SmallBlockPoolHeaderSize + MediumBlockGranularity - 1 - MediumBlockSizeOffset) and -MediumBlockGranularity) + MediumBlockSizeOffset; +{$ifdef CheckHeapForCorruption} + {Debug checks} + if (SmallBlockTypes[LInd].OptimalBlockPoolSize < MinimumMediumBlockSize) + or (SmallBlockTypes[LInd].BlockSize div SmallBlockGranularity * SmallBlockGranularity <> SmallBlockTypes[LInd].BlockSize) then + begin + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} + end; +{$endif} + {Set the previous small block size} + LPreviousBlockSize := SmallBlockTypes[LInd].BlockSize; + end; + {-------------------Set up the medium blocks-------------------} +{$ifdef CheckHeapForCorruption} + {Check that there are no gaps between where the small blocks end and the + medium blocks start} + if (((MaximumSmallBlockSize - 3) + (MediumBlockGranularity - 1 + BlockHeaderSize - MediumBlockSizeOffset)) + and -MediumBlockGranularity) + MediumBlockSizeOffset < MinimumMediumBlockSize then + begin + {$ifdef BCB6OrDelphi7AndUp} + System.Error(reInvalidPtr); + {$else} + System.RunError(reInvalidPtr); + {$endif} + end; +{$endif} + {There are currently no medium block pools} + MediumBlockPoolsCircularList.PreviousMediumBlockPoolHeader := @MediumBlockPoolsCircularList; + MediumBlockPoolsCircularList.NextMediumBlockPoolHeader := @MediumBlockPoolsCircularList; + {All medium bins are empty} + for LInd := 0 to High(MediumBlockBins) do + begin + LPMediumFreeBlock := @MediumBlockBins[LInd]; + LPMediumFreeBlock.PreviousFreeBlock := LPMediumFreeBlock; + LPMediumFreeBlock.NextFreeBlock := LPMediumFreeBlock; + end; + {------------------Set up the large blocks---------------------} + LargeBlocksCircularList.PreviousLargeBlockHeader := @LargeBlocksCircularList; + LargeBlocksCircularList.NextLargeBlockHeader := @LargeBlocksCircularList; + {------------------Set up the debugging structures---------------------} +{$ifdef FullDebugMode} + {Set up the fake VMT} + {Copy the basic info from the TFreedObject class} + System.Move(Pointer(PByte(TFreedObject) + vmtSelfPtr + SizeOf(Pointer))^, + FreedObjectVMT.VMTData[vmtSelfPtr + SizeOf(Pointer)], vmtParent - vmtSelfPtr); + PNativeUInt(@FreedObjectVMT.VMTData[vmtSelfPtr])^ := NativeUInt(@FreedObjectVMT.VMTMethods[0]); + {Set up the virtual method table} + for LInd := 0 to MaxFakeVMTEntries - 1 do + begin + PNativeUInt(@FreedObjectVMT.VMTMethods[Low(FreedObjectVMT.VMTMethods) + Integer(LInd * SizeOf(Pointer))])^ := + NativeUInt(@TFreedObject.GetVirtualMethodIndex) + LInd * VMTIndexIncCodeSize; + {$ifdef CatchUseOfFreedInterfaces} + VMTBadInterface[LInd] := @TFreedObject.InterfaceError; + {$endif} + end; + {Set up the default log file name} + SetDefaultMMLogFileName; +{$endif} +end; + +{Installs the memory manager (InitializeMemoryManager should be called first)} +procedure InstallMemoryManager; +{$ifdef MMSharingEnabled} +var + i, LCurrentProcessID: Cardinal; + LPMapAddress: PPointer; + LChar: AnsiChar; +{$endif} +begin + if not FastMMIsInstalled then + begin +{$ifdef FullDebugMode} + {$ifdef 32Bit} + {Try to reserve the 64K block covering address $80808080} + ReservedBlock := VirtualAlloc(Pointer(DebugReservedAddress), 65536, MEM_RESERVE, PAGE_NOACCESS); + {$endif} +{$endif} +{$ifdef MMSharingEnabled} + {Build a string identifying the current process} + LCurrentProcessID := GetCurrentProcessId; + for i := 0 to 7 do + begin + LChar := HexTable[((LCurrentProcessID shr (i * 4)) and $F)]; + MappingObjectName[(High(MappingObjectName) - 1) - i] := LChar; + {$ifdef EnableBackwardCompatibleMMSharing} + UniqueProcessIDString[8 - i] := LChar; + UniqueProcessIDStringBE[8 - i] := LChar; + {$endif} + end; +{$endif} +{$ifdef AttemptToUseSharedMM} + {Is the replacement memory manager already installed for this process?} +{$ifdef EnableBackwardCompatibleMMSharing} + MMWindow := FindWindowA('STATIC', PAnsiChar(@UniqueProcessIDString[1])); + MMWindowBE := FindWindowA('STATIC', PAnsiChar(@UniqueProcessIDStringBE[1])); +{$endif} + MappingObjectHandle := OpenFileMappingA(FILE_MAP_READ, False, MappingObjectName); + {Is no MM being shared?} +{$ifdef EnableBackwardCompatibleMMSharing} + if (MMWindow or MMWindowBE or MappingObjectHandle) = 0 then +{$else} + if MappingObjectHandle = 0 then +{$endif} + begin +{$endif} +{$ifdef ShareMM} + {Share the MM with other DLLs? - if this DLL is unloaded, then + dependent DLLs will cause a crash.} + {$ifndef ShareMMIfLibrary} + if not IsLibrary then + {$endif} + begin + {$ifdef EnableBackwardCompatibleMMSharing} + {No memory manager installed yet - create the invisible window} + MMWindow := CreateWindowA('STATIC', PAnsiChar(@UniqueProcessIDString[1]), + WS_POPUP, 0, 0, 0, 0, 0, 0, hInstance, nil); + MMWindowBE := CreateWindowA('STATIC', PAnsiChar(@UniqueProcessIDStringBE[1]), + WS_POPUP, 0, 0, 0, 0, 0, 0, hInstance, nil); + {The window data is a pointer to this memory manager} + if MMWindow <> 0 then + SetWindowLongA(MMWindow, GWL_USERDATA, NativeInt(@NewMemoryManager)); + if MMWindowBE <> 0 then + SetWindowLongA(MMWindowBE, GWL_USERDATA, NativeInt(@NewMemoryManager)); + {$endif} + {Create the memory mapped file} + MappingObjectHandle := CreateFileMappingA(INVALID_HANDLE_VALUE, nil, + PAGE_READWRITE, 0, SizeOf(Pointer), MappingObjectName); + {Map a view of the memory} + LPMapAddress := MapViewOfFile(MappingObjectHandle, FILE_MAP_WRITE, 0, 0, 0); + {Set a pointer to the new memory manager} + LPMapAddress^ := @NewMemoryManager; + {Unmap the file} + UnmapViewOfFile(LPMapAddress); + end; +{$endif} + {We will be using this memory manager} +{$ifndef FullDebugMode} + NewMemoryManager.GetMem := FastGetMem; + NewMemoryManager.FreeMem := FastFreeMem; + NewMemoryManager.ReallocMem := FastReallocMem; +{$else} + NewMemoryManager.GetMem := DebugGetMem; + NewMemoryManager.FreeMem := DebugFreeMem; + NewMemoryManager.ReallocMem := DebugReallocMem; +{$endif} +{$ifdef BDS2006AndUp} + {$ifndef FullDebugMode} + NewMemoryManager.AllocMem := FastAllocMem; + {$else} + NewMemoryManager.AllocMem := DebugAllocMem; + {$endif} + {$ifdef EnableMemoryLeakReporting} + NewMemoryManager.RegisterExpectedMemoryLeak := RegisterExpectedMemoryLeak; + NewMemoryManager.UnRegisterExpectedMemoryLeak := UnRegisterExpectedMemoryLeak; + {$else} + NewMemoryManager.RegisterExpectedMemoryLeak := NoOpRegisterExpectedMemoryLeak; + NewMemoryManager.UnRegisterExpectedMemoryLeak := NoOpUnRegisterExpectedMemoryLeak; + {$endif} +{$endif} + {Owns the memory manager} + IsMemoryManagerOwner := True; +{$ifdef AttemptToUseSharedMM} + end + else + begin + {Get the address of the shared memory manager} + {$ifndef BDS2006AndUp} + {$ifdef EnableBackwardCompatibleMMSharing} + if MappingObjectHandle <> 0 then + begin + {$endif} + {Map a view of the memory} + LPMapAddress := MapViewOfFile(MappingObjectHandle, FILE_MAP_READ, 0, 0, 0); + {Set the new memory manager} + NewMemoryManager := PMemoryManager(LPMapAddress^)^; + {Unmap the file} + UnmapViewOfFile(LPMapAddress); + {$ifdef EnableBackwardCompatibleMMSharing} + end + else + begin + if MMWindow <> 0 then + begin + NewMemoryManager := PMemoryManager(GetWindowLong(MMWindow, GWL_USERDATA))^; + end + else + begin + NewMemoryManager := PMemoryManager(GetWindowLong(MMWindowBE, GWL_USERDATA))^; + end; + end; + {$endif} + {$else} + {$ifdef EnableBackwardCompatibleMMSharing} + if MappingObjectHandle <> 0 then + begin + {$endif} + {Map a view of the memory} + LPMapAddress := MapViewOfFile(MappingObjectHandle, FILE_MAP_READ, 0, 0, 0); + {Set the new memory manager} + NewMemoryManager := PMemoryManagerEx(LPMapAddress^)^; + {Unmap the file} + UnmapViewOfFile(LPMapAddress); + {$ifdef EnableBackwardCompatibleMMSharing} + end + else + begin + if MMWindow <> 0 then + begin + NewMemoryManager := PMemoryManagerEx(GetWindowLong(MMWindow, GWL_USERDATA))^; + end + else + begin + NewMemoryManager := PMemoryManagerEx(GetWindowLong(MMWindowBE, GWL_USERDATA))^; + end; + end; + {$endif} + {$endif} + {Close the file mapping handle} + CloseHandle(MappingObjectHandle); + MappingObjectHandle := 0; + {The memory manager is not owned by this module} + IsMemoryManagerOwner := False; + end; +{$endif} + {Save the old memory manager} + GetMemoryManager(OldMemoryManager); + {Replace the memory manager with either this one or the shared one.} + SetMemoryManager(NewMemoryManager); + {FastMM is now installed} + FastMMIsInstalled := True; +{$ifdef UseOutputDebugString} + if IsMemoryManagerOwner then + OutputDebugStringA(FastMMInstallMsg) + else + OutputDebugStringA(FastMMInstallSharedMsg); +{$endif} + end; +end; + +procedure UninstallMemoryManager; +begin + {Is this the owner of the shared MM window?} + if IsMemoryManagerOwner then + begin +{$ifdef ShareMM} + {$ifdef EnableBackwardCompatibleMMSharing} + {Destroy the window} + if MMWindow <> 0 then + begin + DestroyWindow(MMWindow); + MMWindow := 0; + end; + if MMWindowBE <> 0 then + begin + DestroyWindow(MMWindowBE); + MMWindowBE := 0; + end; + {$endif} + {Destroy the memory mapped file handle} + if MappingObjectHandle <> 0 then + begin + CloseHandle(MappingObjectHandle); + MappingObjectHandle := 0; + end; +{$endif} +{$ifdef FullDebugMode} + {Release the reserved block} + if ReservedBlock <> nil then + begin + VirtualFree(ReservedBlock, 0, MEM_RELEASE); + ReservedBlock := nil; + end; +{$endif} + end; +{$ifndef DetectMMOperationsAfterUninstall} + {Restore the old memory manager} + SetMemoryManager(OldMemoryManager); +{$else} + {Set the invalid memory manager: no more MM operations allowed} + SetMemoryManager(InvalidMemoryManager); +{$endif} + {Memory manager has been uninstalled} + FastMMIsInstalled := False; +{$ifdef UseOutputDebugString} + if IsMemoryManagerOwner then + OutputDebugStringA(FastMMuninstallMsg) + else + OutputDebugStringA(FastMMUninstallSharedMsg); +{$endif} +end; + +procedure FinalizeMemoryManager; +begin + {Restore the old memory manager if FastMM has been installed} + if FastMMIsInstalled then + begin +{$ifndef NeverUninstall} + {Uninstall FastMM} + UninstallMemoryManager; +{$endif} + {Do we own the memory manager, or are we just sharing it?} + if IsMemoryManagerOwner then + begin +{$ifdef CheckUseOfFreedBlocksOnShutdown} + CheckBlocksOnShutdown( + {$ifdef EnableMemoryLeakReporting} + True + {$ifdef RequireIDEPresenceForLeakReporting} + and DelphiIsRunning + {$endif} + {$ifdef RequireDebuggerPresenceForLeakReporting} + and ((DebugHook <> 0) + {$ifdef PatchBCBTerminate} + or (Assigned(pCppDebugHook) and (pCppDebugHook^ <> 0)) + {$endif PatchBCBTerminate} + ) + {$endif} + {$ifdef ManualLeakReportingControl} + and ReportMemoryLeaksOnShutdown + {$endif} + {$else} + False + {$endif} + ); +{$else} + {$ifdef EnableMemoryLeakReporting} + if True + {$ifdef RequireIDEPresenceForLeakReporting} + and DelphiIsRunning + {$endif} + {$ifdef RequireDebuggerPresenceForLeakReporting} + and ((DebugHook <> 0) + {$ifdef PatchBCBTerminate} + or (Assigned(pCppDebugHook) and (pCppDebugHook^ <> 0)) + {$endif PatchBCBTerminate} + ) + {$endif} + {$ifdef ManualLeakReportingControl} + and ReportMemoryLeaksOnShutdown + {$endif} + then + CheckBlocksOnShutdown(True); + {$endif} +{$endif} +{$ifdef EnableMemoryLeakReporting} + {Free the expected memory leaks list} + if ExpectedMemoryLeaks <> nil then + begin + VirtualFree(ExpectedMemoryLeaks, 0, MEM_RELEASE); + ExpectedMemoryLeaks := nil; + end; +{$endif} +{$ifndef NeverUninstall} + {Clean up: Free all memory. If this is a .DLL that owns its own MM, then + it is necessary to prevent the main application from running out of + address space.} + FreeAllMemory; +{$endif} + end; + end; +end; + +procedure RunInitializationCode; +begin + {Only run this code once during startup.} + if InitializationCodeHasRun then + Exit; + InitializationCodeHasRun := True; +{$ifndef BCB} + {$ifdef InstallOnlyIfRunningInIDE} + if (DebugHook <> 0) and DelphiIsRunning then + {$endif} + begin + {Initialize all the lookup tables, etc. for the memory manager} + InitializeMemoryManager; + {Has another MM been set, or has the Embarcadero MM been used? If so, this + file is not the first unit in the uses clause of the project's .dpr + file.} + if CheckCanInstallMemoryManager then + begin + {$ifdef ClearLogFileOnStartup} + DeleteEventLog; + {$endif} + InstallMemoryManager; + end; + end; +{$endif} +end; + +initialization + RunInitializationCode; + +finalization +{$ifndef PatchBCBTerminate} + FinalizeMemoryManager; +{$endif} + +end. \ No newline at end of file diff --git a/System/FastMM4Messages.pas b/System/FastMM4Messages.pas new file mode 100644 index 0000000..2dd0bee --- /dev/null +++ b/System/FastMM4Messages.pas @@ -0,0 +1,135 @@ +{ + +Fast Memory Manager: Messages + +English translation by Pierre le Riche. + +} + +unit FastMM4Messages; + +interface + +{$Include FastMM4Options.inc} + +const + {The name of the debug info support DLL} + FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll'; + FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll'; + {Event log strings} + LogFileExtension = '_MemoryManager_EventLog.txt'#0; + CRLF = #13#10; + EventSeparator = '--------------------------------'; + {Class name messages} + UnknownClassNameMsg = 'Unknown'; + {Memory dump message} + MemoryDumpMsg = #13#10#13#10'Current memory dump of 256 bytes starting at pointer address '; + {Block Error Messages} + BlockScanLogHeader = 'Allocated block logged by LogAllocatedBlocksToFile. The size is: '; + ErrorMsgHeader = 'FastMM has detected an error during a '; + GetMemMsg = 'GetMem'; + FreeMemMsg = 'FreeMem'; + ReallocMemMsg = 'ReallocMem'; + BlockCheckMsg = 'free block scan'; + OperationMsg = ' operation. '; + BlockHeaderCorruptedMsg = 'The block header has been corrupted. '; + BlockFooterCorruptedMsg = 'The block footer has been corrupted. '; + FreeModifiedErrorMsg = 'FastMM detected that a block has been modified after being freed. '; + FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): '; + DoubleFreeErrorMsg = 'An attempt has been made to free/reallocate an unallocated block.'; + WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.'; + PreviousBlockSizeMsg = #13#10#13#10'The previous block size was: '; + CurrentBlockSizeMsg = #13#10#13#10'The block size is: '; + PreviousObjectClassMsg = #13#10#13#10'The block was previously used for an object of class: '; + CurrentObjectClassMsg = #13#10#13#10'The block is currently used for an object of class: '; + PreviousAllocationGroupMsg = #13#10#13#10'The allocation group was: '; + PreviousAllocationNumberMsg = #13#10#13#10'The allocation number was: '; + CurrentAllocationGroupMsg = #13#10#13#10'The allocation group is: '; + CurrentAllocationNumberMsg = #13#10#13#10'The allocation number is: '; + BlockErrorMsgTitle = 'Memory Error Detected'; + VirtualMethodErrorHeader = 'FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.'; + InterfaceErrorHeader = 'FastMM has detected an attempt to use an interface of a freed object. An access violation will now be raised in order to abort the current operation.'; + BlockHeaderCorruptedNoHistoryMsg = ' Unfortunately the block header has been corrupted so no history is available.'; + FreedObjectClassMsg = #13#10#13#10'Freed object class: '; + VirtualMethodName = #13#10#13#10'Virtual method: '; + VirtualMethodOffset = 'Offset +'; + VirtualMethodAddress = #13#10#13#10'Virtual method address: '; + {Stack trace messages} + CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x'; + CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:'; + ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x'; + ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x'; + ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x'; + ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x'; + ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x'; + StackTraceMsg = ', and the stack trace (return addresses) at the time was:'; + {Installation Messages} + AlreadyInstalledMsg = 'FastMM4 is already installed.'; + AlreadyInstalledTitle = 'Already installed.'; + OtherMMInstalledMsg = 'FastMM4 cannot be installed since another third party memory ' + + 'manager has already installed itself.'#13#10'If you want to use FastMM4, ' + + 'please make sure that FastMM4.pas is the very first unit in the "uses"' + + #13#10'section of your project''s .dpr file.'; + OtherMMInstalledTitle = 'Cannot install FastMM4 - Another memory manager is already installed'; + MemoryAllocatedMsg = 'FastMM4 cannot install since memory has already been ' + + 'allocated through the default memory manager.'#13#10'FastMM4.pas MUST ' + + 'be the first unit in your project''s .dpr file, otherwise memory may ' + + 'be allocated'#13#10'through the default memory manager before FastMM4 ' + + 'gains control. '#13#10#13#10'If you are using an exception trapper ' + + 'like MadExcept (or any tool that modifies the unit initialization ' + + 'order),'#13#10'go into its configuration page and ensure that the ' + + 'FastMM4.pas unit is initialized before any other unit.'; + MemoryAllocatedTitle = 'Cannot install FastMM4 - Memory has already been allocated'; + {Leak checking messages} + LeakLogHeader = 'A memory block has been leaked. The size is: '; + LeakMessageHeader = 'This application has leaked memory. '; + SmallLeakDetail = 'The small block leaks are' +{$ifdef HideExpectedLeaksRegisteredByPointer} + + ' (excluding expected leaks registered by pointer)' +{$endif} + + ':'#13#10; + LargeLeakDetail = 'The sizes of leaked medium and large blocks are' +{$ifdef HideExpectedLeaksRegisteredByPointer} + + ' (excluding expected leaks registered by pointer)' +{$endif} + + ': '; + BytesMessage = ' bytes: '; + AnsiStringBlockMessage = 'AnsiString'; + UnicodeStringBlockMessage = 'UnicodeString'; + LeakMessageFooter = #13#10 +{$ifndef HideMemoryLeakHintMessage} + + #13#10'Note: ' + {$ifdef RequireIDEPresenceForLeakReporting} + + 'This memory leak check is only performed if Delphi is currently running on the same computer. ' + {$endif} + {$ifdef FullDebugMode} + {$ifdef LogMemoryLeakDetailToFile} + + 'Memory leak detail is logged to a text file in the same folder as this application. ' + {$else} + + 'Enable the "LogMemoryLeakDetailToFile" to obtain a log file containing detail on memory leaks. ' + {$endif} + {$else} + + 'To obtain a log file containing detail on memory leaks, enable the "FullDebugMode" and "LogMemoryLeakDetailToFile" conditional defines. ' + {$endif} + + 'To disable this memory leak check, undefine "EnableMemoryLeakReporting".'#13#10 +{$endif} + + #0; + LeakMessageTitle = 'Memory Leak Detected'; +{$ifdef UseOutputDebugString} + FastMMInstallMsg = 'FastMM has been installed.'; + FastMMInstallSharedMsg = 'Sharing an existing instance of FastMM.'; + FastMMUninstallMsg = 'FastMM has been uninstalled.'; + FastMMUninstallSharedMsg = 'Stopped sharing an existing instance of FastMM.'; +{$endif} +{$ifdef DetectMMOperationsAfterUninstall} + InvalidOperationTitle = 'MM Operation after uninstall.'; + InvalidGetMemMsg = 'FastMM has detected a GetMem call after FastMM was uninstalled.'; + InvalidFreeMemMsg = 'FastMM has detected a FreeMem call after FastMM was uninstalled.'; + InvalidReallocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.'; + InvalidAllocMemMsg = 'FastMM has detected an AllocMem call after FastMM was uninstalled.'; +{$endif} + +implementation + +end. + diff --git a/System/FastMM4Options.inc b/System/FastMM4Options.inc new file mode 100644 index 0000000..928e716 --- /dev/null +++ b/System/FastMM4Options.inc @@ -0,0 +1,426 @@ +{ + +Fast Memory Manager: Options Include File + +Set the default options for FastMM here. + +} + +{---------------------------Miscellaneous Options-----------------------------} + +{Enable this define to align all blocks on 16 byte boundaries so aligned SSE + instructions can be used safely. If this option is disabled then some of the + smallest block sizes will be 8-byte aligned instead which may result in a + reduction in memory usage. Medium and large blocks are always 16-byte aligned + irrespective of this setting.} +{.$define Align16Bytes} + +{Enable to use faster fixed-size move routines when upsizing small blocks. + These routines are much faster than the Borland RTL move procedure since they + are optimized to move a fixed number of bytes. This option may be used + together with the FastMove library for even better performance.} +{$define UseCustomFixedSizeMoveRoutines} + +{Enable this option to use an optimized procedure for moving a memory block of + an arbitrary size. Disable this option when using the Fastcode move + ("FastMove") library. Using the Fastcode move library allows your whole + application to gain from faster move routines, not just the memory manager. It + is thus recommended that you use the Fastcode move library in conjunction with + this memory manager and disable this option.} +{$define UseCustomVariableSizeMoveRoutines} + +{Enable this option to only install FastMM as the memory manager when the + application is running inside the Delphi IDE. This is useful when you want + to deploy the same EXE that you use for testing, but only want the debugging + features active on development machines. When this option is enabled and + the application is not being run inside the IDE debugger, then the default + Delphi memory manager will be used (which, since Delphi 2006, is FastMM + without FullDebugMode.} +{.$define InstallOnlyIfRunningInIDE} + +{Due to QC#14070 ("Delphi IDE attempts to free memory after the shutdown code + of borlndmm.dll has been called"), FastMM cannot be uninstalled safely when + used inside a replacement borlndmm.dll for the IDE. Setting this option will + circumvent this problem by never uninstalling the memory manager.} +{.$define NeverUninstall} + +{Set this option when you use runtime packages in this application or library. + This will automatically set the "AssumeMultiThreaded" option. Note that you + have to ensure that FastMM is finalized after all live pointers have been + freed - failure to do so will result in a large leak report followed by a lot + of A/Vs. (See the FAQ for more detail.) You may have to combine this option + with the NeverUninstall option.} +{.$define UseRuntimePackages} + +{-----------------------Concurrency Management Options------------------------} + +{Enable to always assume that the application is multithreaded. Enabling this + option will cause a significant performance hit with single threaded + applications. Enable if you are using multi-threaded third party tools that do + not properly set the IsMultiThread variable. Also set this option if you are + going to share this memory manager between a single threaded application and a + multi-threaded DLL.} +{.$define AssumeMultiThreaded} + +{Enable this option to not call Sleep when a thread contention occurs. This + option will improve performance if the ratio of the number of active threads + to the number of CPU cores is low (typically < 2). With this option set a + thread will usually enter a "busy waiting" loop instead of relinquishing its + timeslice when a thread contention occurs, unless UseSwitchToThread is + also defined (see below) in which case it will call SwitchToThread instead of + Sleep.} +{.$define NeverSleepOnThreadContention} + + {Set this option to call SwitchToThread instead of sitting in a "busy waiting" + loop when a thread contention occurs. This is used in conjunction with the + NeverSleepOnThreadContention option, and has no effect unless + NeverSleepOnThreadContention is also defined. This option may improve + performance with many CPU cores and/or threads of different priorities. Note + that the SwitchToThread API call is only available on Windows 2000 and later.} + {.$define UseSwitchToThread} + +{-----------------------------Debugging Options-------------------------------} + +{Enable this option to suppress the generation of debug info for the + FastMM4.pas unit. This will prevent the integrated debugger from stepping into + the memory manager code.} +{.$define NoDebugInfo} + +{Enable this option to suppress the display of all message dialogs. This is + useful in service applications that should not be interrupted.} +{.$define NoMessageBoxes} + +{Set this option to use the Windows API OutputDebugString procedure to output + debug strings on startup/shutdown and when errors occur.} +{.$define UseOutputDebugString} + +{Set this option to use the assembly language version which is faster than the + pascal version. Disable only for debugging purposes. Setting the + CheckHeapForCorruption option automatically disables this option.} +{$define ASMVersion} + +{FastMM always catches attempts to free the same memory block twice, however it + can also check for corruption of the memory heap (typically due to the user + program overwriting the bounds of allocated memory). These checks are + expensive, and this option should thus only be used for debugging purposes. + If this option is set then the ASMVersion option is automatically disabled.} +{.$define CheckHeapForCorruption} + +{Enable this option to catch attempts to perform MM operations after FastMM has + been uninstalled. With this option set when FastMM is uninstalled it will not + install the previous MM, but instead a dummy MM handler that throws an error + if any MM operation is attempted. This will catch attempts to use the MM + after FastMM has been uninstalled.} +{$define DetectMMOperationsAfterUninstall} + +{Set the following option to do extensive checking of all memory blocks. All + blocks are padded with both a header and trailer that are used to verify the + integrity of the heap. Freed blocks are also cleared to to ensure that they + cannot be reused after being freed. This option slows down memory operations + dramatically and should only be used to debug an application that is + overwriting memory or reusing freed pointers. Setting this option + automatically enables CheckHeapForCorruption and disables ASMVersion. + Very important: If you enable this option your application will require the + FastMM_FullDebugMode.dll library. If this library is not available you will + get an error on startup.} +{.$define FullDebugMode} + + {Set this option to perform "raw" stack traces, i.e. check all entries on the + stack for valid return addresses. Note that this is significantly slower + than using the stack frame tracing method, but is usually more complete. Has + no effect unless FullDebugMode is enabled} + {$define RawStackTraces} + + {Set this option to check for user code that uses an interface of a freed + object. Note that this will disable the checking of blocks modified after + being freed (the two are not compatible). This option has no effect if + FullDebugMode is not also enabled.} + {.$define CatchUseOfFreedInterfaces} + + {Set this option to log all errors to a text file in the same folder as the + application. Memory errors (with the FullDebugMode option set) will be + appended to the log file. Has no effect if "FullDebugMode" is not set.} + {$define LogErrorsToFile} + + {Set this option to log all memory leaks to a text file in the same folder as + the application. Memory leak reports (with the FullDebugMode option set) + will be appended to the log file. Has no effect if "LogErrorsToFile" and + "FullDebugMode" are not also set. Note that usually all leaks are always + logged, even if they are "expected" leaks registered through + AddExpectedMemoryLeaks. Expected leaks registered by pointer may be excluded + through the HideExpectedLeaksRegisteredByPointer option.} + {$define LogMemoryLeakDetailToFile} + + {Deletes the error log file on startup. No effect if LogErrorsToFile is not + also set.} + {.$define ClearLogFileOnStartup} + + {Loads the FASTMM_FullDebugMode.dll dynamically. If the DLL cannot be found + then stack traces will not be available. Note that this may cause problems + due to a changed DLL unload order when sharing the memory manager. Use with + care.} + {.$define LoadDebugDLLDynamically} + + {.$define DoNotInstallIfDLLMissing} + {If the FastMM_FullDebugMode.dll file is not available then FastMM will not + install itself. No effect unless FullDebugMode and LoadDebugDLLDynamically + are also defined.} + + {FastMM usually allocates large blocks from the topmost available address and + medium and small blocks from the lowest available address (This reduces + fragmentation somewhat). With this option set all blocks are always + allocated from the highest available address. If the process has a >2GB + address space and contains bad pointer arithmetic code, this option should + help to catch those errors sooner.} + {$define AlwaysAllocateTopDown} + + {Disables the logging of memory dumps together with the other detail for + memory errors.} + {.$define DisableLoggingOfMemoryDumps} + + {If FastMM encounters a problem with a memory block inside the FullDebugMode + FreeMem handler then an "invalid pointer operation" exception will usually + be raised. If the FreeMem occurs while another exception is being handled + (perhaps in the try.. finally code) then the original exception will be + lost. With this option set FastMM will ignore errors inside FreeMem when an + exception is being handled, thus allowing the original exception to + propagate.} + {$define SuppressFreeMemErrorsInsideException} + + {Adds support for notification of memory manager events in FullDebugMode. + With this define set, the application may assign the OnDebugGetMemFinish, + OnDebugFreeMemStart, etc. callbacks in order to be notified when the + particular memory manager event occurs.} + {.$define FullDebugModeCallBacks} + +{---------------------------Memory Leak Reporting-----------------------------} + +{Set this option to enable reporting of memory leaks. Combine it with the two + options below for further fine-tuning.} +{.$define EnableMemoryLeakReporting} + + {Set this option to suppress the display and logging of expected memory leaks + that were registered by pointer. Leaks registered by size or class are often + ambiguous, so these expected leaks are always logged to file (in + FullDebugMode with the LogMemoryLeakDetailToFile option set) and are never + hidden from the leak display if there are more leaks than are expected.} + {.$define HideExpectedLeaksRegisteredByPointer} + + {Set this option to require the presence of the Delphi IDE to report memory + leaks. This option has no effect if the option "EnableMemoryLeakReporting" + is not also set.} + {.$define RequireIDEPresenceForLeakReporting} + + {Set this option to require the program to be run inside the IDE debugger to + report memory leaks. This option has no effect if the option + "EnableMemoryLeakReporting" is not also set. Note that this option does not + work with libraries, only EXE projects.} + {.$define RequireDebuggerPresenceForLeakReporting} + + {Set this option to require the presence of debug info ($D+ option) in the + compiled unit to perform memory leak checking. This option has no effect if + the option "EnableMemoryLeakReporting" is not also set.} + {.$define RequireDebugInfoForLeakReporting} + + {Set this option to enable manual control of the memory leak report. When + this option is set the ReportMemoryLeaksOnShutdown variable (default = false) + may be changed to select whether leak reporting should be done or not. When + this option is selected then both the variable must be set to true and the + other leak checking options must be applicable for the leak checking to be + done.} + {.$define ManualLeakReportingControl} + + {Set this option to disable the display of the hint below the memory leak + message.} + {.$define HideMemoryLeakHintMessage} + +{--------------------------Instruction Set Options----------------------------} + +{Set this option to enable the use of MMX instructions. Disabling this option + will result in a slight performance hit, but will enable compatibility with + AMD K5, Pentium I and earlier CPUs. MMX is currently only used in the variable + size move routines, so if UseCustomVariableSizeMoveRoutines is not set then + this option has no effect.} +{.$define EnableMMX} + + {Set this option to force the use of MMX instructions without checking + whether the CPU supports it. If this option is disabled then the CPU will be + checked for compatibility first, and if MMX is not supported it will fall + back to the FPU move code. Has no effect unless EnableMMX is also set.} + {$define ForceMMX} + +{-----------------------Memory Manager Sharing Options------------------------} + +{Allow sharing of the memory manager between a main application and DLLs that + were also compiled with FastMM. This allows you to pass dynamic arrays and + long strings to DLL functions provided both are compiled to use FastMM. + Sharing will only work if the library that is supposed to share the memory + manager was compiled with the "AttemptToUseSharedMM" option set. Note that if + the main application is single threaded and the DLL is multi-threaded that you + have to set the IsMultiThread variable in the main application to true or it + will crash when a thread contention occurs. Note that statically linked DLL + files are initialized before the main application, so the main application may + well end up sharing a statically loaded DLL's memory manager and not the other + way around. } +{.$define ShareMM} + + {Allow sharing of the memory manager by a DLL with other DLLs (or the main + application if this is a statically loaded DLL) that were also compiled with + FastMM. Set this option with care in dynamically loaded DLLs, because if the + DLL that is sharing its MM is unloaded and any other DLL is still sharing + the MM then the application will crash. This setting is only relevant for + DLL libraries and requires ShareMM to also be set to have any effect. + Sharing will only work if the library that is supposed to share the memory + manager was compiled with the "AttemptToUseSharedMM" option set. Note that + if DLLs are statically linked then they will be initialized before the main + application and then the DLL will in fact share its MM with the main + application. This option has no effect unless ShareMM is also set.} + {.$define ShareMMIfLibrary} + +{Define this to attempt to share the MM of the main application or other loaded + DLLs in the same process that were compiled with ShareMM set. When sharing a + memory manager, memory leaks caused by the sharer will not be freed + automatically. Take into account that statically linked DLLs are initialized + before the main application, so set the sharing options accordingly.} +{.$define AttemptToUseSharedMM} + +{Define this to enable backward compatibility for the memory manager sharing + mechanism used by Delphi 2006 and 2007, as well as older FastMM versions.} +{$define EnableBackwardCompatibleMMSharing} + +{-----------------------Security Options------------------------} + +{Windows clears physical memory before reusing it in another process. However, + it is not known how quickly this clearing is performed, so it is conceivable + that confidential data may linger in physical memory longer than absolutely + necessary. If you're paranoid about this kind of thing, enable this option to + clear all freed memory before returning it to the operating system. Note that + this incurs a noticeable performance hit.} +{.$define ClearMemoryBeforeReturningToOS} + +{With this option enabled freed memory will immediately be cleared inside the + FreeMem routine. This incurs a big performance hit, but may be worthwhile for + additional peace of mind when working with highly sensitive data. This option + supersedes the ClearMemoryBeforeReturningToOS option.} +{.$define AlwaysClearFreedMemory} + +{--------------------------------Option Grouping------------------------------} + +{Enabling this option enables FullDebugMode, InstallOnlyIfRunningInIDE and + LoadDebugDLLDynamically. Consequently, FastMM will install itself in + FullDebugMode if the application is being debugged inside the Delphi IDE. + Otherwise the default Delphi memory manager will be used (which is equivalent + to the non-FullDebugMode FastMM since Delphi 2006.)} +{.$define FullDebugModeInIDE} + +{Combines the FullDebugMode, LoadDebugDLLDynamically and + DoNotInstallIfDLLMissing options. Consequently FastMM will only be installed + (In FullDebugMode) when the FastMM_FullDebugMode.dll file is available. This + is useful when the same executable will be distributed for both debugging as + well as deployment.} +{.$define FullDebugModeWhenDLLAvailable} + +{Group the options you use for release and debug versions below} +{$ifdef Release} + {Specify the options you use for release versions below} + {.$undef FullDebugMode} + {.$undef CheckHeapForCorruption} + {.$define ASMVersion} + {.$undef EnableMemoryLeakReporting} + {.$undef UseOutputDebugString} +{$else} + {Specify the options you use for debugging below} + {.$define FullDebugMode} + {.$define EnableMemoryLeakReporting} + {.$define UseOutputDebugString} +{$endif} + +{--------------------Compilation Options For borlndmm.dll---------------------} +{If you're compiling the replacement borlndmm.dll, set the defines below + for the kind of dll you require.} + +{Set this option when compiling the borlndmm.dll} +{.$define borlndmmdll} + +{Set this option if the dll will be used by the Delphi IDE} +{.$define dllforide} + +{Set this option if you're compiling a debug dll} +{.$define debugdll} + +{Do not change anything below this line} +{$ifdef borlndmmdll} + {$define AssumeMultiThreaded} + {$undef HideExpectedLeaksRegisteredByPointer} + {$undef RequireDebuggerPresenceForLeakReporting} + {$undef RequireDebugInfoForLeakReporting} + {$define DetectMMOperationsAfterUninstall} + {$undef ManualLeakReportingControl} + {$undef ShareMM} + {$undef AttemptToUseSharedMM} + {$ifdef dllforide} + {$define NeverUninstall} + {$define HideMemoryLeakHintMessage} + {$undef RequireIDEPresenceForLeakReporting} + {$ifndef debugdll} + {$undef EnableMemoryLeakReporting} + {$endif} + {$else} + {$define EnableMemoryLeakReporting} + {$undef NeverUninstall} + {$undef HideMemoryLeakHintMessage} + {$define RequireIDEPresenceForLeakReporting} + {$endif} + {$ifdef debugdll} + {$define FullDebugMode} + {$define RawStackTraces} + {$undef CatchUseOfFreedInterfaces} + {$define LogErrorsToFile} + {$define LogMemoryLeakDetailToFile} + {$undef ClearLogFileOnStartup} + {$else} + {$undef FullDebugMode} + {$endif} +{$endif} + +{Move BCB related definitions here, because CB2006/CB2007 can build borlndmm.dll + for tracing memory leaks in BCB applications with "Build with Dynamic RTL" + switched on} +{------------------------------Patch BCB Terminate----------------------------} +{To enable the patching for BCB to make uninstallation and leak reporting + possible, you may need to add "BCB" definition + in "Project Options->Pascal/Delphi Compiler->Defines". + (Thanks to JiYuan Xie for implementing this.)} + +{$ifdef BCB} + {$ifdef CheckHeapForCorruption} + {$define PatchBCBTerminate} + {$else} + {$ifdef DetectMMOperationsAfterUninstall} + {$define PatchBCBTerminate} + {$else} + {$ifdef EnableMemoryLeakReporting} + {$define PatchBCBTerminate} + {$endif} + {$endif} + {$endif} + + {$ifdef PatchBCBTerminate} + {$define CheckCppObjectType} + {$undef CheckCppObjectTypeEnabled} + + {$ifdef CheckCppObjectType} + {$define CheckCppObjectTypeEnabled} + {$endif} + + {Turn off "CheckCppObjectTypeEnabled" option if neither "CheckHeapForCorruption" + option or "EnableMemoryLeakReporting" option were defined.} + {$ifdef CheckHeapForCorruption} + {$else} + {$ifdef EnableMemoryLeakReporting} + {$else} + {$undef CheckCppObjectTypeEnabled} + {$endif} + {$endif} + {$endif} +{$endif} diff --git a/System/LibXmlComps.dcr b/System/LibXmlComps.dcr new file mode 100644 index 0000000..ed9cb54 Binary files /dev/null and b/System/LibXmlComps.dcr differ diff --git a/System/LibXmlComps.pas b/System/LibXmlComps.pas new file mode 100644 index 0000000..57646be --- /dev/null +++ b/System/LibXmlComps.pas @@ -0,0 +1,122 @@ +(** +=============================================================================================== +Name : LibXmlComps +=============================================================================================== +Project : All Projects processing XML documents +=============================================================================================== +Subject : XML parser for Delphi's VCL toolbar +=============================================================================================== +Dipl.-Ing. (FH) Stefan Heymann, Softwaresysteme, Tübingen, Germany +=============================================================================================== +Date Author Changes +----------------------------------------------------------------------------------------------- +2000-03-31 HeySt 1.0.0 Start +2000-07-27 HeySt 1.0.1 Added "TAttr" declaration + Moved GetNormalize/SetNormalize to PROTECTED section +2001-02-03 HeySt Changed prototype for the TExternalEvent callback function type + so that C++Builder users should get it compiled better. + +2001-02-28 HeySt 1.0.2 Introduced the "StopParser" property. When you set this property to + TRUE in one of the Parser Events, parsing is stopped and the Execute + method returns. + Introduced Version numbers +2001-07-10 HeySt 1.0.3 Fixed a bug in TScannerXmlParser.DtdElementFound so that the + OnAttList event is correctly fired +2001-07-11 HeySt 1.1.0 Derived from the new TCustomXmlScanner class from LibXmlParser +2005-07-07 HeySt 1.1.1 Published new TranslateCharacter event property +*) + +UNIT LibXmlComps; + +INTERFACE + +USES + Classes, + LibXmlParser; + +TYPE + TXmlScanner = CLASS (TCustomXmlScanner) + PUBLIC + PROPERTY XmlParser; + PROPERTY StopParser; + PUBLISHED + PROPERTY Filename; + PROPERTY Normalize; + PROPERTY OnXmlProlog; + PROPERTY OnComment; + PROPERTY OnPI; + PROPERTY OnDtdRead; + PROPERTY OnStartTag; + PROPERTY OnEmptyTag; + PROPERTY OnEndTag; + PROPERTY OnContent; + PROPERTY OnCData; + PROPERTY OnElement; + PROPERTY OnAttList; + PROPERTY OnEntity; + PROPERTY OnNotation; + PROPERTY OnDtdError; + PROPERTY OnLoadExternal; + PROPERTY OnTranslateEncoding; + PROPERTY OnTranslateCharacter; + END; + + // The "Easy" XML Scanner leaves out events and properties which you are unlikely to use + // for "normal" XML files. + // CDATA sections trigger "OnContent" events + TEasyXmlScanner = CLASS (TCustomXmlScanner) + PROTECTED + PROCEDURE WhenCData (Content : string); OVERRIDE; + PUBLIC + PROPERTY XmlParser; + PROPERTY StopParser; + PUBLISHED + PROPERTY Filename; + PROPERTY Normalize; + PROPERTY OnComment; + PROPERTY OnPI; + PROPERTY OnStartTag; + PROPERTY OnEmptyTag; + PROPERTY OnEndTag; + PROPERTY OnContent; + PROPERTY OnLoadExternal; + PROPERTY OnTranslateEncoding; + END; + +PROCEDURE Register; + +(* +=============================================================================================== +IMPLEMENTATION +=============================================================================================== +*) + +IMPLEMENTATION + + +PROCEDURE Register; +BEGIN + RegisterComponents ('XML', [TXmlScanner, TEasyXmlScanner]); +END; + + +(* +=============================================================================================== +TEasyXmlScanner +=============================================================================================== +*) + +PROCEDURE TEasyXmlScanner.WhenCData (Content : string); +BEGIN + INHERITED WhenContent (Content); +END; + + +(* +=============================================================================================== +INITIALIZATION +=============================================================================================== +*) + +END. + diff --git a/System/LibXmlParser.pas b/System/LibXmlParser.pas new file mode 100644 index 0000000..a33805c --- /dev/null +++ b/System/LibXmlParser.pas @@ -0,0 +1,2719 @@ +(** +=============================================================================================== +Name : LibXmlParser + +Project : All Projects + +Subject : Progressive XML 1.0 Parser for all types of XML 1.0 Files +=============================================================================================== +Author : Stefan Heymann + Eschenweg 3 + 72076 Tübingen + Germany + +E-Mail: stefan@destructor.de +URL: www.destructor.de +=============================================================================================== +Source, Legals ("Licence") +-------------------------- +The official site to get this parser is http://www.destructor.de/ + +Usage and Distribution of this Source Code is ruled by the +"Destructor.de Source code Licence" (DSL) which comes with this file or +can be downloaded at http://www.destructor.de/ + +IN SHORT: Usage and distribution of this source code is free. + You use it completely on your own risk. + +Donateware +---------- +This code is donateware. When you think that it is worth it you can give a donation. +When you use the code on this site to earn money, you might think about giving a part of +it to the author. Whether you donate, and how much, is absolutely up to you. +You can find more information about donations on + http://www.destructor.de/donateware.htm +=============================================================================================== +!!! All parts of this code which are not finished or not conforming exactly to + the XmlSpec are marked with three exclamation marks + +-!- Parts where the parser may be able to detect errors in the document's syntax are + marked with the dash-exlamation mark-dash sequence. +=============================================================================================== +Terminology: +------------ +- Start: Start of a buffer part +- Final: End (last character) of a buffer part +- DTD: Document Type Definition +- DTDc: Document Type Declaration +- XMLSpec: The current W3C XML 1.0 Recommendation (version 1.0 TE as of 2004-02-04), Chapter No. +- Cur*: Fields concerning the "Current" part passed back by the "Scan" method +=============================================================================================== +Scanning the XML document +------------------------- +- Create TXmlParser Instance MyXml := TXmlParser.Create; +- Load XML Document MyXml.LoadFromFile (Filename); +- Start Scanning MyXml.StartScan; +- Scan Loop WHILE MyXml.Scan DO +- Test for Part Type CASE MyXml.CurPartType OF +- Handle Parts ... : ;;; +- Handle Parts ... : ;;; +- Handle Parts ... : ;;; + END; +- Destroy MyXml.Free; +=============================================================================================== +Loading the XML document +------------------------ +You can load the XML document from a file with the "LoadFromFile" method. +It is beyond the scope of this parser to perform HTTP or FTP accesses. If you want your +application to handle such requests (URLs), you can load the XML via HTTP or FTP or whatever +protocol and hand over the data buffer using the "LoadFromBuffer" or "SetBuffer" method. +"LoadFromBuffer" loads the internal buffer of TXmlParser with the given null-terminated +string, thereby creating a copy of that buffer. +"SetBuffer" just takes the pointer to another buffer, which means that the given +buffer pointer must be valid while the document is accessed via TXmlParser. +=============================================================================================== +Encodings: +---------- +This XML parser kind of "understands" the following encodings: +- UTF-8 +- ISO-8859-1 +- Windows-1252 ("ANSI") + +Any flavor of multi-byte characters (and this includes UCS-2 and UTF-16) is not supported. +Sorry. + +Every string which has to be passed to the application passes the virtual method +"TranslateEncoding" which translates the string from the current encoding (stored in +"CurEncoding") into the encoding the application wishes to receive. +The "TranslateEncoding" method that is built into TXmlParser assumes that the application +wants to receive Windows ANSI (Windows-1252, about the same as ISO-8859-1) and is able +to convert UTF-8 and ISO-8859-1 encodings. +For other source and target encodings, you will have to override "TranslateEncoding". +=============================================================================================== +Buffer Handling +--------------- +- The document must be loaded completely into a piece of RAM +- All character positions are referenced by PChar pointers +- The TXmlParser instance can either "own" the buffer itself (then, FBufferSize is > 0) + or reference the buffer of another instance or object (then, FBuffersize is 0 and + FBuffer is not NIL) +- The Property DocBuffer passes back a pointer to the first byte of the document. If there + is no document stored (FBuffer is NIL), the DocBuffer returns a pointer to a NULL character. +=============================================================================================== +Whitespace Handling +------------------- +The TXmlParser property "Normalize" determines how Whitespace is returned in Text Content: +While Normalize is true, all leading and trailing whitespace characters are trimmed of, all +Whitespace is converted to Space #x20 characters and contiguous Whitespace characters are +compressed to one. +If the "Scan" method reports a ptContent part, the application can get the original text +with all whitespace characters by extracting the characters from "CurStart" to "CurFinal". +If the application detects an xml:space attribute, it can set "Normalize" accordingly or +use CurStart/CurFinal. +Please note that TXmlParser does _not_ normalize Line Breaks to single LineFeed characters +as the XMLSpec requires (XMLSpec 2.11). +The xml:space attribute is not handled by TXmlParser. This is on behalf of the application. +=============================================================================================== +Non-XML-Conforming +------------------ +TXmlParser does not conform 100 % exactly to the XMLSpec: +- UTF-16 is not supported (XMLSpec 2.2) + (Workaround: Convert UTF-16 to UTF-8 and hand the buffer over to TXmlParser) +- As the parser only works with single byte strings, all Unicode characters > 255 + can currently not be handled correctly. + (Workaround: Use UTF-8 and handle UTF-8 characters by your own code) +- Line breaks are not normalized to single Linefeed #x0A characters (XMLSpec 2.11) + (Workaround: The Application can access the text contents on its own [CurStart, CurFinal], + thereby applying every normalization it wishes to) +- The attribute value normalization does not work exactly as defined in the + Second Edition of the XML 1.0 specification. +- See also the code parts marked with three consecutive exclamation marks. These are + parts which are not finished in the current code release. + +This list may be incomplete, so it may grow if I get to know any other points. +As work on the parser proceeds, this list may also shrink. +=============================================================================================== +Things Todo +----------- +- Introduce a new event/callback which is called when there is an unresolvable + entity or character reference or another error in the XML +- Correctly Support Unicode +- Use Streams instead of reading the whole XML into memory +- Support the new UnicodeString type of Delphi 2009 and onwards +=============================================================================================== +Change History, Version numbers +------------------------------- +The Date is given in ISO Year-Month-Day (YYYY-MM-DD) order. +Versions are counted from 1.0.0 beginning with the version from 2000-03-16. +Unreleased versions don't get a version number. + +Date Author Version Changes +----------------------------------------------------------------------------------------------- +2000-03-16 HeySt 1.0.0 Start +2000-03-28 HeySt 1.0.1 Initial Publishing of TXmlParser on the destructor.de Web Site +2000-03-30 HeySt 1.0.2 TXmlParser.AnalyzeCData: Call "TranslateEncoding" for CurContent +2000-03-31 HeySt 1.0.3 Deleted the StrPosE function (was not needed anyway) +2000-04-04 HeySt 1.0.4 TDtdElementRec modified: Start/Final for all Elements; + Should be backwards compatible. + AnalyzeDtdc: Set CurPartType to ptDtdc +2000-04-23 HeySt 1.0.5 New class TObjectList. Eliminated reference to the Delphi 5 + "Contnrs" unit so LibXmlParser is Delphi 4 compatible. +2000-07-03 HeySt 1.0.6 TNvpNode: Added Constructor +2000-07-11 HeySt 1.0.7 Removed "Windows" from USES clause + Added three-exclamation-mark comments for Utf8ToAnsi/AnsiToUtf8 + Added three-exclamation-mark comments for CHR function calls +2000-07-23 HeySt 1.0.8 TXmlParser.Clear: CurAttr.Clear; EntityStack.Clear; + (This was not a bug; just defensive programming) +2000-07-29 HeySt 1.0.9 TNvpList: Added methods: Node(Index), Value(Index), Name(Index); +2000-10-07 HeySt Introduced Conditional Defines + Uses Contnrs unit and its TObjectList class again for + Delphi 5 and newer versions +2001-01-30 HeySt Introduced Version Numbering + Made LoadFromFile and LoadFromBuffer BOOLEAN functions + Introduced FileMode parameter for LoadFromFile + BugFix: TAttrList.Analyze: Must add CWhitespace to ExtractName call + Comments worked over +2001-02-28 HeySt 1.0.10 Completely worked over and tested the UTF-8 functions + Fixed a bug in TXmlParser.Scan which caused it to start over when it + was called after the end of scanning, resulting in an endless loop + TEntityStack is now a TObjectList instead of TList +2001-07-03 HeySt 1.0.11 Updated Compiler Version IFDEFs for Kylix +2001-07-11 HeySt 1.0.12 New TCustomXmlScanner component (taken over from LibXmlComps.pas) +2001-07-14 HeySt 1.0.13 Bugfix TCustomXmlScanner.FOnTranslateEncoding +2001-10-22 HeySt Don't clear CurName anymore when the parser finds a CDATA section. +2001-12-03 HeySt 1.0.14 TObjectList.Clear: Make call to INHERITED method (fixes a memory leak) +2001-12-05 HeySt 1.0.15 TObjectList.Clear: removed call to INHERITED method + TObjectList.Destroy: Inserted SetCapacity call. + Reduces need for frequent re-allocation of pointer buffer + Dedicated to my father, Theodor Heymann +2002-06-26 HeySt 1.0.16 TXmlParser.Scan: Fixed a bug with PIs whose name is beginning + with 'xml'. Thanks to Uwe Kamm for submitting this bug. + The CurEncoding property is now always in uppercase letters (the XML + spec wants it to be treated case independently so when it's uppercase + comparisons are faster) +2002-03-04 HeySt 1.0.17 Included an IFDEF for Delphi 7 (VER150) and Kylix + There is a new symbol HAS_CONTNRS_UNIT which is used now to + distinguish between IDEs which come with the Contnrs unit and + those that don't. +2005-07-05 HeySt 1.0.18 Changed old comments referring to "PackSpaces" to "Normalize". + (not publicly released) Reworked IFDEF section at the top to better reflect + Kylix, C++Builder, Delphi 8, and Delphi 2005/2006/2007. + Reworked attribute value normalization to completely conform + to XMLSpec 3.3.3. Deleted the ReplaceGeneralEntities method, which + is not needed anymore. + TXmlParser: Added a new virtual method TranslateCharacter to + translate Unicode character references. + TXmlScanner: Added a new event OnTranslateCharacter to + translate Unicode character references. + Handle (i.e. skip) UTF-8 BOMs. + Switch $R and $B off. + Set UTF-8 as default encoding in .Clear +2009-12-31 HeySt 1.0.19 Finished work at the attribute value normalization. + Delphi 2009/2010 compatibility + (no UnicodeString compatibility though, sorry) +2010-10-12 HeySt 1.0.20 Checked Delphi XE compatibility + Included a $DEFINE for FreePascal compatibility + CurContent is not reset to an empty string with every start tag. + I will keep this behaviour so old code doesn't get broken. + In case you need this you can set CurContent yourself at every + start tag. +*) + + +// --- Delphi/Kylix/C++Builder Version Numbers +// As this is no code, this does not blow up your object or executable code at all +// Versions that will not work with this code (Delphi 1-3, .NET) will see invalid code and stop the compiler here +// The defines D4_OR_NEWER and D5_OR_NEWER are only kept for backward compatibility. +// They are not used in this code anymore. + + (*$DEFINE HAS_CONTNRS_UNIT *) // The Contnrs Unit was introduced in Delphi 5 + (*$DEFINE D4_OR_NEWER *) // It's Delphi 4 or newer for backwards compatibility + (*$DEFINE D5_OR_NEWER *) // It's Delphi 5 or newer for backwards compatibility + // Delphi 1, C++Builder 1: + (*$IFDEF VER80 *)This Code will not compile in Delphi 1 (*$ENDIF*) + (*$IFDEF VER83 *)This Code will not compile in C++Builder 1 (*$ENDIF*) + // Delphi 2, C++Builder 2: + (*$IFDEF VER90 *)This Code will not compile in Delphi 2 (*$ENDIF*) + (*$IFDEF VER93 *)This Code will not compile in C++Builder 2 (*$ENDIF*) + // Delphi 3, C++Builder 3: + (*$IFDEF VER100 *)This Code will not compile in Delphi 3 (*$ENDIF*) + (*$IFDEF VER110 *)This Code will not compile in C++Builder 3 (*$ENDIF*) + // Delphi 4, C++Builder 4: + (*$IFDEF VER120 *)(*$UNDEFINE D5_OR_NEWER *) (*$UNDEFINE HAS_CONTNRS_UNIT *) (*$ENDIF *) + (*$IFDEF VER125 *)(*$UNDEFINE D5_OR_NEWER *) (*$UNDEFINE HAS_CONTNRS_UNIT *) (*$ENDIF *) + // Managed Code + (*$IFDEF MANAGEDCODE *)This code will not compile as Managed Code (*$ENDIF *) + (*$IFDEF CLR *) This code will not compile as Managed Code (*$ENDIF *) + (*$IFDEF FPC *) (*$MODE delphi *) (*$ENDIF *) // It's FreePascal + + +(*$R- Switch Range Checking Off *) +(*$B- Switch Complete Boolean Evaluation Off *) + +UNIT LibXmlParser; + +INTERFACE + +USES + SysUtils, Classes, + (*$IFDEF HAS_CONTNRS_UNIT *) + Contnrs, + (*$ENDIF*) + Math; + +CONST + CVersion = '1.0.20'; // This variable will be updated for every release + // (I hope, I won't forget to do it everytime ...) + CUnknownChar = '?'; // Replacement for unknown/untransformable character references + +TYPE + TCharType = PAnsiChar; + TStringType = Utf8String; + + TPartType = // --- Document Part Types + (ptNone, // Nothing + ptXmlProlog, // XML Prolog XmlSpec 2.8 / 4.3.1 + ptComment, // Comment XmlSpec 2.5 + ptPI, // Processing Instruction XmlSpec 2.6 + ptDtdc, // Document Type Declaration XmlSpec 2.8 + ptStartTag, // Start Tag XmlSpec 3.1 + ptEmptyTag, // Empty-Element Tag XmlSpec 3.1 + ptEndTag, // End Tag XmlSpec 3.1 + ptContent, // Text Content between Tags + ptCData); // CDATA Section XmlSpec 2.7 + + TDtdElemType = // --- DTD Elements + (deElement, // !ELEMENT declaration + deAttList, // !ATTLIST declaration + deEntity, // !ENTITY declaration + deNotation, // !NOTATION declaration + dePI, // PI in DTD + deComment, // Comment in DTD + deError); // Error found in the DTD + +TYPE + TAttrList = CLASS; + TEntityStack = CLASS; + TNvpList = CLASS; + TElemDef = CLASS; + TElemList = CLASS; + TEntityDef = CLASS; + TNotationDef = CLASS; + + TDtdElementRec = RECORD // --- This Record is returned by the DTD parser callback function + Start, Final : TCharType; // Start/End of the Element's Declaration + CASE ElementType : TDtdElemType OF // Type of the Element + deElement, // + deAttList : (ElemDef : TElemDef); // + deEntity : (EntityDef : TEntityDef); // + deNotation : (NotationDef : TNotationDef); // + dePI : (Target : TCharType; // + Content : TCharType; + AttrList : TAttrList); + deError : (Pos : TCharType); // Error + // deComment : ((No additional fields here)); // + END; + + TXmlParser = CLASS // --- Internal Properties and Methods + PROTECTED + FBuffer : TCharType; // NIL if there is no buffer available + FBufferSize : INTEGER; // 0 if the buffer is not owned by the Document instance + FSource : STRING; // Name of Source of document. Filename for Documents loaded with LoadFromFile + + FXmlVersion : TStringType; // XML version from Document header. Default is '1.0' + FEncoding : TStringType; // Encoding from Document header. Default is 'UTF-8' + FStandalone : BOOLEAN; // Standalone declaration from Document header. Default is 'yes' + FRootName : TStringType; // Name of the Root Element (= DTD name) + FDtdcFinal : TCharType; // Pointer to the '>' character terminating the DTD declaration + + FNormalize : BOOLEAN; // If true: Pack Whitespace and don't return empty contents + EntityStack : TEntityStack; // Entity Stack for Parameter and General Entities + FCurEncoding : TStringType; // Current Encoding during parsing (always uppercase) + + PROCEDURE AnalyzeProlog; // Analyze XML Prolog or Text Declaration + PROCEDURE AnalyzeComment (Start : TCharType; VAR Final : TCharType); // Analyze Comments + PROCEDURE AnalyzePI (Start : TCharType; VAR Final : TCharType); // Analyze Processing Instructions (PI) + PROCEDURE AnalyzeDtdc; // Analyze Document Type Declaration + PROCEDURE AnalyzeDtdElements (Start : TCharType; VAR Final : TCharType); // Analyze DTD declarations + PROCEDURE AnalyzeTag; // Analyze Start/End/Empty-Element Tags + PROCEDURE AnalyzeCData; // Analyze CDATA Sections + PROCEDURE AnalyzeText (VAR IsDone : BOOLEAN); // Analyze Text Content between Tags + PROCEDURE AnalyzeElementDecl (Start : TCharType; VAR Final : TCharType); + PROCEDURE AnalyzeAttListDecl (Start : TCharType; VAR Final : TCharType); + PROCEDURE AnalyzeEntityDecl (Start : TCharType; VAR Final : TCharType); + PROCEDURE AnalyzeNotationDecl (Start : TCharType; VAR Final : TCharType); + + PROCEDURE PushPE (VAR Start : TCharType); + PROCEDURE ReplaceCharacterEntities (VAR Str : TStringType); + PROCEDURE ReplaceParameterEntities (VAR Str : TStringType); + + FUNCTION GetDocBuffer : TCharType; // Returns FBuffer or a pointer to a NUL char if Buffer is empty + + PUBLIC // --- Document Properties + PROPERTY XmlVersion : TStringType READ FXmlVersion; // XML version from the Document Prolog + PROPERTY Encoding : TStringType READ FEncoding; // Document Encoding from Prolog + PROPERTY Standalone : BOOLEAN READ FStandalone; // Standalone Declaration from Prolog + PROPERTY RootName : TStringType READ FRootName; // Name of the Root Element + PROPERTY Normalize : BOOLEAN READ FNormalize WRITE FNormalize; // True if Content is to be normalized + PROPERTY Source : STRING READ FSource; // Name of Document Source (Filename) + PROPERTY DocBuffer : TCharType READ GetDocBuffer; // Returns document buffer + PUBLIC // --- DTD Objects + Elements : TElemList; // Elements: List of TElemDef (contains Attribute Definitions) + Entities : TNvpList; // General Entities: List of TEntityDef + ParEntities : TNvpList; // Parameter Entities: List of TEntityDef + Notations : TNvpList; // Notations: List of TNotationDef + PUBLIC + CONSTRUCTOR Create; + DESTRUCTOR Destroy; OVERRIDE; + + // --- Document Handling + FUNCTION LoadFromFile (Filename : STRING; + FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN; + // Loads Document from given file + FUNCTION LoadFromBuffer (Buffer : TCharType) : BOOLEAN; // Loads Document from another buffer + PROCEDURE SetBuffer (Buffer : TCharType); // References another buffer + PROCEDURE Clear; // Clear Document + + PUBLIC + // --- Scanning through the document + CurPartType : TPartType; // Current Type + CurName : TStringType; // Current Name + CurContent : TStringType; // Current Normalized Content + CurStart : TCharType; // Current First character + CurFinal : TCharType; // Current Last character + CurAttr : TAttrList; // Current Attribute List + PROPERTY CurEncoding : TStringType READ FCurEncoding; // Current Encoding (always uppercase) + PROCEDURE StartScan; + FUNCTION Scan : BOOLEAN; + + // --- Events / Callbacks + FUNCTION LoadExternalEntity (SystemId, PublicId, + Notation : TStringType) : TXmlParser; VIRTUAL; + FUNCTION TranslateEncoding (CONST Source : TStringType) : TStringType; VIRTUAL; + FUNCTION TranslateCharacter (CONST UnicodeValue : INTEGER; + CONST UnknownChar : TStringType = CUnknownChar) : TStringType; VIRTUAL; + PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); VIRTUAL; + END; + + TValueType = // --- Attribute Value Type + (vtNormal, // Normal specified Attribute + vtImplied, // #IMPLIED attribute value + vtFixed, // #FIXED attribute value + vtDefault); // Attribute value from default value in !ATTLIST declaration + + TAttrDefault = // --- Attribute Default Type + (adDefault, // Normal default value + adRequired, // #REQUIRED attribute + adImplied, // #IMPLIED attribute + adFixed); // #FIXED attribute + + TAttrType = // --- Type of attribute + (atUnknown, // Unknown type + atCData, // Character data only + atID, // ID + atIdRef, // ID Reference + atIdRefs, // Several ID References, separated by Whitespace + atEntity, // Name of an unparsed Entity + atEntities, // Several unparsed Entity names, separated by Whitespace + atNmToken, // Name Token + atNmTokens, // Several Name Tokens, separated by Whitespace + atNotation, // A selection of Notation names (Unparsed Entity) + atEnumeration); // Enumeration + + TElemType = // --- Element content type + (etEmpty, // Element is always empty + etAny, // Element can have any mixture of PCDATA and any elements + etChildren, // Element must contain only elements + etMixed); // Mixed PCDATA and elements + + (*$IFDEF HAS_CONTNRS_UNIT *) + TObjectList = Contnrs.TObjectList; // Re-Export this identifier + (*$ELSE *) + TObjectList = CLASS (TList) + DESTRUCTOR Destroy; OVERRIDE; + PROCEDURE Delete (Index : INTEGER); + PROCEDURE Clear; OVERRIDE; + END; + (*$ENDIF *) + + TNvpNode = CLASS // Name-Value Pair Node + Name : TStringType; + Value : TStringType; + CONSTRUCTOR Create (TheName : TStringType = ''; TheValue : TStringType = ''); + END; + + TNvpList = CLASS (TObjectList) // Name-Value Pair List + PROCEDURE Add (Node : TNvpNode); + FUNCTION Node (Name : TStringType) : TNvpNode; OVERLOAD; + FUNCTION Node (Index : INTEGER) : TNvpNode; OVERLOAD; + FUNCTION Value (Name : TStringType) : TStringType; OVERLOAD; + FUNCTION Value (Index : INTEGER) : TStringType; OVERLOAD; + FUNCTION Name (Index : INTEGER) : TStringType; + END; + + TAttr = CLASS (TNvpNode) // Attribute of a Start-Tag or Empty-Element-Tag + ValueType : TValueType; + AttrType : TAttrType; + END; + + TAttrList = CLASS (TNvpList) // List of Attributes + PROCEDURE Analyze (Start : TCharType; VAR Final : TCharType); + END; + + TEntityStack = CLASS (TObjectList) // Stack where current position is stored before parsing entities + PROTECTED + Owner : TXmlParser; + PUBLIC + CONSTRUCTOR Create (TheOwner : TXmlParser); + PROCEDURE Push (LastPos : TCharType); OVERLOAD; + PROCEDURE Push (Instance : TObject; LastPos : TCharType); OVERLOAD; + FUNCTION Pop : TCharType; // Returns next char or NIL if EOF is reached. Frees Instance. + END; + + TAttrDef = CLASS (TNvpNode) // Represents a '; + + CUtf8BOM = #$EF#$BB#$BF; // The Byte Order Mark (U+FEFF) coded in UTF-8 + + // --- Name Constants for the above enumeration types + CPartType_Name : ARRAY [TPartType] OF TStringType = + ('', 'XML Prolog', 'Comment', 'PI', + 'DTD Declaration', 'Start Tag', 'Empty Tag', 'End Tag', + 'Text', 'CDATA'); + CValueType_Name : ARRAY [TValueType] OF TStringType = ('Normal', 'Implied', 'Fixed', 'Default'); + CAttrDefault_Name : ARRAY [TAttrDefault] OF TStringType = ('Default', 'Required', 'Implied', 'Fixed'); + CElemType_Name : ARRAY [TElemType] OF TStringType = ('Empty', 'Any', 'Childs only', 'Mixed'); + CAttrType_Name : ARRAY [TAttrType] OF TStringType = ('Unknown', 'CDATA', + 'ID', 'IDREF', 'IDREFS', + 'ENTITY', 'ENTITIES', + 'NMTOKEN', 'NMTOKENS', + 'Notation', 'Enumeration'); + +FUNCTION ConvertWs (Source: TStringType; PackWs: BOOLEAN) : TStringType; // Convert WS to spaces #x20 +PROCEDURE SetStringSF (VAR S : TStringType; BufferStart, BufferFinal : TCharType); // SetString by Start/Final of buffer +FUNCTION StrSFPas (Start, Finish : TCharType) : TStringType; // Convert buffer part to Pascal string +FUNCTION TrimWs (Source : TStringType) : TStringType; // Trim Whitespace + +(* +=============================================================================================== +TCustomXmlScanner: event based component wrapper for TXmlParser +=============================================================================================== +*) + +TYPE + TXmlPrologEvent = PROCEDURE (Sender : TObject; XmlVersion, Encoding: String; Standalone : BOOLEAN) OF OBJECT; + TCommentEvent = PROCEDURE (Sender : TObject; Comment : String) OF OBJECT; + TPIEvent = PROCEDURE (Sender : TObject; Target, Content: String; Attributes : TAttrList) OF OBJECT; + TDtdEvent = PROCEDURE (Sender : TObject; RootElementName : String) OF OBJECT; + TStartTagEvent = PROCEDURE (Sender : TObject; TagName : String; Attributes : TAttrList) OF OBJECT; + TEndTagEvent = PROCEDURE (Sender : TObject; TagName : String) OF OBJECT; + TContentEvent = PROCEDURE (Sender : TObject; Content : String) OF OBJECT; + TElementEvent = PROCEDURE (Sender : TObject; ElemDef : TElemDef) OF OBJECT; + TEntityEvent = PROCEDURE (Sender : TObject; EntityDef : TEntityDef) OF OBJECT; + TNotationEvent = PROCEDURE (Sender : TObject; NotationDef : TNotationDef) OF OBJECT; + TErrorEvent = PROCEDURE (Sender : TObject; ErrorPos : TCharType) OF OBJECT; + TExternalEvent = PROCEDURE (Sender : TObject; SystemId, PublicId, NotationId : String; + VAR Result : TXmlParser) OF OBJECT; + TEncodingEvent = FUNCTION (Sender : TObject; CurrentEncoding, Source : String) : String OF OBJECT; + TEncodeCharEvent = FUNCTION (Sender : TObject; UnicodeValue : INTEGER) : String OF OBJECT; + + TCustomXmlScanner = CLASS (TComponent) + PROTECTED + FXmlParser : TXmlParser; + FOnXmlProlog : TXmlPrologEvent; + FOnComment : TCommentEvent; + FOnPI : TPIEvent; + FOnDtdRead : TDtdEvent; + FOnStartTag : TStartTagEvent; + FOnEmptyTag : TStartTagEvent; + FOnEndTag : TEndTagEvent; + FOnContent : TContentEvent; + FOnCData : TContentEvent; + FOnElement : TElementEvent; + FOnAttList : TElementEvent; + FOnEntity : TEntityEvent; + FOnNotation : TNotationEvent; + FOnDtdError : TErrorEvent; + FOnLoadExternal : TExternalEvent; + FOnTranslateEncoding : TEncodingEvent; + FOnTranslateCharacter : TEncodeCharEvent; + FStopParser : BOOLEAN; + FUNCTION GetNormalize : BOOLEAN; + PROCEDURE SetNormalize (Value : BOOLEAN); + + PROCEDURE WhenXmlProlog(XmlVersion, Encoding: String; Standalone : BOOLEAN); VIRTUAL; + PROCEDURE WhenComment (Comment : String); VIRTUAL; + PROCEDURE WhenPI (Target, Content: String; Attributes : TAttrList); VIRTUAL; + PROCEDURE WhenDtdRead (RootElementName : String); VIRTUAL; + PROCEDURE WhenStartTag (TagName : String; Attributes : TAttrList); VIRTUAL; + PROCEDURE WhenEmptyTag (TagName : String; Attributes : TAttrList); VIRTUAL; + PROCEDURE WhenEndTag (TagName : String); VIRTUAL; + PROCEDURE WhenContent (Content : String); VIRTUAL; + PROCEDURE WhenCData (Content : String); VIRTUAL; + PROCEDURE WhenElement (ElemDef : TElemDef); VIRTUAL; + PROCEDURE WhenAttList (ElemDef : TElemDef); VIRTUAL; + PROCEDURE WhenEntity (EntityDef : TEntityDef); VIRTUAL; + PROCEDURE WhenNotation (NotationDef : TNotationDef); VIRTUAL; + PROCEDURE WhenDtdError (ErrorPos : TCharType); VIRTUAL; + + PUBLIC + CONSTRUCTOR Create (AOwner: TComponent); OVERRIDE; + DESTRUCTOR Destroy; OVERRIDE; + + PROCEDURE LoadFromFile (Filename : TFilename); // Load XML Document from file + PROCEDURE LoadFromBuffer (Buffer : TCharType); // Load XML Document from buffer + PROCEDURE SetBuffer (Buffer : TCharType); // Refer to Buffer + FUNCTION GetFilename : TFilename; + + PROCEDURE Execute; // Perform scanning + + PROTECTED + PROPERTY XmlParser : TXmlParser READ FXmlParser; + PROPERTY StopParser : BOOLEAN READ FStopParser WRITE FStopParser; + PROPERTY Filename : TFilename READ GetFilename WRITE LoadFromFile; + PROPERTY Normalize : BOOLEAN READ GetNormalize WRITE SetNormalize; + PROPERTY OnXmlProlog : TXmlPrologEvent READ FOnXmlProlog WRITE FOnXmlProlog; + PROPERTY OnComment : TCommentEvent READ FOnComment WRITE FOnComment; + PROPERTY OnPI : TPIEvent READ FOnPI WRITE FOnPI; + PROPERTY OnDtdRead : TDtdEvent READ FOnDtdRead WRITE FOnDtdRead; + PROPERTY OnStartTag : TStartTagEvent READ FOnStartTag WRITE FOnStartTag; + PROPERTY OnEmptyTag : TStartTagEvent READ FOnEmptyTag WRITE FOnEmptyTag; + PROPERTY OnEndTag : TEndTagEvent READ FOnEndTag WRITE FOnEndTag; + PROPERTY OnContent : TContentEvent READ FOnContent WRITE FOnContent; + PROPERTY OnCData : TContentEvent READ FOnCData WRITE FOnCData; + PROPERTY OnElement : TElementEvent READ FOnElement WRITE FOnElement; + PROPERTY OnAttList : TElementEvent READ FOnAttList WRITE FOnAttList; + PROPERTY OnEntity : TEntityEvent READ FOnEntity WRITE FOnEntity; + PROPERTY OnNotation : TNotationEvent READ FOnNotation WRITE FOnNotation; + PROPERTY OnDtdError : TErrorEvent READ FOnDtdError WRITE FOnDtdError; + PROPERTY OnLoadExternal : TExternalEvent READ FOnLoadExternal WRITE FOnLoadExternal; + PROPERTY OnTranslateEncoding : TEncodingEvent READ FOnTranslateEncoding WRITE FOnTranslateEncoding; + PROPERTY OnTranslateCharacter : TEncodeCharEvent READ FOnTranslateCharacter WRITE FOnTranslateCharacter; + END; + +(* +=============================================================================================== +IMPLEMENTATION +=============================================================================================== +*) + +IMPLEMENTATION + +(* +=============================================================================================== +"Special" Helper Functions + +Don't ask me why. But including these functions makes the parser *DRAMATICALLY* faster +on my K6-233 and Pentium-M machine. You can test it yourself just by commenting them out. +They do exactly the same as the Assembler routines defined in SysUtils. +(This is where you can see how great the Delphi compiler really is. The compiled code is +faster than hand-coded assembler! :-) +=============================================================================================== +--> Just move this line below the StrScan function --> *) + +FUNCTION StrPos (CONST Str, SearchStr : TCharType) : TCharType; + // Same functionality as SysUtils.StrPos +VAR + First : ANSICHAR; + Len : INTEGER; +BEGIN + First := SearchStr^; + Len := StrLen (SearchStr); + Result := Str; + REPEAT + IF Result^ = First THEN + IF StrLComp (Result, SearchStr, Len) = 0 THEN BREAK; + IF Result^ = #0 THEN BEGIN + Result := NIL; + BREAK; + END; + INC (Result); + UNTIL FALSE; +END; + + +FUNCTION StrScan (CONST Start : TCharType; CONST Ch : ANSICHAR) : TCharType; + // Same functionality as SysUtils.StrScan +BEGIN + Result := Start; + WHILE Result^ <> Ch DO BEGIN + IF Result^ = #0 THEN BEGIN + Result := NIL; + EXIT; + END; + INC (Result); + END; +END; + + +(* +=============================================================================================== +Helper Functions +=============================================================================================== +*) + +FUNCTION DelChars (Source : TStringType; CharsToDelete : TCharset) : TStringType; + // Delete all "CharsToDelete" from the string +VAR + I : INTEGER; +BEGIN + Result := Source; + FOR I := Length (Result) DOWNTO 1 DO + IF Result [I] IN CharsToDelete THEN + Delete (Result, I, 1); +END; + +FUNCTION TrimWs (Source : TStringType) : TStringType; + // Trimms off Whitespace characters from both ends of the string +VAR + I : INTEGER; +BEGIN + // --- Trim Left + I := 1; + WHILE (I <= Length (Source)) AND (Source [I] IN CWhitespace) DO + INC (I); + Result := Copy (Source, I, MaxInt); + + // --- Trim Right + I := Length (Result); + WHILE (I > 1) AND (Result [I] IN CWhitespace) DO + DEC (I); + Delete (Result, I+1, Length (Result)-I); +END; + + +FUNCTION TrimAndPackSpace (Source : TStringType) : TStringType; + // Trim and pack contiguous space (#x20) characters + // Needed for attribute value normalization of non-CDATA attributes (XMLSpec 3.3.3) +VAR + I, T : INTEGER; +BEGIN + // --- Trim Left + T := 1; + FOR I := 1 to Length (Source) DO + IF Source [I] = #32 + THEN INC (T) + ELSE BREAK; + IF T > 1 + THEN Result := Copy (Source, T, MaxInt) + ELSE Result := Source; + + // --- Trim Right + I := Length (Result); + WHILE (I > 1) AND (Result [I] = #32) DO + DEC (I); + Delete (Result, I+1, Length (Result)-I); + + // --- Pack + FOR I := Length (Result) DOWNTO 2 DO + IF (Result [I] = #32) AND (Result [I-1] = #32) THEN + Delete (Result, I, 1); +END; + + +FUNCTION ConvertWs (Source: TStringType; PackWs: BOOLEAN) : TStringType; + // Converts all Whitespace characters to the Space #x20 character + // If "PackWs" is true, contiguous Whitespace characters are packed to one +VAR + I : INTEGER; +BEGIN + Result := Source; + FOR I := Length (Result) DOWNTO 1 DO + IF (Result [I] IN CWhitespace) THEN + IF PackWs AND (I > 1) AND (Result [I-1] IN CWhitespace) + THEN Delete (Result, I, 1) + ELSE Result [I] := #32; +END; + + + + +PROCEDURE SetStringSF (VAR S : TStringType; BufferStart, BufferFinal : TCharType); +BEGIN + SetString (S, BufferStart, BufferFinal-BufferStart+1); +END; + + +FUNCTION StrLPas (Start : TCharType; Len : INTEGER) : TStringType; +BEGIN + SetString (Result, Start, Len); +END; + + +FUNCTION StrSFPas (Start, Finish : TCharType) : TStringType; +BEGIN + SetString (Result, Start, Finish-Start+1); +END; + + +FUNCTION StrScanE (CONST Source : TCharType; CONST CharToScanFor : ANSICHAR) : TCharType; + // If "CharToScanFor" is not found, StrScanE returns the last char of the + // buffer instead of NIL +BEGIN + Result := StrScan (Source, CharToScanFor); + IF Result = NIL THEN + Result := StrEnd (Source)-1; +END; + + +PROCEDURE ExtractName (Start : TCharType; Terminators : TCharset; VAR Final : TCharType); + (* Extracts the complete Name beginning at "Start". + It is assumed that the name is contained in Markup, so the '>' character is + always a Termination. + Start: IN Pointer to first char of name. Is always considered to be valid + Terminators: IN Characters which terminate the name + Final: OUT Pointer to last char of name *) +BEGIN + Final := Start; + Include (Terminators, #0); + Include (Terminators, '>'); + WHILE NOT ((Final + 1)^ IN Terminators) DO + INC (Final); +END; + + +PROCEDURE ExtractQuote (Start : TCharType; VAR Content : TStringType; VAR Final : TCharType); + (* Extract a string which is contained in single or double Quotes. + Start: IN Pointer to opening quote + Content: OUT The quoted string + Final: OUT Pointer to closing quote *) +BEGIN + Final := StrScan (Start+1, Start^); + IF Final = NIL THEN BEGIN + Final := StrEnd (Start+1)-1; + SetString (Content, Start+1, Final-Start); + END + ELSE + SetString (Content, Start+1, Final-1-Start); +END; + + +(* +=============================================================================================== +TEntityStackNode +This Node is pushed to the "Entity Stack" whenever the parser parses entity replacement text. +The "Instance" field holds the Instance pointer of an External Entity buffer. When it is +popped, the Instance is freed. +The "Encoding" field holds the name of the Encoding. External Parsed Entities may have +another encoding as the document entity (XmlSpec 4.3.3). So when there is an " 0 THEN BEGIN + ESN := TEntityStackNode (Items [Count-1]); + Result := ESN.LastPos; + IF ESN.Instance <> NIL THEN + ESN.Instance.Free; + IF ESN.Encoding <> '' THEN + Owner.FCurEncoding := ESN.Encoding; // Restore current Encoding + Delete (Count-1); + END + ELSE + Result := NIL; +END; + + +(* +=============================================================================================== +TExternalID +----------- +XmlSpec 4.2.2: ExternalID ::= 'SYSTEM' S SystemLiteral | + 'PUBLIC' S PubidLiteral S SystemLiteral +XmlSpec 4.7: PublicID ::= 'PUBLIC' S PubidLiteral +SystemLiteral and PubidLiteral are quoted +=============================================================================================== +*) + +TYPE + TExternalID = CLASS + PublicId : TStringType; + SystemId : TStringType; + Final : TCharType; + CONSTRUCTOR Create (Start : TCharType); + END; + +CONSTRUCTOR TExternalID.Create (Start : TCharType); +BEGIN + INHERITED Create; + Final := Start; + IF StrLComp (Start, 'SYSTEM', 6) = 0 THEN BEGIN + WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final); + IF NOT (Final^ IN CQuoteChar) THEN EXIT; + ExtractQuote (Final, SystemID, Final); + END + ELSE IF StrLComp (Start, 'PUBLIC', 6) = 0 THEN BEGIN + WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final); + IF NOT (Final^ IN CQuoteChar) THEN EXIT; + ExtractQuote (Final, PublicID, Final); + INC (Final); + WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final); + IF NOT (Final^ IN CQuoteChar) THEN EXIT; + ExtractQuote (Final, SystemID, Final); + END; +END; + + +(* +=============================================================================================== +TXmlParser +=============================================================================================== +*) + +CONSTRUCTOR TXmlParser.Create; +BEGIN + INHERITED Create; + FBuffer := NIL; + FBufferSize := 0; + Elements := TElemList.Create; + Entities := TNvpList.Create; + ParEntities := TNvpList.Create; + Notations := TNvpList.Create; + CurAttr := TAttrList.Create; + EntityStack := TEntityStack.Create (Self); + Clear; +END; + + +DESTRUCTOR TXmlParser.Destroy; +BEGIN + Clear; + Elements.Free; + Entities.Free; + ParEntities.Free; + Notations.Free; + CurAttr.Free; + EntityStack.Free; + INHERITED Destroy; +END; + + +PROCEDURE TXmlParser.Clear; + // Free Buffer and clear all object attributes +BEGIN + IF (FBufferSize > 0) AND (FBuffer <> NIL) THEN + FreeMem (FBuffer); + FBuffer := NIL; + FBufferSize := 0; + FSource := ''; + FXmlVersion := ''; + FEncoding := 'UTF-8'; + FCurEncoding := 'UTF-8'; + FStandalone := FALSE; + FRootName := ''; + FDtdcFinal := NIL; + FNormalize := TRUE; + Elements.Clear; + Entities.Clear; + ParEntities.Clear; + Notations.Clear; + CurAttr.Clear; + EntityStack.Clear; +END; + + +FUNCTION TXmlParser.LoadFromFile (Filename : string; FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN; + // Loads Document from given file + // Returns TRUE if successful +VAR + f : FILE; + ReadIn : INTEGER; + OldFileMode : INTEGER; +BEGIN + Result := FALSE; + Clear; + + // --- Open File + OldFileMode := SYSTEM.FileMode; + TRY + SYSTEM.FileMode := FileMode; + TRY + AssignFile (f, Filename); + Reset (f, 1); + EXCEPT + EXIT; + END; + + TRY + // --- Allocate Memory + TRY + FBufferSize := Filesize (f) + 1; + GetMem (FBuffer, FBufferSize); + EXCEPT + Clear; + EXIT; + END; + + // --- Read File + TRY + BlockRead (f, FBuffer^, FBufferSize, ReadIn); + (FBuffer+ReadIn)^ := #0; // NULL termination + EXCEPT + Clear; + EXIT; + END; + FINALLY + CloseFile (f); + END; + + FSource := Filename; + Result := TRUE; + + FINALLY + SYSTEM.FileMode := OldFileMode; + END; +END; + + +FUNCTION TXmlParser.LoadFromBuffer (Buffer : TCharType) : BOOLEAN; + // Loads Document from another buffer + // Returns TRUE if successful + // The "Source" property becomes '' if successful +BEGIN + Result := FALSE; + Clear; + FBufferSize := StrLen (Buffer) + 1; + TRY + GetMem (FBuffer, FBufferSize); + EXCEPT + Clear; + EXIT; + END; + StrCopy (FBuffer, Buffer); + FSource := ''; + Result := TRUE; +END; + + +PROCEDURE TXmlParser.SetBuffer (Buffer : TCharType); // References another buffer +BEGIN + Clear; + FBuffer := Buffer; + FBufferSize := 0; + FSource := ''; +END; + + +//----------------------------------------------------------------------------------------------- +// Scanning through the document +//----------------------------------------------------------------------------------------------- + +PROCEDURE TXmlParser.StartScan; +BEGIN + CurPartType := ptNone; + CurName := ''; + CurContent := ''; + CurStart := NIL; + CurFinal := NIL; + CurAttr.Clear; + EntityStack.Clear; +END; + + +FUNCTION TXmlParser.Scan : BOOLEAN; + // Scans the next Part + // Returns TRUE if a part could be found, FALSE if there is no part any more + // + // "IsDone" can be set to FALSE by AnalyzeText in order to go to the next part + // if there is no Content due to normalization +VAR + IsDone : BOOLEAN; +BEGIN + REPEAT + IsDone := TRUE; + + // --- Start of next Part + IF CurStart = NIL THEN BEGIN + CurStart := DocBuffer; + IF StrLComp (CurStart, CUtf8BOM, 3) = 0 THEN BEGIN + INC (CurStart, 3); // Skip UTF-8 BOM + FEncoding := 'UTF-8'; + END; + END + ELSE + CurStart := CurFinal+1; + CurFinal := CurStart; + + // --- End of Document or Pop off a new part from the Entity stack? + IF CurStart^ = #0 THEN + CurStart := EntityStack.Pop; + + // --- No Document or End Of Document: Terminate Scan + IF (CurStart = NIL) OR (CurStart^ = #0) THEN BEGIN + CurStart := StrEnd (DocBuffer); + CurFinal := CurStart-1; + EntityStack.Clear; + Result := FALSE; + EXIT; + END; + + IF (StrLComp (CurStart, ''); + IF CurFinal <> NIL + THEN INC (CurFinal) + ELSE CurFinal := StrEnd (CurStart)-1; + FCurEncoding := CurAttr.Value ('encoding'); + IF FCurEncoding = '' THEN + FCurEncoding := 'UTF-8'; // Default XML Encoding is UTF-8 + AnsiStrupper (TCharType (FCurEncoding)); + CurPartType := ptXmlProlog; + CurName := ''; + CurContent := ''; +END; + + +PROCEDURE TXmlParser.AnalyzeComment (Start : TCharType; VAR Final : TCharType); + // Analyze Comments +BEGIN + Final := StrPos (Start+4, '-->'); + IF Final = NIL + THEN Final := StrEnd (Start)-1 + ELSE INC (Final, 2); + CurPartType := ptComment; +END; + + +PROCEDURE TXmlParser.AnalyzePI (Start : TCharType; VAR Final : TCharType); + // Analyze Processing Instructions (PI) +VAR + F : TCharType; +BEGIN + CurPartType := ptPI; + Final := StrPos (Start+2, '?>'); + IF Final = NIL + THEN Final := StrEnd (Start)-1 + ELSE INC (Final); + ExtractName (Start+2, CWhitespace + ['?', '>'], F); + SetStringSF (CurName, Start+2, F); + SetStringSF (CurContent, F+1, Final-2); + CurAttr.Analyze (F+1, F); +END; + + +PROCEDURE TXmlParser.AnalyzeDtdc; + (* Analyze Document Type Declaration + doctypedecl ::= '' + markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment + PEReference ::= '%' Name ';' + + elementdecl ::= '' + AttlistDecl ::= '' + EntityDecl ::= '' | + '' + NotationDecl ::= '' + PI ::= '' Char* )))? '?>' + Comment ::= '' *) +TYPE + TPhase = (phName, phDtd, phInternal, phFinishing); +VAR + Phase : TPhase; + F : TCharType; + ExternalID : TExternalID; + ExternalDTD : TXmlParser; + DER : TDtdElementRec; +BEGIN + DER.Start := CurStart; + EntityStack.Clear; // Clear stack for Parameter Entities + CurPartType := ptDtdc; + + // --- Don't read DTDc twice + IF FDtdcFinal <> NIL THEN BEGIN + CurFinal := FDtdcFinal; + EXIT; + END; + + // --- Scan DTDc + CurFinal := CurStart + 9; // First char after '' : BREAK; + ELSE IF NOT (CurFinal^ IN CWhitespace) THEN BEGIN + CASE Phase OF + phName : IF (CurFinal^ IN CNameStart) THEN BEGIN + ExtractName (CurFinal, CWhitespace + ['[', '>'], F); + SetStringSF (FRootName, CurFinal, F); + CurFinal := F; + Phase := phDtd; + END; + phDtd : IF (StrLComp (CurFinal, 'SYSTEM', 6) = 0) OR + (StrLComp (CurFinal, 'PUBLIC', 6) = 0) THEN BEGIN + ExternalID := TExternalID.Create (CurFinal); + ExternalDTD := NIL; + TRY + ExternalDTD := LoadExternalEntity (ExternalId.SystemId, ExternalID.PublicId, ''); + F := StrPos (ExternalDtd.DocBuffer, ' NIL THEN + AnalyzeDtdElements (F, F); + CurFinal := ExternalID.Final; + FINALLY + ExternalDTD.Free; + ExternalID.Free; + END; + END; + ELSE BEGIN + DER.ElementType := deError; + DER.Pos := CurFinal; + DER.Final := CurFinal; + DtdElementFound (DER); + END; + END; + + END; + END; + INC (CurFinal); + UNTIL FALSE; + + CurPartType := ptDtdc; + CurName := ''; + CurContent := ''; + + // -!- It is an error in the document if "EntityStack" is not empty now + IF EntityStack.Count > 0 THEN BEGIN + DER.ElementType := deError; + DER.Final := CurFinal; + DER.Pos := CurFinal; + DtdElementFound (DER); + END; + + EntityStack.Clear; // Clear stack for General Entities + FDtdcFinal := CurFinal; +END; + + +PROCEDURE TXmlParser.AnalyzeDtdElements (Start : TCharType; VAR Final : TCharType); + // Analyze the "Elements" of a DTD contained in the external or + // internal DTD subset. +VAR + DER : TDtdElementRec; +BEGIN + Final := Start; + REPEAT + CASE Final^ OF + '%' : BEGIN + PushPE (Final); + CONTINUE; + END; + #0 : IF EntityStack.Count = 0 THEN + BREAK + ELSE BEGIN + CurFinal := EntityStack.Pop; + CONTINUE; + END; + ']', + '>' : BREAK; + '<' : IF StrLComp (Final, ' NIL then begin + EntLen := PSemi - TCharType (Str) - i; + EntName := Copy (Str, i + 1, EntLen); + IF EntName = 'lt' THEN Repl := '<' + ELSE IF EntName = 'gt' THEN Repl := '>' + ELSE IF EntName = 'amp' THEN Repl := '&' + ELSE IF EntName = 'apos' THEN Repl := '''' + ELSE IF EntName = 'quot' THEN Repl := '"' + ELSE IF Copy (EntName, 1, 1) = '#' THEN BEGIN // Character Reference + IF EntName [2] = 'x' + THEN Repl := TranslateCharacter(StrToIntDef ('$' + Copy (string (EntName), 3, MaxInt), ord (CUnknownChar))) + ELSE Repl := TranslateCharacter(StrToIntDef ( Copy (string (EntName), 2, MaxInt), ord (CUnknownChar))); + END + ELSE BEGIN // Resolve General Entity Reference + EntityDef := TEntityDef (Entities.Node (EntName)); + IF EntityDef = NIL THEN // Unknown Entity + Repl := EntName + ELSE BEGIN // Known Entity + IF EntityDef.Value <> '' then // Internal Entity + Repl := NormalizeAttrValStr (EntityDef.Value, FALSE) + ELSE BEGIN // External Entity + ExternalEntity := NIL; + TRY + ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName); + ExternalEntity.Normalize := Self.Normalize; + Repl := ''; // External Entity can have a different encoding than parent entity + ExternalEntity.StartScan; + WHILE ExternalEntity.Scan DO + if (ExternalEntity.CurPartType = ptContent) or (ExternalEntity.CurPartType = ptCData) then + Repl := Repl + ExternalEntity.CurContent; // CurContent is already encoded + Repl := NormalizeAttrValStr (Repl, TRUE); // Recursively resolve Entity References + FINALLY + ExternalEntity.Free; + END; + END; + END + END; + end + else + EntLen := 0; + if IsEncoded + then Result := Result + Copy (Str, i - EncLen, EncLen) + Repl + else Result := Result + TranslateEncoding (Copy (Str, i - EncLen, EncLen)) + Repl; + EncLen := 0; + i := i + EntLen + 1; + end; + else inc (EncLen); + end; + inc (i); + end; + if IsEncoded + then Result := Result + Copy (Str, Len - EncLen + 1, EncLen) + else Result := Result + TranslateEncoding (Copy (Str, Len - EncLen + 1, EncLen)); + end; + + begin + if (Attr.AttrType in [atCData, atUnknown]) + then Attr.Value := NormalizeAttrValStr (Attr.Value, FALSE) + else Attr.Value := TrimAndPackSpace (NormalizeAttrValStr (Attr.Value, FALSE)); + end; + +VAR + S, F : TCharType; + Attr : TAttr; + ElemDef : TElemDef; + AttrDef : TAttrDef; + I : INTEGER; +BEGIN + CurPartType := ptStartTag; + S := CurStart+1; + IF S^ = '/' THEN BEGIN + CurPartType := ptEndTag; + INC (S); + END; + ExtractName (S, CWhitespace + ['/'], F); + SetStringSF (CurName, S, F); + CurAttr.Analyze (F+1, CurFinal); + IF CurFinal^ = '/' THEN + CurPartType := ptEmptyTag; + CurFinal := StrScanE (CurFinal, '>'); + + // --- Set Default Attribute values for nonexistent attributes + IF (CurPartType = ptStartTag) OR (CurPartType = ptEmptyTag) THEN BEGIN + ElemDef := Elements.Node (CurName); + IF ElemDef <> NIL THEN BEGIN + FOR I := 0 TO ElemDef.Count-1 DO BEGIN + AttrDef := TAttrDef (ElemDef [I]); + Attr := TAttr (CurAttr.Node (AttrDef.Name)); + IF (Attr = NIL) AND (AttrDef.Value <> '') THEN BEGIN + Attr := TAttr.Create (AttrDef.Name, AttrDef.Value); + Attr.ValueType := vtDefault; + CurAttr.Add (Attr); + END; + IF Attr <> NIL THEN BEGIN + CASE AttrDef.DefaultType OF + adDefault : ; + adRequired : ; // -!- It is an error in the document if "Attr.Value" is an empty string + adImplied : Attr.ValueType := vtImplied; + adFixed : BEGIN + Attr.ValueType := vtFixed; + Attr.Value := AttrDef.Value; + END; + END; + Attr.AttrType := AttrDef.AttrType; + END; + END; + END; + + // --- Normalize Attribute Values + FOR I := 0 TO CurAttr.Count-1 DO + NormalizeAttrValue (TAttr (CurAttr [I])); + END; +END; + + +PROCEDURE TXmlParser.AnalyzeCData; + // Analyze CDATA Sections +BEGIN + CurPartType := ptCData; + CurFinal := StrPos (CurStart, CDEnd); + IF CurFinal = NIL THEN BEGIN + CurFinal := StrEnd (CurStart)-1; + CurContent := TranslateEncoding (TStringType(StrPas (CurStart+Length (CDStart)))); + END + ELSE BEGIN + SetStringSF (CurContent, CurStart+Length (CDStart), CurFinal-1); + INC (CurFinal, Length (CDEnd)-1); + CurContent := TranslateEncoding (CurContent); + END; +END; + + +PROCEDURE TXmlParser.AnalyzeText (VAR IsDone : BOOLEAN); + (* Analyzes Text Content between Tags. CurFinal will point to the last content character. + Content ends at a '<' character or at the end of the document. + Entity References and Character References are resolved. + If Normalize is TRUE, contiguous Whitespace Characters will be compressed to + one Space #x20 character, Whitespace at the beginning and end of content will + be trimmed off and content which is or becomes empty is not returned to + the application (in this case, "IsDone" is set to FALSE which causes the + Scan method to proceed directly to the next part. *) + + PROCEDURE ProcessEntity; + (* Is called if there is an ampsersand '&' character found in the document. + IN "CurFinal" points to the ampersand + OUT "CurFinal" points to the first character after the semi-colon ';' *) + VAR + P : TCharType; + Name : TStringType; + EntityDef : TEntityDef; + ExternalEntity : TXmlParser; + BEGIN + P := StrScan (CurFinal, ';'); + IF P <> NIL THEN BEGIN + SetStringSF (Name, CurFinal+1, P-1); + + // Is it a Character Reference? + IF (CurFinal+1)^ = '#' THEN BEGIN + IF (CurFinal+2)^ = 'x' + THEN CurContent := CurContent + TranslateCharacter (StrToIntDef ('$' + Copy (string (Name), 3, MaxInt), 32)) + ELSE CurContent := CurContent + TranslateCharacter (StrToIntDef ( Copy (string (Name), 2, MaxInt), 32)); + CurFinal := P+1; + EXIT; + END + + // Is it a Predefined Entity? + ELSE IF Name = 'lt' THEN BEGIN CurContent := CurContent + '<'; CurFinal := P+1; EXIT; END + ELSE IF Name = 'gt' THEN BEGIN CurContent := CurContent + '>'; CurFinal := P+1; EXIT; END + ELSE IF Name = 'amp' THEN BEGIN CurContent := CurContent + '&'; CurFinal := P+1; EXIT; END + ELSE IF Name = 'apos' THEN BEGIN CurContent := CurContent + ''''; CurFinal := P+1; EXIT; END + ELSE IF Name = 'quot' THEN BEGIN CurContent := CurContent + '"'; CurFinal := P+1; EXIT; END; + + // Replace with Entity from DTD + EntityDef := TEntityDef (Entities.Node (Name)); + IF EntityDef <> NIL THEN BEGIN + IF EntityDef.Value <> '' THEN BEGIN + EntityStack.Push (P+1); + CurFinal := TCharType (EntityDef.Value); + END + ELSE BEGIN + ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName); + EntityStack.Push (ExternalEntity, P+1); + CurFinal := ExternalEntity.DocBuffer; + END; + END + ELSE BEGIN + CurContent := CurContent + Name; + CurFinal := P+1; + END; + END + ELSE BEGIN + INC (CurFinal); + END; + END; + +VAR + C : INTEGER; +BEGIN + CurFinal := CurStart; + CurPartType := ptContent; + CurContent := ''; + C := 0; + REPEAT + CASE CurFinal^ OF + '&' : BEGIN + CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C)); + C := 0; + ProcessEntity; + CONTINUE; + END; + #0 : BEGIN + IF EntityStack.Count = 0 THEN + BREAK + ELSE BEGIN + CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C)); + C := 0; + CurFinal := EntityStack.Pop; + CONTINUE; + END; + END; + '<' : BREAK; + ELSE INC (C); + END; + INC (CurFinal); + UNTIL FALSE; + CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C)); + DEC (CurFinal); + + IF FNormalize THEN BEGIN + CurContent := ConvertWs (TrimWs (CurContent), TRUE); + IsDone := CurContent <> ''; // IsDone will only get FALSE if Normalize is TRUE + END; +END; + + +PROCEDURE TXmlParser.AnalyzeElementDecl (Start : TCharType; VAR Final : TCharType); + (* Parse ' character + XmlSpec 3.2: + elementdecl ::= '' + contentspec ::= 'EMPTY' | 'ANY' | Mixed | children + Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | + '(' S? '#PCDATA' S? ')' + children ::= (choice | seq) ('?' | '*' | '+')? + choice ::= '(' S? cp ( S? '|' S? cp )* S? ')' + cp ::= (Name | choice | seq) ('?' | '*' | '+')? + seq ::= '(' S? cp ( S? ',' S? cp )* S? ')' + + More simply: + contentspec ::= EMPTY + ANY + '(#PCDATA)' + '(#PCDATA | A | B)*' + '(A, B, C)' + '(A | B | C)' + '(A?, B*, C+), + '(A, (B | C | D)* )' *) +VAR + Element : TElemDef; + Elem2 : TElemDef; + F : TCharType; + DER : TDtdElementRec; +BEGIN + Element := TElemDef.Create; + Final := Start + 9; + DER.Start := Start; + REPEAT + IF Final^ = '>' THEN BREAK; + IF (Final^ IN CNameStart) AND (Element.Name = '') THEN BEGIN + ExtractName (Final, CWhitespace, F); + SetStringSF (Element.Name, Final, F); + Final := F; + F := StrScan (Final+1, '>'); + IF F = NIL THEN BEGIN + Element.Definition := TStringType (Final); + Final := StrEnd (Final); + BREAK; + END + ELSE BEGIN + SetStringSF (Element.Definition, Final+1, F-1); + Final := F; + BREAK; + END; + END; + INC (Final); + UNTIL FALSE; + Element.Definition := DelChars (Element.Definition, CWhitespace); + ReplaceParameterEntities (Element.Definition); + IF Element.Definition = 'EMPTY' THEN Element.ElemType := etEmpty + ELSE IF Element.Definition = 'ANY' THEN Element.ElemType := etAny + ELSE IF Copy (Element.Definition, 1, 8) = '(#PCDATA' THEN Element.ElemType := etMixed + ELSE IF Copy (Element.Definition, 1, 1) = '(' THEN Element.ElemType := etChildren + ELSE Element.ElemType := etAny; + + Elem2 := Elements.Node (Element.Name); + IF Elem2 <> NIL THEN + Elements.Delete (Elements.IndexOf (Elem2)); + Elements.Add (Element); + Final := StrScanE (Final, '>'); + DER.ElementType := deElement; + DER.ElemDef := Element; + DER.Final := Final; + DtdElementFound (DER); +END; + + +PROCEDURE TXmlParser.AnalyzeAttListDecl (Start : TCharType; VAR Final : TCharType); + (* Parse ' character + XmlSpec 3.3: + AttlistDecl ::= '' + AttDef ::= S Name S AttType S DefaultDecl + AttType ::= StringType | TokenizedType | EnumeratedType + StringType ::= 'CDATA' + TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS' + EnumeratedType ::= NotationType | Enumeration + NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')' + Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' + DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue) + AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'" + Examples: + *) +TYPE + TPhase = (phElementName, phName, phType, phNotationContent, phDefault); +VAR + Phase : TPhase; + F : TCharType; + ElementName : TStringType; + ElemDef : TElemDef; + AttrDef : TAttrDef; + AttrDef2 : TAttrDef; + Strg : TStringType; + DER : TDtdElementRec; +BEGIN + Final := Start + 9; // The character after ' : BREAK; + ELSE CASE Phase OF + phElementName : BEGIN + ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F); + SetStringSF (ElementName, Final, F); + Final := F; + ElemDef := Elements.Node (ElementName); + IF ElemDef = NIL THEN BEGIN + ElemDef := TElemDef.Create; + ElemDef.Name := ElementName; + ElemDef.Definition := 'ANY'; + ElemDef.ElemType := etAny; + Elements.Add (ElemDef); + END; + Phase := phName; + END; + phName : BEGIN + AttrDef := TAttrDef.Create; + ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F); + SetStringSF (AttrDef.Name, Final, F); + Final := F; + AttrDef2 := TAttrDef (ElemDef.Node (AttrDef.Name)); + IF AttrDef2 <> NIL THEN + ElemDef.Delete (ElemDef.IndexOf (AttrDef2)); + ElemDef.Add (AttrDef); + Phase := phType; + END; + phType : BEGIN + IF Final^ = '(' THEN BEGIN + F := StrScan (Final+1, ')'); + IF F <> NIL + THEN SetStringSF (AttrDef.TypeDef, Final+1, F-1) + ELSE AttrDef.TypeDef := TStringType (Final+1); + AttrDef.TypeDef := DelChars (AttrDef.TypeDef, CWhitespace); + AttrDef.AttrType := atEnumeration; + ReplaceParameterEntities (AttrDef.TypeDef); + ReplaceCharacterEntities (AttrDef.TypeDef); + Phase := phDefault; + END + ELSE IF StrLComp (Final, 'NOTATION', 8) = 0 THEN BEGIN + INC (Final, 8); + AttrDef.AttrType := atNotation; + Phase := phNotationContent; + END + ELSE BEGIN + ExtractName (Final, CWhitespace+CQuoteChar+['#'], F); + SetStringSF (AttrDef.TypeDef, Final, F); + IF AttrDef.TypeDef = 'CDATA' THEN AttrDef.AttrType := atCData + ELSE IF AttrDef.TypeDef = 'ID' THEN AttrDef.AttrType := atId + ELSE IF AttrDef.TypeDef = 'IDREF' THEN AttrDef.AttrType := atIdRef + ELSE IF AttrDef.TypeDef = 'IDREFS' THEN AttrDef.AttrType := atIdRefs + ELSE IF AttrDef.TypeDef = 'ENTITY' THEN AttrDef.AttrType := atEntity + ELSE IF AttrDef.TypeDef = 'ENTITIES' THEN AttrDef.AttrType := atEntities + ELSE IF AttrDef.TypeDef = 'NMTOKEN' THEN AttrDef.AttrType := atNmToken + ELSE IF AttrDef.TypeDef = 'NMTOKENS' THEN AttrDef.AttrType := atNmTokens; + Phase := phDefault; + END + END; + phNotationContent : BEGIN + F := StrScan (Final, ')'); + IF F <> NIL THEN + SetStringSF (AttrDef.Notations, Final+1, F-1) + ELSE BEGIN + AttrDef.Notations := TStringType (Final+1); + Final := StrEnd (Final); + END; + ReplaceParameterEntities (AttrDef.Notations); + AttrDef.Notations := DelChars (AttrDef.Notations, CWhitespace); + Phase := phDefault; + END; + phDefault : BEGIN + IF Final^ = '#' THEN BEGIN + ExtractName (Final, CWhiteSpace + CQuoteChar, F); + SetStringSF (Strg, Final, F); + Final := F; + ReplaceParameterEntities (Strg); + IF Strg = '#REQUIRED' THEN BEGIN AttrDef.DefaultType := adRequired; Phase := phName; END + ELSE IF Strg = '#IMPLIED' THEN BEGIN AttrDef.DefaultType := adImplied; Phase := phName; END + ELSE IF Strg = '#FIXED' THEN AttrDef.DefaultType := adFixed; + END + ELSE IF (Final^ IN CQuoteChar) THEN BEGIN + ExtractQuote (Final, AttrDef.Value, Final); + ReplaceParameterEntities (AttrDef.Value); + ReplaceCharacterEntities (AttrDef.Value); + Phase := phName; + END; + IF Phase = phName THEN BEGIN + AttrDef := NIL; + END; + END; + + END; + END; + INC (Final); + UNTIL FALSE; + + Final := StrScan (Final, '>'); + + DER.ElementType := deAttList; + DER.ElemDef := ElemDef; + DER.Final := Final; + DtdElementFound (DER); +END; + + +PROCEDURE TXmlParser.AnalyzeEntityDecl (Start : TCharType; VAR Final : TCharType); + (* Parse ' character + XmlSpec 4.2: + EntityDecl ::= '' | + '' + EntityDef ::= EntityValue | (ExternalID NDataDecl?) + PEDef ::= EntityValue | ExternalID + NDataDecl ::= S 'NDATA' S Name + EntityValue ::= '"' ([^%&"] | PEReference | EntityRef | CharRef)* '"' | + "'" ([^%&'] | PEReference | EntityRef | CharRef)* "'" + PEReference ::= '%' Name ';' + + Examples + + + + "> + + + Dies ist ein Test-Absatz

"> + *) +TYPE + TPhase = (phName, phContent, phNData, phNotationName, phFinalGT); +VAR + Phase : TPhase; + IsParamEntity : BOOLEAN; + F : TCharType; + ExternalID : TExternalID; + EntityDef : TEntityDef; + EntityDef2 : TEntityDef; + DER : TDtdElementRec; +BEGIN + Final := Start + 8; // First char after ' : BREAK; + ELSE CASE Phase OF + phName : IF Final^ IN CNameStart THEN BEGIN + ExtractName (Final, CWhitespace + CQuoteChar, F); + SetStringSF (EntityDef.Name, Final, F); + Final := F; + Phase := phContent; + END; + phContent : IF Final^ IN CQuoteChar THEN BEGIN + ExtractQuote (Final, EntityDef.Value, Final); + Phase := phFinalGT; + END + ELSE IF (StrLComp (Final, 'SYSTEM', 6) = 0) OR + (StrLComp (Final, 'PUBLIC', 6) = 0) THEN BEGIN + ExternalID := TExternalID.Create (Final); + EntityDef.SystemId := ExternalID.SystemId; + EntityDef.PublicId := ExternalID.PublicId; + Final := ExternalID.Final; + Phase := phNData; + ExternalID.Free; + END; + phNData : IF StrLComp (Final, 'NDATA', 5) = 0 THEN BEGIN + INC (Final, 4); + Phase := phNotationName; + END; + phNotationName : IF Final^ IN CNameStart THEN BEGIN + ExtractName (Final, CWhitespace + ['>'], F); + SetStringSF (EntityDef.NotationName, Final, F); + Final := F; + Phase := phFinalGT; + END; + phFinalGT : ; // -!- There is an error in the document if this branch is called + END; + END; + INC (Final); + UNTIL FALSE; + IF IsParamEntity THEN BEGIN + EntityDef2 := TEntityDef (ParEntities.Node (EntityDef.Name)); + IF EntityDef2 <> NIL THEN + ParEntities.Delete (ParEntities.IndexOf (EntityDef2)); + ParEntities.Add (EntityDef); + ReplaceCharacterEntities (EntityDef.Value); + END + ELSE BEGIN + EntityDef2 := TEntityDef (Entities.Node (EntityDef.Name)); + IF EntityDef2 <> NIL THEN + Entities.Delete (Entities.IndexOf (EntityDef2)); + Entities.Add (EntityDef); + ReplaceParameterEntities (EntityDef.Value); // Create replacement texts (see XmlSpec 4.5) + ReplaceCharacterEntities (EntityDef.Value); + END; + Final := StrScanE (Final, '>'); + + DER.ElementType := deEntity; + DER.EntityDef := EntityDef; + DER.Final := Final; + DtdElementFound (DER); +END; + + +PROCEDURE TXmlParser.AnalyzeNotationDecl (Start : TCharType; VAR Final : TCharType); + // Parse ' character + // XmlSpec 4.7: NotationDecl ::= '' +TYPE + TPhase = (phName, phExtId, phEnd); +VAR + ExternalID : TExternalID; + Phase : TPhase; + F : TCharType; + NotationDef : TNotationDef; + DER : TDtdElementRec; +BEGIN + Final := Start + 10; // Character after ', + #0 : BREAK; + ELSE CASE Phase OF + phName : BEGIN + ExtractName (Final, CWhitespace + ['>'], F); + SetStringSF (NotationDef.Name, Final, F); + Final := F; + Phase := phExtId; + END; + phExtId : BEGIN + ExternalID := TExternalID.Create (Final); + NotationDef.Value := ExternalID.SystemId; + NotationDef.PublicId := ExternalID.PublicId; + Final := ExternalId.Final; + ExternalId.Free; + Phase := phEnd; + END; + phEnd : ; // -!- There is an error in the document if this branch is called + END; + END; + INC (Final); + UNTIL FALSE; + Notations.Add (NotationDef); + Final := StrScanE (Final, '>'); + + DER.ElementType := deNotation; + DER.NotationDef := NotationDef; + DER.Final := Final; + DtdElementFound (DER); +END; + + +PROCEDURE TXmlParser.PushPE (VAR Start : TCharType); + (* If there is a parameter entity reference found in the data stream, + the current position will be pushed to the entity stack. + Start: IN Pointer to the '%' character starting the PE reference + OUT Pointer to first character of PE replacement text *) +VAR + P : TCharType; + EntityDef : TEntityDef; +BEGIN + P := StrScan (Start, ';'); + IF P <> NIL THEN BEGIN + EntityDef := TEntityDef (ParEntities.Node (StrSFPas (Start+1, P-1))); + IF EntityDef <> NIL THEN BEGIN + EntityStack.Push (P+1); + Start := TCharType (EntityDef.Value); + END + ELSE + Start := P+1; + END; +END; + + +PROCEDURE TXmlParser.ReplaceCharacterEntities (VAR Str : TStringType); + // Replaces all Character References in the String +VAR + Start : INTEGER; + PAmp : TCharType; + PSemi : TCharType; + PosAmp : INTEGER; + Len : INTEGER; // Length of complete Character Reference + Repl : TStringType; // Replacement Text +BEGIN + IF Str = '' THEN EXIT; + Start := 1; + REPEAT + PAmp := StrPos (TCharType (Str) + Start-1, '&#'); + IF PAmp = NIL THEN BREAK; + PSemi := StrScan (PAmp + 3, ';'); + IF PSemi = NIL THEN BREAK; + PosAmp := PAmp - TCharType (Str) + 1; + Len := PSemi - PAmp + 1; + IF (PAmp + 2)^ = 'x' + THEN Repl := TranslateCharacter (StrToIntDef ('$' + Copy (string (Str), PosAmp + 3, Len - 4), 32)) + ELSE Repl := TranslateCharacter (StrToIntDef ( Copy (string (Str), PosAmp + 2, Len - 3), 32)); + Delete (Str, PosAmp, Len); + Insert (Repl, Str, PosAmp); + Start := PosAmp + Length (Repl); + UNTIL FALSE; +END; + + +PROCEDURE TXmlParser.ReplaceParameterEntities (VAR Str : TStringType); + // Recursively replaces all Parameter Entity References in the String + PROCEDURE ReplaceEntities (VAR Str : TStringType); + VAR + Start : INTEGER; + PAmp : TCharType; + PSemi : TCharType; + PosAmp : INTEGER; + Len : INTEGER; + Entity : TEntityDef; + Repl : TStringType; // Replacement + BEGIN + IF Str = '' THEN EXIT; + Start := 1; + REPEAT + PAmp := StrPos (TCharType (Str)+Start-1, '%'); + IF PAmp = NIL THEN BREAK; + PSemi := StrScan (PAmp+2, ';'); + IF PSemi = NIL THEN BREAK; + PosAmp := PAmp - TCharType (Str) + 1; + Len := PSemi-PAmp+1; + Entity := TEntityDef (ParEntities.Node (Copy (Str, PosAmp+1, Len-2))); + IF Entity <> NIL THEN BEGIN + Repl := Entity.Value; + ReplaceEntities (Repl); // Recursion + END + ELSE + Repl := Copy (Str, PosAmp, Len); + Delete (Str, PosAmp, Len); + Insert (Repl, Str, PosAmp); + Start := PosAmp + Length (Repl); + UNTIL FALSE; + END; +BEGIN + ReplaceEntities (Str); +END; + + +FUNCTION TXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : TStringType) : TXmlParser; + // This will be called whenever there is a Parsed External Entity or + // the DTD External Subset has to be loaded. + // It must create a TXmlParser instance and load the desired Entity. + // This instance of LoadExternalEntity assumes that "SystemId" is a valid + // file name (relative to the Document source) and loads this file using + // the LoadFromFile method. +VAR + Filename : string; +BEGIN + // --- Convert System ID to complete filename + Filename := StringReplace (string (SystemId), '/', '\', [rfReplaceAll]); + IF Copy (FSource, 1, 1) <> '<' THEN + IF (Copy (Filename, 1, 2) = '\\') OR (Copy (Filename, 2, 1) = ':') THEN + // Already has an absolute Path + ELSE BEGIN + Filename := ExtractFilePath (FSource) + Filename; + END; + + // --- Load the File + Result := TXmlParser.Create; + Result.LoadFromFile (Filename); +END; + + +FUNCTION TXmlParser.TranslateEncoding (CONST Source : TStringType) : TStringType; + // The member variable "CurEncoding" always holds the name of the current + // encoding, e.g. 'UTF-8' or 'ISO-8859-1' (always uppercase). + // This virtual method "TranslateEncoding" is responsible for translating + // the content passed in the "Source" parameter to the target encoding which + // is expected by the application. + // This instance of "TranlateEncoding" assumes that the Application expects + // Windows ANSI (windows-1252) strings. It is able to transform UTF-8 or ISO-8859-1 + // encodings. + // Override this function when you want your application to understand other + // source encodings or create other target encodings. +BEGIN + Result := Source;//Utf8ToAnsi (Source) +END; + +FUNCTION TXmlParser.TranslateCharacter (CONST UnicodeValue : INTEGER; + CONST UnknownChar : TStringType = CUnknownChar) : TStringType; + // Corresponding to TranslateEncoding, the task of TranslateCharacter is + // to translate a given Character value to the representation in the target charset. + // This instance of TranslateCharacter assumes that the application expects + // Windows ANSI (windows-1252) strings. All unknown characters will be transformed + // to UnknownChar +var + I : integer; +begin + if (UnicodeValue <= 255) then begin + Result := TCharType(UnicodeValue); + exit; + end; + Result := CUnknownChar; +END; + + +procedure TXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec); + // This method is called for every element which is found in the DTD + // declaration. The variant record TDtdElementRec is passed which + // holds informations about the element. + // You can override this function to handle DTD declarations. + // Note that when you parse the same document instance a second time, + // the DTD will not get parsed again. +BEGIN +END; + + +FUNCTION TXmlParser.GetDocBuffer: TCharType; + // Returns FBuffer or a pointer to a NUL char if Buffer is empty +BEGIN + IF FBuffer = NIL + THEN Result := #0 + ELSE Result := FBuffer; +END; + + +(*$IFNDEF HAS_CONTNRS_UNIT +=============================================================================================== +TObjectList +=============================================================================================== +*) + +DESTRUCTOR TObjectList.Destroy; +BEGIN + Clear; + SetCapacity(0); + INHERITED Destroy; +END; + + +PROCEDURE TObjectList.Delete (Index : INTEGER); +BEGIN + IF (Index < 0) OR (Index >= Count) THEN EXIT; + TObject (Items [Index]).Free; + INHERITED Delete (Index); +END; + + +PROCEDURE TObjectList.Clear; +BEGIN + WHILE Count > 0 DO + Delete (Count-1); +END; + +(*$ENDIF *) + +(* +=============================================================================================== +TNvpNode +-------- +Node base class for the TNvpList +=============================================================================================== +*) + +CONSTRUCTOR TNvpNode.Create (TheName, TheValue : TStringType); +BEGIN + INHERITED Create; + Name := TheName; + Value := TheValue; +END; + + +(* +=============================================================================================== +TNvpList +-------- +A generic List of Name-Value Pairs, based on the TObjectList introduced in Delphi 5 +=============================================================================================== +*) + +PROCEDURE TNvpList.Add (Node : TNvpNode); +VAR + I : INTEGER; +BEGIN + FOR I := Count-1 DOWNTO 0 DO + IF Node.Name > TNvpNode (Items [I]).Name THEN BEGIN + Insert (I+1, Node); + EXIT; + END; + Insert (0, Node); +END; + + + +FUNCTION TNvpList.Node (Name : TStringType) : TNvpNode; + // Binary search for Node +VAR + L, H : INTEGER; // Low, High Limit + T, C : INTEGER; // Test Index, Comparison result + Last : INTEGER; // Last Test Index +BEGIN + IF Count=0 THEN BEGIN + Result := NIL; + EXIT; + END; + + L := 0; + H := Count; + Last := -1; + REPEAT + T := (L+H) DIV 2; + IF T=Last THEN BREAK; + Result := TNvpNode (Items [T]); + C := CompareStr (string (Result.Name), string (Name)); + IF C = 0 THEN EXIT + ELSE IF C < 0 THEN L := T + ELSE H := T; + Last := T; + UNTIL FALSE; + Result := NIL; +END; + + +FUNCTION TNvpList.Node (Index : INTEGER) : TNvpNode; +BEGIN + IF (Index < 0) OR (Index >= Count) + THEN Result := NIL + ELSE Result := TNvpNode (Items [Index]); +END; + + +FUNCTION TNvpList.Value (Name : TStringType) : TStringType; +VAR + Nvp : TNvpNode; +BEGIN + Nvp := TNvpNode (Node (Name)); + IF Nvp <> NIL + THEN Result := Nvp.Value + ELSE Result := ''; +END; + + +FUNCTION TNvpList.Value (Index : INTEGER) : TStringType; +BEGIN + IF (Index < 0) OR (Index >= Count) + THEN Result := '' + ELSE Result := TNvpNode (Items [Index]).Value; +END; + + +FUNCTION TNvpList.Name (Index : INTEGER) : TStringType; +BEGIN + IF (Index < 0) OR (Index >= Count) + THEN Result := '' + ELSE Result := TNvpNode (Items [Index]).Name; +END; + + +(* +=============================================================================================== +TAttrList +List of Attributes. The "Analyze" method extracts the Attributes from the given Buffer. +Is used for extraction of Attributes in Start-Tags, Empty-Element Tags and the "pseudo" +attributes in XML Prologs, Text Declarations and PIs. +=============================================================================================== +*) + +PROCEDURE TAttrList.Analyze (Start : TCharType; VAR Final : TCharType); + // Analyze the Buffer for Attribute=Name pairs. + // Terminates when there is a character which is not IN CNameStart + // (e.g. '?>' or '>' or '/>') +TYPE + TPhase = (phName, phEq, phValue); +VAR + Phase : TPhase; + F : TCharType; + Name : TStringType; + Value : TStringType; + Attr : TAttr; +BEGIN + Clear; + Phase := phName; + Final := Start; + REPEAT + IF (Final^ = #0) OR (Final^ = '>') THEN BREAK; + IF NOT (Final^ IN CWhitespace) THEN + CASE Phase OF + phName : BEGIN + IF NOT (Final^ IN CNameStart) THEN BREAK; + ExtractName (Final, CWhitespace + ['=', '/'], F); + SetStringSF (Name, Final, F); + Final := F; + Phase := phEq; + END; + phEq : BEGIN + IF Final^ = '=' THEN + Phase := phValue + END; + phValue : BEGIN + IF Final^ IN CQuoteChar THEN BEGIN + ExtractQuote (Final, Value, F); + Attr := TAttr.Create; + Attr.Name := Name; + Attr.Value := Value; + Attr.ValueType := vtNormal; + Add (Attr); + Final := F; + Phase := phName; + END; + END; + END; + INC (Final); + UNTIL FALSE; +END; + + +(* +=============================================================================================== +TElemList +List of TElemDef nodes. +=============================================================================================== +*) + +FUNCTION TElemList.Node (Name : TStringType) : TElemDef; + // Binary search for the Node with the given Name +VAR + L, H : INTEGER; // Low, High Limit + T, C : INTEGER; // Test Index, Comparison result + Last : INTEGER; // Last Test Index +BEGIN + IF Count=0 THEN BEGIN + Result := NIL; + EXIT; + END; + + L := 0; + H := Count; + Last := -1; + REPEAT + T := (L+H) DIV 2; + IF T=Last THEN BREAK; + Result := TElemDef (Items [T]); + C := CompareStr (string (Result.Name), string (Name)); + IF C = 0 THEN EXIT + ELSE IF C < 0 THEN L := T + ELSE H := T; + Last := T; + UNTIL FALSE; + Result := NIL; +END; + + +PROCEDURE TElemList.Add (Node : TElemDef); +VAR + I : INTEGER; +BEGIN + FOR I := Count-1 DOWNTO 0 DO + IF Node.Name > TElemDef (Items [I]).Name THEN BEGIN + Insert (I+1, Node); + EXIT; + END; + Insert (0, Node); +END; + + +(* +=============================================================================================== +TScannerXmlParser +A TXmlParser descendant for the TCustomXmlScanner component +=============================================================================================== +*) + +TYPE + TScannerXmlParser = CLASS (TXmlParser) + Scanner : TCustomXmlScanner; + CONSTRUCTOR Create (TheScanner : TCustomXmlScanner); + FUNCTION LoadExternalEntity (SystemId, PublicId, + Notation : TStringType) : TXmlParser; OVERRIDE; + FUNCTION TranslateEncoding (CONST Source : TStringType) : TStringType; OVERRIDE; + FUNCTION TranslateCharacter (CONST UnicodeValue : INTEGER; + CONST UnknownChar : TStringType = CUnknownChar) : TStringType; OVERRIDE; + PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); OVERRIDE; + END; + +CONSTRUCTOR TScannerXmlParser.Create (TheScanner : TCustomXmlScanner); +BEGIN + INHERITED Create; + Scanner := TheScanner; +END; + + +FUNCTION TScannerXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : TStringType) : TXmlParser; +BEGIN + IF Assigned (Scanner.FOnLoadExternal) + THEN Scanner.FOnLoadExternal (Scanner, string (SystemId), string (PublicId), string (Notation), Result) + ELSE Result := INHERITED LoadExternalEntity (SystemId, PublicId, Notation); +END; + + +FUNCTION TScannerXmlParser.TranslateEncoding (CONST Source : TStringType) : TStringType; +BEGIN + IF Assigned (Scanner.FOnTranslateEncoding) + THEN Result := TStringType (Scanner.FOnTranslateEncoding (Scanner, string (CurEncoding), string (Source))) + ELSE Result := TStringType (INHERITED TranslateEncoding (Source)); +END; + + +FUNCTION TScannerXmlParser.TranslateCharacter (CONST UnicodeValue : INTEGER; + CONST UnknownChar : TStringType = CUnknownChar) : TStringType; +BEGIN + IF Assigned (Scanner.FOnTranslateCharacter) + THEN Result := TStringType (Scanner.FOnTranslateCharacter (Scanner, UnicodeValue)) + ELSE Result := TStringType (INHERITED TranslateCharacter (UnicodeValue, UnknownChar)); +END; + + +PROCEDURE TScannerXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec); +BEGIN + WITH DtdElementRec DO + CASE ElementType OF + deElement : Scanner.WhenElement (ElemDef); + deAttList : Scanner.WhenAttList (ElemDef); + deEntity : Scanner.WhenEntity (EntityDef); + deNotation : Scanner.WhenNotation (NotationDef); + dePI : Scanner.WhenPI (string (Target), string (Content), AttrList); + deComment : Scanner.WhenComment (string (StrSFPas (Start, Final))); + deError : Scanner.WhenDtdError (Pos); + END; +END; + + +(* +=============================================================================================== +TCustomXmlScanner +=============================================================================================== +*) + +CONSTRUCTOR TCustomXmlScanner.Create (AOwner: TComponent); +BEGIN + INHERITED; + FXmlParser := TScannerXmlParser.Create (Self); +END; + + +DESTRUCTOR TCustomXmlScanner.Destroy; +BEGIN + FXmlParser.Free; + INHERITED; +END; + + +PROCEDURE TCustomXmlScanner.LoadFromFile (Filename : TFilename); + // Load XML Document from file +BEGIN + FXmlParser.LoadFromFile (Filename); +END; + + +PROCEDURE TCustomXmlScanner.LoadFromBuffer (Buffer : TCharType); + // Load XML Document from buffer +BEGIN + FXmlParser.LoadFromBuffer (Buffer); +END; + + +PROCEDURE TCustomXmlScanner.SetBuffer (Buffer : TCharType); + // Refer to Buffer +BEGIN + FXmlParser.SetBuffer (Buffer); +END; + + +FUNCTION TCustomXmlScanner.GetFilename : TFilename; +BEGIN + Result := FXmlParser.Source; +END; + + +FUNCTION TCustomXmlScanner.GetNormalize : BOOLEAN; +BEGIN + Result := FXmlParser.Normalize; +END; + + +PROCEDURE TCustomXmlScanner.SetNormalize (Value : BOOLEAN); +BEGIN + FXmlParser.Normalize := Value; +END; + + +PROCEDURE TCustomXmlScanner.WhenXmlProlog(XmlVersion, Encoding: String; Standalone : BOOLEAN); + // Is called when the parser has parsed the declaration of the prolog +BEGIN + IF Assigned (FOnXmlProlog) THEN FOnXmlProlog (Self, XmlVersion, Encoding, Standalone); +END; + + +PROCEDURE TCustomXmlScanner.WhenComment (Comment : String); + // Is called when the parser has parsed a +BEGIN + IF Assigned (FOnComment) THEN FOnComment (Self, Comment); +END; + + +PROCEDURE TCustomXmlScanner.WhenPI (Target, Content: String; Attributes : TAttrList); + // Is called when the parser has parsed a +BEGIN + IF Assigned (FOnPI) THEN FOnPI (Self, Target, Content, Attributes); +END; + + +PROCEDURE TCustomXmlScanner.WhenDtdRead (RootElementName : String); + // Is called when the parser has completely parsed the DTD +BEGIN + IF Assigned (FOnDtdRead) THEN FOnDtdRead (Self, RootElementName); +END; + + +PROCEDURE TCustomXmlScanner.WhenStartTag (TagName : String; Attributes : TAttrList); + // Is called when the parser has parsed a start tag like

+BEGIN + IF Assigned (FOnStartTag) THEN FOnStartTag (Self, TagName, Attributes); +END; + + +PROCEDURE TCustomXmlScanner.WhenEmptyTag (TagName : String; Attributes : TAttrList); + // Is called when the parser has parsed an Empty Element Tag like
+BEGIN + IF Assigned (FOnEmptyTag) THEN FOnEmptyTag (Self, TagName, Attributes); +END; + + +PROCEDURE TCustomXmlScanner.WhenEndTag (TagName : String); + // Is called when the parser has parsed an End Tag like

+BEGIN + IF Assigned (FOnEndTag) THEN FOnEndTag (Self, TagName); +END; + + +PROCEDURE TCustomXmlScanner.WhenContent (Content : String); + // Is called when the parser has parsed an element's text content +BEGIN + IF Assigned (FOnContent) THEN FOnContent (Self, Content); +END; + + +PROCEDURE TCustomXmlScanner.WhenCData (Content : String); + // Is called when the parser has parsed a CDATA section +BEGIN + IF Assigned (FOnCData) THEN FOnCData (Self, Content); +END; + + +PROCEDURE TCustomXmlScanner.WhenElement (ElemDef : TElemDef); + // Is called when the parser has parsed an definition + // inside the DTD +BEGIN + IF Assigned (FOnElement) THEN FOnElement (Self, ElemDef); +END; + + +PROCEDURE TCustomXmlScanner.WhenAttList (ElemDef : TElemDef); + // Is called when the parser has parsed an definition + // inside the DTD +BEGIN + IF Assigned (FOnAttList) THEN FOnAttList (Self, ElemDef); +END; + + +PROCEDURE TCustomXmlScanner.WhenEntity (EntityDef : TEntityDef); + // Is called when the parser has parsed an definition + // inside the DTD +BEGIN + IF Assigned (FOnEntity) THEN FOnEntity (Self, EntityDef); +END; + + +PROCEDURE TCustomXmlScanner.WhenNotation (NotationDef : TNotationDef); + // Is called when the parser has parsed a definition + // inside the DTD +BEGIN + IF Assigned (FOnNotation) THEN FOnNotation (Self, NotationDef); +END; + + +PROCEDURE TCustomXmlScanner.WhenDtdError (ErrorPos : TCharType); + // Is called when the parser has found an Error in the DTD +BEGIN + IF Assigned (FOnDtdError) THEN FOnDtdError (Self, ErrorPos); +END; + + +PROCEDURE TCustomXmlScanner.Execute; + // Perform scanning + // Scanning is done synchronously, i.e. you can expect events to be triggered + // in the order of the XML data stream. Execute will finish when the whole XML + // document has been scanned or when the StopParser property has been set to TRUE. +BEGIN + FStopParser := FALSE; + FXmlParser.StartScan; + WHILE FXmlParser.Scan AND (NOT FStopParser) DO + CASE FXmlParser.CurPartType OF + ptNone : ; + ptXmlProlog : WhenXmlProlog (string (FXmlParser.XmlVersion), string (FXmlParser.Encoding), FXmlParser.Standalone); + ptComment : WhenComment (string (StrSFPas (FXmlParser.CurStart, FXmlParser.CurFinal))); + ptPI : WhenPI (string (FXmlParser.CurName), string (FXmlParser.CurContent), FXmlParser.CurAttr); + ptDtdc : WhenDtdRead (string (FXmlParser.RootName)); + ptStartTag : WhenStartTag (string (FXmlParser.CurName), FXmlParser.CurAttr); + ptEmptyTag : WhenEmptyTag (string (FXmlParser.CurName), FXmlParser.CurAttr); + ptEndTag : WhenEndTag (string (FXmlParser.CurName)); + ptContent : WhenContent (string (FXmlParser.CurContent)); + ptCData : WhenCData (string (FXmlParser.CurContent)); + END; +END; + + +END. diff --git a/System/NativeXml.inc b/System/NativeXml.inc new file mode 100644 index 0000000..9d72f92 --- /dev/null +++ b/System/NativeXml.inc @@ -0,0 +1,71 @@ +{ unit NativeXml.inc + + Nativexml a small-footprint implementation to read and write XML documents + natively from Delpi code. NativeXml has very fast parsing speeds. + + Author: Nils Haeck M.Sc. + Copyright (c) 2007 - 2010 Simdesign B.V. + + It is NOT allowed under ANY circumstances to publish, alter or copy this code + without accepting the license conditions in accompanying LICENSE.txt + first! + + This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF + ANY KIND, either express or implied. + + Please visit http://www.simdesign.nl/xml.html for more information. +} +// Delphi and BCB versions + +// Freepascal (MK) +{$ifdef FPC} + {$MODE DELPHI} + {$define D7UP} +{$endif FPC} +//Delphi 7 +{$ifdef VER150} + {$define D7UP} +{$endif} +//Delphi 8 +{$ifdef VER160} + {$define D7UP} +{$endif} +// Delphi 2005 +{$ifdef VER170} + {$define D7UP} +{$endif} +// Delphi 2006 +{$ifdef VER180} + {$define D7UP} +{$endif} +// Delphi 2007 - NET +{$ifdef VER190} + {$define D7UP} +{$endif} +// Delphi 2009 +{$ifdef VER200} + {$define D7UP} + {$define D12UP} +{$endif} +// Delphi 2010 +{$ifdef VER210} + {$define D7UP} + {$define D12UP} +{$endif} +// Delphi XE +{$ifdef VER220} + {$define D7UP} + {$define D12UP} + {$define D15UP} +{$endif} + +// Uncomment to save memory space for large documents if you don't need tags. +// Tags are an additional integer field that can be used by the application. +{$define USETAGS} + +// uncomment if you do not want to include the Graphics unit. +{$define USEGRAPHICS} + +// uncomment if you do not want line number/position info from the source file +{$define SOURCEPOS} + diff --git a/System/NativeXml.pas b/System/NativeXml.pas new file mode 100644 index 0000000..3ab013b --- /dev/null +++ b/System/NativeXml.pas @@ -0,0 +1,6372 @@ +{ unit NativeXml + + This is a small-footprint implementation to read and write XML documents + natively from Delpi code. + + You can use this code to read XML documents from files, streams or strings. + The load routine generates events that can be used to display load progress + on the fly. + + Note: any external encoding (ANSI, UTF16, etc) is converted to an internal + encoding that is ANSI or UTF8. When the loaded document is ANSI based, + the encoding will be ANSI, in other cases (UTF8, UTF16) the encoding + will be UTF8. + + Original Author: Nils Haeck M.Sc. (n.haeck@simdesign.nl) + Original Date: 01 Apr 2003 + Version: see below + Copyright (c) 2003-2010 Simdesign BV + Contributor(s): Stefan Glienke + + It is NOT allowed under ANY circumstances to publish or copy this code + without accepting the license conditions in accompanying LICENSE.txt + first! + + This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF + ANY KIND, either express or implied. + + Please visit http://www.simdesign.nl/xml.html for more information. +} +unit NativeXml; + +interface + +{$i nativexml.inc} + +uses + Windows, + {$IFDEF CLR} + System.Text, + {$ENDIF} + {$IFDEF USEGRAPHICS} + {$IFDEF LINUX} + QGraphics, + {$ELSE} + Graphics, + {$ENDIF} + {$ENDIF} + Classes, + SysUtils; + +const + + // Current version of the NativeXml unit + cNativeXmlVersion = '3.10'; + +// cross-platform pointer type +type + {$IFDEF CLR} + TPointer = TObject; + {$ELSE} + TPointer = Pointer; + {$ENDIF} + +{$IFDEF D12UP} +// Delphi 2009 and up +type + UnicodeChar = Char; + PUnicodeChar = PChar; +{$ELSE} +// Delphi 2007 and below +type + UnicodeString = WideString; + UnicodeChar = WideChar; + PUnicodeChar = PWideChar; + RawByteString = AnsiString; +{$ENDIF} + +type + + // Note on TNativeXml.Format: + // - xfReadable (default) to be able to read the xml file with a standard editor. + // - xfCompact to save the xml fully compliant and at smallest size + TXmlFormatType = ( + xfReadable, // Save in readable format with CR-LF and indents + xfCompact // Save without any control chars except LF after declarations + ); + + // TXmlElementType enumerates the different kinds of elements that can be found + // in the XML document. + TXmlElementType = ( + xeNormal, // Normal element [value][sub-elements] + xeComment, // Comment + xeCData, // literal data + xeDeclaration, // XML declaration + xeStylesheet, // Stylesheet + xeDoctype, // DOCTYPE DTD declaration + xeElement, // + xeAttList, // + xeEntity, // + xeNotation, // + xeExclam, // Any + xeQuestion, // Any + xeCharData, // character data in a node + xeUnknown // Any + ); + + // Choose what kind of binary encoding will be used when calling + // TXmlNode BufferRead and BufferWrite. + TBinaryEncodingType = ( + xbeBinHex, { With this encoding, each byte is stored as a hexadecimal + number, e.g. 0 = 00 and 255 = FF. } + xbeBase64 { With this encoding, each group of 3 bytes are stored as 4 + characters, requiring 64 different AnsiCharacters.} + ); + + // Definition of different methods of String encoding. + TStringEncodingType = ( + seAnsi, // General 8 bit encoding, encoding must be determined from encoding declaration + seUCS4BE, // UCS-4 Big Endian + seUCS4LE, // UCS-4 Little Endian + seUCS4_2143, // UCS-4 unusual octet order (2143) + seUCS4_3412, // UCS-4 unusual octet order (3412) + se16BitBE, // General 16 bit Big Endian, encoding must be determined from encoding declaration + se16BitLE, // General 16 bit Little Endian, encoding must be determined from encoding declaration + seUTF8, // UTF-8 + seUTF16BE, // UTF-16 Big Endian + seUTF16LE, // UTF-16 Little Endian + seEBCDIC // EBCDIC flavour + ); + + TXmlCompareOption = ( + xcNodeName, + xcNodeType, + xcNodeValue, + xcAttribCount, + xcAttribNames, + xcAttribValues, + xcChildCount, + xcChildNames, + xcChildValues, + xcRecursive + ); + + TXmlCompareOptions = set of TXmlCompareOption; + +const + + xcAll: TXmlCompareOptions = [xcNodeName, xcNodeType, xcNodeValue, xcAttribCount, + xcAttribNames, xcAttribValues, xcChildCount, xcChildNames, xcChildValues, + xcRecursive]; + +var + + // XML Defaults + + cDefaultEncodingString: UTF8String = 'UTF-8'; + cDefaultExternalEncoding: TStringEncodingType = seUTF8; + cDefaultVersionString: UTF8String = '1.0'; + cDefaultXmlFormat: TXmlFormatType = xfCompact; + cDefaultWriteOnDefault: boolean = True; + cDefaultBinaryEncoding: TBinaryEncodingType = xbeBase64; + cDefaultIndentString: UTF8String = ' '; + cDefaultDropCommentsOnParse: boolean = False; + cDefaultUseFullNodes: boolean = False; + cDefaultUseLocalBias: boolean = False; + cDefaultFloatAllowScientific: boolean = True; + cDefaultFloatSignificantDigits: integer = 6; + +type + + TXmlNode = class; + TNativeXml = class; + TsdCodecStream = class; + + // An event that is based on the TXmlNode object Node. + TXmlNodeEvent = procedure(Sender: TObject; Node: TXmlNode) of object; + + // An event that is used to indicate load or save progress. + TXmlProgressEvent = procedure(Sender: TObject; Size: integer) of object; + + // This event is used in the TNativeXml.OnNodeCompare event, and should + // return -1 if Node1 < Node2, 0 if Node1 = Node2 and 1 if Node1 > Node2. + TXmlNodeCompareEvent = function(Sender: TObject; Node1, Node2: TXmlNode; Info: TPointer): integer of object; + + // Pass a function of this kind to TXmlNode.SortChildNodes. The function should + // return -1 if Node1 < Node2, 0 if Node1 = Node2 and 1 if Node1 > Node2. + TXMLNodeCompareFunction = function(Node1, Node2: TXmlNode; Info: TPointer): integer; + + // Very simple autonomous stringlist that holds the list of attributes in the node + TsdUTF8StringList = class(TPersistent) + private + FItems: array of UTF8String; + FCount: integer; + function GetItems(Index: integer): UTF8String; + procedure SetItems(Index: integer; const Value: UTF8String); + function GetValues(const Name: UTF8String): UTF8String; + function GetNames(Index: integer): UTF8String; + procedure SetValues(const Name, Value: UTF8String); + function GetText: UTF8String; + public + function Add(const S: UTF8String): integer; + procedure Assign(Source: TPersistent); override; + procedure Clear; + procedure Delete(Index: Integer); + function IndexOfName(const Name: UTF8String): integer; + property Count: integer read FCount; + property Items[Index: integer]: UTF8String read GetItems write SetItems; default; + property Names[Index: integer]: UTF8String read GetNames; + property Values[const Name: UTF8String]: UTF8String read GetValues write SetValues; + property Text: UTF8String read GetText; + end; + + // The TXmlNode represents an element in the XML file. Each TNativeXml holds + // one Root element. Under ths root element, sub-elements can be nested (there + // is no limit on how deep). Property ElementType defines what kind of element + // this node is. + TXmlNode = class(TPersistent) + private + FName: UTF8String; // The element name + FValue: UTF8String; // The *escaped* value + FAttributes: TsdUTF8StringList; // List with attributes + FNodes: TList; // These are the child elements + FParent: TXmlNode; // Pointer to parent element + FDocument: TNativeXml; // Pointer to parent XmlDocument + FElementType: TXmlElementType; // The type of element + FTag: integer; // A value the developer can use + function AbortParsing: boolean; + function GetValueAsString: UTF8String; + procedure SetAttributeName(Index: integer; const Value: UTF8String); + procedure SetAttributeValue(Index: integer; const Value: UTF8String); + procedure SetValueAsString(const AValue: UTF8String); + function GetIndent: UTF8String; + function GetLineFeed: UTF8String; + function GetTreeDepth: integer; + function GetAttributeCount: integer; + function GetAttributePair(Index: integer): UTF8String; + function GetAttributeName(Index: integer): UTF8String; + function GetAttributeValue(Index: integer): UTF8String; + function GetWriteOnDefault: boolean; + function GetBinaryEncoding: TBinaryEncodingType; + function GetCascadedName: UTF8String; + function QualifyAsDirectNode: boolean; + procedure SetName(const Value: UTF8String); + function GetFullPath: UTF8String; + procedure SetBinaryEncoding(const Value: TBinaryEncodingType); + function GetBinaryString: RawByteString; + procedure SetBinaryString(const Value: RawByteString); + function UseFullNodes: boolean; + function UseLocalBias: Boolean; + function GetValueAsUnicodeString: UnicodeString; + procedure SetValueAsUnicodeString(const Value: UnicodeString); + function GetAttributeByName(const AName: UTF8String): UTF8String; + procedure SetAttributeByName(const AName, Value: UTF8String); + function GetValueAsInteger: integer; + procedure SetValueAsInteger(const Value: integer); + function GetValueAsFloat: double; + procedure SetValueAsFloat(const Value: double); + function GetValueAsDateTime: TDateTime; + procedure SetValueAsDateTime(const Value: TDateTime); + function GetValueAsBool: boolean; + procedure SetValueAsBool(const Value: boolean); + function GetValueAsInt64: int64; + procedure SetValueAsInt64(const Value: int64); + procedure CheckCreateAttributesList; + function GetAttributeValueAsUnicodeString(Index: integer): UnicodeString; + procedure SetAttributeValueAsUnicodeString(Index: integer; + const Value: UnicodeString); + function GetAttributeValueAsInteger(Index: integer): integer; + procedure SetAttributeValueAsInteger(Index: integer; + const Value: integer); + function GetAttributeByNameWide(const AName: UTF8String): UnicodeString; + procedure SetAttributeByNameWide(const AName: UTF8String; + const Value: UnicodeString); + function GetTotalNodeCount: integer; + function FloatSignificantDigits: integer; + function FloatAllowScientific: boolean; + function GetAttributeValueDirect(Index: integer): UTF8String; + procedure SetAttributeValueDirect(Index: integer; const Value: UTF8String); + protected + function CompareNodeName(const NodeName: UTF8String): integer; + procedure DeleteEmptyAttributes; + function GetNodes(Index: integer): TXmlNode; virtual; + function GetNodeCount: integer; virtual; + procedure ParseTag(const AValue: UTF8String; TagStart, TagClose: integer); + procedure ReadFromStream(S: TStream); virtual; + procedure ReadFromString(const AValue: UTF8String); virtual; + procedure ResolveEntityReferences; + function UnescapeString(const AValue: UTF8String): UTF8String; virtual; + function WriteInnerTag: UTF8String; virtual; + procedure WriteToStream(S: TStream); virtual; + procedure ChangeDocument(ADocument: TNativeXml); + public + // Create a new TXmlNode object. ADocument must be the TNativeXml that is + // going to hold this new node. + constructor Create(ADocument: TNativeXml); virtual; + // \Create a new TXmlNode with name AName. ADocument must be the TNativeXml + // that is going to hold this new node. + constructor CreateName(ADocument: TNativeXml; const AName: UTF8String); virtual; + // \Create a new TXmlNode with name AName and UTF8String value AValue. ADocument + // must be the TNativeXml that is going to hold this new node. + constructor CreateNameValue(ADocument: TNativeXml; const AName, AValue: UTF8String); virtual; + // \Create a new TXmlNode with XML element type AType. ADocument must be the + // TNativeXml that is going to hold this new node. + constructor CreateType(ADocument: TNativeXml; AType: TXmlElementType); virtual; + // Use Assign to assign another TXmlNode to this node. This means that all + // properties and subnodes from the Source TXmlNode are copied to the current + // node. You can also Assign a TNativeXml document to the node, in that case + // the RootNodeList property of the TNativeXml object will be copied. + procedure Assign(Source: TPersistent); override; + // Call Delete to delete this node completely from the parent node list. This + // call only succeeds if the node has a parent. It has no effect when called for + // the root node. + procedure Delete; virtual; + // \Delete all nodes that are empty (this means, which have no subnodes, no + // attributes, and no value assigned). This procedure works recursively. + procedure DeleteEmptyNodes; + // Destroy a TXmlNode object. This will free the child node list automatically. + // Never call this method directly. All TXmlNodes in the document will be + // recursively freed when TNativeXml.Free is called. + destructor Destroy; override; + // Use this method to add an integer attribute to the node. + procedure AttributeAdd(const AName: UTF8String; AValue: integer); overload; + // Use this method to add a string attribute with value AValue to the node. + procedure AttributeAdd(const AName, AValue: UTF8String); overload; + // Use this method to delete the attribute at Index in the list. Index must be + // equal or greater than 0, and smaller than AttributeCount. Using an index + // outside of that range has no effect. + procedure AttributeDelete(Index: integer); + // Switch position of the attributes at Index1 and Index2. + procedure AttributeExchange(Index1, Index2: integer); + // Use this method to find the index of an attribute with name AName. + function AttributeIndexByname(const AName: UTF8String): integer; + // \Clear all attributes from the current node. + procedure AttributesClear; virtual; + // Use this method to read binary data from the node into Buffer with a length of Count. + procedure BufferRead(var Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Count: Integer); virtual; + // Use this method to write binary data in Buffer with a length of Count to the + // current node. The data will appear as text using either BinHex or Base64 + // method) in the final XML document. + // Notice that NativeXml does only support up to 2Gb bytes of data per file, + // so do not use this option for huge files. The binary encoding method (converting + // binary data into text) can be selected using property BinaryEncoding. + // xbeBase64 is most efficient, but slightly slower. Always use identical methods + // for reading and writing. + procedure BufferWrite(const Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Count: Integer); virtual; + // Returns the length of the data in the buffer, once it would be decoded by + // method xbeBinHex or xbeBase64. If BinaryEncoding is xbeSixBits, this function + // cannot be used. The length of the unencoded data is determined from the + // length of the encoded data. For xbeBinHex this is trivial (just half the + // length), for xbeBase64 this is more difficult (must use the padding characters) + function BufferLength: integer; virtual; + // Clear all child nodes and attributes, and the name and value of the current + // XML node. However, the node is not deleted. Call Delete instead for that. + procedure Clear; virtual; + // Find the first node which has name NodeName. Contrary to the NodeByName + // function, this function will search the whole subnode tree, using the + // DepthFirst method. It is possible to search for a full path too, e.g. + // FoundNode := MyNode.FindNode('/Root/SubNode1/SubNode2/ThisNode'); + function FindNode(const NodeName: UTF8String): TXmlNode; + // Find all nodes which have name NodeName. Contrary to the NodesByName + // function, this function will search the whole subnode tree. If you use + // a TXmlNodeList for the AList parameter, you don't need to cast the list + // items to TXmlNode. + procedure FindNodes(const NodeName: UTF8String; const AList: TList); + // Use FromAnsiString to convert a normal ANSI String to a UTF8String for the node + // (name, value, attributes). In TNativeXml the ANSI Characters are encoded + // into UTF8. + function FromAnsiString(const s: AnsiString): UTF8String; + // Use FromUnicodeString to convert UnicodeString to a UTF8String for the node (name, value, + // attributes). + function FromUnicodeString(const W: UnicodeString): UTF8String; + // Use HasAttribute to determine if the node has an attribute with name AName. + function HasAttribute(const AName: UTF8String): boolean; virtual; + // This function returns the index of this node in the parent's node list. + // If Parent is not assigned, this function returns -1. + function IndexInParent: integer; + // This function returns True if the node has no subnodes and no attributes, + // and if the node Name and value are empty. + function IsClear: boolean; virtual; + // This function returns True if the node has no subnodes and no attributes, + // and if the node value is empty. + function IsEmpty: boolean; virtual; + function IsEqualTo(ANode: TXmlNode; Options: TXmlCompareOptions; MismatchNodes: TList = nil): boolean; + // Add the node ANode as a new subelement in the nodelist. The node will be + // added in position NodeCount (which will be returned). + function NodeAdd(ANode: TXmlNode): integer; virtual; + // This function returns a pointer to the first subnode that has an attribute with + // name AttribName and value AttribValue. If ShouldRecurse = True (default), the + // function works recursively, using the depthfirst method. + function NodeByAttributeValue(const NodeName, AttribName, AttribValue: UTF8String; + ShouldRecurse: boolean = True): TXmlNode; + // Return a pointer to the first subnode with this Elementype, or return nil + // if no subnode with that type is found. + function NodeByElementType(ElementType: TXmlElementType): TXmlNode; + // Return a pointer to the first subnode in the nodelist that has name AName. + // If no subnodes with AName are found, the function returns nil. + function NodeByName(const AName: UTF8String): TXmlNode; virtual; + // \Delete the subnode at Index. The node will also be freed, so do not free the + // node in the application. + procedure NodeDelete(Index: integer); virtual; + // Switch position of the nodes at Index1 and Index2. + procedure NodeExchange(Index1, Index2: integer); + // Extract the node ANode from the subnode list. The node will no longer appear + // in the subnodes list, so the application is responsible for freeing ANode later. + function NodeExtract(ANode: TXmlNode): TXmlNode; virtual; + // This function returns a pointer to the first node with AName. If this node + // is not found, then it creates a new node with AName and returns its pointer. + function NodeFindOrCreate(const AName: UTF8String): TXmlNode; virtual; + // Find the index of the first subnode with name AName. + function NodeIndexByName(const AName: UTF8String): integer; virtual; + // Find the index of the first subnode with name AName that appears after or on + // the index AFrom. This function can be used in a loop to retrieve all nodes + // with a certain name, without using a helper list. See also NodesByName. + function NodeIndexByNameFrom(const AName: UTF8String; AFrom: integer): integer; virtual; + // Call NodeIndexOf to get the index for ANode in the Nodes array. The first + // node in the array has index 0, the second item has index 1, and so on. If + // a node is not in the list, NodeIndexOf returns -1. + function NodeIndexOf(ANode: TXmlNode): integer; + // Insert the node ANode at location Index in the list. + procedure NodeInsert(Index: integer; ANode: TXmlNode); virtual; + // \Create a new node with AName, add it to the subnode list, and return a + // pointer to it. + function NodeNew(const AName: UTF8String): TXmlNode; virtual; + // \Create a new node with AName, and insert it into the subnode list at location + // Index, and return a pointer to it. + function NodeNewAtIndex(Index: integer; const AName: UTF8String): TXmlNode; virtual; + // Call NodeRemove to remove a specific node from the Nodes array when its index + // is unknown. The value returned is the index of the item in the Nodes array + // before it was removed. After an item is removed, all the items that follow + // it are moved up in index position and the NodeCount is reduced by one. + function NodeRemove(ANode: TxmlNode): integer; + // \Clear (and free) the complete list of subnodes. + procedure NodesClear; virtual; + // Use this procedure to retrieve all nodes that have name AName. Pointers to + // these nodes are added to the list in AList. AList must be initialized + // before calling this procedure. If you use a TXmlNodeList you don't need + // to cast the list items to TXmlNode. + procedure NodesByName(const AName: UTF8String; const AList: TList); + // Find the attribute with AName, and convert its value to a boolean. If the + // attribute is not found, or cannot be converted, the default ADefault will + // be returned. + function ReadAttributeBool(const AName: UTF8String; ADefault: boolean = False): boolean; virtual; + function ReadAttributeDateTime(const AName: UTF8String; ADefault: TDateTime = 0): TDateTime; virtual; + // Find the attribute with AName, and convert its value to an integer. If the + // attribute is not found, or cannot be converted, the default ADefault will + // be returned. + function ReadAttributeInteger(const AName: UTF8String; ADefault: integer = 0): integer; virtual; + // Find the attribute with AName, and convert its value to an int64. If the + // attribute is not found, or cannot be converted, the default ADefault will + // be returned. + function ReadAttributeInt64(const AName: UTF8String; ADefault: int64 = 0): int64; virtual; + // Find the attribute with AName, and convert its value to a float. If the + // attribute is not found, or cannot be converted, the default ADefault will + // be returned. + function ReadAttributeFloat(const AName: UTF8String; ADefault: double = 0): double; + function ReadAttributeString(const AName: UTF8String; const ADefault: UTF8String = ''): UTF8String; virtual; + // Read the subnode with AName and convert it to a boolean value. If the + // subnode is not found, or cannot be converted, the boolean ADefault will + // be returned. + function ReadBool(const AName: UTF8String; ADefault: boolean = False): boolean; virtual; + {$IFDEF USEGRAPHICS} + // Read the properties Color and Style for the TBrush object ABrush from the + // subnode with AName. + procedure ReadBrush(const AName: UTF8String; ABrush: TBrush); virtual; + // Read the subnode with AName and convert its value to TColor. If the + // subnode is not found, or cannot be converted, ADefault will be returned. + function ReadColor(const AName: UTF8String; ADefault: TColor = clBlack): TColor; virtual; + // Read the properties \Name, Color, Size and Style for the TFont object AFont + // from the subnode with AName. + procedure ReadFont(const AName: UTF8String; AFont: TFont); virtual; + // Read the properties Color, Mode, Style and Width for the TPen object APen + // from the subnode with AName. + procedure ReadPen(const AName: UTF8String; APen: TPen); virtual; + {$ENDIF} + // Read the subnode with AName and convert its value to TDateTime. If the + // subnode is not found, or cannot be converted, ADefault will be returned. + function ReadDateTime(const AName: UTF8String; ADefault: TDateTime = 0): TDateTime; virtual; + // Read the subnode with AName and convert its value to a double. If the + // subnode is not found, or cannot be converted, ADefault will be returned. + function ReadFloat(const AName: UTF8String; ADefault: double = 0.0): double; virtual; + // Read the subnode with AName and convert its value to an int64. If the + // subnode is not found, or cannot be converted, ADefault will be returned. + function ReadInt64(const AName: UTF8String; ADefault: int64 = 0): int64; virtual; + // Read the subnode with AName and convert its value to an integer. If the + // subnode is not found, or cannot be converted, ADefault will be returned. + function ReadInteger(const AName: UTF8String; ADefault: integer = 0): integer; virtual; + // Read the subnode with AName and return its UTF8String value. If the subnode is + // not found, ADefault will be returned. + function ReadString(const AName: UTF8String; const ADefault: UTF8String = ''): UTF8String; virtual; + // Read the subnode with AName and return its UnicodeString value. If the subnode is + // not found, ADefault will be returned. + function ReadUnicodeString(const AName: UTF8String; const ADefault: UnicodeString = ''): UnicodeString; virtual; + // Sort the child nodes of this node. Provide a custom node compare function in Compare, + // or attach an event handler to the parent documents' OnNodeCompare in order to + // provide custom sorting. If no compare function is given (nil) and OnNodeCompare + // is not implemented, SortChildNodes will simply sort the nodes by name (ascending, + // case insensitive). The Info pointer parameter can be used to pass any custom + // information to the compare function. Default value for Info is nil. + procedure SortChildNodes(Compare: TXMLNodeCompareFunction = nil; Info: TPointer = nil); + // Use ToUnicodeString to convert any UTF8 String from the node (name, value, attributes) + // to a UnicodeString. + function ToUnicodeString(const s: UTF8String): UnicodeString; + // Convert the node's value to boolean and return the result. If this conversion + // fails, or no value is found, then the function returns ADefault. + function ValueAsBoolDef(ADefault: boolean): boolean; virtual; + // Convert the node's value to a TDateTime and return the result. If this conversion + // fails, or no value is found, then the function returns ADefault. + function ValueAsDateTimeDef(ADefault: TDateTime): TDateTime; virtual; + // Convert the node's value to a double and return the result. If this conversion + // fails, or no value is found, then the function returns ADefault. + function ValueAsFloatDef(ADefault: double): double; virtual; + // Convert the node's value to int64 and return the result. If this conversion + // fails, or no value is found, then the function returns ADefault. + function ValueAsInt64Def(ADefault: int64): int64; virtual; + // Convert the node's value to integer and return the result. If this conversion + // fails, or no value is found, then the function returns ADefault. + function ValueAsIntegerDef(ADefault: integer): integer; virtual; + // If the attribute with name AName exists, then set its value to the boolean + // AValue. If it does not exist, then create a new attribute AName with the + // boolean value converted to either "True" or "False". If ADefault = AValue, and + // WriteOnDefault = False, no attribute will be added. + procedure WriteAttributeBool(const AName: UTF8String; AValue: boolean; ADefault: boolean = False); virtual; + procedure WriteAttributeDateTime(const AName: UTF8string; AValue: TDateTime; ADefault: TDateTime = 0); virtual; + // If the attribute with name AName exists, then set its value to the integer + // AValue. If it does not exist, then create a new attribute AName with the + // integer value converted to a quoted string. If ADefault = AValue, and + // WriteOnDefault = False, no attribute will be added. + procedure WriteAttributeInteger(const AName: UTF8String; AValue: integer; ADefault: integer = 0); virtual; + procedure WriteAttributeInt64(const AName: UTF8String; const AValue: int64; ADefault: int64 = 0); virtual; + procedure WriteAttributeFloat(const AName: UTF8String; AValue: double; ADefault: double = 0); virtual; + // If the attribute with name AName exists, then set its value to the UTF8String + // AValue. If it does not exist, then create a new attribute AName with the + // value AValue. If ADefault = AValue, and WriteOnDefault = False, no attribute + // will be added. + procedure WriteAttributeString(const AName: UTF8String; const AValue: UTF8String; const ADefault: UTF8String = ''); virtual; + // Add or replace the subnode with AName and set its value to represent the boolean + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteBool(const AName: UTF8String; AValue: boolean; ADefault: boolean = False); virtual; + {$IFDEF USEGRAPHICS} + // Write properties Color and Style of the TBrush object ABrush to the subnode + // with AName. If AName does not exist, it will be created. + procedure WriteBrush(const AName: UTF8String; ABrush: TBrush); virtual; + // Add or replace the subnode with AName and set its value to represent the TColor + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteColor(const AName: UTF8String; AValue: TColor; ADefault: TColor = clBlack); virtual; + // Write properties \Name, Color, Size and Style of the TFont object AFont to + // the subnode with AName. If AName does not exist, it will be created. + procedure WriteFont(const AName: UTF8String; AFont: TFont); virtual; + // Write properties Color, Mode, Style and Width of the TPen object APen to + // the subnode with AName. If AName does not exist, it will be created. + procedure WritePen(const AName: UTF8String; APen: TPen); virtual; + {$ENDIF} + // Add or replace the subnode with AName and set its value to represent the TDateTime + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + // The XML format used is compliant with W3C's specification of date and time. + procedure WriteDateTime(const AName: UTF8String; AValue: TDateTime; ADefault: TDateTime = 0); virtual; + // Add or replace the subnode with AName and set its value to represent the double + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteFloat(const AName: UTF8String; AValue: double; ADefault: double = 0.0); virtual; + // Add or replace the subnode with AName and set its value to represent the hexadecimal representation of + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteHex(const AName: UTF8String; AValue: integer; Digits: integer; ADefault: integer = 0); virtual; + // Add or replace the subnode with AName and set its value to represent the int64 + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteInt64(const AName: UTF8String; AValue: int64; ADefault: int64 = 0); virtual; + // Add or replace the subnode with AName and set its value to represent the integer + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteInteger(const AName: UTF8String; AValue: integer; ADefault: integer = 0); virtual; + // Add or replace the subnode with AName and set its value to represent the UTF8String + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteString(const AName, AValue: UTF8String; const ADefault: UTF8String = ''); virtual; + // Call WriteToString to save the XML node to a UTF8String. This method can be used to store + // individual nodes instead of the complete XML document. + function WriteToString: UTF8String; virtual; + // Add or replace the subnode with AName and set its value to represent the UnicodeString + // AValue. If AValue = ADefault, and WriteOnDefault = False, no subnode will be added. + procedure WriteUnicodeString(const AName: UTF8String; const AValue: UnicodeString; const ADefault: UnicodeString = ''); virtual; + // AttributeByName returns the attribute value for the attribute that has name AName. + // Set AttributeByName to add an attribute to the attribute list, or replace an + // existing one. + property AttributeByName[const AName: UTF8String]: UTF8String read GetAttributeByName write + SetAttributeByName; + // AttributeByNameWide returns the attribute value for the attribute that has name AName + // as UnicodeString. Set AttributeByNameWide to add an attribute to the attribute list, or replace an + // existing one. + property AttributeByNameWide[const AName: UTF8String]: UnicodeString read GetAttributeByNameWide write + SetAttributeByNameWide; + // Returns the number of attributes in the current node. + property AttributeCount: integer read GetAttributeCount; + // Read this property to get the name of the attribute at Index. Note that Index + // is zero-based: Index goes from 0 to AttributeCount - 1 + property AttributeName[Index: integer]: UTF8String read GetAttributeName write SetAttributeName; + // Read this property to get the Attribute \Name and Value pair at index Index. + // This is a UTF8String with \Name and Value separated by a TAB character (#9). + property AttributePair[Index: integer]: UTF8String read GetAttributePair; + // Read this property to get the UTF8String value of the attribute at index Index. + // Write to it to set the UTF8String value. + property AttributeValue[Index: integer]: UTF8String read GetAttributeValue write SetAttributeValue; + // Read this property to get the UnicodeString value of the attribute at index Index. + // Write to it to set the UnicodeString value. + property AttributeValueAsUnicodeString[Index: integer]: UnicodeString read GetAttributeValueAsUnicodeString write SetAttributeValueAsUnicodeString; + // Read this property to get the integer value of the attribute at index Index. + // If the value cannot be converted, 0 will be returned. Write to it to set the integer value. + property AttributeValueAsInteger[Index: integer]: integer read GetAttributeValueAsInteger write SetAttributeValueAsInteger; + // Set or get the raw attribute value, thus circumventing the escape function. Make sure that + // the value you set does not contain the & and quote AnsiCharacters, or the produced + // XML will be invalid. + property AttributeValueDirect[Index: integer]: UTF8String read GetAttributeValueDirect write SetAttributeValueDirect; + // BinaryEncoding reflects the same value as the BinaryEncoding setting of the parent + // Document. + property BinaryEncoding: TBinaryEncodingType read GetBinaryEncoding write SetBinaryEncoding; + // Use BinaryString to add/extract binary data in an easy way to/from the node. Internally the + // data gets stored as Base64-encoded data. Do not use this method for normal textual + // information, it is better to use ValueAsString in that case (adds less overhead). + property BinaryString: RawByteString read GetBinaryString write SetBinaryString; + // This property returns the name and index and all predecessors with underscores + // to separate, in order to get a unique reference that can be used in filenames. + property CascadedName: UTF8String read GetCascadedName; + // Pointer to parent NativeXml document, or Nil if none. + property Document: TNativeXml read FDocument write FDocument; + // ElementType contains the type of element that this node holds. + property ElementType: TXmlElementType read FElementType write FElementType; + // Fullpath will return the complete path of the node from the root, e.g. + // /Root/SubNode1/SubNode2/ThisNode + property FullPath: UTF8String read GetFullPath; + // Read Name to get the name of the element, and write Name to set the name. + // This is the full name and may include a namespace. (Namespace:Name) + property Name: UTF8String read FName write SetName; + // Parent points to the parent node of the current XML node. + property Parent: TXmlNode read FParent write FParent; + // NodeCount is the number of child nodes that this node holds. In order to + // loop through all child nodes, use a construct like this: + // + // with MyNode do + // for i := 0 to NodeCount - 1 do + // with Nodes[i] do + // ..processing here + // + property NodeCount: integer read GetNodeCount; + // Use Nodes to access the child nodes of the current XML node by index. Note + // that the list is zero-based, so Index is valid from 0 to NodeCount - 1. + property Nodes[Index: integer]: TXmlNode read GetNodes; default; + // Tag is an integer value the developer can use in any way. Tag does not get + // saved to the XML. Tag is often used to point to a GUI element (and is then + // cast to a pointer). + property Tag: integer read FTag write FTag; + // TotalNodeCount represents the total number of child nodes, and child nodes + // of child nodes etcetera of this particular node. Use the following to get + // the total number of nodes in the XML document: + // + // Total := MyDoc.RootNodes.TotalNodeCount; + // + property TotalNodeCount: integer read GetTotalNodeCount; + // Read TreeDepth to find out many nested levels there are for the current XML + // node. Root has a TreeDepth of zero. + property TreeDepth: integer read GetTreeDepth; + // ValueAsBool returns the node's value as boolean, or raises an + // exception if the value cannot be converted to boolean. Set ValueAsBool + // to convert a boolean to a UTF8String in the node's value field. See also + // function ValueAsBoolDef. + property ValueAsBool: boolean read GetValueAsBool write SetValueAsBool; + // ValueAsDateTime returns the node's value as TDateTime, or raises an + // exception if the value cannot be converted to TDateTime. Set ValueAsDateTime + // to convert a TDateTime to a UTF8String in the node's value field. See also + // function ValueAsDateTimeDef. + property ValueAsDateTime: TDateTime read GetValueAsDateTime write SetValueAsDateTime; + // ValueAsIn64 returns the node's value as int64, or raises an + // exception if the value cannot be converted to int64. Set ValueAsInt64 + // to convert an int64 to a UTF8String in the node's value field. See also + // function ValueAsInt64Def. + property ValueAsInt64: int64 read GetValueAsInt64 write SetValueAsInt64; + // ValueAsInteger returns the node's value as integer, or raises an + // exception if the value cannot be converted to integer. Set ValueAsInteger + // to convert an integer to a UTF8String in the node's value field. See also + // function ValueAsIntegerDef. + property ValueAsInteger: integer read GetValueAsInteger write SetValueAsInteger; + // ValueAsFloat returns the node's value as float, or raises an + // exception if the value cannot be converted to float. Set ValueAsFloat + // to convert a float to a UTF8String in the node's value field. See also + // function ValueAsFloatDef. + property ValueAsFloat: double read GetValueAsFloat write SetValueAsFloat; + // ValueAsString returns the unescaped version of ValueDirect. All neccesary + // characters in ValueDirect must be escaped (e.g. "&" becomes "&") but + // ValueAsString returns them in original format. Always use ValueAsString to + // set the text value of a node, to make sure all neccesary charaters are + // escaped. + property ValueAsString: UTF8String read GetValueAsString write SetValueAsString; + // ValueAsUnicodeString returns the unescaped version of ValueDirect as a UnicodeString. + // Always use ValueAsUnicodeString to set the text value of a node, to make sure all + // neccesary charaters are escaped. + property ValueAsUnicodeString: UnicodeString read GetValueAsUnicodeString write SetValueAsUnicodeString; + // ValueDirect is the exact text value as was parsed from the stream. If multiple + // text elements are encountered, they are added to ValueDirect with a CR to + // separate them. + property ValueDirect: UTF8String read FValue write FValue; + // WriteOnDefault reflects the same value as the WriteOnDefault setting of the parent + // Document. + property WriteOnDefault: boolean read GetWriteOnDefault; + end; + + // TXmlNodeList is a utility TList descendant that can be used to work with selection + // lists. An example: + // + // procedure FindAllZips(ANode: TXmlNode); + // var + // i: integer; + // AList: TXmlNodeList; + // begin + // AList := TXmlNodeList.Create; + // try + // // Get a list of all nodes named 'ZIP' + // ANode.NodesByName('ZIP', AList); + // for i := 0 to AList.Count - 1 do + // // Write the value of the node to output. Since AList[i] will be + // // of type TXmlNode, we can directly access the Value property. + // WriteLn(AList[i].Value); + // finally + // AList.Free; + // end; + // end; + // + TXmlNodeList = class(TList) + private + function GetItems(Index: Integer): TXmlNode; + procedure SetItems(Index: Integer; const Value: TXmlNode); + public + // Return the first node in the list that has an attribute with AName, AValue + function ByAttribute(const AName, AValue: UTF8String): TXmlNode; + property Items[Index: Integer]: TXmlNode read GetItems write SetItems; default; + end; + + // TNativeXml is the XML document holder. Create a TNativeXml and then use + // methods LoadFromFile, LoadFromStream or ReadFromString to load an XML document + // into memory. Or start from scratch and use Root.NodeNew to add nodes and + // eventually SaveToFile and SaveToStream to save the results as an XML document. + // Use property Xmlformat = xfReadable to ensure that indented (readable) output + // is produced. + TNativeXml = class(TPersistent) + private + FAbortParsing: boolean; // Signal to abort the parsing process + FBinaryEncoding: TBinaryEncodingType; // xbeBinHex or xbeBase64 + FCodecStream: TsdCodecStream; // Temporary stream used to read encoded files + FDropCommentsOnParse: boolean; // If true, comments are dropped (deleted) when parsing + FExternalEncoding: TStringEncodingType; + FFloatAllowScientific: boolean; + FFloatSignificantDigits: integer; + FParserWarnings: boolean; // Show parser warnings for non-critical errors + FRootNodes: TXmlNode; // Root nodes in the document (which contains one normal element that is the root) + FIndentString: UTF8String; // The indent string used to indent content (default is two spaces) + FUseFullNodes: boolean; // If true, nodes are never written in short notation. + FUseLocalBias: Boolean; // If true, datetime values are written with timezone offset and converted to local time when read + FWriteOnDefault: boolean; // Set this option to "False" to only write values <> default value (default = true) + FXmlFormat: TXmlFormatType; // xfReadable, xfCompact + FOnNodeCompare: TXmlNodeCompareEvent; // Compare two nodes + FOnNodeNew: TXmlNodeEvent; // Called after a node is added + FOnNodeLoaded: TXmlNodeEvent; // Called after a node is loaded completely + FOnProgress: TXmlProgressEvent; // Called after a node is loaded/saved, with the current position in the file + FOnUnicodeLoss: TNotifyEvent; // This event is called when there is a warning for unicode conversion loss when reading unicode + procedure DoNodeNew(Node: TXmlNode); + procedure DoNodeLoaded(Node: TXmlNode); + procedure DoUnicodeLoss(Sender: TObject); + function GetCommentString: UTF8String; + procedure SetCommentString(const Value: UTF8String); + function GetEntityByName(AName: UTF8String): UTF8String; + function GetRoot: TXmlNode; + function GetEncodingString: UTF8String; + procedure SetEncodingString(const Value: UTF8String); + function GetVersionString: UTF8String; + procedure SetVersionString(const Value: UTF8String); + function GetStyleSheetNode: TXmlNode; + function GetUtf8Encoded: boolean; + protected + procedure CopyFrom(Source: TNativeXml); virtual; + procedure DoProgress(Size: integer); + function LineFeed: UTF8String; virtual; + procedure ParseDTD(ANode: TXmlNode; S: TStream); virtual; + procedure ReadFromStream(S: TStream); virtual; + procedure WriteToStream(S: TStream); virtual; + procedure SetDefaults; virtual; + public + // Create a new NativeXml document which can then be used to read or write XML files. + // A document that is created with Create must later be freed using Free. + // Example: + // + // var + // ADoc: TNativeXml; + // begin + // ADoc := TNativeXml.Create; + // try + // ADoc.LoadFromFile('c:\\temp\\myxml.xml'); + // {do something with the document here} + // finally + // ADoc.Free; + // end; + // end; + // + constructor Create; virtual; + // Use CreateName to Create a new Xml document that will automatically + // contain a root element with name ARootName. + constructor CreateName(const ARootName: UTF8String); virtual; + // Destroy will free all data in the TNativeXml object. This includes the + // root node and all subnodes under it. Do not call Destroy directly, call + // Free instead. + destructor Destroy; override; + // When calling Assign with a Source object that is a TNativeXml, will cause + // it to copy all data from Source. + procedure Assign(Source: TPersistent); override; + // Call Clear to remove all data from the object, and restore all defaults. + procedure Clear; virtual; + // Function IsEmpty returns true if the root is clear, or in other words, the + // root contains no value, no name, no subnodes and no attributes. + function IsEmpty: boolean; virtual; + // Load an XML document from the TStream object in Stream. The LoadFromStream + // procedure will raise an exception of type EFilerError when it encounters + // non-wellformed XML. This method can be used with any TStream descendant. + // See also LoadFromFile and ReadFromString. + procedure LoadFromStream(Stream: TStream); virtual; + // Call procedure LoadFromFile to load an XML document from the filename + // specified. See Create for an example. The LoadFromFile procedure will raise + // an exception of type EFilerError when it encounters non-wellformed XML. + procedure LoadFromFile(const AFileName: string); virtual; + // Call procedure ReadFromString to load an XML document from the UTF8String AValue. + // The ReadFromString procedure will raise an exception of type EFilerError + // when it encounters non-wellformed XML. + procedure ReadFromString(const AValue: UTF8String); virtual; + // Call ResolveEntityReferences after the document has been loaded to resolve + // any present entity references (&Entity;). When an entity is found in the + // DTD, it will replace the entity reference. Whenever an entity contains + // XML markup, it will be parsed and become part of the document tree. Since + // calling ResolveEntityReferences is adding quite some extra overhead, it + // is not done automatically. If you want to do the entity replacement, a good + // moment to call ResolveEntityReferences is right after LoadFromFile. + procedure ResolveEntityReferences; + // Call SaveToStream to save the XML document to the Stream. Stream + // can be any TStream descendant. Set XmlFormat to xfReadable if you want + // the stream to contain indentations to make the XML more human-readable. This + // is not the default and also not compliant with the XML specification. See + // SaveToFile for information on how to save in special encoding. + procedure SaveToStream(Stream: TStream); virtual; + // Call SaveToFile to save the XML document to a file with FileName. If the + // filename exists, it will be overwritten without warning. If the file cannot + // be created, a standard I/O exception will be generated. Set XmlFormat to + // xfReadable if you want the file to contain indentations to make the XML + // more human-readable. This is not the default and also not compliant with + // the XML specification.

+ // Saving to special encoding types can be achieved by setting two properties + // before saving: + // * ExternalEncoding + // * EncodingString + // ExternalEncoding can be se8bit (for plain ascii), seUtf8 (UTF-8), seUtf16LE + // (for unicode) or seUtf16BE (unicode big endian).

Do not forget to also + // set the EncodingString (e.g. "UTF-8" or "UTF-16") which matches with your + // ExternalEncoding. + procedure SaveToFile(const AFileName: string); virtual; + // Call WriteToString to save the XML document to a UTF8String. Set XmlFormat to + // xfReadable if you want the UTF8String to contain indentations to make the XML + // more human-readable. This is not the default and also not compliant with + // the XML specification. + function WriteToString: UTF8String; virtual; + // Set AbortParsing to True if you use the OnNodeNew and OnNodeLoaded events in + // a SAX-like manner, and you want to abort the parsing process halfway. Example: + // + // procedure MyForm.NativeXmlNodeLoaded(Sender: TObject; Node: TXmlNode); + // begin + // if (Node.Name = 'LastNode') and (Sender is TNativeXml) then + // TNativeXml(Sender).AbortParsing := True; + // end; + // + property AbortParsing: boolean read FAbortParsing write FAbortParsing; + // Choose what kind of binary encoding will be used when calling TXmlNode.BufferRead + // and TXmlNode.BufferWrite. Default value is xbeBase64. + property BinaryEncoding: TBinaryEncodingType read FBinaryEncoding write FBinaryEncoding; + // A comment string above the root element \'; Style: xeComment), + (Start: ''; Style: xeExclam), + (Start: ''; Style: xeQuestion), + (Start: '<'; Close: '>'; Style: xeNormal) ); + // direct tags are derived from Normal tags by checking for the /> + + // These constant are used when generating hexchars from buffer data + cHexChar: array[0..15] of AnsiChar = '0123456789ABCDEF'; + cHexCharLoCase: array[0..15] of AnsiChar = '0123456789abcdef'; + + // These AnsiCharacters are used when generating BASE64 AnsiChars from buffer data + cBase64Char: array[0..63] of AnsiChar = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + cBase64PadChar: AnsiChar = '='; + + // The amount of bytes to allocate with each increase of the value buffer + cNodeValueBuf = 2048; + + // byte order marks for strings + // Unicode text files 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. + + const cBomInfoCount = 15; + const cBomInfo: array[0..cBomInfoCount - 1] of TBomInfo = + ( (BOM: ($00,$00,$FE,$FF); Len: 4; Encoding: seUCS4BE; HasBOM: true), + (BOM: ($FF,$FE,$00,$00); Len: 4; Encoding: seUCS4LE; HasBOM: true), + (BOM: ($00,$00,$FF,$FE); Len: 4; Encoding: seUCS4_2143; HasBOM: true), + (BOM: ($FE,$FF,$00,$00); Len: 4; Encoding: seUCS4_3412; HasBOM: true), + (BOM: ($FE,$FF,$00,$00); Len: 2; Encoding: seUTF16BE; HasBOM: true), + (BOM: ($FF,$FE,$00,$00); Len: 2; Encoding: seUTF16LE; HasBOM: true), + (BOM: ($EF,$BB,$BF,$00); Len: 3; Encoding: seUTF8; HasBOM: true), + (BOM: ($00,$00,$00,$3C); Len: 4; Encoding: seUCS4BE; HasBOM: false), + (BOM: ($3C,$00,$00,$00); Len: 4; Encoding: seUCS4LE; HasBOM: false), + (BOM: ($00,$00,$3C,$00); Len: 4; Encoding: seUCS4_2143; HasBOM: false), + (BOM: ($00,$3C,$00,$00); Len: 4; Encoding: seUCS4_3412; HasBOM: false), + (BOM: ($00,$3C,$00,$3F); Len: 4; Encoding: seUTF16BE; HasBOM: false), + (BOM: ($3C,$00,$3F,$00); Len: 4; Encoding: seUTF16LE; HasBOM: false), + (BOM: ($3C,$3F,$78,$6D); Len: 4; Encoding: seAnsi; HasBOM: false), + (BOM: ($4C,$6F,$A7,$94); Len: 4; Encoding: seEBCDIC; HasBOM: false) + ); + +// .NET compatible stub for TBytes (array of byte) type +{$IFNDEF CLR} +type + TBytes = TBigByteArray; +{$ENDIF} + +function StrScan(const Str: PAnsiChar; Chr: AnsiChar): PAnsiChar; +begin + Result := Str; + while Result^ <> Chr do + begin + if Result^ = #0 then + begin + Result := nil; + Exit; + end; + Inc(Result); + end; +end; + +function UTF8QuotedStr(const S: UTF8String; Quote: AnsiChar): UTF8String; +var + P, Src, Dest: PAnsiChar; + AddCount: Integer; +begin + AddCount := 0; + P := StrScan(PAnsiChar(S), Quote); + while P <> nil do + begin + Inc(P); + Inc(AddCount); + P := StrScan(P, Quote); + end; + if AddCount = 0 then + begin + Result := UTF8String(Quote) + S + UTF8String(Quote); + Exit; + end; + SetLength(Result, Length(S) + AddCount + 2); + Dest := Pointer(Result); + Dest^ := Quote; + Inc(Dest); + Src := Pointer(S); + P := StrScan(Src, Quote); + repeat + Inc(P); + Move(Src^, Dest^, P - Src); + Inc(Dest, P - Src); + Dest^ := Quote; + Inc(Dest); + Src := P; + P := StrScan(Src, Quote); + until P = nil; + P := StrEnd(Src); + Move(Src^, Dest^, P - Src); + Inc(Dest, P - Src); + Dest^ := Quote; +end; + +function UTF8ExtractQuotedStr(const S: UTF8String; Quote: AnsiChar): UTF8String; +var + P, Src, Dest: PAnsiChar; + DropCount: Integer; +begin + Result := ''; + Src := PAnsiChar(S); + if (Src = nil) or (Src^ <> Quote) then + Exit; + Inc(Src); + DropCount := 1; + P := Src; + Src := StrScan(Src, Quote); + while Src <> nil do + begin + Inc(Src); + if Src^ <> Quote then + Break; + Inc(Src); + Inc(DropCount); + Src := StrScan(Src, Quote); + end; + if Src = nil then + Src := StrEnd(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 := PAnsiChar(Result); + Src := StrScan(P, Quote); + while Src <> nil do + begin + Inc(Src); + if Src^ <> Quote then + Break; + Move(P^, Dest^, Src - P); + Inc(Dest, Src - P); + Inc(Src); + P := Src; + Src := StrScan(Src, Quote); + end; + if Src = nil then + Src := StrEnd(P); + Move(P^, Dest^, Src - P - 1); + end; +end; + +function Utf8Pos(const Substr, S: UTF8String): Integer; +var + i, x: Integer; + Len, LenSubStr: Integer; +begin + i := 1; + LenSubStr := Length(SubStr); + Len := Length(S) - LenSubStr + 1; + while i <= Len do + begin + if S[i] = SubStr[1] then + begin + x := 1; + while (x < LenSubStr) and (S[i + x] = SubStr[x + 1]) do + Inc(x); + if (x = LenSubStr) then + begin + Result := i; + exit; + end; + end; + Inc(i); + end; + Result := 0; +end; + +// .NET-compatible TStream.Write + +function StreamWrite(Stream: TStream; const Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Offset, Count: Longint): Longint; +begin +{$IFDEF CLR} + Result := Stream.Write(Buffer, Offset, Count); +{$ELSE} + Result := Stream.Write(TBytes(Buffer)[Offset], Count); +{$ENDIF} +end; + +{$IFNDEF CLR} +// Delphi's implementation of TStringStream is severely flawed, it does a SetLength +// on each write, which slows down everything to a crawl. This implementation over- +// comes this issue. +type + TsdUTF8StringStream = class(TMemoryStream) + public + constructor Create(const S: UTF8String); + function DataString: UTF8String; + end; + +constructor TsdUTF8StringStream.Create(const S: UTF8String); +begin + inherited Create; + SetSize(length(S)); + if Size > 0 then + begin + Write(S[1], Size); + Position := 0; + end; +end; + +function TsdUTF8StringStream.DataString: UTF8String; +begin + SetLength(Result, Size); + if Size > 0 then + begin + Position := 0; + Read(Result[1], length(Result)); + end; +end; +{$ELSE} +// In .NET we use the standard TStringStream +type + TsdUTF8StringStream = TStringStream; +{$ENDIF} + +// Utility functions + +function Min(A, B: integer): integer; +begin + if A < B then + Result := A + else + Result := B; +end; + +function Max(A, B: integer): integer; +begin + if A > B then + Result := A + else + Result := B; +end; + +function sdUTF8StringReplace(const S, OldPattern, NewPattern: UTF8String): UTF8String; +var + SearchStr, NewStr: UTF8String; + Offset: Integer; +begin + // Case Sensitive, Replace All + SearchStr := S; + NewStr := S; + Result := ''; + while SearchStr <> '' do + begin + Offset := UTF8Pos(OldPattern, 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); + SearchStr := Copy(SearchStr, Offset + Length(OldPattern), MaxInt); + end; +end; + +function sdUTF8EscapeString(const AValue: UTF8String): UTF8String; +var + i: integer; +begin + Result := AValue; + for i := 0 to cEscapeCount - 1 do + Result := sdUTF8StringReplace(Result, cEscapes[i], cReplaces[i]); +end; + +function sdUTF8UnEscapeString(const AValue: UTF8String): UTF8String; +var + SearchStr, Reference, Replace: UTF8String; + i, Offset, Code: Integer; + W: word; +begin + SearchStr := AValue; + Result := ''; + while SearchStr <> '' do + begin + // find '&' + Offset := Utf8Pos('&', SearchStr); + if Offset = 0 then + begin + // Nothing found + Result := Result + SearchStr; + Break; + end; + Result := Result + Copy(SearchStr, 1, Offset - 1); + SearchStr := Copy(SearchStr, Offset, MaxInt); + // find next ';' + Offset := Utf8Pos(';', SearchStr); + if Offset = 0 then + begin + // Error: encountered a '&' but not a ';'.. we will ignore, just return + // the unmodified value + Result := Result + SearchStr; + Break; + end; + // Reference + Reference := copy(SearchStr, 1, Offset); + SearchStr := Copy(SearchStr, Offset + 1, MaxInt); + Replace := Reference; + // See if it is a Character reference + if copy(Reference, 1, 2) = '&#' then + begin + Reference := copy(Reference, 3, length(Reference) - 3); + if length(Reference) > 0 then + begin + if sdUpCase(Reference[1]) = 'X' then + // Hex notation + Reference[1] := '$'; + Code := StrToIntDef(string(Reference), -1); + if (Code >= 0) and (Code < $FFFF) then + begin + W := Code; + Replace := sdUnicodeToUtf8(UnicodeChar(W)); + end; + end; + end else + begin + // Look up default escapes + for i := 0 to cEscapeCount - 1 do + if Reference = cReplaces[i] then + begin + // Replace + Replace := cEscapes[i]; + Break; + end; + end; + // New result + Result := Result + Replace; + end; +end; + +function sdUTF8QuotedString(const AValue: UTF8String): UTF8String; +var + Quote: AnsiChar; +begin + Quote := '"'; + if UTF8Pos('"', AValue) > 0 then + Quote := ''''; +{$IFDEF CLR} + Result := QuotedStr(AValue, AQuoteChar); +{$ELSE} + Result := UTF8QuotedStr(AValue, Quote); +{$ENDIF} +end; + +function sdUTF8UnQuotedString(const AValue: UTF8String): UTF8String; +var + Quote: AnsiChar; +begin + if Length(AValue) < 2 then + begin + Result := AValue; + exit; + end; + Quote := AValue[1]; + if Quote in cQuoteChars then + begin + {$IFDEF CLR} + Result := DequotedStr(AValue, Quote); + {$ELSE} + Result := UTF8ExtractQuotedStr(AValue, Quote); + {$ENDIF} + end else + Result := AValue; +end; + +function sdAddControlChars(const AValue: UTF8String; const Chars: UTF8String; Interval: integer): UTF8String; +// Insert AnsiChars in AValue at each Interval AnsiChars +var + i, j, ALength: integer; + // local + procedure InsertControlChars; + var + k: integer; + begin + for k := 1 to Length(Chars) do + begin + Result[j] := Chars[k]; + inc(j); + end; + end; +// main +begin + if (Length(Chars) = 0) or (Interval <= 0) then + begin + Result := AValue; + exit; + end; + + // Calculate length based on original length and total extra length for control AnsiChars + ALength := Length(AValue) + ((Length(AValue) - 1) div Interval + 3) * Length(Chars); + SetLength(Result, ALength); + + // Copy and insert + j := 1; + for i := 1 to Length(AValue) do + begin + if (i mod Interval) = 1 then + // Insert control AnsiChars + InsertControlChars; + Result[j] := AValue[i]; + inc(j); + end; + InsertControlChars; + + // Adjust length + dec(j); + if ALength > j then + SetLength(Result, j); +end; + +function sdRemoveControlChars(const AValue: UTF8String): UTF8String; +// Remove control characters from UTF8String in AValue +var + i, j: integer; +begin + Setlength(Result, Length(AValue)); + i := 1; + j := 1; + while i <= Length(AValue) do + if AValue[i] in cControlChars then + inc(i) + else + begin + Result[j] := AValue[i]; + inc(i); + inc(j); + end; + // Adjust length + if i <> j then + SetLength(Result, j - 1); +end; + +function sdUTF8FindString(const SubString, S: UTF8String; Start, Close: integer; var APos: integer): boolean; +// Check if the Substring matches the UTF8String S in any position in interval Start to Close - 1 +// and returns found positon in APos. Result = True if anything is found. +// Note: this funtion is case-insensitive +var + CharIndex: integer; +begin + Result := False; + APos := 0; + for CharIndex := Start to Close - Length(SubString) do + if sdUTF8MatchString(SubString, S, CharIndex) then + begin + APos := CharIndex; + Result := True; + exit; + end; +end; + +function UTF8CompareText(const S1, S2: UTF8String): integer; +begin + Result := AnsiCompareText(string(S1), string(S2)); +end; + +function IntToUTF8Str(Value: integer): UTF8String; +begin + Result := UTF8String(IntToStr(Value)); +end; + +function Int64ToUTF8Str(Value: int64): UTF8String; +begin + Result := UTF8String(IntToStr(Value)); +end; + +function sdUTF8MatchString(const SubString: UTF8String; const S: UTF8String; Start: integer): boolean; +// Check if the Substring matches the string S at position Start. +// Note: this funtion is case-insensitive +var + CharIndex: integer; +begin + Result := False; + // Check range just in case + if (Length(S) - Start + 1) < Length(Substring) then + exit; + + CharIndex := 0; + while CharIndex < Length(SubString) do + if sdUpCase(SubString[CharIndex + 1]) = sdUpCase(S[Start + CharIndex]) then + inc(CharIndex) + else + exit; + // All AnsiChars were the same, so we succeeded + Result := True; +end; + +procedure sdUTF8ParseAttributes(const AValue: UTF8String; Start, Close: integer; Attributes: TsdUTF8StringList); +// Convert the attributes string AValue in [Start, Close - 1] to the attributes Stringlist +var + i: integer; + InQuotes: boolean; + Quote: AnsiChar; +begin + InQuotes := False; + Quote := '"'; + if not assigned(Attributes) then + exit; + if not sdUTF8TrimPos(AValue, Start, Close) then + exit; + + // Clear first + Attributes.Clear; + + // Loop through characters + for i := Start to Close - 1 do + begin + + // In quotes? + if InQuotes then + begin + if AValue[i] = Quote then + InQuotes := False; + end else + begin + if AValue[i] in cQuoteChars then + begin + InQuotes := True; + Quote := AValue[i]; + end; + end; + + // Add attribute strings on each controlchar break + if not InQuotes then + if AValue[i] in cControlChars then + begin + if i > Start then + Attributes.Add(copy(AValue, Start, i - Start)); + Start := i + 1; + end; + end; + + // Add last attribute string + if Start < Close then + Attributes.Add(copy(AValue, Start, Close - Start)); + + // First-char "=" signs should append to previous + for i := Attributes.Count - 1 downto 1 do + if Attributes[i][1] = '=' then + begin + Attributes[i - 1] := Attributes[i - 1] + Attributes[i]; + Attributes.Delete(i); + end; + + // First-char quotes should append to previous + for i := Attributes.Count - 1 downto 1 do + if (Attributes[i][1] in cQuoteChars) and (UTF8Pos('=', Attributes[i - 1]) > 0) then + begin + Attributes[i - 1] := Attributes[i - 1] + Attributes[i]; + Attributes.Delete(i); + end; +end; + +function sdUTF8TrimPos(const AValue: UTF8String; var Start, Close: integer): boolean; +// Trim the string in AValue in [Start, Close - 1] by adjusting Start and Close variables +begin + // Checks + Start := Max(1, Start); + Close := Min(Length(AValue) + 1, Close); + if Close <= Start then + begin + Result := False; + exit; + end; + + // Trim left + while + (Start < Close) and + (AValue[Start] in cControlChars) do + inc(Start); + + // Trim right + while + (Start < Close) and + (AValue[Close - 1] in cControlChars) do + dec(Close); + + // Do we have a string left? + Result := Close > Start; +end; + +function sdUTF8Trim(const AValue: UTF8String): UTF8String; +var + Start, Close: integer; + Res: boolean; +begin + Start := 1; + Close := length(AValue) + 1; + Res := sdUTF8TrimPos(AValue, Start, Close); + if Res then + Result := Copy(AValue, Start, Close - Start) + else + Result := ''; +end; + +procedure sdUTF8WriteStringToStream(S: TStream; const AString: UTF8String); +begin + if Length(AString) > 0 then + begin + {$IFDEF CLR} + S.Write(BytesOf(AString), Length(AString)); + {$ELSE} + S.Write(AString[1], Length(AString)); + {$ENDIF} + end; +end; + +function sdUpCase(Ch: AnsiChar): AnsiChar; +begin + Result := Ch; + case Result of + 'a'..'z': Dec(Result, Ord('a') - Ord('A')); + end; +end; + +function ReadOpenTag(AReader: TsdSurplusReader): integer; +// Try to read the type of open tag from S +var + AIndex, i: integer; + Found: boolean; + Ch: AnsiChar; + Candidates: array[0..cTagCount - 1] of boolean; + Surplus: UTF8String; +begin + Surplus := ''; + Result := cTagCount - 1; + for i := 0 to cTagCount - 1 do Candidates[i] := True; + AIndex := 1; + repeat + Found := False; + inc(AIndex); + if AReader.ReadChar(Ch) = 0 then + exit; + Surplus := Surplus + UTF8String(Ch); + for i := cTagCount - 1 downto 0 do + if Candidates[i] and (length(cTags[i].Start) >= AIndex) then + begin + if cTags[i].Start[AIndex] = Ch then + begin + Found := True; + if length(cTags[i].Start) = AIndex then + Result := i; + end else + Candidates[i] := False; + end; + until Found = False; + // The surplus string that we already read (everything after the tag) + AReader.Surplus := copy(Surplus, length(cTags[Result].Start), length(Surplus)); +end; + +function ReadStringFromStreamUntil(AReader: TsdSurplusReader; const ASearch: UTF8String; + var AValue: UTF8String; SkipQuotes: boolean): boolean; +var + AIndex, ValueIndex, SearchIndex: integer; + LastSearchChar, Ch: AnsiChar; + InQuotes: boolean; + QuoteChar: AnsiChar; + SB: TsdStringBuilder; +begin + Result := False; + InQuotes := False; + + // Get last searchstring character + AIndex := length(ASearch); + if AIndex = 0 then exit; + LastSearchChar := ASearch[AIndex]; + + SB := TsdStringBuilder.Create; + try + QuoteChar := #0; + + repeat + // Add characters to the value to be returned + if AReader.ReadChar(Ch) = 0 then + exit; + SB.AddChar(Ch); + + // Do we skip quotes? + if SkipQuotes then + begin + if InQuotes then + begin + if (Ch = QuoteChar) then + InQuotes := false; + end else + begin + if Ch in cQuoteChars then + begin + InQuotes := true; + QuoteChar := Ch; + end; + end; + end; + + // In quotes? If so, we don't check the end condition + if not InQuotes then + begin + // Is the last char the same as the last char of the search string? + if Ch = LastSearchChar then + begin + + // Check to see if the whole search string is present + ValueIndex := SB.Length - 1; + SearchIndex := length(ASearch) - 1; + if ValueIndex < SearchIndex then continue; + + Result := True; + while (SearchIndex > 0)and Result do + begin + Result := SB[ValueIndex] = ASearch[SearchIndex]; + dec(ValueIndex); + dec(SearchIndex); + end; + end; + end; + until Result; + + // Use only the part before the search string + AValue := SB.StringCopy(1, SB.Length - length(ASearch)); + finally + SB.Free; + end; +end; + +function ReadStringFromStreamWithQuotes(S: TStream; const Terminator: UTF8String; + var AValue: UTF8String): boolean; +var + Ch, QuoteChar: AnsiChar; + InQuotes: boolean; + SB: TsdStringBuilder; +begin + SB := TsdStringBuilder.Create; + try + QuoteChar := #0; + Result := False; + InQuotes := False; + repeat + if S.Read(Ch, 1) = 0 then exit; + if not InQuotes then + begin + if (Ch = '"') or (Ch = '''') then + begin + InQuotes := True; + QuoteChar := Ch; + end; + end else + begin + if Ch = QuoteChar then + InQuotes := False; + end; + if not InQuotes and (UTF8String(Ch) = Terminator) then + break; + SB.AddChar(Ch); + until False; + AValue := SB.Value; + Result := True; + finally + SB.Free; + end; +end; + +function GetTimeZoneBias: Integer; +// uses windows unit, func GetTimeZoneInformation +var + TimeZoneInfo: TTimeZoneInformation; +begin + case GetTimeZoneInformation(TimeZoneInfo) of + TIME_ZONE_ID_UNKNOWN: Result := TimeZoneInfo.Bias; + TIME_ZONE_ID_STANDARD: Result := TimeZoneInfo.Bias + TimeZoneInfo.StandardBias; + TIME_ZONE_ID_DAYLIGHT: Result := TimeZoneInfo.Bias + TimeZoneInfo.DaylightBias; + else + Result := 0; + end; +end; + +function sdDateTimeFromString(const ADate: UTF8String; UseLocalBias: Boolean): TDateTime; +// Convert the string ADate to a TDateTime according to the W3C date/time specification +// as found here: http://www.w3.org/TR/NOTE-datetime +// contributor: Stefan Glienke +var + AYear, AMonth, ADay, AHour, AMin, ASec, AMSec: word; + ALocalBias, ABias: Integer; +begin + AYear := StrToInt(string(copy(ADate, 1, 4))); + AMonth := StrToInt(string(copy(ADate, 6, 2))); + ADay := StrToInt(string(copy(ADate, 9, 2))); + if Length(ADate) > 16 then + begin + AHour := StrToInt(string(copy(ADate, 12, 2))); + AMin := StrToInt(string(copy(ADate, 15, 2))); + ASec := StrToIntDef(string(copy(ADate, 18, 2)), 0); // They might be omitted, so default to 0 + AMSec := StrToIntDef(string(copy(ADate, 21, 3)), 0); // They might be omitted, so default to 0 + end else + begin + AHour := 0; + AMin := 0; + ASec := 0; + AMSec := 0; + end; + Result := + EncodeDate(AYear, AMonth, ADay) + + EncodeTime(AHour, AMin, ASec, AMSec); + ALocalBias := GetTimeZoneBias; + if UseLocalBias then + begin + if (Length(ADate) > 24) then + begin + ABias := StrToInt(string(Copy(ADate, 25, 2))) * MinsPerHour + + StrToInt(string(Copy(ADate, 28, 2))); + if ADate[24] = '+' then + ABias := ABias * -1; + Result := Result + ABias / MinsPerDay; + end; + Result := Result - ALocalBias / MinsPerDay; + end; +end; + +function sdDateTimeFromStringDefault(const ADate: UTF8String; ADefault: TDateTime; UseLocalBias: Boolean): TDateTime; +// Convert the string ADate to a TDateTime according to the W3C date/time specification +// as found here: http://www.w3.org/TR/NOTE-datetime +// If there is a conversion error, the default value ADefault is returned. +begin + try + Result := sdDateTimeFromString(ADate, UseLocalBias); + except + Result := ADefault; + end; +end; + +function sdDateTimeToString(ADate: TDateTime; UseLocalBias: Boolean): UTF8String; +// Convert the TDateTime ADate to a string according to the W3C date/time specification +// as found here: http://www.w3.org/TR/NOTE-datetime +// contributor: Stefan Glienke +var + AYear, AMonth, ADay, AHour, AMin, ASec, AMSec: word; + ABias: Integer; +const + Neg: array[Boolean] of string = ('+', '-'); +begin + DecodeDate(ADate, AYear, AMonth, ADay); + DecodeTime(ADate, AHour, AMin, ASec, AMSec); + if frac(ADate) = 0 then + Result := UTF8String(Format('%.4d-%.2d-%.2d', [AYear, AMonth, ADay])) + else + begin + ABias := GetTimeZoneBias; + if UseLocalBias and (ABias <> 0) then + Result := UTF8String(Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d%s%.2d:%.2d', + [AYear, AMonth, ADay, AHour, AMin, ASec, AMSec, + Neg[ABias > 0], Abs(ABias) div MinsPerHour, Abs(ABias) mod MinsPerHour])) + else + Result := UTF8String(Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ', + [AYear, AMonth, ADay, AHour, AMin, ASec, AMSec])); + end; +end; + +function sdWriteNumber(Value: double; SignificantDigits: integer; AllowScientific: boolean): UTF8String; +const + Limits: array[1..9] of integer = + (10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000); +var + Limit, Limitd, PointPos, IntVal, ScPower: integer; + Body: UTF8String; +begin + if (SignificantDigits < 1) or (SignificantDigits > 9) then + raise Exception.Create(sxeSignificantDigitsOutOfRange); + + // Zero + if Value = 0 then + begin + Result := '0'; + exit; + end; + + // Sign + if Value < 0 then + begin + Result := '-'; + Value := -Value; + end else + Result := ''; + + // Determine point position + Limit := Limits[SignificantDigits]; + Limitd := Limit div 10; + PointPos := SignificantDigits; + while Value < Limitd do + begin + Value := Value * 10; + dec(PointPos); + end; + while Value >= Limit do + begin + Value := Value * 0.1; + inc(PointPos); + end; + + // Round + IntVal := round(Value); + + // Exceptional case which happens when the value rounds up to the limit + if Intval = Limit then + begin + IntVal := IntVal div 10; + inc(PointPos); + end; + + // Strip off any zeros, these reduce significance count + while (IntVal mod 10 = 0) and (PointPos < SignificantDigits) do + begin + dec(SignificantDigits); + IntVal := IntVal div 10; + end; + + // Check for scientific notation + ScPower := 0; + if AllowScientific and ((PointPos < -1) or (PointPos > SignificantDigits + 2)) then + begin + ScPower := PointPos - 1; + dec(PointPos, ScPower); + end; + + // Body + Body := IntToUTF8Str(IntVal); + while PointPos > SignificantDigits do + begin + Body := Body + '0'; + inc(SignificantDigits); + end; + while PointPos < 0 do + begin + Body := '0' + Body; + inc(PointPos); + end; + if PointPos = 0 then + Body := '.' + Body + else + if PointPos < SignificantDigits then + Body := copy(Body, 1, PointPos) + '.' + copy(Body, PointPos + 1, SignificantDigits); + + // Final result + if ScPower = 0 then + Result := Result + Body + else + Result := Result + Body + 'E' + IntToUTF8Str(ScPower); +end; + +{$IFDEF CLR} + +function sdUnicodeToUtf8(const W: UnicodeString): UTF8String; +begin + Result := Encoding.UTF8.GetBytes(W); +end; + +function sdUtf8ToUnicode(const S: UTF8String): UnicodeString; +begin + Result := Encoding.UTF8.GetString(BytesOf(S)); +end; + +function EncodeBase64Buf(const Buffer: TBytes; Count: Integer): UTF8String; +begin + Result := Convert.ToBase64String(Buffer, 0, Count); +end; + +function EncodeBase64(const Source: UTF8String): UTF8String; +begin + Result := Convert.ToBase64String(BytesOf(Source)); +end; + +procedure DecodeBase64Buf(const Source: UTF8String; var Buffer: TBytes; Count: Integer); +var + ADecoded: TBytes; +begin + ADecoded := Convert.FromBase64String(Source); + if Count > Length(ADecoded) then + raise EFilerError.Create(sxeMissingDataInBinaryStream); + SetLength(ADecoded, Count); + Buffer := ADecoded; +end; + +function DecodeBase64(const Source: UTF8String): UTF8String; +begin + Result := UTF8String(Convert.FromBase64String(Source)); +end; + +{$ELSE} + +function PtrUnicodeToUtf8(Dest: PAnsiChar; MaxDestBytes: Cardinal; Source: PUnicodeChar; SourceChars: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Cardinal; +begin + Result := 0; + if not assigned(Source) or not assigned(Dest) then + exit; + + count := 0; + i := 0; + + while (i < SourceChars) and (count < MaxDestBytes) do + begin + c := Cardinal(Source[i]); + Inc(i); + if c <= $7F then + begin + Dest[count] := AnsiChar(c); + Inc(count); + end else + if c > $7FF then + begin + if count + 3 > MaxDestBytes then + break; + Dest[count] := AnsiChar($E0 or (c shr 12)); + Dest[count+1] := AnsiChar($80 or ((c shr 6) and $3F)); + Dest[count+2] := AnsiChar($80 or (c and $3F)); + Inc(count,3); + end else + begin // $7F < Source[i] <= $7FF + if count + 2 > MaxDestBytes then + break; + Dest[count] := AnsiChar($C0 or (c shr 6)); + Dest[count+1] := AnsiChar($80 or (c and $3F)); + Inc(count,2); + end; + end; + if count >= MaxDestBytes then + count := MaxDestBytes-1; + Dest[count] := #0; + Result := count + 1; // convert zero based index to byte count +end; + +function PtrUtf8ToUnicode(Dest: PUnicodeChar; MaxDestChars: Cardinal; Source: PAnsiChar; + SourceBytes: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Byte; + wc: Cardinal; +begin + if not assigned(Dest) or not assigned(Source) then + begin + Result := 0; + Exit; + end; + Result := Cardinal(-1); + count := 0; + i := 0; + 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 + // incomplete multibyte char + Exit; + wc := wc and $3F; + if (wc and $20) <> 0 then + begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + // malformed trail byte or out of range char + Exit; + if i >= SourceBytes then + // incomplete multibyte char + Exit; + wc := (wc shl 6) or (c and $3F); + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + // malformed trail byte + Exit; + Dest[count] := UnicodeChar((wc shl 6) or (c and $3F)); + end else + Dest[count] := UnicodeChar(wc); + Inc(count); + end; + + if count >= MaxDestChars then + count := MaxDestChars-1; + + Dest[count] := #0; + Result := count + 1; +end; + +function sdUnicodeToUtf8(const W: UnicodeString): UTF8String; +var + L: integer; + Temp: UTF8String; +begin + Result := ''; + if W = '' then + Exit; + SetLength(Temp, Length(W) * 3); // SetLength includes space for null terminator + + L := PtrUnicodeToUtf8(PAnsiChar(Temp), Length(Temp) + 1, PUnicodeChar(W), Length(W)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function sdUtf8ToUnicode(const S: UTF8String): UnicodeString; +var + L: Integer; + Temp: UnicodeString; +begin + Result := ''; + if S = '' then + Exit; + SetLength(Temp, Length(S)); + + L := PtrUtf8ToUnicode(PUnicodeChar(Temp), Length(Temp)+1, PAnsiChar(S), Length(S)); + if L > 0 then + SetLength(Temp, L-1) + else + Temp := ''; + Result := Temp; +end; + +function EncodeBase64Buf(const Buffer; Count: Integer): UTF8String; +var + i, j: integer; + ACore: integer; + ALong: cardinal; + S: PByte; +begin + // Make sure ASize is always a multiple of 3, and this multiple + // gets saved as 4 characters + ACore := (Count + 2) div 3; + + // Set the length of the string that stores encoded characters + SetLength(Result, ACore * 4); + S := @Buffer; + // Do the loop ACore times + for i := 0 to ACore - 1 do + begin + ALong := 0; + for j := 0 to 2 do + begin + ALong := ALong shl 8 + S^; + inc(S); + end; + for j := 0 to 3 do + begin + Result[i * 4 + 4 - j] := cBase64Char[ALong and $3F]; + ALong := ALong shr 6; + end; + end; + // For comformity to Base64, we must pad the data instead of zero out + // if the size is not an exact multiple of 3 + case ACore * 3 - Count of + 0:;// nothing to do + 1: // pad one byte + Result[ACore * 4] := cBase64PadChar; + 2: // pad two bytes + begin + Result[ACore * 4 ] := cBase64PadChar; + Result[ACore * 4 - 1] := cBase64PadChar; + end; + end;//case +end; + +function EncodeBase64(const Source: RawByteString): UTF8String; +// Encode binary data in Source as BASE64. The function returns the BASE64 encoded +// data as string, without any linebreaks. +begin + if length(Source) > 0 then + Result := EncodeBase64Buf(Source[1], length(Source)) + else + Result := ''; +end; + +procedure DecodeBase64Buf(var Source: UTF8String; var Buffer; Count: Integer); +var + i, j: integer; + BufPos, Core: integer; + LongVal: cardinal; + D: PByte; + Map: array[AnsiChar] of byte; +begin + // Core * 4 is the number of chars to read - check length + Core := Length(Source) div 4; + if Count > Core * 3 then + raise EFilerError.Create(sxeMissingDataInBinaryStream); + + // Prepare map + for i := 0 to 63 do + Map[cBase64Char[i]] := i; + D := @Buffer; + + // Check for final padding, and replace with "zeros". There can be + // at max two pad chars ('=') + BufPos := length(Source); + if (BufPos > 0) and (Source[BufPos] = cBase64PadChar) then + begin + Source[BufPos] := cBase64Char[0]; + dec(BufPos); + if (BufPos > 0) and (Source[BufPos] = cBase64PadChar) then + Source[BufPos] := cBase64Char[0]; + end; + + // Do this Core times + for i := 0 to Core - 1 do + begin + LongVal := 0; + // Unroll the characters + for j := 0 to 3 do + LongVal := LongVal shl 6 + Map[Source[i * 4 + j + 1]]; + // and unroll the bytes + for j := 2 downto 0 do + begin + // Check overshoot + if integer(D) - integer(@Buffer) >= Count then + exit; + D^ := LongVal shr (j * 8) and $FF; + inc(D); + end; + end; +end; + +function DecodeBase64(const Source: UTF8String): RawByteString; +// Decode BASE64 data in Source into binary data. The function returns the binary +// data as UTF8String. Use a TStringStream to convert this data to a stream. +var + BufData: UTF8String; + BufSize, BufPos: integer; +begin + BufData := sdRemoveControlChars(Source); + + // Determine length of data + BufSize := length(BufData) div 4; + if BufSize * 4 <> length(BufData) then + raise EFilerError.Create(sxeErrorCalcStreamLength); + BufSize := BufSize * 3; + // Check padding AnsiChars + BufPos := length(BufData); + if (BufPos > 0) and (BufData[BufPos] = cBase64PadChar) then + begin + dec(BufPos); + dec(BufSize); + if (BufPos > 0) and (BufData[BufPos] = cBase64PadChar) then + dec(BufSize); + end; + Setlength(Result, BufSize); + + // Decode + if BufSize > 0 then + DecodeBase64Buf(BufData, Result[1], BufSize); +end; + +{$ENDIF} + +function sdAnsiToUtf8(const S: AnsiString): UTF8String; +begin + // We let the OS figure out Ansi<->Unicode + Result := sdUnicodeToUtf8(UnicodeString(S)); +end; + +function sdUtf8ToAnsi(const S: UTF8String): AnsiString; +begin + // We let the OS figure out Ansi<->Unicode. There might be dataloss! + Result := Ansistring(sdUtf8ToUnicode(S)); +end; + +function EncodeBinHexBuf(const Source; Count: Integer): UTF8String; +// Encode binary data in Source as BINHEX. The function returns the BINHEX encoded +// data as UTF8String, without any linebreaks. +var +{$IFDEF CLR} + Text: TBytes; +{$ELSE} + Text: UTF8String; +{$ENDIF} +begin + SetLength(Text, Count * 2); +{$IFDEF CLR} + BinToHex(TBytes(Source), 0, Text, 0, Count); +{$ELSE} + BinToHex(PAnsiChar(@Source), PAnsiChar(Text), Count); +{$ENDIF} + Result := Text; +end; + +function EncodeBinHex(const Source: RawByteString): UTF8String; +// Encode binary data in Source as BINHEX. The function returns the BINHEX encoded +// data as UTF8String, without any linebreaks. +var +{$IFDEF CLR} + Text: TBytes; +{$ELSE} + Text: UTF8String; +{$ENDIF} +begin + SetLength(Text, Length(Source) * 2); +{$IFDEF CLR} + BinToHex(BytesOf(Source), 0, Text, 0, Length(Source)); +{$ELSE} + BinToHex(PAnsiChar(Source), PAnsiChar(Text), Length(Source)); +{$ENDIF} + Result := Text; +end; + +procedure DecodeBinHexBuf(const Source: UTF8String; var Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Count: Integer); +// Decode BINHEX data in Source into binary data. +begin + if Length(Source) div 2 < Count then + raise EFilerError.Create(sxeMissingDataInBinaryStream); + +{$IFDEF CLR} + HexToBin(BytesOf(Source), 0, Buffer, 0, Count); +{$ELSE} + HexToBin(PAnsiChar(Source), PAnsiChar(@Buffer), Count); +{$ENDIF} +end; + +function DecodeBinHex(const Source: UTF8String): RawByteString; +// Decode BINHEX data in Source into binary data. The function returns the binary +// data as RawByteString. Use a TStringStream to convert this data to a stream. +var + Data: Utf8String; + Size: integer; +{$IFDEF CLR} + Buffer: TBytes; +{$ELSE} + Buffer: RawByteString; +{$ENDIF} +begin + Data := sdRemoveControlChars(Source); + + // Determine length of data + Size := length(Data) div 2; + if Size * 2 <> length(Data) then + raise EFilerError.Create(sxeErrorCalcStreamLength); + + SetLength(Buffer, Size); +{$IFDEF CLR} + HexToBin(BytesOf(Data), 0, Buffer, 0, Size); +{$ELSE} + HexToBin(PAnsiChar(Data), PAnsiChar(Buffer), Size); +{$ENDIF} + Result := Buffer; +end; + +function sdStringToBool(const AValue: UTF8String): boolean; +var + Ch: AnsiChar; +begin + if Length(AValue) > 0 then + begin + Ch := sdUpCase(AValue[1]); + if Ch in ['T', 'Y', '1'] then + begin + Result := True; + exit; + end; + if Ch in ['F', 'N', '0'] then + begin + Result := False; + exit; + end; + end; + raise Exception.Create(sxeCannotConverToBool); +end; + +function sdStringFromBool(ABool: boolean): UTF8String; +const + cBoolValues: array[boolean] of UTF8String = ('false', 'true'); +begin + Result := cBoolValues[ABool]; +end; + +{ TsdUTF8StringList } + +function TsdUTF8StringList.Add(const S: UTF8String): integer; +var + L: integer; +begin + L := Length(FItems); + if L = FCount then + begin + // Increase capacity + SetLength(FItems, FCount + 4); + end; + FItems[FCount] := S; + Result := FCount; + inc(FCount); +end; + +procedure TsdUTF8StringList.Assign(Source: TPersistent); +var + i: integer; + SL: TsdUTF8StringList; +begin + if Source is TsdUTF8StringList then + begin + SL := TsdUTF8StringList(Source); + SetLength(FItems, SL.FCount); + for i := 0 to SL.FCount - 1 do + FItems[i] := SL.FItems[i]; + FCount := SL.FCount; + end else + inherited; +end; + +procedure TsdUTF8StringList.Clear; +begin + FCount := 0; +end; + +procedure TsdUTF8StringList.Delete(Index: Integer); +var + i: integer; +begin + if (Index < 0) or (Index >= Count) then + exit; + for i := Index + 1 to Count - 1 do + FItems[i - 1] := FItems[i]; + dec(FCount); +end; + +function TsdUTF8StringList.GetItems(Index: integer): UTF8String; +begin + if (Index >= 0) and (Index < Count) then + Result := FItems[Index] + else + Result := ''; +end; + +function TsdUTF8StringList.GetNames(Index: integer): UTF8String; +var + P: integer; +begin + Result := Items[Index]; + P := UTF8Pos('=', Result); + if P <> 0 then + SetLength(Result, P - 1) + else + SetLength(Result, 0); +end; + +function TsdUTF8StringList.GetText: UTF8String; +const + cLB: UTF8String = #13#10; +var + i, L, LItem: integer; + P: PAnsiChar; +begin + L := 0; + for i := 0 to Count - 1 do + begin + inc(L, length(FItems[i])); + inc(L, 2); + end; + SetLength(Result, L); + if L = 0 then + exit; + P := @Result[1]; + for i := 0 to Count - 1 do + begin + LItem := length(FItems[i]); + if LItem > 0 then + begin + System.Move(FItems[i][1], P^, LItem); + inc(P, LItem); + end; + System.Move(cLB[1], P^, 2); + inc(P, 2); + end; +end; + +function TsdUTF8StringList.GetValues(const Name: UTF8String): UTF8String; +var + Idx: integer; +begin + Idx := IndexOfName(Name); + if Idx >= 0 then + Result := Copy(FItems[Idx], Length(Name) + 2, MaxInt) + else + Result := ''; +end; + +function TsdUTF8StringList.IndexOfName(const Name: UTF8String): integer; +begin + for Result := 0 to Count - 1 do + begin + if sdUTF8MatchString(Name + '=', FItems[Result], 1) then + exit; + end; + Result := -1; +end; + +procedure TsdUTF8StringList.SetItems(Index: integer; const Value: UTF8String); +begin + if (Index >= 0) and (Index < Count) then + FItems[Index] := Value; +end; + +procedure TsdUTF8StringList.SetValues(const Name, Value: UTF8String); +var + Idx: integer; +begin + Idx := IndexOfName(Name); + if Value <> '' then + begin + if Idx < 0 then + Idx := Add(''); + FItems[Idx] := Name + '=' + Value; + end else + Delete(Idx); +end; + +{ TXmlNode } + +function TXmlNode.AbortParsing: boolean; +begin + Result := assigned(Document) and Document.AbortParsing; +end; + +procedure TXmlNode.Assign(Source: TPersistent); +var + i: integer; + Node: TXmlNode; +begin + if Source is TXmlNode then + begin + // Clear first + Clear; + + // Properties + FElementType := TXmlNode(Source).FElementType; + FName := TXmlNode(Source).FName; + FTag := TXmlNode(Source).FTag; + FValue := TXmlNode(Source).FValue; + + // Attributes + if assigned(TXmlNode(Source).FAttributes) then + begin + CheckCreateAttributesList; + FAttributes.Assign(TXmlNode(Source).FAttributes); + end; + + // Nodes + for i := 0 to TXmlNode(Source).NodeCount - 1 do + begin + Node := NodeNew(''); + Node.Assign(TXmlNode(Source).Nodes[i]); + end; + end else + if Source is TNativeXml then + begin + Assign(TNativeXml(Source).FRootNodes); + end else + inherited; +end; + +procedure TXmlNode.AttributeAdd(const AName, AValue: UTF8String); +var + Attr: UTF8String; +begin + Attr := UTF8String(Format('%s=%s', [AName, sdUTF8QuotedString(sdUTF8EscapeString(AValue))])); + CheckCreateAttributesList; + FAttributes.Add(Attr); +end; + +procedure TXmlNode.AttributeAdd(const AName: UTF8String; AValue: integer); +begin + AttributeAdd(AName, IntToUTF8Str(AValue)); +end; + +procedure TXmlNode.AttributeDelete(Index: integer); +begin + if (Index >= 0) and (Index < AttributeCount) then + FAttributes.Delete(Index); +end; + +procedure TXmlNode.AttributeExchange(Index1, Index2: integer); +var + Temp: UTF8String; +begin + if (Index1 <> Index2) and + (Index1 >= 0) and (Index1 < FAttributes.Count) and + (Index2 >= 0) and (Index2 < FAttributes.Count) then + begin + Temp := FAttributes[Index1]; + FAttributes[Index1] := FAttributes[Index2]; + FAttributes[Index2] := Temp; + end; +end; + +function TXmlNode.AttributeIndexByname(const AName: UTF8String): integer; +// Return the index of the attribute with name AName, or -1 if not found +begin + if assigned(FAttributes) then + Result := FAttributes.IndexOfName(AName) + else + Result := -1; +end; + +procedure TXmlNode.AttributesClear; +begin + FreeAndNil(FAttributes); +end; + +function TXmlNode.BufferLength: integer; +var + BufData: UTF8String; + BufPos: integer; +begin + BufData := sdRemoveControlChars(FValue); + case BinaryEncoding of + xbeBinHex: + begin + Result := length(BufData) div 2; + if Result * 2 <> length(BufData) then + raise EFilerError.Create(sxeErrorCalcStreamLength); + end; + xbeBase64: + begin + Result := length(BufData) div 4; + if Result * 4 <> length(BufData) then + raise EFilerError.Create(sxeErrorCalcStreamLength); + Result := Result * 3; + // Check padding AnsiChars + BufPos := length(BufData); + if (BufPos > 0) and (BufData[BufPos] = cBase64PadChar) then + begin + dec(BufPos); + dec(Result); + if (BufPos > 0) and (BufData[BufPos] = cBase64PadChar) then + dec(Result); + end; + end; + else + Result := 0; // avoid compiler warning + end; +end; + +procedure TXmlNode.BufferRead(var Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Count: Integer); +// Read data from XML binhex to the buffer +var + BufData: UTF8String; +begin + BufData := sdRemoveControlChars(FValue); + case BinaryEncoding of + xbeBinHex: + DecodeBinHexBuf(BufData, Buffer, Count); + xbeBase64: + DecodeBase64Buf(BufData, Buffer, Count); + end; +end; + +procedure TXmlNode.BufferWrite(const Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Count: Integer); +// Write data from the buffer to XML in binhex or base64 format +var + BufData: UTF8String; +begin + if Count > 0 then + case BinaryEncoding of + xbeBinHex: + BufData := EncodeBinHexBuf(Buffer, Count); + xbeBase64: + BufData := EncodeBase64Buf(Buffer, Count); + end; + + // For comformity with Base64, we must add linebreaks each 76 AnsiCharacters + FValue := sdAddControlChars(BufData, GetLineFeed + GetIndent, 76); +end; + +procedure TXmlNode.ChangeDocument(ADocument: TNativeXml); +var + i: integer; +begin + FDocument := ADocument; + for i := 0 to NodeCount - 1 do + Nodes[i].ChangeDocument(ADocument); +end; + +procedure TXmlNode.CheckCreateAttributesList; +begin + if not assigned(FAttributes) then + FAttributes := TsdUTF8StringList.Create; +end; + +procedure TXmlNode.Clear; +begin + // Name + value + FName := ''; + FValue := ''; + // Clear attributes and nodes + AttributesClear; + NodesClear; +end; + +function TXmlNode.CompareNodeName(const NodeName: UTF8String): integer; +begin + // Compare with FullPath or local name based on NodeName's first AnsiCharacter + if length(NodeName) > 0 then + if NodeName[1] = '/' then + begin + // FullPath + Result := UTF8CompareText(FullPath, NodeName); + exit; + end; + // local name + Result := UTF8CompareText(Name, NodeName); +end; + +constructor TXmlNode.Create(ADocument: TNativeXml); +begin + inherited Create; + FDocument := ADocument; +end; + +constructor TXmlNode.CreateName(ADocument: TNativeXml; const AName: UTF8String); +begin + Create(ADocument); + Name := AName; +end; + +constructor TXmlNode.CreateNameValue(ADocument: TNativeXml; const AName, AValue: UTF8String); +begin + Create(ADocument); + Name := AName; + ValueAsString := AValue; +end; + +constructor TXmlNode.CreateType(ADocument: TNativeXml; + AType: TXmlElementType); +begin + Create(ADocument); + FElementType := AType; +end; + +procedure TXmlNode.Delete; +begin + if assigned(Parent) then + Parent.NodeRemove(Self); +end; + +procedure TXmlNode.DeleteEmptyAttributes; +var + i: integer; + V: UTF8String; +begin + for i := AttributeCount - 1 downto 0 do + begin + V := AttributeValue[i]; + if length(V) = 0 then + FAttributes.Delete(i); + end; +end; + +procedure TXmlNode.DeleteEmptyNodes; +var + i: integer; + Node: TXmlNode; +begin + for i := NodeCount - 1 downto 0 do + begin + Node := Nodes[i]; + // Recursive call + Node.DeleteEmptyNodes; + // Check if we should delete child node + if Node.IsEmpty then + NodeDelete(i); + end; +end; + +destructor TXmlNode.Destroy; +begin + NodesClear; + AttributesClear; + inherited; +end; + +function TXmlNode.FindNode(const NodeName: UTF8String): TXmlNode; +// Find the first node which has name NodeName. Contrary to the NodeByName +// function, this function will search the whole subnode tree, using the +// DepthFirst method. +var + i: integer; +begin + Result := nil; + // Loop through all subnodes + for i := 0 to NodeCount - 1 do + begin + Result := Nodes[i]; + // If the subnode has name NodeName then we have a result, exit + if Result.CompareNodeName(NodeName) = 0 then + exit; + // If not, we will search the subtree of this node + Result := Result.FindNode(NodeName); + if assigned(Result) then + exit; + end; +end; + +procedure TXmlNode.FindNodes(const NodeName: UTF8String; const AList: TList); + // local + procedure FindNodesRecursive(ANode: TXmlNode; AList: TList); + var + i: integer; + begin + with ANode do + for i := 0 to NodeCount - 1 do + begin + if Nodes[i].CompareNodeName(NodeName) = 0 then + AList.Add(Nodes[i]); + FindNodesRecursive(Nodes[i], AList); + end; + end; +// main +begin + AList.Clear; + FindNodesRecursive(Self, AList); +end; + +function TXmlNode.FloatAllowScientific: boolean; +begin + if assigned(Document) then + Result := Document.FloatAllowScientific + else + Result := cDefaultFloatAllowScientific; +end; + +function TXmlNode.FloatSignificantDigits: integer; +begin + if assigned(Document) then + Result := Document.FloatSignificantDigits + else + Result := cDefaultFloatSignificantDigits; +end; + +function TXmlNode.FromAnsiString(const s: AnsiString): UTF8String; +begin + Result := sdAnsiToUtf8(s) +end; + +function TXmlNode.FromUnicodeString(const W: UnicodeString): UTF8String; +begin + Result := sdUnicodeToUtf8(W) +end; + +function TXmlNode.GetAttributeByName(const AName: UTF8String): UTF8String; +begin + if assigned(FAttributes) then + Result := sdUTF8UnEscapeString(sdUTF8UnQuotedString(FAttributes.Values[AName])) + else + Result := ''; +end; + +function TXmlNode.GetAttributeByNameWide(const AName: UTF8String): UnicodeString; +begin + Result := ToUnicodeString(GetAttributeByName(AName)); +end; + +function TXmlNode.GetAttributeCount: integer; +begin + if assigned(FAttributes) then + Result := FAttributes.Count + else + Result := 0; +end; + +function TXmlNode.GetAttributeName(Index: integer): UTF8String; +begin + if (Index >= 0) and (Index < AttributeCount) then + Result := FAttributes.Names[Index]; +end; + +function TXmlNode.GetAttributePair(Index: integer): UTF8String; +begin + if (Index >= 0) and (Index < AttributeCount) then + Result := FAttributes[Index]; +end; + +function TXmlNode.GetAttributeValue(Index: integer): UTF8String; +var + P: integer; + S: UTF8String; +begin + Result := ''; + if (Index >= 0) and (Index < AttributeCount) then + begin + S := FAttributes[Index]; + P := Utf8Pos('=', S); + if P > 0 then + Result := sdUTF8UnEscapeString(sdUTF8UnQuotedString(Copy(S, P + 1, MaxInt))); + end; +end; + +function TXmlNode.GetAttributeValueAsInteger(Index: integer): integer; +begin + Result := StrToIntDef(string(GetAttributeValue(Index)), 0); +end; + +function TXmlNode.GetAttributeValueAsUnicodeString(Index: integer): UnicodeString; +begin + Result := ToUnicodeString(GetAttributeValue(Index)); +end; + +function TXmlNode.GetAttributeValueDirect(Index: integer): UTF8String; +var + P: integer; + S: UTF8String; +begin + Result := ''; + if (Index >= 0) and (Index < AttributeCount) then + begin + S := FAttributes[Index]; + P := Utf8Pos('=', S); + if P > 0 then + Result := sdUTF8UnQuotedString(Copy(S, P + 1, MaxInt)); + end; +end; + +function TXmlNode.GetBinaryEncoding: TBinaryEncodingType; +begin + Result := xbeBinHex; + if assigned(Document) then + Result := Document.BinaryEncoding; +end; + +function TXmlNode.GetBinaryString: RawByteString; +// Get the binary contents of this node as Base64 and return it as a RawByteString +var + OldEncoding: TBinaryEncodingType; +{$IFDEF CLR} + Buffer: TBytes; +{$ENDIF} +begin + // Set to base64 + OldEncoding := BinaryEncoding; + try + BinaryEncoding := xbeBase64; + {$IFDEF CLR} + SetLength(Buffer, BufferLength); + if length(Buffer) > 0 then + BufferRead(Buffer, length(Buffer)); + Result := Buffer; + {$ELSE} + SetLength(Result, BufferLength); + if length(Result) > 0 then + BufferRead(Result[1], length(Result)); + {$ENDIF} + finally + BinaryEncoding := OldEncoding; + end; +end; + +function TXmlNode.GetCascadedName: UTF8String; +// Return the name+index and all predecessors with underscores to separate, in +// order to get a unique reference that can be used in filenames +var + LName: UTF8String; +begin + LName := UTF8String(Format('%s%.4d', [Name, StrToIntDef(string(AttributeByName['Index']), 0)])); + if assigned(Parent) then + Result := UTF8String(Format('%s_%s', [Parent.CascadedName, LName])) + else + Result := LName; +end; + +function TXmlNode.GetFullPath: UTF8String; +// GetFullpath will return the complete path of the node from the root, e.g. +// /Root/SubNode1/SubNode2/ThisNode +begin + Result := '/' + Name; + if Treedepth > 0 then + // Recursive call + Result := Parent.GetFullPath + Result; +end; + +function TXmlNode.GetIndent: UTF8String; +var + i: integer; +begin + if assigned(Document) then + begin + case Document.XmlFormat of + xfCompact: Result := ''; + xfReadable: + for i := 0 to TreeDepth - 1 do + Result := Result + Document.IndentString; + end; //case + end else + Result := '' +end; + +function TXmlNode.GetLineFeed: UTF8String; +begin + if assigned(Document) then + begin + case Document.XmlFormat of + xfCompact: Result := ''; + xfReadable: Result := #13#10; + else + Result := #10; + end; //case + end else + Result := ''; +end; + +function TXmlNode.GetNodeCount: integer; +begin + if Assigned(FNodes) then + Result := FNodes.Count + else + Result := 0; +end; + +function TXmlNode.GetNodes(Index: integer): TXmlNode; +begin + if (Index >= 0) and (Index < NodeCount) then + Result := TXmlNode(FNodes[Index]) + else + Result := nil; +end; + +function TXmlNode.GetTotalNodeCount: integer; +var + i: integer; +begin + Result := NodeCount; + for i := 0 to NodeCount - 1 do + inc(Result, Nodes[i].TotalNodeCount); +end; + +function TXmlNode.GetTreeDepth: integer; +begin + Result := -1; + if assigned(Parent) then + Result := Parent.TreeDepth + 1; +end; + +function TXmlNode.GetValueAsBool: boolean; +begin + Result := sdStringToBool(FValue); +end; + +function TXmlNode.GetValueAsDateTime: TDateTime; +begin + Result := sdDateTimeFromString(ValueAsString, UseLocalBias); +end; + +function TXmlNode.GetValueAsFloat: double; +var + Code: integer; +begin + val(string(sdUTF8StringReplace(FValue, ',', '.')), Result, Code); + if Code > 0 then + raise Exception.Create(sxeCannotConvertToFloat); +end; + +function TXmlNode.GetValueAsInt64: int64; +begin + Result := StrToInt64(string(FValue)); +end; + +function TXmlNode.GetValueAsInteger: integer; +begin + Result := StrToInt(string(FValue)); +end; + +function TXmlNode.GetValueAsString: UTF8String; +begin + if FElementType = xeNormal then + Result := UnEscapeString(sdUTF8Trim(FValue)) + else + Result := UnEscapeString(FValue); +end; + +function TXmlNode.GetValueAsUnicodeString: UnicodeString; +begin + Result := ToUnicodeString(ValueAsString); +end; + +function TXmlNode.GetWriteOnDefault: boolean; +begin + Result := True; + if assigned(Document) then + Result := Document.WriteOnDefault; +end; + +function TXmlNode.HasAttribute(const AName: UTF8String): boolean; +begin + if assigned(FAttributes) then + Result := FAttributes.IndexOfName(AName) >= 0 + else + Result := False; +end; + +function TXmlNode.IndexInParent: integer; +// Retrieve our index in the parent's nodelist +begin + Result := -1; + if assigned(Parent) then + Result := Parent.FNodes.IndexOf(Self); +end; + +function TXmlNode.IsClear: boolean; +begin + Result := (Length(FName) = 0) and IsEmpty; +end; + +function TXmlNode.IsEmpty: boolean; +begin + Result := (Length(FValue) = 0) and (NodeCount = 0) and (AttributeCount = 0); +end; + +function TXmlNode.IsEqualTo(ANode: TXmlNode; Options: TXmlCompareOptions; + MismatchNodes: TList): boolean; +var + i, Index: integer; + NodeResult, ChildResult: boolean; +begin + // Start with a negative result + Result := False; + NodeResult := False; + if not assigned(ANode) then + exit; + + // Assume childs equals other node's childs + ChildResult := True; + + // child node names and values - this comes first to assure the lists are filled + if (xcChildNames in Options) or (xcChildValues in Options) or (xcRecursive in Options) then + for i := 0 to NodeCount - 1 do + begin + // Do child name check + Index := ANode.NodeIndexByName(Nodes[i].Name); + // Do we have the childnode in the other? + if Index < 0 then + begin + // No we dont have it + if xcChildNames in Options then + begin + if assigned(MismatchNodes) then MismatchNodes.Add(Nodes[i]); + ChildResult := False; + end; + end else + begin + // Do child value check + if xcChildValues in Options then + if UTF8CompareText(Nodes[i].ValueAsString, ANode.Nodes[Index].ValueAsString) <> 0 then + begin + if assigned(MismatchNodes) then + MismatchNodes.Add(Nodes[i]); + ChildResult := False; + end; + // Do recursive check + if xcRecursive in Options then + if not Nodes[i].IsEqualTo(ANode.Nodes[Index], Options, MismatchNodes) then + ChildResult := False; + end; + end; + + try + // We assume there are differences + NodeResult := False; + + // Node name, type and value + if xcNodeName in Options then + if UTF8CompareText(Name, ANode.Name) <> 0 then + exit; + + if xcNodeType in Options then + if ElementType <> ANode.ElementType then + exit; + + if xcNodeValue in Options then + if UTF8CompareText(ValueAsString, ANode.ValueAsString) <> 0 then + exit; + + // attribute count + if xcAttribCount in Options then + if AttributeCount <> ANode.AttributeCount then + exit; + + // attribute names and values + if (xcAttribNames in Options) or (xcAttribValues in Options) then + for i := 0 to AttributeCount - 1 do + begin + Index := ANode.AttributeIndexByName(AttributeName[i]); + if Index < 0 then + if xcAttribNames in Options then + exit + else + continue; + if xcAttribValues in Options then + if UTF8CompareText(AttributeValue[i], ANode.AttributeValue[Index]) <> 0 then + exit; + end; + + // child node count + if xcChildCount in Options then + if NodeCount <> ANode.NodeCount then + exit; + + // If we arrive here, it means no differences were found, return True + NodeResult := True; + + finally + + Result := ChildResult and NodeResult; + if (not NodeResult) and assigned(MismatchNodes) then + MismatchNodes.Insert(0, Self); + + end; +end; + +function TXmlNode.NodeAdd(ANode: TXmlNode): integer; +begin + if assigned(ANode) then + begin + ANode.Parent := Self; + ANode.ChangeDocument(Document); + if not assigned(FNodes) then + FNodes := TList.Create; + Result := FNodes.Add(ANode); + end else + Result := -1; +end; + +function TXmlNode.NodeByAttributeValue(const NodeName, AttribName, AttribValue: UTF8String; + ShouldRecurse: boolean): TXmlNode; +// This function returns a pointer to the first subnode that has an attribute with +// name AttribName and value AttribValue. +var + i: integer; + Node: TXmlNode; +begin + Result := nil; + // Find all nodes that are potential results + for i := 0 to NodeCount - 1 do + begin + Node := Nodes[i]; + if (UTF8CompareText(Node.Name, NodeName) = 0) and + Node.HasAttribute(AttribName) and + (UTF8CompareText(Node.AttributeByName[AttribName], AttribValue) = 0) then + begin + Result := Node; + exit; + end; + // Recursive call + if ShouldRecurse then + Result := Node.NodeByAttributeValue(NodeName, AttribName, AttribValue, True); + if assigned(Result) then + exit; + end; +end; + +function TXmlNode.NodeByElementType(ElementType: TXmlElementType): TXmlNode; +var + i: integer; +begin + Result := nil; + for i := 0 to NodeCount - 1 do + if Nodes[i].ElementType = ElementType then + begin + Result := Nodes[i]; + exit; + end; +end; + +function TXmlNode.NodeByName(const AName: UTF8String): TXmlNode; +var + i: integer; +begin + Result := nil; + for i := 0 to NodeCount - 1 do + if UTF8CompareText(Nodes[i].Name, AName) = 0 then + begin + Result := Nodes[i]; + exit; + end; +end; + +procedure TXmlNode.NodeDelete(Index: integer); +begin + if (Index >= 0) and (Index < NodeCount) then + begin + TXmlNode(FNodes[Index]).Free; + FNodes.Delete(Index); + end; +end; + +procedure TXmlNode.NodeExchange(Index1, Index2: integer); +begin + if (Index1 >= 0) and (Index1 < Nodecount) and + (Index2 >= 0) and (Index2 < Nodecount) then + FNodes.Exchange(Index1, Index2); +end; + +function TXmlNode.NodeExtract(ANode: TXmlNode): TXmlNode; +var + Index: integer; +begin + // Compatibility with Delphi4 + Result := nil; + if assigned(FNodes) then + begin + Index := FNodes.IndexOf(ANode); + if Index >= 0 then begin + Result := ANode; + FNodes.Delete(Index); + end; + end; +end; + +function TXmlNode.NodeFindOrCreate(const AName: UTF8String): TXmlNode; +// Find the node with AName, and if not found, add new one +begin + Result := NodeByName(AName); + if not assigned(Result) then + Result := NodeNew(AName); +end; + +function TXmlNode.NodeIndexByName(const AName: UTF8String): integer; +begin + Result := 0; + while Result < NodeCount do + begin + if UTF8CompareText(Nodes[Result].Name, AName) = 0 then + exit; + inc(Result); + end; + if Result = NodeCount then + Result := -1; +end; + +function TXmlNode.NodeIndexByNameFrom(const AName: UTF8String; AFrom: integer): integer; +begin + Result := AFrom; + while Result < NodeCount do + begin + if UTF8CompareText(Nodes[Result].Name, AName) = 0 then + exit; + inc(Result); + end; + if Result = NodeCount then + Result := -1; +end; + +function TXmlNode.NodeIndexOf(ANode: TXmlNode): integer; +begin + if assigned(ANode) and assigned(FNodes) then + Result := FNodes.IndexOf(ANode) + else + Result := -1; +end; + +procedure TXmlNode.NodeInsert(Index: integer; ANode: TXmlNode); +// Insert the node ANode at location Index in the list. +begin + if not assigned(ANode) then + exit; + if (Index >=0) and (Index <= NodeCount) then + begin + if not assigned(FNodes) then + FNodes := TList.Create; + ANode.Parent := Self; + FNodes.Insert(Index, ANode); + end; +end; + +function TXmlNode.NodeNew(const AName: UTF8String): TXmlNode; +// Add a new child node and return its pointer +begin + Result := Nodes[NodeAdd(TXmlNode.CreateName(Document, AName))]; +end; + +function TXmlNode.NodeNewAtIndex(Index: integer; const AName: UTF8String): TXmlNode; +// Create a new node with AName, and insert it into the subnode list at location +// Index, and return a pointer to it. +begin + if (Index >= 0) and (Index <= NodeCount) then + begin + Result := TXmlNode.CreateName(Document, AName); + NodeInsert(Index, Result); + end else + Result := nil; +end; + +function TXmlNode.NodeRemove(ANode: TxmlNode): integer; +begin + Result := NodeIndexOf(ANode); + if Result >= 0 then + NodeDelete(Result); +end; + +procedure TXmlNode.NodesByName(const AName: UTF8String; const AList: TList); +// Fill AList with nodes that have name AName +var + i: integer; +begin + if not assigned(AList) then + exit; + AList.Clear; + for i := 0 to NodeCount - 1 do + if UTF8CompareText(Nodes[i].Name, AName) = 0 then + AList.Add(Nodes[i]); +end; + +procedure TXmlNode.NodesClear; +var + i: integer; +begin + for i := 0 to NodeCount - 1 do + TXmlNode(FNodes[i]).Free; + FreeAndNil(FNodes); +end; + +procedure TXmlNode.ParseTag(const AValue: UTF8String; TagStart, TagClose: integer); +var + LItems: TsdUTF8StringList; +begin + // Create a list to hold string items + LItems := TsdUTF8StringList.Create; + try + sdUTF8ParseAttributes(AValue, TagStart, TagClose, LItems); + + // Determine name, attributes or value for each element type + case ElementType of + xeDeclaration: + FName := 'xml'; + xeStyleSheet: + begin + FName := 'xml-stylesheet'; + // We also set this as the value for use in "StyleSheetString" + ValueDirect := sdUTF8Trim(copy(AValue, TagStart, TagClose - TagStart)); + end; + else + // First item is the name - is it there? + if LItems.Count = 0 then + raise EFilerError.Create(sxeMissingElementName); + + // Set the name - using the element instead of property for speed + FName := LItems[0]; + LItems.Delete(0); + end;//case + + // Any attributes? + if LItems.Count > 0 then + begin + CheckCreateAttributesList; + FAttributes.Assign(LItems); + end; + + finally + LItems.Free; + end; +end; + +function TXmlNode.QualifyAsDirectNode: boolean; +// If this node qualifies as a direct node when writing, we return True. +// A direct node may have attributes, but no value or subnodes. Furhtermore, +// the root node will never be displayed as a direct node. +begin + Result := + (Length(FValue) = 0) and + (NodeCount = 0) and + (ElementType = xeNormal) and + not UseFullNodes and + (TreeDepth > 0); +end; + +function TXmlNode.ReadAttributeBool(const AName: UTF8String; ADefault: boolean): boolean; +var + V: UTF8String; +begin + Result := ADefault; + V := AttributeByName[AName]; + if Length(V) = 0 then + exit; + + try + Result := sdStringToBool(V); + except + Result := ADefault; + end; +end; + +function TXmlNode.ReadAttributeDateTime(const AName: UTF8String; ADefault: TDateTime): TDateTime; +var + V: UTF8String; +begin + Result := ADefault; + V := AttributeByName[AName]; + if Length(V) = 0 then + exit; + + try + Result := sdDateTimeFromStringDefault(V, ADefault, UseLocalBias); + except + Result := ADefault; + end; +end; + +function TXmlNode.ReadAttributeFloat(const AName: UTF8String; ADefault: double): double; +var + V: UTF8String; + Code: integer; +begin + V := AttributeByName[AName]; + val(string(sdUTF8StringReplace(V, ',', '.')), Result, Code); + if Code > 0 then + Result := ADefault; +end; + +function TXmlNode.ReadAttributeInteger(const AName: UTF8String; ADefault: integer): integer; +begin + Result := StrToIntDef(string(AttributeByName[AName]), ADefault); +end; + +function TXmlNode.ReadAttributeInt64(const AName: UTF8String; ADefault: int64): int64; +begin + Result := StrToInt64Def(string(AttributeByName[AName]), ADefault); +end; + +function TXmlNode.ReadAttributeString(const AName: UTF8String; const ADefault: UTF8String): UTF8String; +begin + Result := AttributeByName[AName]; + if length(Result) = 0 then + Result := ADefault; +end; + +function TXmlNode.ReadBool(const AName: UTF8String; ADefault: boolean): boolean; +var + Index: integer; +begin + Result := ADefault; + Index := NodeIndexByName(AName); + if Index >= 0 then + Result := Nodes[Index].ValueAsBoolDef(ADefault); +end; + +{$IFDEF USEGRAPHICS} +procedure TXmlNode.ReadBrush(const AName: UTF8String; ABrush: TBrush); +var + Child: TXmlNode; +begin + Child := NodeByName(AName); + if assigned(Child) then with Child do + begin + // Read values + ABrush.Color := ReadColor('Color', clWhite); + ABrush.Style := TBrushStyle(ReadInteger('Style', integer(bsSolid))); + end else + begin + // Defaults + ABrush.Bitmap := nil; + ABrush.Color := clWhite; + ABrush.Style := bsSolid; + end; +end; + +function TXmlNode.ReadColor(const AName: UTF8String; ADefault: TColor): TColor; +var + Index: integer; +begin + Result := ADefault; + Index := NodeIndexByName(AName); + if Index >= 0 then + Result := StrToInt(string(Nodes[Index].ValueAsString)); +end; +{$ENDIF} + +function TXmlNode.ReadDateTime(const AName: UTF8String; ADefault: TDateTime): TDateTime; +// Date MUST always be written in this format: +// YYYY-MM-DD (if just date) or +// YYYY-MM-DDThh:mm:ss.sssZ (if date and time. The Z stands for universal time +// zone. Since Delphi's TDateTime does not give us a clue about the timezone, +// this is the easiest solution) +// This format SHOULD NOT be changed, to avoid all kinds of +// conversion errors in future. +// This format is compatible with the W3C date/time specification as found here: +// http://www.w3.org/TR/NOTE-datetime +begin + Result := sdDateTimeFromStringDefault(ReadString(AName, ''), ADefault, UseLocalBias); +end; + +function TXmlNode.ReadFloat(const AName: UTF8String; ADefault: double): double; +var + Index: integer; +begin + Result := ADefault; + Index := NodeIndexByName(AName); + if Index >= 0 then + Result := Nodes[Index].ValueAsFloatDef(ADefault); +end; + +{$IFDEF USEGRAPHICS} +procedure TXmlNode.ReadFont(const AName: UTF8String; AFont: TFont); +var + Child: TXmlNode; +begin + Child := NodeByName(AName); + AFont.Style := []; + if assigned(Child) then with Child do + begin + // Read values + AFont.Name := string(ReadString('Name', 'Arial')); + AFont.Color := ReadColor('Color', clBlack); + AFont.Size := ReadInteger('Size', 14); + if ReadBool('Bold', False) then AFont.Style := AFont.Style + [fsBold]; + if ReadBool('Italic', False) then AFont.Style := AFont.Style + [fsItalic]; + if ReadBool('Underline', False) then AFont.Style := AFont.Style + [fsUnderline]; + if ReadBool('Strikeout', False) then AFont.Style := AFont.Style + [fsStrikeout]; + end else + begin + // Defaults + AFont.Name := 'Arial'; + AFont.Color := clBlack; + AFont.Size := 14; + end; +end; +{$ENDIF} + +procedure TXmlNode.ReadFromStream(S: TStream); +// Read the node from the starting "<" until the closing ">" from the stream in S. +// This procedure also calls OnNodeNew and OnNodeLoaded events +var + Ch: AnsiChar; + i: integer; + TagIndex: integer; + V: UTF8String; + Len: integer; + Node: TXmlNode; + NodeValue: UTF8String; + ValuePos, ValueLen: integer; + ClosePos: integer; + HasCR: boolean; + HasSubtags: boolean; + Words: TsdUTF8StringList; + IsDirect: boolean; + Reader: TsdSurplusReader; + // local + procedure AddCharDataNode(PreserveWhiteSpace: boolean); + var + V: UTF8String; + Node: TXmlNode; + L: integer; + begin + // Add all text up till now as xeCharData + if ValuePos > 0 then + begin + V := copy(NodeValue, 1, ValuePos); + + if PreserveWhiteSpace then + L := length(V) + else + L := length(sdUTF8Trim(V)); + + if L > 0 then + begin + Node := TXmlNode.CreateType(Document, xeCharData); + Node.ValueDirect := V; + NodeAdd(Node); + end; + ValuePos := 0; + end; + end; +// Main +begin + // Check if we aborted parsing + if AbortParsing then + exit; + // Clear this node first + Clear; + // Initial reserve textual value: just 80 AnsiCharacters which is OK for most short values + ValuePos := 0; + ValueLen := 80; + SetLength(NodeValue, ValueLen); + HasCR := False; + HasSubTags := False; + Reader := TsdSurplusReader.Create(S); + try + // Trailing blanks/controls AnsiChars? + if not Reader.ReadCharSkipBlanks(Ch) then + exit; + + // What is it? + if Ch = '<' then + begin + // A tag - which one? + TagIndex := ReadOpenTag(Reader); + if TagIndex >= 0 then + begin + try + ElementType := cTags[TagIndex].Style; + case ElementType of + xeNormal, xeDeclaration, xeStyleSheet: + begin + // These tags we will process + ReadStringFromStreamUntil(Reader, cTags[TagIndex].Close, V, True); + Len := length(V); + + // Is it a direct tag? + IsDirect := False; + if (ElementType = xeNormal) and (Len > 0) then + if V[Len] = '/' then + begin + dec(Len); + IsDirect := True; + end; + ParseTag(V, 1, Len + 1); + + // Here we know our name so good place to call OnNodeNew event + if assigned(Document) then + begin + Document.DoNodeNew(Self); + if AbortParsing then + exit; + end; + + // Now the tag can be a direct close - in that case we're finished + if IsDirect or (ElementType in [xeDeclaration, xeStyleSheet]) then + exit; + + // Process rest of tag + repeat + + // Read AnsiCharacter from stream + if S.Read(Ch, 1) <> 1 then + raise EFilerError.CreateFmt(sxeMissingCloseTag, [Name]); + + // Is there a subtag? + if Ch = '<' then + begin + if not Reader.ReadCharSkipBlanks(Ch) then + raise EFilerError.CreateFmt(sxeMissingDataAfterGreaterThan, [Name]); + if Ch = '/' then + begin + + // This seems our closing tag + if not ReadStringFromStreamUntil(Reader, '>', V, True) then + raise EFilerError.CreateFmt(sxeMissingLessThanInCloseTag, [Name]); + if UTF8CompareText(sdUTF8Trim(V), Name) <> 0 then + raise EFilerError.CreateFmt(sxeIncorrectCloseTag, [Name]); + V := ''; + break; + + end else + begin + + // Add all text up till now as xeCharData + AddCharDataNode(False); + + // Reset the HasCR flag if we add node, we only want to detect + // the CR after last subnode + HasCR := False; + + // This is a subtag... so create it and let it process + HasSubTags := True; + S.Seek(-2, soCurrent); + Node := TXmlNode.Create(Document); + NodeAdd(Node); + Node.ReadFromStream(S); + + // Check for dropping comments + if assigned(Document) and Document.DropCommentsOnParse and + (Node.ElementType = xeComment) then + NodeDelete(NodeIndexOf(Node)); + + end; + end else + begin + + // If we detect a CR we will set the flag. This will signal the fact + // that this XML file was saved with xfReadable + if Ch = #13 then + HasCR := True; + + // Add the AnsiCharacter to the node value buffer. + inc(ValuePos); + if ValuePos > ValueLen then + begin + inc(ValueLen, cNodeValueBuf); + SetLength(NodeValue, ValueLen); + end; + NodeValue[ValuePos] := Ch; + + end; + until False or AbortParsing; + + // Add all text up till now as xeText + AddCharDataNode(not HasSubtags); + + // Check AnsiCharData nodes, remove trailing CRLF + indentation if we + // were in xfReadable mode + if HasSubtags and HasCR then + begin + for i := 0 to NodeCount - 1 do + if Nodes[i].ElementType = xeCharData then + begin + ClosePos := length(Nodes[i].FValue); + while (ClosePos > 0) and (Nodes[i].FValue[ClosePos] in [#10, #13, ' ']) do + dec(ClosePos); + Nodes[i].FValue := copy(Nodes[i].FValue, 1, ClosePos); + end; + end; + + // If the first node is xeCharData we use it as ValueDirect + if NodeCount > 0 then + if Nodes[0].ElementType = xeCharData then + begin + ValueDirect := Nodes[0].ValueDirect; + NodeDelete(0); + end; + + end; + xeDocType: + begin + Name := 'DTD'; + if assigned(Document) then + begin + Document.DoNodeNew(Self); + if AbortParsing then + exit; + end; + // Parse DTD + if assigned(Document) then + Document.ParseDTD(Self, S); + end; + xeElement, xeAttList, xeEntity, xeNotation: + begin + // DTD elements + ReadStringFromStreamWithQuotes(S, cTags[TagIndex].Close, V); + Len := length(V); + Words := TsdUTF8StringList.Create; + try + sdUTF8ParseAttributes(V, 1, Len + 1, Words); + if Words.Count > 0 then + begin + Name := Words[0]; + Words.Delete(0); + end; + ValueDirect := sdUTF8Trim(Words.Text); + finally + Words.Free; + end; + if assigned(Document) then + begin + Document.DoNodeNew(Self); + if AbortParsing then + exit; + end; + end; + else + case ElementType of + xeComment: Name := 'Comment'; + xeCData: Name := 'CData'; + xeExclam: Name := 'Special'; + xeQuestion: Name := 'Special'; + else + Name := 'Unknown'; + end; //case + + // Here we know our name so good place to call OnNodeNew + if assigned(Document) then + begin + Document.DoNodeNew(Self); + if AbortParsing then + exit; + end; + + // In these cases just get all data up till the closing tag + ReadStringFromStreamUntil(Reader, cTags[TagIndex].Close, V, False); + ValueDirect := V; + end;//case + finally + // Call the OnNodeLoaded and OnProgress events + if assigned(Document) and not AbortParsing then + begin + Document.DoProgress(S.Position); + Document.DoNodeLoaded(Self); + end; + end; + end; + end; + finally + Reader.Free; + end; +end; + +procedure TXmlNode.ReadFromString(const AValue: UTF8String); +var + S: TStream; +begin + S := TsdUTF8StringStream.Create(AValue); + try + ReadFromStream(S); + finally + S.Free; + end; +end; + +function TXmlNode.ReadInt64(const AName: UTF8String; ADefault: int64): int64; +var + Index: integer; +begin + Result := ADefault; + Index := NodeIndexByName(AName); + if Index >= 0 then + Result := Nodes[Index].ValueAsInt64Def(ADefault); +end; + +function TXmlNode.ReadInteger(const AName: UTF8String; ADefault: integer): integer; +var + Index: integer; +begin + Result := ADefault; + Index := NodeIndexByName(AName); + if Index >= 0 then + Result := Nodes[Index].ValueAsIntegerDef(ADefault); +end; + +{$IFDEF USEGRAPHICS} +procedure TXmlNode.ReadPen(const AName: UTF8String; APen: TPen); +var + Child: TXmlNode; +begin + Child := NodeByName(AName); + if assigned(Child) then with Child do + begin + // Read values + APen.Color := ReadColor('Color', clBlack); + APen.Mode := TPenMode(ReadInteger('Mode', integer(pmCopy))); + APen.Style := TPenStyle(ReadInteger('Style', integer(psSolid))); + APen.Width := ReadInteger('Width', 1); + end else + begin + // Defaults + APen.Color := clBlack; + APen.Mode := pmCopy; + APen.Style := psSolid; + APen.Width := 1; + end; +end; +{$ENDIF} + +function TXmlNode.ReadString(const AName: UTF8String; const ADefault: UTF8String): UTF8String; +var + Index: integer; +begin + Result := ADefault; + Index := NodeIndexByName(AName); + if Index >= 0 then + Result := Nodes[Index].ValueAsString; +end; + +function TXmlNode.ReadUnicodeString(const AName: UTF8String; const ADefault: UnicodeString): UnicodeString; +begin + Result := ToUnicodeString(ReadString(AName, FromUnicodeString(ADefault))); +end; + +procedure TXmlNode.ResolveEntityReferences; +// Replace any entity references by the entities, and parse the new content if any + // local + function SplitReference(const AValue: UTF8String; var Text1, Text2: UTF8String): UTF8String; + var + P: integer; + begin + Result := ''; + P := UTF8Pos('&', AValue); + Text1 := ''; + Text2 := AValue; + if P = 0 then + exit; + Text1 := copy(AValue, 1, P - 1); + Text2 := copy(AValue, P + 1, length(AValue)); + P := UTF8Pos(';', Text2); + if P = 0 then + exit; + Result := copy(Text2, 1, P - 1); + Text2 := copy(Text2, P + 1, length(Text2)); + end; + // local + function ReplaceEntityReferenceByNodes(ARoot: TXmlNode; const AValue: UTF8String; var InsertPos: integer; var Text1, Text2: UTF8String): boolean; + var + Reference: UTF8String; + Entity: UTF8String; + Node: TXmlNode; + S: TStream; + begin + Result := False; + Reference := SplitReference(AValue, Text1, Text2); + if (length(Reference) = 0) or not assigned(Document) then + exit; + + // Lookup entity references + Entity := Document.EntityByName[Reference]; + + // Does the entity contain markup? + if (length(Entity) > 0) and (UTF8Pos('<', Entity) > 0) then + begin + S := TsdUTF8StringStream.Create(Entity); + try + while S.Position < S.Size do + begin + Node := TXmlNode.Create(Document); + Node.ReadFromStream(S); + if Node.IsEmpty then + Node.Free + else + begin + ARoot.NodeInsert(InsertPos, Node); + inc(InsertPos); + Result := True; + end; + end; + finally + S.Free; + end; + end; + end; +// main +var + i: integer; + InsertPos: integer; + Text1, Text2: UTF8String; + Node: TXmlNode; + V, Reference, Replace, Entity, First, Last: UTF8String; +begin + if length(FValue) > 0 then + begin + // Different behaviour for xeNormal and xeCharData + if ElementType = xeNormal then + begin + InsertPos := 0; + if ReplaceEntityReferenceByNodes(Self, FValue, InsertPos, Text1, Text2) then + begin + FValue := Text1; + if length(sdUTF8Trim(Text2)) > 0 then + begin + Node := TXmlNode.CreateType(Document, xeCharData); + Node.ValueDirect := Text2; + NodeInsert(InsertPos, Node); + end; + end; + end else if (ElementType = xeCharData) and assigned(Parent) then + begin + InsertPos := Parent.NodeIndexOf(Self); + if ReplaceEntityReferenceByNodes(Parent, FValue, InsertPos, Text1, Text2) then + begin + FValue := Text1; + if length(sdUTF8Trim(FValue)) = 0 then + FValue := ''; + if length(sdUTF8Trim(Text2)) > 0 then + begin + Node := TXmlNode.CreateType(Document, xeCharData); + Node.ValueDirect := Text2; + Parent.NodeInsert(InsertPos, Node); + end; + end; + end; + end; + + // Do attributes + for i := 0 to AttributeCount - 1 do + begin + Last := AttributeValue[i]; + V := ''; + repeat + Reference := SplitReference(Last, First, Last); + Replace := ''; + if length(Reference) > 0 then + begin + Entity := Document.EntityByName[Reference]; + if length(Entity) > 0 then + Replace := Entity + else + Replace := '&' + Reference + ';'; + end; + V := V + First + Replace; + until length(Reference) = 0; + V := V + Last; + AttributeValue[i] := V; + end; + + // Do childnodes too + i := 0; + while i < NodeCount do + begin + Nodes[i].ResolveEntityReferences; + inc(i); + end; + + // Check for empty AnsiCharData nodes + for i := NodeCount - 1 downto 0 do + if (Nodes[i].ElementType = xeCharData) and (length(Nodes[i].ValueDirect) = 0) then + NodeDelete(i); +end; + +procedure TXmlNode.SetAttributeByName(const AName, Value: UTF8String); +begin + CheckCreateAttributesList; + FAttributes.Values[AName] := sdUTF8QuotedString(sdUTF8EscapeString(Value)); +end; + +procedure TXmlNode.SetAttributeByNameWide(const AName: UTF8String; const Value: UnicodeString); +begin + SetAttributeByName(AName, FromUnicodeString(Value)); +end; + +procedure TXmlNode.SetAttributeName(Index: integer; const Value: UTF8String); +var + S: UTF8String; + P: integer; +begin + if (Index >= 0) and (Index < AttributeCount) then + begin + S := FAttributes[Index]; + P := Utf8Pos('=', S); + if P > 0 then + FAttributes[Index] := Value + '=' + Copy(S, P + 1, MaxInt); + end; +end; + +procedure TXmlNode.SetAttributeValue(Index: integer; const Value: UTF8String); +begin + if (Index >= 0) and (Index < AttributeCount) then + FAttributes[Index] := AttributeName[Index] + '=' + + sdUTF8QuotedString(sdUTF8EscapeString(Value)); +end; + +procedure TXmlNode.SetAttributeValueAsInteger(Index: integer; const Value: integer); +begin + SetAttributeValue(Index, IntToUTF8Str(Value)); +end; + +procedure TXmlNode.SetAttributeValueAsUnicodeString(Index: integer; + const Value: UnicodeString); +begin + SetAttributeValue(Index, FromUnicodeString(Value)); +end; + +procedure TXmlNode.SetAttributeValueDirect(Index: integer; const Value: UTF8String); +begin + if (Index >= 0) and (Index < AttributeCount) then + FAttributes[Index] := AttributeName[Index] + '=' + + sdUTF8QuotedString(Value); +end; + +procedure TXmlNode.SetBinaryEncoding(const Value: TBinaryEncodingType); +begin + if assigned(Document) then + Document.BinaryEncoding := Value; +end; + +procedure TXmlNode.SetBinaryString(const Value: RawByteString); +var + OldEncoding: TBinaryEncodingType; +begin + // Set to base64 + OldEncoding := BinaryEncoding; + try + BinaryEncoding := xbeBase64; + if length(Value) = 0 then + begin + ValueAsString := ''; + exit; + end; + // fill the buffer + {$IFDEF CLR} + BufferWrite(BytesOf(Value), length(Value)); + {$ELSE} + BufferWrite(Value[1], length(Value)); + {$ENDIF} + finally + BinaryEncoding := OldEncoding; + end; +end; + +procedure TXmlNode.SetName(const Value: UTF8String); +var + i: integer; +begin + if FName <> Value then + begin + // Check if the name abides the rules. We will be very forgiving here and + // just accept any name that at least does not contain control AnsiCharacters + for i := 1 to length(Value) do + if Value[i] in cControlChars then + raise Exception.Create(Format(sxeIllegalCharInNodeName, [Value])); + FName := Value; + end; +end; + +procedure TXmlNode.SetValueAsBool(const Value: boolean); +begin + FValue := sdStringFromBool(Value); +end; + +procedure TXmlNode.SetValueAsDateTime(const Value: TDateTime); +begin + ValueAsString := sdDateTimeToString(Value, UseLocalBias); +end; + +procedure TXmlNode.SetValueAsFloat(const Value: double); +begin + FValue := sdWriteNumber(Value, FloatSignificantDigits, FloatAllowScientific); +end; + +procedure TXmlNode.SetValueAsInt64(const Value: int64); +begin + FValue := Int64ToUTF8Str(Value); +end; + +procedure TXmlNode.SetValueAsInteger(const Value: integer); +begin + FValue := IntToUTF8Str(Value); +end; + +procedure TXmlNode.SetValueAsString(const AValue: UTF8String); +begin + FValue := sdUTF8EscapeString(AValue); +end; + +procedure TXmlNode.SetValueAsUnicodeString(const Value: UnicodeString); +begin + ValueAsString := FromUnicodeString(Value); +end; + +procedure TXmlNode.SortChildNodes(Compare: TXMLNodeCompareFunction; Info: TPointer); +// Sort the child nodes using the quicksort algorithm + //local + function DoNodeCompare(Node1, Node2: TXmlNode): integer; + begin + if assigned(Compare) then + Result := Compare(Node1, Node2, Info) + else + if assigned(Document) and assigned(Document.OnNodeCompare) then + Result := Document.OnNodeCompare(Document, Node1, Node2, Info) + else + Result := UTF8CompareText(Node1.Name, Node2.Name); + end; + // local + procedure QuickSort(iLo, iHi: Integer); + var + Lo, Hi, Mid: longint; + begin + Lo := iLo; + Hi := iHi; + Mid:= (Lo + Hi) div 2; + repeat + while DoNodeCompare(Nodes[Lo], Nodes[Mid]) < 0 do + Inc(Lo); + while DoNodeCompare(Nodes[Hi], Nodes[Mid]) > 0 do + Dec(Hi); + if Lo <= Hi then + begin + // Swap pointers; + NodeExchange(Lo, Hi); + if Mid = Lo then + Mid := Hi + else + if Mid = Hi then + Mid := Lo; + Inc(Lo); + Dec(Hi); + end; + until Lo > Hi; + if Hi > iLo then + QuickSort(iLo, Hi); + if Lo < iHi then + QuickSort(Lo, iHi); + end; +// main +begin + if NodeCount > 1 then + QuickSort(0, NodeCount - 1); +end; + +function TXmlNode.ToUnicodeString(const s: UTF8String): UnicodeString; +begin + Result := sdUtf8ToUnicode(s) +end; + +function TXmlNode.UnescapeString(const AValue: UTF8String): UTF8String; +begin + Result := sdUTF8UnEscapeString(AValue) +end; + +function TXmlNode.UseFullNodes: boolean; +begin + Result := False; + if assigned(Document) then + Result := Document.UseFullNodes; +end; + +function TXmlNode.UseLocalBias: Boolean; +begin + Result := False; + if Assigned(Document) then + Result := Document.UseLocalBias; +end; + +function TXmlNode.ValueAsBoolDef(ADefault: boolean): boolean; +var + Ch: AnsiChar; +begin + Result := ADefault; + if Length(FValue) = 0 then + exit; + Ch := sdUpCase(FValue[1]); + if Ch in ['T', 'Y'] then + begin + Result := True; + exit; + end; + if Ch in ['F', 'N'] then + begin + Result := False; + exit; + end; +end; + +function TXmlNode.ValueAsDateTimeDef(ADefault: TDateTime): TDateTime; +begin + Result := sdDateTimeFromStringDefault(ValueAsString, ADefault, UseLocalBias); +end; + +function TXmlNode.ValueAsFloatDef(ADefault: double): double; +var + Code: integer; +begin + try + val(string(sdUTF8StringReplace(FValue, ',', '.')), Result, Code); + if Code > 0 then + Result := ADefault; + except + Result := ADefault; + end; +end; + +function TXmlNode.ValueAsInt64Def(ADefault: int64): int64; +begin + Result := StrToInt64Def(string(FValue), ADefault); +end; + +function TXmlNode.ValueAsIntegerDef(ADefault: integer): integer; +begin + Result := StrToIntDef(string(FValue), ADefault); +end; + +procedure TXmlNode.WriteAttributeBool(const AName: UTF8String; AValue: boolean; ADefault: boolean); +var + Index: integer; +begin + if WriteOnDefault or (AValue <> ADefault) then + begin + Index := AttributeIndexByName(AName); + if Index >= 0 then + AttributeValue[Index] := sdStringFromBool(AValue) + else + AttributeAdd(AName, sdStringFromBool(AValue)); + end; +end; + +procedure TXmlNode.WriteAttributeDateTime(const AName: UTF8String; AValue, ADefault: TDateTime); +var + Index: integer; +begin + if WriteOnDefault or (AValue <> ADefault) then + begin + Index := AttributeIndexByName(AName); + if Index >= 0 then + AttributeValue[Index] := sdDateTimeToString(AValue, UseLocalBias) + else + AttributeAdd(AName, sdDateTimeToString(AValue, UseLocalBias)); + end; +end; + +procedure TXmlNode.WriteAttributeFloat(const AName: UTF8String; AValue, ADefault: double); +var + Index: integer; + S: UTF8String; +begin + if WriteOnDefault or (AValue <> ADefault) then + begin + Index := AttributeIndexByName(AName); + S := sdWriteNumber(AValue, FloatSignificantDigits, FloatAllowScientific); + if Index >= 0 then + AttributeValue[Index] := S + else + AttributeAdd(AName, S); + end; +end; + +procedure TXmlNode.WriteAttributeInteger(const AName: UTF8String; AValue: integer; ADefault: integer); +var + Index: integer; +begin + if WriteOnDefault or (AValue <> ADefault) then + begin + Index := AttributeIndexByName(AName); + if Index >= 0 then + AttributeValue[Index] := IntToUTF8Str(AValue) + else + AttributeAdd(AName, IntToUTF8Str(AValue)); + end; +end; + +procedure TXmlNode.WriteAttributeInt64(const AName: UTF8String; const AValue: int64; ADefault: int64); +var + Index: integer; +begin + if WriteOnDefault or (AValue <> ADefault) then + begin + Index := AttributeIndexByName(AName); + if Index >= 0 then + AttributeValue[Index] := IntToUTF8Str(AValue) + else + AttributeAdd(AName, IntToUTF8Str(AValue)); + end; +end; + +procedure TXmlNode.WriteAttributeString(const AName, AValue, ADefault: UTF8String); +var + Index: integer; +begin + if WriteOnDefault or (AValue <> ADefault) then + begin + Index := AttributeIndexByName(AName); + if Index >= 0 then + AttributeValue[Index] := AValue + else + AttributeAdd(AName, AValue); + end; +end; + +procedure TXmlNode.WriteBool(const AName: UTF8String; AValue: boolean; ADefault: boolean); +const + cBoolValues: array[boolean] of UTF8String = ('False', 'True'); +begin + if WriteOnDefault or (AValue <> ADefault) then + with NodeFindOrCreate(AName) do + ValueAsString := cBoolValues[AValue]; +end; + +{$IFDEF USEGRAPHICS} +procedure TXmlNode.WriteBrush(const AName: UTF8String; ABrush: TBrush); +begin + with NodeFindOrCreate(AName) do + begin + WriteColor('Color', ABrush.Color, clBlack); + WriteInteger('Style', integer(ABrush.Style), 0); + end; +end; + +procedure TXmlNode.WriteColor(const AName: UTF8String; AValue, ADefault: TColor); +begin + if WriteOnDefault or (AValue <> ADefault) then + WriteHex(AName, ColorToRGB(AValue), 8, 0); +end; +{$ENDIF} + +procedure TXmlNode.WriteDateTime(const AName: UTF8String; AValue, ADefault: TDateTime); +// Date MUST always be written in this format: +// YYYY-MM-DD (if just date) or +// YYYY-MM-DDThh:mm:ss.sssZ (if date and time. The Z stands for universal time +// zone. Since Delphi's TDateTime does not give us a clue about the timezone, +// this is the easiest solution) +// This format SHOULD NOT be changed, to avoid all kinds of +// conversion errors in future. +// This format is compatible with the W3C date/time specification as found here: +// http://www.w3.org/TR/NOTE-datetime +begin + if WriteOnDefault or (AValue <> ADefault) then + WriteString(AName, sdDateTimeToString(AValue, UseLocalBias), ''); +end; + +procedure TXmlNode.WriteFloat(const AName: UTF8String; AValue: double; ADefault: double); +begin + if WriteOnDefault or (AValue <> ADefault) then + with NodeFindOrCreate(AName) do + ValueAsString := sdWriteNumber(AValue, FloatSignificantDigits, FloatAllowScientific); +end; + +{$IFDEF USEGRAPHICS} +procedure TXmlNode.WriteFont(const AName: UTF8String; AFont: TFont); +begin + with NodeFindOrCreate(AName) do + begin + WriteString('Name', UTF8String(AFont.Name), 'Arial'); + WriteColor('Color', AFont.Color, clBlack); + WriteInteger('Size', AFont.Size, 14); + WriteBool('Bold', fsBold in AFont.Style, False); + WriteBool('Italic', fsItalic in AFont.Style, False); + WriteBool('Underline', fsUnderline in AFont.Style, False); + WriteBool('Strikeout', fsStrikeout in AFont.Style, False); + end; +end; +{$ENDIF} + +procedure TXmlNode.WriteHex(const AName: UTF8String; AValue, Digits: integer; ADefault: integer); +begin + if WriteOnDefault or (AValue <> ADefault) then + with NodeFindOrCreate(AName) do + ValueAsString := '$' + UTF8String(IntToHex(AValue, Digits)); +end; + +function TXmlNode.WriteInnerTag: UTF8String; +// Write the inner part of the tag, the one that contains the attributes +var + i: integer; +begin + Result := ''; + // Attributes + for i := 0 to AttributeCount - 1 do + // Here we used to prevent empty attributes, but in fact, empty attributes + // should be allowed because sometimes they're required + Result := Result + ' ' + AttributePair[i]; + // End of tag - direct nodes get an extra "/" + if QualifyAsDirectNode then + Result := Result + '/'; +end; + +procedure TXmlNode.WriteInt64(const AName: UTF8String; AValue, ADefault: int64); +begin + if WriteOnDefault or (AValue <> ADefault) then + with NodeFindOrCreate(AName) do + ValueAsString := IntToUTF8Str(AValue); +end; + +procedure TXmlNode.WriteInteger(const AName: UTF8String; AValue: integer; ADefault: integer); +begin + if WriteOnDefault or (AValue <> ADefault) then + with NodeFindOrCreate(AName) do + ValueAsString := IntToUTF8Str(AValue); +end; + +{$IFDEF USEGRAPHICS} +procedure TXmlNode.WritePen(const AName: UTF8String; APen: TPen); +begin + with NodeFindOrCreate(AName) do + begin + WriteColor('Color', APen.Color, clBlack); + WriteInteger('Mode', integer(APen.Mode), 0); + WriteInteger('Style', integer(APen.Style), 0); + WriteInteger('Width', APen.Width, 0); + end; +end; +{$ENDIF} + +procedure TXmlNode.WriteString(const AName, AValue: UTF8String; const ADefault: UTF8String); +begin + if WriteOnDefault or (AValue <> ADefault) then + with NodeFindOrCreate(AName) do + ValueAsString := AValue; +end; + +procedure TXmlNode.WriteToStream(S: TStream); +var + i: integer; + Indent: UTF8String; + LFeed: UTF8String; + Line: UTF8String; + ThisNode, NextNode: TXmlNode; + AddLineFeed: boolean; +begin + Indent := GetIndent; + LFeed := GetLineFeed; + + // Write indent + Line := Indent; + + // Write the node - distinguish node type + case ElementType of + xeDeclaration: // XML declaration + begin + // Explicitly delete empty attributes in the declaration, + // this is usually the encoding and we do not want encoding="" + // to show up + DeleteEmptyAttributes; + Line := Indent + ''; + end; + xeStylesheet: // Stylesheet + Line := Indent + ''; + xeDoctype: + begin + if NodeCount = 0 then + Line := Indent + '' + else + begin + Line := Indent + ''; + end; + end; + xeElement: + Line := Indent + ''; + xeAttList: + Line := Indent + ''; + xeEntity: + Line := Indent + ''; + xeNotation: + Line := Indent + ''; + xeComment: // Comment + Line := Indent + ''; + xeCData: // literal data + Line := Indent + ''; + xeExclam: // Any + Line := Indent + ''; + xeQuestion: // Any + Line := Indent + ''; + xeCharData: + Line := FValue; + xeUnknown: // Any + Line := Indent + '<' + ValueDirect + '>'; + xeNormal: // normal nodes (xeNormal) + begin + // Write tag + Line := Line + '<' + FName + WriteInnerTag + '>'; + + // Write value (if any) + Line := Line + FValue; + if (NodeCount > 0) then + // ..and a linefeed + Line := Line + LFeed; + + sdUTF8WriteStringToStream(S, Line); + + // Write child elements + for i := 0 to NodeCount - 1 do + begin + ThisNode := Nodes[i]; + NextNode := Nodes[i + 1]; + ThisNode.WriteToStream(S); + AddLineFeed := True; + if ThisNode.ElementType = xeCharData then + AddLineFeed := False; + if assigned(NextNode) then + if NextNode.ElementType = xeCharData then + AddLineFeed := False; + if AddLineFeed then + sdUTF8WriteStringToStream(S, LFeed); + end; + + // Write end tag + Line := ''; + if not QualifyAsDirectNode then + begin + if NodeCount > 0 then + Line := Indent; + Line := Line + ''; + end; + end; + else + raise EFilerError.Create(sxeIllegalElementType); + end;//case + sdUTF8WriteStringToStream(S, Line); + + // Call the onprogress + if assigned(Document) then + Document.DoProgress(S.Position); +end; + +function TXmlNode.WriteToString: UTF8String; +var + S: TsdUTF8StringStream; +begin + // We will simply call WriteToStream and collect the result as UTF8String using + // a string stream + S := TsdUTF8StringStream.Create(''); + try + WriteToStream(S); + Result := S.DataString; + finally + S.Free; + end; +end; + +procedure TXmlNode.WriteUnicodeString(const AName: UTF8String; + const AValue: UnicodeString; const ADefault: UnicodeString); +begin + WriteString(AName, FromUnicodeString(AValue), FromUnicodeString(ADefault)); +end; + +{ TXmlNodeList } + +function TXmlNodeList.ByAttribute(const AName, AValue: UTF8String): TXmlNode; +var + i: integer; +begin + for i := 0 to Count - 1 do + if UTF8CompareText(Items[i].AttributeByName[AName], AValue) = 0 then + begin + Result := Items[i]; + exit; + end; + Result := nil; +end; + +function TXmlNodeList.GetItems(Index: Integer): TXmlNode; +begin + Result := TXmlNode(Get(Index)); +end; + +procedure TXmlNodeList.SetItems(Index: Integer; const Value: TXmlNode); +begin + Put(Index, TPointer(Value)); +end; + +{ TNativeXml } + +procedure TNativeXml.Assign(Source: TPersistent); + // local + procedure SetDocumentRecursively(ANode: TXmlNode; ADocument: TNativeXml); + var + i: integer; + begin + ANode.Document := ADocument; + for i := 0 to ANode.NodeCount - 1 do + SetDocumentRecursively(ANode.Nodes[i], ADocument); + end; +// main +begin + if Source is TNativeXml then + begin + // Copy private members + FBinaryEncoding := TNativeXml(Source).FBinaryEncoding; + FDropCommentsOnParse := TNativeXml(Source).FDropCommentsOnParse; + FExternalEncoding := TNativeXml(Source).FExternalEncoding; + FParserWarnings := TNativeXml(Source).FParserWarnings; + FIndentString := TNativeXml(Source).FIndentString; + FUseFullNodes := TNativeXml(Source).FUseFullNodes; + FUseLocalBias := TNativeXml(Source).FUseLocalBias; + FWriteOnDefault := TNativeXml(Source).FWriteOnDefault; + FXmlFormat := TNativeXml(Source).FXmlFormat; + // Assign root + FRootNodes.Assign(TNativeXml(Source).FRootNodes); + // Set Document property recursively + SetDocumentRecursively(FRootNodes, Self); + end else + if Source is TXmlNode then + begin + // Assign this node to the FRootNodes property + FRootNodes.Assign(Source); + // Set Document property recursively + SetDocumentRecursively(FRootNodes, Self); + end else + inherited; +end; + +procedure TNativeXml.Clear; +var + Node: TXmlNode; +begin + // Reset defaults + SetDefaults; + // Clear root + FRootNodes.Clear; + // Build default items in RootNodes + // - first the declaration + Node := TXmlNode.CreateType(Self, xeDeclaration); + Node.Name := 'xml'; + Node.AttributeAdd('version', cDefaultVersionString); + Node.AttributeAdd('encoding', cDefaultEncodingString); + FRootNodes.NodeAdd(Node); + // - then the root node + FRootNodes.NodeNew(''); +end; + +procedure TNativeXml.CopyFrom(Source: TNativeXml); +begin + if not assigned(Source) then + exit; + Assign(Source); +end; + +constructor TNativeXml.Create; +begin + inherited Create; + FRootNodes := TXmlNode.Create(Self); + Clear; +end; + +constructor TNativeXml.CreateName(const ARootName: UTF8String); +begin + Create; + Root.Name := ARootName; +end; + +destructor TNativeXml.Destroy; +begin + FreeAndNil(FRootNodes); + inherited; +end; + +procedure TNativeXml.DoNodeLoaded(Node: TXmlNode); +begin + if assigned(FOnNodeLoaded) then + FOnNodeLoaded(Self, Node); +end; + +procedure TNativeXml.DoNodeNew(Node: TXmlNode); +begin + if assigned(FOnNodeNew) then + FOnNodeNew(Self, Node); +end; + +procedure TNativeXml.DoProgress(Size: integer); +begin + if assigned(FOnProgress) then + FOnProgress(Self, Size); +end; + +procedure TNativeXml.DoUnicodeLoss(Sender: TObject); +begin + if assigned(FOnUnicodeLoss) then + FOnUnicodeLoss(Self); +end; + +function TNativeXml.GetCommentString: UTF8String; +// Get the first comment node, and return its value +var + Node: TXmlNode; +begin + Result := ''; + Node := FRootNodes.NodeByElementType(xeComment); + if assigned(Node) then + Result := Node.ValueAsString; +end; + +function TNativeXml.GetEncodingString: UTF8String; +begin + Result := ''; + if FRootNodes.NodeCount > 0 then + if FRootNodes[0].ElementType = xeDeclaration then + Result := FRootNodes[0].AttributeByName['encoding']; +end; + +function TNativeXml.GetEntityByName(AName: UTF8String): UTF8String; +var + i, j: integer; +begin + Result := ''; + for i := 0 to FRootNodes.NodeCount - 1 do + if FRootNodes[i].ElementType = xeDoctype then with FRootNodes[i] do + begin + for j := 0 to NodeCount - 1 do + if (Nodes[j].ElementType = xeEntity) and (Nodes[j].Name = AName) then + begin + Result := sdUTF8UnQuotedString(sdUTF8Trim(Nodes[j].ValueDirect)); + exit; + end; + end; +end; + +function TNativeXml.GetRoot: TXmlNode; +begin + Result := FRootNodes.NodeByElementType(xeNormal); +end; + +function TNativeXml.GetStyleSheetNode: TXmlNode; +begin + Result := FRootNodes.NodeByElementType(xeStylesheet); + if not assigned(Result) then + begin + // Add a stylesheet node as second one if none present + Result := TXmlNode.CreateType(Self, xeStyleSheet); + FRootNodes.NodeInsert(1, Result); + end; +end; + +function TNativeXml.GetUtf8Encoded: boolean; +begin + Result := True; +end; + +function TNativeXml.GetVersionString: UTF8String; +begin + Result := ''; + if FRootNodes.NodeCount > 0 then + if FRootNodes[0].ElementType = xeDeclaration then + Result := FRootNodes[0].AttributeByName['version']; +end; + +function TNativeXml.IsEmpty: boolean; +var + R: TXmlNode; +begin + Result := True; + R := GetRoot; + if assigned(R) then + Result := R.IsClear; +end; + +function TNativeXml.LineFeed: UTF8String; +begin + case XmlFormat of + xfReadable: + Result := #13#10; + xfCompact: + Result := #10; + else + Result := #10; + end;//case +end; + +procedure TNativeXml.LoadFromFile(const AFileName: string); +var + S: TStream; +begin + S := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite); + try + LoadFromStream(S); + finally + S.Free; + end; +end; + +procedure TNativeXml.LoadFromStream(Stream: TStream); +var + B: TsdBufferedReadStream; +begin + // Create buffer filter. Since we read from the original stream a buffer at a + // time, this speeds up the reading process for disk-based files. + B := TsdBufferedReadStream.Create(Stream, False); + try + // We will create a conversion stream as intermediate + FCodecStream := TsdUtf8Stream.Create(B); + try + // Connect events + FCodecStream.OnUnicodeLoss := DoUnicodeLoss; + // Read from stream + ReadFromStream(FCodecStream); + // Set our external encoding + FExternalEncoding := FCodecStream.Encoding; + finally + FreeAndNil(FCodecStream); + end; + finally + B.Free; + end; +end; + +procedure TNativeXml.ParseDTD(ANode: TXmlNode; S: TStream); +// DTD parsing is quite different from normal node parsing so it is brought +// under in the main NativeXml object + // local + procedure ParseMarkupDeclarations; + var + Ch: AnsiChar; + begin + repeat + ANode.NodeNew('').ReadFromStream(S); + // Read AnsiCharacter, exit if none available + repeat + if S.Read(Ch, 1) = 0 then + exit; + // Read until end markup declaration or end + until not (Ch in cControlChars); + if Ch = ']' then + break; + S.Seek(-1, soCurrent); + until False; + end; +// main +var + Prework: UTF8String; + Ch: AnsiChar; + Words: TsdUTF8StringList; +begin + // Get the name and external ID + Prework := ''; + repeat + // Read AnsiCharacter, exit if none available + if S.Read(Ch, 1) = 0 then + exit; + // Read until markup declaration or end + if Ch in ['[', '>'] then + break; + Prework := Prework + UTF8String(Ch); + until False; + Words := TsdUTF8StringList.Create; + try + sdUTF8ParseAttributes(Prework, 1, length(Prework) + 1, Words); + // First word is name + if Words.Count > 0 then + begin + ANode.Name := Words[0]; + Words.Delete(0); + // Put the rest in the valuedirect + ANode.ValueDirect := sdUTF8Trim(sdUTF8StringReplace(Words.Text, #13#10, ' ')); + end; + finally + Words.Free; + end; + + if Ch = '[' then + begin + + // Parse any !ENTITY nodes and such + ParseMarkupDeclarations; + + // read final tag + repeat + if S.Read(Ch, 1) = 0 then + exit; + if Ch = '>' then + break; + until False; + + end; +end; + +procedure TNativeXml.ReadFromStream(S: TStream); +var + i: integer; + Node: TXmlNode; + Enc: UTF8String; + NormalCount, DeclarationCount, + DoctypeCount, CDataCount: integer; + NormalPos, DoctypePos: integer; +begin + FAbortParsing := False; + with FRootNodes do + begin + // Clear the old root nodes - we do not reset the defaults + Clear; + DoProgress(0); + repeat + Node := NodeNew(''); + Node.ReadFromStream(S); + if AbortParsing then + exit; + + // XML declaration + if Node.ElementType = xeDeclaration then + begin + if Node.HasAttribute('encoding') then + Enc := Node.AttributeByName['encoding'] + else + FCodecStream.Encoding := seUTF8; + // Check encoding + if assigned(FCodecStream) and (AnsiUpperCase(string(Enc)) = 'UTF-8') then + FCodecStream.Encoding := seUTF8; + end; + // Skip clear nodes + if Node.IsClear then + NodeDelete(NodeCount - 1); + until S.Position >= S.Size; + DoProgress(S.Size); + + // Do some checks + NormalCount := 0; + DeclarationCount := 0; + DoctypeCount := 0; + CDataCount := 0; + NormalPos := -1; + DoctypePos := -1; + for i := 0 to NodeCount - 1 do + begin + // Count normal elements - there may be only one + case Nodes[i].ElementType of + xeNormal: + begin + inc(NormalCount); + NormalPos := i; + end; + xeDeclaration: inc(DeclarationCount); + xeDoctype: + begin + inc(DoctypeCount); + DoctypePos := i; + end; + xeCData: inc(CDataCount); + end;//case + end; + + // We *must* have a root node + if NormalCount = 0 then + raise EFilerError.Create(sxeNoRootElement); + + // Do some validation if we allow parser warnings + if FParserWarnings then + begin + + // Check for more than one root node + if NormalCount > 1 then + raise EFilerError.Create(sxeMoreThanOneRootElement); + + // Check for more than one xml declaration + if DeclarationCount > 1 then + raise EFilerError.Create(sxeMoreThanOneDeclaration); + + // Declaration must be first element if present + if DeclarationCount = 1 then + if Nodes[0].ElementType <> xeDeclaration then + raise EFilerError.Create(sxeDeclarationMustBeFirstElem); + + // Check for more than one DTD + if DoctypeCount > 1 then + raise EFilerError.Create(sxeMoreThanOneDoctype); + + // Check if DTD is after root, this is not allowed + if (DoctypeCount = 1) and (DoctypePos > NormalPos) then + raise EFilerError.Create(sxeDoctypeAfterRootElement); + + // No CDATA in root allowed + if CDataCount > 0 then + raise EFilerError.Create(sxeCDataInRoot); + end; + end;//with +end; + +procedure TNativeXml.ReadFromString(const AValue: UTF8String); +var + S: TStream; +begin + S := TsdUTF8StringStream.Create(AValue); + try + ReadFromStream(S); + finally + S.Free; + end; +end; + +procedure TNativeXml.ResolveEntityReferences; +begin + if assigned(Root) then + Root.ResolveEntityReferences; +end; + +procedure TNativeXml.SaveToFile(const AFileName: string); +var + S: TStream; +begin + S := TFileStream.Create(AFileName, fmCreate); + try + SaveToStream(S); + finally + S.Free; + end; +end; + +procedure TNativeXml.SaveToStream(Stream: TStream); +var + B: TsdBufferedWriteStream; +begin + // Create buffer filter. Since we write a buffer at a time to the destination + // stream, this speeds up the writing process for disk-based files. + B := TsdBufferedWriteStream.Create(Stream, False); + try + // Create conversion stream + FCodecStream := TsdUtf8Stream.Create(B); + try + // Set External encoding + FCodecStream.Encoding := FExternalEncoding; + WriteToStream(FCodecStream); + finally + FreeAndNil(FCodecStream); + end; + finally + B.Free; + end; +end; + +procedure TNativeXml.SetCommentString(const Value: UTF8String); +// Find first comment node and set it's value, otherwise add new comment node +// right below the xml declaration +var + Node: TXmlNode; +begin + Node := FRootNodes.NodeByElementType(xeComment); + if not assigned(Node) and (length(Value) > 0) then + begin + Node := TXmlNode.CreateType(Self, xeComment); + FRootNodes.NodeInsert(1, Node); + end; + if assigned(Node) then + Node.ValueAsString := Value; +end; + +procedure TNativeXml.SetDefaults; +begin + // Defaults + FExternalEncoding := cDefaultExternalEncoding; + FXmlFormat := cDefaultXmlFormat; + FWriteOnDefault := cDefaultWriteOnDefault; + FBinaryEncoding := cDefaultBinaryEncoding; + FIndentString := cDefaultIndentString; + FDropCommentsOnParse := cDefaultDropCommentsOnParse; + FUseFullNodes := cDefaultUseFullNodes; + FUseLocalBias := cDefaultUseLocalBias; + FFloatAllowScientific := cDefaultFloatAllowScientific; + FFloatSignificantDigits := cDefaultFloatSignificantDigits; + FOnNodeNew := nil; + FOnNodeLoaded := nil; +end; + +procedure TNativeXml.SetEncodingString(const Value: UTF8String); +var + Node: TXmlNode; +begin + if Value = GetEncodingString then + exit; + Node := FRootNodes[0]; + if not assigned(Node) or (Node.ElementType <> xeDeclaration) then + begin + Node := TXmlNode.CreateType(Self, xeDeclaration); + FRootNodes.NodeInsert(0, Node); + end; + if assigned(Node) then + Node.AttributeByName['encoding'] := Value; +end; + +procedure TNativeXml.SetVersionString(const Value: UTF8String); +var + Node: TXmlNode; +begin + if Value = GetVersionString then + exit; + Node := FRootNodes[0]; + if not assigned(Node) or (Node.ElementType <> xeDeclaration) then + begin + if length(Value) > 0 then + begin + Node := TXmlNode.CreateType(Self, xeDeclaration); + FRootNodes.NodeInsert(0, Node); + end; + end; + if assigned(Node) then + Node.AttributeByName['version'] := Value; +end; + +procedure TNativeXml.WriteToStream(S: TStream); +var + i: integer; +begin + if not assigned(Root) and FParserWarnings then + raise EFilerError.Create(sxeRootElementNotDefined); + + DoProgress(0); + + // write the root nodes + for i := 0 to FRootNodes.NodeCount - 1 do + begin + FRootNodes[i].WriteToStream(S); + sdUTF8WriteStringToStream(S, LineFeed); + end; + + DoProgress(S.Size); +end; + +function TNativeXml.WriteToString: UTF8String; +var + S: TsdUTF8StringStream; +begin + S := TsdUTF8StringStream.Create(''); + try + WriteToStream(S); + Result := S.DataString; + finally + S.Free; + end; +end; + +{ TsdCodecStream } + +constructor TsdCodecStream.Create(AStream: TStream); +begin + inherited Create; + FStream := AStream; +end; + +function TsdCodecStream.InternalRead(var Buffer{$IFDEF CLR}: array of Byte{$ENDIF}; Offset, Count: Longint): Longint; +// Read from FStream and pass back data +var + i, j: integer; + BOM: array[0..3] of byte; + BytesRead: integer; + Found: boolean; +begin + Result := 0; + if FMode = umUnknown then + begin + FMode := umRead; + // Check FStream + if not assigned(FStream) then + raise EStreamError.Create(sxeCodecStreamNotAssigned); + + // Determine encoding + FEncoding := seAnsi; + BytesRead := FStream.Read(BOM, 4); + for i := 0 to cBomInfoCount - 1 do + begin + Found := True; + for j := 0 to Min(BytesRead, cBomInfo[i].Len) - 1 do + begin + if BOM[j] <> cBomInfo[i].BOM[j] then + begin + Found := False; + break; + end; + end; + if Found then + break; + end; + if Found then + begin + FEncoding := cBomInfo[i].Encoding; + FWriteBom := cBomInfo[i].HasBOM; + end else + begin + // Unknown.. default to this + FEncoding := seAnsi; + FWriteBom := False; + end; + + // Some encodings are not supported (yet) + if FEncoding in [seUCS4BE, seUCS4_2143, seUCS4_3412, seEBCDIC] then + raise EStreamError.Create(sxeUnsupportedEncoding); + + // Correct stream to start position + if FWriteBom then + FStream.Seek(cBomInfo[i].Len - BytesRead, soCurrent) + else + FStream.Seek(-BytesRead, soCurrent); + + // Check if we must swap byte order + if FEncoding in [se16BitBE, seUTF16BE] then + FSwapByteOrder := True; + + end; + + // Check mode + if FMode <> umRead then + raise EStreamError.Create(sxeCannotReadCodecForWriting); + + // Check count + if Count <> 1 then + raise EStreamError.Create(sxeCannotReadMultipeChar); + + // Now finally read + TBytes(Buffer)[Offset] := ReadByte; + if TBytes(Buffer)[Offset] <> 0 then Result := 1; +end; + +{$IFDEF CLR} + +function TsdCodecStream.Read(var Buffer: array of Byte; Offset, Count: Longint): Longint; +begin + Result := InternalRead(Buffer, Offset, Count); +end; + +{$ELSE} + +function TsdCodecStream.Read(var Buffer; Count: Longint): Longint; +begin + Result := InternalRead(Buffer, 0, Count); +end; + +{$ENDIF} + +function TsdCodecStream.ReadByte: byte; +begin + // default does nothing + Result := 0; +end; + +function TsdCodecStream.InternalSeek(Offset: Longint; Origin: TSeekOrigin): Longint; +begin + Result := 0; + if FMode = umUnknown then + raise EStreamError.Create(sxeCannotSeekBeforeReadWrite); + + if Origin = soCurrent then + begin + if Offset = 0 then + begin + // Position + Result := FStream.Position; + exit; + end; + if (FMode = umRead) and ((Offset = -1) or (Offset = -2)) then + begin + FBuffer := ''; + case Offset of + -1: FStream.Seek(FPosMin1, soBeginning); + -2: FStream.Seek(FPosMin2, soBeginning); + end;//case + exit; + end; + end; + if (Origin = soEnd) and (Offset = 0) then + begin + // Size + Result := FStream.Size; + exit; + end; + // Ignore set position from beginning (used in Size command) + if Origin = soBeginning then + exit; + // Arriving here means we cannot do it + raise EStreamError.Create(sxeCannotPerformSeek); +end; + +{$IFDEF CLR} + +function TsdCodecStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + Result := InternalSeek(Offset, Origin); +end; + +{$ELSE} + +function TsdCodecStream.Seek(Offset: Longint; Origin: Word): Longint; +begin + Result := InternalSeek(Offset, TSeekOrigin(Origin)); +end; + +{$ENDIF} + +procedure TsdCodecStream.StorePrevPositions; +begin + FPosMin2 := FPosMin1; + FPosMin1 := FStream.Position; +end; + +function TsdCodecStream.InternalWrite(const Buffer{$IFDEF CLR}: array of Byte{$ENDIF}; Offset, Count: Longint): Longint; +var + i: integer; +begin + if FMode = umUnknown then + begin + FMode := umWrite; + + // Some encodings are not supported (yet) + if FEncoding in [seUCS4BE, seUCS4_2143, seUCS4_3412, seEBCDIC] then + raise EStreamError.Create(sxeUnsupportedEncoding); + + // Find correct encoding info + for i := 0 to cBomInfoCount - 1 do + if cBomInfo[i].Encoding = FEncoding then + begin + // we do not write BOM if UTF8 since UTF8 is default + FWriteBom := cBomInfo[i].HasBOM and (FEncoding <> seUTF8); + break; + end; + + // Write BOM + if FWriteBom then + FStream.WriteBuffer(cBomInfo[i].BOM, cBomInfo[i].Len); + + // Check if we must swap byte order + if FEncoding in [se16BitBE, seUTF16BE] then + FSwapByteOrder := True; + end; + + if FMode <> umWrite then + raise EStreamError.Create(sxeCannotWriteCodecForReading); + WriteBuf(Buffer, Offset, Count); + Result := Count; +end; + +{$IFDEF CLR} + +function TsdCodecStream.Write(const Buffer: array of Byte; Offset, Count: Longint): Longint; +begin + Result := InternalWrite(Buffer, Offset, Count); +end; + +{$ELSE} + +function TsdCodecStream.Write(const Buffer; Count: Longint): Longint; +begin + Result := InternalWrite(Byte(Buffer), 0, Count); +end; + +{$ENDIF} + +procedure TsdCodecStream.WriteBuf(const Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Offset, Count: longint); +var + i: integer; +begin + // Default just writes out bytes one by one. We override this in descendants + // to provide faster writes for some modes + for i := 0 to Count - 1 do + {$IFDEF CLR} + WriteByte(Buffer[Offset + i]); + {$ELSE} + WriteByte(TBytes(Buffer)[Offset + i]); + {$ENDIF} +end; + +procedure TsdCodecStream.WriteByte(const B: byte); +begin +// default does nothing +end; + +{$IFDEF CLR} + +procedure TsdCodecStream.SetSize(NewSize: Int64); +begin +// default does nothing +end; + +{$ENDIF} + +{ TsdUtf8Stream } + +function TsdUtf8Stream.ReadByte: byte; +var + B, B1, B2, B3: byte; + W: word; + SA: AnsiString; +begin + Result := 0; + + // New AnsiCharacter? + if (Length(FBuffer) = 0) or (FBufferPos > length(FBuffer)) then + begin + StorePrevPositions; + FBufferPos := 1; + // Read another AnsiChar and put in buffer + case FEncoding of + seAnsi: + begin + // read one byte + B := 0; + FStream.Read(B, 1); + SA := AnsiChar(B); + // Convert to UTF8 + FBuffer := sdAnsiToUtf8(SA); + end; + seUTF8: + begin + // Read one, two or three bytes in the buffer + B1 := 0; + FStream.Read(B1, 1); + FBuffer := AnsiChar(B1); + if (B1 and $80) > 0 then + begin + if (B1 and $20) <> 0 then + begin + B2 := 0; + FStream.Read(B2, 1); + FBuffer := FBuffer + UTF8String(AnsiChar(B2)); + end; + B3 := 0; + FStream.Read(B3, 1); + FBuffer := FBuffer + UTF8String(AnsiChar(B3)); + end; + end; + se16BitBE, se16BitLE, seUTF16BE, seUTF16LE: + begin + // Read two bytes + W := 0; + FStream.Read(W, 2); + // Swap byte order + if FSwapByteOrder then + W := swap(W); + // Convert to UTF8 in buffer + FBuffer := sdUnicodeToUtf8(UnicodeChar(W)); + end; + else + raise EStreamError.Create(sxeUnsupportedEncoding); + end;//case + end; + + // Now we have the buffer, so read + if (FBufferPos > 0) and (FBufferPos <= length(FBuffer)) then + Result := byte(FBuffer[FBufferPos]); + inc(FBufferPos); +end; + +procedure TsdUtf8Stream.WriteBuf(const Buffer{$IFDEF CLR}: TBytes{$ENDIF}; Offset, Count: longint); +begin + case FEncoding of + seUtf8: + begin + // one on one + if StreamWrite(FStream, Buffer, Offset, Count) <> Count then + raise EStreamError.Create(sxeCannotWriteToOutputStream); + end + else + inherited; + end;//case +end; + +procedure TsdUtf8Stream.WriteByte(const B: byte); +var + SA: AnsiString; + SW: UnicodeString; + MustWrite: boolean; +begin + case FEncoding of + seAnsi, se16BitBE, se16BitLE, seUTF16BE, seUTF16LE: + begin + MustWrite := True; + case Length(FBuffer) of + 0: + begin + FBuffer := AnsiChar(B); + if (B and $80) <> 0 then + MustWrite := False; + end; + 1: + begin + FBuffer := FBuffer + UTF8String(AnsiChar(B)); + if (byte(FBuffer[1]) and $20) <> 0 then + MustWrite := False; + end; + 2: FBuffer := FBuffer + UTF8String(AnsiChar(B)); + end; + if MustWrite then + begin + if FEncoding = seAnsi then + begin + // Convert to ansi + SA := sdUtf8ToAnsi(FBuffer); + // write out + if length(SA) = 1 then + if FStream.Write(SA[1], 1) <> 1 then + raise EStreamError.Create(sxeCannotWriteToOutputStream); + end else + begin + // Convert to unicode + SW := sdUtf8ToUnicode(FBuffer); + // write out + if length(SW) = 1 then + if FStream.Write(SW[1], 2) <> 2 then + raise EStreamError.Create(sxeCannotWriteToOutputStream); + end; + FBuffer := ''; + end; + end; + seUTF8: + begin + // Just a flat write of one byte + if FStream.Write(B, 1) <> 1 then + raise EStreamError.Create(sxeCannotWriteToOutputStream); + end; + else + raise EStreamError.Create(sxeUnsupportedEncoding); + end;//case +end; + +{$IFDEF CLR} +{ TsdBufferedStream } + +constructor TsdBufferedStream.Create(AStream: TStream; Owned: Boolean = False); +begin + inherited Create; + FStream := AStream; + FOwned := Owned; +end; + +destructor TsdBufferedStream.Destroy; +begin + if FOwned then FreeAndNil(FStream); + inherited Destroy; +end; + +function TsdBufferedStream.Read(var Buffer: array of Byte; Offset, Count: Longint): Longint; +begin + Result := FStream.Read(Buffer, Offset, Count); +end; + +function TsdBufferedStream.Write(const Buffer: array of Byte; Offset, Count: Longint): Longint; +begin + Result := FStream.Write(Buffer, Offset, Count); +end; + +function TsdBufferedStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + Result := FStream.Seek(Offset, Origin); +end; + +procedure TsdBufferedStream.SetSize(NewSize: Int64); +begin + FStream.Size := NewSize; +end; + +{$ELSE} + +{ TsdBufferedReadStream } + +const + cMaxBufferSize = $10000; // 65536 bytes in the buffer + +procedure TsdBufferedReadStream.CheckPosition; +var + NewPage: integer; + FStartPos: longint; +begin + // Page and buffer position + NewPage := FPosition div cMaxBufferSize; + FBufPos := FPosition mod cMaxBufferSize; + + // Read new page if required + if (NewPage <> FPage) then + begin + // New page and buffer + FPage := NewPage; + + // Start position in stream + FStartPos := FPage * cMaxBufferSize; + FBufSize := Min(cMaxBufferSize, FStream.Size - FStartPos); + + FStream.Seek(FStartPos, soBeginning); + if FBufSize > 0 then + FStream.Read(FBuffer^, FBufSize); + end; + FMustCheck := False; +end; + +constructor TsdBufferedReadStream.Create(AStream: TStream; Owned: boolean); +begin + inherited Create; + FStream := AStream; + FOwned := Owned; + FMustCheck := True; + FPage := -1; // Set to invalid number to force an update on first read + ReallocMem(FBuffer, cMaxBufferSize); +end; + +destructor TsdBufferedReadStream.Destroy; +begin + if FOwned then FreeAndNil(FStream); + ReallocMem(FBuffer, 0); + inherited; +end; + +function TsdBufferedReadStream.Read(var Buffer; Count: longint): Longint; +var + Packet: PByte; + PacketCount: integer; +begin + // Set the right page + if FMustCheck then + CheckPosition; + + // Special case - read one byte, most often + if (Count = 1) and (FBufPos < FBufSize - 1) then + begin + byte(Buffer) := FBuffer^[FBufPos]; + inc(FBufPos); + inc(FPosition); + Result := 1; + exit; + end; + + // general case + Packet := @Buffer; + Result := 0; + while Count > 0 do + begin + PacketCount := min(FBufSize - FBufPos, Count); + if PacketCount <= 0 then + exit; + Move(FBuffer^[FBufPos], Packet^, PacketCount); + dec(Count, PacketCount); + inc(Packet, PacketCount); + inc(Result, PacketCount); + inc(FPosition, PacketCount); + inc(FBufPos, PacketCount); + if FBufPos >= FBufSize then + CheckPosition; + end; +end; + +function TsdBufferedReadStream.Seek(Offset: longint; Origin: Word): Longint; +begin + case Origin of + soFromBeginning: + FPosition := Offset; + soFromCurrent: + begin + // no need to check in this case - it is the GetPosition command + if Offset = 0 then + begin + Result := FPosition; + exit; + end; + FPosition := FPosition + Offset; + end; + soFromEnd: + FPosition := FStream.Size + Offset; + end;//case + Result := FPosition; + FMustCheck := True; +end; + +function TsdBufferedReadStream.Write(const Buffer; Count: longint): Longint; +begin + raise EStreamError.Create(sxeCannotWriteCodecForReading); +end; + +{ TsdBufferedWriteStream } + +constructor TsdBufferedWriteStream.Create(AStream: TStream; Owned: boolean); +begin + inherited Create; + FStream := AStream; + FOwned := Owned; + ReallocMem(FBuffer, cMaxBufferSize); +end; + +destructor TsdBufferedWriteStream.Destroy; +begin + Flush; + if FOwned then + FreeAndNil(FStream); + ReallocMem(FBuffer, 0); + inherited; +end; + +procedure TsdBufferedWriteStream.Flush; +begin + // Write the buffer to the stream + if FBufPos > 0 then + begin + FStream.Write(FBuffer^, FBufPos); + FBufPos := 0; + end; +end; + +function TsdBufferedWriteStream.Read(var Buffer; Count: longint): Longint; +begin + raise EStreamError.Create(sxeCannotReadCodecForWriting); +end; + +function TsdBufferedWriteStream.Seek(Offset: longint; Origin: Word): Longint; +begin + case Origin of + soFromBeginning: + if Offset = FPosition then + begin + Result := FPosition; + exit; + end; + soFromCurrent: + begin + // GetPosition command + if Offset = 0 then + begin + Result := FPosition; + exit; + end; + end; + soFromEnd: + if Offset = 0 then + begin + Result := FPosition; + exit; + end; + end;//case + raise EStreamError.Create(sxeCannotPerformSeek); +end; + +function TsdBufferedWriteStream.Write(const Buffer; Count: longint): Longint; +var + Packet: PByte; + PacketCount: integer; +begin + // Special case - read less bytes than would fill buffersize + if (FBufPos + Count < cMaxBufferSize) then + begin + Move(Buffer, FBuffer^[FBufPos], Count); + inc(FBufPos, Count); + inc(FPosition, Count); + Result := Count; + exit; + end; + + // general case that wraps buffer + Packet := @Buffer; + Result := 0; + while Count > 0 do + begin + PacketCount := min(cMaxBufferSize - FBufPos, Count); + if PacketCount <= 0 then + exit; + Move(Packet^, FBuffer^[FBufPos], PacketCount); + dec(Count, PacketCount); + inc(Result, PacketCount); + inc(FPosition, PacketCount); + inc(Packet, PacketCount); + inc(FBufPos, PacketCount); + if FBufPos = cMaxBufferSize then + Flush; + end; +end; +{$ENDIF} + +{ TsdSurplusReader } + +constructor TsdSurplusReader.Create(AStream: TStream); +begin + inherited Create; + FStream := AStream; +end; + +function TsdSurplusReader.ReadChar(var Ch: AnsiChar): integer; +begin + if length(FSurplus) > 0 then + begin + Ch := FSurplus[1]; + FSurplus := copy(FSurplus, 2, length(FSurplus) - 1); + Result := 1; + end else + Result := FStream.Read(Ch, 1); +end; + +function TsdSurplusReader.ReadCharSkipBlanks(var Ch: AnsiChar): boolean; +begin + Result := False; + repeat + // Read AnsiCharacter, exit if none available + if ReadChar(Ch) = 0 then + exit; + // Skip if in controlchars + if not (Ch in cControlchars) then + break; + until False; + Result := True; +end; + +{ TsdStringBuilder } + +procedure TsdStringBuilder.AddChar(Ch: AnsiChar); +begin + inc(FCurrentIdx); + Reallocate(FCurrentIdx); + FData[FCurrentIdx] := Ch; +end; + +procedure TsdStringBuilder.AddString(var S: UTF8String); +var + {$IFDEF CLR} + i: integer; + {$ENDIF} + Count: integer; +begin + {$IFDEF CLR} + Count := S.Length; + {$ELSE} + Count := System.length(S); + {$ENDIF} + if Count = 0 then + exit; + Reallocate(FCurrentIdx + Count); + {$IFDEF CLR} + for i := 1 to S.Length do + FData[FCurrentIdx + i] := S[i]; + {$ELSE} + Move(S[1], FData[FCurrentIdx + 1], Count); + {$ENDIF} + inc(FCurrentIdx, Count); +end; + +procedure TsdStringBuilder.Clear; +begin + FCurrentIdx := 0; +end; + +function TsdStringBuilder.StringCopy(AFirst, ALength: integer): UTF8String; +begin + if ALength > FCurrentIdx - AFirst + 1 then + ALength := FCurrentIdx - AFirst + 1; + Result := Copy(FData, AFirst, ALength); +end; + +constructor TsdStringBuilder.Create; +begin + inherited Create; + SetLength(FData, 64); +end; + +function TsdStringBuilder.GetData(Index: integer): AnsiChar; +begin + Result := FData[Index]; +end; + +procedure TsdStringBuilder.Reallocate(RequiredLength: integer); +begin + {$IFDEF CLR} + while FData.Length < RequiredLength do + SetLength(FData, FData.Length * 2); + {$ELSE} + while System.Length(FData) < RequiredLength do + SetLength(FData, System.Length(FData) * 2); + {$ENDIF} +end; + +function TsdStringBuilder.Value: UTF8String; +begin + Result := Copy(FData, 1, FCurrentIdx); +end; + +end. diff --git a/System/NativeXmlAppend.pas b/System/NativeXmlAppend.pas new file mode 100644 index 0000000..da87926 --- /dev/null +++ b/System/NativeXmlAppend.pas @@ -0,0 +1,243 @@ +{ + Unit NativeXmlAppend + + This unit implements a method to add XML fragments to the end of an existing + XML file that resides on disk. The file is never loaded completely into memory, + the new data will be appended at the end. + + This unit requires NativeXml. + + Possible exceptions (apart from the regular ones for file access): + + 'Reverse read past beginning of stream': + The file provided in S is not an XML file or it is an XML file with not enough + levels. The XML file should have in its last tag at least ALevel levels of + elements. Literally this exception means that the algorithm went backwards + through the complete file and arrived at the beginning, without finding a + suitable position to insert the node data. + + 'Level cannot be found' + This exception will be raised when the last element does not contain enough + levels, so the algorithm encounters an opening tag where it would expect a + closing tag. + Example: + We try to add a node at level 3 in this XML file + + + + + + <-- This last node does not have a level2, so the algorithm + does not know where to add the data of level 3 under level2 + + + See Example4 for an implementation + + Original Author: Nils Haeck M.Sc. + Copyright (c) 2003-2009 Simdesign B.V. + + It is NOT allowed under ANY circumstances to publish or copy this code + without accepting the license conditions in accompanying LICENSE.txt + first! + + This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF + ANY KIND, either express or implied. + + Please visit http://www.simdesign.nl/xml.html for more information. +} +unit NativeXmlAppend; + +interface + +{$I NativeXml.inc} + +uses + Classes, SysUtils, Dialogs, NativeXml; + +type + ustring = UTF8String; + +// With this routine we can add a single node (TXmlNode) to an existing XML file. +// The file will NOT be read in completely, the data will simply be appended at the +// end. In order to do this, the file is scanned from the end until the last node +// at ALevel levels deep is located. +// ALevel = 0 would add the new node at the very end. This is not wise, since XML +// does not allow more than one root node. Choose ALevel = 1 to add the new node +// at the first level under the root (default). +//

+// TIP: If you want to start with an empty (template) XmlDocument, make sure to +// set TsdXmlDocument.UseFullNodes to True before saving it. This ensures that +// the append function will work correctly on the root node. +//

+// NOTE 1: This method does not work for unicode files. +procedure XmlAppendToExistingFile(const AFilename: string; ANode: TXmlNode; + ALevel: integer {$IFDEF D4UP}= 1{$ENDIF}); + +implementation + +type + // We need this class to get access to protected method WriteToString + THackNode = class(TXmlNode); + + TTagType = record + FClose: string; + FStart: string; + end; + +const + + // Reversed tags, note: the record fields are also in reversed order. This + // is because we read backwards + cTagCount = 4; + cTags: array[0..cTagCount - 1] of TTagType = ( + // The order is important here; the items are searched for in appearing order + (FClose: '>]]'; FStart: '[ATADC[!<'), // CDATA + (FClose: '>--'; FStart: '--!<'), // Comment + (FClose: '>?'; FStart: '?<'), // + (FClose: '>'; FStart: '<') // Any other + ); + +function ScanBackwards(S: TStream): char; +begin + if S.Position = 0 then + raise Exception.Create('Reverse read past beginning of stream'); + S.Seek(-1, soFromCurrent); + S.Read(Result, 1); + S.Seek(-1, soFromCurrent); +end; + +function ReverseReadCloseTag(S: TStream): integer; +// Try to read the type of close tag from S, in reversed order +var + AIndex, i: integer; + Found: boolean; + Ch: char; +begin + Result := cTagCount - 1; + AIndex := 1; + repeat + Found := False; + inc(AIndex); + Ch := ScanBackwards(S); + for i := cTagCount - 1 downto 0 do begin + if length(cTags[i].FClose) >= AIndex then + if cTags[i].FClose[AIndex] = Ch then begin + Found := True; + Result := i; + break; + end; + end; + until Found = False; + // Increase position again because we read too far + S.Seek(1, soFromCurrent); +end; + +procedure ReverseReadFromStreamUntil(S: TStream; const ASearch: string; + var AValue: string); +// Read the tag in reversed order. We are looking for the string in ASearch +// (in reversed order). AValue will contain the tag when done (in correct order). +var + AIndex: integer; + Ch: char; +begin + AIndex := 1; + AValue := ''; + while AIndex <= length(ASearch) do begin + Ch := ScanBackwards(S); + AValue := Ch + AValue; + if ASearch[AIndex] = Ch then + inc(AIndex) + else + AIndex := 1; + end; + AValue := copy(AValue, Length(ASearch) + 1, length(AValue)); +end; + +function XmlScanNodeFromEnd(S: TStream; ALevel: integer): integer; +// Scan the stream S from the end and find the end of node at level ALevel +var + Ch: char; + ATagIndex: integer; + AValue: string; +begin + S.Seek(0, soFromEnd); + while ALevel > 0 do begin + Ch := ScanBackwards(S); + if Ch = '>' then begin + // Determine tag type from closing tag + ATagIndex := ReverseReadCloseTag(S); + // Try to find the start + ReverseReadFromStreamUntil(S, cTags[ATagIndex].FStart, AValue); + // We found the start, now decide what to do. We only decrease + // level if this is a closing tag. If it is an opening tag, we + // should raise an exception + if (ATagIndex = 3) then begin + if (Length(AValue) > 0) and (AValue[1] = '/') then + dec(ALevel) + else + raise Exception.Create('Level cannot be found'); + end; + end; + end; + Result := S.Position; +end; + +procedure StreamInsertString(S: TStream; APos: integer; Value: string); +// Insert Value into stream S at position APos. The stream S (if it is a disk +// file) should have write access! +var + ASize: integer; + M: TMemoryStream; +begin + // Nothing to do if no value + if Length(Value) = 0 then exit; + + S.Position := APos; + ASize := S.Size - S.Position; + // Create intermediate memory stream that holds the new ending + M := TMemoryStream.Create; + try + // Create a copy into a memory stream that contains new insert + old last part + M.SetSize(ASize + Length(Value)); + M.Write(Value[1], Length(Value)); + M.CopyFrom(S, ASize); + // Now add this copy at the current position + M.Position := 0; + S.Position := APos; + S.CopyFrom(M, M.Size); + finally + M.Free; + end; +end; + +procedure XmlAppendToExistingFile(const AFilename: string; ANode: TXmlNode; + ALevel: integer); +// With this routine we can add a single node (TXmlNode) to an existing XML file. +// The file will NOT be read in completely, the data will simply be appended at the +// end. In order to do this, the file is scanned from the end until the last node +// at ALevel levels deep is located. +// ALevel = 0 would add the new node at the very end. This is not wise, since XML +// does not allow more than one root node. Choose ALevel = 1 to add the new node +// at the first level under the root (default). +var + S: TStream; + APos: integer; + AInsert: ustring; +begin + // Open the file with Read/Write access + S := TFileStream.Create(AFilename, fmOpenReadWrite or fmShareDenyWrite); + try + // After a successful open, we can locate the correct end of node + APos := XmlScanNodeFromEnd(S, ALevel); + // Still no exceptions, this means we found a valid position.. now insert the + // new node in here. + AInsert := THackNode(ANode).WriteToString; + // Now we happily insert the string into the opened stream at the right position + StreamInsertString(S, APos, string(AInsert)); + finally + // We're done, close the stream, this will save the modified filestream + S.Free; + end; +end; + +end. diff --git a/System/NativeXmlObjectStorage.pas b/System/NativeXmlObjectStorage.pas new file mode 100644 index 0000000..c159056 --- /dev/null +++ b/System/NativeXmlObjectStorage.pas @@ -0,0 +1,1273 @@ +{ unit NativeXmlObjectStorage + + This unit provides functionality to store any TObject descendant to an XML file + or stream. Internally it makes full use of RTTI (runtime type information) in + order to store all published properties and events. + + It can even be used to copy forms, but form inheritance is not exploited, so + child forms descending from parent forms store everything that the parent already + stored. + + All published properties and events of objects are stored. This includes + the "DefineProperties". These are stored in binary form in the XML, encoded + as BASE64. + + Known limitations: + - The method and event lookup will not work correctly across forms. + + Please see the "ObjectToXML" demo for example usage of this unit. + + Original Author: Nils Haeck M.Sc. + Copyright (c) 2003-2009 Simdesign B.V. + + It is NOT allowed under ANY circumstances to publish or copy this code + without accepting the license conditions in accompanying LICENSE.txt + first! + + This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF + ANY KIND, either express or implied. + + Please visit http://www.simdesign.nl/xml.html for more information. +} +unit NativeXmlObjectStorage; + +{$i NativeXml.inc} + +interface + +uses + Classes, Forms, SysUtils, Controls, NativeXml, TypInfo, Variants; + +type + + // Use TsdXmlObjectWriter to write any TPersistent descendant's published properties + // to an XML node. + TsdXmlObjectWriter = class(TPersistent) + protected + procedure WriteProperty(ANode: TXmlNode; AObject: TObject; AParent: TComponent; PropInfo: PPropInfo); + public + // Call WriteObject to write the published properties of AObject to the TXmlNode + // ANode. Specify AParent in order to store references to parent methods and + // events correctly. + procedure WriteObject(ANode: TXmlNode; AObject: TObject; AParent: TComponent = nil); + // Call WriteComponent to write the published properties of AComponent to the TXmlNode + // ANode. Specify AParent in order to store references to parent methods and + // events correctly. + procedure WriteComponent(ANode: TXmlNode; AComponent: TComponent; AParent: TComponent = nil); + end; + + // Use TsdXmlObjectReader to read any TPersistent descendant's published properties + // from an XML node. + TsdXmlObjectReader = class(TPersistent) + protected + procedure ReadProperty(ANode: TXmlNode; AObject: TObject; AParent: TComponent; PropInfo: PPropInfo); + public + // Call CreateComponent to first create AComponent and then read its published + // properties from the TXmlNode ANode. Specify AParent in order to resolve + // references to parent methods and events correctly. In order to successfully + // create the component from scratch, the component's class must be registered + // beforehand with a call to RegisterClass. Specify Owner to add the component + // as a child to Owner's component list. This is usually a form. Specify Name + // as the new component name for the created component. + function CreateComponent(ANode: TXmlNode; AOwner, AParent: TComponent; AName: string = ''): TComponent; + // Call ReadObject to read the published properties of AObject from the TXmlNode + // ANode. Specify AParent in order to resolve references to parent methods and + // events correctly. + procedure ReadObject(ANode: TXmlNode; AObject: TObject; AParent: TComponent = nil); + // Call ReadComponent to read the published properties of AComponent from the TXmlNode + // ANode. Specify AParent in order to resolve references to parent methods and + // events correctly. + procedure ReadComponent(ANode: TXmlNode; AComponent: TComponent; AParent: TComponent); + end; + +// High-level create methods + +// Create and read a component from the XML file with FileName. In order to successfully +// create the component from scratch, the component's class must be registered +// beforehand with a call to RegisterClass. Specify Owner to add the component +// as a child to Owner's component list. This is usually a form. Specify Name +// as the new component name for the created component. +function ComponentCreateFromXmlFile(const FileName: string; Owner: TComponent; + const Name: string): TComponent; + +// Create and read a component from the TXmlNode ANode. In order to successfully +// create the component from scratch, the component's class must be registered +// beforehand with a call to RegisterClass. Specify Owner to add the component +// as a child to Owner's component list. This is usually a form. Specify Name +// as the new component name for the created component. +function ComponentCreateFromXmlNode(ANode: TXmlNode; Owner: TComponent; + const Name: string): TComponent; + +// Create and read a component from the XML stream S. In order to successfully +// create the component from scratch, the component's class must be registered +// beforehand with a call to RegisterClass. Specify Owner to add the component +// as a child to Owner's component list. This is usually a form. Specify Name +// as the new component name for the created component. +function ComponentCreateFromXmlStream(S: TStream; Owner: TComponent; + const Name: string): TComponent; + +// Create and read a component from the XML in string in Value. In order to successfully +// create the component from scratch, the component's class must be registered +// beforehand with a call to RegisterClass. Specify Owner to add the component +// as a child to Owner's component list. This is usually a form. Specify Name +// as the new component name for the created component. +function ComponentCreateFromXmlString(const Value: string; Owner: TComponent; + const Name: string): TComponent; + +// Create and read a form from the XML file with FileName. In order to successfully +// create the form from scratch, the form's class must be registered +// beforehand with a call to RegisterClass. Specify Owner to add the form +// as a child to Owner's component list. For forms this is usually Application. +// Specify Name as the new form name for the created form. +function FormCreateFromXmlFile(const FileName: string; Owner: TComponent; + const Name: string): TForm; + +// Create and read a form from the XML stream in S. In order to successfully +// create the form from scratch, the form's class must be registered +// beforehand with a call to RegisterClass. Specify Owner to add the form +// as a child to Owner's component list. For forms this is usually Application. +// Specify Name as the new form name for the created form. +function FormCreateFromXmlStream(S: TStream; Owner: TComponent; + const Name: string): TForm; + +// Create and read a form from the XML string in Value. In order to successfully +// create the form from scratch, the form's class must be registered +// beforehand with a call to RegisterClass. Specify Owner to add the form +// as a child to Owner's component list. For forms this is usually Application. +// Specify Name as the new form name for the created form. +function FormCreateFromXmlString(const Value: string; Owner: TComponent; + const Name: string): TForm; + +// High-level load methods + +// Load all the published properties of AObject from the XML file in Filename. +// Specify AParent in order to resolve references to parent methods and +// events correctly. +procedure ObjectLoadFromXmlFile(AObject: TObject; const FileName: string; + AParent: TComponent = nil); + +// Load all the published properties of AObject from the TXmlNode ANode. +// Specify AParent in order to resolve references to parent methods and +// events correctly. +procedure ObjectLoadFromXmlNode(AObject: TObject; ANode: TXmlNode; AParent: TComponent = nil); + +// Load all the published properties of AObject from the XML stream in S. +// Specify AParent in order to resolve references to parent methods and +// events correctly. +procedure ObjectLoadFromXmlStream(AObject: TObject; S: TStream; AParent: TComponent = nil); + +// Load all the published properties of AObject from the XML string in Value. +// Specify AParent in order to resolve references to parent methods and +// events correctly. +procedure ObjectLoadFromXmlString(AObject: TObject; const Value: string; AParent: TComponent = nil); + +// High-level save methods + +// Save all the published properties of AObject as XML to the file in Filename. +// Specify AParent in order to store references to parent methods and +// events correctly. +procedure ObjectSaveToXmlFile(AObject: TObject; const FileName: string; + AParent: TComponent = nil); + +// Save all the published properties of AObject to the TXmlNode ANode. +// Specify AParent in order to store references to parent methods and +// events correctly. +procedure ObjectSaveToXmlNode(AObject: TObject; ANode: TXmlNode; AParent: TComponent = nil); + +// Save all the published properties of AObject as XML in stream S. +// Specify AParent in order to store references to parent methods and +// events correctly. +procedure ObjectSaveToXmlStream(AObject: TObject; S: TStream; AParent: TComponent = nil); + +// Save all the published properties of AObject as XML in string Value. +// Specify AParent in order to store references to parent methods and +// events correctly. +function ObjectSaveToXmlString(AObject: TObject; AParent: TComponent = nil): string; + +// Save all the published properties of AComponent as XML in the file in Filename. +// Specify AParent in order to store references to parent methods and +// events correctly. +procedure ComponentSaveToXmlFile(AComponent: TComponent; const FileName: string; + AParent: TComponent = nil); + +// Save all the published properties of AComponent to the TXmlNode ANode. +// Specify AParent in order to store references to parent methods and +// events correctly. +procedure ComponentSaveToXmlNode(AComponent: TComponent; ANode: TXmlNode; + AParent: TComponent = nil); + +// Save all the published properties of AComponent as XML in the stream in S. +// Specify AParent in order to store references to parent methods and +// events correctly. +procedure ComponentSaveToXmlStream(AComponent: TComponent; S: TStream; + AParent: TComponent = nil); + +// Save all the published properties of AComponent as XML in the string Value. +// Specify AParent in order to store references to parent methods and +// events correctly. +function ComponentSaveToXmlString(AComponent: TComponent; AParent: TComponent = nil): string; + +// Save the form AForm as XML to the file in Filename. This method also stores +// properties of all child components on the form, and can therefore be used +// as a form-storage method. +procedure FormSaveToXmlFile(AForm: TForm; const FileName: string); + +// Save the form AForm as XML to the stream in S. This method also stores +// properties of all child components on the form, and can therefore be used +// as a form-storage method. +procedure FormSaveToXmlStream(AForm: TForm; S: TStream); + +// Save the form AForm as XML to a string. This method also stores +// properties of all child components on the form, and can therefore be used +// as a form-storage method. +function FormSaveToXmlString(AForm: TForm): string; + +resourcestring + + sxwIllegalVarType = 'Illegal variant type'; + sxrUnregisteredClassType = 'Unregistered classtype encountered in '; + sxrInvalidPropertyValue = 'Invalid property value'; + sxwInvalidMethodName = 'Invalid method name'; + +implementation + +type + + TPersistentAccess = class(TPersistent); + TComponentAccess = class(TComponent) + public + procedure SetComponentState(const AState: TComponentState); + published + property ComponentState; + end; + + TReaderAccess = class(TReader); + +function ComponentCreateFromXmlFile(const FileName: string; Owner: TComponent; + const Name: string): TComponent; +var + S: TStream; +begin + S := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); + try + Result := ComponentCreateFromXmlStream(S, Owner, Name); + finally + S.Free; + end; +end; + +function ComponentCreateFromXmlNode(ANode: TXmlNode; Owner: TComponent; + const Name: string): TComponent; +var + AReader: TsdXmlObjectReader; +begin + Result := nil; + if not assigned(ANode) then + exit; + // Create reader + AReader := TsdXmlObjectReader.Create; + try + // Read the component from the node + Result := AReader.CreateComponent(ANode, Owner, nil, Name); + finally + AReader.Free; + end; +end; + +function ComponentCreateFromXmlStream(S: TStream; Owner: TComponent; + const Name: string): TComponent; +var + ADoc: TNativeXml; +begin + Result := nil; + if not assigned(S) then + exit; + // Create XML document + ADoc := TNativeXml.Create; + try + // Load XML + ADoc.LoadFromStream(S); + // Load from XML node + Result := ComponentCreateFromXmlNode(ADoc.Root, Owner, Name); + finally + ADoc.Free; + end; +end; + +function ComponentCreateFromXmlString(const Value: string; Owner: TComponent; + const Name: string): TComponent; +var + S: TStream; +begin + S := TStringStream.Create(Value); + try + Result := ComponentCreateFromXmlStream(S, Owner, Name); + finally + S.Free; + end; +end; + +function FormCreateFromXmlFile(const FileName: string; Owner: TComponent; + const Name: string): TForm; +var + S: TStream; +begin + S := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); + try + Result := FormCreateFromXmlStream(S, Owner, Name); + finally + S.Free; + end; +end; + +function FormCreateFromXmlStream(S: TStream; Owner: TComponent; + const Name: string): TForm; +var + ADoc: TNativeXml; +begin + Result := nil; + if not assigned(S) then exit; + // Create XML document + ADoc := TNativeXml.Create; + try + // Load XML + ADoc.LoadFromStream(S); + + // Load from XML node + Result := TForm(ComponentCreateFromXmlNode(ADoc.Root, Owner, Name)); + finally + ADoc.Free; + end; +end; + +function FormCreateFromXmlString(const Value: string; Owner: TComponent; + const Name: string): TForm; +var + S: TStream; +begin + S := TStringStream.Create(Value); + try + Result := FormCreateFromXmlStream(S, Owner, Name); + finally + S.Free; + end; +end; + +procedure ObjectLoadFromXmlFile(AObject: TObject; const FileName: string; + AParent: TComponent = nil); +var + S: TStream; +begin + S := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); + try + ObjectLoadFromXmlStream(AObject, S, AParent); + finally + S.Free; + end; +end; + +procedure ObjectLoadFromXmlNode(AObject: TObject; ANode: TXmlNode; AParent: TComponent = nil); +var + AReader: TsdXmlObjectReader; +begin + if not assigned(AObject) or not assigned(ANode) then + exit; + // Create writer + AReader := TsdXmlObjectReader.Create; + try + // Write the object to the document + if AObject is TComponent then + AReader.ReadComponent(ANode, TComponent(AObject), AParent) + else + AReader.ReadObject(ANode, AObject, AParent); + finally + AReader.Free; + end; +end; + +procedure ObjectLoadFromXmlStream(AObject: TObject; S: TStream; AParent: TComponent = nil); +var + ADoc: TNativeXml; +begin + if not assigned(S) then + exit; + // Create XML document + ADoc := TNativeXml.Create; + try + // Load XML + ADoc.LoadFromStream(S); + // Load from XML node + ObjectLoadFromXmlNode(AObject, ADoc.Root, AParent); + finally + ADoc.Free; + end; +end; + +procedure ObjectLoadFromXmlString(AObject: TObject; const Value: string; AParent: TComponent = nil); +var + S: TStringStream; +begin + S := TStringStream.Create(Value); + try + ObjectLoadFromXmlStream(AObject, S, AParent); + finally + S.Free; + end; +end; + +procedure ObjectSaveToXmlFile(AObject: TObject; const FileName: string; + AParent: TComponent = nil); +var + S: TStream; +begin + S := TFileStream.Create(FileName, fmCreate); + try + ObjectSaveToXmlStream(AObject, S, AParent); + finally + S.Free; + end; +end; + +procedure ObjectSaveToXmlNode(AObject: TObject; ANode: TXmlNode; AParent: TComponent = nil); +var + AWriter: TsdXmlObjectWriter; +begin + if not assigned(AObject) or not assigned(ANode) then + exit; + // Create writer + AWriter := TsdXmlObjectWriter.Create; + try + // Write the object to the document + if AObject is TComponent then + AWriter.WriteComponent(ANode, TComponent(AObject), AParent) + else begin + ANode.Name := UTF8String(AObject.ClassName); + AWriter.WriteObject(ANode, AObject, AParent); + end; + finally + AWriter.Free; + end; +end; + +procedure ObjectSaveToXmlStream(AObject: TObject; S: TStream; AParent: TComponent = nil); +var + ADoc: TNativeXml; +begin + if not assigned(S) then + exit; + // Create XML document + ADoc := TNativeXml.Create; + try + ADoc.XmlFormat := xfReadable; + // Save to XML node + ObjectSaveToXmlNode(AObject, ADoc.Root, AParent); + // Save to stream + ADoc.SaveToStream(S); + finally + ADoc.Free; + end; +end; + +function ObjectSaveToXmlString(AObject: TObject; AParent: TComponent = nil): string; +var + S: TStringStream; +begin + S := TStringStream.Create(''); + try + ObjectSaveToXmlStream(AObject, S, AParent); + Result := S.DataString; + finally + S.Free; + end; +end; + +procedure ComponentSaveToXmlFile(AComponent: TComponent; const FileName: string; + AParent: TComponent = nil); +begin + ObjectSaveToXmlFile(AComponent, FileName, AParent); +end; + +procedure ComponentSaveToXmlNode(AComponent: TComponent; ANode: TXmlNode; + AParent: TComponent = nil); +begin + ObjectSaveToXmlNode(AComponent, ANode, AParent); +end; + +procedure ComponentSaveToXmlStream(AComponent: TComponent; S: TStream; + AParent: TComponent = nil); +begin + ObjectSaveToXmlStream(AComponent, S, AParent); +end; + +function ComponentSaveToXmlString(AComponent: TComponent; AParent: TComponent = nil): string; +begin + Result := ObjectSaveToXmlString(AComponent, AParent); +end; + +procedure FormSaveToXmlFile(AForm: TForm; const FileName: string); +begin + ComponentSaveToXmlFile(AForm, FileName, AForm); +end; + +procedure FormSaveToXmlStream(AForm: TForm; S: TStream); +begin + ComponentSaveToXmlStream(AForm, S, AForm); +end; + +function FormSaveToXmlString(AForm: TForm): string; +begin + Result := ComponentSaveToXmlString(AForm, AForm); +end; + +{ TsdXmlObjectWriter } + +procedure TsdXmlObjectWriter.WriteComponent(ANode: TXmlNode; AComponent, + AParent: TComponent); +begin + if not assigned(ANode) or not assigned(AComponent) then + exit; + ANode.Name := UTF8String(AComponent.ClassName); + if length(AComponent.Name) > 0 then + ANode.AttributeAdd('Name', UTF8String(AComponent.Name)); + WriteObject(ANode, AComponent, AParent); +end; + +procedure TsdXmlObjectWriter.WriteObject(ANode: TXmlNode; AObject: TObject; + AParent: TComponent); +var + i, Count: Integer; + PropInfo: PPropInfo; + PropList: PPropList; + S: TStringStream; + AWriter: TWriter; + AChildNode: TXmlNode; + AComponentNode: TXmlNode; +begin + if not assigned(ANode) or not assigned(AObject) then + exit; + + // If this is a component, store child components + if AObject is TComponent then with TComponent(AObject) do + begin + if ComponentCount > 0 then + begin + AChildNode := ANode.NodeNew('Components'); + for i := 0 to ComponentCount - 1 do + begin + AComponentNode := AChildNode.NodeNew(UTF8String(Components[i].ClassName)); + if length(Components[i].Name) > 0 then + AComponentNode.AttributeAdd('Name', UTF8String(Components[i].Name)); + WriteObject(AComponentNode, Components[i], TComponent(AObject)); + end; + end; + end; + + // Save all regular properties that need storing + Count := GetTypeData(AObject.ClassInfo)^.PropCount; + if Count > 0 then + begin + GetMem(PropList, Count * SizeOf(Pointer)); + try + GetPropInfos(AObject.ClassInfo, PropList); + for i := 0 to Count - 1 do + begin + PropInfo := PropList^[i]; + if PropInfo = nil then + continue; + if IsStoredProp(AObject, PropInfo) then + WriteProperty(ANode, AObject, AParent, PropInfo); + end; + finally + FreeMem(PropList, Count * SizeOf(Pointer)); + end; + end; + + // Save defined properties + if AObject is TPersistent then + begin + S := TStringStream.Create(''); + try + AWriter := TWriter.Create(S, 4096); + try + TPersistentAccess(AObject).DefineProperties(AWriter); + finally + AWriter.Free; + end; + // Do we have data from DefineProperties? + if S.Size > 0 then + begin + // Yes, add a node with binary data + ANode.NodeNew('DefinedProperties').BinaryString := RawByteString(S.DataString); + end; + finally + S.Free; + end; + end; +end; + +procedure TsdXmlObjectWriter.WriteProperty(ANode: TXmlNode; AObject: TObject; + AParent: TComponent; PropInfo: PPropInfo); +var + PropType: PTypeInfo; + AChildNode: TXmlNode; + ACollectionNode: TXmlNode; + //local + procedure WritePropName; + begin + AChildNode := ANode.NodeNew(PPropInfo(PropInfo)^.Name); + end; + //local + procedure WriteInteger(Value: Int64); + begin + AChildNode.ValueAsString := UTF8String(IntToStr(Value)); + end; + //local + procedure WriteString(Value: string); + begin + AChildNode.ValueAsUnicodeString := Value; + end; + //local + procedure WriteSet(Value: Longint); + var + I: Integer; + BaseType: PTypeInfo; + S, Enum: string; + begin + BaseType := GetTypeData(PropType)^.CompType^; + for i := 0 to SizeOf(TIntegerSet) * 8 - 1 do + begin + if i in TIntegerSet(Value) then + begin + Enum := GetEnumName(BaseType, i); + if i > 0 then + S := S + ',' + Enum + else + S := Enum; + end; + end; + AChildNode.ValueAsString := UTF8String(Format('[%s]', [S])); + end; + //local + procedure WriteIntProp(IntType: PTypeInfo; Value: Longint); + var + Ident: string; + IntToIdent: TIntToIdent; + begin + IntToIdent := FindIntToIdent(IntType); + if Assigned(IntToIdent) and IntToIdent(Value, Ident) then + WriteString(Ident) + else + WriteInteger(Value); + end; + //local + procedure WriteCollectionProp(Collection: TCollection); + var + i: integer; + begin + if assigned(Collection) then + begin + for i := 0 to Collection.Count - 1 do + begin + ACollectionNode := AChildNode.NodeNew(UTF8String(Collection.Items[i].ClassName)); + WriteObject(ACollectionNode, Collection.Items[I], AParent); + end; + end; + end; + //local + procedure WriteOrdProp; + var + Value: Longint; + begin + Value := GetOrdProp(AObject, PropInfo); + if not (Value = PPropInfo(PropInfo)^.Default) then + begin + WritePropName; + case PropType^.Kind of + tkInteger: WriteIntProp(PPropInfo(PropInfo)^.PropType^, Value); + tkChar: WriteString(Chr(Value)); + tkSet: WriteSet(Value); + tkEnumeration: WriteString(GetEnumName(PropType, Value)); + end; + end; + end; + //local + procedure WriteFloatProp; + var + Value: Extended; + begin + Value := GetFloatProp(AObject, PropInfo); + if not (Value = 0) then + ANode.WriteFloat(PPropInfo(PropInfo)^.Name, Value); + end; + //local + procedure WriteInt64Prop; + var + Value: Int64; + begin + Value := GetInt64Prop(AObject, PropInfo); + if not (Value = 0) then + ANode.WriteInt64(PPropInfo(PropInfo)^.Name, Value); + end; + //local + procedure WriteStrProp; + var + Value: string; + begin + Value := GetStrProp(AObject, PropInfo); + if not (length(Value) = 0) then + ANode.WriteUnicodeString(PPropInfo(PropInfo)^.Name, Value); + end; + //local + procedure WriteWideStrProp; + var + Value: WideString; + begin + Value := GetWideStrProp(AObject, PropInfo); + if not (length(Value) = 0) then + ANode.WriteUnicodeString(PPropInfo(PropInfo)^.Name, Value); + end; + {$IFDEF D12UP} + //local + procedure WriteUnicodeStrProp; + var + Value: UnicodeString; + begin + Value := GetUnicodeStrProp(AObject, PropInfo); + if not (length(Value) = 0) then + ANode.WriteUnicodeString(PPropInfo(PropInfo)^.Name, Value); + end; + {$ENDIF} + //local + procedure WriteObjectProp; + var + Value: TObject; + ComponentName: string; + function GetComponentName(Component: TComponent): string; + begin + if Component.Owner = AParent then + Result := Component.Name + else if Component = AParent then + Result := 'Owner' + else if assigned(Component.Owner) and (length(Component.Owner.Name) > 0) + and (length(Component.Name) > 0) then + Result := Component.Owner.Name + '.' + Component.Name + else if length(Component.Name) > 0 then + Result := Component.Name + '.Owner' + else Result := ''; + end; + begin + Value := TObject(GetOrdProp(AObject, PropInfo)); + if not assigned(Value) then + exit; + WritePropName; + if Value is TComponent then + begin + ComponentName := GetComponentName(TComponent(Value)); + if length(ComponentName) > 0 then + WriteString(ComponentName); + end else + begin + WriteString(Format('(%s)', [Value.ClassName])); + if Value is TCollection then + WriteCollectionProp(TCollection(Value)) + else + begin + if AObject is TComponent then + WriteObject(AChildNode, Value, TComponent(AObject)) + else + WriteObject(AChildNode, Value, AParent) + end; + // No need to store an empty child.. so check and remove + if AChildNode.NodeCount = 0 then + ANode.NodeRemove(AChildNode); + end; + end; + //local + procedure WriteMethodProp; + var + Value: TMethod; + function IsDefaultValue: Boolean; + begin + Result := (Value.Code = nil) or + ((Value.Code <> nil) and assigned(AParent) and (AParent.MethodName(Value.Code) = '')); + end; + begin + Value := GetMethodProp(AObject, PropInfo); + if not IsDefaultValue then + begin + if assigned(Value.Code) then + begin + WritePropName; + if assigned(AParent) then + WriteString(AParent.MethodName(Value.Code)) + else + AChildNode.ValueAsString := '???'; + end; + end; + end; + //local + procedure WriteVariantProp; + var + AValue: Variant; + ACurrency: Currency; + var + VType: Integer; + begin + AValue := GetVariantProp(AObject, PropInfo); + if not VarIsEmpty(AValue) or VarIsNull(AValue) then + begin + if VarIsArray(AValue) then + raise Exception.Create(sxwIllegalVarType); + WritePropName; + VType := VarType(AValue); + AChildNode.AttributeAdd('VarType', UTF8String(IntToHex(VType, 4))); + case VType and varTypeMask of + varNull: AChildNode.ValueAsUnicodeString := ''; + varOleStr: AChildNode.ValueAsUnicodeString := AValue; + varString: AChildNode.ValueAsUnicodeString := AValue; + varByte, + varSmallInt, + varInteger: AChildNode.ValueAsInteger := AValue; + varSingle, + varDouble: AChildNode.ValueAsFloat := AValue; + varCurrency: + begin + ACurrency := AValue; + AChildNode.BufferWrite(ACurrency, SizeOf(ACurrency)); + end; + varDate: AChildNode.ValueAsDateTime := AValue; + varBoolean: AChildNode.ValueAsBool := AValue; + else + try + ANode.ValueAsUnicodeString := AValue; + except + raise Exception.Create(sxwIllegalVarType); + end; + end;//case + end; + end; +//main +begin + if (PPropInfo(PropInfo)^.SetProc <> nil) and + (PPropInfo(PropInfo)^.GetProc <> nil) then + begin + PropType := PPropInfo(PropInfo)^.PropType^; + case PropType^.Kind of + tkInteger, tkChar, tkEnumeration, tkSet: WriteOrdProp; + tkFloat: WriteFloatProp; + tkString, tkLString: WriteStrProp; + {$IFDEF D6UP} + tkWString: WriteWideStrProp; + {$ENDIF} + {$IFDEF D12UP} + tkUString: WriteUnicodeStrProp; + {$ENDIF} + tkClass: WriteObjectProp; + tkMethod: WriteMethodProp; + tkVariant: WriteVariantProp; + tkInt64: WriteInt64Prop; + end; + end; +end; + +{ TsdXmlObjectReader } + +function TsdXmlObjectReader.CreateComponent(ANode: TXmlNode; + AOwner, AParent: TComponent; AName: string): TComponent; +var + AClass: TComponentClass; +begin + AClass := TComponentClass(GetClass(string(ANode.Name))); + if not assigned(AClass) then + raise Exception.CreateFmt(sxrUnregisteredClassType, [ANode.Name]); + Result := AClass.Create(AOwner); + if length(AName) = 0 then + Result.Name := string(ANode.AttributeByName['Name']) + else + Result.Name := AName; + if not assigned(AParent) then + AParent := Result; + ReadComponent(ANode, Result, AParent); +end; + +procedure TsdXmlObjectReader.ReadComponent(ANode: TXmlNode; AComponent, + AParent: TComponent); +begin + ReadObject(ANode, AComponent, AParent); +end; + +procedure TsdXmlObjectReader.ReadObject(ANode: TXmlNode; AObject: TObject; AParent: TComponent); +var + i, Count: Integer; + Item: TCollectionItem; + PropInfo: PPropInfo; + PropList: PPropList; + S: TStringStream; + AReader: TReader; + AChildNode: TXmlNode; + AComponentNode: TXmlNode; + AClass: TComponentClass; + AComponent: TComponent; +begin + if not assigned(ANode) or not assigned(AObject) then + exit; + + // Start loading + if AObject is TComponent then + with TComponentAccess(AObject) do + begin + TComponentAccess(AObject).Updating; + SetComponentState(ComponentState + [csLoading, csReading]); + end; + try + + // If this is a component, load child components + if AObject is TComponent then with TComponent(AObject) do + begin + AChildNode := ANode.NodeByName('Components'); + if assigned(AChildNode) then + begin + for i := 0 to AChildNode.NodeCount - 1 do + begin + AComponentNode := AChildNode.Nodes[i]; + AComponent := FindComponent(string(AComponentNode.AttributeByName['Name'])); + if not assigned(AComponent) then + begin + AClass := TComponentClass(GetClass(string(AComponentNode.Name))); + if not assigned(AClass) then + raise Exception.Create(sxrUnregisteredClassType); + AComponent := AClass.Create(TComponent(AObject)); + AComponent.Name := AComponentNode.AttributeByName['Name']; + // In case of new (visual) controls we set the parent + if (AComponent is TControl) and (AObject is TWinControl) then + TControl(AComponent).Parent := TWinControl(AObject); + end; + ReadComponent(AComponentNode, AComponent, TComponent(AObject)); + end; + end; + end; + + // If this is a collection, load collections items + if AObject is TCollection then + with TCollection(AObject) do + begin + BeginUpdate; + try + Clear; + for i := 0 to ANode.NodeCount - 1 do + begin + item := Add; + ReadObject(ANode.Nodes[i], item, AParent); + end; + finally + EndUpdate; + end; + end; + + // Load all loadable regular properties + Count := GetTypeData(AObject.ClassInfo)^.PropCount; + if Count > 0 then + begin + GetMem(PropList, Count * SizeOf(Pointer)); + try + GetPropInfos(AObject.ClassInfo, PropList); + for i := 0 to Count - 1 do + begin + PropInfo := PropList^[i]; + if PropInfo = nil then + continue; + if IsStoredProp(AObject, PropInfo) then + ReadProperty(ANode, AObject, AParent, PropInfo); + end; + finally + FreeMem(PropList, Count * SizeOf(Pointer)); + end; + end; + + // Load defined properties + if AObject is TPersistent then + begin + AChildNode := ANode.NodeByName('DefinedProperties'); + if assigned(AChildNode) then + begin + S := TStringStream.Create(AChildNode.BinaryString); + try + AReader := TReader.Create(S, 4096); + try + with TReaderAccess(AReader) do + while Position < S.Size do + ReadProperty(TPersistent(AObject)); + finally + AReader.Free; + end; + finally + S.Free; + end; + end; + end; + + finally + // End loading + if AObject is TComponent then with TComponentAccess(AObject) do + begin + SetComponentState(ComponentState - [csReading]); + TComponentAccess(AObject).Loaded; + TComponentAccess(AObject).Updated; + end; + end; +end; + +procedure TsdXmlObjectReader.ReadProperty(ANode: TXmlNode; + AObject: TObject; AParent: TComponent; PropInfo: PPropInfo); +var + PropType: PTypeInfo; + AChildNode: TXmlNode; + Method: TMethod; + PropObject: TObject; + //local + procedure SetSetProp(const AValue: string); + var + S: string; + P: integer; + ASet: integer; + EnumType: PTypeInfo; + procedure AddToEnum(const EnumName: string); + var + V: integer; + begin + if length(EnumName) = 0 then + exit; + V := GetEnumValue(EnumType, EnumName); + if V = -1 then + raise Exception.Create(sxrInvalidPropertyValue); + Include(TIntegerSet(ASet), V); + end; + begin + ASet := 0; + EnumType := GetTypeData(PropType)^.CompType^; + S := copy(AValue, 2, length(AValue) - 2); + repeat + P := Pos(',', S); + if P > 0 then begin + AddToEnum(copy(S, 1, P - 1)); + S := copy(S, P + 1, length(S)); + end else begin + AddToEnum(S); + break; + end; + until False; + SetOrdProp(AObject, PropInfo, ASet); + end; + + procedure SetIntProp(const AValue: string); + var + V: Longint; + IdentToInt: TIdentToInt; + begin + IdentToInt := FindIdentToInt(PropType); + if Assigned(IdentToInt) and IdentToInt(AValue, V) then + SetOrdProp(AObject, PropInfo, V) + else + SetOrdProp(AObject, PropInfo, StrToInt(AValue)); + end; + + procedure SetCharProp(const AValue: string); + begin + if length(AValue) <> 1 then + raise Exception.Create(sxrInvalidPropertyValue); + SetOrdProp(AObject, PropInfo, Ord(AValue[1])); + end; + + procedure SetEnumProp(const AValue: string); + var + V: integer; + begin + V := GetEnumValue(PropType, AValue); + if V = -1 then + raise Exception.Create(sxrInvalidPropertyValue); + SetOrdProp(AObject, PropInfo, V) + end; + + procedure ReadCollectionProp(ACollection: TCollection); + var + i: integer; + Item: TPersistent; + begin + ACollection.BeginUpdate; + try + ACollection.Clear; + for i := 0 to AChildNode.NodeCount - 1 do + begin + Item := ACollection.Add; + ReadObject(AChildNode.Nodes[i], Item, AParent); + end; + finally + ACollection.EndUpdate; + end; + end; + + procedure SetObjectProp(const AValue: string); + var + AClassName: string; + PropObject: TObject; + Reference: TComponent; + begin + if length(AValue) = 0 then + exit; + if AValue[1] = '(' then + begin + // Persistent class + AClassName := Copy(AValue, 2, length(AValue) - 2); + PropObject := TObject(GetOrdProp(AObject, PropInfo)); + if assigned(PropObject) and (PropObject.ClassName = AClassName) then + begin + if PropObject is TCollection then + ReadCollectionProp(TCollection(PropObject)) + else + begin + if AObject is TComponent then + ReadObject(AChildNode, PropObject, TComponent(AObject)) + else + ReadObject(AChildNode, PropObject, AParent); + end; + end else + raise Exception.Create(sxrUnregisteredClassType); + end else + begin + // Component reference + if assigned(AParent) then + begin + Reference := FindNestedComponent(AParent, AValue); + SetOrdProp(AObject, PropInfo, Longint(Reference)); + end; + end; + end; + + procedure SetMethodProp(const AValue: string); + var + Method: TMethod; + begin + // to do: add OnFindMethod + if not assigned(AParent) then + exit; + Method.Code := AParent.MethodAddress(AValue); + if not assigned(Method.Code) then + raise Exception.Create(sxwInvalidMethodName); + Method.Data := AParent; + TypInfo.SetMethodProp(AObject, PropInfo, Method); + end; + + procedure SetVariantProp(const AValue: string); + var + VType: integer; + Value: Variant; + ACurrency: Currency; + begin + VType := StrToInt('$' + AChildNode.AttributeByName['VarType']); + + case VType and varTypeMask of + varNull: Value := Null; + varOleStr: Value := AChildNode.ValueAsUnicodeString; + varString: Value := AChildNode.ValueAsString; + varByte, + varSmallInt, + varInteger: Value := AChildNode.ValueAsInteger; + varSingle, + varDouble: Value := AChildNode.ValueAsFloat; + varCurrency: + begin + AChildNode.BufferRead(ACurrency, SizeOf(ACurrency)); + Value := ACurrency; + end; + varDate: Value := AChildNode.ValueAsDateTime; + varBoolean: Value := AChildNode.ValueAsBool; + else + try + Value := ANode.ValueAsString; + except + raise Exception.Create(sxwIllegalVarType); + end; + end;//case + + TVarData(Value).VType := VType; + TypInfo.SetVariantProp(AObject, PropInfo, Value); + end; + +begin + if (PPropInfo(PropInfo)^.SetProc <> nil) and + (PPropInfo(PropInfo)^.GetProc <> nil) then + begin + PropType := PPropInfo(PropInfo)^.PropType^; + AChildNode := ANode.NodeByName(PPropInfo(PropInfo)^.Name); + if assigned(AChildNode) then + begin + // Non-default values from XML + case PropType^.Kind of + tkInteger: SetIntProp(AChildNode.ValueAsString); + tkChar: SetCharProp(AChildNode.ValueAsString); + tkSet: SetSetProp(AChildNode.ValueAsString); + tkEnumeration: SetEnumProp(AChildNode.ValueAsString); + tkFloat: SetFloatProp(AObject, PropInfo, AChildNode.ValueAsFloat); + tkString, + tkLString: SetStrProp(AObject, PropInfo, AChildNode.ValueAsString); + tkWString: SetWideStrProp(AObject, PropInfo, UTF8Decode(AChildNode.ValueAsUnicodeString)); + {$IFDEF D12UP} + tkUString: SetUnicodeStrProp(AObject, PropInfo, AChildNode.ValueAsUnicodeString); + {$ENDIF} + tkClass: SetObjectProp(AChildNode.ValueAsString); + tkMethod: SetMethodProp(AChildNode.ValueAsString); + tkVariant: SetVariantProp(AChildNode.ValueAsString); + tkInt64: SetInt64Prop(AObject, PropInfo, AChildNode.ValueAsInt64); + end;//case + end else + begin + // Set Default value + case PropType^.Kind of + tkInteger: SetOrdProp(AObject, PropInfo, PPropInfo(PropInfo)^.Default); + tkChar: SetOrdProp(AObject, PropInfo, PPropInfo(PropInfo)^.Default); + tkSet: SetOrdProp(AObject, PropInfo, PPropInfo(PropInfo)^.Default); + tkEnumeration: SetOrdProp(AObject, PropInfo, PPropInfo(PropInfo)^.Default); + tkFloat: SetFloatProp(AObject, PropInfo, 0); + tkString, + tkLString, + tkWString: SetStrProp(AObject, PropInfo, ''); + {$IFDEF D12UP} + tkUString: SetStrProp(AObject, PropInfo, ''); + {$ENDIF} + tkClass: + begin + PropObject := TObject(GetOrdProp(AObject, PropInfo)); + if PropObject is TComponent then + SetOrdProp(AObject, PropInfo, 0); + end; + tkMethod: + begin + Method := TypInfo.GetMethodProp(AObject, PropInfo); + Method.Code := nil; + TypInfo.SetMethodProp(AObject, PropInfo, Method); + end; + tkInt64: SetInt64Prop(AObject, PropInfo, 0); + end;//case + end; + end; +end; + +{ TComponentAccess } + +procedure TComponentAccess.SetComponentState(const AState: TComponentState); +type + PInteger = ^integer; +var + PSet: PInteger; + AInfo: PPropInfo; +begin + // This is a "severe" hack in order to set a non-writable property value, + // also using RTTI + PSet := PInteger(@AState); + AInfo := GetPropInfo(TComponentAccess, 'ComponentState'); + if assigned(AInfo.GetProc) then + PInteger(Integer(Self) + Integer(AInfo.GetProc) and $00FFFFFF)^ := PSet^; +end; + +end. + diff --git a/System/PerlRegEx.pas b/System/PerlRegEx.pas new file mode 100644 index 0000000..3f2f9cc --- /dev/null +++ b/System/PerlRegEx.pas @@ -0,0 +1,924 @@ +{**************************************************************************************************} +{ } +{ Perl Regular Expressions VCL component } +{ } +{ 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 PerlRegEx.pas. } +{ } +{ The Initial Developer of the Original Code is Jan Goyvaerts. } +{ Portions created by Jan Goyvaerts are Copyright (C) 1999, 2005, 2008 Jan Goyvaerts. } +{ All rights reserved. } +{ } +{ Design & implementation, by Jan Goyvaerts, 1999, 2005, 2008 } +{ } +{ TPerlRegEx is available at http://www.regular-expressions.info/delphi.html } +{ } +{**************************************************************************************************} + +unit PerlRegEx; + +interface + +uses + Windows, Messages, SysUtils, Classes, + pcre; + +type + TPerlRegExOptions = set of ( + preCaseLess, // /i -> Case insensitive + preMultiLine, // /m -> ^ and $ also match before/after a newline, not just at the beginning and the end of the PCREString + preSingleLine, // /s -> Dot matches any character, including \n (newline). Otherwise, it matches anything except \n + preExtended, // /x -> Allow regex to contain extra whitespace, newlines and Perl-style comments, all of which will be filtered out + preAnchored, // /A -> Successful match can only occur at the start of the subject or right after the previous match + preUnGreedy, // Repeat operators (+, *, ?) are not greedy by default (i.e. they try to match the minimum number of characters instead of the maximum) + preNoAutoCapture // (group) is a non-capturing group; only named groups capture + ); + +type + TPerlRegExState = set of ( + preNotBOL, // Not Beginning Of Line: ^ does not match at the start of Subject + preNotEOL, // Not End Of Line: $ does not match at the end of Subject + preNotEmpty // Empty matches not allowed + ); + +const + // Maximum number of subexpressions (backreferences) + // Subexpressions are created by placing round brackets in the regex, and are referenced by \1, \2, ... + // In Perl, they are available as $1, $2, ... after the regex matched; with TPerlRegEx, use the Subexpressions property + // You can also insert \1, \2, ... in the Replacement PCREString; \0 is the complete matched expression + MAX_SUBEXPRESSIONS = 99; + +{$IFDEF UNICODE} +// All implicit string casts have been verified to be correct +{$WARN IMPLICIT_STRING_CAST OFF} +// Use UTF-8 in Delphi 2009 and later, so Unicode strings are handled correctly. +// PCRE does not support UTF-16 +type + PCREString = UTF8String; +{$ELSE UNICODE} +// Use AnsiString in Delphi 2007 and earlier +type + PCREString = AnsiString; +{$ENDIF UNICODE} + +type + TPerlRegExReplaceEvent = procedure(Sender: TObject; var ReplaceWith: PCREString) of object; + +type + TPerlRegEx = class(TComponent) + private // *** Property storage, getters and setters + FCompiled, FStudied: Boolean; + FOptions: TPerlRegExOptions; + FState: TPerlRegExState; + FRegEx, FReplacement, FSubject: PCREString; + FStart, FStop: Integer; + FOnMatch: TNotifyEvent; + FOnReplace: TPerlRegExReplaceEvent; + function GetMatchedExpression: PCREString; + function GetMatchedExpressionLength: Integer; + function GetMatchedExpressionOffset: Integer; + procedure SetOptions(Value: TPerlRegExOptions); + procedure SetRegEx(const Value: PCREString); + function GetSubExpressionCount: Integer; + function GetSubExpressions(Index: Integer): PCREString; + function GetSubExpressionLengths(Index: Integer): Integer; + function GetSubExpressionOffsets(Index: Integer): Integer; + procedure SetSubject(const Value: PCREString); + procedure SetStart(const Value: Integer); + procedure SetStop(const Value: Integer); + function GetFoundMatch: Boolean; + private // *** Variables used by pcrelib.dll + Offsets: array[0..(MAX_SUBEXPRESSIONS+1)*3] of Integer; + OffsetCount: Integer; + pcreOptions: Integer; + pattern, hints, chartable: Pointer; + FSubjectPChar: PAnsiChar; + FHasStoredSubExpressions: Boolean; + FStoredSubExpressions: array of PCREString; + function GetSubjectLeft: PCREString; + function GetSubjectRight: PCREString; + protected + procedure CleanUp; + // Dispose off whatever we created, so we can start over. Called automatically when needed, so it is not made public + procedure ClearStoredSubExpressions; + public + constructor Create(AOwner: TComponent); override; + // Come to life + destructor Destroy; override; + // Clean up after ourselves + class function EscapeRegExChars(const S: string): string; + // Escapes regex characters in S so that the regex engine can be used to match S as plain text + procedure Compile; + // Compile the regex. Called automatically by Match + procedure Study; + // Study the regex. Studying takes time, but will make the execution of the regex a lot faster. + // Call study if you will be using the same regex many times + function Match: Boolean; + // Attempt to match the regex + function MatchAgain: Boolean; + // Attempt to match the regex to the remainder of the string after the previous match + // To avoid problems (when using ^ in the regex), call MatchAgain only after a succesful Match() + function Replace: PCREString; + // Replace matched expression in Subject with ComputeReplacement. Returns the actual replacement text from ComputeReplacement + function ReplaceAll: Boolean; + // Repeat MatchAgain and Replace until you drop. Returns True if anything was replaced at all. + function ComputeReplacement: PCREString; + // Returns Replacement with backreferences filled in + procedure StoreSubExpressions; + // Stores duplicates of SubExpressions[] so they and ComputeReplacement will still return the proper strings + // even if FSubject is changed or cleared + function NamedSubExpression(const SEName: PCREString): Integer; + // Returns the index of the named group SEName + procedure Split(Strings: TStrings; Limit: Integer); + // Split Subject along regex matches. Items are appended to PCREStrings. + property Compiled: Boolean read FCompiled; + // True if the RegEx has already been compiled. + property FoundMatch: Boolean read GetFoundMatch; + // Returns True when MatchedExpression* and SubExpression* indicate a match + property Studied: Boolean read FStudied; + // True if the RegEx has already been studied + property MatchedExpression: PCREString read GetMatchedExpression; + // The matched PCREString + property MatchedExpressionLength: Integer read GetMatchedExpressionLength; + // Length of the matched PCREString + property MatchedExpressionOffset: Integer read GetMatchedExpressionOffset; + // Character offset in the Subject PCREString at which the matched subPCREString starts + property Start: Integer read FStart write SetStart; + // Starting position in Subject from which MatchAgain begins + property Stop: Integer read FStop write SetStop; + // Last character in Subject that Match and MatchAgain search through + property State: TPerlRegExState read FState write FState; + // State of Subject + property SubExpressionCount: Integer read GetSubExpressionCount; + // Number of matched subexpressions + property SubExpressions[Index: Integer]: PCREString read GetSubExpressions; + // Matched subexpressions after a regex has been matched + property SubExpressionLengths[Index: Integer]: Integer read GetSubExpressionLengths; + // Lengths of the subexpressions + property SubExpressionOffsets[Index: Integer]: Integer read GetSubExpressionOffsets; + // Character offsets in the Subject PCREString of the subexpressions + property Subject: PCREString read FSubject write SetSubject; + // The PCREString on which Match() will try to match RegEx + property SubjectLeft: PCREString read GetSubjectLeft; + // Part of the subject to the left of the match + property SubjectRight: PCREString read GetSubjectRight; + // Part of the subject to the right of the match + published + property Options: TPerlRegExOptions read FOptions write SetOptions; + // Options + property RegEx: PCREString read FRegEx write SetRegEx; + // The regular expression to be matched + property Replacement: PCREString read FReplacement write FReplacement; + // PCREString to replace matched expression with. \number backreferences will be substituted with SubExpressions + // TPerlRegEx supports the "JGsoft" replacement text flavor as explained at http://www.regular-expressions.info/refreplace.html + property OnMatch: TNotifyEvent read FOnMatch write FOnMatch; + // Triggered by Match and MatchAgain after a successful match + property OnReplace: TPerlRegExReplaceEvent read FOnReplace write FOnReplace; + // Triggered by Replace and ReplaceAll just before the replacement is done, allowing you to determine the new PCREString + end; + +{ + You can add TPerlRegEx components to a TPerlRegExList to match them all together on the same subject, + as if they were one regex regex1|regex2|regex3|... + TPerlRegExList does not own the TPerlRegEx components, just like a TList + If a TPerlRegEx has been added to a TPerlRegExList, it should not be used in any other situation + until it is removed from the list +} + +type + TPerlRegExList = class + private + FList: TList; + FSubject: PCREString; + FMatchedRegEx: TPerlRegEx; + FStart, FStop: Integer; + function GetRegEx(Index: Integer): TPerlRegEx; + procedure SetRegEx(Index: Integer; Value: TPerlRegEx); + procedure SetSubject(const Value: PCREString); + procedure SetStart(const Value: Integer); + procedure SetStop(const Value: Integer); + function GetCount: Integer; + protected + procedure UpdateRegEx(ARegEx: TPerlRegEx); + public + constructor Create; + destructor Destroy; override; + public + function Add(ARegEx: TPerlRegEx): Integer; + procedure Clear; + procedure Delete(Index: Integer); + function IndexOf(ARegEx: TPerlRegEx): Integer; + procedure Insert(Index: Integer; ARegEx: TPerlRegEx); + public + function Match: Boolean; + function MatchAgain: Boolean; + property RegEx[Index: Integer]: TPerlRegEx read GetRegEx write SetRegEx; + property Count: Integer read GetCount; + property Subject: PCREString read FSubject write SetSubject; + property Start: Integer read FStart write SetStart; + property Stop: Integer read FStop write SetStop; + property MatchedRegEx: TPerlRegEx read FMatchedRegEx; + end; + +procedure Register; + +implementation + + + { ********* Unit support routines ********* } + +procedure Register; +begin + RegisterComponents('JGsoft', [TPerlRegEx]); +end; + +function FirstCap(const S: string): string; +begin + if S = '' then Result := '' + else begin + Result := AnsiLowerCase(S); + {$IFDEF UNICODE} + CharUpperBuffW(@Result[1], 1); + {$ELSE} + CharUpperBuffA(@Result[1], 1); + {$ENDIF} + end +end; + +function InitialCaps(const S: string): string; +var + I: Integer; + Up: Boolean; +begin + Result := AnsiLowerCase(S); + Up := True; +{$IFDEF UNICODE} + for I := 1 to Length(Result) do begin + case Result[I] of + #0..'&', '(', '*', '+', ',', '-', '.', '?', '<', '[', '{', #$00B7: + Up := True + else + if Up and (Result[I] <> '''') then begin + CharUpperBuffW(@Result[I], 1); + Up := False + end + end; + end; +{$ELSE UNICODE} + if SysLocale.FarEast then begin + I := 1; + while I <= Length(Result) do begin + if Result[I] in LeadBytes then begin + Inc(I, 2) + end + else begin + if Result[I] in [#0..'&', '('..'.', '?', '<', '[', '{'] then Up := True + else if Up and (Result[I] <> '''') then begin + CharUpperBuffA(@Result[I], 1); + Result[I] := UpperCase(Result[I])[1]; + Up := False + end; + Inc(I) + end + end + end + else + for I := 1 to Length(Result) do begin + if Result[I] in [#0..'&', '('..'.', '?', '<', '[', '{', #$B7] then Up := True + else if Up and (Result[I] <> '''') then begin + CharUpperBuffA(@Result[I], 1); + Result[I] := AnsiUpperCase(Result[I])[1]; + Up := False + end + end; +{$ENDIF UNICODE} +end; + + + { ********* TPerlRegEx component ********* } + +procedure TPerlRegEx.CleanUp; +begin + FCompiled := False; FStudied := False; + pcre_dispose(pattern, hints, nil); + pattern := nil; + hints := nil; + ClearStoredSubExpressions; + OffsetCount := 0; +end; + +procedure TPerlRegEx.ClearStoredSubExpressions; +begin + FHasStoredSubExpressions := False; + FStoredSubExpressions := nil; +end; + +procedure TPerlRegEx.Compile; +var + Error: PAnsiChar; + ErrorOffset: Integer; +begin + if FRegEx = '' then + raise Exception.Create('TPerlRegEx.Compile() - Please specify a regular expression in RegEx first'); + CleanUp; + Pattern := pcre_compile(PAnsiChar(FRegEx), pcreOptions, @Error, @ErrorOffset, chartable); + if Pattern = nil then + raise Exception.Create(Format('TPerlRegEx.Compile() - Error in regex at offset %d: %s', [ErrorOffset, AnsiString(Error)])); + FCompiled := True +end; + +(* Backreference overview: + +Assume there are 13 backreferences: + +Text TPerlRegex .NET Java ECMAScript +$17 $1 + "7" "$17" $1 + "7" $1 + "7" +$017 $1 + "7" "$017" $1 + "7" $1 + "7" +$12 $12 $12 $12 $12 +$012 $1 + "2" $12 $12 $1 + "2" +${1}2 $1 + "2" $1 + "2" error "${1}2" +$$ "$" "$" error "$" +\$ "$" "\$" "$" "\$" +*) + +function TPerlRegEx.ComputeReplacement: PCREString; +var + Mode: AnsiChar; + S: PCREString; + I, J, N: Integer; + + procedure ReplaceBackreference(Number: Integer); + var + Backreference: PCREString; + begin + Delete(S, I, J-I); + if Number <= SubExpressionCount then begin + Backreference := SubExpressions[Number]; + if Backreference <> '' then begin + // Ignore warnings; converting to UTF-8 does not cause data loss + case Mode of + 'L', 'l': Backreference := AnsiLowerCase(Backreference); + 'U', 'u': Backreference := AnsiUpperCase(Backreference); + 'F', 'f': Backreference := FirstCap(Backreference); + 'I', 'i': Backreference := InitialCaps(Backreference); + end; + if S <> '' then begin + Insert(Backreference, S, I); + I := I + Length(Backreference); + end + else begin + S := Backreference; + I := MaxInt; + end + end; + end + end; + + procedure ProcessBackreference(NumberOnly, Dollar: Boolean); + var + Number, Number2: Integer; + Group: PCREString; + begin + Number := -1; + if (J <= Length(S)) and (S[J] in ['0'..'9']) then begin + // Get the number of the backreference + Number := Ord(S[J]) - Ord('0'); + Inc(J); + if (J <= Length(S)) and (S[J] in ['0'..'9']) then begin + // Expand it to two digits only if that would lead to a valid backreference + Number2 := Number*10 + Ord(S[J]) - Ord('0'); + if Number2 <= SubExpressionCount then begin + Number := Number2; + Inc(J) + end; + end; + end + else if not NumberOnly then begin + if Dollar and (J < Length(S)) and (S[J] = '{') then begin + // Number or name in curly braces + Inc(J); + case S[J] of + '0'..'9': begin + Number := Ord(S[J]) - Ord('0'); + Inc(J); + while (J <= Length(S)) and (S[J] in ['0'..'9']) do begin + Number := Number*10 + Ord(S[J]) - Ord('0'); + Inc(J) + end; + end; + 'A'..'Z', 'a'..'z', '_': begin + Inc(J); + while (J <= Length(S)) and (S[J] in ['A'..'Z', 'a'..'z', '0'..'9', '_']) do Inc(J); + if (J <= Length(S)) and (S[J] = '}') then begin + Group := Copy(S, I+2, J-I-2); + Number := NamedSubExpression(Group); + end + end; + end; + if (J > Length(S)) or (S[J] <> '}') then Number := -1 + else Inc(J) + end + else if Dollar and (S[J] = '_') then begin + // $_ (whole subject) + Delete(S, I, J+1-I); + Insert(Subject, S, I); + I := I + Length(Subject); + Exit; + end + else case S[J] of + '&': begin + // \& or $& (whole regex match) + Number := 0; + Inc(J); + end; + '+': begin + // \+ or $+ (highest-numbered participating group) + Number := SubExpressionCount; + Inc(J); + end; + '`': begin + // \` or $` (backtick; subject to the left of the match) + Delete(S, I, J+1-I); + Insert(SubjectLeft, S, I); + I := I + Offsets[0] - 1; + Exit; + end; + '''': begin + // \' or $' (straight quote; subject to the right of the match) + Delete(S, I, J+1-I); + Insert(SubjectRight, S, I); + I := I + Length(Subject) - Offsets[1]; + Exit; + end + end; + end; + if Number >= 0 then ReplaceBackreference(Number) + else Inc(I) + end; + +begin + S := FReplacement; + I := 1; + while I < Length(S) do begin + case S[I] of + '\': begin + J := I + 1; + Assert(J <= Length(S), 'CHECK: We let I stop one character before the end, so J cannot point beyond the end of the PCREString here'); + case S[J] of + '$', '\': begin + Delete(S, I, 1); + Inc(I); + end; + 'g': begin + if (J < Length(S)-1) and (S[J+1] = '<') and (S[J+2] in ['A'..'Z', 'a'..'z', '_']) then begin + // Python-style named group reference \g + J := J+3; + while (J <= Length(S)) and (S[J] in ['0'..'9', 'A'..'Z', 'a'..'z', '_']) do Inc(J); + if (J <= Length(S)) and (S[J] = '>') then begin + N := NamedSubExpression(Copy(S, I+3, J-I-3)); + Inc(J); + Mode := #0; + if N > 0 then ReplaceBackreference(N) + else Delete(S, I, J-I) + end + else I := J + end + else I := I+2; + end; + 'l', 'L', 'u', 'U', 'f', 'F', 'i', 'I': begin + Mode := S[J]; + Inc(J); + ProcessBackreference(True, False); + end; + else begin + Mode := #0; + ProcessBackreference(False, False); + end; + end; + end; + '$': begin + J := I + 1; + Assert(J <= Length(S), 'CHECK: We let I stop one character before the end, so J cannot point beyond the end of the PCREString here'); + if S[J] = '$' then begin + Delete(S, J, 1); + Inc(I); + end + else begin + Mode := #0; + ProcessBackreference(False, True); + end + end; + else Inc(I) + end + end; + Result := S +end; + +constructor TPerlRegEx.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FState := [preNotEmpty]; + chartable := pcre_maketables; +{$IFDEF UNICODE} + pcreOptions := PCRE_UTF8 or PCRE_NEWLINE_ANY; +{$ELSE} + pcreOptions := PCRE_NEWLINE_ANY; +{$ENDIF} +end; + +destructor TPerlRegEx.Destroy; +begin + pcre_dispose(pattern, hints, chartable); + inherited Destroy; +end; + +class function TPerlRegEx.EscapeRegExChars(const S: string): string; +var + I: Integer; +begin + Result := S; + I := Length(Result); + while I > 0 do begin + case Result[I] of + '.', '[', ']', '(', ')', '?', '*', '+', '{', '}', '^', '$', '|', '\': + Insert('\', Result, I); + #0: begin + Result[I] := '0'; + Insert('\', Result, I); + end; + end; + Dec(I); + end; +end; + +function TPerlRegEx.GetFoundMatch: Boolean; +begin + Result := OffsetCount > 0; +end; + +function TPerlRegEx.GetMatchedExpression: PCREString; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + Result := GetSubExpressions(0); +end; + +function TPerlRegEx.GetMatchedExpressionLength: Integer; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + Result := GetSubExpressionLengths(0) +end; + +function TPerlRegEx.GetMatchedExpressionOffset: Integer; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + Result := GetSubExpressionOffsets(0) +end; + +function TPerlRegEx.GetSubExpressionCount: Integer; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + Result := OffsetCount-1 +end; + +function TPerlRegEx.GetSubExpressionLengths(Index: Integer): Integer; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + Assert((Index >= 0) and (Index <= SubExpressionCount), 'REQUIRE: Index <= SubExpressionCount'); + Result := Offsets[Index*2+1]-Offsets[Index*2] +end; + +function TPerlRegEx.GetSubExpressionOffsets(Index: Integer): Integer; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + Assert((Index >= 0) and (Index <= SubExpressionCount), 'REQUIRE: Index <= SubExpressionCount'); + Result := Offsets[Index*2] +end; + +function TPerlRegEx.GetSubExpressions(Index: Integer): PCREString; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + if Index > SubExpressionCount then Result := '' + else if FHasStoredSubExpressions then Result := FStoredSubExpressions[Index] + else Result := Copy(FSubject, Offsets[Index*2], Offsets[Index*2+1]-Offsets[Index*2]); +end; + +function TPerlRegEx.GetSubjectLeft: PCREString; +begin + Result := Copy(Subject, 1, Offsets[0]-1); +end; + +function TPerlRegEx.GetSubjectRight: PCREString; +begin + Result := Copy(Subject, Offsets[1], MaxInt); +end; + +function TPerlRegEx.Match: Boolean; +var + I, Opts: Integer; +begin + ClearStoredSubExpressions; + if not Compiled then Compile; + if preNotBOL in State then Opts := PCRE_NOTBOL else Opts := 0; + if preNotEOL in State then Opts := Opts or PCRE_NOTEOL; + if preNotEmpty in State then Opts := Opts or PCRE_NOTEMPTY; + OffsetCount := pcre_exec(Pattern, Hints, FSubjectPChar, FStop, 0, Opts, @Offsets[0], High(Offsets)); + Result := OffsetCount > 0; + // Convert offsets into PCREString indices + if Result then begin + for I := 0 to OffsetCount*2-1 do + Inc(Offsets[I]); + FStart := Offsets[1]; + if Offsets[0] = Offsets[1] then Inc(FStart); // Make sure we don't get stuck at the same position + if Assigned(OnMatch) then OnMatch(Self) + end; +end; + +function TPerlRegEx.MatchAgain: Boolean; +var + I, Opts: Integer; +begin + ClearStoredSubExpressions; + if not Compiled then Compile; + if preNotBOL in State then Opts := PCRE_NOTBOL else Opts := 0; + if preNotEOL in State then Opts := Opts or PCRE_NOTEOL; + if preNotEmpty in State then Opts := Opts or PCRE_NOTEMPTY; + if FStart-1 > FStop then OffsetCount := -1 + else OffsetCount := pcre_exec(Pattern, Hints, FSubjectPChar, FStop, FStart-1, Opts, @Offsets[0], High(Offsets)); + Result := OffsetCount > 0; + // Convert offsets into PCREString indices + if Result then begin + for I := 0 to OffsetCount*2-1 do + Inc(Offsets[I]); + FStart := Offsets[1]; + if Offsets[0] = Offsets[1] then Inc(FStart); // Make sure we don't get stuck at the same position + if Assigned(OnMatch) then OnMatch(Self) + end; +end; + +function TPerlRegEx.NamedSubExpression(const SEName: PCREString): Integer; +begin + Result := pcre_get_stringnumber(Pattern, PAnsiChar(SEName)); +end; + +function TPerlRegEx.Replace: PCREString; +begin + Assert(FoundMatch, 'REQUIRE: There must be a successful match first'); + // Substitute backreferences + Result := ComputeReplacement; + // Allow for just-in-time substitution determination + if Assigned(OnReplace) then OnReplace(Self, Result); + // Perform substitution + Delete(FSubject, MatchedExpressionOffset, MatchedExpressionLength); + if Result <> '' then Insert(Result, FSubject, MatchedExpressionOffset); + FSubjectPChar := PAnsiChar(FSubject); + // Position to continue search + FStart := FStart - MatchedExpressionLength + Length(Result); + FStop := FStop - MatchedExpressionLength + Length(Result); + // Replacement no longer matches regex, we assume + ClearStoredSubExpressions; + OffsetCount := 0; +end; + +function TPerlRegEx.ReplaceAll: Boolean; +begin + if Match then begin + Result := True; + repeat + Replace + until not MatchAgain; + end + else Result := False; +end; + +procedure TPerlRegEx.SetOptions(Value: TPerlRegExOptions); +begin + if (FOptions <> Value) then begin + FOptions := Value; + {$IFDEF UNICODE} + pcreOptions := PCRE_UTF8 or PCRE_NEWLINE_ANY; + {$ELSE} + pcreOptions := PCRE_NEWLINE_ANY; + {$ENDIF} + if (preCaseLess in Value) then pcreOptions := pcreOptions or PCRE_CASELESS; + if (preMultiLine in Value) then pcreOptions := pcreOptions or PCRE_MULTILINE; + if (preSingleLine in Value) then pcreOptions := pcreOptions or PCRE_DOTALL; + if (preExtended in Value) then pcreOptions := pcreOptions or PCRE_EXTENDED; + if (preAnchored in Value) then pcreOptions := pcreOptions or PCRE_ANCHORED; + if (preUnGreedy in Value) then pcreOptions := pcreOptions or PCRE_UNGREEDY; + if (preNoAutoCapture in Value) then pcreOptions := pcreOptions or PCRE_NO_AUTO_CAPTURE; + CleanUp + end +end; + +procedure TPerlRegEx.SetRegEx(const Value: PCREString); +begin + if FRegEx <> Value then begin + FRegEx := Value; + CleanUp + end +end; + +procedure TPerlRegEx.SetStart(const Value: Integer); +begin + if Value < 1 then FStart := 1 + else FStart := Value; + // If FStart > Length(Subject), MatchAgain() will simply return False +end; + +procedure TPerlRegEx.SetStop(const Value: Integer); +begin + if Value > Length(Subject) then FStop := Length(Subject) + else FStop := Value; +end; + +procedure TPerlRegEx.SetSubject(const Value: PCREString); +begin + FSubject := Value; + FSubjectPChar := PAnsiChar(Value); + FStart := 1; + FStop := Length(Subject); + if not FHasStoredSubExpressions then OffsetCount := 0; +end; + +procedure TPerlRegEx.Split(Strings: TStrings; Limit: Integer); +var + Offset, Count: Integer; +begin + Assert(Strings <> nil, 'REQUIRE: Strings'); + if (Limit = 1) or not Match then Strings.Add(Subject) + else begin + Offset := 1; + Count := 1; + repeat + Strings.Add(Copy(Subject, Offset, MatchedExpressionOffset - Offset)); + Inc(Count); + Offset := MatchedExpressionOffset + MatchedExpressionLength; + until ((Limit > 1) and (Count >= Limit)) or not MatchAgain; + Strings.Add(Copy(Subject, Offset, MaxInt)); + end +end; + +procedure TPerlRegEx.StoreSubExpressions; +var + I: Integer; +begin + if OffsetCount > 0 then begin + ClearStoredSubExpressions; + SetLength(FStoredSubExpressions, SubExpressionCount+1); + for I := SubExpressionCount downto 0 do + FStoredSubExpressions[I] := SubExpressions[I]; + FHasStoredSubExpressions := True; + end +end; + +procedure TPerlRegEx.Study; +var + Error: PAnsiChar; +begin + if not FCompiled then Compile; + Hints := pcre_study(Pattern, 0, @Error); + if Error <> nil then + raise Exception.Create('TPerlRegEx.Study() - Error studying the regex: ' + AnsiString(Error)); + FStudied := True +end; + +{ TPerlRegExList } + +function TPerlRegExList.Add(ARegEx: TPerlRegEx): Integer; +begin + Result := FList.Add(ARegEx); + UpdateRegEx(ARegEx); +end; + +procedure TPerlRegExList.Clear; +begin + FList.Clear; +end; + +constructor TPerlRegExList.Create; +begin + inherited Create; + FList := TList.Create; +end; + +procedure TPerlRegExList.Delete(Index: Integer); +begin + FList.Delete(Index); +end; + +destructor TPerlRegExList.Destroy; +begin + FList.Free; + inherited +end; + +function TPerlRegExList.GetCount: Integer; +begin + Result := FList.Count; +end; + +function TPerlRegExList.GetRegEx(Index: Integer): TPerlRegEx; +begin + Result := TPerlRegEx(Pointer(FList[Index])); +end; + +function TPerlRegExList.IndexOf(ARegEx: TPerlRegEx): Integer; +begin + Result := FList.IndexOf(ARegEx); +end; + +procedure TPerlRegExList.Insert(Index: Integer; ARegEx: TPerlRegEx); +begin + FList.Insert(Index, ARegEx); + UpdateRegEx(ARegEx); +end; + +function TPerlRegExList.Match: Boolean; +begin + SetStart(1); + FMatchedRegEx := nil; + Result := MatchAgain; +end; + +function TPerlRegExList.MatchAgain: Boolean; +var + I, MatchStart, MatchPos: Integer; + ARegEx: TPerlRegEx; +begin + if FMatchedRegEx <> nil then + MatchStart := FMatchedRegEx.MatchedExpressionOffset + FMatchedRegEx.MatchedExpressionLength + else + MatchStart := FStart; + FMatchedRegEx := nil; + MatchPos := MaxInt; + for I := 0 to Count-1 do begin + ARegEx := RegEx[I]; + if (not ARegEx.FoundMatch) or (ARegEx.MatchedExpressionOffset < MatchStart) then begin + ARegEx.Start := MatchStart; + ARegEx.MatchAgain; + end; + if ARegEx.FoundMatch and (ARegEx.MatchedExpressionOffset < MatchPos) then begin + MatchPos := ARegEx.MatchedExpressionOffset; + FMatchedRegEx := ARegEx; + end; + if MatchPos = MatchStart then Break; + end; + Result := MatchPos < MaxInt; +end; + +procedure TPerlRegExList.SetRegEx(Index: Integer; Value: TPerlRegEx); +begin + FList[Index] := Value; + UpdateRegEx(Value); +end; + +procedure TPerlRegExList.SetStart(const Value: Integer); +var + I: Integer; +begin + if FStart <> Value then begin + FStart := Value; + for I := Count-1 downto 0 do + RegEx[I].Start := Value; + FMatchedRegEx := nil; + end; +end; + +procedure TPerlRegExList.SetStop(const Value: Integer); +var + I: Integer; +begin + if FStop <> Value then begin + FStop := Value; + for I := Count-1 downto 0 do + RegEx[I].Stop := Value; + FMatchedRegEx := nil; + end; +end; + +procedure TPerlRegExList.SetSubject(const Value: PCREString); +var + I: Integer; +begin + if FSubject <> Value then begin + FSubject := Value; + for I := Count-1 downto 0 do + RegEx[I].Subject := Value; + FMatchedRegEx := nil; + end; +end; + +procedure TPerlRegExList.UpdateRegEx(ARegEx: TPerlRegEx); +begin + ARegEx.Subject := FSubject; + ARegEx.Start := FStart; +end; + +end. diff --git a/System/RegexHelper.pas b/System/RegexHelper.pas new file mode 100644 index 0000000..3d46ffd --- /dev/null +++ b/System/RegexHelper.pas @@ -0,0 +1,90 @@ +unit RegexHelper; + +interface + uses Global, SysUtils, StrUtils, RegularExpressionsCore; + + type T2Int = record + i1, i2: integer; + end; + type T2Float = record + f1, f2: extended; + end; + type TRgb = record + r, g, b: integer; + end; + +function GetStringPart(text, expression: string; group: integer; def: string): string; +function GetBoolPart(text, expression: string; group: integer; def: boolean): boolean; +function GetIntPart(text, expression: string; group: integer; def: integer): integer; +function GetFloatPart(text, expression: string; group: integer; def: extended): extended; +function Get2IntPart(text, expression: string; group: integer; def: integer): T2Int; +function Get2FloatPart(text, expression: string; group: integer; def: extended): T2Float; +function GetRGBPart(text, expression: string; group: integer; def: integer): TRGB; + +implementation + +(* ***************************** Extract functions ******************************* *) +function GetStringPart(text, expression: string; group: integer; def: string): string; +var Regex: TPerlRegEx; +begin + Regex := TPerlRegEx.Create; + Regex.RegEx := Utf8String(expression); + Regex.Options := [preSingleLine, preCaseless]; + Regex.Subject := Utf8String(text); + + if Regex.Match and (Regex.GroupCount >= group) then + Result := String(Regex.Groups[group]) + else Result := def; + + Regex.Free; +end; +function GetBoolPart(text, expression: string; group: integer; def: boolean): boolean; +begin + Result := GetFloatPart(text, expression, group, StrToFloat(IfThen(def, '1', '0'))) <> 0; +end; +function GetIntPart(text, expression: string; group: integer; def: integer): integer; +var str: string; +begin + str := GetStringPart(text, expression, group, ''); + Result := StrToIntDef(str, def); +end; +function GetFloatPart(text, expression: string; group: integer; def: extended): extended; +var str: string; +begin + str := GetStringPart(text, expression, group, ''); + Result := StrToFloatDef(str, def); +end; +function Get2IntPart(text, expression: string; group: integer; def: integer): T2Int; +const expr : string = '(\d+)\s+(\d+)'; +var str, s1, s2: string; +begin + str := GetStringPart(text, expression, group, IntToStr(def) + ' ' + IntToStr(def)); + s1 := GetStringPart(str, expr, 1, IntToStr(def)); + s2 := GetStringPart(str, expr, 2, IntToStr(def)); + Result.i1 := StrToIntDef(s1, def); + Result.i2 := StrToIntDef(s2, def); +end; +function Get2FloatPart(text, expression: string; group: integer; def: extended): T2Float; +const expr : string = '([\d.eE+-]+)\s+([\d.eE+-]+)'; +var str, s1, s2: string; +begin + str := GetStringPart(text, expression, group, FloatToStr(def) + ' ' + FloatToStr(def)); + s1 := GetStringPart(str, expr, 1, FloatToStr(def)); + s2 := GetStringPart(str, expr, 2, FloatToStr(def)); + Result.f1 := StrToFloatDef(s1, def); + Result.f2 := StrToFloatDef(s2, def); +end; +function GetRGBPart(text, expression: string; group: integer; def: integer): TRGB; +const expr : string = '(\d+)\s+(\d+)\s+(\d+)'; +var str, s1, s2, s3: string; +begin + str := GetStringPart(text, expression, group, IntToStr(def) + ' ' + IntToStr(def) + ' ' + IntToStr(def)); + s1 := GetStringPart(str, expr, 1, IntToStr(def)); + s2 := GetStringPart(str, expr, 2, IntToStr(def)); + s3 := GetStringPart(str, expr, 3, IntToStr(def)); + Result.r := StrToIntDef(s1, def); + Result.g := StrToIntDef(s2, def); + Result.b := StrToIntDef(s3, def); +end; + +end. diff --git a/System/Windows7.pas b/System/Windows7.pas new file mode 100644 index 0000000..ea23c3a --- /dev/null +++ b/System/Windows7.pas @@ -0,0 +1,155 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +unit Windows7; + +////////////////////////////////////////////////////////////////////////////// +interface +////////////////////////////////////////////////////////////////////////////// + +uses + Forms, Types, Windows, SysUtils, ComObj, Controls, Graphics; + +type + TTaskBarProgressState = (tbpsNone, tbpsIndeterminate, tbpsNormal, tbpsError, tbpsPaused); + +function InitializeTaskbarAPI: Boolean; +function SetTaskbarProgressState(const AState: TTaskBarProgressState): Boolean; +function SetTaskbarProgressValue(const ACurrent:UInt64; const AMax: UInt64): Boolean; + +////////////////////////////////////////////////////////////////////////////// +implementation +////////////////////////////////////////////////////////////////////////////// + +const + TASKBAR_CID: TGUID = '{56FDF344-FD6D-11d0-958A-006097C9A090}'; + +const + TBPF_NOPROGRESS = 0; + TBPF_INDETERMINATE = 1; + TBPF_NORMAL = 2; + TBPF_ERROR = 4; + TBPF_PAUSED = 8; + +type + ITaskBarList3 = interface(IUnknown) + ['{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}'] + function HrInit(): HRESULT; stdcall; + function AddTab(hwnd: THandle): HRESULT; stdcall; + function DeleteTab(hwnd: THandle): HRESULT; stdcall; + function ActivateTab(hwnd: THandle): HRESULT; stdcall; + function SetActiveAlt(hwnd: THandle): HRESULT; stdcall; + function MarkFullscreenWindow(hwnd: THandle; fFullscreen: Boolean): HRESULT; stdcall; + function SetProgressValue(hwnd: THandle; ullCompleted: UInt64; ullTotal: UInt64): HRESULT; stdcall; + function SetProgressState(hwnd: THandle; tbpFlags: Cardinal): HRESULT; stdcall; + function RegisterTab(hwnd: THandle; hwndMDI: THandle): HRESULT; stdcall; + function UnregisterTab(hwndTab: THandle): HRESULT; stdcall; + function SetTabOrder(hwndTab: THandle; hwndInsertBefore: THandle): HRESULT; stdcall; + function SetTabActive(hwndTab: THandle; hwndMDI: THandle; tbatFlags: Cardinal): HRESULT; stdcall; + function ThumbBarAddButtons(hwnd: THandle; cButtons: Cardinal; pButtons: Pointer): HRESULT; stdcall; + function ThumbBarUpdateButtons(hwnd: THandle; cButtons: Cardinal; pButtons: Pointer): HRESULT; stdcall; + function ThumbBarSetImageList(hwnd: THandle; himl: THandle): HRESULT; stdcall; + function SetOverlayIcon(hwnd: THandle; hIcon: THandle; pszDescription: PChar): HRESULT; stdcall; + function SetThumbnailTooltip(hwnd: THandle; pszDescription: PChar): HRESULT; stdcall; + function SetThumbnailClip(hwnd: THandle; var prcClip: TRect): HRESULT; stdcall; + end; + +////////////////////////////////////////////////////////////////////////////// + +var + GlobalTaskBarInterface: ITaskBarList3; + +function InitializeTaskbarAPI: Boolean; +var + Unknown: IInterface; + Temp: ITaskBarList3; +begin + if Assigned(GlobalTaskBarInterface) then + begin + Result := True; + Exit; + end; + + try + Unknown := CreateComObject(TASKBAR_CID); + if Assigned(Unknown) then + begin + Temp := Unknown as ITaskBarList3; + if Temp.HrInit() = S_OK then + begin + GlobalTaskBarInterface := Temp; + end; + end; + except + GlobalTaskBarInterface := nil; + end; + + Result := Assigned(GlobalTaskBarInterface); +end; + +function CheckAPI:Boolean; +begin + Result := Assigned(GlobalTaskBarInterface); +end; + +////////////////////////////////////////////////////////////////////////////// + +function SetTaskbarProgressState(const AState: TTaskBarProgressState): Boolean; +var + Flag: Cardinal; +begin + Result := False; + + if CheckAPI then + begin + case AState of + tbpsIndeterminate: Flag := TBPF_INDETERMINATE; + tbpsNormal: Flag := TBPF_NORMAL; + tbpsError: Flag := TBPF_ERROR; + tbpsPaused: Flag := TBPF_PAUSED; + else + Flag := TBPF_NOPROGRESS; + end; + Result := GlobalTaskBarInterface.SetProgressState(Application.Handle, Flag) = S_OK; + end; +end; + +function SetTaskbarProgressValue(const ACurrent:UInt64; const AMax: UInt64): Boolean; +begin + Result := False; + + if CheckAPI then + begin + Result := GlobalTaskBarInterface.SetProgressValue(Application.Handle, ACurrent, AMax) = S_OK; + end; +end; + +////////////////////////////////////////////////////////////////////////////// + +initialization + GlobalTaskBarInterface := nil; + +finalization + GlobalTaskBarInterface := nil; + +////////////////////////////////////////////////////////////////////////////// + +end. \ No newline at end of file diff --git a/System/ZLibEx.inc b/System/ZLibEx.inc new file mode 100644 index 0000000..fadeb88 --- /dev/null +++ b/System/ZLibEx.inc @@ -0,0 +1,146 @@ +{***************************************************************************** +* ZLibEx.inc * +* copyright (c) 2006-2009 base2 technologies * +* * +* version information for delphi/c++ builder * +* * +* revision history * +* 2009.04.11 updated to use CONDITIONALEXPRESSIONS and CompilerVersion * +* 2009.01.28 updated for delphi 2009 * +* 2007.10.01 updated for delphi 2007 * +* 2005.11.29 created * +* * +* acknowledgments * +* iztok kacin * +* 2009.04.11 CONDITIONALEXPRESSIONS and CompilerVersion changes * +*****************************************************************************} + +{$ifndef CONDITIONALEXPRESSIONS} + + {** delphi ****************************************************************} + + {$ifdef VER80} // delphi 1 + {$define Delphi} + + {$define Version1} + {$endif} + + {$ifdef VER90} // delphi 2 + {$define Delphi} + + {$define Version2} + {$endif} + + {$ifdef VER100} // delphi 3 + {$define Delphi} + + {$define Version3} + {$endif} + + {$ifdef VER120} // delphi 4 + {$define Delphi} + + {$define Version4} + {$endif} + + {** c++ builder ***********************************************************} + + {$ifdef VER93} // c++ builder 1 + {$define CBuilder} + + {$define Version1} + {$endif} + + {$ifdef VER110} // c++ builder 3 + {$define CBuilder} + + {$define Version3} + {$endif} + + {$ifdef VER125} // c++ builder 4 + {$define CBuilder} + + {$define Version4} + {$endif} + + {** delphi/c++ builder (common) *******************************************} + + {$ifdef VER130} // delphi/c++ builder 5 + {$ifdef BCB} + {$define CBuilder} + {$ELSE} + {$define Delphi} + {$endif} + + {$define Version5} + + {$define Version5Plus} + {$endif} + +{$ELSE} + + {$ifdef BCB} + {$define CBuilder} + {$ELSE} + {$define Delphi} + {$endif} + + {$define Version5Plus} + + {$if CompilerVersion >= 14.0} // delphi 6 + {$ifdef VER140} + {$define Version6} + {$endif} + + {$define Version6Plus} + {$ifend} + + {$if CompilerVersion >= 15.0} // delphi 7 + {$ifdef VER150} + {$define Version7} + {$endif} + + {$define Version7Plus} + {$ifend} + + {$if CompilerVersion >= 16.0} // delphi 8 (.net) + {$ifdef VER160} + {$define Version8} + {$endif} + + {$define Version8Plus} + {$ifend} + + {$if CompilerVersion >= 17.0} // delphi 2005 + {$ifdef VER170} + {$define Version2005} + {$endif} + + {$define Version2005Plus} + {$ifend} + + {$if CompilerVersion >= 18.0} // bds 2006 + {$ifdef VER180} + {$define Version2006} + {$endif} + + {$define Version2006Plus} + {$ifend} + + {$if CompilerVersion >= 18.5} // bds 2007 + {$ifdef VER185} + {$define Version2007} + {$endif} + + {$define Version2007Plus} + {$ifend} + + {$if CompilerVersion >= 20.0} // bds 2009 + {$ifdef VER200} + {$define Version2009} + {$endif} + + {$define Version2009Plus} + {$ifend} + +{$endif} diff --git a/System/pcre.pas b/System/pcre.pas new file mode 100644 index 0000000..952a1f5 --- /dev/null +++ b/System/pcre.pas @@ -0,0 +1,1159 @@ +{**************************************************************************************************} +{ } +{ Project JEDI Code Library (JCL) } +{ } +{ 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 pcre.pas. } +{ } +{ The Initial Developer of the Original Code is Peter Thornqvist. } +{ Portions created by Peter Thornqvist are Copyright (C) of Peter Thornqvist. All rights reserved. } +{ Portions created by University of Cambridge are } +{ Copyright (C) 1997-2001 by University of Cambridge. } +{ } +{ Contributor(s): } +{ Robert Rossmair (rrossmair) } +{ Mario R. Carro } +{ Florent Ouchet (outchy) } +{ } +{ The latest release of PCRE is always available from } +{ ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz } +{ } +{ Modified by Jan Goyvaerts for use with TPerlRegEx } +{ TPerlRegEx is available at http://www.regular-expressions.info/delphi.html } +{ } +{**************************************************************************************************} +{ } +{ Header conversion of pcre.h } +{ } +{**************************************************************************************************} + +unit pcre; + +interface + +(************************************************* +* Perl-Compatible Regular Expressions * +*************************************************) + +{$WEAKPACKAGEUNIT ON} + +//{$IFDEF CONDITIONALEXPRESSIONS} + //{$IF COMPILERVERSION >= 21.0} + // Define PCRE_STATICLINK to link the OBJ files with PCRE 7.9. + // This works correctly in all cases with Delphi 2010 (and later). + {$DEFINE PCRE_STATICLINK} + //{$ELSE} + // Delphi 2009 and earlier have a compiler bug that may cause an internal error if install TPerlRegEx + // into a design time package, and you don't put TPerlRegEx into a runtime package at the same time. + // With Delphi 2009 and earlier you can use PCRE_STATICLINK if you don't use packages at all + // (which means you don't install it into the IDE and you don't drop TPerlRegEx on a form) + // You can also use PCRE_STATICLINK if you put the component into a runtime package + + // Define PCRE_LINKDLL to use pcrelib.dll + //{$DEFINE PCRE_LINKDLL} +//{$IFEND} +//{$ELSE} + // Define PCRE_LINKDLL to use pcrelib.dll + //{$DEFINE PCRE_LINKDLL} +//{$ENDIF} + +// The supplied pcrelib.dll compiled PCRE 7.9 using the C calling convention +{$IFDEF PCRE_LINKDLL} + {$DEFINE PCRE_EXPORT_CDECL} +{$ENDIF} + +(*$HPPEMIT '#include "pcre.h"'*) + +const + MAX_PATTERN_LENGTH = $10003; + {$EXTERNALSYM MAX_PATTERN_LENGTH} + MAX_QUANTIFY_REPEAT = $10000; + {$EXTERNALSYM MAX_QUANTIFY_REPEAT} + MAX_CAPTURE_COUNT = $FFFF; + {$EXTERNALSYM MAX_CAPTURE_COUNT} + MAX_NESTING_DEPTH = 200; + {$EXTERNALSYM MAX_NESTING_DEPTH} + +const + (* Options *) + PCRE_CASELESS = $00000001; + {$EXTERNALSYM PCRE_CASELESS} + PCRE_MULTILINE = $00000002; + {$EXTERNALSYM PCRE_MULTILINE} + PCRE_DOTALL = $00000004; + {$EXTERNALSYM PCRE_DOTALL} + PCRE_EXTENDED = $00000008; + {$EXTERNALSYM PCRE_EXTENDED} + PCRE_ANCHORED = $00000010; + {$EXTERNALSYM PCRE_ANCHORED} + PCRE_DOLLAR_ENDONLY = $00000020; + {$EXTERNALSYM PCRE_DOLLAR_ENDONLY} + PCRE_EXTRA = $00000040; + {$EXTERNALSYM PCRE_EXTRA} + PCRE_NOTBOL = $00000080; + {$EXTERNALSYM PCRE_NOTBOL} + PCRE_NOTEOL = $00000100; + {$EXTERNALSYM PCRE_NOTEOL} + PCRE_UNGREEDY = $00000200; + {$EXTERNALSYM PCRE_UNGREEDY} + PCRE_NOTEMPTY = $00000400; + {$EXTERNALSYM PCRE_NOTEMPTY} + PCRE_UTF8 = $00000800; + {$EXTERNALSYM PCRE_UTF8} + PCRE_NO_AUTO_CAPTURE = $00001000; + {$EXTERNALSYM PCRE_NO_AUTO_CAPTURE} + PCRE_NO_UTF8_CHECK = $00002000; + {$EXTERNALSYM PCRE_NO_UTF8_CHECK} + PCRE_AUTO_CALLOUT = $00004000; + {$EXTERNALSYM PCRE_AUTO_CALLOUT} + PCRE_PARTIAL = $00008000; + {$EXTERNALSYM PCRE_PARTIAL} + PCRE_DFA_SHORTEST = $00010000; + {$EXTERNALSYM PCRE_DFA_SHORTEST} + PCRE_DFA_RESTART = $00020000; + {$EXTERNALSYM PCRE_DFA_RESTART} + PCRE_FIRSTLINE = $00040000; + {$EXTERNALSYM PCRE_FIRSTLINE} + PCRE_DUPNAMES = $00080000; + {$EXTERNALSYM PCRE_DUPNAMES} + PCRE_NEWLINE_CR = $00100000; + {$EXTERNALSYM PCRE_NEWLINE_CR} + PCRE_NEWLINE_LF = $00200000; + {$EXTERNALSYM PCRE_NEWLINE_LF} + PCRE_NEWLINE_CRLF = $00300000; + {$EXTERNALSYM PCRE_NEWLINE_CRLF} + PCRE_NEWLINE_ANY = $00400000; + {$EXTERNALSYM PCRE_NEWLINE_ANY} + PCRE_NEWLINE_ANYCRLF = $00500000; + {$EXTERNALSYM PCRE_NEWLINE_ANYCRLF} + PCRE_BSR_ANYCRLF = $00800000; + {$EXTERNALSYM PCRE_BSR_ANYCRLF} + PCRE_BSR_UNICODE = $01000000; + {$EXTERNALSYM PCRE_BSR_UNICODE} + PCRE_JAVASCRIPT_COMPAT = $02000000; + {$EXTERNALSYM PCRE_JAVASCRIPT_COMPAT} + PCRE_NO_START_OPTIMIZE = $04000000; + {$EXTERNALSYM PCRE_NO_START_OPTIMIZE} + PCRE_NO_START_OPTIMISE = $04000000; + {$EXTERNALSYM PCRE_NO_START_OPTIMISE} + + (* Exec-time and get-time error codes *) + + PCRE_ERROR_NOMATCH = -1; + {$EXTERNALSYM PCRE_ERROR_NOMATCH} + PCRE_ERROR_NULL = -2; + {$EXTERNALSYM PCRE_ERROR_NULL} + PCRE_ERROR_BADOPTION = -3; + {$EXTERNALSYM PCRE_ERROR_BADOPTION} + PCRE_ERROR_BADMAGIC = -4; + {$EXTERNALSYM PCRE_ERROR_BADMAGIC} + PCRE_ERROR_UNKNOWN_NODE = -5; + {$EXTERNALSYM PCRE_ERROR_UNKNOWN_NODE} + PCRE_ERROR_NOMEMORY = -6; + {$EXTERNALSYM PCRE_ERROR_NOMEMORY} + PCRE_ERROR_NOSUBSTRING = -7; + {$EXTERNALSYM PCRE_ERROR_NOSUBSTRING} + PCRE_ERROR_MATCHLIMIT = -8; + {$EXTERNALSYM PCRE_ERROR_MATCHLIMIT} + PCRE_ERROR_CALLOUT = -9; (* Never used by PCRE itself *) + {$EXTERNALSYM PCRE_ERROR_CALLOUT} + PCRE_ERROR_BADUTF8 = -10; + {$EXTERNALSYM PCRE_ERROR_BADUTF8} + PCRE_ERROR_BADUTF8_OFFSET = -11; + {$EXTERNALSYM PCRE_ERROR_BADUTF8_OFFSET} + PCRE_ERROR_PARTIAL = -12; + {$EXTERNALSYM PCRE_ERROR_PARTIAL} + PCRE_ERROR_BADPARTIAL = -13; + {$EXTERNALSYM PCRE_ERROR_BADPARTIAL} + PCRE_ERROR_INTERNAL = -14; + {$EXTERNALSYM PCRE_ERROR_INTERNAL} + PCRE_ERROR_BADCOUNT = -15; + {$EXTERNALSYM PCRE_ERROR_BADCOUNT} + PCRE_ERROR_DFA_UITEM = -16; + {$EXTERNALSYM PCRE_ERROR_DFA_UITEM} + PCRE_ERROR_DFA_UCOND = -17; + {$EXTERNALSYM PCRE_ERROR_DFA_UCOND} + PCRE_ERROR_DFA_UMLIMIT = -18; + {$EXTERNALSYM PCRE_ERROR_DFA_UMLIMIT} + PCRE_ERROR_DFA_WSSIZE = -19; + {$EXTERNALSYM PCRE_ERROR_DFA_WSSIZE} + PCRE_ERROR_DFA_RECURSE = -20; + {$EXTERNALSYM PCRE_ERROR_DFA_RECURSE} + PCRE_ERROR_RECURSIONLIMIT = -21; + {$EXTERNALSYM PCRE_ERROR_RECURSIONLIMIT} + PCRE_ERROR_NULLWSLIMIT = -22; (* No longer actually used *) + {$EXTERNALSYM PCRE_ERROR_NULLWSLIMIT} + PCRE_ERROR_BADNEWLINE = -23; + {$EXTERNALSYM PCRE_ERROR_BADNEWLINE} + + (* Request types for pcre_fullinfo() *) + + PCRE_INFO_OPTIONS = 0; + {$EXTERNALSYM PCRE_INFO_OPTIONS} + PCRE_INFO_SIZE = 1; + {$EXTERNALSYM PCRE_INFO_SIZE} + PCRE_INFO_CAPTURECOUNT = 2; + {$EXTERNALSYM PCRE_INFO_CAPTURECOUNT} + PCRE_INFO_BACKREFMAX = 3; + {$EXTERNALSYM PCRE_INFO_BACKREFMAX} + PCRE_INFO_FIRSTCHAR = 4; + {$EXTERNALSYM PCRE_INFO_FIRSTCHAR} + PCRE_INFO_FIRSTTABLE = 5; + {$EXTERNALSYM PCRE_INFO_FIRSTTABLE} + PCRE_INFO_LASTLITERAL = 6; + {$EXTERNALSYM PCRE_INFO_LASTLITERAL} + PCRE_INFO_NAMEENTRYSIZE = 7; + {$EXTERNALSYM PCRE_INFO_NAMEENTRYSIZE} + PCRE_INFO_NAMECOUNT = 8; + {$EXTERNALSYM PCRE_INFO_NAMECOUNT} + PCRE_INFO_NAMETABLE = 9; + {$EXTERNALSYM PCRE_INFO_NAMETABLE} + PCRE_INFO_STUDYSIZE = 10; + {$EXTERNALSYM PCRE_INFO_STUDYSIZE} + PCRE_INFO_DEFAULT_TABLES = 11; + {$EXTERNALSYM PCRE_INFO_DEFAULT_TABLES} + PCRE_INFO_OKPARTIAL = 12; + {$EXTERNALSYM PCRE_INFO_OKPARTIAL} + PCRE_INFO_JCHANGED = 13; + {$EXTERNALSYM PCRE_INFO_JCHANGED} + PCRE_INFO_HASCRORLF = 14; + {$EXTERNALSYM PCRE_INFO_HASCRORLF} + + (* Request types for pcre_config() *) + PCRE_CONFIG_UTF8 = 0; + {$EXTERNALSYM PCRE_CONFIG_UTF8} + PCRE_CONFIG_NEWLINE = 1; + {$EXTERNALSYM PCRE_CONFIG_NEWLINE} + PCRE_CONFIG_LINK_SIZE = 2; + {$EXTERNALSYM PCRE_CONFIG_LINK_SIZE} + PCRE_CONFIG_POSIX_MALLOC_THRESHOLD = 3; + {$EXTERNALSYM PCRE_CONFIG_POSIX_MALLOC_THRESHOLD} + PCRE_CONFIG_MATCH_LIMIT = 4; + {$EXTERNALSYM PCRE_CONFIG_MATCH_LIMIT} + PCRE_CONFIG_STACKRECURSE = 5; + {$EXTERNALSYM PCRE_CONFIG_STACKRECURSE} + PCRE_CONFIG_UNICODE_PROPERTIES = 6; + {$EXTERNALSYM PCRE_CONFIG_UNICODE_PROPERTIES} + PCRE_CONFIG_MATCH_LIMIT_RECURSION = 7; + {$EXTERNALSYM PCRE_CONFIG_MATCH_LIMIT_RECURSION} + PCRE_CONFIG_BSR = 8; + {$EXTERNALSYM PCRE_CONFIG_BSR} + + (* Bit flags for the pcre_extra structure *) + + PCRE_EXTRA_STUDY_DATA = $0001; + {$EXTERNALSYM PCRE_EXTRA_STUDY_DATA} + PCRE_EXTRA_MATCH_LIMIT = $0002; + {$EXTERNALSYM PCRE_EXTRA_MATCH_LIMIT} + PCRE_EXTRA_CALLOUT_DATA = $0004; + {$EXTERNALSYM PCRE_EXTRA_CALLOUT_DATA} + PCRE_EXTRA_TABLES = $0008; + {$EXTERNALSYM PCRE_EXTRA_TABLES} + PCRE_EXTRA_MATCH_LIMIT_RECURSION = $0010; + {$EXTERNALSYM PCRE_EXTRA_MATCH_LIMIT_RECURSION} + +type + (* Types *) + PPAnsiChar = ^PAnsiChar; + {$EXTERNALSYM PPAnsiChar} + PPPAnsiChar = ^PPAnsiChar; + {$EXTERNALSYM PPPAnsiChar} + PInteger = ^Integer; + {$EXTERNALSYM PInteger} + + real_pcre = packed record + {magic_number: Longword; + size: Integer; + tables: PAnsiChar; + options: Longword; + top_bracket: Word; + top_backref: word; + first_char: PAnsiChar; + req_char: PAnsiChar; + code: array [0..0] of AnsiChar;} + end; + TPCRE = real_pcre; + PPCRE = ^TPCRE; + + real_pcre_extra = packed record + {options: PAnsiChar; + start_bits: array [0..31] of AnsiChar;} + flags: Cardinal; (* Bits for which fields are set *) + study_data: Pointer; (* Opaque data from pcre_study() *) + match_limit: Cardinal; (* Maximum number of calls to match() *) + callout_data: Pointer; (* Data passed back in callouts *) + tables: PAnsiChar; (* Pointer to character tables *) + match_limit_recursion: Cardinal; (* Max recursive calls to match() *) + end; + TPCREExtra = real_pcre_extra; + PPCREExtra = ^TPCREExtra; + + pcre_callout_block = packed record + version: Integer; (* Identifies version of block *) + (* ------------------------ Version 0 ------------------------------- *) + callout_number: Integer; (* Number compiled into pattern *) + offset_vector: PInteger; (* The offset vector *) + subject: PAnsiChar; (* The subject being matched *) + subject_length: Integer; (* The length of the subject *) + start_match: Integer; (* Offset to start of this match attempt *) + current_position: Integer; (* Where we currently are in the subject *) + capture_top: Integer; (* Max current capture *) + capture_last: Integer; (* Most recently closed capture *) + callout_data: Pointer; (* Data passed in with the call *) + (* ------------------- Added for Version 1 -------------------------- *) + pattern_position: Integer; (* Offset to next item in the pattern *) + next_item_length: Integer; (* Length of next item in the pattern *) + (* ------------------------------------------------------------------ *) + end; + + pcre_malloc_callback = function(Size: Integer): Pointer; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_malloc_callback} + pcre_free_callback = procedure(P: Pointer); {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_free_callback} + pcre_stack_malloc_callback = function(Size: Integer): Pointer; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_stack_malloc_callback} + pcre_stack_free_callback = procedure(P: Pointer); {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_stack_free_callback} + pcre_callout_callback = function(var callout_block: pcre_callout_block): Integer; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_callout_callback} + +var + // renamed from "pcre_X" to "pcre_X_func" to allow functions with name "pcre_X" to be + // declared in implementation when static linked + pcre_malloc_func: ^pcre_malloc_callback = nil; + {$EXTERNALSYM pcre_malloc_func} + pcre_free_func: ^pcre_free_callback = nil; + {$EXTERNALSYM pcre_free_func} + pcre_stack_malloc_func: ^pcre_stack_malloc_callback = nil; + {$EXTERNALSYM pcre_stack_malloc_func} + pcre_stack_free_func: ^pcre_stack_free_callback = nil; + {$EXTERNALSYM pcre_stack_free_func} + pcre_callout_func: ^pcre_callout_callback = nil; + {$EXTERNALSYM pcre_callout_func} + +procedure SetPCREMallocCallback(const Value: pcre_malloc_callback); +{$EXTERNALSYM SetPCREMallocCallback} +function GetPCREMallocCallback: pcre_malloc_callback; +{$EXTERNALSYM GetPCREMallocCallback} +function CallPCREMalloc(Size: Integer): Pointer; +{$EXTERNALSYM CallPCREMalloc} + +procedure SetPCREFreeCallback(const Value: pcre_free_callback); +{$EXTERNALSYM SetPCREFreeCallback} +function GetPCREFreeCallback: pcre_free_callback; +{$EXTERNALSYM GetPCREFreeCallback} +procedure CallPCREFree(P: Pointer); +{$EXTERNALSYM CallPCREFree} + +procedure SetPCREStackMallocCallback(const Value: pcre_stack_malloc_callback); +{$EXTERNALSYM SetPCREStackMallocCallback} +function GetPCREStackMallocCallback: pcre_stack_malloc_callback; +{$EXTERNALSYM GetPCREStackMallocCallback} +function CallPCREStackMalloc(Size: Integer): Pointer; +{$EXTERNALSYM CallPCREStackMalloc} + +procedure SetPCREStackFreeCallback(const Value: pcre_stack_free_callback); +{$EXTERNALSYM SetPCREStackFreeCallback} +function GetPCREStackFreeCallback: pcre_stack_free_callback; +{$EXTERNALSYM GetPCREStackFreeCallback} +procedure CallPCREStackFree(P: Pointer); +{$EXTERNALSYM CallPCREStackFree} + +procedure SetPCRECalloutCallback(const Value: pcre_callout_callback); +{$EXTERNALSYM SetPCRECalloutCallback} +function GetPCRECalloutCallback: pcre_callout_callback; +{$EXTERNALSYM GetPCRECalloutCallback} +function CallPCRECallout(var callout_block: pcre_callout_block): Integer; +{$EXTERNALSYM CallPCRECallout} + +type + TPCRELibNotLoadedHandler = procedure; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + +var + // Value to initialize function pointers below with, in case LoadPCRE fails + // or UnloadPCRE is called. Typically the handler will raise an exception. + LibNotLoadedHandler: TPCRELibNotLoadedHandler = nil; + +(* Functions *) + +{$IFNDEF PCRE_LINKONREQUEST} +// static link and static dll import +function pcre_compile(const pattern: PAnsiChar; options: Integer; + const errptr: PPAnsiChar; erroffset: PInteger; const tableptr: PAnsiChar): PPCRE; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_compile} +function pcre_compile2(const pattern: PAnsiChar; options: Integer; + const errorcodeptr: PInteger; const errorptr: PPAnsiChar; erroroffset: PInteger; + const tables: PAnsiChar): PPCRE; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_compile2} +function pcre_config(what: Integer; where: Pointer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_config} +function pcre_copy_named_substring(const code: PPCRE; const subject: PAnsiChar; + ovector: PInteger; stringcount: Integer; const stringname: PAnsiChar; + buffer: PAnsiChar; size: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_copy_named_substring} +function pcre_copy_substring(const subject: PAnsiChar; ovector: PInteger; + stringcount, stringnumber: Integer; buffer: PAnsiChar; buffersize: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_copy_substring} +function pcre_dfa_exec(const argument_re: PPCRE; const extra_data: PPCREExtra; + const subject: PAnsiChar; length: Integer; start_offset: Integer; + options: Integer; offsets: PInteger; offsetcount: Integer; workspace: PInteger; + wscount: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_dfa_exec} +function pcre_exec(const code: PPCRE; const extra: PPCREExtra; const subject: PAnsiChar; + length, startoffset, options: Integer; ovector: PInteger; ovecsize: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_exec} +procedure pcre_free_substring(stringptr: PAnsiChar); + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_free_substring} +procedure pcre_free_substring_list(stringlistptr: PPAnsiChar); + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_free_substring_list} +function pcre_fullinfo(const code: PPCRE; const extra: PPCREExtra; + what: Integer; where: Pointer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_fullinfo} +function pcre_get_named_substring(const code: PPCRE; const subject: PAnsiChar; + ovector: PInteger; stringcount: Integer; const stringname: PAnsiChar; + const stringptr: PPAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_get_named_substring} +function pcre_get_stringnumber(const code: PPCRE; const stringname: PAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_get_stringnumber} +function pcre_get_stringtable_entries(const code: PPCRE; const stringname: PAnsiChar; + firstptr: PPAnsiChar; lastptr: PPAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_get_stringtable_entries} +function pcre_get_substring(const subject: PAnsiChar; ovector: PInteger; + stringcount, stringnumber: Integer; const stringptr: PPAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_get_substring} +function pcre_get_substring_list(const subject: PAnsiChar; ovector: PInteger; + stringcount: Integer; listptr: PPPAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_get_substring_list} +function pcre_info(const code: PPCRE; optptr, firstcharptr: PInteger): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_info} +function pcre_maketables: PAnsiChar; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_maketables} +function pcre_refcount(argument_re: PPCRE; adjust: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_refcount} +function pcre_study(const code: PPCRE; options: Integer; const errptr: PPAnsiChar): PPCREExtra; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_study} +function pcre_version: PAnsiChar; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} +{$EXTERNALSYM pcre_version} + +// Calling pcre_free in the DLL causes an access violation error; use pcre_dispose instead +procedure pcre_dispose(pattern, hints, chartable: Pointer); {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + +{$ELSE} +// dynamic dll import +type + pcre_compile_func = function(const pattern: PAnsiChar; options: Integer; + const errptr: PPAnsiChar; erroffset: PInteger; const tableptr: PAnsiChar): PPCRE; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_compile_func} + pcre_compile2_func = function(const pattern: PAnsiChar; options: Integer; + const errorcodeptr: PInteger; const errorptr: PPAnsiChar; erroroffset: PInteger; + const tables: PAnsiChar): PPCRE; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_compile2_func} + pcre_config_func = function(what: Integer; where: Pointer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_config_func} + pcre_copy_named_substring_func = function(const code: PPCRE; const subject: PAnsiChar; + ovector: PInteger; stringcount: Integer; const stringname: PAnsiChar; + buffer: PAnsiChar; size: Integer): Integer; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_copy_named_substring_func} + pcre_copy_substring_func = function(const subject: PAnsiChar; ovector: PInteger; + stringcount, stringnumber: Integer; buffer: PAnsiChar; buffersize: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_copy_substring_func} + pcre_dfa_exec_func = function(const argument_re: PPCRE; const extra_data: PPCREExtra; + const subject: PAnsiChar; length: Integer; start_offset: Integer; + options: Integer; offsets: PInteger; offsetcount: Integer; workspace: PInteger; + wscount: Integer): Integer; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_dfa_exec_func} + pcre_exec_func = function(const code: PPCRE; const extra: PPCREExtra; const subject: PAnsiChar; + length, startoffset, options: Integer; ovector: PInteger; ovecsize: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_exec_func} + pcre_free_substring_func = procedure(stringptr: PAnsiChar); + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_free_substring_func} + pcre_free_substring_list_func = procedure(stringptr: PPAnsiChar); + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_free_substring_list_func} + pcre_fullinfo_func = function(const code: PPCRE; const extra: PPCREExtra; + what: Integer; where: Pointer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_fullinfo_func} + pcre_get_named_substring_func = function(const code: PPCRE; const subject: PAnsiChar; + ovector: PInteger; stringcount: Integer; const stringname: PAnsiChar; + const stringptr: PPAnsiChar): Integer; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_get_named_substring_func} + pcre_get_stringnumber_func = function(const code: PPCRE; + const stringname: PAnsiChar): Integer; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_get_stringnumber_func} + pcre_get_stringtable_entries_func = function(const code: PPCRE; const stringname: PAnsiChar; + firstptr: PPAnsiChar; lastptr: PPAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_get_stringtable_entries_func} + pcre_get_substring_func = function(const subject: PAnsiChar; ovector: PInteger; + stringcount, stringnumber: Integer; const stringptr: PPAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_get_substring_func} + pcre_get_substring_list_func = function(const subject: PAnsiChar; ovector: PInteger; + stringcount: Integer; listptr: PPPAnsiChar): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_get_substring_list_func} + pcre_info_func = function(const code: PPCRE; optptr, firstcharptr: PInteger): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_info_func} + pcre_maketables_func = function: PAnsiChar; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_maketables_func} + pcre_refcount_func = function(argument_re: PPCRE; adjust: Integer): Integer; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_refcount_func} + pcre_study_func = function(const code: PPCRE; options: Integer; const errptr: PPAnsiChar): PPCREExtra; + {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_study_func} + pcre_version_func = function: PAnsiChar; {$IFDEF PCRE_EXPORT_CDECL} cdecl; {$ENDIF PCRE_EXPORT_CDECL} + {$EXTERNALSYM pcre_version_func} + +var + pcre_compile: pcre_compile_func = nil; + {$EXTERNALSYM pcre_compile} + pcre_compile2: pcre_compile2_func = nil; + {$EXTERNALSYM pcre_compile2} + pcre_config: pcre_config_func = nil; + {$EXTERNALSYM pcre_config} + pcre_copy_named_substring: pcre_copy_named_substring_func = nil; + {$EXTERNALSYM pcre_copy_named_substring} + pcre_copy_substring: pcre_copy_substring_func = nil; + {$EXTERNALSYM pcre_copy_substring} + pcre_dfa_exec: pcre_dfa_exec_func = nil; + {$EXTERNALSYM pcre_dfa_exec} + pcre_exec: pcre_exec_func = nil; + {$EXTERNALSYM pcre_exec} + pcre_free_substring: pcre_free_substring_func = nil; + {$EXTERNALSYM pcre_free_substring} + pcre_free_substring_list: pcre_free_substring_list_func = nil; + {$EXTERNALSYM pcre_free_substring_list} + pcre_fullinfo: pcre_fullinfo_func = nil; + {$EXTERNALSYM pcre_fullinfo} + pcre_get_named_substring: pcre_get_named_substring_func = nil; + {$EXTERNALSYM pcre_get_named_substring} + pcre_get_stringnumber: pcre_get_stringnumber_func = nil; + {$EXTERNALSYM pcre_get_stringnumber} + pcre_get_stringtable_entries: pcre_get_stringtable_entries_func = nil; + {$EXTERNALSYM pcre_get_stringtable_entries} + pcre_get_substring: pcre_get_substring_func = nil; + {$EXTERNALSYM pcre_get_substring} + pcre_get_substring_list: pcre_get_substring_list_func = nil; + {$EXTERNALSYM pcre_get_substring_list} + pcre_info: pcre_info_func = nil; + {$EXTERNALSYM pcre_info} + pcre_maketables: pcre_maketables_func = nil; + {$EXTERNALSYM pcre_maketables} + pcre_refcount: pcre_refcount_func = nil; + {$EXTERNALSYM pcre_refcount} + pcre_study: pcre_study_func = nil; + {$EXTERNALSYM pcre_study} + pcre_version: pcre_version_func = nil; + {$EXTERNALSYM pcre_version} + +{$ENDIF ~PCRE_LINKONREQUEST} + +function IsPCRELoaded: Boolean; +function LoadPCRE: Boolean; +procedure UnloadPCRE; + +implementation + +uses + SysUtils, + {$IFDEF MSWINDOWS} + Windows; + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + {$IFDEF HAS_UNIT_TYPES} + Types, + {$ENDIF HAS_UNIT_TYPES} + {$IFDEF HAS_UNIT_LIBC} + Libc; + {$ELSE ~HAS_UNIT_LIBC} + dl; + {$ENDIF ~HAS_UNIT_LIBC} + {$ENDIF UNIX} + +{$IFDEF PCRE_STATICLINK} +{$LINK lib\pcre_compile.obj} +{$LINK lib\pcre_config.obj} +{$LINK lib\pcre_dfa_exec.obj} +{$LINK lib\pcre_exec.obj} +{$LINK lib\pcre_fullinfo.obj} +{$LINK lib\pcre_get.obj} +{$LINK lib\pcre_globals.obj} +{$LINK lib\pcre_info.obj} +{$LINK lib\pcre_maketables.obj} +{$LINK lib\pcre_newline.obj} +{$LINK lib\pcre_ord2utf8.obj} +{$LINK lib\pcre_refcount.obj} +{$LINK lib\pcre_study.obj} +{$LINK lib\pcre_tables.obj} +{$LINK lib\pcre_try_flipped.obj} +{$LINK lib\pcre_ucd.obj} +{$LINK lib\pcre_valid_utf8.obj} +{$LINK lib\pcre_version.obj} +{$LINK lib\pcre_xclass.obj} +{$LINK lib\pcre_default_tables.obj} + +// user's defined callbacks +var + pcre_malloc_user: pcre_malloc_callback; + pcre_free_user: pcre_free_callback; + pcre_stack_malloc_user: pcre_stack_malloc_callback; + pcre_stack_free_user: pcre_stack_free_callback; + pcre_callout_user: pcre_callout_callback; + +function pcre_compile; external; +function pcre_compile2; external; +function pcre_config; external; +function pcre_copy_named_substring; external; +function pcre_copy_substring; external; +function pcre_dfa_exec; external; +function pcre_exec; external; +procedure pcre_free_substring; external; +procedure pcre_free_substring_list; external; +function pcre_fullinfo; external; +function pcre_get_named_substring; external; +function pcre_get_stringnumber; external; +function pcre_get_stringtable_entries; external; +function pcre_get_substring; external; +function pcre_get_substring_list; external; +function pcre_info; external; +function pcre_maketables; external; +function pcre_refcount; external; +function pcre_study; external; +function pcre_version; external; + +type + size_t = Longint; + +const + szMSVCRT = 'MSVCRT.DLL'; + +function _memcpy(dest, src: Pointer; count: size_t): Pointer; cdecl; external szMSVCRT name 'memcpy'; +function _memmove(dest, src: Pointer; count: size_t): Pointer; cdecl; external szMSVCRT name 'memmove'; +function _memset(dest: Pointer; val: Integer; count: size_t): Pointer; cdecl; external szMSVCRT name 'memset'; +function _strncmp(s1: PAnsiChar; s2: PAnsiChar; n: size_t): Integer; cdecl; external szMSVCRT name 'strncmp'; +function _memcmp(s1: Pointer; s2: Pointer; n: size_t): Integer; cdecl; external szMSVCRT name 'memcmp'; +function _strlen(s: PAnsiChar): size_t; cdecl; external szMSVCRT name 'strlen'; +function __ltolower(__ch: Integer): Integer; cdecl; external szMSVCRT name 'tolower'; +function __ltoupper(__ch: Integer): Integer; cdecl; external szMSVCRT name 'toupper'; +function _isalnum(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isalnum'; +function _isalpha(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isalpha'; +function _iscntrl(__ch: Integer): Integer; cdecl; external szMSVCRT name 'iscntrl'; +function _isdigit(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isdigit'; +function _isgraph(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isgraph'; +function _islower(__ch: Integer): Integer; cdecl; external szMSVCRT name 'islower'; +function _isprint(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isprint'; +function _ispunct(__ch: Integer): Integer; cdecl; external szMSVCRT name 'ispunct'; +function _isspace(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isspace'; +function _isupper(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isupper'; +function _isxdigit(__ch: Integer): Integer; cdecl; external szMSVCRT name 'isxdigit'; +function _strchr(__s: PAnsiChar; __c: Integer): PAnsiChar; cdecl; external szMSVCRT name 'strchr'; + +function malloc(size: size_t): Pointer; cdecl; external szMSVCRT name 'malloc'; + +function pcre_malloc(Size: Integer): Pointer; +begin + if Assigned(pcre_malloc_user) then + Result := pcre_malloc_user(Size) + else + Result := malloc(Size); +end; + +function pcre_stack_malloc(Size: Integer): Pointer; +begin + if Assigned(pcre_stack_malloc_user) then + Result := pcre_stack_malloc_user(Size) + else + Result := malloc(Size); +end; + +function _malloc(size: size_t): Pointer; +begin + Result := pcre_malloc(size); +end; + +procedure free(pBlock: Pointer); cdecl; external szMSVCRT name 'free'; + +procedure pcre_free(P: Pointer); +begin + if Assigned(pcre_free_user) then + pcre_free_user(P) + else + free(P); +end; + +procedure pcre_stack_free(P: Pointer); +begin + if Assigned(pcre_stack_free_user) then + pcre_stack_free_user(P) + else + free(P); +end; + +procedure _free(pBlock: Pointer); +begin + pcre_free(pBlock); +end; + +function pcre_callout(var callout_block: pcre_callout_block): Integer; cdecl; +begin + if Assigned(pcre_callout_user) then + Result := pcre_callout_user(callout_block) + else + Result := 0; +end; + +{$ELSE ~PCRE_STATICLINK} + +type + {$IFDEF MSWINDOWS} + TModuleHandle = HINST; + {$ENDIF MSWINDOWS} + {$IFDEF LINUX} + TModuleHandle = Pointer; + {$ENDIF LINUX} + +const + {$IFDEF MSWINDOWS} + libpcremodulename = 'pcrelib.dll'; + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + libpcremodulename = 'libpcre.so.0'; + {$ENDIF UNIX} + PCRECompileExportName = 'pcre_compile'; + PCRECompile2ExportName = 'pcre_compile2'; + PCREConfigExportName = 'pcre_config'; + PCRECopyNamedSubstringExportName = 'pcre_copy_named_substring'; + PCRECopySubStringExportName = 'pcre_copy_substring'; + PCREDfaExecExportName = 'pcre_dfa_exec'; + PCREExecExportName = 'pcre_exec'; + PCREFreeSubStringExportName = 'pcre_free_substring'; + PCREFreeSubStringListExportName = 'pcre_free_substring_list'; + PCREFullInfoExportName = 'pcre_fullinfo'; + PCREGetNamedSubstringExportName = 'pcre_get_named_substring'; + PCREGetStringNumberExportName = 'pcre_get_stringnumber'; + PCREGetStringTableEntriesExportName = 'pcre_get_stringtable_entries'; + PCREGetSubStringExportName = 'pcre_get_substring'; + PCREGetSubStringListExportName = 'pcre_get_substring_list'; + PCREInfoExportName = 'pcre_info'; + PCREMakeTablesExportName = 'pcre_maketables'; + PCRERefCountExportName = 'pcre_refcount'; + PCREStudyExportName = 'pcre_study'; + PCREVersionExportName = 'pcre_version'; + PCREMallocExportName = 'pcre_malloc'; + PCREFreeExportName = 'pcre_free'; + PCREStackMallocExportName = 'pcre_stack_malloc'; + PCREStackFreeExportName = 'pcre_stack_free'; + PCRECalloutExportName = 'pcre_callout'; + INVALID_MODULEHANDLE_VALUE = TModuleHandle(0); + +var + PCRELib: TModuleHandle = INVALID_MODULEHANDLE_VALUE; +{$ENDIF ~PCRE_STATICLINK} + +procedure SetPCREMallocCallback(const Value: pcre_malloc_callback); +begin + {$IFDEF PCRE_STATICLINK} + pcre_malloc_user := Value; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_malloc_func) then + LoadPCRE; + + if Assigned(pcre_malloc_func) then + pcre_malloc_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + {$ENDIF ~PCRE_STATICLINK} +end; + +function GetPCREMallocCallback: pcre_malloc_callback; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_malloc_user; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_malloc_func) then + LoadPCRE; + + if not Assigned(pcre_malloc_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_malloc_func^; + {$ENDIF ~PCRE_STATICLINK} +end; + +function CallPCREMalloc(Size: Integer): Pointer; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_malloc(Size); + {$ELSE ~PCRE_STATICLINK} + Result := pcre_malloc_func^(Size); + {$ENDIF ~PCRE_STATICLINK} +end; + +procedure SetPCREFreeCallback(const Value: pcre_free_callback); +begin + {$IFDEF PCRE_STATICLINK} + pcre_free_user := Value; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_free_func) then + LoadPCRE; + + if Assigned(pcre_free_func) then + pcre_free_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + {$ENDIF ~PCRE_STATICLINK} +end; + +function GetPCREFreeCallback: pcre_free_callback; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_free_user; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_free_func) then + LoadPCRE; + + if not Assigned(pcre_free_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_free_func^ + {$ENDIF ~PCRE_STATICLINK} +end; + +procedure CallPCREFree(P: Pointer); +begin + {$IFDEF PCRE_STATICLINK} + pcre_free(P); + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_free_func) then + LoadPCRE; + pcre_free_func^(P); + {$ENDIF ~PCRE_STATICLINK} +end; + +procedure SetPCREStackMallocCallback(const Value: pcre_stack_malloc_callback); +begin + {$IFDEF PCRE_STATICLINK} + pcre_stack_malloc_user := Value; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_stack_malloc_func) then + LoadPCRE; + + if Assigned(pcre_stack_malloc_func) then + pcre_stack_malloc_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + {$ENDIF ~PCRE_STATICLINK} +end; + +function GetPCREStackMallocCallback: pcre_stack_malloc_callback; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_stack_malloc_user; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_stack_malloc_func) then + LoadPCRE; + + if not Assigned(pcre_stack_malloc_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_stack_malloc_func^; + {$ENDIF ~PCRE_STATICLINK} +end; + +function CallPCREStackMalloc(Size: Integer): Pointer; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_stack_malloc(Size); + {$ELSE ~PCRE_STATICLINK} + Result := pcre_stack_malloc_func^(Size); + {$ENDIF ~PCRE_STATICLINK} +end; + +procedure SetPCREStackFreeCallback(const Value: pcre_stack_free_callback); +begin + {$IFDEF PCRE_STATICLINK} + pcre_stack_free_user := Value; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_stack_free_func) then + LoadPCRE; + + if Assigned(pcre_stack_free_func) then + pcre_stack_free_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + {$ENDIF ~PCRE_STATICLINK} +end; + +function GetPCREStackFreeCallback: pcre_stack_free_callback; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_stack_free_user; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_stack_free_func) then + LoadPCRE; + + if not Assigned(pcre_stack_free_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_stack_free_func^; + {$ENDIF ~PCRE_STATICLINK} +end; + +procedure CallPCREStackFree(P: Pointer); +begin + {$IFDEF PCRE_STATICLINK} + pcre_stack_free(P); + {$ELSE ~PCRE_STATICLINK} + pcre_stack_free_func^(P); + {$ENDIF ~PCRE_STATICLINK} +end; + +procedure SetPCRECalloutCallback(const Value: pcre_callout_callback); +begin + {$IFDEF PCRE_STATICLINK} + pcre_callout_user := Value; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_callout_func) then + LoadPCRE; + + if Assigned(pcre_callout_func) then + pcre_callout_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + {$ENDIF ~PCRE_STATICLINK} +end; + +function GetPCRECalloutCallback: pcre_callout_callback; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_callout_user; + {$ELSE ~PCRE_STATICLINK} + if not Assigned(pcre_callout_func) then + LoadPCRE; + + if not Assigned(pcre_callout_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_callout_func^; + {$ENDIF ~PCRE_STATICLINK} +end; + +function CallPCRECallout(var callout_block: pcre_callout_block): Integer; +begin + {$IFDEF PCRE_STATICLINK} + Result := pcre_callout(callout_block); + {$ELSE ~PCRE_STATICLINK} + Result := pcre_callout_func^(callout_block); + {$ENDIF ~PCRE_STATICLINK} +end; + +{$IFNDEF PCRE_STATICLINK} +procedure InitPCREFuncPtrs(const Value: Pointer); +begin + {$IFDEF PCRE_LINKONREQUEST} + @pcre_compile := Value; + @pcre_compile2 := Value; + @pcre_config := Value; + @pcre_copy_named_substring := Value; + @pcre_copy_substring := Value; + @pcre_dfa_exec := Value; + @pcre_exec := Value; + @pcre_free_substring := Value; + @pcre_free_substring_list := Value; + @pcre_fullinfo := Value; + @pcre_get_named_substring := Value; + @pcre_get_stringnumber := Value; + @pcre_get_stringtable_entries := Value; + @pcre_get_substring := Value; + @pcre_get_substring_list := Value; + @pcre_info := Value; + @pcre_maketables := Value; + @pcre_refcount := Value; + @pcre_study := Value; + @pcre_version := Value; + {$ENDIF PCRE_LINKONREQUEST} + pcre_malloc_func := nil; + pcre_free_func := nil; + pcre_stack_malloc_func := nil; + pcre_stack_free_func := nil; + pcre_callout_func := nil; +end; +{$ENDIF ~PCRE_STATICLINK} + +function IsPCRELoaded: Boolean; +begin + {$IFDEF PCRE_STATICLINK} + Result := True; + {$ELSE ~PCRE_STATICLINK} + Result := PCRELib <> INVALID_MODULEHANDLE_VALUE; + {$ENDIF ~PCRE_STATICLINK} +end; + +function LoadPCRE: Boolean; +{$IFDEF PCRE_STATICLINK} +begin + Result := True; +end; +{$ELSE ~PCRE_STATICLINK} + function GetSymbol(SymbolName: PAnsiChar): Pointer; + begin + {$IFDEF MSWINDOWS} + Result := GetProcAddress(PCRELib, PChar(SymbolName)); + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + Result := dlsym(PCRELib, PChar(SymbolName)); + {$ENDIF UNIX} + end; + +begin + Result := PCRELib <> INVALID_MODULEHANDLE_VALUE; + if Result then + Exit; + + if PCRELib = INVALID_MODULEHANDLE_VALUE then + {$IFDEF MSWINDOWS} + PCRELib := SafeLoadLibrary(libpcremodulename); + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + PCRELib := dlopen(PAnsiChar(libpcremodulename), RTLD_NOW); + {$ENDIF UNIX} + Result := PCRELib <> INVALID_MODULEHANDLE_VALUE; + if Result then + begin + {$IFDEF PCRE_LINKONREQUEST} + @pcre_compile := GetSymbol(PCRECompileExportName); + @pcre_compile2 := GetSymbol(PCRECompile2ExportName); + @pcre_config := GetSymbol(PCREConfigExportName); + @pcre_copy_named_substring := GetSymbol(PCRECopyNamedSubstringExportName); + @pcre_copy_substring := GetSymbol(PCRECopySubStringExportName); + @pcre_dfa_exec := GetSymbol(PCREDfaExecExportName); + @pcre_exec := GetSymbol(PCREExecExportName); + @pcre_free_substring := GetSymbol(PCREFreeSubStringExportName); + @pcre_free_substring_list := GetSymbol(PCREFreeSubStringListExportName); + @pcre_fullinfo := GetSymbol(PCREFullInfoExportName); + @pcre_get_named_substring := GetSymbol(PCREGetNamedSubstringExportName); + @pcre_get_stringnumber := GetSymbol(PCREGetStringNumberExportName); + @pcre_get_stringtable_entries := GetSymbol(PCREGetStringTableEntriesExportName); + @pcre_get_substring := GetSymbol(PCREGetSubStringExportName); + @pcre_get_substring_list := GetSymbol(PCREGetSubStringListExportName); + @pcre_info := GetSymbol(PCREInfoExportName); + @pcre_maketables := GetSymbol(PCREMakeTablesExportName); + @pcre_refcount := GetSymbol(PCRERefCountExportName); + @pcre_study := GetSymbol(PCREStudyExportName); + @pcre_version := GetSymbol(PCREVersionExportName); + {$ENDIF PCRE_LINKONREQUEST} + pcre_malloc_func := GetSymbol(PCREMallocExportName); + pcre_free_func := GetSymbol(PCREFreeExportName); + pcre_stack_malloc_func := GetSymbol(PCREStackMallocExportName); + pcre_stack_free_func := GetSymbol(PCREStackFreeExportName); + pcre_callout_func := GetSymbol(PCRECalloutExportName); + end + else + InitPCREFuncPtrs(@LibNotLoadedHandler); +end; +{$ENDIF ~PCRE_STATICLINK} + +procedure UnloadPCRE; +begin + {$IFNDEF PCRE_STATICLINK} + if PCRELib <> INVALID_MODULEHANDLE_VALUE then + {$IFDEF MSWINDOWS} + FreeLibrary(PCRELib); + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + dlclose(Pointer(PCRELib)); + {$ENDIF UNIX} + PCRELib := INVALID_MODULEHANDLE_VALUE; + InitPCREFuncPtrs(@LibNotLoadedHandler); + {$ENDIF ~PCRE_STATICLINK} +end; + +{$IFDEF PCRE_STATICLINK} +procedure pcre_dispose(pattern, hints, chartable: Pointer); +begin + if pattern <> nil then pcre_free(pattern); + if hints <> nil then pcre_free(hints); + if chartable <> nil then pcre_free(chartable); +end; +{$ENDIF PCRE_STATICLINK} + +{$IFDEF PCRE_LINKDLL} +function pcre_compile; external libpcremodulename name PCRECompileExportName; +function pcre_compile2; external libpcremodulename name PCRECompile2ExportName; +function pcre_config; external libpcremodulename name PCREConfigExportName; +function pcre_copy_named_substring; external libpcremodulename name PCRECopyNamedSubStringExportName; +function pcre_copy_substring; external libpcremodulename name PCRECopySubStringExportName; +function pcre_dfa_exec; external libpcremodulename name PCREDfaExecExportName; +function pcre_exec; external libpcremodulename name PCREExecExportName; +procedure pcre_free_substring; external libpcremodulename name PCREFreeSubStringExportName; +procedure pcre_free_substring_list; external libpcremodulename name PCREFreeSubStringListExportName; +function pcre_fullinfo; external libpcremodulename name PCREFullInfoExportName; +function pcre_get_named_substring; external libpcremodulename name PCREGetNamedSubStringExportName; +function pcre_get_stringnumber; external libpcremodulename name PCREGetStringNumberExportName; +function pcre_get_stringtable_entries; external libpcremodulename name PCREGetStringTableEntriesExportName; +function pcre_get_substring; external libpcremodulename name PCREGetSubStringExportName; +function pcre_get_substring_list; external libpcremodulename name PCREGetSubStringListExportName; +function pcre_info; external libpcremodulename name PCREInfoExportName; +function pcre_maketables; external libpcremodulename name PCREMakeTablesExportName; +function pcre_refcount; external libpcremodulename name PCRERefCountExportName; +function pcre_study; external libpcremodulename name PCREStudyExportName; +function pcre_version; external libpcremodulename name PCREVersionExportName; +procedure pcre_dispose; external libpcremodulename name 'pcre_dispose'; +{$ENDIF PCRE_LINKDLL} + +end. + diff --git a/System/pngextra.pas b/System/pngextra.pas new file mode 100644 index 0000000..c219e7e --- /dev/null +++ b/System/pngextra.pas @@ -0,0 +1,353 @@ +unit pngextra; + +interface + +uses + Windows, Graphics, Messages, SysUtils, Classes, Controls, pngimage, Buttons, + ExtCtrls; + +type + TPNGButtonStyle = (pbsDefault, pbsFlat, pbsNoFrame); + TPNGButtonLayout = (pbsImageAbove, pbsImageBellow, pbsImageLeft, + pbsImageRight); + TPNGButtonState = (pbsNormal, pbsDown, pbsDisabled); + + TPNGButton = class(TGraphicControl) + private + {Holds the property values} + fButtonStyle: TPNGButtonStyle; + fMouseOverControl: Boolean; + FCaption: String; + FButtonLayout: TPNGButtonLayout; + FButtonState: TPNGButtonState; + FImageDown: TPNGObject; + fImageNormal: TPNGObject; + fImageDisabled: TPNGObject; + fImageOver: TPNGObject; + fOnMouseEnter, fOnMouseExit: TNotifyEvent; + {Procedures for setting the property values} + procedure SetButtonStyle(const Value: TPNGButtonStyle); + procedure SetCaption(const Value: String); + procedure SetButtonLayout(const Value: TPNGButtonLayout); + procedure SetButtonState(const Value: TPNGButtonState); + procedure SetImageNormal(const Value: TPNGObject); + procedure SetImageDown(const Value: TPNGObject); + procedure SetImageOver(const Value: TPNGObject); + published + {Published properties} + property Font; + property Visible; + property ButtonLayout: TPNGButtonLayout read FButtonLayout write SetButtonLayout; + property Caption: String read FCaption write SetCaption; + property ImageNormal: TPNGObject read fImageNormal write SetImageNormal; + property ImageDown: TPNGObject read FImageDown write SetImageDown; + property ImageOver: TPNGObject read FImageOver write SetImageOver; + property ButtonStyle: TPNGButtonStyle read fButtonStyle + write SetButtonStyle; + property Enabled; + property ParentShowHint; + property ShowHint; + {Default events} + property OnMouseDown; + property OnClick; + property OnMouseUp; + property OnMouseMove; + property OnDblClick; + property OnMouseEnter: TNotifyEvent read fOnMouseEnter write fOnMouseEnter; + property OnMouseExit: TNotifyEvent read fOnMouseExit write fOnMouseExit; + public + {Public properties} + property ButtonState: TPNGButtonState read FButtonState write SetButtonState; + protected + {Being painted} + procedure Paint; override; + {Clicked} + procedure Click; override; + {Mouse pressed} + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); override; + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); override; + procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; + {Mouse entering or leaving} + procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER; + procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; + {Being enabled or disabled} + procedure CMEnabledChanged(var Message: TMessage); + message CM_ENABLEDCHANGED; + public + {Returns if the mouse is over the control} + property IsMouseOver: Boolean read fMouseOverControl; + {Constructor and destructor} + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + +procedure Register; +procedure MakeImageHalfTransparent(Source, Dest: TPNGObject); + +implementation + +procedure Register; +begin + RegisterComponents('Samples', [TPNGButton]); +end; + +procedure MakeImageHalfTransparent(Source, Dest: TPNGObject); +var + i, j: Integer; +begin + Dest.Assign(Source); + Dest.CreateAlpha; + if (Dest.Header.ColorType <> COLOR_PALETTE) then + for j := 0 to Source.Height - 1 do + for i := 0 to Source.Width - 1 do + Dest.AlphaScanline[j]^[i] := Dest.AlphaScanline[j]^[i] div 3; +end; + +{TPNGButton implementation} + +{Being created} +constructor TPNGButton.Create(AOwner: TComponent); +begin + {Calls ancestor} + inherited Create(AOwner); + {Creates the TPNGObjects} + fImageNormal := TPNGObject.Create; + fImageDown := TPNGObject.Create; + fImageDisabled := TPNGObject.Create; + fImageOver := TPNGObject.Create; + {Initial properties} + ControlStyle := ControlStyle + [csCaptureMouse]; + SetBounds(Left, Top, 23, 23); + fMouseOverControl := False; + fButtonLayout := pbsImageAbove; + fButtonState := pbsNormal +end; + +destructor TPNGButton.Destroy; +begin + {Frees the TPNGObject} + fImageNormal.Free; + fImageDown.Free; + fImageDisabled.Free; + fImageOver.Free; + + {Calls ancestor} + inherited Destroy; +end; + +{Being enabled or disabled} +procedure TPNGButton.CMEnabledChanged(var Message: TMessage); +begin + if not Enabled then MakeImageHalfTransparent(fImageNormal, fImageDisabled); + if Enabled then ButtonState := pbsNormal else ButtonState := pbsDisabled +end; + +{Returns the largest number} +function Max(A, B: Integer): Integer; +begin + if A > B then Result := A else Result := B +end; + +{Button being painted} +procedure TPNGButton.Paint; +const + Slide: Array[false..true] of Integer = (0, 2); +var + Area: TRect; + TextSize, ImageSize: TSize; + TextPos, ImagePos: TPoint; + Image: TPNGObject; + Pushed: Boolean; +begin + {Prepares the canvas} + Canvas.Font.Assign(Font); + + {Determines if the button is pushed} + Pushed := (ButtonState = pbsDown) and IsMouseOver; + + {Determines the image to use} + if (Pushed) and not fImageDown.Empty then + Image := fImageDown + else if IsMouseOver and not fImageOver.Empty and Enabled then + Image := fImageOver + else if (ButtonState = pbsDisabled) and not fImageDisabled.Empty then + Image := fImageDisabled + else + Image := fImageNormal; + + {Get the elements size} + ImageSize.cx := Image.Width; + ImageSize.cy := Image.Height; + Area := ClientRect; + if Caption <> '' then + begin + TextSize := Canvas.TextExtent(Caption); + ImageSize.cy := ImageSize.Cy + 4; + end else FillChar(TextSize, SizeOf(TextSize), #0); + + {Set the elements position} + ImagePos.X := (Width - ImageSize.cx) div 2 + Slide[Pushed]; + TextPos.X := (Width - TextSize.cx) div 2 + Slide[Pushed]; + TextPos.Y := (Height - TextSize.cy) div 2; + ImagePos.Y := (Height - ImageSize.cy) div 2; + case ButtonLayout of + pbsImageAbove: begin + ImagePos.Y := (Height - ImageSize.cy - TextSize.cy) div 2; + TextPos.Y := ImagePos.Y + ImageSize.cy; + end; + pbsImageBellow: begin + TextPos.Y := (Height - ImageSize.cy - TextSize.cy) div 2; + ImagePos.Y := TextPos.Y + TextSize.cy; + end; + pbsImageLeft: begin + ImagePos.X := (Width - ImageSize.cx - TextSize.cx) div 2; + TextPos.X := ImagePos.X + ImageSize.cx + 5; + end; + pbsImageRight: begin + TextPos.X := (Width - ImageSize.cx - TextSize.cx) div 2;; + ImagePos.X := TextPos.X + TextSize.cx + 5; + end + end; + ImagePos.Y := ImagePos.Y + Slide[Pushed]; + TextPos.Y := TextPos.Y + Slide[Pushed]; + + {Draws the border} + if ButtonStyle = pbsFlat then + begin + if ButtonState <> pbsDisabled then + if (Pushed) then + Frame3D(Canvas, Area, clBtnShadow, clBtnHighlight, 1) + else if IsMouseOver or (ButtonState = pbsDown) then + Frame3D(Canvas, Area, clBtnHighlight, clBtnShadow, 1) + end + else if ButtonStyle = pbsDefault then + DrawButtonFace(Canvas, Area, 1, bsNew, TRUE, Pushed, FALSE); + + {Draws the elements} + Canvas.Brush.Style := bsClear; + Canvas.Draw(ImagePos.X, ImagePos.Y, Image); + if ButtonState = pbsDisabled then Canvas.Font.Color := clGrayText; + Canvas.TextRect(Area, TextPos.X, TextPos.Y, Caption) +end; + +{Changing the button Layout property} +procedure TPNGButton.SetButtonLayout(const Value: TPNGButtonLayout); +begin + FButtonLayout := Value; + Repaint +end; + +{Changing the button state property} +procedure TPNGButton.SetButtonState(const Value: TPNGButtonState); +begin + FButtonState := Value; + Repaint +end; + +{Changing the button style property} +procedure TPNGButton.SetButtonStyle(const Value: TPNGButtonStyle); +begin + fButtonStyle := Value; + Repaint +end; + +{Changing the caption property} +procedure TPNGButton.SetCaption(const Value: String); +begin + FCaption := Value; + Repaint +end; + +{Changing the image property} +procedure TPNGButton.SetImageNormal(const Value: TPNGObject); +begin + fImageNormal.Assign(Value); + MakeImageHalfTransparent(fImageNormal, fImageDisabled); + Repaint +end; + +{Setting the down image} +procedure TPNGButton.SetImageDown(const Value: TPNGObject); +begin + FImageDown.Assign(Value); + Repaint +end; + +{Setting the over image} +procedure TPNGButton.SetImageOver(const Value: TPNGObject); +begin + fImageOver.Assign(Value); + Repaint +end; + +{Mouse pressed} +procedure TPNGButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, + Y: Integer); +begin + {Changes the state and repaints} + if (ButtonState = pbsNormal) and (Button = mbLeft) then + ButtonState := pbsDown; + {Calls ancestor} + inherited +end; + +{Being clicked} +procedure TPNGButton.Click; +begin + if ButtonState = pbsDown then ButtonState := pbsNormal; + inherited Click; +end; + +{Mouse released} +procedure TPNGButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, + Y: Integer); +begin + {Changes the state and repaints} + if ButtonState = pbsDown then ButtonState := pbsNormal; + {Calls ancestor} + inherited +end; + +{Mouse moving over the control} +procedure TPNGButton.MouseMove(Shift: TShiftState; X, Y: Integer); +begin + {In case cursor is over the button} + if (X >= 0) and (X < ClientWidth) and (Y >= 0) and (Y <= ClientHeight) and + (fMouseOverControl = False) and (ButtonState <> pbsDown) then + begin + fMouseOverControl := True; + Repaint; + end; + + {Calls ancestor} + inherited; + +end; + +{Mouse is now over the control} +procedure TPNGButton.CMMouseEnter(var Message: TMessage); +begin + if Enabled then + begin + if Assigned(fOnMouseEnter) then fOnMouseEnter(Self); + fMouseOverControl := True; + Repaint + end +end; + +{Mouse has left the control} +procedure TPNGButton.CMMouseLeave(var Message: TMessage); +begin + if Enabled then + begin + if Assigned(fOnMouseExit) then FOnMouseExit(Self); + fMouseOverControl := False; + Repaint + end +end; + + + +end. diff --git a/System/pngimage.pas b/System/pngimage.pas new file mode 100644 index 0000000..320891d --- /dev/null +++ b/System/pngimage.pas @@ -0,0 +1,5824 @@ +{Portable Network Graphics Delphi 1.564 (31 July 2006) } + +{This is a full, open sourced implementation of png in Delphi } +{It has native support for most of png features including the } +{partial transparency, gamma and more. } +{For the latest version, please be sure to check my website } +{http://pngdelphi.sourceforge.net } +{Gustavo Huffenbacher Daud (gustavo.daud@terra.com.br) } + + +{ + Version 1.564 + 2006-07-25 BUG 1 - There was one GDI Palette object leak + when assigning from other PNG (fixed) + BUG 2 - Loosing color information when assigning png + to bmp on lower screen depth system + BUG 3 - There was a bug in TStream.GetSize + (fixed thanks to Vladimir Panteleev) + IMPROVE 1 - When assigning png to bmp now alpha information + is drawn (simulated into a white background) + + Version 1.563 + 2006-07-25 BUG 1 - There was a memory bug in the main component + destructor (fixed thanks to Steven L Brenner) + BUG 2 - The packages name contained spaces which was + causing some strange bugs in Delphi + (fixed thanks to Martijn Saly) + BUG 3 - Lots of fixes when handling palettes + (bugs implemented in the last version) + Fixed thanks to Gabriel Corneanu!!! + BUG 4 - CreateAlpha was raising an error because it did + not resized the palette chunk it created; + Fixed thanks to Miha Sokolov + IMPROVE 1 - Renamed the pngzlib.pas unit to zlibpas.pas + as a tentative to all libraries use the same + shared zlib implementation and to avoid including + two or three times the same P-Code. + (Gabriel Corneanu idea) + + + + Version 1.561 + 2006-05-17 BUG 1 - There was a bug in the method that draws semi + transparent images (a memory leak). fixed. + + Version 1.56 + 2006-05-09 - IMPROVE 1 - Delphi standard TCanvas support is now implemented + IMPROVE 2 - The PNG files may now be resized and created from + scratch using CreateBlank, Resize, Width and Height + BUG 1 - Fixed some bugs on handling tRNS transparencies + BUG 2 - Fixed bugs related to palette handling + + Version 1.535 + 2006-04-21 - IMPROVE 1 - Now the library uses the latest ZLIB release (1.2.3) + (thanks to: Roberto Della Pasqua + http://www.dellapasqua.com/delphizlib/) + + Version 1.53 + 2006-04-14 - + BUG 1 - Remove transparency was not working for + RGB Alpha and Grayscale alpha. fixed + BUG 2 - There was a bug were compressed text chunks no keyword + name could not be read + IMPROVE 1 - Add classes and methods to work with the pHYs chunk + (including TPNGObject.DrawUsingPixelInformation) + IMPROVE 3 - Included a property Version to return the library + version + IMPROVE 4 - New polish translation (thanks to Piotr Domanski) + IMPROVE 5 - Now packages for delphi 5, 6, 7, 2005 and 2006 + + Also Martijn Saly (thany) made some improvements in the library: + IMPROVE 1 - SetPixel now works with grayscale + IMPROVE 2 - Palette property now can be written using a + windows handle + Thanks !! + + Version 1.5 + 2005-06-29 - Fixed a lot of bugs using tips from mails that I´ve + being receiving for some time + BUG 1 - Loosing palette when assigning to TBitmap. fixed + BUG 2 - SetPixels and GetPixels worked only with + parameters in range 0..255. fixed + BUG 3 - Force type address off using directive + BUG 4 - TChunkzTXt contained an error + BUG 5 - MaxIdatSize was not working correctly (fixed thanks + to Gabriel Corneanu + BUG 6 - Corrected german translation (thanks to Mael Horz) + And the following improvements: + IMPROVE 1 - Create ImageHandleValue properties as public in + TChunkIHDR to get access to this handle + IMPROVE 2 - Using SetStretchBltMode to improve stretch quality + IMPROVE 3 - Scale is now working for alpha transparent images + IMPROVE 4 - GammaTable propery is now public to support an + article in the help file + + Version 1.4361 + 2003-03-04 - Fixed important bug for simple transparency when using + RGB, Grayscale color modes + + Version 1.436 + 2003-03-04 - * NEW * Property Pixels for direct access to pixels + * IMPROVED * Palette property (TPngObject) (read only) + Slovenian traslation for the component (Miha Petelin) + Help file update (scanline article/png->jpg example) + + Version 1.435 + 2003-11-03 - * NEW * New chunk implementation zTXt (method AddzTXt) + * NEW * New compiler flags to store the extra 8 bits + from 16 bits samples (when saving it is ignored), the + extra data may be acessed using ExtraScanline property + * Fixed * a bug on tIMe chunk + French translation included (Thanks to IBE Software) + Bugs fixed + + Version 1.432 + 2002-08-24 - * NEW * A new method, CreateAlpha will transform the + current image into partial transparency. + Help file updated with a new article on how to handle + partial transparency. + + Version 1.431 + 2002-08-14 - Fixed and tested to work on: + C++ Builder 3 + C++ Builder 5 + Delphi 3 + There was an error when setting TransparentColor, fixed + New method, RemoveTransparency to remove image + BIT TRANSPARENCY + + Version 1.43 + 2002-08-01 - * NEW * Support for Delphi 3 and C++ Builder 3 + Implements mostly some things that were missing, + a few tweaks and fixes. + + Version 1.428 + 2002-07-24 - More minor fixes (thanks to Ian Boyd) + Bit transparency fixes + * NEW * Finally support to bit transparency + (palette / rgb / grayscale -> all) + + Version 1.427 + 2002-07-19 - Lots of bugs and leaks fixed + * NEW * method to easy adding text comments, AddtEXt + * NEW * property for setting bit transparency, + TransparentColor + + Version 1.426 + 2002-07-18 - Clipboard finally fixed and working + Changed UseDelphi trigger to UseDelphi + * NEW * Support for bit transparency bitmaps + when assigning from/to TBitmap objects + Altough it does not support drawing transparent + parts of bit transparency pngs (only partial) + it is closer than ever + + Version 1.425 + 2002-07-01 - Clipboard methods implemented + Lots of bugs fixed + + Version 1.424 + 2002-05-16 - Scanline and AlphaScanline are now working correctly. + New methods for handling the clipboard + + Version 1.423 + 2002-05-16 - * NEW * Partial transparency for 1, 2, 4 and 8 bits is + also supported using the tRNS chunk (for palette and + grayscaling). + New bug fixes (Peter Haas). + + Version 1.422 + 2002-05-14 - Fixed some critical leaks, thanks to Peter Haas tips. + New translation for German (Peter Haas). + + Version 1.421 + 2002-05-06 - Now uses new ZLIB version, 1.1.4 with some security + fixes. + LoadFromResourceID and LoadFromResourceName added and + help file updated for that. + The resources strings are now located in pnglang.pas. + New translation for Brazilian Portuguese. + Bugs fixed. + + IMPORTANT: As always I´m looking for bugs on the library. If + anyone has found one, please send me an email and + I will fix asap. Thanks for all the help and ideas + I'm receiving so far.} + +{My email is : gustavo.daud@terra.com.br} +{Website link : http://pngdelphi.sourceforge.net} +{Gustavo Huffenbacher Daud} + +unit pngimage; + +interface + +{Triggers avaliable (edit the fields bellow)} +{$TYPEDADDRESS OFF} + +{$DEFINE UseDelphi} //Disable fat vcl units(perfect for small apps) +{$DEFINE ErrorOnUnknownCritical} //Error when finds an unknown critical chunk +{$DEFINE CheckCRC} //Enables CRC checking +{$DEFINE RegisterGraphic} //Registers TPNGObject to use with TPicture +{$DEFINE PartialTransparentDraw} //Draws partial transparent images +{$DEFINE Store16bits} //Stores the extra 8 bits from 16bits/sample +{$RANGECHECKS OFF} {$J+} + + + +uses + Windows {$IFDEF UseDelphi}, Classes, Graphics, SysUtils{$ENDIF}, + zlibpas, pnglang; + +const + LibraryVersion = '1.564'; + +{$IFNDEF UseDelphi} + const + soFromBeginning = 0; + soFromCurrent = 1; + soFromEnd = 2; +{$ENDIF} + +const + {ZLIB constants} + ZLIBErrors: Array[-6..2] of string = ('incompatible version (-6)', + 'buffer error (-5)', 'insufficient memory (-4)', 'data error (-3)', + 'stream error (-2)', 'file error (-1)', '(0)', 'stream end (1)', + 'need dictionary (2)'); + Z_NO_FLUSH = 0; + Z_FINISH = 4; + Z_STREAM_END = 1; + + {Avaliable PNG filters for mode 0} + FILTER_NONE = 0; + FILTER_SUB = 1; + FILTER_UP = 2; + FILTER_AVERAGE = 3; + FILTER_PAETH = 4; + + {Avaliable color modes for PNG} + COLOR_GRAYSCALE = 0; + COLOR_RGB = 2; + COLOR_PALETTE = 3; + COLOR_GRAYSCALEALPHA = 4; + COLOR_RGBALPHA = 6; + + +type + {$IFNDEF UseDelphi} + {Custom exception handler} + Exception = class(TObject) + constructor Create(Msg: String); + end; + ExceptClass = class of Exception; + TColor = ColorRef; + {$ENDIF} + + {Error types} + EPNGOutMemory = class(Exception); + EPngError = class(Exception); + EPngUnexpectedEnd = class(Exception); + EPngInvalidCRC = class(Exception); + EPngInvalidIHDR = class(Exception); + EPNGMissingMultipleIDAT = class(Exception); + EPNGZLIBError = class(Exception); + EPNGInvalidPalette = class(Exception); + EPNGInvalidFileHeader = class(Exception); + EPNGIHDRNotFirst = class(Exception); + EPNGNotExists = class(Exception); + EPNGSizeExceeds = class(Exception); + EPNGMissingPalette = class(Exception); + EPNGUnknownCriticalChunk = class(Exception); + EPNGUnknownCompression = class(Exception); + EPNGUnknownInterlace = class(Exception); + EPNGNoImageData = class(Exception); + EPNGCouldNotLoadResource = class(Exception); + EPNGCannotChangeTransparent = class(Exception); + EPNGHeaderNotPresent = class(Exception); + EPNGInvalidNewSize = class(Exception); + EPNGInvalidSpec = class(Exception); + +type + {Direct access to pixels using R,G,B} + TRGBLine = array[word] of TRGBTriple; + pRGBLine = ^TRGBLine; + + {Same as TBitmapInfo but with allocated space for} + {palette entries} + TMAXBITMAPINFO = packed record + bmiHeader: TBitmapInfoHeader; + bmiColors: packed array[0..255] of TRGBQuad; + end; + + {Transparency mode for pngs} + TPNGTransparencyMode = (ptmNone, ptmBit, ptmPartial); + {Pointer to a cardinal type} + pCardinal = ^Cardinal; + {Access to a rgb pixel} + pRGBPixel = ^TRGBPixel; + TRGBPixel = packed record + B, G, R: Byte; + end; + + {Pointer to an array of bytes type} + TByteArray = Array[Word] of Byte; + pByteArray = ^TByteArray; + + {Forward} + TPNGObject = class; + pPointerArray = ^TPointerArray; + TPointerArray = Array[Word] of Pointer; + + {Contains a list of objects} + TPNGPointerList = class + private + fOwner: TPNGObject; + fCount : Cardinal; + fMemory: pPointerArray; + function GetItem(Index: Cardinal): Pointer; + procedure SetItem(Index: Cardinal; const Value: Pointer); + protected + {Removes an item} + function Remove(Value: Pointer): Pointer; virtual; + {Inserts an item} + procedure Insert(Value: Pointer; Position: Cardinal); + {Add a new item} + procedure Add(Value: Pointer); + {Returns an item} + property Item[Index: Cardinal]: Pointer read GetItem write SetItem; + {Set the size of the list} + procedure SetSize(const Size: Cardinal); + {Returns owner} + property Owner: TPNGObject read fOwner; + public + {Returns number of items} + property Count: Cardinal read fCount write SetSize; + {Object being either created or destroyed} + constructor Create(AOwner: TPNGObject); + destructor Destroy; override; + end; + + {Forward declaration} + TChunk = class; + TChunkClass = class of TChunk; + + {Same as TPNGPointerList but providing typecasted values} + TPNGList = class(TPNGPointerList) + private + {Used with property Item} + function GetItem(Index: Cardinal): TChunk; + public + {Finds the first item with this class} + function FindChunk(ChunkClass: TChunkClass): TChunk; + {Removes an item} + procedure RemoveChunk(Chunk: TChunk); overload; + {Add a new chunk using the class from the parameter} + function Add(ChunkClass: TChunkClass): TChunk; + {Returns pointer to the first chunk of class} + function ItemFromClass(ChunkClass: TChunkClass): TChunk; + {Returns a chunk item from the list} + property Item[Index: Cardinal]: TChunk read GetItem; + end; + + {$IFNDEF UseDelphi} + {The STREAMs bellow are only needed in case delphi provided ones is not} + {avaliable (UseDelphi trigger not set)} + {Object becomes handles} + TCanvas = THandle; + TBitmap = HBitmap; + {Trick to work} + TPersistent = TObject; + + {Base class for all streams} + TStream = class + protected + {Returning/setting size} + function GetSize: Longint; virtual; + procedure SetSize(const Value: Longint); virtual; abstract; + {Returns/set position} + function GetPosition: Longint; virtual; + procedure SetPosition(const Value: Longint); virtual; + public + {Returns/sets current position} + property Position: Longint read GetPosition write SetPosition; + {Property returns/sets size} + property Size: Longint read GetSize write SetSize; + {Allows reading/writing data} + function Read(var Buffer; Count: Longint): Cardinal; virtual; abstract; + function Write(const Buffer; Count: Longint): Cardinal; virtual; abstract; + {Copies from another Stream} + function CopyFrom(Source: TStream; + Count: Cardinal): Cardinal; virtual; + {Seeks a stream position} + function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract; + end; + + {File stream modes} + TFileStreamMode = (fsmRead, fsmWrite, fsmCreate); + TFileStreamModeSet = set of TFileStreamMode; + + {File stream for reading from files} + TFileStream = class(TStream) + private + {Opened mode} + Filemode: TFileStreamModeSet; + {Handle} + fHandle: THandle; + protected + {Set the size of the file} + procedure SetSize(const Value: Longint); override; + public + {Seeks a file position} + function Seek(Offset: Longint; Origin: Word): Longint; override; + {Reads/writes data from/to the file} + function Read(var Buffer; Count: Longint): Cardinal; override; + function Write(const Buffer; Count: Longint): Cardinal; override; + {Stream being created and destroy} + constructor Create(Filename: String; Mode: TFileStreamModeSet); + destructor Destroy; override; + end; + + {Stream for reading from resources} + TResourceStream = class(TStream) + constructor Create(Instance: HInst; const ResName: String; ResType:PChar); + private + {Variables for reading} + Size: Integer; + Memory: Pointer; + Position: Integer; + protected + {Set the size of the file} + procedure SetSize(const Value: Longint); override; + public + {Stream processing} + function Read(var Buffer; Count: Integer): Cardinal; override; + function Seek(Offset: Integer; Origin: Word): Longint; override; + function Write(const Buffer; Count: Longint): Cardinal; override; + end; + {$ENDIF} + + {Forward} + TChunkIHDR = class; + TChunkpHYs = class; + {Interlace method} + TInterlaceMethod = (imNone, imAdam7); + {Compression level type} + TCompressionLevel = 0..9; + {Filters type} + TFilter = (pfNone, pfSub, pfUp, pfAverage, pfPaeth); + TFilters = set of TFilter; + + {Png implementation object} + TPngObject = class{$IFDEF UseDelphi}(TGraphic){$ENDIF} + protected + {Inverse gamma table values} + InverseGamma: Array[Byte] of Byte; + procedure InitializeGamma; + private + {Canvas} + {$IFDEF UseDelphi}fCanvas: TCanvas;{$ENDIF} + {Filters to test to encode} + fFilters: TFilters; + {Compression level for ZLIB} + fCompressionLevel: TCompressionLevel; + {Maximum size for IDAT chunks} + fMaxIdatSize: Integer; + {Returns if image is interlaced} + fInterlaceMethod: TInterlaceMethod; + {Chunks object} + fChunkList: TPngList; + {Clear all chunks in the list} + procedure ClearChunks; + {Returns if header is present} + function HeaderPresent: Boolean; + procedure GetPixelInfo(var LineSize, Offset: Cardinal); + {Returns linesize and byte offset for pixels} + procedure SetMaxIdatSize(const Value: Integer); + function GetAlphaScanline(const LineIndex: Integer): pByteArray; + function GetScanline(const LineIndex: Integer): Pointer; + {$IFDEF Store16bits} + function GetExtraScanline(const LineIndex: Integer): Pointer; + {$ENDIF} + function GetPixelInformation: TChunkpHYs; + function GetTransparencyMode: TPNGTransparencyMode; + function GetTransparentColor: TColor; + procedure SetTransparentColor(const Value: TColor); + {Returns the version} + function GetLibraryVersion: String; + protected + {Being created} + BeingCreated: Boolean; + {Returns / set the image palette} + function GetPalette: HPALETTE; {$IFDEF UseDelphi}override;{$ENDIF} + procedure SetPalette(Value: HPALETTE); {$IFDEF UseDelphi}override;{$ENDIF} + procedure DoSetPalette(Value: HPALETTE; const UpdateColors: Boolean); + {Returns/sets image width and height} + function GetWidth: Integer; {$IFDEF UseDelphi}override;{$ENDIF} + function GetHeight: Integer; {$IFDEF UseDelphi}override; {$ENDIF} + procedure SetWidth(Value: Integer); {$IFDEF UseDelphi}override; {$ENDIF} + procedure SetHeight(Value: Integer); {$IFDEF UseDelphi}override;{$ENDIF} + {Assigns from another TPNGObject} + procedure AssignPNG(Source: TPNGObject); + {Returns if the image is empty} + function GetEmpty: Boolean; {$IFDEF UseDelphi}override; {$ENDIF} + {Used with property Header} + function GetHeader: TChunkIHDR; + {Draws using partial transparency} + procedure DrawPartialTrans(DC: HDC; Rect: TRect); + {$IFDEF UseDelphi} + {Returns if the image is transparent} + function GetTransparent: Boolean; override; + {$ENDIF} + {Returns a pixel} + function GetPixels(const X, Y: Integer): TColor; virtual; + procedure SetPixels(const X, Y: Integer; const Value: TColor); virtual; + public + {Gamma table array} + GammaTable: Array[Byte] of Byte; + {Resizes the PNG image} + procedure Resize(const CX, CY: Integer); + {Generates alpha information} + procedure CreateAlpha; + {Removes the image transparency} + procedure RemoveTransparency; + {Transparent color} + property TransparentColor: TColor read GetTransparentColor write + SetTransparentColor; + {Add text chunk, TChunkTEXT, TChunkzTXT} + procedure AddtEXt(const Keyword, Text: String); + procedure AddzTXt(const Keyword, Text: String); + {$IFDEF UseDelphi} + {Saves to clipboard format (thanks to Antoine Pottern)} + procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; + var APalette: HPalette); override; + procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle; + APalette: HPalette); override; + {$ENDIF} + {Calling errors} + procedure RaiseError(ExceptionClass: ExceptClass; Text: String); + {Returns a scanline from png} + property Scanline[const Index: Integer]: Pointer read GetScanline; + {$IFDEF Store16bits} + property ExtraScanline[const Index: Integer]: Pointer read GetExtraScanline; + {$ENDIF} + {Used to return pixel information} + function HasPixelInformation: Boolean; + property PixelInformation: TChunkpHYs read GetPixelInformation; + property AlphaScanline[const Index: Integer]: pByteArray read + GetAlphaScanline; + procedure DrawUsingPixelInformation(Canvas: TCanvas; Point: TPoint); + + {Canvas} + {$IFDEF UseDelphi}property Canvas: TCanvas read fCanvas;{$ENDIF} + {Returns pointer to the header} + property Header: TChunkIHDR read GetHeader; + {Returns the transparency mode used by this png} + property TransparencyMode: TPNGTransparencyMode read GetTransparencyMode; + {Assigns from another object} + procedure Assign(Source: TPersistent);{$IFDEF UseDelphi}override;{$ENDIF} + {Assigns to another object} + procedure AssignTo(Dest: TPersistent);{$IFDEF UseDelphi}override;{$ENDIF} + {Assigns from a windows bitmap handle} + procedure AssignHandle(Handle: HBitmap; Transparent: Boolean; + TransparentColor: ColorRef); + {Draws the image into a canvas} + procedure Draw(ACanvas: TCanvas; const Rect: TRect); + {$IFDEF UseDelphi}override;{$ENDIF} + {Width and height properties} + property Width: Integer read GetWidth; + property Height: Integer read GetHeight; + {Returns if the image is interlaced} + property InterlaceMethod: TInterlaceMethod read fInterlaceMethod + write fInterlaceMethod; + {Filters to test to encode} + property Filters: TFilters read fFilters write fFilters; + {Maximum size for IDAT chunks, default and minimum is 65536} + property MaxIdatSize: Integer read fMaxIdatSize write SetMaxIdatSize; + {Property to return if the image is empty or not} + property Empty: Boolean read GetEmpty; + {Compression level} + property CompressionLevel: TCompressionLevel read fCompressionLevel + write fCompressionLevel; + {Access to the chunk list} + property Chunks: TPngList read fChunkList; + {Object being created and destroyed} + constructor Create; {$IFDEF UseDelphi}override;{$ENDIF} + constructor CreateBlank(ColorType, Bitdepth: Cardinal; cx, cy: Integer); + destructor Destroy; override; + {$IFNDEF UseDelphi}procedure LoadFromFile(const Filename: String);{$ENDIF} + {$IFNDEF UseDelphi}procedure SaveToFile(const Filename: String);{$ENDIF} + procedure LoadFromStream(Stream: TStream); + {$IFDEF UseDelphi}override;{$ENDIF} + procedure SaveToStream(Stream: TStream); {$IFDEF UseDelphi}override;{$ENDIF} + {Loading the image from resources} + procedure LoadFromResourceName(Instance: HInst; const Name: String); + procedure LoadFromResourceID(Instance: HInst; ResID: Integer); + {Access to the png pixels} + property Pixels[const X, Y: Integer]: TColor read GetPixels write SetPixels; + {Palette property} + {$IFNDEF UseDelphi}property Palette: HPalette read GetPalette write + SetPalette;{$ENDIF} + {Returns the version} + property Version: String read GetLibraryVersion; + end; + + {Chunk name object} + TChunkName = Array[0..3] of Char; + + {Global chunk object} + TChunk = class + private + {Contains data} + fData: Pointer; + fDataSize: Cardinal; + {Stores owner} + fOwner: TPngObject; + {Stores the chunk name} + fName: TChunkName; + {Returns pointer to the TChunkIHDR} + function GetHeader: TChunkIHDR; + {Used with property index} + function GetIndex: Integer; + {Should return chunk class/name} + class function GetName: String; virtual; + {Returns the chunk name} + function GetChunkName: String; + public + {Returns index from list} + property Index: Integer read GetIndex; + {Returns pointer to the TChunkIHDR} + property Header: TChunkIHDR read GetHeader; + {Resize the data} + procedure ResizeData(const NewSize: Cardinal); + {Returns data and size} + property Data: Pointer read fData; + property DataSize: Cardinal read fDataSize; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); virtual; + {Returns owner} + property Owner: TPngObject read fOwner; + {Being destroyed/created} + constructor Create(Owner: TPngObject); virtual; + destructor Destroy; override; + {Returns chunk class/name} + property Name: String read GetChunkName; + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; virtual; + {Saves the chunk to a stream} + function SaveData(Stream: TStream): Boolean; + function SaveToStream(Stream: TStream): Boolean; virtual; + end; + + {Chunk classes} + TChunkIEND = class(TChunk); {End chunk} + + {IHDR data} + pIHDRData = ^TIHDRData; + TIHDRData = packed record + Width, Height: Cardinal; + BitDepth, + ColorType, + CompressionMethod, + FilterMethod, + InterlaceMethod: Byte; + end; + + {Information header chunk} + TChunkIHDR = class(TChunk) + private + {Current image} + ImageHandle: HBitmap; + ImageDC: HDC; + ImagePalette: HPalette; + {Output windows bitmap} + HasPalette: Boolean; + BitmapInfo: TMaxBitmapInfo; + {Stores the image bytes} + {$IFDEF Store16bits}ExtraImageData: Pointer;{$ENDIF} + ImageData: pointer; + ImageAlpha: Pointer; + + {Contains all the ihdr data} + IHDRData: TIHDRData; + protected + BytesPerRow: Integer; + {Creates a grayscale palette} + function CreateGrayscalePalette(Bitdepth: Integer): HPalette; + {Copies the palette to the Device Independent bitmap header} + procedure PaletteToDIB(Palette: HPalette); + {Resizes the image data to fill the color type, bit depth, } + {width and height parameters} + procedure PrepareImageData; + {Release allocated ImageData memory} + procedure FreeImageData; + public + {Access to ImageHandle} + property ImageHandleValue: HBitmap read ImageHandle; + {Properties} + property Width: Cardinal read IHDRData.Width write IHDRData.Width; + property Height: Cardinal read IHDRData.Height write IHDRData.Height; + property BitDepth: Byte read IHDRData.BitDepth write IHDRData.BitDepth; + property ColorType: Byte read IHDRData.ColorType write IHDRData.ColorType; + property CompressionMethod: Byte read IHDRData.CompressionMethod + write IHDRData.CompressionMethod; + property FilterMethod: Byte read IHDRData.FilterMethod + write IHDRData.FilterMethod; + property InterlaceMethod: Byte read IHDRData.InterlaceMethod + write IHDRData.InterlaceMethod; + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Saves the chunk to a stream} + function SaveToStream(Stream: TStream): Boolean; override; + {Destructor/constructor} + constructor Create(Owner: TPngObject); override; + destructor Destroy; override; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); override; + end; + + {pHYs chunk} + pUnitType = ^TUnitType; + TUnitType = (utUnknown, utMeter); + TChunkpHYs = class(TChunk) + private + fPPUnitX, fPPUnitY: Cardinal; + fUnit: TUnitType; + public + {Returns the properties} + property PPUnitX: Cardinal read fPPUnitX write fPPUnitX; + property PPUnitY: Cardinal read fPPUnitY write fPPUnitY; + property UnitType: TUnitType read fUnit write fUnit; + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Saves the chunk to a stream} + function SaveToStream(Stream: TStream): Boolean; override; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); override; + end; + + {Gamma chunk} + TChunkgAMA = class(TChunk) + private + {Returns/sets the value for the gamma chunk} + function GetValue: Cardinal; + procedure SetValue(const Value: Cardinal); + public + {Returns/sets gamma value} + property Gamma: Cardinal read GetValue write SetValue; + {Loading the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Being created} + constructor Create(Owner: TPngObject); override; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); override; + end; + + {ZLIB Decompression extra information} + TZStreamRec2 = packed record + {From ZLIB} + ZLIB: TZStreamRec; + {Additional info} + Data: Pointer; + fStream : TStream; + end; + + {Palette chunk} + TChunkPLTE = class(TChunk) + protected + {Number of items in the palette} + fCount: Integer; + private + {Contains the palette handle} + function GetPaletteItem(Index: Byte): TRGBQuad; + public + {Returns the color for each item in the palette} + property Item[Index: Byte]: TRGBQuad read GetPaletteItem; + {Returns the number of items in the palette} + property Count: Integer read fCount; + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Saves the chunk to a stream} + function SaveToStream(Stream: TStream): Boolean; override; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); override; + end; + + {Transparency information} + TChunktRNS = class(TChunk) + private + fBitTransparency: Boolean; + function GetTransparentColor: ColorRef; + {Returns the transparent color} + procedure SetTransparentColor(const Value: ColorRef); + public + {Palette values for transparency} + PaletteValues: Array[Byte] of Byte; + {Returns if it uses bit transparency} + property BitTransparency: Boolean read fBitTransparency; + {Returns the transparent color} + property TransparentColor: ColorRef read GetTransparentColor write + SetTransparentColor; + {Loads/saves the chunk from/to a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + function SaveToStream(Stream: TStream): Boolean; override; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); override; + end; + + {Actual image information} + TChunkIDAT = class(TChunk) + private + {Holds another pointer to the TChunkIHDR} + Header: TChunkIHDR; + {Stores temporary image width and height} + ImageWidth, ImageHeight: Integer; + {Size in bytes of each line and offset} + Row_Bytes, Offset : Cardinal; + {Contains data for the lines} + Encode_Buffer: Array[0..5] of pByteArray; + Row_Buffer: Array[Boolean] of pByteArray; + {Variable to invert the Row_Buffer used} + RowUsed: Boolean; + {Ending position for the current IDAT chunk} + EndPos: Integer; + {Filter the current line} + procedure FilterRow; + {Filter to encode and returns the best filter} + function FilterToEncode: Byte; + {Reads ZLIB compressed data} + function IDATZlibRead(var ZLIBStream: TZStreamRec2; Buffer: Pointer; + Count: Integer; var EndPos: Integer; var crcfile: Cardinal): Integer; + {Compress and writes IDAT data} + procedure IDATZlibWrite(var ZLIBStream: TZStreamRec2; Buffer: Pointer; + const Length: Cardinal); + procedure FinishIDATZlib(var ZLIBStream: TZStreamRec2); + {Prepares the palette} + procedure PreparePalette; + protected + {Decode interlaced image} + procedure DecodeInterlacedAdam7(Stream: TStream; + var ZLIBStream: TZStreamRec2; const Size: Integer; var crcfile: Cardinal); + {Decode non interlaced imaged} + procedure DecodeNonInterlaced(Stream: TStream; + var ZLIBStream: TZStreamRec2; const Size: Integer; + var crcfile: Cardinal); + protected + {Encode non interlaced images} + procedure EncodeNonInterlaced(Stream: TStream; + var ZLIBStream: TZStreamRec2); + {Encode interlaced images} + procedure EncodeInterlacedAdam7(Stream: TStream; + var ZLIBStream: TZStreamRec2); + protected + {Memory copy methods to decode} + procedure CopyNonInterlacedRGB8( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedRGB16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedPalette148( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedPalette2( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedGray2( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedGrayscale16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedRGBAlpha8( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedRGBAlpha16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedGrayscaleAlpha8( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyNonInterlacedGrayscaleAlpha16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedRGB8(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedRGB16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedPalette148(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedPalette2(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedGray2(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedGrayscale16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedRGBAlpha8(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedRGBAlpha16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedGrayscaleAlpha8(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + procedure CopyInterlacedGrayscaleAlpha16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); + protected + {Memory copy methods to encode} + procedure EncodeNonInterlacedRGB8(Src, Dest, Trans: pChar); + procedure EncodeNonInterlacedRGB16(Src, Dest, Trans: pChar); + procedure EncodeNonInterlacedGrayscale16(Src, Dest, Trans: pChar); + procedure EncodeNonInterlacedPalette148(Src, Dest, Trans: pChar); + procedure EncodeNonInterlacedRGBAlpha8(Src, Dest, Trans: pChar); + procedure EncodeNonInterlacedRGBAlpha16(Src, Dest, Trans: pChar); + procedure EncodeNonInterlacedGrayscaleAlpha8(Src, Dest, Trans: pChar); + procedure EncodeNonInterlacedGrayscaleAlpha16(Src, Dest, Trans: pChar); + procedure EncodeInterlacedRGB8(const Pass: Byte; Src, Dest, Trans: pChar); + procedure EncodeInterlacedRGB16(const Pass: Byte; Src, Dest, Trans: pChar); + procedure EncodeInterlacedPalette148(const Pass: Byte; + Src, Dest, Trans: pChar); + procedure EncodeInterlacedGrayscale16(const Pass: Byte; + Src, Dest, Trans: pChar); + procedure EncodeInterlacedRGBAlpha8(const Pass: Byte; + Src, Dest, Trans: pChar); + procedure EncodeInterlacedRGBAlpha16(const Pass: Byte; + Src, Dest, Trans: pChar); + procedure EncodeInterlacedGrayscaleAlpha8(const Pass: Byte; + Src, Dest, Trans: pChar); + procedure EncodeInterlacedGrayscaleAlpha16(const Pass: Byte; + Src, Dest, Trans: pChar); + public + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Saves the chunk to a stream} + function SaveToStream(Stream: TStream): Boolean; override; + end; + + {Image last modification chunk} + TChunktIME = class(TChunk) + private + {Holds the variables} + fYear: Word; + fMonth, fDay, fHour, fMinute, fSecond: Byte; + public + {Returns/sets variables} + property Year: Word read fYear write fYear; + property Month: Byte read fMonth write fMonth; + property Day: Byte read fDay write fDay; + property Hour: Byte read fHour write fHour; + property Minute: Byte read fMinute write fMinute; + property Second: Byte read fSecond write fSecond; + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Saves the chunk to a stream} + function SaveToStream(Stream: TStream): Boolean; override; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); override; + end; + + {Textual data} + TChunktEXt = class(TChunk) + private + fKeyword, fText: String; + public + {Keyword and text} + property Keyword: String read fKeyword write fKeyword; + property Text: String read fText write fText; + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Saves the chunk to a stream} + function SaveToStream(Stream: TStream): Boolean; override; + {Assigns from another TChunk} + procedure Assign(Source: TChunk); override; + end; + + {zTXT chunk} + TChunkzTXt = class(TChunktEXt) + {Loads the chunk from a stream} + function LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; override; + {Saves the chunk to a stream} + function SaveToStream(Stream: TStream): Boolean; override; + end; + +{Here we test if it's c++ builder or delphi version 3 or less} +{$IFDEF VER110}{$DEFINE DelphiBuilder3Less}{$ENDIF} +{$IFDEF VER100}{$DEFINE DelphiBuilder3Less}{$ENDIF} +{$IFDEF VER93}{$DEFINE DelphiBuilder3Less}{$ENDIF} +{$IFDEF VER90}{$DEFINE DelphiBuilder3Less}{$ENDIF} +{$IFDEF VER80}{$DEFINE DelphiBuilder3Less}{$ENDIF} + + +{Registers a new chunk class} +procedure RegisterChunk(ChunkClass: TChunkClass); +{Calculates crc} +function update_crc(crc: {$IFNDEF DelphiBuilder3Less}Cardinal{$ELSE}Integer + {$ENDIF}; buf: pByteArray; len: Integer): Cardinal; +{Invert bytes using assembly} +function ByteSwap(const a: integer): integer; + +implementation + +var + ChunkClasses: TPngPointerList; + {Table of CRCs of all 8-bit messages} + crc_table: Array[0..255] of Cardinal; + {Flag: has the table been computed? Initially false} + crc_table_computed: Boolean; + +{Draw transparent image using transparent color} +procedure DrawTransparentBitmap(dc: HDC; srcBits: Pointer; + var srcHeader: TBitmapInfoHeader; + srcBitmapInfo: pBitmapInfo; Rect: TRect; cTransparentColor: COLORREF); +var + cColor: COLORREF; + bmAndBack, bmAndObject, bmAndMem: HBITMAP; + bmBackOld, bmObjectOld, bmMemOld: HBITMAP; + hdcMem, hdcBack, hdcObject, hdcTemp: HDC; + ptSize, orgSize: TPOINT; + OldBitmap, DrawBitmap: HBITMAP; +begin + hdcTemp := CreateCompatibleDC(dc); + {Select the bitmap} + DrawBitmap := CreateDIBitmap(dc, srcHeader, CBM_INIT, srcBits, srcBitmapInfo^, + DIB_RGB_COLORS); + OldBitmap := SelectObject(hdcTemp, DrawBitmap); + + {Get sizes} + OrgSize.x := abs(srcHeader.biWidth); + OrgSize.y := abs(srcHeader.biHeight); + ptSize.x := Rect.Right - Rect.Left; // Get width of bitmap + ptSize.y := Rect.Bottom - Rect.Top; // Get height of bitmap + + {Create some DCs to hold temporary data} + hdcBack := CreateCompatibleDC(dc); + hdcObject := CreateCompatibleDC(dc); + hdcMem := CreateCompatibleDC(dc); + + // Create a bitmap for each DC. DCs are required for a number of + // GDI functions. + + // Monochrome DCs + bmAndBack := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil); + bmAndObject := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil); + + bmAndMem := CreateCompatibleBitmap(dc, ptSize.x, ptSize.y); + + // Each DC must select a bitmap object to store pixel data. + bmBackOld := SelectObject(hdcBack, bmAndBack); + bmObjectOld := SelectObject(hdcObject, bmAndObject); + bmMemOld := SelectObject(hdcMem, bmAndMem); + + // Set the background color of the source DC to the color. + // contained in the parts of the bitmap that should be transparent + cColor := SetBkColor(hdcTemp, cTransparentColor); + + // Create the object mask for the bitmap by performing a BitBlt + // from the source bitmap to a monochrome bitmap. + StretchBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, + orgSize.x, orgSize.y, SRCCOPY); + + // Set the background color of the source DC back to the original + // color. + SetBkColor(hdcTemp, cColor); + + // Create the inverse of the object mask. + BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, + NOTSRCCOPY); + + // Copy the background of the main DC to the destination. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, dc, Rect.Left, Rect.Top, + SRCCOPY); + + // Mask out the places where the bitmap will be placed. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND); + + // Mask out the transparent colored pixels on the bitmap. +// BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND); + StretchBlt(hdcTemp, 0, 0, OrgSize.x, OrgSize.y, hdcBack, 0, 0, + PtSize.x, PtSize.y, SRCAND); + + // XOR the bitmap with the background on the destination DC. + StretchBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, + OrgSize.x, OrgSize.y, SRCPAINT); + + // Copy the destination to the screen. + BitBlt(dc, Rect.Left, Rect.Top, ptSize.x, ptSize.y, hdcMem, 0, 0, + SRCCOPY); + + // Delete the memory bitmaps. + DeleteObject(SelectObject(hdcBack, bmBackOld)); + DeleteObject(SelectObject(hdcObject, bmObjectOld)); + DeleteObject(SelectObject(hdcMem, bmMemOld)); + DeleteObject(SelectObject(hdcTemp, OldBitmap)); + + // Delete the memory DCs. + DeleteDC(hdcMem); + DeleteDC(hdcBack); + DeleteDC(hdcObject); + DeleteDC(hdcTemp); +end; + +{Make the table for a fast CRC.} +procedure make_crc_table; +var + c: Cardinal; + n, k: Integer; +begin + + {fill the crc table} + for n := 0 to 255 do + begin + c := Cardinal(n); + for k := 0 to 7 do + begin + if Boolean(c and 1) then + c := $edb88320 xor (c shr 1) + else + c := c shr 1; + end; + crc_table[n] := c; + end; + + {The table has already being computated} + crc_table_computed := true; +end; + +{Update a running CRC with the bytes buf[0..len-1]--the CRC + should be initialized to all 1's, and the transmitted value + is the 1's complement of the final running CRC (see the + crc() routine below)).} +function update_crc(crc: {$IFNDEF DelphiBuilder3Less}Cardinal{$ELSE}Integer + {$ENDIF}; buf: pByteArray; len: Integer): Cardinal; +var + c: Cardinal; + n: Integer; +begin + c := crc; + + {Create the crc table in case it has not being computed yet} + if not crc_table_computed then make_crc_table; + + {Update} + for n := 0 to len - 1 do + c := crc_table[(c XOR buf^[n]) and $FF] XOR (c shr 8); + + {Returns} + Result := c; +end; + +{$IFNDEF UseDelphi} + function FileExists(Filename: String): Boolean; + var + FindFile: THandle; + FindData: TWin32FindData; + begin + FindFile := FindFirstFile(PChar(Filename), FindData); + Result := FindFile <> INVALID_HANDLE_VALUE; + if Result then Windows.FindClose(FindFile); + end; + + +{$ENDIF} + +{$IFNDEF UseDelphi} + {Exception implementation} + constructor Exception.Create(Msg: String); + begin + end; +{$ENDIF} + +{Calculates the paeth predictor} +function PaethPredictor(a, b, c: Byte): Byte; +var + pa, pb, pc: Integer; +begin + { a = left, b = above, c = upper left } + pa := abs(b - c); { distances to a, b, c } + pb := abs(a - c); + pc := abs(a + b - c * 2); + + { return nearest of a, b, c, breaking ties in order a, b, c } + if (pa <= pb) and (pa <= pc) then + Result := a + else + if pb <= pc then + Result := b + else + Result := c; +end; + +{Invert bytes using assembly} +function ByteSwap(const a: integer): integer; +asm + bswap eax +end; +function ByteSwap16(inp:word): word; +asm + bswap eax + shr eax, 16 +end; + +{Calculates number of bytes for the number of pixels using the} +{color mode in the paramenter} +function BytesForPixels(const Pixels: Integer; const ColorType, + BitDepth: Byte): Integer; +begin + case ColorType of + {Palette and grayscale contains a single value, for palette} + {an value of size 2^bitdepth pointing to the palette index} + {and grayscale the value from 0 to 2^bitdepth with color intesity} + COLOR_GRAYSCALE, COLOR_PALETTE: + Result := (Pixels * BitDepth + 7) div 8; + {RGB contains 3 values R, G, B with size 2^bitdepth each} + COLOR_RGB: + Result := (Pixels * BitDepth * 3) div 8; + {Contains one value followed by alpha value booth size 2^bitdepth} + COLOR_GRAYSCALEALPHA: + Result := (Pixels * BitDepth * 2) div 8; + {Contains four values size 2^bitdepth, Red, Green, Blue and alpha} + COLOR_RGBALPHA: + Result := (Pixels * BitDepth * 4) div 8; + else + Result := 0; + end {case ColorType} +end; + +type + pChunkClassInfo = ^TChunkClassInfo; + TChunkClassInfo = record + ClassName: TChunkClass; + end; + +{Register a chunk type} +procedure RegisterChunk(ChunkClass: TChunkClass); +var + NewClass: pChunkClassInfo; +begin + {In case the list object has not being created yet} + if ChunkClasses = nil then ChunkClasses := TPngPointerList.Create(nil); + + {Add this new class} + new(NewClass); + NewClass^.ClassName := ChunkClass; + ChunkClasses.Add(NewClass); +end; + +{Free chunk class list} +procedure FreeChunkClassList; +var + i: Integer; +begin + if (ChunkClasses <> nil) then + begin + FOR i := 0 TO ChunkClasses.Count - 1 do + Dispose(pChunkClassInfo(ChunkClasses.Item[i])); + ChunkClasses.Free; + end; +end; + +{Registering of common chunk classes} +procedure RegisterCommonChunks; +begin + {Important chunks} + RegisterChunk(TChunkIEND); + RegisterChunk(TChunkIHDR); + RegisterChunk(TChunkIDAT); + RegisterChunk(TChunkPLTE); + RegisterChunk(TChunkgAMA); + RegisterChunk(TChunktRNS); + + {Not so important chunks} + RegisterChunk(TChunkpHYs); + RegisterChunk(TChunktIME); + RegisterChunk(TChunktEXt); + RegisterChunk(TChunkzTXt); +end; + +{Creates a new chunk of this class} +function CreateClassChunk(Owner: TPngObject; Name: TChunkName): TChunk; +var + i : Integer; + NewChunk: TChunkClass; +begin + {Looks for this chunk} + NewChunk := TChunk; {In case there is no registered class for this} + + {Looks for this class in all registered chunks} + if Assigned(ChunkClasses) then + FOR i := 0 TO ChunkClasses.Count - 1 DO + begin + if pChunkClassInfo(ChunkClasses.Item[i])^.ClassName.GetName = Name then + begin + NewChunk := pChunkClassInfo(ChunkClasses.Item[i])^.ClassName; + break; + end; + end; + + {Returns chunk class} + Result := NewChunk.Create(Owner); + Result.fName := Name; +end; + +{ZLIB support} + +const + ZLIBAllocate = High(Word); + +{Initializes ZLIB for decompression} +function ZLIBInitInflate(Stream: TStream): TZStreamRec2; +begin + {Fill record} + Fillchar(Result, SIZEOF(TZStreamRec2), #0); + + {Set internal record information} + with Result do + begin + GetMem(Data, ZLIBAllocate); + fStream := Stream; + end; + + {Init decompression} + InflateInit_(Result.zlib, zlib_version, SIZEOF(TZStreamRec)); +end; + +{Initializes ZLIB for compression} +function ZLIBInitDeflate(Stream: TStream; + Level: TCompressionlevel; Size: Cardinal): TZStreamRec2; +begin + {Fill record} + Fillchar(Result, SIZEOF(TZStreamRec2), #0); + + {Set internal record information} + with Result, ZLIB do + begin + GetMem(Data, Size); + fStream := Stream; + next_out := Data; + avail_out := Size; + end; + + {Inits compression} + deflateInit_(Result.zlib, Level, zlib_version, sizeof(TZStreamRec)); +end; + +{Terminates ZLIB for compression} +procedure ZLIBTerminateDeflate(var ZLIBStream: TZStreamRec2); +begin + {Terminates decompression} + DeflateEnd(ZLIBStream.zlib); + {Free internal record} + FreeMem(ZLIBStream.Data, ZLIBAllocate); +end; + +{Terminates ZLIB for decompression} +procedure ZLIBTerminateInflate(var ZLIBStream: TZStreamRec2); +begin + {Terminates decompression} + InflateEnd(ZLIBStream.zlib); + {Free internal record} + FreeMem(ZLIBStream.Data, ZLIBAllocate); +end; + +{Decompresses ZLIB into a memory address} +function DecompressZLIB(const Input: Pointer; InputSize: Integer; + var Output: Pointer; var OutputSize: Integer; + var ErrorOutput: String): Boolean; +var + StreamRec : TZStreamRec; + Buffer : Array[Byte] of Byte; + InflateRet: Integer; +begin + with StreamRec do + begin + {Initializes} + Result := True; + OutputSize := 0; + + {Prepares the data to decompress} + FillChar(StreamRec, SizeOf(TZStreamRec), #0); + InflateInit_(StreamRec, zlib_version, SIZEOF(TZStreamRec)); + next_in := Input; + avail_in := InputSize; + + {Decodes data} + repeat + {In case it needs an output buffer} + if (avail_out = 0) then + begin + next_out := @Buffer; + avail_out := SizeOf(Buffer); + end {if (avail_out = 0)}; + + {Decompress and put in output} + InflateRet := inflate(StreamRec, 0); + if (InflateRet = Z_STREAM_END) or (InflateRet = 0) then + begin + {Reallocates output buffer} + inc(OutputSize, total_out); + if Output = nil then + GetMem(Output, OutputSize) else ReallocMem(Output, OutputSize); + {Copies the new data} + CopyMemory(Ptr(Longint(Output) + OutputSize - total_out), + @Buffer, total_out); + end {if (InflateRet = Z_STREAM_END) or (InflateRet = 0)} + {Now tests for errors} + else if InflateRet < 0 then + begin + Result := False; + ErrorOutput := StreamRec.msg; + InflateEnd(StreamRec); + Exit; + end {if InflateRet < 0} + until InflateRet = Z_STREAM_END; + + {Terminates decompression} + InflateEnd(StreamRec); + end {with StreamRec} + +end; + +{Compresses ZLIB into a memory address} +function CompressZLIB(Input: Pointer; InputSize, CompressionLevel: Integer; + var Output: Pointer; var OutputSize: Integer; + var ErrorOutput: String): Boolean; +var + StreamRec : TZStreamRec; + Buffer : Array[Byte] of Byte; + DeflateRet: Integer; +begin + with StreamRec do + begin + Result := True; {By default returns TRUE as everything might have gone ok} + OutputSize := 0; {Initialize} + {Prepares the data to compress} + FillChar(StreamRec, SizeOf(TZStreamRec), #0); + DeflateInit_(StreamRec, CompressionLevel,zlib_version, SIZEOF(TZStreamRec)); + + next_in := Input; + avail_in := InputSize; + + while avail_in > 0 do + begin + {When it needs new buffer to stores the compressed data} + if avail_out = 0 then + begin + {Restore buffer} + next_out := @Buffer; + avail_out := SizeOf(Buffer); + end {if avail_out = 0}; + + {Compresses} + DeflateRet := deflate(StreamRec, Z_FINISH); + + if (DeflateRet = Z_STREAM_END) or (DeflateRet = 0) then + begin + {Updates the output memory} + inc(OutputSize, total_out); + if Output = nil then + GetMem(Output, OutputSize) else ReallocMem(Output, OutputSize); + + {Copies the new data} + CopyMemory(Ptr(Longint(Output) + OutputSize - total_out), + @Buffer, total_out); + end {if (InflateRet = Z_STREAM_END) or (InflateRet = 0)} + {Now tests for errors} + else if DeflateRet < 0 then + begin + Result := False; + ErrorOutput := StreamRec.msg; + DeflateEnd(StreamRec); + Exit; + end {if InflateRet < 0} + + end {while avail_in > 0}; + + {Finishes compressing} + DeflateEnd(StreamRec); + end {with StreamRec} + +end; + +{TPngPointerList implementation} + +{Object being created} +constructor TPngPointerList.Create(AOwner: TPNGObject); +begin + inherited Create; {Let ancestor work} + {Holds owner} + fOwner := AOwner; + {Memory pointer not being used yet} + fMemory := nil; + {No items yet} + fCount := 0; +end; + +{Removes value from the list} +function TPngPointerList.Remove(Value: Pointer): Pointer; +var + I, Position: Integer; +begin + {Gets item position} + Position := -1; + FOR I := 0 TO Count - 1 DO + if Value = Item[I] then Position := I; + {In case a match was found} + if Position >= 0 then + begin + Result := Item[Position]; {Returns pointer} + {Remove item and move memory} + Dec(fCount); + if Position < Integer(FCount) then + System.Move(fMemory^[Position + 1], fMemory^[Position], + (Integer(fCount) - Position) * SizeOf(Pointer)); + end {if Position >= 0} else Result := nil +end; + +{Add a new value in the list} +procedure TPngPointerList.Add(Value: Pointer); +begin + Count := Count + 1; + Item[Count - 1] := Value; +end; + + +{Object being destroyed} +destructor TPngPointerList.Destroy; +begin + {Release memory if needed} + if fMemory <> nil then + FreeMem(fMemory, fCount * sizeof(Pointer)); + + {Free things} + inherited Destroy; +end; + +{Returns one item from the list} +function TPngPointerList.GetItem(Index: Cardinal): Pointer; +begin + if (Index <= Count - 1) then + Result := fMemory[Index] + else + {In case it's out of bounds} + Result := nil; +end; + +{Inserts a new item in the list} +procedure TPngPointerList.Insert(Value: Pointer; Position: Cardinal); +begin + if (Position < Count) or (Count = 0) then + begin + {Increase item count} + SetSize(Count + 1); + {Move other pointers} + if Position < Count then + System.Move(fMemory^[Position], fMemory^[Position + 1], + (Count - Position - 1) * SizeOf(Pointer)); + {Sets item} + Item[Position] := Value; + end; +end; + +{Sets one item from the list} +procedure TPngPointerList.SetItem(Index: Cardinal; const Value: Pointer); +begin + {If index is in bounds, set value} + if (Index <= Count - 1) then + fMemory[Index] := Value +end; + +{This method resizes the list} +procedure TPngPointerList.SetSize(const Size: Cardinal); +begin + {Sets the size} + if (fMemory = nil) and (Size > 0) then + GetMem(fMemory, Size * SIZEOF(Pointer)) + else + if Size > 0 then {Only realloc if the new size is greater than 0} + ReallocMem(fMemory, Size * SIZEOF(Pointer)) + else + {In case user is resize to 0 items} + begin + FreeMem(fMemory); + fMemory := nil; + end; + {Update count} + fCount := Size; +end; + +{TPNGList implementation} + +{Finds the first chunk of this class} +function TPNGList.FindChunk(ChunkClass: TChunkClass): TChunk; +var + i: Integer; +begin + Result := nil; + for i := 0 to Count - 1 do + if Item[i] is ChunkClass then + begin + Result := Item[i]; + Break + end +end; + + +{Removes an item} +procedure TPNGList.RemoveChunk(Chunk: TChunk); +begin + Remove(Chunk); + Chunk.Free +end; + +{Add a new item} +function TPNGList.Add(ChunkClass: TChunkClass): TChunk; +var + IHDR: TChunkIHDR; + IEND: TChunkIEND; + + IDAT: TChunkIDAT; + PLTE: TChunkPLTE; +begin + Result := nil; {Default result} + {Adding these is not allowed} + if ((ChunkClass = TChunkIHDR) or (ChunkClass = TChunkIDAT) or + (ChunkClass = TChunkPLTE) or (ChunkClass = TChunkIEND)) and not + (Owner.BeingCreated) then + fOwner.RaiseError(EPngError, EPNGCannotAddChunkText) + {Two of these is not allowed} + else if ((ChunkClass = TChunkgAMA) and (ItemFromClass(TChunkgAMA) <> nil)) or + ((ChunkClass = TChunktRNS) and (ItemFromClass(TChunktRNS) <> nil)) or + ((ChunkClass = TChunkpHYs) and (ItemFromClass(TChunkpHYs) <> nil)) then + fOwner.RaiseError(EPngError, EPNGCannotAddChunkText) + {There must have an IEND and IHDR chunk} + else if ((ItemFromClass(TChunkIEND) = nil) or + (ItemFromClass(TChunkIHDR) = nil)) and not Owner.BeingCreated then + fOwner.RaiseError(EPngError, EPNGCannotAddInvalidImageText) + else + begin + {Get common chunks} + IHDR := ItemFromClass(TChunkIHDR) as TChunkIHDR; + IEND := ItemFromClass(TChunkIEND) as TChunkIEND; + {Create new chunk} + Result := ChunkClass.Create(Owner); + {Add to the list} + if (ChunkClass = TChunkgAMA) or (ChunkClass = TChunkpHYs) or + (ChunkClass = TChunkPLTE) then + Insert(Result, IHDR.Index + 1) + {Header and end} + else if (ChunkClass = TChunkIEND) then + Insert(Result, Count) + else if (ChunkClass = TChunkIHDR) then + Insert(Result, 0) + {Transparency chunk (fix by Ian Boyd)} + else if (ChunkClass = TChunktRNS) then + begin + {Transparecy chunk must be after PLTE; before IDAT} + IDAT := ItemFromClass(TChunkIDAT) as TChunkIDAT; + PLTE := ItemFromClass(TChunkPLTE) as TChunkPLTE; + + if Assigned(PLTE) then + Insert(Result, PLTE.Index + 1) + else if Assigned(IDAT) then + Insert(Result, IDAT.Index) + else + Insert(Result, IHDR.Index + 1) + end + else {All other chunks} + Insert(Result, IEND.Index); + end {if} +end; + +{Returns item from the list} +function TPNGList.GetItem(Index: Cardinal): TChunk; +begin + Result := inherited GetItem(Index); +end; + +{Returns first item from the list using the class from parameter} +function TPNGList.ItemFromClass(ChunkClass: TChunkClass): TChunk; +var + i: Integer; +begin + Result := nil; {Initial result} + FOR i := 0 TO Count - 1 DO + {Test if this item has the same class} + if Item[i] is ChunkClass then + begin + {Returns this item and exit} + Result := Item[i]; + break; + end {if} +end; + +{$IFNDEF UseDelphi} + + {TStream implementation} + + {Copies all from another stream} + function TStream.CopyFrom(Source: TStream; Count: Cardinal): Cardinal; + const + MaxBytes = $f000; + var + Buffer: PChar; + BufSize, N: Cardinal; + begin + {If count is zero, copy everything from Source} + if Count = 0 then + begin + Source.Seek(0, soFromBeginning); + Count := Source.Size; + end; + + Result := Count; {Returns the number of bytes readed} + {Allocates memory} + if Count > MaxBytes then BufSize := MaxBytes else BufSize := Count; + GetMem(Buffer, BufSize); + + {Copy memory} + while Count > 0 do + begin + if Count > BufSize then N := BufSize else N := Count; + Source.Read(Buffer^, N); + Write(Buffer^, N); + dec(Count, N); + end; + + {Deallocates memory} + FreeMem(Buffer, BufSize); + end; + +{Set current stream position} +procedure TStream.SetPosition(const Value: Longint); +begin + Seek(Value, soFromBeginning); +end; + +{Returns position} +function TStream.GetPosition: Longint; +begin + Result := Seek(0, soFromCurrent); +end; + + {Returns stream size} +function TStream.GetSize: Longint; + var + Pos: Cardinal; + begin + Pos := Seek(0, soFromCurrent); + Result := Seek(0, soFromEnd); + Seek(Pos, soFromBeginning); + end; + + {TFileStream implementation} + + {Filestream object being created} + constructor TFileStream.Create(Filename: String; Mode: TFileStreamModeSet); + {Makes file mode} + function OpenMode: DWORD; + begin + Result := 0; + if fsmRead in Mode then Result := GENERIC_READ; + if (fsmWrite in Mode) or (fsmCreate in Mode) then + Result := Result OR GENERIC_WRITE; + end; + const + IsCreate: Array[Boolean] of Integer = (OPEN_ALWAYS, CREATE_ALWAYS); + begin + {Call ancestor} + inherited Create; + + {Create handle} + fHandle := CreateFile(PChar(Filename), OpenMode, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, IsCreate[fsmCreate in Mode], 0, 0); + {Store mode} + FileMode := Mode; + end; + + {Filestream object being destroyed} + destructor TFileStream.Destroy; + begin + {Terminates file and close} + if FileMode = [fsmWrite] then + SetEndOfFile(fHandle); + CloseHandle(fHandle); + + {Call ancestor} + inherited Destroy; + end; + + {Writes data to the file} + function TFileStream.Write(const Buffer; Count: Longint): Cardinal; + begin + if not WriteFile(fHandle, Buffer, Count, Result, nil) then + Result := 0; + end; + + {Reads data from the file} + function TFileStream.Read(var Buffer; Count: Longint): Cardinal; + begin + if not ReadFile(fHandle, Buffer, Count, Result, nil) then + Result := 0; + end; + + {Seeks the file position} + function TFileStream.Seek(Offset: Integer; Origin: Word): Longint; + begin + Result := SetFilePointer(fHandle, Offset, nil, Origin); + end; + + {Sets the size of the file} + procedure TFileStream.SetSize(const Value: Longint); + begin + Seek(Value, soFromBeginning); + SetEndOfFile(fHandle); + end; + + {TResourceStream implementation} + + {Creates the resource stream} + constructor TResourceStream.Create(Instance: HInst; const ResName: String; + ResType: PChar); + var + ResID: HRSRC; + ResGlobal: HGlobal; + begin + {Obtains the resource ID} + ResID := FindResource(hInstance, PChar(ResName), RT_RCDATA); + if ResID = 0 then raise EPNGError.Create(''); + {Obtains memory and size} + ResGlobal := LoadResource(hInstance, ResID); + Size := SizeOfResource(hInstance, ResID); + Memory := LockResource(ResGlobal); + if (ResGlobal = 0) or (Memory = nil) then EPNGError.Create(''); + end; + + + {Setting resource stream size is not supported} + procedure TResourceStream.SetSize(const Value: Integer); + begin + end; + + {Writing into a resource stream is not supported} + function TResourceStream.Write(const Buffer; Count: Integer): Cardinal; + begin + Result := 0; + end; + + {Reads data from the stream} + function TResourceStream.Read(var Buffer; Count: Integer): Cardinal; + begin + //Returns data + CopyMemory(@Buffer, Ptr(Longint(Memory) + Position), Count); + //Update position + inc(Position, Count); + //Returns + Result := Count; + end; + + {Seeks data} + function TResourceStream.Seek(Offset: Integer; Origin: Word): Longint; + begin + {Move depending on the origin} + case Origin of + soFromBeginning: Position := Offset; + soFromCurrent: inc(Position, Offset); + soFromEnd: Position := Size + Offset; + end; + + {Returns the current position} + Result := Position; + end; + +{$ENDIF} + +{TChunk implementation} + +{Resizes the data} +procedure TChunk.ResizeData(const NewSize: Cardinal); +begin + fDataSize := NewSize; + ReallocMem(fData, NewSize + 1); +end; + +{Returns index from list} +function TChunk.GetIndex: Integer; +var + i: Integer; +begin + Result := -1; {Avoiding warnings} + {Searches in the list} + FOR i := 0 TO Owner.Chunks.Count - 1 DO + if Owner.Chunks.Item[i] = Self then + begin + {Found match} + Result := i; + exit; + end {for i} +end; + +{Returns pointer to the TChunkIHDR} +function TChunk.GetHeader: TChunkIHDR; +begin + Result := Owner.Chunks.Item[0] as TChunkIHDR; +end; + +{Assigns from another TChunk} +procedure TChunk.Assign(Source: TChunk); +begin + {Copy properties} + fName := Source.fName; + {Set data size and realloc} + ResizeData(Source.fDataSize); + + {Copy data (if there's any)} + if fDataSize > 0 then CopyMemory(fData, Source.fData, fDataSize); +end; + +{Chunk being created} +constructor TChunk.Create(Owner: TPngObject); +var + ChunkName: String; +begin + {Ancestor create} + inherited Create; + + {If it's a registered class, set the chunk name based on the class} + {name. For instance, if the class name is TChunkgAMA, the GAMA part} + {will become the chunk name} + ChunkName := Copy(ClassName, Length('TChunk') + 1, Length(ClassName)); + if Length(ChunkName) = 4 then CopyMemory(@fName[0], @ChunkName[1], 4); + + {Initialize data holder} + GetMem(fData, 1); + fDataSize := 0; + {Record owner} + fOwner := Owner; +end; + +{Chunk being destroyed} +destructor TChunk.Destroy; +begin + {Free data holder} + FreeMem(fData, fDataSize + 1); + {Let ancestor destroy} + inherited Destroy; +end; + +{Returns the chunk name 1} +function TChunk.GetChunkName: String; +begin + Result := fName +end; + +{Returns the chunk name 2} +class function TChunk.GetName: String; +begin + {For avoid writing GetName for each TChunk descendent, by default for} + {classes which don't declare GetName, it will look for the class name} + {to extract the chunk kind. Example, if the class name is TChunkIEND } + {this method extracts and returns IEND} + Result := Copy(ClassName, Length('TChunk') + 1, Length(ClassName)); +end; + +{Saves the data to the stream} +function TChunk.SaveData(Stream: TStream): Boolean; +var + ChunkSize, ChunkCRC: Cardinal; +begin + {First, write the size for the following data in the chunk} + ChunkSize := ByteSwap(DataSize); + Stream.Write(ChunkSize, 4); + {The chunk name} + Stream.Write(fName, 4); + {If there is data for the chunk, write it} + if DataSize > 0 then Stream.Write(Data^, DataSize); + {Calculates and write CRC} + ChunkCRC := update_crc($ffffffff, @fName[0], 4); + ChunkCRC := Byteswap(update_crc(ChunkCRC, Data, DataSize) xor $ffffffff); + Stream.Write(ChunkCRC, 4); + + {Returns that everything went ok} + Result := TRUE; +end; + +{Saves the chunk to the stream} +function TChunk.SaveToStream(Stream: TStream): Boolean; +begin + Result := SaveData(Stream) +end; + + +{Loads the chunk from a stream} +function TChunk.LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; +var + CheckCRC: Cardinal; + {$IFDEF CheckCRC}RightCRC: Cardinal;{$ENDIF} +begin + {Copies data from source} + ResizeData(Size); + if Size > 0 then Stream.Read(fData^, Size); + {Reads CRC} + Stream.Read(CheckCRC, 4); + CheckCrc := ByteSwap(CheckCRC); + + {Check if crc readed is valid} + {$IFDEF CheckCRC} + RightCRC := update_crc($ffffffff, @ChunkName[0], 4); + RightCRC := update_crc(RightCRC, fData, Size) xor $ffffffff; + Result := RightCRC = CheckCrc; + + {Handle CRC error} + if not Result then + begin + {In case it coult not load chunk} + Owner.RaiseError(EPngInvalidCRC, EPngInvalidCRCText); + exit; + end + {$ELSE}Result := TRUE; {$ENDIF} + +end; + +{TChunktIME implementation} + +{Chunk being loaded from a stream} +function TChunktIME.LoadFromStream(Stream: TStream; + const ChunkName: TChunkName; Size: Integer): Boolean; +begin + {Let ancestor load the data} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + if not Result or (Size <> 7) then exit; {Size must be 7} + + {Reads data} + fYear := ((pByte(Longint(Data) )^) * 256)+ (pByte(Longint(Data) + 1)^); + fMonth := pByte(Longint(Data) + 2)^; + fDay := pByte(Longint(Data) + 3)^; + fHour := pByte(Longint(Data) + 4)^; + fMinute := pByte(Longint(Data) + 5)^; + fSecond := pByte(Longint(Data) + 6)^; +end; + +{Assigns from another TChunk} +procedure TChunktIME.Assign(Source: TChunk); +begin + fYear := TChunktIME(Source).fYear; + fMonth := TChunktIME(Source).fMonth; + fDay := TChunktIME(Source).fDay; + fHour := TChunktIME(Source).fHour; + fMinute := TChunktIME(Source).fMinute; + fSecond := TChunktIME(Source).fSecond; +end; + +{Saving the chunk to a stream} +function TChunktIME.SaveToStream(Stream: TStream): Boolean; +begin + {Update data} + ResizeData(7); {Make sure the size is 7} + pWord(Data)^ := ByteSwap16(Year); + pByte(Longint(Data) + 2)^ := Month; + pByte(Longint(Data) + 3)^ := Day; + pByte(Longint(Data) + 4)^ := Hour; + pByte(Longint(Data) + 5)^ := Minute; + pByte(Longint(Data) + 6)^ := Second; + + {Let inherited save data} + Result := inherited SaveToStream(Stream); +end; + +{TChunkztXt implementation} + +{Loading the chunk from a stream} +function TChunkzTXt.LoadFromStream(Stream: TStream; + const ChunkName: TChunkName; Size: Integer): Boolean; +var + ErrorOutput: String; + CompressionMethod: Byte; + Output: Pointer; + OutputSize: Integer; +begin + {Load data from stream and validate} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + if not Result or (Size < 4) then exit; + fKeyword := PChar(Data); {Get keyword and compression method bellow} + if Longint(fKeyword) = 0 then + CompressionMethod := pByte(Data)^ + else + CompressionMethod := pByte(Longint(fKeyword) + Length(fKeyword))^; + fText := ''; + + {In case the compression is 0 (only one accepted by specs), reads it} + if CompressionMethod = 0 then + begin + Output := nil; + if DecompressZLIB(PChar(Longint(Data) + Length(fKeyword) + 2), + Size - Length(fKeyword) - 2, Output, OutputSize, ErrorOutput) then + begin + SetLength(fText, OutputSize); + CopyMemory(@fText[1], Output, OutputSize); + end {if DecompressZLIB(...}; + FreeMem(Output); + end {if CompressionMethod = 0} + +end; + +{Saving the chunk to a stream} +function TChunkztXt.SaveToStream(Stream: TStream): Boolean; +var + Output: Pointer; + OutputSize: Integer; + ErrorOutput: String; +begin + Output := nil; {Initializes output} + if fText = '' then fText := ' '; + + {Compresses the data} + if CompressZLIB(@fText[1], Length(fText), Owner.CompressionLevel, Output, + OutputSize, ErrorOutput) then + begin + {Size is length from keyword, plus a null character to divide} + {plus the compression method, plus the length of the text (zlib compressed)} + ResizeData(Length(fKeyword) + 2 + OutputSize); + + Fillchar(Data^, DataSize, #0); + {Copies the keyword data} + if Keyword <> '' then + CopyMemory(Data, @fKeyword[1], Length(Keyword)); + {Compression method 0 (inflate/deflate)} + pByte(Ptr(Longint(Data) + Length(Keyword) + 1))^ := 0; + if OutputSize > 0 then + CopyMemory(Ptr(Longint(Data) + Length(Keyword) + 2), Output, OutputSize); + + {Let ancestor calculate crc and save} + Result := SaveData(Stream); + end {if CompressZLIB(...} else Result := False; + + {Frees output} + if Output <> nil then FreeMem(Output) +end; + +{TChunktEXt implementation} + +{Assigns from another text chunk} +procedure TChunktEXt.Assign(Source: TChunk); +begin + fKeyword := TChunktEXt(Source).fKeyword; + fText := TChunktEXt(Source).fText; +end; + +{Loading the chunk from a stream} +function TChunktEXt.LoadFromStream(Stream: TStream; + const ChunkName: TChunkName; Size: Integer): Boolean; +begin + {Load data from stream and validate} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + if not Result or (Size < 3) then exit; + {Get text} + fKeyword := PChar(Data); + SetLength(fText, Size - Length(fKeyword) - 1); + CopyMemory(@fText[1], Ptr(Longint(Data) + Length(fKeyword) + 1), + Length(fText)); +end; + +{Saving the chunk to a stream} +function TChunktEXt.SaveToStream(Stream: TStream): Boolean; +begin + {Size is length from keyword, plus a null character to divide} + {plus the length of the text} + ResizeData(Length(fKeyword) + 1 + Length(fText)); + Fillchar(Data^, DataSize, #0); + {Copy data} + if Keyword <> '' then + CopyMemory(Data, @fKeyword[1], Length(Keyword)); + if Text <> '' then + CopyMemory(Ptr(Longint(Data) + Length(Keyword) + 1), @fText[1], + Length(Text)); + {Let ancestor calculate crc and save} + Result := inherited SaveToStream(Stream); +end; + + +{TChunkIHDR implementation} + +{Chunk being created} +constructor TChunkIHDR.Create(Owner: TPngObject); +begin + {Prepare pointers} + ImageHandle := 0; + ImagePalette := 0; + ImageDC := 0; + + {Call inherited} + inherited Create(Owner); +end; + +{Chunk being destroyed} +destructor TChunkIHDR.Destroy; +begin + {Free memory} + FreeImageData(); + + {Calls TChunk destroy} + inherited Destroy; +end; + +{Copies the palette} +procedure CopyPalette(Source: HPALETTE; Destination: HPALETTE); +var + PaletteSize: Integer; + Entries: Array[Byte] of TPaletteEntry; +begin + PaletteSize := 0; + if GetObject(Source, SizeOf(PaletteSize), @PaletteSize) = 0 then Exit; + if PaletteSize = 0 then Exit; + ResizePalette(Destination, PaletteSize); + GetPaletteEntries(Source, 0, PaletteSize, Entries); + SetPaletteEntries(Destination, 0, PaletteSize, Entries); +end; + +{Assigns from another IHDR chunk} +procedure TChunkIHDR.Assign(Source: TChunk); +begin + {Copy the IHDR data} + if Source is TChunkIHDR then + begin + {Copy IHDR values} + IHDRData := TChunkIHDR(Source).IHDRData; + + {Prepare to hold data by filling BitmapInfo structure and} + {resizing ImageData and ImageAlpha memory allocations} + PrepareImageData(); + + {Copy image data} + CopyMemory(ImageData, TChunkIHDR(Source).ImageData, + BytesPerRow * Integer(Height)); + CopyMemory(ImageAlpha, TChunkIHDR(Source).ImageAlpha, + Integer(Width) * Integer(Height)); + + {Copy palette colors} + BitmapInfo.bmiColors := TChunkIHDR(Source).BitmapInfo.bmiColors; + {Copy palette also} + CopyPalette(TChunkIHDR(Source).ImagePalette, ImagePalette); + end + else + Owner.RaiseError(EPNGError, EPNGCannotAssignChunkText); +end; + +{Release allocated image data} +procedure TChunkIHDR.FreeImageData; +begin + {Free old image data} + if ImageHandle <> 0 then DeleteObject(ImageHandle); + if ImageDC <> 0 then DeleteDC(ImageDC); + if ImageAlpha <> nil then FreeMem(ImageAlpha); + if ImagePalette <> 0 then DeleteObject(ImagePalette); + {$IFDEF Store16bits} + if ExtraImageData <> nil then FreeMem(ExtraImageData); + {$ENDIF} + ImageHandle := 0; ImageDC := 0; ImageAlpha := nil; ImageData := nil; + ImagePalette := 0; ExtraImageData := nil; +end; + +{Chunk being loaded from a stream} +function TChunkIHDR.LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; +begin + {Let TChunk load it} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + if not Result then Exit; + + {Now check values} + {Note: It's recommended by png specification to make sure that the size} + {must be 13 bytes to be valid, but some images with 14 bytes were found} + {which could be loaded by internet explorer and other tools} + if (fDataSize < SIZEOF(TIHdrData)) then + begin + {Ihdr must always have at least 13 bytes} + Result := False; + Owner.RaiseError(EPNGInvalidIHDR, EPNGInvalidIHDRText); + exit; + end; + + {Everything ok, reads IHDR} + IHDRData := pIHDRData(fData)^; + IHDRData.Width := ByteSwap(IHDRData.Width); + IHDRData.Height := ByteSwap(IHDRData.Height); + + {The width and height must not be larger than 65535 pixels} + if (IHDRData.Width > High(Word)) or (IHDRData.Height > High(Word)) then + begin + Result := False; + Owner.RaiseError(EPNGSizeExceeds, EPNGSizeExceedsText); + exit; + end {if IHDRData.Width > High(Word)}; + {Compression method must be 0 (inflate/deflate)} + if (IHDRData.CompressionMethod <> 0) then + begin + Result := False; + Owner.RaiseError(EPNGUnknownCompression, EPNGUnknownCompressionText); + exit; + end; + {Interlace must be either 0 (none) or 7 (adam7)} + if (IHDRData.InterlaceMethod <> 0) and (IHDRData.InterlaceMethod <> 1) then + begin + Result := False; + Owner.RaiseError(EPNGUnknownInterlace, EPNGUnknownInterlaceText); + exit; + end; + + {Updates owner properties} + Owner.InterlaceMethod := TInterlaceMethod(IHDRData.InterlaceMethod); + + {Prepares data to hold image} + PrepareImageData(); +end; + +{Saving the IHDR chunk to a stream} +function TChunkIHDR.SaveToStream(Stream: TStream): Boolean; +begin + {Ignore 2 bits images} + if BitDepth = 2 then BitDepth := 4; + + {It needs to do is update the data with the IHDR data} + {structure containing the write values} + ResizeData(SizeOf(TIHDRData)); + pIHDRData(fData)^ := IHDRData; + {..byteswap 4 byte types} + pIHDRData(fData)^.Width := ByteSwap(pIHDRData(fData)^.Width); + pIHDRData(fData)^.Height := ByteSwap(pIHDRData(fData)^.Height); + {..update interlace method} + pIHDRData(fData)^.InterlaceMethod := Byte(Owner.InterlaceMethod); + {..and then let the ancestor SaveToStream do the hard work} + Result := inherited SaveToStream(Stream); +end; + +{Creates a grayscale palette} +function TChunkIHDR.CreateGrayscalePalette(Bitdepth: Integer): HPalette; +var + j: Integer; + palEntries: TMaxLogPalette; +begin + {Prepares and fills the strucutre} + if Bitdepth = 16 then Bitdepth := 8; + fillchar(palEntries, sizeof(palEntries), 0); + palEntries.palVersion := $300; + palEntries.palNumEntries := 1 shl Bitdepth; + {Fill it with grayscale colors} + for j := 0 to palEntries.palNumEntries - 1 do + begin + palEntries.palPalEntry[j].peRed := + fOwner.GammaTable[MulDiv(j, 255, palEntries.palNumEntries - 1)]; + palEntries.palPalEntry[j].peGreen := palEntries.palPalEntry[j].peRed; + palEntries.palPalEntry[j].peBlue := palEntries.palPalEntry[j].peRed; + end; + {Creates and returns the palette} + Result := CreatePalette(pLogPalette(@palEntries)^); +end; + +{Copies the palette to the Device Independent bitmap header} +procedure TChunkIHDR.PaletteToDIB(Palette: HPalette); +var + j: Integer; + palEntries: TMaxLogPalette; +begin + {Copy colors} + Fillchar(palEntries, sizeof(palEntries), #0); + BitmapInfo.bmiHeader.biClrUsed := GetPaletteEntries(Palette, 0, 256, palEntries.palPalEntry[0]); + for j := 0 to BitmapInfo.bmiHeader.biClrUsed - 1 do + begin + BitmapInfo.bmiColors[j].rgbBlue := palEntries.palPalEntry[j].peBlue; + BitmapInfo.bmiColors[j].rgbRed := palEntries.palPalEntry[j].peRed; + BitmapInfo.bmiColors[j].rgbGreen := palEntries.palPalEntry[j].peGreen; + end; +end; + +{Resizes the image data to fill the color type, bit depth, } +{width and height parameters} +procedure TChunkIHDR.PrepareImageData(); + {Set the bitmap info} + procedure SetInfo(const Bitdepth: Integer; const Palette: Boolean); + begin + + {Copy if the bitmap contain palette entries} + HasPalette := Palette; + {Fill the strucutre} + with BitmapInfo.bmiHeader do + begin + biSize := sizeof(TBitmapInfoHeader); + biHeight := Height; + biWidth := Width; + biPlanes := 1; + biBitCount := BitDepth; + biCompression := BI_RGB; + end {with BitmapInfo.bmiHeader} + end; +begin + {Prepare bitmap info header} + Fillchar(BitmapInfo, sizeof(TMaxBitmapInfo), #0); + {Release old image data} + FreeImageData(); + + {Obtain number of bits for each pixel} + case ColorType of + COLOR_GRAYSCALE, COLOR_PALETTE, COLOR_GRAYSCALEALPHA: + case BitDepth of + {These are supported by windows} + 1, 4, 8: SetInfo(BitDepth, TRUE); + {2 bits for each pixel is not supported by windows bitmap} + 2 : SetInfo(4, TRUE); + {Also 16 bits (2 bytes) for each pixel is not supported} + {and should be transormed into a 8 bit grayscale} + 16 : SetInfo(8, TRUE); + end; + {Only 1 byte (8 bits) is supported} + COLOR_RGB, COLOR_RGBALPHA: SetInfo(24, FALSE); + end {case ColorType}; + {Number of bytes for each scanline} + BytesPerRow := (((BitmapInfo.bmiHeader.biBitCount * Width) + 31) + and not 31) div 8; + + {Build array for alpha information, if necessary} + if (ColorType = COLOR_RGBALPHA) or (ColorType = COLOR_GRAYSCALEALPHA) then + begin + GetMem(ImageAlpha, Integer(Width) * Integer(Height)); + FillChar(ImageAlpha^, Integer(Width) * Integer(Height), #0); + end; + + {Build array for extra byte information} + {$IFDEF Store16bits} + if (BitDepth = 16) then + begin + GetMem(ExtraImageData, BytesPerRow * Integer(Height)); + FillChar(ExtraImageData^, BytesPerRow * Integer(Height), #0); + end; + {$ENDIF} + + {Creates the image to hold the data, CreateDIBSection does a better} + {work in allocating necessary memory} + ImageDC := CreateCompatibleDC(0); + {$IFDEF UseDelphi}Self.Owner.Canvas.Handle := ImageDC;{$ENDIF} + + {In case it is a palette image, create the palette} + if HasPalette then + begin + {Create a standard palette} + if ColorType = COLOR_PALETTE then + ImagePalette := CreateHalfTonePalette(ImageDC) + else + ImagePalette := CreateGrayscalePalette(Bitdepth); + ResizePalette(ImagePalette, 1 shl BitmapInfo.bmiHeader.biBitCount); + BitmapInfo.bmiHeader.biClrUsed := 1 shl BitmapInfo.bmiHeader.biBitCount; + SelectPalette(ImageDC, ImagePalette, False); + RealizePalette(ImageDC); + PaletteTODIB(ImagePalette); + end; + + {Create the device independent bitmap} + ImageHandle := CreateDIBSection(ImageDC, pBitmapInfo(@BitmapInfo)^, + DIB_RGB_COLORS, ImageData, 0, 0); + SelectObject(ImageDC, ImageHandle); + + {Build array and allocate bytes for each row} + fillchar(ImageData^, BytesPerRow * Integer(Height), 0); +end; + +{TChunktRNS implementation} + +{$IFNDEF UseDelphi} +function CompareMem(P1, P2: pByte; const Size: Integer): Boolean; +var i: Integer; +begin + Result := True; + for i := 1 to Size do + begin + if P1^ <> P2^ then Result := False; + inc(P1); inc(P2); + end {for i} +end; +{$ENDIF} + +{Sets the transpararent color} +procedure TChunktRNS.SetTransparentColor(const Value: ColorRef); +var + i: Byte; + LookColor: TRGBQuad; +begin + {Clears the palette values} + Fillchar(PaletteValues, SizeOf(PaletteValues), #0); + {Sets that it uses bit transparency} + fBitTransparency := True; + + + {Depends on the color type} + with Header do + case ColorType of + COLOR_GRAYSCALE: + begin + Self.ResizeData(2); + pWord(@PaletteValues[0])^ := ByteSwap16(GetRValue(Value)); + end; + COLOR_RGB: + begin + Self.ResizeData(6); + pWord(@PaletteValues[0])^ := ByteSwap16(GetRValue(Value)); + pWord(@PaletteValues[2])^ := ByteSwap16(GetGValue(Value)); + pWord(@PaletteValues[4])^ := ByteSwap16(GetBValue(Value)); + end; + COLOR_PALETTE: + begin + {Creates a RGBQuad to search for the color} + LookColor.rgbRed := GetRValue(Value); + LookColor.rgbGreen := GetGValue(Value); + LookColor.rgbBlue := GetBValue(Value); + {Look in the table for the entry} + for i := 0 to BitmapInfo.bmiHeader.biClrUsed - 1 do + if CompareMem(@BitmapInfo.bmiColors[i], @LookColor, 3) then + Break; + {Fill the transparency table} + Fillchar(PaletteValues, i, 255); + Self.ResizeData(i + 1) + + end + end {case / with}; + +end; + +{Returns the transparent color for the image} +function TChunktRNS.GetTransparentColor: ColorRef; +var + PaletteChunk: TChunkPLTE; + i: Integer; + Value: Byte; +begin + Result := 0; {Default: Unknown transparent color} + + {Depends on the color type} + with Header do + case ColorType of + COLOR_GRAYSCALE: + begin + Value := BitmapInfo.bmiColors[PaletteValues[1]].rgbRed; + Result := RGB(Value, Value, Value); + end; + COLOR_RGB: + Result := RGB(fOwner.GammaTable[PaletteValues[1]], + fOwner.GammaTable[PaletteValues[3]], + fOwner.GammaTable[PaletteValues[5]]); + COLOR_PALETTE: + begin + {Obtains the palette chunk} + PaletteChunk := Owner.Chunks.ItemFromClass(TChunkPLTE) as TChunkPLTE; + + {Looks for an entry with 0 transparency meaning that it is the} + {full transparent entry} + for i := 0 to Self.DataSize - 1 do + if PaletteValues[i] = 0 then + with PaletteChunk.GetPaletteItem(i) do + begin + Result := RGB(rgbRed, rgbGreen, rgbBlue); + break + end + end {COLOR_PALETTE} + end {case Header.ColorType}; +end; + +{Saving the chunk to a stream} +function TChunktRNS.SaveToStream(Stream: TStream): Boolean; +begin + {Copy palette into data buffer} + if DataSize <= 256 then + CopyMemory(fData, @PaletteValues[0], DataSize); + + Result := inherited SaveToStream(Stream); +end; + +{Assigns from another chunk} +procedure TChunktRNS.Assign(Source: TChunk); +begin + CopyMemory(@PaletteValues[0], @TChunkTrns(Source).PaletteValues[0], 256); + fBitTransparency := TChunkTrns(Source).fBitTransparency; + inherited Assign(Source); +end; + +{Loads the chunk from a stream} +function TChunktRNS.LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; +var + i, Differ255: Integer; +begin + {Let inherited load} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + + if not Result then Exit; + + {Make sure size is correct} + if Size > 256 then Owner.RaiseError(EPNGInvalidPalette, + EPNGInvalidPaletteText); + + {The unset items should have value 255} + Fillchar(PaletteValues[0], 256, 255); + {Copy the other values} + CopyMemory(@PaletteValues[0], fData, Size); + + {Create the mask if needed} + case Header.ColorType of + {Mask for grayscale and RGB} + COLOR_RGB, COLOR_GRAYSCALE: fBitTransparency := True; + COLOR_PALETTE: + begin + Differ255 := 0; {Count the entries with a value different from 255} + {Tests if it uses bit transparency} + for i := 0 to Size - 1 do + if PaletteValues[i] <> 255 then inc(Differ255); + + {If it has one value different from 255 it is a bit transparency} + fBitTransparency := (Differ255 = 1); + end {COLOR_PALETTE} + end {case Header.ColorType}; + +end; + +{Prepares the image palette} +procedure TChunkIDAT.PreparePalette; +var + Entries: Word; + j : Integer; + palEntries: TMaxLogPalette; +begin + {In case the image uses grayscale, build a grayscale palette} + with Header do + if (ColorType = COLOR_GRAYSCALE) or (ColorType = COLOR_GRAYSCALEALPHA) then + begin + {Calculate total number of palette entries} + Entries := (1 shl Byte(BitmapInfo.bmiHeader.biBitCount)); + Fillchar(palEntries, sizeof(palEntries), #0); + palEntries.palVersion := $300; + palEntries.palNumEntries := Entries; + + FOR j := 0 TO Entries - 1 DO + with palEntries.palPalEntry[j] do + begin + + {Calculate each palette entry} + peRed := fOwner.GammaTable[MulDiv(j, 255, Entries - 1)]; + peGreen := peRed; + peBlue := peRed; + end {with BitmapInfo.bmiColors[j]}; + Owner.SetPalette(CreatePalette(pLogPalette(@palEntries)^)); + end {if ColorType = COLOR_GRAYSCALE..., with Header} +end; + +{Reads from ZLIB} +function TChunkIDAT.IDATZlibRead(var ZLIBStream: TZStreamRec2; + Buffer: Pointer; Count: Integer; var EndPos: Integer; + var crcfile: Cardinal): Integer; +var + ProcResult : Integer; + IDATHeader : Array[0..3] of char; + IDATCRC : Cardinal; +begin + {Uses internal record pointed by ZLIBStream to gather information} + with ZLIBStream, ZLIBStream.zlib do + begin + {Set the buffer the zlib will read into} + next_out := Buffer; + avail_out := Count; + + {Decode until it reach the Count variable} + while avail_out > 0 do + begin + {In case it needs more data and it's in the end of a IDAT chunk,} + {it means that there are more IDAT chunks} + if (fStream.Position = EndPos) and (avail_out > 0) and + (avail_in = 0) then + begin + {End this chunk by reading and testing the crc value} + fStream.Read(IDATCRC, 4); + + {$IFDEF CheckCRC} + if crcfile xor $ffffffff <> Cardinal(ByteSwap(IDATCRC)) then + begin + Result := -1; + Owner.RaiseError(EPNGInvalidCRC, EPNGInvalidCRCText); + exit; + end; + {$ENDIF} + + {Start reading the next chunk} + fStream.Read(EndPos, 4); {Reads next chunk size} + fStream.Read(IDATHeader[0], 4); {Next chunk header} + {It must be a IDAT chunk since image data is required and PNG} + {specification says that multiple IDAT chunks must be consecutive} + if IDATHeader <> 'IDAT' then + begin + Owner.RaiseError(EPNGMissingMultipleIDAT, EPNGMissingMultipleIDATText); + result := -1; + exit; + end; + + {Calculate chunk name part of the crc} + {$IFDEF CheckCRC} + crcfile := update_crc($ffffffff, @IDATHeader[0], 4); + {$ENDIF} + EndPos := fStream.Position + ByteSwap(EndPos); + end; + + + {In case it needs compressed data to read from} + if avail_in = 0 then + begin + {In case it's trying to read more than it is avaliable} + if fStream.Position + ZLIBAllocate > EndPos then + avail_in := fStream.Read(Data^, EndPos - fStream.Position) + else + avail_in := fStream.Read(Data^, ZLIBAllocate); + {Update crc} + {$IFDEF CheckCRC} + crcfile := update_crc(crcfile, Data, avail_in); + {$ENDIF} + + {In case there is no more compressed data to read from} + if avail_in = 0 then + begin + Result := Count - avail_out; + Exit; + end; + + {Set next buffer to read and record current position} + next_in := Data; + + end {if avail_in = 0}; + + ProcResult := inflate(zlib, 0); + + {In case the result was not sucessfull} + if (ProcResult < 0) then + begin + Result := -1; + Owner.RaiseError(EPNGZLIBError, + EPNGZLIBErrorText + zliberrors[procresult]); + exit; + end; + + end {while avail_out > 0}; + + end {with}; + + {If everything gone ok, it returns the count bytes} + Result := Count; +end; + +{TChunkIDAT implementation} + +const + {Adam 7 interlacing values} + RowStart: array[0..6] of Integer = (0, 0, 4, 0, 2, 0, 1); + ColumnStart: array[0..6] of Integer = (0, 4, 0, 2, 0, 1, 0); + RowIncrement: array[0..6] of Integer = (8, 8, 8, 4, 4, 2, 2); + ColumnIncrement: array[0..6] of Integer = (8, 8, 4, 4, 2, 2, 1); + +{Copy interlaced images with 1 byte for R, G, B} +procedure TChunkIDAT.CopyInterlacedRGB8(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Dest := pChar(Longint(Dest) + Col * 3); + repeat + {Copy this row} + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + + {Move to next column} + inc(Src, 3); + inc(Dest, ColumnIncrement[Pass] * 3 - 3); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy interlaced images with 2 bytes for R, G, B} +procedure TChunkIDAT.CopyInterlacedRGB16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Dest := pChar(Longint(Dest) + Col * 3); + repeat + {Copy this row} + Byte(Dest^) := Owner.GammaTable[pByte(Longint(Src) + 4)^]; inc(Dest); + Byte(Dest^) := Owner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := Owner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + {$IFDEF Store16bits} + {Copy extra pixel values} + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 5)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 3)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Extra); + {$ENDIF} + + {Move to next column} + inc(Src, 6); + inc(Dest, ColumnIncrement[Pass] * 3 - 3); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy ímages with palette using bit depths 1, 4 or 8} +procedure TChunkIDAT.CopyInterlacedPalette148(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +const + BitTable: Array[1..8] of Integer = ($1, $3, 0, $F, 0, 0, 0, $FF); + StartBit: Array[1..8] of Integer = (7 , 0 , 0, 4, 0, 0, 0, 0); +var + CurBit, Col: Integer; + Dest2: PChar; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + repeat + {Copy data} + CurBit := StartBit[Header.BitDepth]; + repeat + {Adjust pointer to pixel byte bounds} + Dest2 := pChar(Longint(Dest) + (Header.BitDepth * Col) div 8); + {Copy data} + Byte(Dest2^) := Byte(Dest2^) or + ( ((Byte(Src^) shr CurBit) and BitTable[Header.BitDepth]) + shl (StartBit[Header.BitDepth] - (Col * Header.BitDepth mod 8))); + + {Move to next column} + inc(Col, ColumnIncrement[Pass]); + {Will read next bits} + dec(CurBit, Header.BitDepth); + until CurBit < 0; + + {Move to next byte in source} + inc(Src); + until Col >= ImageWidth; +end; + +{Copy ímages with palette using bit depth 2} +procedure TChunkIDAT.CopyInterlacedPalette2(const Pass: Byte; Src, Dest, + Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + CurBit, Col: Integer; + Dest2: PChar; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + repeat + {Copy data} + CurBit := 6; + repeat + {Adjust pointer to pixel byte bounds} + Dest2 := pChar(Longint(Dest) + Col div 2); + {Copy data} + Byte(Dest2^) := Byte(Dest2^) or (((Byte(Src^) shr CurBit) and $3) + shl (4 - (4 * Col) mod 8)); + {Move to next column} + inc(Col, ColumnIncrement[Pass]); + {Will read next bits} + dec(CurBit, 2); + until CurBit < 0; + + {Move to next byte in source} + inc(Src); + until Col >= ImageWidth; +end; + +{Copy ímages with grayscale using bit depth 2} +procedure TChunkIDAT.CopyInterlacedGray2(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + CurBit, Col: Integer; + Dest2: PChar; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + repeat + {Copy data} + CurBit := 6; + repeat + {Adjust pointer to pixel byte bounds} + Dest2 := pChar(Longint(Dest) + Col div 2); + {Copy data} + Byte(Dest2^) := Byte(Dest2^) or ((((Byte(Src^) shr CurBit) shl 2) and $F) + shl (4 - (Col*4) mod 8)); + {Move to next column} + inc(Col, ColumnIncrement[Pass]); + {Will read next bits} + dec(CurBit, 2); + until CurBit < 0; + + {Move to next byte in source} + inc(Src); + until Col >= ImageWidth; +end; + +{Copy ímages with palette using 2 bytes for each pixel} +procedure TChunkIDAT.CopyInterlacedGrayscale16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Dest := pChar(Longint(Dest) + Col); + repeat + {Copy this row} + Dest^ := Src^; inc(Dest); + {$IFDEF Store16bits} + Extra^ := pChar(Longint(Src) + 1)^; inc(Extra); + {$ENDIF} + + {Move to next column} + inc(Src, 2); + inc(Dest, ColumnIncrement[Pass] - 1); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Decodes interlaced RGB alpha with 1 byte for each sample} +procedure TChunkIDAT.CopyInterlacedRGBAlpha8(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Dest := pChar(Longint(Dest) + Col * 3); + Trans := pChar(Longint(Trans) + Col); + repeat + {Copy this row and alpha value} + Trans^ := pChar(Longint(Src) + 3)^; + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + + {Move to next column} + inc(Src, 4); + inc(Dest, ColumnIncrement[Pass] * 3 - 3); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Decodes interlaced RGB alpha with 2 bytes for each sample} +procedure TChunkIDAT.CopyInterlacedRGBAlpha16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Dest := pChar(Longint(Dest) + Col * 3); + Trans := pChar(Longint(Trans) + Col); + repeat + {Copy this row and alpha value} + Trans^ := pChar(Longint(Src) + 6)^; + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 4)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + {$IFDEF Store16bits} + {Copy extra pixel values} + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 5)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 3)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Extra); + {$ENDIF} + + {Move to next column} + inc(Src, 8); + inc(Dest, ColumnIncrement[Pass] * 3 - 3); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Decodes 8 bit grayscale image followed by an alpha sample} +procedure TChunkIDAT.CopyInterlacedGrayscaleAlpha8(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + Col: Integer; +begin + {Get first column, pointers to the data and enter in loop} + Col := ColumnStart[Pass]; + Dest := pChar(Longint(Dest) + Col); + Trans := pChar(Longint(Trans) + Col); + repeat + {Copy this grayscale value and alpha} + Dest^ := Src^; inc(Src); + Trans^ := Src^; inc(Src); + + {Move to next column} + inc(Dest, ColumnIncrement[Pass]); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Decodes 16 bit grayscale image followed by an alpha sample} +procedure TChunkIDAT.CopyInterlacedGrayscaleAlpha16(const Pass: Byte; + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + Col: Integer; +begin + {Get first column, pointers to the data and enter in loop} + Col := ColumnStart[Pass]; + Dest := pChar(Longint(Dest) + Col); + Trans := pChar(Longint(Trans) + Col); + repeat + {$IFDEF Store16bits} + Extra^ := pChar(Longint(Src) + 1)^; inc(Extra); + {$ENDIF} + {Copy this grayscale value and alpha, transforming 16 bits into 8} + Dest^ := Src^; inc(Src, 2); + Trans^ := Src^; inc(Src, 2); + + {Move to next column} + inc(Dest, ColumnIncrement[Pass]); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Decodes an interlaced image} +procedure TChunkIDAT.DecodeInterlacedAdam7(Stream: TStream; + var ZLIBStream: TZStreamRec2; const Size: Integer; var crcfile: Cardinal); +var + CurrentPass: Byte; + PixelsThisRow: Integer; + CurrentRow: Integer; + Trans, Data{$IFDEF Store16bits}, Extra{$ENDIF}: pChar; + CopyProc: procedure(const Pass: Byte; Src, Dest, + Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar) of object; +begin + + CopyProc := nil; {Initialize} + {Determine method to copy the image data} + case Header.ColorType of + {R, G, B values for each pixel} + COLOR_RGB: + case Header.BitDepth of + 8: CopyProc := CopyInterlacedRGB8; + 16: CopyProc := CopyInterlacedRGB16; + end {case Header.BitDepth}; + {Palette} + COLOR_PALETTE, COLOR_GRAYSCALE: + case Header.BitDepth of + 1, 4, 8: CopyProc := CopyInterlacedPalette148; + 2 : if Header.ColorType = COLOR_PALETTE then + CopyProc := CopyInterlacedPalette2 + else + CopyProc := CopyInterlacedGray2; + 16 : CopyProc := CopyInterlacedGrayscale16; + end; + {RGB followed by alpha} + COLOR_RGBALPHA: + case Header.BitDepth of + 8: CopyProc := CopyInterlacedRGBAlpha8; + 16: CopyProc := CopyInterlacedRGBAlpha16; + end; + {Grayscale followed by alpha} + COLOR_GRAYSCALEALPHA: + case Header.BitDepth of + 8: CopyProc := CopyInterlacedGrayscaleAlpha8; + 16: CopyProc := CopyInterlacedGrayscaleAlpha16; + end; + end {case Header.ColorType}; + + {Adam7 method has 7 passes to make the final image} + FOR CurrentPass := 0 TO 6 DO + begin + {Calculates the number of pixels and bytes for this pass row} + PixelsThisRow := (ImageWidth - ColumnStart[CurrentPass] + + ColumnIncrement[CurrentPass] - 1) div ColumnIncrement[CurrentPass]; + Row_Bytes := BytesForPixels(PixelsThisRow, Header.ColorType, + Header.BitDepth); + {Clear buffer for this pass} + ZeroMemory(Row_Buffer[not RowUsed], Row_Bytes); + + {Get current row index} + CurrentRow := RowStart[CurrentPass]; + {Get a pointer to the current row image data} + Data := Ptr(Longint(Header.ImageData) + Header.BytesPerRow * + (ImageHeight - 1 - CurrentRow)); + Trans := Ptr(Longint(Header.ImageAlpha) + ImageWidth * CurrentRow); + {$IFDEF Store16bits} + Extra := Ptr(Longint(Header.ExtraImageData) + Header.BytesPerRow * + (ImageHeight - 1 - CurrentRow)); + {$ENDIF} + + if Row_Bytes > 0 then {There must have bytes for this interlaced pass} + while CurrentRow < ImageHeight do + begin + {Reads this line and filter} + if IDATZlibRead(ZLIBStream, @Row_Buffer[RowUsed][0], Row_Bytes + 1, + EndPos, CRCFile) = 0 then break; + + FilterRow; + {Copy image data} + + CopyProc(CurrentPass, @Row_Buffer[RowUsed][1], Data, Trans + {$IFDEF Store16bits}, Extra{$ENDIF}); + + {Use the other RowBuffer item} + RowUsed := not RowUsed; + + {Move to the next row} + inc(CurrentRow, RowIncrement[CurrentPass]); + {Move pointer to the next line} + dec(Data, RowIncrement[CurrentPass] * Header.BytesPerRow); + inc(Trans, RowIncrement[CurrentPass] * ImageWidth); + {$IFDEF Store16bits} + dec(Extra, RowIncrement[CurrentPass] * Header.BytesPerRow); + {$ENDIF} + end {while CurrentRow < ImageHeight}; + + end {FOR CurrentPass}; + +end; + +{Copy 8 bits RGB image} +procedure TChunkIDAT.CopyNonInterlacedRGB8( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + {Copy pixel values} + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + {Move to next pixel} + inc(Src, 3); + end {for I} +end; + +{Copy 16 bits RGB image} +procedure TChunkIDAT.CopyNonInterlacedRGB16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + //Since windows does not supports 2 bytes for + //each R, G, B value, the method will read only 1 byte from it + {Copy pixel values} + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 4)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + {$IFDEF Store16bits} + {Copy extra pixel values} + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 5)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 3)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Extra); + {$ENDIF} + + {Move to next pixel} + inc(Src, 6); + end {for I} +end; + +{Copy types using palettes (1, 4 or 8 bits per pixel)} +procedure TChunkIDAT.CopyNonInterlacedPalette148( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +begin + {It's simple as copying the data} + CopyMemory(Dest, Src, Row_Bytes); +end; + +{Copy grayscale types using 2 bits for each pixel} +procedure TChunkIDAT.CopyNonInterlacedGray2( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + i: Integer; +begin + {2 bits is not supported, this routine will converted into 4 bits} + FOR i := 1 TO Row_Bytes do + begin + Byte(Dest^) := ((Byte(Src^) shr 2) and $F) or ((Byte(Src^)) and $F0); + inc(Dest); + Byte(Dest^) := ((Byte(Src^) shl 2) and $F) or ((Byte(Src^) shl 4) and $F0); + inc(Dest); + inc(Src); + end {FOR i} +end; + +{Copy types using palette with 2 bits for each pixel} +procedure TChunkIDAT.CopyNonInterlacedPalette2( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + i: Integer; +begin + {2 bits is not supported, this routine will converted into 4 bits} + FOR i := 1 TO Row_Bytes do + begin + Byte(Dest^) := ((Byte(Src^) shr 4) and $3) or ((Byte(Src^) shr 2) and $30); + inc(Dest); + Byte(Dest^) := (Byte(Src^) and $3) or ((Byte(Src^) shl 2) and $30); + inc(Dest); + inc(Src); + end {FOR i} +end; + +{Copy grayscale images with 16 bits} +procedure TChunkIDAT.CopyNonInterlacedGrayscale16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + {Windows does not supports 16 bits for each pixel in grayscale} + {mode, so reduce to 8} + Dest^ := Src^; inc(Dest); + {$IFDEF Store16bits} + Extra^ := pChar(Longint(Src) + 1)^; inc(Extra); + {$ENDIF} + + {Move to next pixel} + inc(Src, 2); + end {for I} +end; + +{Copy 8 bits per sample RGB images followed by an alpha byte} +procedure TChunkIDAT.CopyNonInterlacedRGBAlpha8( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + i: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + {Copy pixel values and transparency} + Trans^ := pChar(Longint(Src) + 3)^; + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + {Move to next pixel} + inc(Src, 4); inc(Trans); + end {for I} +end; + +{Copy 16 bits RGB image with alpha using 2 bytes for each sample} +procedure TChunkIDAT.CopyNonInterlacedRGBAlpha16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + //Copy rgb and alpha values (transforming from 16 bits to 8 bits) + {Copy pixel values} + Trans^ := pChar(Longint(Src) + 6)^; + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 4)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); + {$IFDEF Store16bits} + {Copy extra pixel values} + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 5)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 3)^]; inc(Extra); + Byte(Extra^) := fOwner.GammaTable[pByte(Longint(Src) + 1)^]; inc(Extra); + {$ENDIF} + {Move to next pixel} + inc(Src, 8); inc(Trans); + end {for I} +end; + +{Copy 8 bits per sample grayscale followed by alpha} +procedure TChunkIDAT.CopyNonInterlacedGrayscaleAlpha8( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + {Copy alpha value and then gray value} + Dest^ := Src^; inc(Src); + Trans^ := Src^; inc(Src); + inc(Dest); inc(Trans); + end; +end; + +{Copy 16 bits per sample grayscale followed by alpha} +procedure TChunkIDAT.CopyNonInterlacedGrayscaleAlpha16( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + {Copy alpha value and then gray value} + {$IFDEF Store16bits} + Extra^ := pChar(Longint(Src) + 1)^; inc(Extra); + {$ENDIF} + Dest^ := Src^; inc(Src, 2); + Trans^ := Src^; inc(Src, 2); + inc(Dest); inc(Trans); + end; +end; + +{Decode non interlaced image} +procedure TChunkIDAT.DecodeNonInterlaced(Stream: TStream; + var ZLIBStream: TZStreamRec2; const Size: Integer; var crcfile: Cardinal); +var + j: Cardinal; + Trans, Data{$IFDEF Store16bits}, Extra{$ENDIF}: pChar; + CopyProc: procedure( + Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar) of object; +begin + CopyProc := nil; {Initialize} + {Determines the method to copy the image data} + case Header.ColorType of + {R, G, B values} + COLOR_RGB: + case Header.BitDepth of + 8: CopyProc := CopyNonInterlacedRGB8; + 16: CopyProc := CopyNonInterlacedRGB16; + end; + {Types using palettes} + COLOR_PALETTE, COLOR_GRAYSCALE: + case Header.BitDepth of + 1, 4, 8: CopyProc := CopyNonInterlacedPalette148; + 2 : if Header.ColorType = COLOR_PALETTE then + CopyProc := CopyNonInterlacedPalette2 + else + CopyProc := CopyNonInterlacedGray2; + 16 : CopyProc := CopyNonInterlacedGrayscale16; + end; + {R, G, B followed by alpha} + COLOR_RGBALPHA: + case Header.BitDepth of + 8 : CopyProc := CopyNonInterlacedRGBAlpha8; + 16 : CopyProc := CopyNonInterlacedRGBAlpha16; + end; + {Grayscale followed by alpha} + COLOR_GRAYSCALEALPHA: + case Header.BitDepth of + 8 : CopyProc := CopyNonInterlacedGrayscaleAlpha8; + 16 : CopyProc := CopyNonInterlacedGrayscaleAlpha16; + end; + end; + + {Get the image data pointer} + Longint(Data) := Longint(Header.ImageData) + + Header.BytesPerRow * (ImageHeight - 1); + Trans := Header.ImageAlpha; + {$IFDEF Store16bits} + Longint(Extra) := Longint(Header.ExtraImageData) + + Header.BytesPerRow * (ImageHeight - 1); + {$ENDIF} + {Reads each line} + FOR j := 0 to ImageHeight - 1 do + begin + {Read this line Row_Buffer[RowUsed][0] if the filter type for this line} + if IDATZlibRead(ZLIBStream, @Row_Buffer[RowUsed][0], Row_Bytes + 1, EndPos, + CRCFile) = 0 then break; + + {Filter the current row} + FilterRow; + {Copies non interlaced row to image} + CopyProc(@Row_Buffer[RowUsed][1], Data, Trans{$IFDEF Store16bits}, Extra + {$ENDIF}); + + {Invert line used} + RowUsed := not RowUsed; + dec(Data, Header.BytesPerRow); + {$IFDEF Store16bits}dec(Extra, Header.BytesPerRow);{$ENDIF} + inc(Trans, ImageWidth); + end {for I}; + + +end; + +{Filter the current line} +procedure TChunkIDAT.FilterRow; +var + pp: Byte; + vv, left, above, aboveleft: Integer; + Col: Cardinal; +begin + {Test the filter} + case Row_Buffer[RowUsed]^[0] of + {No filtering for this line} + FILTER_NONE: begin end; + {AND 255 serves only to never let the result be larger than one byte} + {Sub filter} + FILTER_SUB: + FOR Col := Offset + 1 to Row_Bytes DO + Row_Buffer[RowUsed][Col] := (Row_Buffer[RowUsed][Col] + + Row_Buffer[RowUsed][Col - Offset]) and 255; + {Up filter} + FILTER_UP: + FOR Col := 1 to Row_Bytes DO + Row_Buffer[RowUsed][Col] := (Row_Buffer[RowUsed][Col] + + Row_Buffer[not RowUsed][Col]) and 255; + {Average filter} + FILTER_AVERAGE: + FOR Col := 1 to Row_Bytes DO + begin + {Obtains up and left pixels} + above := Row_Buffer[not RowUsed][Col]; + if col - 1 < Offset then + left := 0 + else + Left := Row_Buffer[RowUsed][Col - Offset]; + + {Calculates} + Row_Buffer[RowUsed][Col] := (Row_Buffer[RowUsed][Col] + + (left + above) div 2) and 255; + end; + {Paeth filter} + FILTER_PAETH: + begin + {Initialize} + left := 0; + aboveleft := 0; + {Test each byte} + FOR Col := 1 to Row_Bytes DO + begin + {Obtains above pixel} + above := Row_Buffer[not RowUsed][Col]; + {Obtains left and top-left pixels} + if (col - 1 >= offset) Then + begin + left := row_buffer[RowUsed][col - offset]; + aboveleft := row_buffer[not RowUsed][col - offset]; + end; + + {Obtains current pixel and paeth predictor} + vv := row_buffer[RowUsed][Col]; + pp := PaethPredictor(left, above, aboveleft); + + {Calculates} + Row_Buffer[RowUsed][Col] := (pp + vv) and $FF; + end {for}; + end; + + end {case}; +end; + +{Reads the image data from the stream} +function TChunkIDAT.LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; +var + ZLIBStream: TZStreamRec2; + CRCCheck, + CRCFile : Cardinal; +begin + {Get pointer to the header chunk} + Header := Owner.Chunks.Item[0] as TChunkIHDR; + {Build palette if necessary} + if Header.HasPalette then PreparePalette(); + + {Copy image width and height} + ImageWidth := Header.Width; + ImageHeight := Header.Height; + + {Initialize to calculate CRC} + {$IFDEF CheckCRC} + CRCFile := update_crc($ffffffff, @ChunkName[0], 4); + {$ENDIF} + + Owner.GetPixelInfo(Row_Bytes, Offset); {Obtain line information} + ZLIBStream := ZLIBInitInflate(Stream); {Initializes decompression} + + {Calculate ending position for the current IDAT chunk} + EndPos := Stream.Position + Size; + + {Allocate memory} + GetMem(Row_Buffer[false], Row_Bytes + 1); + GetMem(Row_Buffer[true], Row_Bytes + 1); + ZeroMemory(Row_Buffer[false], Row_bytes + 1); + {Set the variable to alternate the Row_Buffer item to use} + RowUsed := TRUE; + + {Call special methods for the different interlace methods} + case Owner.InterlaceMethod of + imNone: DecodeNonInterlaced(stream, ZLIBStream, Size, crcfile); + imAdam7: DecodeInterlacedAdam7(stream, ZLIBStream, size, crcfile); + end; + + {Free memory} + ZLIBTerminateInflate(ZLIBStream); {Terminates decompression} + FreeMem(Row_Buffer[False], Row_Bytes + 1); + FreeMem(Row_Buffer[True], Row_Bytes + 1); + + {Now checks CRC} + Stream.Read(CRCCheck, 4); + {$IFDEF CheckCRC} + CRCFile := CRCFile xor $ffffffff; + CRCCheck := ByteSwap(CRCCheck); + Result := CRCCheck = CRCFile; + + {Handle CRC error} + if not Result then + begin + {In case it coult not load chunk} + Owner.RaiseError(EPngInvalidCRC, EPngInvalidCRCText); + exit; + end; + {$ELSE}Result := TRUE; {$ENDIF} +end; + +const + IDATHeader: Array[0..3] of char = ('I', 'D', 'A', 'T'); + BUFFER = 5; + +{Saves the IDAT chunk to a stream} +function TChunkIDAT.SaveToStream(Stream: TStream): Boolean; +var + ZLIBStream : TZStreamRec2; +begin + {Get pointer to the header chunk} + Header := Owner.Chunks.Item[0] as TChunkIHDR; + {Copy image width and height} + ImageWidth := Header.Width; + ImageHeight := Header.Height; + Owner.GetPixelInfo(Row_Bytes, Offset); {Obtain line information} + + {Allocate memory} + GetMem(Encode_Buffer[BUFFER], Row_Bytes); + ZeroMemory(Encode_Buffer[BUFFER], Row_Bytes); + {Allocate buffers for the filters selected} + {Filter none will always be calculated to the other filters to work} + GetMem(Encode_Buffer[FILTER_NONE], Row_Bytes); + ZeroMemory(Encode_Buffer[FILTER_NONE], Row_Bytes); + if pfSub in Owner.Filters then + GetMem(Encode_Buffer[FILTER_SUB], Row_Bytes); + if pfUp in Owner.Filters then + GetMem(Encode_Buffer[FILTER_UP], Row_Bytes); + if pfAverage in Owner.Filters then + GetMem(Encode_Buffer[FILTER_AVERAGE], Row_Bytes); + if pfPaeth in Owner.Filters then + GetMem(Encode_Buffer[FILTER_PAETH], Row_Bytes); + + {Initialize ZLIB} + ZLIBStream := ZLIBInitDeflate(Stream, Owner.fCompressionLevel, + Owner.MaxIdatSize); + {Write data depending on the interlace method} + case Owner.InterlaceMethod of + imNone: EncodeNonInterlaced(stream, ZLIBStream); + imAdam7: EncodeInterlacedAdam7(stream, ZLIBStream); + end; + {Terminates ZLIB} + ZLIBTerminateDeflate(ZLIBStream); + + {Release allocated memory} + FreeMem(Encode_Buffer[BUFFER], Row_Bytes); + FreeMem(Encode_Buffer[FILTER_NONE], Row_Bytes); + if pfSub in Owner.Filters then + FreeMem(Encode_Buffer[FILTER_SUB], Row_Bytes); + if pfUp in Owner.Filters then + FreeMem(Encode_Buffer[FILTER_UP], Row_Bytes); + if pfAverage in Owner.Filters then + FreeMem(Encode_Buffer[FILTER_AVERAGE], Row_Bytes); + if pfPaeth in Owner.Filters then + FreeMem(Encode_Buffer[FILTER_PAETH], Row_Bytes); + + {Everything went ok} + Result := True; +end; + +{Writes the IDAT using the settings} +procedure WriteIDAT(Stream: TStream; Data: Pointer; const Length: Cardinal); +var + ChunkLen, CRC: Cardinal; +begin + {Writes IDAT header} + ChunkLen := ByteSwap(Length); + Stream.Write(ChunkLen, 4); {Chunk length} + Stream.Write(IDATHeader[0], 4); {Idat header} + CRC := update_crc($ffffffff, @IDATHeader[0], 4); {Crc part for header} + + {Writes IDAT data and calculates CRC for data} + Stream.Write(Data^, Length); + CRC := Byteswap(update_crc(CRC, Data, Length) xor $ffffffff); + {Writes final CRC} + Stream.Write(CRC, 4); +end; + +{Compress and writes IDAT chunk data} +procedure TChunkIDAT.IDATZlibWrite(var ZLIBStream: TZStreamRec2; + Buffer: Pointer; const Length: Cardinal); +begin + with ZLIBStream, ZLIBStream.ZLIB do + begin + {Set data to be compressed} + next_in := Buffer; + avail_in := Length; + + {Compress all the data avaliable to compress} + while avail_in > 0 do + begin + deflate(ZLIB, Z_NO_FLUSH); + + {The whole buffer was used, save data to stream and restore buffer} + if avail_out = 0 then + begin + {Writes this IDAT chunk} + WriteIDAT(fStream, Data, Owner.MaxIdatSize); + + {Restore buffer} + next_out := Data; + avail_out := Owner.MaxIdatSize; + end {if avail_out = 0}; + + end {while avail_in}; + + end {with ZLIBStream, ZLIBStream.ZLIB} +end; + +{Finishes compressing data to write IDAT chunk} +procedure TChunkIDAT.FinishIDATZlib(var ZLIBStream: TZStreamRec2); +begin + with ZLIBStream, ZLIBStream.ZLIB do + begin + {Set data to be compressed} + next_in := nil; + avail_in := 0; + + while deflate(ZLIB,Z_FINISH) <> Z_STREAM_END do + begin + {Writes this IDAT chunk} + WriteIDAT(fStream, Data, Owner.MaxIdatSize - avail_out); + {Re-update buffer} + next_out := Data; + avail_out := Owner.MaxIdatSize; + end; + + if avail_out < Owner.MaxIdatSize then + {Writes final IDAT} + WriteIDAT(fStream, Data, Owner.MaxIdatSize - avail_out); + + end {with ZLIBStream, ZLIBStream.ZLIB}; +end; + +{Copy memory to encode RGB image with 1 byte for each color sample} +procedure TChunkIDAT.EncodeNonInterlacedRGB8(Src, Dest, Trans: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + {Copy pixel values} + Byte(Dest^) := fOwner.InverseGamma[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.InverseGamma[pByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := fOwner.InverseGamma[pByte(Longint(Src) )^]; inc(Dest); + {Move to next pixel} + inc(Src, 3); + end {for I} +end; + +{Copy memory to encode RGB images with 16 bits for each color sample} +procedure TChunkIDAT.EncodeNonInterlacedRGB16(Src, Dest, Trans: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + //Now we copy from 1 byte for each sample stored to a 2 bytes (or 1 word) + //for sample + {Copy pixel values} + pWORD(Dest)^ := fOwner.InverseGamma[pByte(Longint(Src) + 2)^]; inc(Dest, 2); + pWORD(Dest)^ := fOwner.InverseGamma[pByte(Longint(Src) + 1)^]; inc(Dest, 2); + pWORD(Dest)^ := fOwner.InverseGamma[pByte(Longint(Src) )^]; inc(Dest, 2); + {Move to next pixel} + inc(Src, 3); + end {for I} + +end; + +{Copy memory to encode types using palettes (1, 4 or 8 bits per pixel)} +procedure TChunkIDAT.EncodeNonInterlacedPalette148(Src, Dest, Trans: pChar); +begin + {It's simple as copying the data} + CopyMemory(Dest, Src, Row_Bytes); +end; + +{Copy memory to encode grayscale images with 2 bytes for each sample} +procedure TChunkIDAT.EncodeNonInterlacedGrayscale16(Src, Dest, Trans: pChar); +var + I: Integer; +begin + FOR I := 1 TO ImageWidth DO + begin + //Now we copy from 1 byte for each sample stored to a 2 bytes (or 1 word) + //for sample + pWORD(Dest)^ := pByte(Longint(Src))^; inc(Dest, 2); + {Move to next pixel} + inc(Src); + end {for I} +end; + +{Encode images using RGB followed by an alpha value using 1 byte for each} +procedure TChunkIDAT.EncodeNonInterlacedRGBAlpha8(Src, Dest, Trans: pChar); +var + i: Integer; +begin + {Copy the data to the destination, including data from Trans pointer} + FOR i := 1 TO ImageWidth do + begin + Byte(Dest^) := Owner.InverseGamma[PByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := Owner.InverseGamma[PByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := Owner.InverseGamma[PByte(Longint(Src) )^]; inc(Dest); + Dest^ := Trans^; inc(Dest); + inc(Src, 3); inc(Trans); + end {for i}; +end; + +{Encode images using RGB followed by an alpha value using 2 byte for each} +procedure TChunkIDAT.EncodeNonInterlacedRGBAlpha16(Src, Dest, Trans: pChar); +var + i: Integer; +begin + {Copy the data to the destination, including data from Trans pointer} + FOR i := 1 TO ImageWidth do + begin + pWord(Dest)^ := Owner.InverseGamma[PByte(Longint(Src) + 2)^]; inc(Dest, 2); + pWord(Dest)^ := Owner.InverseGamma[PByte(Longint(Src) + 1)^]; inc(Dest, 2); + pWord(Dest)^ := Owner.InverseGamma[PByte(Longint(Src) )^]; inc(Dest, 2); + pWord(Dest)^ := PByte(Longint(Trans) )^; inc(Dest, 2); + inc(Src, 3); inc(Trans); + end {for i}; +end; + +{Encode grayscale images followed by an alpha value using 1 byte for each} +procedure TChunkIDAT.EncodeNonInterlacedGrayscaleAlpha8( + Src, Dest, Trans: pChar); +var + i: Integer; +begin + {Copy the data to the destination, including data from Trans pointer} + FOR i := 1 TO ImageWidth do + begin + Dest^ := Src^; inc(Dest); + Dest^ := Trans^; inc(Dest); + inc(Src); inc(Trans); + end {for i}; +end; + +{Encode grayscale images followed by an alpha value using 2 byte for each} +procedure TChunkIDAT.EncodeNonInterlacedGrayscaleAlpha16( + Src, Dest, Trans: pChar); +var + i: Integer; +begin + {Copy the data to the destination, including data from Trans pointer} + FOR i := 1 TO ImageWidth do + begin + pWord(Dest)^ := pByte(Src)^; inc(Dest, 2); + pWord(Dest)^ := pByte(Trans)^; inc(Dest, 2); + inc(Src); inc(Trans); + end {for i}; +end; + +{Encode non interlaced images} +procedure TChunkIDAT.EncodeNonInterlaced(Stream: TStream; + var ZLIBStream: TZStreamRec2); +var + {Current line} + j: Cardinal; + {Pointers to image data} + Data, Trans: PChar; + {Filter used for this line} + Filter: Byte; + {Method which will copy the data into the buffer} + CopyProc: procedure(Src, Dest, Trans: pChar) of object; +begin + CopyProc := nil; {Initialize to avoid warnings} + {Defines the method to copy the data to the buffer depending on} + {the image parameters} + case Header.ColorType of + {R, G, B values} + COLOR_RGB: + case Header.BitDepth of + 8: CopyProc := EncodeNonInterlacedRGB8; + 16: CopyProc := EncodeNonInterlacedRGB16; + end; + {Palette and grayscale values} + COLOR_GRAYSCALE, COLOR_PALETTE: + case Header.BitDepth of + 1, 4, 8: CopyProc := EncodeNonInterlacedPalette148; + 16: CopyProc := EncodeNonInterlacedGrayscale16; + end; + {RGB with a following alpha value} + COLOR_RGBALPHA: + case Header.BitDepth of + 8: CopyProc := EncodeNonInterlacedRGBAlpha8; + 16: CopyProc := EncodeNonInterlacedRGBAlpha16; + end; + {Grayscale images followed by an alpha} + COLOR_GRAYSCALEALPHA: + case Header.BitDepth of + 8: CopyProc := EncodeNonInterlacedGrayscaleAlpha8; + 16: CopyProc := EncodeNonInterlacedGrayscaleAlpha16; + end; + end {case Header.ColorType}; + + {Get the image data pointer} + Longint(Data) := Longint(Header.ImageData) + + Header.BytesPerRow * (ImageHeight - 1); + Trans := Header.ImageAlpha; + + {Writes each line} + FOR j := 0 to ImageHeight - 1 do + begin + {Copy data into buffer} + CopyProc(Data, @Encode_Buffer[BUFFER][0], Trans); + {Filter data} + Filter := FilterToEncode; + + {Compress data} + IDATZlibWrite(ZLIBStream, @Filter, 1); + IDATZlibWrite(ZLIBStream, @Encode_Buffer[Filter][0], Row_Bytes); + + {Adjust pointers to the actual image data} + dec(Data, Header.BytesPerRow); + inc(Trans, ImageWidth); + end; + + {Compress and finishes copying the remaining data} + FinishIDATZlib(ZLIBStream); +end; + +{Copy memory to encode interlaced images using RGB value with 1 byte for} +{each color sample} +procedure TChunkIDAT.EncodeInterlacedRGB8(const Pass: Byte; + Src, Dest, Trans: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Src := pChar(Longint(Src) + Col * 3); + repeat + {Copy this row} + Byte(Dest^) := fOwner.InverseGamma[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := fOwner.InverseGamma[pByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := fOwner.InverseGamma[pByte(Longint(Src) )^]; inc(Dest); + + {Move to next column} + inc(Src, ColumnIncrement[Pass] * 3); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy memory to encode interlaced RGB images with 2 bytes each color sample} +procedure TChunkIDAT.EncodeInterlacedRGB16(const Pass: Byte; + Src, Dest, Trans: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Src := pChar(Longint(Src) + Col * 3); + repeat + {Copy this row} + pWord(Dest)^ := Owner.InverseGamma[pByte(Longint(Src) + 2)^]; inc(Dest, 2); + pWord(Dest)^ := Owner.InverseGamma[pByte(Longint(Src) + 1)^]; inc(Dest, 2); + pWord(Dest)^ := Owner.InverseGamma[pByte(Longint(Src) )^]; inc(Dest, 2); + + {Move to next column} + inc(Src, ColumnIncrement[Pass] * 3); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy memory to encode interlaced images using palettes using bit depths} +{1, 4, 8 (each pixel in the image)} +procedure TChunkIDAT.EncodeInterlacedPalette148(const Pass: Byte; + Src, Dest, Trans: pChar); +const + BitTable: Array[1..8] of Integer = ($1, $3, 0, $F, 0, 0, 0, $FF); + StartBit: Array[1..8] of Integer = (7 , 0 , 0, 4, 0, 0, 0, 0); +var + CurBit, Col: Integer; + Src2: PChar; +begin + {Clean the line} + fillchar(Dest^, Row_Bytes, #0); + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + with Header.BitmapInfo.bmiHeader do + repeat + {Copy data} + CurBit := StartBit[biBitCount]; + repeat + {Adjust pointer to pixel byte bounds} + Src2 := pChar(Longint(Src) + (biBitCount * Col) div 8); + {Copy data} + Byte(Dest^) := Byte(Dest^) or + (((Byte(Src2^) shr (StartBit[Header.BitDepth] - (biBitCount * Col) + mod 8))) and (BitTable[biBitCount])) shl CurBit; + + {Move to next column} + inc(Col, ColumnIncrement[Pass]); + {Will read next bits} + dec(CurBit, biBitCount); + until CurBit < 0; + + {Move to next byte in source} + inc(Dest); + until Col >= ImageWidth; +end; + +{Copy to encode interlaced grayscale images using 16 bits for each sample} +procedure TChunkIDAT.EncodeInterlacedGrayscale16(const Pass: Byte; + Src, Dest, Trans: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Src := pChar(Longint(Src) + Col); + repeat + {Copy this row} + pWord(Dest)^ := Byte(Src^); inc(Dest, 2); + + {Move to next column} + inc(Src, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy to encode interlaced rgb images followed by an alpha value, all using} +{one byte for each sample} +procedure TChunkIDAT.EncodeInterlacedRGBAlpha8(const Pass: Byte; + Src, Dest, Trans: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Src := pChar(Longint(Src) + Col * 3); + Trans := pChar(Longint(Trans) + Col); + repeat + {Copy this row} + Byte(Dest^) := Owner.InverseGamma[pByte(Longint(Src) + 2)^]; inc(Dest); + Byte(Dest^) := Owner.InverseGamma[pByte(Longint(Src) + 1)^]; inc(Dest); + Byte(Dest^) := Owner.InverseGamma[pByte(Longint(Src) )^]; inc(Dest); + Dest^ := Trans^; inc(Dest); + + {Move to next column} + inc(Src, ColumnIncrement[Pass] * 3); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy to encode interlaced rgb images followed by an alpha value, all using} +{two byte for each sample} +procedure TChunkIDAT.EncodeInterlacedRGBAlpha16(const Pass: Byte; + Src, Dest, Trans: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Src := pChar(Longint(Src) + Col * 3); + Trans := pChar(Longint(Trans) + Col); + repeat + {Copy this row} + pWord(Dest)^ := pByte(Longint(Src) + 2)^; inc(Dest, 2); + pWord(Dest)^ := pByte(Longint(Src) + 1)^; inc(Dest, 2); + pWord(Dest)^ := pByte(Longint(Src) )^; inc(Dest, 2); + pWord(Dest)^ := pByte(Trans)^; inc(Dest, 2); + + {Move to next column} + inc(Src, ColumnIncrement[Pass] * 3); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy to encode grayscale interlaced images followed by an alpha value, all} +{using 1 byte for each sample} +procedure TChunkIDAT.EncodeInterlacedGrayscaleAlpha8(const Pass: Byte; + Src, Dest, Trans: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Src := pChar(Longint(Src) + Col); + Trans := pChar(Longint(Trans) + Col); + repeat + {Copy this row} + Dest^ := Src^; inc(Dest); + Dest^ := Trans^; inc(Dest); + + {Move to next column} + inc(Src, ColumnIncrement[Pass]); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Copy to encode grayscale interlaced images followed by an alpha value, all} +{using 2 bytes for each sample} +procedure TChunkIDAT.EncodeInterlacedGrayscaleAlpha16(const Pass: Byte; + Src, Dest, Trans: pChar); +var + Col: Integer; +begin + {Get first column and enter in loop} + Col := ColumnStart[Pass]; + Src := pChar(Longint(Src) + Col); + Trans := pChar(Longint(Trans) + Col); + repeat + {Copy this row} + pWord(Dest)^ := pByte(Src)^; inc(Dest, 2); + pWord(Dest)^ := pByte(Trans)^; inc(Dest, 2); + + {Move to next column} + inc(Src, ColumnIncrement[Pass]); + inc(Trans, ColumnIncrement[Pass]); + inc(Col, ColumnIncrement[Pass]); + until Col >= ImageWidth; +end; + +{Encode interlaced images} +procedure TChunkIDAT.EncodeInterlacedAdam7(Stream: TStream; + var ZLIBStream: TZStreamRec2); +var + CurrentPass, Filter: Byte; + PixelsThisRow: Integer; + CurrentRow : Integer; + Trans, Data: pChar; + CopyProc: procedure(const Pass: Byte; + Src, Dest, Trans: pChar) of object; +begin + CopyProc := nil; {Initialize to avoid warnings} + {Defines the method to copy the data to the buffer depending on} + {the image parameters} + case Header.ColorType of + {R, G, B values} + COLOR_RGB: + case Header.BitDepth of + 8: CopyProc := EncodeInterlacedRGB8; + 16: CopyProc := EncodeInterlacedRGB16; + end; + {Grayscale and palette} + COLOR_PALETTE, COLOR_GRAYSCALE: + case Header.BitDepth of + 1, 4, 8: CopyProc := EncodeInterlacedPalette148; + 16: CopyProc := EncodeInterlacedGrayscale16; + end; + {RGB followed by alpha} + COLOR_RGBALPHA: + case Header.BitDepth of + 8: CopyProc := EncodeInterlacedRGBAlpha8; + 16: CopyProc := EncodeInterlacedRGBAlpha16; + end; + COLOR_GRAYSCALEALPHA: + {Grayscale followed by alpha} + case Header.BitDepth of + 8: CopyProc := EncodeInterlacedGrayscaleAlpha8; + 16: CopyProc := EncodeInterlacedGrayscaleAlpha16; + end; + end {case Header.ColorType}; + + {Compress the image using the seven passes for ADAM 7} + FOR CurrentPass := 0 TO 6 DO + begin + {Calculates the number of pixels and bytes for this pass row} + PixelsThisRow := (ImageWidth - ColumnStart[CurrentPass] + + ColumnIncrement[CurrentPass] - 1) div ColumnIncrement[CurrentPass]; + Row_Bytes := BytesForPixels(PixelsThisRow, Header.ColorType, + Header.BitDepth); + ZeroMemory(Encode_Buffer[FILTER_NONE], Row_Bytes); + + {Get current row index} + CurrentRow := RowStart[CurrentPass]; + {Get a pointer to the current row image data} + Data := Ptr(Longint(Header.ImageData) + Header.BytesPerRow * + (ImageHeight - 1 - CurrentRow)); + Trans := Ptr(Longint(Header.ImageAlpha) + ImageWidth * CurrentRow); + + {Process all the image rows} + if Row_Bytes > 0 then + while CurrentRow < ImageHeight do + begin + {Copy data into buffer} + CopyProc(CurrentPass, Data, @Encode_Buffer[BUFFER][0], Trans); + {Filter data} + Filter := FilterToEncode; + + {Compress data} + IDATZlibWrite(ZLIBStream, @Filter, 1); + IDATZlibWrite(ZLIBStream, @Encode_Buffer[Filter][0], Row_Bytes); + + {Move to the next row} + inc(CurrentRow, RowIncrement[CurrentPass]); + {Move pointer to the next line} + dec(Data, RowIncrement[CurrentPass] * Header.BytesPerRow); + inc(Trans, RowIncrement[CurrentPass] * ImageWidth); + end {while CurrentRow < ImageHeight} + + end {CurrentPass}; + + {Compress and finishes copying the remaining data} + FinishIDATZlib(ZLIBStream); +end; + +{Filters the row to be encoded and returns the best filter} +function TChunkIDAT.FilterToEncode: Byte; +var + Run, LongestRun, ii, jj: Cardinal; + Last, Above, LastAbove: Byte; +begin + {Selecting more filters using the Filters property from TPngObject} + {increases the chances to the file be much smaller, but decreases} + {the performace} + + {This method will creates the same line data using the different} + {filter methods and select the best} + + {Sub-filter} + if pfSub in Owner.Filters then + for ii := 0 to Row_Bytes - 1 do + begin + {There is no previous pixel when it's on the first pixel, so} + {set last as zero when in the first} + if (ii >= Offset) then + last := Encode_Buffer[BUFFER]^[ii - Offset] + else + last := 0; + Encode_Buffer[FILTER_SUB]^[ii] := Encode_Buffer[BUFFER]^[ii] - last; + end; + + {Up filter} + if pfUp in Owner.Filters then + for ii := 0 to Row_Bytes - 1 do + Encode_Buffer[FILTER_UP]^[ii] := Encode_Buffer[BUFFER]^[ii] - + Encode_Buffer[FILTER_NONE]^[ii]; + + {Average filter} + if pfAverage in Owner.Filters then + for ii := 0 to Row_Bytes - 1 do + begin + {Get the previous pixel, if the current pixel is the first, the} + {previous is considered to be 0} + if (ii >= Offset) then + last := Encode_Buffer[BUFFER]^[ii - Offset] + else + last := 0; + {Get the pixel above} + above := Encode_Buffer[FILTER_NONE]^[ii]; + + {Calculates formula to the average pixel} + Encode_Buffer[FILTER_AVERAGE]^[ii] := Encode_Buffer[BUFFER]^[ii] - + (above + last) div 2 ; + end; + + {Paeth filter (the slower)} + if pfPaeth in Owner.Filters then + begin + {Initialize} + last := 0; + lastabove := 0; + for ii := 0 to Row_Bytes - 1 do + begin + {In case this pixel is not the first in the line obtains the} + {previous one and the one above the previous} + if (ii >= Offset) then + begin + last := Encode_Buffer[BUFFER]^[ii - Offset]; + lastabove := Encode_Buffer[FILTER_NONE]^[ii - Offset]; + end; + {Obtains the pixel above} + above := Encode_Buffer[FILTER_NONE]^[ii]; + {Calculate paeth filter for this byte} + Encode_Buffer[FILTER_PAETH]^[ii] := Encode_Buffer[BUFFER]^[ii] - + PaethPredictor(last, above, lastabove); + end; + end; + + {Now calculates the same line using no filter, which is necessary} + {in order to have data to the filters when the next line comes} + CopyMemory(@Encode_Buffer[FILTER_NONE]^[0], + @Encode_Buffer[BUFFER]^[0], Row_Bytes); + + {If only filter none is selected in the filter list, we don't need} + {to proceed and further} + if (Owner.Filters = [pfNone]) or (Owner.Filters = []) then + begin + Result := FILTER_NONE; + exit; + end {if (Owner.Filters = [pfNone...}; + + {Check which filter is the best by checking which has the larger} + {sequence of the same byte, since they are best compressed} + LongestRun := 0; Result := FILTER_NONE; + for ii := FILTER_NONE TO FILTER_PAETH do + {Check if this filter was selected} + if TFilter(ii) in Owner.Filters then + begin + Run := 0; + {Check if it's the only filter} + if Owner.Filters = [TFilter(ii)] then + begin + Result := ii; + exit; + end; + + {Check using a sequence of four bytes} + for jj := 2 to Row_Bytes - 1 do + if (Encode_Buffer[ii]^[jj] = Encode_Buffer [ii]^[jj-1]) or + (Encode_Buffer[ii]^[jj] = Encode_Buffer [ii]^[jj-2]) then + inc(Run); {Count the number of sequences} + + {Check if this one is the best so far} + if (Run > LongestRun) then + begin + Result := ii; + LongestRun := Run; + end {if (Run > LongestRun)}; + + end {if TFilter(ii) in Owner.Filters}; +end; + +{TChunkPLTE implementation} + +{Returns an item in the palette} +function TChunkPLTE.GetPaletteItem(Index: Byte): TRGBQuad; +begin + {Test if item is valid, if not raise error} + if Index > Count - 1 then + Owner.RaiseError(EPNGError, EPNGUnknownPalEntryText) + else + {Returns the item} + Result := Header.BitmapInfo.bmiColors[Index]; +end; + +{Loads the palette chunk from a stream} +function TChunkPLTE.LoadFromStream(Stream: TStream; + const ChunkName: TChunkName; Size: Integer): Boolean; +type + pPalEntry = ^PalEntry; + PalEntry = record + r, g, b: Byte; + end; +var + j : Integer; {For the FOR} + PalColor : pPalEntry; + palEntries: TMaxLogPalette; +begin + {Let ancestor load data and check CRC} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + if not Result then exit; + + {This chunk must be divisible by 3 in order to be valid} + if (Size mod 3 <> 0) or (Size div 3 > 256) then + begin + {Raise error} + Result := FALSE; + Owner.RaiseError(EPNGInvalidPalette, EPNGInvalidPaletteText); + exit; + end {if Size mod 3 <> 0}; + + {Fill array with the palette entries} + fCount := Size div 3; + Fillchar(palEntries, sizeof(palEntries), #0); + palEntries.palVersion := $300; + palEntries.palNumEntries := fCount; + PalColor := Data; + FOR j := 0 TO fCount - 1 DO + with palEntries.palPalEntry[j] do + begin + peRed := Owner.GammaTable[PalColor.r]; + peGreen := Owner.GammaTable[PalColor.g]; + peBlue := Owner.GammaTable[PalColor.b]; + peFlags := 0; + {Move to next palette entry} + inc(PalColor); + end; + Owner.SetPalette(CreatePalette(pLogPalette(@palEntries)^)); +end; + +{Saves the PLTE chunk to a stream} +function TChunkPLTE.SaveToStream(Stream: TStream): Boolean; +var + J: Integer; + DataPtr: pByte; + BitmapInfo: TMAXBITMAPINFO; + palEntries: TMaxLogPalette; +begin + {Adjust size to hold all the palette items} + if fCount = 0 then fCount := Header.BitmapInfo.bmiHeader.biClrUsed; + ResizeData(fCount * 3); + {Get all the palette entries} + fillchar(palEntries, sizeof(palEntries), #0); + GetPaletteEntries(Header.ImagePalette, 0, 256, palEntries.palPalEntry[0]); + {Copy pointer to data} + DataPtr := fData; + + {Copy palette items} + BitmapInfo := Header.BitmapInfo; + FOR j := 0 TO fCount - 1 DO + with palEntries.palPalEntry[j] do + begin + DataPtr^ := Owner.InverseGamma[peRed]; inc(DataPtr); + DataPtr^ := Owner.InverseGamma[peGreen]; inc(DataPtr); + DataPtr^ := Owner.InverseGamma[peBlue]; inc(DataPtr); + end {with BitmapInfo}; + + {Let ancestor do the rest of the work} + Result := inherited SaveToStream(Stream); +end; + +{Assigns from another PLTE chunk} +procedure TChunkPLTE.Assign(Source: TChunk); +begin + {Copy the number of palette items} + if Source is TChunkPLTE then + fCount := TChunkPLTE(Source).fCount + else + Owner.RaiseError(EPNGError, EPNGCannotAssignChunkText); +end; + +{TChunkgAMA implementation} + +{Assigns from another chunk} +procedure TChunkgAMA.Assign(Source: TChunk); +begin + {Copy the gamma value} + if Source is TChunkgAMA then + Gamma := TChunkgAMA(Source).Gamma + else + Owner.RaiseError(EPNGError, EPNGCannotAssignChunkText); +end; + +{Gamma chunk being created} +constructor TChunkgAMA.Create(Owner: TPngObject); +begin + {Call ancestor} + inherited Create(Owner); + Gamma := 1; {Initial value} +end; + +{Returns gamma value} +function TChunkgAMA.GetValue: Cardinal; +begin + {Make sure that the size is four bytes} + if DataSize <> 4 then + begin + {Adjust size and returns 1} + ResizeData(4); + Result := 1; + end + {If it's right, read the value} + else Result := Cardinal(ByteSwap(pCardinal(Data)^)) +end; + +function Power(Base, Exponent: Extended): Extended; +begin + if Exponent = 0.0 then + Result := 1.0 {Math rule} + else if (Base = 0) or (Exponent = 0) then Result := 0 + else + Result := Exp(Exponent * Ln(Base)); +end; + +{Loading the chunk from a stream} +function TChunkgAMA.LoadFromStream(Stream: TStream; + const ChunkName: TChunkName; Size: Integer): Boolean; +var + i: Integer; + Value: Cardinal; +begin + {Call ancestor and test if it went ok} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + if not Result then exit; + Value := Gamma; + {Build gamma table and inverse table for saving} + if Value <> 0 then + with Owner do + FOR i := 0 TO 255 DO + begin + GammaTable[I] := Round(Power((I / 255), 1 / + (Value / 100000 * 2.2)) * 255); + InverseGamma[Round(Power((I / 255), 1 / + (Value / 100000 * 2.2)) * 255)] := I; + end +end; + +{Sets the gamma value} +procedure TChunkgAMA.SetValue(const Value: Cardinal); +begin + {Make sure that the size is four bytes} + if DataSize <> 4 then ResizeData(4); + {If it's right, set the value} + pCardinal(Data)^ := ByteSwap(Value); +end; + +{TPngObject implementation} + +{Assigns from another object} +procedure TPngObject.Assign(Source: TPersistent); +begin + {Being cleared} + if Source = nil then + ClearChunks + {Assigns contents from another TPNGObject} + else if Source is TPNGObject then + AssignPNG(Source as TPNGObject) + {Copy contents from a TBitmap} + {$IFDEF UseDelphi}else if Source is TBitmap then + with Source as TBitmap do + AssignHandle(Handle, Transparent, + ColorToRGB(TransparentColor)){$ENDIF} + {Unknown source, let ancestor deal with it} + else + inherited; +end; + +{Clear all the chunks in the list} +procedure TPngObject.ClearChunks; +var + i: Integer; +begin + {Initialize gamma} + InitializeGamma(); + {Free all the objects and memory (0 chunks Bug fixed by Noel Sharpe)} + for i := 0 TO Integer(Chunks.Count) - 1 do + TChunk(Chunks.Item[i]).Free; + Chunks.Count := 0; +end; + +{Portable Network Graphics object being created as a blank image} +constructor TPNGObject.CreateBlank(ColorType, BitDepth: Cardinal; + cx, cy: Integer); +var NewIHDR: TChunkIHDR; +begin + {Calls creator} + Create; + {Checks if the parameters are ok} + if not (ColorType in [COLOR_GRAYSCALE, COLOR_RGB, COLOR_PALETTE, + COLOR_GRAYSCALEALPHA, COLOR_RGBALPHA]) or not (BitDepth in + [1,2,4,8, 16]) or ((ColorType = COLOR_PALETTE) and (BitDepth = 16)) or + ((ColorType = COLOR_RGB) and (BitDepth < 8)) then + begin + RaiseError(EPNGInvalidSpec, EInvalidSpec); + exit; + end; + if Bitdepth = 2 then Bitdepth := 4; + + {Add the basis chunks} + InitializeGamma; + BeingCreated := True; + Chunks.Add(TChunkIEND); + NewIHDR := Chunks.Add(TChunkIHDR) as TChunkIHDR; + NewIHDR.IHDRData.ColorType := ColorType; + NewIHDR.IHDRData.BitDepth := BitDepth; + NewIHDR.IHDRData.Width := cx; + NewIHDR.IHDRData.Height := cy; + NewIHDR.PrepareImageData; + if NewIHDR.HasPalette then + TChunkPLTE(Chunks.Add(TChunkPLTE)).fCount := 1 shl BitDepth; + Chunks.Add(TChunkIDAT); + BeingCreated := False; +end; + +{Portable Network Graphics object being created} +constructor TPngObject.Create; +begin + {Let it be created} + inherited Create; + + {Initial properties} + {$IFDEF UseDelphi}fCanvas := TCanvas.Create;{$ENDIF} + fFilters := [pfSub]; + fCompressionLevel := 7; + fInterlaceMethod := imNone; + fMaxIdatSize := High(Word); + {Create chunklist object} + fChunkList := TPngList.Create(Self); + +end; + +{Portable Network Graphics object being destroyed} +destructor TPngObject.Destroy; +begin + {Free object list} + ClearChunks; + fChunkList.Free; + {$IFDEF UseDelphi}if fCanvas <> nil then + fCanvas.Free;{$ENDIF} + + {Call ancestor destroy} + inherited Destroy; +end; + +{Returns linesize and byte offset for pixels} +procedure TPngObject.GetPixelInfo(var LineSize, Offset: Cardinal); +begin + {There must be an Header chunk to calculate size} + if HeaderPresent then + begin + {Calculate number of bytes for each line} + LineSize := BytesForPixels(Header.Width, Header.ColorType, Header.BitDepth); + + {Calculates byte offset} + Case Header.ColorType of + {Grayscale} + COLOR_GRAYSCALE: + If Header.BitDepth = 16 Then + Offset := 2 + Else + Offset := 1 ; + {It always smaller or equal one byte, so it occupes one byte} + COLOR_PALETTE: + offset := 1; + {It might be 3 or 6 bytes} + COLOR_RGB: + offset := 3 * Header.BitDepth Div 8; + {It might be 2 or 4 bytes} + COLOR_GRAYSCALEALPHA: + offset := 2 * Header.BitDepth Div 8; + {4 or 8 bytes} + COLOR_RGBALPHA: + offset := 4 * Header.BitDepth Div 8; + else + Offset := 0; + End ; + + end + else + begin + {In case if there isn't any Header chunk} + Offset := 0; + LineSize := 0; + end; + +end; + +{Returns image height} +function TPngObject.GetHeight: Integer; +begin + {There must be a Header chunk to get the size, otherwise returns 0} + if HeaderPresent then + Result := TChunkIHDR(Chunks.Item[0]).Height + else Result := 0; +end; + +{Returns image width} +function TPngObject.GetWidth: Integer; +begin + {There must be a Header chunk to get the size, otherwise returns 0} + if HeaderPresent then + Result := Header.Width + else Result := 0; +end; + +{Returns if the image is empty} +function TPngObject.GetEmpty: Boolean; +begin + Result := (Chunks.Count = 0); +end; + +{Raises an error} +procedure TPngObject.RaiseError(ExceptionClass: ExceptClass; Text: String); +begin + raise ExceptionClass.Create(Text); +end; + +{Set the maximum size for IDAT chunk} +procedure TPngObject.SetMaxIdatSize(const Value: Integer); +begin + {Make sure the size is at least 65535} + if Value < High(Word) then + fMaxIdatSize := High(Word) else fMaxIdatSize := Value; +end; + +{Draws the image using pixel information from TChunkpHYs} +procedure TPNGObject.DrawUsingPixelInformation(Canvas: TCanvas; Point: TPoint); + function Rect(Left, Top, Right, Bottom: Integer): TRect; + begin + Result.Left := Left; + Result.Top := Top; + Result.Right := Right; + Result.Bottom := Bottom; + end; +var + PPMeterY, PPMeterX: Double; + NewSizeX, NewSizeY: Integer; + DC: HDC; +begin + {Get system information} + DC := GetDC(0); + PPMeterY := GetDeviceCaps(DC, LOGPIXELSY) / 0.0254; + PPMeterX := GetDeviceCaps(DC, LOGPIXELSX) / 0.0254; + ReleaseDC(0, DC); + + {In case it does not has pixel information} + if not HasPixelInformation then + Draw(Canvas, Rect(Point.X, Point.Y, Point.X + Width, + Point.Y + Height)) + else + with PixelInformation do + begin + NewSizeX := Trunc(Self.Width / (PPUnitX / PPMeterX)); + NewSizeY := Trunc(Self.Height / (PPUnitY / PPMeterY)); + Draw(Canvas, Rect(Point.X, Point.Y, Point.X + NewSizeX, + Point.Y + NewSizeY)); + end; +end; + +{$IFNDEF UseDelphi} + {Creates a file stream reading from the filename in the parameter and load} + procedure TPngObject.LoadFromFile(const Filename: String); + var + FileStream: TFileStream; + begin + {Test if the file exists} + if not FileExists(Filename) then + begin + {In case it does not exists, raise error} + RaiseError(EPNGNotExists, EPNGNotExistsText); + exit; + end; + + {Creates the file stream to read} + FileStream := TFileStream.Create(Filename, [fsmRead]); + LoadFromStream(FileStream); {Loads the data} + FileStream.Free; {Free file stream} + end; + + {Saves the current png image to a file} + procedure TPngObject.SaveToFile(const Filename: String); + var + FileStream: TFileStream; + begin + {Creates the file stream to write} + FileStream := TFileStream.Create(Filename, [fsmWrite]); + SaveToStream(FileStream); {Saves the data} + FileStream.Free; {Free file stream} + end; + +{$ENDIF} + +{Returns if it has the pixel information chunk} +function TPngObject.HasPixelInformation: Boolean; +begin + Result := (Chunks.ItemFromClass(TChunkpHYs) as tChunkpHYs) <> nil; +end; + +{Returns the pixel information chunk} +function TPngObject.GetPixelInformation: TChunkpHYs; +begin + Result := Chunks.ItemFromClass(TChunkpHYs) as tChunkpHYs; + if not Assigned(Result) then + begin + Result := Chunks.Add(tChunkpHYs) as tChunkpHYs; + Result.fUnit := utMeter; + end; +end; + +{Returns pointer to the chunk TChunkIHDR which should be the first} +function TPngObject.GetHeader: TChunkIHDR; +begin + {If there is a TChunkIHDR returns it, otherwise returns nil} + if (Chunks.Count <> 0) and (Chunks.Item[0] is TChunkIHDR) then + Result := Chunks.Item[0] as TChunkIHDR + else + begin + {No header, throw error message} + RaiseError(EPNGHeaderNotPresent, EPNGHeaderNotPresentText); + Result := nil + end +end; + +{Draws using partial transparency} +procedure TPngObject.DrawPartialTrans(DC: HDC; Rect: TRect); + {Adjust the rectangle structure} + procedure AdjustRect(var Rect: TRect); + var + t: Integer; + begin + if Rect.Right < Rect.Left then + begin + t := Rect.Right; + Rect.Right := Rect.Left; + Rect.Left := t; + end; + if Rect.Bottom < Rect.Top then + begin + t := Rect.Bottom; + Rect.Bottom := Rect.Top; + Rect.Top := t; + end + end; + +type + {Access to pixels} + TPixelLine = Array[Word] of TRGBQuad; + pPixelLine = ^TPixelLine; +const + {Structure used to create the bitmap} + BitmapInfoHeader: TBitmapInfoHeader = + (biSize: sizeof(TBitmapInfoHeader); + biWidth: 100; + biHeight: 100; + biPlanes: 1; + biBitCount: 32; + biCompression: BI_RGB; + biSizeImage: 0; + biXPelsPerMeter: 0; + biYPelsPerMeter: 0; + biClrUsed: 0; + biClrImportant: 0); +var + {Buffer bitmap creation} + BitmapInfo : TBitmapInfo; + BufferDC : HDC; + BufferBits : Pointer; + OldBitmap, + BufferBitmap: HBitmap; + Header: TChunkIHDR; + + {Transparency/palette chunks} + TransparencyChunk: TChunktRNS; + PaletteChunk: TChunkPLTE; + TransValue, PaletteIndex: Byte; + CurBit: Integer; + Data: PByte; + + {Buffer bitmap modification} + BytesPerRowDest, + BytesPerRowSrc, + BytesPerRowAlpha: Integer; + ImageSource, ImageSourceOrg, + AlphaSource : pByteArray; + ImageData : pPixelLine; + i, j, i2, j2 : Integer; + + {For bitmap stretching} + W, H : Cardinal; + Stretch : Boolean; + FactorX, FactorY: Double; +begin + {Prepares the rectangle structure to stretch draw} + if (Rect.Right = Rect.Left) or (Rect.Bottom = Rect.Top) then exit; + AdjustRect(Rect); + {Gets the width and height} + W := Rect.Right - Rect.Left; + H := Rect.Bottom - Rect.Top; + Header := Self.Header; {Fast access to header} + Stretch := (W <> Header.Width) or (H <> Header.Height); + if Stretch then FactorX := W / Header.Width else FactorX := 1; + if Stretch then FactorY := H / Header.Height else FactorY := 1; + + {Prepare to create the bitmap} + Fillchar(BitmapInfo, sizeof(BitmapInfo), #0); + BitmapInfoHeader.biWidth := W; + BitmapInfoHeader.biHeight := -Integer(H); + BitmapInfo.bmiHeader := BitmapInfoHeader; + + {Create the bitmap which will receive the background, the applied} + {alpha blending and then will be painted on the background} + BufferDC := CreateCompatibleDC(0); + {In case BufferDC could not be created} + if (BufferDC = 0) then RaiseError(EPNGOutMemory, EPNGOutMemoryText); + BufferBitmap := CreateDIBSection(BufferDC, BitmapInfo, DIB_RGB_COLORS, + BufferBits, 0, 0); + {In case buffer bitmap could not be created} + if (BufferBitmap = 0) or (BufferBits = Nil) then + begin + if BufferBitmap <> 0 then DeleteObject(BufferBitmap); + DeleteDC(BufferDC); + RaiseError(EPNGOutMemory, EPNGOutMemoryText); + end; + + {Selects new bitmap and release old bitmap} + OldBitmap := SelectObject(BufferDC, BufferBitmap); + + {Draws the background on the buffer image} + BitBlt(BufferDC, 0, 0, W, H, DC, Rect.Left, Rect.Top, SRCCOPY); + + {Obtain number of bytes for each row} + BytesPerRowAlpha := Header.Width; + BytesPerRowDest := (((BitmapInfo.bmiHeader.biBitCount * W) + 31) + and not 31) div 8; {Number of bytes for each image row in destination} + BytesPerRowSrc := (((Header.BitmapInfo.bmiHeader.biBitCount * Header.Width) + + 31) and not 31) div 8; {Number of bytes for each image row in source} + + {Obtains image pointers} + ImageData := BufferBits; + AlphaSource := Header.ImageAlpha; + Longint(ImageSource) := Longint(Header.ImageData) + + Header.BytesPerRow * Longint(Header.Height - 1); + ImageSourceOrg := ImageSource; + + case Header.BitmapInfo.bmiHeader.biBitCount of + {R, G, B images} + 24: + FOR j := 1 TO H DO + begin + {Process all the pixels in this line} + FOR i := 0 TO W - 1 DO + begin + if Stretch then i2 := trunc(i / FactorX) else i2 := i; + {Optmize when we don´t have transparency} + if (AlphaSource[i2] <> 0) then + if (AlphaSource[i2] = 255) then + ImageData[i] := pRGBQuad(@ImageSource[i2 * 3])^ + else + with ImageData[i] do + begin + rgbRed := (255+ImageSource[2+i2*3] * AlphaSource[i2] + rgbRed * + (not AlphaSource[i2])) shr 8; + rgbGreen := (255+ImageSource[1+i2*3] * AlphaSource[i2] + + rgbGreen * (not AlphaSource[i2])) shr 8; + rgbBlue := (255+ImageSource[i2*3] * AlphaSource[i2] + rgbBlue * + (not AlphaSource[i2])) shr 8; + end; + end; + + {Move pointers} + inc(Longint(ImageData), BytesPerRowDest); + if Stretch then j2 := trunc(j / FactorY) else j2 := j; + Longint(ImageSource) := Longint(ImageSourceOrg) - BytesPerRowSrc * j2; + Longint(AlphaSource) := Longint(Header.ImageAlpha) + + BytesPerRowAlpha * j2; + end; + {Palette images with 1 byte for each pixel} + 1,4,8: if Header.ColorType = COLOR_GRAYSCALEALPHA then + FOR j := 1 TO H DO + begin + {Process all the pixels in this line} + FOR i := 0 TO W - 1 DO + with ImageData[i], Header.BitmapInfo do begin + if Stretch then i2 := trunc(i / FactorX) else i2 := i; + rgbRed := (255 + ImageSource[i2] * AlphaSource[i2] + + rgbRed * (255 - AlphaSource[i2])) shr 8; + rgbGreen := (255 + ImageSource[i2] * AlphaSource[i2] + + rgbGreen * (255 - AlphaSource[i2])) shr 8; + rgbBlue := (255 + ImageSource[i2] * AlphaSource[i2] + + rgbBlue * (255 - AlphaSource[i2])) shr 8; + end; + + {Move pointers} + Longint(ImageData) := Longint(ImageData) + BytesPerRowDest; + if Stretch then j2 := trunc(j / FactorY) else j2 := j; + Longint(ImageSource) := Longint(ImageSourceOrg) - BytesPerRowSrc * j2; + Longint(AlphaSource) := Longint(Header.ImageAlpha) + + BytesPerRowAlpha * j2; + end + else {Palette images} + begin + {Obtain pointer to the transparency chunk} + TransparencyChunk := TChunktRNS(Chunks.ItemFromClass(TChunktRNS)); + PaletteChunk := TChunkPLTE(Chunks.ItemFromClass(TChunkPLTE)); + + FOR j := 1 TO H DO + begin + {Process all the pixels in this line} + i := 0; + repeat + CurBit := 0; + if Stretch then i2 := trunc(i / FactorX) else i2 := i; + Data := @ImageSource[i2]; + + repeat + {Obtains the palette index} + case Header.BitDepth of + 1: PaletteIndex := (Data^ shr (7-(I Mod 8))) and 1; + 2,4: PaletteIndex := (Data^ shr ((1-(I Mod 2))*4)) and $0F; + else PaletteIndex := Data^; + end; + + {Updates the image with the new pixel} + with ImageData[i] do + begin + TransValue := TransparencyChunk.PaletteValues[PaletteIndex]; + rgbRed := (255 + PaletteChunk.Item[PaletteIndex].rgbRed * + TransValue + rgbRed * (255 - TransValue)) shr 8; + rgbGreen := (255 + PaletteChunk.Item[PaletteIndex].rgbGreen * + TransValue + rgbGreen * (255 - TransValue)) shr 8; + rgbBlue := (255 + PaletteChunk.Item[PaletteIndex].rgbBlue * + TransValue + rgbBlue * (255 - TransValue)) shr 8; + end; + + {Move to next data} + inc(i); inc(CurBit, Header.BitmapInfo.bmiHeader.biBitCount); + until CurBit >= 8; + {Move to next source data} + //inc(Data); + until i >= Integer(W); + + {Move pointers} + Longint(ImageData) := Longint(ImageData) + BytesPerRowDest; + if Stretch then j2 := trunc(j / FactorY) else j2 := j; + Longint(ImageSource) := Longint(ImageSourceOrg) - BytesPerRowSrc * j2; + end + end {Palette images} + end {case Header.BitmapInfo.bmiHeader.biBitCount}; + + {Draws the new bitmap on the foreground} + BitBlt(DC, Rect.Left, Rect.Top, W, H, BufferDC, 0, 0, SRCCOPY); + + {Free bitmap} + SelectObject(BufferDC, OldBitmap); + DeleteObject(BufferBitmap); + DeleteDC(BufferDC); +end; + +{Draws the image into a canvas} +procedure TPngObject.Draw(ACanvas: TCanvas; const Rect: TRect); +var + Header: TChunkIHDR; +begin + {Quit in case there is no header, otherwise obtain it} + if Empty then Exit; + Header := Chunks.GetItem(0) as TChunkIHDR; + + {Copy the data to the canvas} + case Self.TransparencyMode of + {$IFDEF PartialTransparentDraw} + ptmPartial: + DrawPartialTrans(ACanvas{$IFDEF UseDelphi}.Handle{$ENDIF}, Rect); + {$ENDIF} + ptmBit: DrawTransparentBitmap(ACanvas{$IFDEF UseDelphi}.Handle{$ENDIF}, + Header.ImageData, Header.BitmapInfo.bmiHeader, + pBitmapInfo(@Header.BitmapInfo), Rect, + {$IFDEF UseDelphi}ColorToRGB({$ENDIF}TransparentColor) + {$IFDEF UseDelphi}){$ENDIF} + else + begin + SetStretchBltMode(ACanvas{$IFDEF UseDelphi}.Handle{$ENDIF}, COLORONCOLOR); + StretchDiBits(ACanvas{$IFDEF UseDelphi}.Handle{$ENDIF}, Rect.Left, + Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top, 0, 0, + Header.Width, Header.Height, Header.ImageData, + pBitmapInfo(@Header.BitmapInfo)^, DIB_RGB_COLORS, SRCCOPY) + end + end {case} +end; + +{Characters for the header} +const + PngHeader: Array[0..7] of Char = (#137, #80, #78, #71, #13, #10, #26, #10); + +{Loads the image from a stream of data} +procedure TPngObject.LoadFromStream(Stream: TStream); +var + Header : Array[0..7] of Char; + HasIDAT : Boolean; + + {Chunks reading} + ChunkCount : Cardinal; + ChunkLength: Cardinal; + ChunkName : TChunkName; +begin + {Initialize before start loading chunks} + ChunkCount := 0; + ClearChunks(); + {Reads the header} + Stream.Read(Header[0], 8); + + {Test if the header matches} + if Header <> PngHeader then + begin + RaiseError(EPNGInvalidFileHeader, EPNGInvalidFileHeaderText); + Exit; + end; + + + HasIDAT := FALSE; + Chunks.Count := 10; + + {Load chunks} + repeat + inc(ChunkCount); {Increment number of chunks} + if Chunks.Count < ChunkCount then {Resize the chunks list if needed} + Chunks.Count := Chunks.Count + 10; + + {Reads chunk length and invert since it is in network order} + {also checks the Read method return, if it returns 0, it} + {means that no bytes was readed, probably because it reached} + {the end of the file} + if Stream.Read(ChunkLength, 4) = 0 then + begin + {In case it found the end of the file here} + Chunks.Count := ChunkCount - 1; + RaiseError(EPNGUnexpectedEnd, EPNGUnexpectedEndText); + end; + + ChunkLength := ByteSwap(ChunkLength); + {Reads chunk name} + Stream.Read(Chunkname, 4); + + {Here we check if the first chunk is the Header which is necessary} + {to the file in order to be a valid Portable Network Graphics image} + if (ChunkCount = 1) and (ChunkName <> 'IHDR') then + begin + Chunks.Count := ChunkCount - 1; + RaiseError(EPNGIHDRNotFirst, EPNGIHDRNotFirstText); + exit; + end; + + {Has a previous IDAT} + if (HasIDAT and (ChunkName = 'IDAT')) or (ChunkName = 'cHRM') then + begin + dec(ChunkCount); + Stream.Seek(ChunkLength + 4, soFromCurrent); + Continue; + end; + {Tell it has an IDAT chunk} + if ChunkName = 'IDAT' then HasIDAT := TRUE; + + {Creates object for this chunk} + Chunks.SetItem(ChunkCount - 1, CreateClassChunk(Self, ChunkName)); + + {Check if the chunk is critical and unknown} + {$IFDEF ErrorOnUnknownCritical} + if (TChunk(Chunks.Item[ChunkCount - 1]).ClassType = TChunk) and + ((Byte(ChunkName[0]) AND $20) = 0) and (ChunkName <> '') then + begin + Chunks.Count := ChunkCount; + RaiseError(EPNGUnknownCriticalChunk, EPNGUnknownCriticalChunkText); + end; + {$ENDIF} + + {Loads it} + try if not TChunk(Chunks.Item[ChunkCount - 1]).LoadFromStream(Stream, + ChunkName, ChunkLength) then break; + except + Chunks.Count := ChunkCount; + raise; + end; + + {Terminates when it reaches the IEND chunk} + until (ChunkName = 'IEND'); + + {Resize the list to the appropriate size} + Chunks.Count := ChunkCount; + + {Check if there is data} + if not HasIDAT then + RaiseError(EPNGNoImageData, EPNGNoImageDataText); +end; + +{Changing height is not supported} +procedure TPngObject.SetHeight(Value: Integer); +begin + Resize(Width, Value) +end; + +{Changing width is not supported} +procedure TPngObject.SetWidth(Value: Integer); +begin + Resize(Value, Height) +end; + +{$IFDEF UseDelphi} +{Saves to clipboard format (thanks to Antoine Pottern)} +procedure TPNGObject.SaveToClipboardFormat(var AFormat: Word; + var AData: THandle; var APalette: HPalette); +begin + with TBitmap.Create do + try + Width := Self.Width; + Height := Self.Height; + Self.Draw(Canvas, Rect(0, 0, Width, Height)); + SaveToClipboardFormat(AFormat, AData, APalette); + finally + Free; + end {try} +end; + +{Loads data from clipboard} +procedure TPngObject.LoadFromClipboardFormat(AFormat: Word; + AData: THandle; APalette: HPalette); +begin + with TBitmap.Create do + try + LoadFromClipboardFormat(AFormat, AData, APalette); + Self.AssignHandle(Handle, False, 0); + finally + Free; + end {try} +end; + +{Returns if the image is transparent} +function TPngObject.GetTransparent: Boolean; +begin + Result := (TransparencyMode <> ptmNone); +end; + +{$ENDIF} + +{Saving the PNG image to a stream of data} +procedure TPngObject.SaveToStream(Stream: TStream); +var + j: Integer; +begin + {Reads the header} + Stream.Write(PNGHeader[0], 8); + {Write each chunk} + FOR j := 0 TO Chunks.Count - 1 DO + Chunks.Item[j].SaveToStream(Stream) +end; + +{Prepares the Header chunk} +procedure BuildHeader(Header: TChunkIHDR; Handle: HBitmap; Info: pBitmap); +var + DC: HDC; +begin + {Set width and height} + Header.Width := Info.bmWidth; + Header.Height := abs(Info.bmHeight); + {Set bit depth} + if Info.bmBitsPixel >= 16 then + Header.BitDepth := 8 else Header.BitDepth := Info.bmBitsPixel; + {Set color type} + if Info.bmBitsPixel >= 16 then + Header.ColorType := COLOR_RGB else Header.ColorType := COLOR_PALETTE; + {Set other info} + Header.CompressionMethod := 0; {deflate/inflate} + Header.InterlaceMethod := 0; {no interlace} + + {Prepares bitmap headers to hold data} + Header.PrepareImageData(); + {Copy image data} + DC := CreateCompatibleDC(0); + GetDIBits(DC, Handle, 0, Header.Height, Header.ImageData, + pBitmapInfo(@Header.BitmapInfo)^, DIB_RGB_COLORS); + + DeleteDC(DC); +end; + +{Loads the image from a resource} +procedure TPngObject.LoadFromResourceName(Instance: HInst; + const Name: String); +var + ResStream: TResourceStream; +begin + {Creates an especial stream to load from the resource} + try ResStream := TResourceStream.Create(Instance, Name, RT_RCDATA); + except RaiseError(EPNGCouldNotLoadResource, EPNGCouldNotLoadResourceText); + exit; end; + + {Loads the png image from the resource} + try + LoadFromStream(ResStream); + finally + ResStream.Free; + end; +end; + +{Loads the png from a resource ID} +procedure TPngObject.LoadFromResourceID(Instance: HInst; ResID: Integer); +begin + LoadFromResourceName(Instance, String(ResID)); +end; + +{Assigns this tpngobject to another object} +procedure TPngObject.AssignTo(Dest: TPersistent); +{$IFDEF UseDelphi} + function DetectPixelFormat: TPixelFormat; + begin + with Header do + begin + {Always use 24bits for partial transparency} + if TransparencyMode = ptmPartial then + DetectPixelFormat := pf24bit + else + case BitDepth of + {Only supported by COLOR_PALETTE} + 1: DetectPixelFormat := pf1bit; + 2, 4: DetectPixelFormat := pf4bit; + {8 may be palette or r, g, b values} + 8, 16: + case ColorType of + COLOR_RGB, COLOR_GRAYSCALE: DetectPixelFormat := pf24bit; + COLOR_PALETTE: DetectPixelFormat := pf8bit; + else raise Exception.Create(''); + end {case ColorFormat of} + else raise Exception.Create(''); + end {case BitDepth of} + end {with Header} + end; +var + TRNS: TChunkTRNS; +{$ENDIF} +begin + {If the destination is also a TPNGObject make it assign} + {this one} + if Dest is TPNGObject then + TPNGObject(Dest).AssignPNG(Self) + {$IFDEF UseDelphi} + {In case the destination is a bitmap} + else if (Dest is TBitmap) and HeaderPresent then + begin + {Copies the handle using CopyImage API} + TBitmap(Dest).PixelFormat := DetectPixelFormat; + TBitmap(Dest).Width := Width; + TBitmap(Dest).Height := Height; + TBitmap(Dest).Canvas.Draw(0, 0, Self); + + {Copy transparency mode} + if (TransparencyMode = ptmBit) then + begin + TRNS := Chunks.ItemFromClass(TChunkTRNS) as TChunkTRNS; + TBitmap(Dest).TransparentColor := TRNS.TransparentColor; + TBitmap(Dest).Transparent := True + end {if (TransparencyMode = ptmBit)} + + end + else + {Unknown destination kind} + inherited AssignTo(Dest); + {$ENDIF} +end; + +{Assigns from a bitmap object} +procedure TPngObject.AssignHandle(Handle: HBitmap; Transparent: Boolean; + TransparentColor: ColorRef); +var + BitmapInfo: Windows.TBitmap; + {Chunks} + Header: TChunkIHDR; + PLTE: TChunkPLTE; + IDAT: TChunkIDAT; + IEND: TChunkIEND; + TRNS: TChunkTRNS; + i: Integer; + palEntries : TMaxLogPalette; +begin + {Obtain bitmap info} + GetObject(Handle, SizeOf(BitmapInfo), @BitmapInfo); + + {Clear old chunks and prepare} + ClearChunks(); + + {Create the chunks} + Header := TChunkIHDR.Create(Self); + + {This method will fill the Header chunk with bitmap information} + {and copy the image data} + BuildHeader(Header, Handle, @BitmapInfo); + + if Header.HasPalette then PLTE := TChunkPLTE.Create(Self) else PLTE := nil; + if Transparent then TRNS := TChunkTRNS.Create(Self) else TRNS := nil; + IDAT := TChunkIDAT.Create(Self); + IEND := TChunkIEND.Create(Self); + + {Add chunks} + TPNGPointerList(Chunks).Add(Header); + if Header.HasPalette then TPNGPointerList(Chunks).Add(PLTE); + if Transparent then TPNGPointerList(Chunks).Add(TRNS); + TPNGPointerList(Chunks).Add(IDAT); + TPNGPointerList(Chunks).Add(IEND); + + {In case there is a image data, set the PLTE chunk fCount variable} + {to the actual number of palette colors which is 2^(Bits for each pixel)} + if Header.HasPalette then + begin + PLTE.fCount := 1 shl BitmapInfo.bmBitsPixel; + + {Create and set palette} + fillchar(palEntries, sizeof(palEntries), 0); + palEntries.palVersion := $300; + palEntries.palNumEntries := 1 shl BitmapInfo.bmBitsPixel; + for i := 0 to palEntries.palNumEntries - 1 do + begin + palEntries.palPalEntry[i].peRed := Header.BitmapInfo.bmiColors[i].rgbRed; + palEntries.palPalEntry[i].peGreen := Header.BitmapInfo.bmiColors[i].rgbGreen; + palEntries.palPalEntry[i].peBlue := Header.BitmapInfo.bmiColors[i].rgbBlue; + end; + DoSetPalette(CreatePalette(pLogPalette(@palEntries)^), false); + end; + + {In case it is a transparent bitmap, prepares it} + if Transparent then TRNS.TransparentColor := TransparentColor; +end; + +{Assigns from another PNG} +procedure TPngObject.AssignPNG(Source: TPNGObject); +var + J: Integer; +begin + {Copy properties} + InterlaceMethod := Source.InterlaceMethod; + MaxIdatSize := Source.MaxIdatSize; + CompressionLevel := Source.CompressionLevel; + Filters := Source.Filters; + + {Clear old chunks and prepare} + ClearChunks(); + Chunks.Count := Source.Chunks.Count; + {Create chunks and makes a copy from the source} + FOR J := 0 TO Chunks.Count - 1 DO + with Source.Chunks do + begin + Chunks.SetItem(J, TChunkClass(TChunk(Item[J]).ClassType).Create(Self)); + TChunk(Chunks.Item[J]).Assign(TChunk(Item[J])); + end {with}; +end; + +{Returns a alpha data scanline} +function TPngObject.GetAlphaScanline(const LineIndex: Integer): pByteArray; +begin + with Header do + if (ColorType = COLOR_RGBALPHA) or (ColorType = COLOR_GRAYSCALEALPHA) then + Longint(Result) := Longint(ImageAlpha) + (LineIndex * Longint(Width)) + else Result := nil; {In case the image does not use alpha information} +end; + +{$IFDEF Store16bits} +{Returns a png data extra scanline} +function TPngObject.GetExtraScanline(const LineIndex: Integer): Pointer; +begin + with Header do + Longint(Result) := (Longint(ExtraImageData) + ((Longint(Height) - 1) * + BytesPerRow)) - (LineIndex * BytesPerRow); +end; +{$ENDIF} + +{Returns a png data scanline} +function TPngObject.GetScanline(const LineIndex: Integer): Pointer; +begin + with Header do + Longint(Result) := (Longint(ImageData) + ((Longint(Height) - 1) * + BytesPerRow)) - (LineIndex * BytesPerRow); +end; + +{Initialize gamma table} +procedure TPngObject.InitializeGamma; +var + i: Integer; +begin + {Build gamma table as if there was no gamma} + FOR i := 0 to 255 do + begin + GammaTable[i] := i; + InverseGamma[i] := i; + end {for i} +end; + +{Returns the transparency mode used by this png} +function TPngObject.GetTransparencyMode: TPNGTransparencyMode; +var + TRNS: TChunkTRNS; +begin + with Header do + begin + Result := ptmNone; {Default result} + {Gets the TRNS chunk pointer} + TRNS := Chunks.ItemFromClass(TChunkTRNS) as TChunkTRNS; + + {Test depending on the color type} + case ColorType of + {This modes are always partial} + COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA: Result := ptmPartial; + {This modes support bit transparency} + COLOR_RGB, COLOR_GRAYSCALE: if TRNS <> nil then Result := ptmBit; + {Supports booth translucid and bit} + COLOR_PALETTE: + {A TRNS chunk must be present, otherwise it won't support transparency} + if TRNS <> nil then + if TRNS.BitTransparency then + Result := ptmBit else Result := ptmPartial + end {case} + + end {with Header} +end; + +{Add a text chunk} +procedure TPngObject.AddtEXt(const Keyword, Text: String); +var + TextChunk: TChunkTEXT; +begin + TextChunk := Chunks.Add(TChunkText) as TChunkTEXT; + TextChunk.Keyword := Keyword; + TextChunk.Text := Text; +end; + +{Add a text chunk} +procedure TPngObject.AddzTXt(const Keyword, Text: String); +var + TextChunk: TChunkzTXt; +begin + TextChunk := Chunks.Add(TChunkzTXt) as TChunkzTXt; + TextChunk.Keyword := Keyword; + TextChunk.Text := Text; +end; + +{Removes the image transparency} +procedure TPngObject.RemoveTransparency; +var + TRNS: TChunkTRNS; +begin + {Removes depending on the color type} + with Header do + case ColorType of + {Palette uses the TChunktRNS to store alpha} + COLOR_PALETTE: + begin + TRNS := Chunks.ItemFromClass(TChunkTRNS) as TChunkTRNS; + if TRNS <> nil then Chunks.RemoveChunk(TRNS) + end; + {Png allocates different memory space to hold alpha information} + {for these types} + COLOR_GRAYSCALEALPHA, COLOR_RGBALPHA: + begin + {Transform into the appropriate color type} + if ColorType = COLOR_GRAYSCALEALPHA then + ColorType := COLOR_GRAYSCALE + else ColorType := COLOR_RGB; + {Free the pointer data} + if ImageAlpha <> nil then FreeMem(ImageAlpha); + ImageAlpha := nil + end + end +end; + +{Generates alpha information} +procedure TPngObject.CreateAlpha; +var + TRNS: TChunkTRNS; +begin + {Generates depending on the color type} + with Header do + case ColorType of + {Png allocates different memory space to hold alpha information} + {for these types} + COLOR_GRAYSCALE, COLOR_RGB: + begin + {Transform into the appropriate color type} + if ColorType = COLOR_GRAYSCALE then + ColorType := COLOR_GRAYSCALEALPHA + else ColorType := COLOR_RGBALPHA; + {Allocates memory to hold alpha information} + GetMem(ImageAlpha, Integer(Width) * Integer(Height)); + FillChar(ImageAlpha^, Integer(Width) * Integer(Height), #255); + end; + {Palette uses the TChunktRNS to store alpha} + COLOR_PALETTE: + begin + {Gets/creates TRNS chunk} + if Chunks.ItemFromClass(TChunkTRNS) = nil then + TRNS := Chunks.Add(TChunkTRNS) as TChunkTRNS + else + TRNS := Chunks.ItemFromClass(TChunkTRNS) as TChunkTRNS; + + {Prepares the TRNS chunk} + with TRNS do + begin + ResizeData(256); + Fillchar(PaletteValues[0], 256, 255); + fDataSize := 1 shl Header.BitDepth; + fBitTransparency := False + end {with Chunks.Add}; + end; + end {case Header.ColorType} + +end; + +{Returns transparent color} +function TPngObject.GetTransparentColor: TColor; +var + TRNS: TChunkTRNS; +begin + TRNS := Chunks.ItemFromClass(TChunkTRNS) as TChunkTRNS; + {Reads the transparency chunk to get this info} + if Assigned(TRNS) then Result := TRNS.TransparentColor + else Result := 0 +end; + +{$OPTIMIZATION OFF} +procedure TPngObject.SetTransparentColor(const Value: TColor); +var + TRNS: TChunkTRNS; +begin + if HeaderPresent then + {Tests the ColorType} + case Header.ColorType of + {Not allowed for this modes} + COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA: Self.RaiseError( + EPNGCannotChangeTransparent, EPNGCannotChangeTransparentText); + {Allowed} + COLOR_PALETTE, COLOR_RGB, COLOR_GRAYSCALE: + begin + TRNS := Chunks.ItemFromClass(TChunkTRNS) as TChunkTRNS; + if not Assigned(TRNS) then TRNS := Chunks.Add(TChunkTRNS) as TChunkTRNS; + + {Sets the transparency value from TRNS chunk} + TRNS.TransparentColor := {$IFDEF UseDelphi}ColorToRGB({$ENDIF}Value + {$IFDEF UseDelphi}){$ENDIF} + end {COLOR_PALETTE, COLOR_RGB, COLOR_GRAYSCALE)} + end {case} +end; + +{Returns if header is present} +function TPngObject.HeaderPresent: Boolean; +begin + Result := ((Chunks.Count <> 0) and (Chunks.Item[0] is TChunkIHDR)) +end; + +{Returns pixel for png using palette and grayscale} +function GetByteArrayPixel(const png: TPngObject; const X, Y: Integer): TColor; +var + ByteData: Byte; + DataDepth: Byte; +begin + with png, Header do + begin + {Make sure the bitdepth is not greater than 8} + DataDepth := BitDepth; + if DataDepth > 8 then DataDepth := 8; + {Obtains the byte containing this pixel} + ByteData := pByteArray(png.Scanline[Y])^[X div (8 div DataDepth)]; + {Moves the bits we need to the right} + ByteData := (ByteData shr ((8 - DataDepth) - + (X mod (8 div DataDepth)) * DataDepth)); + {Discard the unwanted pixels} + ByteData:= ByteData and ($FF shr (8 - DataDepth)); + + {For palette mode map the palette entry and for grayscale convert and + returns the intensity} + case ColorType of + COLOR_PALETTE: + with TChunkPLTE(png.Chunks.ItemFromClass(TChunkPLTE)).Item[ByteData] do + Result := rgb(GammaTable[rgbRed], GammaTable[rgbGreen], + GammaTable[rgbBlue]); + COLOR_GRAYSCALE: + begin + if BitDepth = 1 + then ByteData := GammaTable[Byte(ByteData * 255)] + else ByteData := GammaTable[Byte(ByteData * ((1 shl DataDepth) + 1))]; + Result := rgb(ByteData, ByteData, ByteData); + end; + else Result := 0; + end {case}; + end {with} +end; + +{In case vcl units are not being used} +{$IFNDEF UseDelphi} +function ColorToRGB(const Color: TColor): COLORREF; +begin + Result := Color +end; +{$ENDIF} + +{Sets a pixel for grayscale and palette pngs} +procedure SetByteArrayPixel(const png: TPngObject; const X, Y: Integer; + const Value: TColor); +const + ClearFlag: Array[1..8] of Integer = (1, 3, 0, 15, 0, 0, 0, $FF); +var + ByteData: pByte; + DataDepth: Byte; + ValEntry: Byte; +begin + with png.Header do + begin + {Map into a palette entry} + ValEntry := GetNearestPaletteIndex(Png.Palette, ColorToRGB(Value)); + + {16 bits grayscale extra bits are discarted} + DataDepth := BitDepth; + if DataDepth > 8 then DataDepth := 8; + {Gets a pointer to the byte we intend to change} + ByteData := @pByteArray(png.Scanline[Y])^[X div (8 div DataDepth)]; + {Clears the old pixel data} + ByteData^ := ByteData^ and not (ClearFlag[DataDepth] shl ((8 - DataDepth) - + (X mod (8 div DataDepth)) * DataDepth)); + + {Setting the new pixel} + ByteData^ := ByteData^ or (ValEntry shl ((8 - DataDepth) - + (X mod (8 div DataDepth)) * DataDepth)); + end {with png.Header} +end; + +{Returns pixel when png uses RGB} +function GetRGBLinePixel(const png: TPngObject; + const X, Y: Integer): TColor; +begin + with pRGBLine(png.Scanline[Y])^[X] do + Result := RGB(rgbtRed, rgbtGreen, rgbtBlue) +end; + +{Sets pixel when png uses RGB} +procedure SetRGBLinePixel(const png: TPngObject; + const X, Y: Integer; Value: TColor); +begin + with pRGBLine(png.Scanline[Y])^[X] do + begin + rgbtRed := GetRValue(Value); + rgbtGreen := GetGValue(Value); + rgbtBlue := GetBValue(Value) + end +end; + +{Returns pixel when png uses grayscale} +function GetGrayLinePixel(const png: TPngObject; + const X, Y: Integer): TColor; +var + B: Byte; +begin + B := PByteArray(png.Scanline[Y])^[X]; + Result := RGB(B, B, B); +end; + +{Sets pixel when png uses grayscale} +procedure SetGrayLinePixel(const png: TPngObject; + const X, Y: Integer; Value: TColor); +begin + PByteArray(png.Scanline[Y])^[X] := GetRValue(Value); +end; + +{Resizes the PNG image} +procedure TPngObject.Resize(const CX, CY: Integer); + function Min(const A, B: Integer): Integer; + begin + if A < B then Result := A else Result := B; + end; +var + Header: TChunkIHDR; + Line, NewBytesPerRow: Integer; + NewHandle: HBitmap; + NewDC: HDC; + NewImageData: Pointer; + NewImageAlpha: Pointer; + NewImageExtra: Pointer; +begin + if (CX > 0) and (CY > 0) then + begin + {Gets some actual information} + Header := Self.Header; + + {Creates the new image} + NewDC := CreateCompatibleDC(Header.ImageDC); + Header.BitmapInfo.bmiHeader.biWidth := cx; + Header.BitmapInfo.bmiHeader.biHeight := cy; + NewHandle := CreateDIBSection(NewDC, pBitmapInfo(@Header.BitmapInfo)^, + DIB_RGB_COLORS, NewImageData, 0, 0); + SelectObject(NewDC, NewHandle); + {$IFDEF UseDelphi}Canvas.Handle := NewDC;{$ENDIF} + NewBytesPerRow := (((Header.BitmapInfo.bmiHeader.biBitCount * cx) + 31) + and not 31) div 8; + + {Copies the image data} + for Line := 0 to Min(CY - 1, Height - 1) do + CopyMemory(Ptr(Longint(NewImageData) + (Longint(CY) - 1) * + NewBytesPerRow - (Line * NewBytesPerRow)), Scanline[Line], + Min(NewBytesPerRow, Header.BytesPerRow)); + + {Build array for alpha information, if necessary} + if (Header.ColorType = COLOR_RGBALPHA) or + (Header.ColorType = COLOR_GRAYSCALEALPHA) then + begin + GetMem(NewImageAlpha, CX * CY); + Fillchar(NewImageAlpha^, CX * CY, 255); + for Line := 0 to Min(CY - 1, Height - 1) do + CopyMemory(Ptr(Longint(NewImageAlpha) + (Line * CX)), + AlphaScanline[Line], Min(CX, Width)); + FreeMem(Header.ImageAlpha); + Header.ImageAlpha := NewImageAlpha; + end; + + {$IFDEF Store16bits} + if (Header.BitDepth = 16) then + begin + GetMem(NewImageExtra, CX * CY); + Fillchar(NewImageExtra^, CX * CY, 0); + for Line := 0 to Min(CY - 1, Height - 1) do + CopyMemory(Ptr(Longint(NewImageExtra) + (Line * CX)), + ExtraScanline[Line], Min(CX, Width)); + FreeMem(Header.ExtraImageData); + Header.ExtraImageData := NewImageExtra; + end; + {$ENDIF} + + {Deletes the old image} + DeleteObject(Header.ImageHandle); + DeleteDC(Header.ImageDC); + + {Prepares the header to get the new image} + Header.BytesPerRow := NewBytesPerRow; + Header.IHDRData.Width := CX; + Header.IHDRData.Height := CY; + Header.ImageData := NewImageData; + + {Replaces with the new image} + Header.ImageHandle := NewHandle; + Header.ImageDC := NewDC; + end + else + {The new size provided is invalid} + RaiseError(EPNGInvalidNewSize, EInvalidNewSize) + +end; + +{Sets a pixel} +procedure TPngObject.SetPixels(const X, Y: Integer; const Value: TColor); +begin + if ((X >= 0) and (X <= Width - 1)) and + ((Y >= 0) and (Y <= Height - 1)) then + with Header do + begin + if ColorType in [COLOR_GRAYSCALE, COLOR_PALETTE] then + SetByteArrayPixel(Self, X, Y, Value) + else if ColorType in [COLOR_GRAYSCALEALPHA] then + SetGrayLinePixel(Self, X, Y, Value) + else + SetRGBLinePixel(Self, X, Y, Value) + end {with} +end; + + +{Returns a pixel} +function TPngObject.GetPixels(const X, Y: Integer): TColor; +begin + if ((X >= 0) and (X <= Width - 1)) and + ((Y >= 0) and (Y <= Height - 1)) then + with Header do + begin + if ColorType in [COLOR_GRAYSCALE, COLOR_PALETTE] then + Result := GetByteArrayPixel(Self, X, Y) + else if ColorType in [COLOR_GRAYSCALEALPHA] then + Result := GetGrayLinePixel(Self, X, Y) + else + Result := GetRGBLinePixel(Self, X, Y) + end {with} + else Result := 0 +end; + +{Returns the image palette} +function TPngObject.GetPalette: HPALETTE; +begin + Result := Header.ImagePalette; +end; + +{Assigns from another TChunk} +procedure TChunkpHYs.Assign(Source: TChunk); +begin + fPPUnitY := TChunkpHYs(Source).fPPUnitY; + fPPUnitX := TChunkpHYs(Source).fPPUnitX; + fUnit := TChunkpHYs(Source).fUnit; +end; + +{Loads the chunk from a stream} +function TChunkpHYs.LoadFromStream(Stream: TStream; const ChunkName: TChunkName; + Size: Integer): Boolean; +begin + {Let ancestor load the data} + Result := inherited LoadFromStream(Stream, ChunkName, Size); + if not Result or (Size <> 9) then exit; {Size must be 9} + + {Reads data} + fPPUnitX := ByteSwap(pCardinal(Longint(Data))^); + fPPUnitY := ByteSwap(pCardinal(Longint(Data) + 4)^); + fUnit := pUnitType(Longint(Data) + 8)^; +end; + +{Saves the chunk to a stream} +function TChunkpHYs.SaveToStream(Stream: TStream): Boolean; +begin + {Update data} + ResizeData(9); {Make sure the size is 9} + pCardinal(Data)^ := ByteSwap(fPPUnitX); + pCardinal(Longint(Data) + 4)^ := ByteSwap(fPPUnitY); + pUnitType(Longint(Data) + 8)^ := fUnit; + + {Let inherited save data} + Result := inherited SaveToStream(Stream); +end; + +procedure TPngObject.DoSetPalette(Value: HPALETTE; const UpdateColors: boolean); +begin + if (Header.HasPalette) then + begin + {Update the palette entries} + if UpdateColors then + Header.PaletteToDIB(Value); + + {Resize the new palette} + SelectPalette(Header.ImageDC, Value, False); + RealizePalette(Header.ImageDC); + + {Replaces} + DeleteObject(Header.ImagePalette); + Header.ImagePalette := Value; + end +end; + +{Set palette based on a windows palette handle} +procedure TPngObject.SetPalette(Value: HPALETTE); +begin + DoSetPalette(Value, true); +end; + +{Returns the library version} +function TPNGObject.GetLibraryVersion: String; +begin + Result := LibraryVersion +end; + +initialization + {Initialize} + ChunkClasses := nil; + {crc table has not being computed yet} + crc_table_computed := FALSE; + {Register the necessary chunks for png} + RegisterCommonChunks; + {Registers TPNGObject to use with TPicture} + {$IFDEF UseDelphi}{$IFDEF RegisterGraphic} + TPicture.RegisterFileFormat('PNG', 'Portable Network Graphics', TPNGObject); + {$ENDIF}{$ENDIF} +finalization + {$IFDEF UseDelphi}{$IFDEF RegisterGraphic} + TPicture.UnregisterGraphicClass(TPNGObject); + {$ENDIF}{$ENDIF} + {Free chunk classes} + FreeChunkClassList; +end. + + diff --git a/System/pnglang.pas b/System/pnglang.pas new file mode 100644 index 0000000..c4a5fb8 --- /dev/null +++ b/System/pnglang.pas @@ -0,0 +1,355 @@ +{Portable Network Graphics Delphi Language Info (24 July 2002)} + +{Feel free to change the text bellow to adapt to your language} +{Also if you have a translation to other languages and want to} +{share it, send me: gubadaud@terra.com.br } +unit pnglang; + +interface + +{$DEFINE English} +{.$DEFINE Polish} +{.$DEFINE Portuguese} +{.$DEFINE German} +{.$DEFINE French} +{.$DEFINE Slovenian} + +{Language strings for english} +resourcestring + {$IFDEF Polish} + EPngInvalidCRCText = 'Ten obraz "Portable Network Graphics" jest nieprawid³owy ' + + 'poniewa¿ zawiera on nieprawid³owe czêœci danych (b³¹d crc)'; + EPNGInvalidIHDRText = 'Obraz "Portable Network Graphics" nie mo¿e zostaæ ' + + 'wgrany poniewa¿ jedna z czêœci danych (ihdr) mo¿e byæ uszkodzona'; + EPNGMissingMultipleIDATText = 'Obraz "Portable Network Graphics" jest ' + + 'nieprawid³owy poniewa¿ brakuje w nim czêœci obrazu.'; + EPNGZLIBErrorText = 'Nie mo¿na zdekompresowaæ obrazu poniewa¿ zawiera ' + + 'b³êdnie zkompresowane dane.'#13#10 + ' Opis b³êdu: '; + EPNGInvalidPaletteText = 'Obraz "Portable Network Graphics" zawiera ' + + 'niew³aœciw¹ paletê.'; + EPNGInvalidFileHeaderText = 'Plik który jest odczytywany jest nieprawid³owym '+ + 'obrazem "Portable Network Graphics" poniewa¿ zawiera nieprawid³owy nag³ówek.' + + ' Plik mo¿ê byæ uszkodzony, spróbuj pobraæ go ponownie.'; + EPNGIHDRNotFirstText = 'Obraz "Portable Network Graphics" nie jest ' + + 'obs³ugiwany lub mo¿e byæ niew³aœciwy.'#13#10 + '(stopka IHDR nie jest pierwsza)'; + EPNGNotExistsText = 'Plik png nie mo¿e zostaæ wgrany poniewa¿ nie ' + + 'istnieje.'; + EPNGSizeExceedsText = 'Obraz "Portable Network Graphics" nie jest ' + + 'obs³ugiwany poniewa¿ jego szerokoœæ lub wysokoœæ przekracza maksimum ' + + 'rozmiaru, który wynosi 65535 pikseli d³ugoœci.'; + EPNGUnknownPalEntryText = 'Nie znaleziono wpisów palety.'; + EPNGMissingPaletteText = 'Obraz "Portable Network Graphics" nie mo¿e zostaæ ' + + 'wgrany poniewa¿ u¿ywa tabeli kolorów której brakuje.'; + EPNGUnknownCriticalChunkText = 'Obraz "Portable Network Graphics" ' + + 'zawiera nieznan¹ krytyczn¹ czêœæ która nie mo¿e zostaæ odkodowana.'; + EPNGUnknownCompressionText = 'Obraz "Portable Network Graphics" jest ' + + 'skompresowany nieznanym schemat który nie mo¿e zostaæ odszyfrowany.'; + EPNGUnknownInterlaceText = 'Obraz "Portable Network Graphics" u¿ywa ' + + 'nie znany schamat przeplatania który nie mo¿e zostaæ odszyfrowany.'; + EPNGCannotAssignChunkText = 'Stopka mysi byæ kompatybilna aby zosta³a wyznaczona.'; + EPNGUnexpectedEndText = 'Obraz "Portable Network Graphics" jest nieprawid³owy ' + + 'poniewa¿ dekoder znalaz³ niespodziewanie koniec pliku.'; + EPNGNoImageDataText = 'Obraz "Portable Network Graphics" nie zawiera' + + 'danych.'; + EPNGCannotAddChunkText = 'Program próbuje dodaæ krytyczn¹ ' + + 'stopkê do aktualnego obrazu co jest niedozwolone.'; + EPNGCannotAddInvalidImageText = 'Nie mo¿na dodaæ nowej stopki ' + + 'poniewa¿ aktualny obraz jest nieprawid³owy.'; + EPNGCouldNotLoadResourceText = 'Obraz png nie mo¿e zostaæ za³adowany z' + + 'zasobów o podanym ID.'; + EPNGOutMemoryText = 'Niektóre operacje nie mog¹ zostaæ zrealizowane poniewa¿ ' + + 'systemowi brakuje zasobów. Zamknij kilka okien i spróbuj ponownie.'; + EPNGCannotChangeTransparentText = 'Ustawienie bitu przezroczystego koloru jest ' + + 'zabronione dla obrazów png zawieraj¹cych wartoœæ alpha dla ka¿dego piksela ' + + '(COLOR_RGBALPHA i COLOR_GRAYSCALEALPHA)'; + EPNGHeaderNotPresentText = 'Ta operacja jest niedozwolona poniewa¿ ' + + 'aktualny obraz zawiera niew³aœciwy nag³ówek.'; + EInvalidNewSize = 'The new size provided for image resizing is invalid.'; + EInvalidSpec = 'The "Portable Network Graphics" could not be created ' + + 'because invalid image type parameters have being provided.'; + {$ENDIF} + + {$IFDEF English} + EPngInvalidCRCText = 'This "Portable Network Graphics" image is not valid ' + + 'because it contains invalid pieces of data (crc error)'; + EPNGInvalidIHDRText = 'The "Portable Network Graphics" image could not be ' + + 'loaded because one of its main piece of data (ihdr) might be corrupted'; + EPNGMissingMultipleIDATText = 'This "Portable Network Graphics" image is ' + + 'invalid because it has missing image parts.'; + EPNGZLIBErrorText = 'Could not decompress the image because it contains ' + + 'invalid compressed data.'#13#10 + ' Description: '; + EPNGInvalidPaletteText = 'The "Portable Network Graphics" image contains ' + + 'an invalid palette.'; + EPNGInvalidFileHeaderText = 'The file being readed is not a valid '+ + '"Portable Network Graphics" image because it contains an invalid header.' + + ' This file may be corruped, try obtaining it again.'; + EPNGIHDRNotFirstText = 'This "Portable Network Graphics" image is not ' + + 'supported or it might be invalid.'#13#10 + '(IHDR chunk is not the first)'; + EPNGNotExistsText = 'The png file could not be loaded because it does not ' + + 'exists.'; + EPNGSizeExceedsText = 'This "Portable Network Graphics" image is not ' + + 'supported because either it''s width or height exceeds the maximum ' + + 'size, which is 65535 pixels length.'; + EPNGUnknownPalEntryText = 'There is no such palette entry.'; + EPNGMissingPaletteText = 'This "Portable Network Graphics" could not be ' + + 'loaded because it uses a color table which is missing.'; + EPNGUnknownCriticalChunkText = 'This "Portable Network Graphics" image ' + + 'contains an unknown critical part which could not be decoded.'; + EPNGUnknownCompressionText = 'This "Portable Network Graphics" image is ' + + 'encoded with an unknown compression scheme which could not be decoded.'; + EPNGUnknownInterlaceText = 'This "Portable Network Graphics" image uses ' + + 'an unknown interlace scheme which could not be decoded.'; + EPNGCannotAssignChunkText = 'The chunks must be compatible to be assigned.'; + EPNGUnexpectedEndText = 'This "Portable Network Graphics" image is invalid ' + + 'because the decoder found an unexpected end of the file.'; + EPNGNoImageDataText = 'This "Portable Network Graphics" image contains no ' + + 'data.'; + EPNGCannotAddChunkText = 'The program tried to add a existent critical ' + + 'chunk to the current image which is not allowed.'; + EPNGCannotAddInvalidImageText = 'It''s not allowed to add a new chunk ' + + 'because the current image is invalid.'; + EPNGCouldNotLoadResourceText = 'The png image could not be loaded from the ' + + 'resource ID.'; + EPNGOutMemoryText = 'Some operation could not be performed because the ' + + 'system is out of resources. Close some windows and try again.'; + EPNGCannotChangeTransparentText = 'Setting bit transparency color is not ' + + 'allowed for png images containing alpha value for each pixel ' + + '(COLOR_RGBALPHA and COLOR_GRAYSCALEALPHA)'; + EPNGHeaderNotPresentText = 'This operation is not valid because the ' + + 'current image contains no valid header.'; + EInvalidNewSize = 'The new size provided for image resizing is invalid.'; + EInvalidSpec = 'The "Portable Network Graphics" could not be created ' + + 'because invalid image type parameters have being provided.'; + {$ENDIF} + {$IFDEF Portuguese} + EPngInvalidCRCText = 'Essa imagem "Portable Network Graphics" não é válida ' + + 'porque contém chunks inválidos de dados (erro crc)'; + EPNGInvalidIHDRText = 'A imagem "Portable Network Graphics" não pode ser ' + + 'carregada porque um dos seus chunks importantes (ihdr) pode estar '+ + 'inválido'; + EPNGMissingMultipleIDATText = 'Essa imagem "Portable Network Graphics" é ' + + 'inválida porque tem chunks de dados faltando.'; + EPNGZLIBErrorText = 'Não foi possível descomprimir os dados da imagem ' + + 'porque ela contém dados inválidos.'#13#10 + ' Descrição: '; + EPNGInvalidPaletteText = 'A imagem "Portable Network Graphics" contém ' + + 'uma paleta inválida.'; + EPNGInvalidFileHeaderText = 'O arquivo sendo lido não é uma imagem '+ + '"Portable Network Graphics" válida porque contém um cabeçalho inválido.' + + ' O arquivo pode estar corrompida, tente obter ela novamente.'; + EPNGIHDRNotFirstText = 'Essa imagem "Portable Network Graphics" não é ' + + 'suportada ou pode ser inválida.'#13#10 + '(O chunk IHDR não é o ' + + 'primeiro)'; + EPNGNotExistsText = 'A imagem png não pode ser carregada porque ela não ' + + 'existe.'; + EPNGSizeExceedsText = 'Essa imagem "Portable Network Graphics" não é ' + + 'suportada porque a largura ou a altura ultrapassam o tamanho máximo, ' + + 'que é de 65535 pixels de diâmetro.'; + EPNGUnknownPalEntryText = 'Não existe essa entrada de paleta.'; + EPNGMissingPaletteText = 'Essa imagem "Portable Network Graphics" não pode ' + + 'ser carregada porque usa uma paleta que está faltando.'; + EPNGUnknownCriticalChunkText = 'Essa imagem "Portable Network Graphics" ' + + 'contém um chunk crítico desconheçido que não pode ser decodificado.'; + EPNGUnknownCompressionText = 'Essa imagem "Portable Network Graphics" está ' + + 'codificada com um esquema de compressão desconheçido e não pode ser ' + + 'decodificada.'; + EPNGUnknownInterlaceText = 'Essa imagem "Portable Network Graphics" usa um ' + + 'um esquema de interlace que não pode ser decodificado.'; + EPNGCannotAssignChunkText = 'Os chunk devem ser compatíveis para serem ' + + 'copiados.'; + EPNGUnexpectedEndText = 'Essa imagem "Portable Network Graphics" é ' + + 'inválida porque o decodificador encontrou um fim inesperado.'; + EPNGNoImageDataText = 'Essa imagem "Portable Network Graphics" não contém ' + + 'dados.'; + EPNGCannotAddChunkText = 'O programa tentou adicionar um chunk crítico ' + + 'já existente para a imagem atual, oque não é permitido.'; + EPNGCannotAddInvalidImageText = 'Não é permitido adicionar um chunk novo ' + + 'porque a imagem atual é inválida.'; + EPNGCouldNotLoadResourceText = 'A imagem png não pode ser carregada apartir' + + ' do resource.'; + EPNGOutMemoryText = 'Uma operação não pode ser completada porque o sistema ' + + 'está sem recursos. Fecha algumas janelas e tente novamente.'; + EPNGCannotChangeTransparentText = 'Definir transparência booleana não é ' + + 'permitido para imagens png contendo informação alpha para cada pixel ' + + '(COLOR_RGBALPHA e COLOR_GRAYSCALEALPHA)'; + EPNGHeaderNotPresentText = 'Essa operação não é válida porque a ' + + 'imagem atual não contém um cabeçalho válido.'; + EInvalidNewSize = 'O novo tamanho fornecido para o redimensionamento de ' + + 'imagem é inválido.'; + EInvalidSpec = 'A imagem "Portable Network Graphics" não pode ser criada ' + + 'porque parâmetros de tipo de imagem inválidos foram usados.'; + {$ENDIF} + {Language strings for German} + {$IFDEF German} + EPngInvalidCRCText = 'Dieses "Portable Network Graphics" Bild ist ' + + 'ungültig, weil Teile der Daten fehlerhaft sind (CRC-Fehler)'; + EPNGInvalidIHDRText = 'Dieses "Portable Network Graphics" Bild konnte ' + + 'nicht geladen werden, weil wahrscheinlich einer der Hauptdatenbreiche ' + + '(IHDR) beschädigt ist'; + EPNGMissingMultipleIDATText = 'Dieses "Portable Network Graphics" Bild ' + + 'ist ungültig, weil Grafikdaten fehlen.'; + EPNGZLIBErrorText = 'Die Grafik konnte nicht entpackt werden, weil Teile der ' + + 'komprimierten Daten fehlerhaft sind.'#13#10 + ' Beschreibung: '; + EPNGInvalidPaletteText = 'Das "Portable Network Graphics" Bild enthält ' + + 'eine ungültige Palette.'; + EPNGInvalidFileHeaderText = 'Die Datei, die gelesen wird, ist kein ' + + 'gültiges "Portable Network Graphics" Bild, da es keinen gültigen ' + + 'Header enthält. Die Datei könnte beschädigt sein, versuchen Sie, ' + + 'eine neue Kopie zu bekommen.'; + EPNGIHDRNotFirstText = 'Dieses "Portable Network Graphics" Bild wird ' + + 'nicht unterstützt oder ist ungültig.'#13#10 + + '(Der IHDR-Abschnitt ist nicht der erste Abschnitt in der Datei).'; + EPNGNotExistsText = 'Die PNG Datei konnte nicht geladen werden, da sie ' + + 'nicht existiert.'; + EPNGSizeExceedsText = 'Dieses "Portable Network Graphics" Bild wird nicht ' + + 'unterstützt, weil entweder seine Breite oder seine Höhe das Maximum von ' + + '65535 Pixeln überschreitet.'; + EPNGUnknownPalEntryText = 'Es gibt keinen solchen Palettenwert.'; + EPNGMissingPaletteText = 'Dieses "Portable Network Graphics" Bild konnte ' + + 'nicht geladen werden, weil die benötigte Farbtabelle fehlt.'; + EPNGUnknownCriticalChunkText = 'Dieses "Portable Network Graphics" Bild ' + + 'enhält einen unbekannten aber notwendigen Teil, welcher nicht entschlüsselt ' + + 'werden kann.'; + EPNGUnknownCompressionText = 'Dieses "Portable Network Graphics" Bild ' + + 'wurde mit einem unbekannten Komprimierungsalgorithmus kodiert, welcher ' + + 'nicht entschlüsselt werden kann.'; + EPNGUnknownInterlaceText = 'Dieses "Portable Network Graphics" Bild ' + + 'benutzt ein unbekanntes Interlace-Schema, welches nicht entschlüsselt ' + + 'werden kann.'; + EPNGCannotAssignChunkText = 'Die Abschnitte müssen kompatibel sein, damit ' + + 'sie zugewiesen werden können.'; + EPNGUnexpectedEndText = 'Dieses "Portable Network Graphics" Bild ist ' + + 'ungültig: Der Dekoder ist unerwartete auf das Ende der Datei gestoßen.'; + EPNGNoImageDataText = 'Dieses "Portable Network Graphics" Bild enthält ' + + 'keine Daten.'; + EPNGCannotAddChunkText = 'Das Programm versucht einen existierenden und ' + + 'notwendigen Abschnitt zum aktuellen Bild hinzuzufügen. Dies ist nicht ' + + 'zulässig.'; + EPNGCannotAddInvalidImageText = 'Es ist nicht zulässig, einem ungültigen ' + + 'Bild einen neuen Abschnitt hinzuzufügen.'; + EPNGCouldNotLoadResourceText = 'Das PNG Bild konnte nicht aus den ' + + 'Resourcendaten geladen werden.'; + EPNGOutMemoryText = 'Es stehen nicht genügend Resourcen im System zur ' + + 'Verfügung, um die Operation auszuführen. Schließen Sie einige Fenster '+ + 'und versuchen Sie es erneut.'; + EPNGCannotChangeTransparentText = 'Das Setzen der Bit-' + + 'Transparent-Farbe ist für PNG-Images die Alpha-Werte für jedes ' + + 'Pixel enthalten (COLOR_RGBALPHA und COLOR_GRAYSCALEALPHA) nicht ' + + 'zulässig'; + EPNGHeaderNotPresentText = 'Die Datei, die gelesen wird, ist kein ' + + 'gültiges "Portable Network Graphics" Bild, da es keinen gültigen ' + + 'Header enthält.'; + EInvalidNewSize = 'The new size provided for image resizing is invalid.'; + EInvalidSpec = 'The "Portable Network Graphics" could not be created ' + + 'because invalid image type parameters have being provided.'; + {$ENDIF} + {Language strings for French} + {$IFDEF French} + EPngInvalidCRCText = 'Cette image "Portable Network Graphics" n''est pas valide ' + + 'car elle contient des données invalides (erreur crc)'; + EPNGInvalidIHDRText = 'Cette image "Portable Network Graphics" n''a pu être ' + + 'chargée car l''une de ses principale donnée (ihdr) doit être corrompue'; + EPNGMissingMultipleIDATText = 'Cette image "Portable Network Graphics" est ' + + 'invalide car elle contient des parties d''image manquantes.'; + EPNGZLIBErrorText = 'Impossible de décompresser l''image car elle contient ' + + 'des données compressées invalides.'#13#10 + ' Description: '; + EPNGInvalidPaletteText = 'L''image "Portable Network Graphics" contient ' + + 'une palette invalide.'; + EPNGInvalidFileHeaderText = 'Le fichier actuellement lu est une image '+ + '"Portable Network Graphics" invalide car elle contient un en-tête invalide.' + + ' Ce fichier doit être corrompu, essayer de l''obtenir à nouveau.'; + EPNGIHDRNotFirstText = 'Cette image "Portable Network Graphics" n''est pas ' + + 'supportée ou doit être invalide.'#13#10 + '(la partie IHDR n''est pas la première)'; + EPNGNotExistsText = 'Le fichier png n''a pu être chargé car il n''éxiste pas.'; + EPNGSizeExceedsText = 'Cette image "Portable Network Graphics" n''est pas supportée ' + + 'car sa longueur ou sa largeur excède la taille maximale, qui est de 65535 pixels.'; + EPNGUnknownPalEntryText = 'Il n''y a aucune entrée pour cette palette.'; + EPNGMissingPaletteText = 'Cette image "Portable Network Graphics" n''a pu être ' + + 'chargée car elle utilise une table de couleur manquante.'; + EPNGUnknownCriticalChunkText = 'Cette image "Portable Network Graphics" ' + + 'contient une partie critique inconnue qui n'' pu être décodée.'; + EPNGUnknownCompressionText = 'Cette image "Portable Network Graphics" est ' + + 'encodée à l''aide d''un schémas de compression inconnu qui ne peut être décodé.'; + EPNGUnknownInterlaceText = 'Cette image "Portable Network Graphics" utilise ' + + 'un schémas d''entrelacement inconnu qui ne peut être décodé.'; + EPNGCannotAssignChunkText = 'Ce morceau doit être compatible pour être assigné.'; + EPNGUnexpectedEndText = 'Cette image "Portable Network Graphics" est invalide ' + + 'car le decodeur est arrivé à une fin de fichier non attendue.'; + EPNGNoImageDataText = 'Cette image "Portable Network Graphics" ne contient pas de ' + + 'données.'; + EPNGCannotAddChunkText = 'Le programme a essayé d''ajouter un morceau critique existant ' + + 'à l''image actuelle, ce qui n''est pas autorisé.'; + EPNGCannotAddInvalidImageText = 'Il n''est pas permis d''ajouter un nouveau morceau ' + + 'car l''image actuelle est invalide.'; + EPNGCouldNotLoadResourceText = 'L''image png n''a pu être chargée depuis ' + + 'l''ID ressource.'; + EPNGOutMemoryText = 'Certaines opérations n''ont pu être effectuée car le ' + + 'système n''a plus de ressources. Fermez quelques fenêtres et essayez à nouveau.'; + EPNGCannotChangeTransparentText = 'Définir le bit de transparence n''est pas ' + + 'permis pour des images png qui contiennent une valeur alpha pour chaque pixel ' + + '(COLOR_RGBALPHA et COLOR_GRAYSCALEALPHA)'; + EPNGHeaderNotPresentText = 'Cette opération n''est pas valide car l''image ' + + 'actuelle ne contient pas de header valide.'; + EPNGAlphaNotSupportedText = 'Le type de couleur de l''image "Portable Network Graphics" actuelle ' + + 'contient déjà des informations alpha ou il ne peut être converti.'; + EInvalidNewSize = 'The new size provided for image resizing is invalid.'; + EInvalidSpec = 'The "Portable Network Graphics" could not be created ' + + 'because invalid image type parameters have being provided.'; + {$ENDIF} + {Language strings for slovenian} + {$IFDEF Slovenian} + EPngInvalidCRCText = 'Ta "Portable Network Graphics" slika je neveljavna, ' + + 'ker vsebuje neveljavne dele podatkov (CRC napaka).'; + EPNGInvalidIHDRText = 'Slike "Portable Network Graphics" ni bilo možno ' + + 'naložiti, ker je eden od glavnih delov podatkov (IHDR) verjetno pokvarjen.'; + EPNGMissingMultipleIDATText = 'Ta "Portable Network Graphics" slika je ' + + 'naveljavna, ker manjkajo deli slike.'; + EPNGZLIBErrorText = 'Ne morem raztegniti slike, ker vsebuje ' + + 'neveljavne stisnjene podatke.'#13#10 + ' Opis: '; + EPNGInvalidPaletteText = 'Slika "Portable Network Graphics" vsebuje ' + + 'neveljavno barvno paleto.'; + EPNGInvalidFileHeaderText = 'Datoteka za branje ni veljavna '+ + '"Portable Network Graphics" slika, ker vsebuje neveljavno glavo.' + + ' Datoteka je verjetno pokvarjena, poskusite jo ponovno naložiti.'; + EPNGIHDRNotFirstText = 'Ta "Portable Network Graphics" slika ni ' + + 'podprta ali pa je neveljavna.'#13#10 + '(IHDR del datoteke ni prvi).'; + EPNGNotExistsText = 'Ne morem naložiti png datoteke, ker ta ne ' + + 'obstaja.'; + EPNGSizeExceedsText = 'Ta "Portable Network Graphics" slika ni ' + + 'podprta, ker ali njena širina ali višina presega najvecjo možno vrednost ' + + '65535 pik.'; + EPNGUnknownPalEntryText = 'Slika nima vnešene take barvne palete.'; + EPNGMissingPaletteText = 'Te "Portable Network Graphics" ne morem ' + + 'naložiti, ker uporablja manjkajoco barvno paleto.'; + EPNGUnknownCriticalChunkText = 'Ta "Portable Network Graphics" slika ' + + 'vsebuje neznan kriticni del podatkov, ki ga ne morem prebrati.'; + EPNGUnknownCompressionText = 'Ta "Portable Network Graphics" slika je ' + + 'kodirana z neznano kompresijsko shemo, ki je ne morem prebrati.'; + EPNGUnknownInterlaceText = 'Ta "Portable Network Graphics" slika uporablja ' + + 'neznano shemo za preliv, ki je ne morem prebrati.'; + EPNGCannotAssignChunkText = Košcki morajo biti med seboj kompatibilni za prireditev vrednosti.'; + EPNGUnexpectedEndText = 'Ta "Portable Network Graphics" slika je neveljavna, ' + + 'ker je bralnik prišel do nepricakovanega konca datoteke.'; + EPNGNoImageDataText = 'Ta "Portable Network Graphics" ne vsebuje nobenih ' + + 'podatkov.'; + EPNGCannotAddChunkText = 'Program je poskusil dodati obstojeci kriticni ' + + 'kos podatkov k trenutni sliki, kar ni dovoljeno.'; + EPNGCannotAddInvalidImageText = 'Ni dovoljeno dodati nov kos podatkov, ' + + 'ker trenutna slika ni veljavna.'; + EPNGCouldNotLoadResourceText = 'Ne morem naložiti png slike iz ' + + 'skladišca.'; + EPNGOutMemoryText = 'Ne morem izvesti operacije, ker je ' + + 'sistem ostal brez resorjev. Zaprite nekaj oken in poskusite znova.'; + EPNGCannotChangeTransparentText = 'Ni dovoljeno nastaviti prosojnosti posamezne barve ' + + 'za png slike, ki vsebujejo alfa prosojno vrednost za vsako piko ' + + '(COLOR_RGBALPHA and COLOR_GRAYSCALEALPHA)'; + EPNGHeaderNotPresentText = 'Ta operacija ni veljavna, ker ' + + 'izbrana slika ne vsebuje veljavne glave.'; + EInvalidNewSize = 'The new size provided for image resizing is invalid.'; + EInvalidSpec = 'The "Portable Network Graphics" could not be created ' + + 'because invalid image type parameters have being provided.'; + {$ENDIF} + + +implementation + +end. diff --git a/System/sdStringTable.pas b/System/sdStringTable.pas new file mode 100644 index 0000000..dd42fb6 --- /dev/null +++ b/System/sdStringTable.pas @@ -0,0 +1,633 @@ +{ unit sdStringTable + + Author: Nils Haeck M.Sc. (n.haeck@simdesign.nl) + Original Date: 28 May 2007 + Version: 1.1 + Copyright (c) 2007 - 2010 Simdesign BV + + It is NOT allowed under ANY circumstances to publish or copy this code + without accepting the license conditions in accompanying LICENSE.txt + first! + + This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF + ANY KIND, either express or implied. + + Please visit http://www.simdesign.nl/xml.html for more information. +} +unit sdStringTable; + +interface + +{$i NativeXml.inc} + +uses + Classes, SysUtils, Contnrs; + +type + + // A record describing a string by its first position and length (Count) + TsdStringRec = record + First: Pbyte; + Count: integer; + end; + + // A string reference item used in string reference lists (do not use directly) + TsdRefString = class + private + FID: integer; + FFrequency: integer; + FFirst: Pbyte; + FCharCount: integer; + protected + procedure SetString(const SR: TsdStringRec); + function CompareToSR(const SR: TsdStringRec): integer; + function StringRec: TsdStringRec; + public + destructor Destroy; override; + function AsString: UTF8String; + property CharCount: integer read FCharCount; + property Frequency: integer read FFrequency; + end; + + // A list of string reference items (do not use directly) + TsdRefStringList = class(TObjectList) + private + function GetItems(Index: integer): TsdRefString; + protected + // Assumes list is sorted by StringID + function IndexOfID(AID: integer; var Index: integer): boolean; + // Assumes list is sorted by string rec + function IndexOfSR(const AStringRec: TsdStringRec; var Index: integer): boolean; + public + property Items[Index: integer]: TsdRefString read GetItems; default; + end; + + // A string table, holding a collection of unique strings, sorted in 2 ways + // for fast access. Strings can be added with AddString or AddStringRec, + // and should be updated with SetString. When a string is added or updated, + // an ID is returned which the application can use to retrieve the string, + // using GetString. + TsdStringTable = class(TPersistent) + private + FByID: TsdRefStringList; + FBySR: TsdRefStringList; + protected + procedure DecFrequency(AItem: TsdRefString; ByIdIndex: integer); + function NextUniqueID: integer; + public + constructor Create; + destructor Destroy; override; + procedure Clear; + // Add a new string rec, return fresh ID or ID of existing item, and increase + // the existing item's ref count + function AddStringRec(const SR: TsdStringRec): integer; + // Add a new string S to the table, the function returns its ID. + function AddString(const S: UTF8String): integer; + // Get the refstring by ID + function ById(index: integer): TsdRefString; + // Delete refstring by ID + procedure Delete(ByIdIndex: integer); + // determine if the stringrec exists + function ExistStringRec(const SR: TsdStringRec): boolean; + // Get the string of refstring with ID + function GetString(ID: integer): UTF8String; + // Set the string value of refstring with ID. + procedure SetString(var ID: integer; const S: UTF8String); + // Number of refstrings + function StringCount: integer; + procedure SaveToFile(const AFileName: string); + procedure SaveToStream(S: TStream); + end; + +{utility functions} + +// convert a string into a string rec +function sdStringToSR(const S: Utf8String): TsdStringRec; + +// convert a string rec into a string +function sdSRToString(const SR: TsdStringRec): Utf8String; + +// compare two string recs. This is NOT an alphabetic compare. SRs are first +// compared by length, then by first byte, then last byte then second, then +// N-1, until all bytes are compared. +function sdCompareSR(const SR1, SR2: TsdStringRec): integer; + +// compare 2 bytes +function sdCompareByte(Byte1, Byte2: byte): integer; + +// compare 2 integers +function sdCompareInteger(Int1, Int2: integer): integer; + +function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer; +function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer; +procedure sdStreamWrite(S: TStream; const AString: AnsiString); +procedure sdStreamWriteStringRec(S: TStream; const AStringRec: TsdStringRec); +procedure sdStreamWriteRefString(S: TStream; ARefString: TsdRefString); + +implementation + +{ TsdRefString } + +function TsdRefString.AsString: UTF8String; +begin + Result := sdSRToString(StringRec); +end; + +function TsdRefString.CompareToSR(const SR: TsdStringRec): integer; +begin + if SR.Count = 0 then + begin + // shortcut + Result := 1; + exit; + end; + Result := sdCompareSR(StringRec, SR); +end; + +destructor TsdRefString.Destroy; +begin + FreeMem(FFirst); + inherited; +end; + +procedure TsdRefString.SetString(const SR: TsdStringRec); +begin + FCharCount := SR.Count; + ReallocMem(FFirst, FCharCount); + Move(SR.First^, FFirst^, FCharCount); +end; + +function TsdRefString.StringRec: TsdStringRec; +begin + Result.First := FFirst; + Result.Count := FCharCount; +end; + +{ TsdRefStringList } + +function TsdRefStringList.GetItems(Index: integer): TsdRefString; +begin + Result := Get(Index); +end; + +function TsdRefStringList.IndexOfID(AID: integer; var Index: integer): boolean; +var + Min, Max: integer; +begin + Result := False; + + // Find position - binary method + Index := 0; + Min := 0; + Max := Count; + while Min < Max do + begin + Index := (Min + Max) div 2; + case sdCompareInteger(Items[Index].FID, AID) of + -1: Min := Index + 1; + 0: begin + Result := True; + exit; + end; + 1: Max := Index; + end; + end; + + Index := Min; +end; + +function TsdRefStringList.IndexOfSR(const AStringRec: TsdStringRec; var Index: integer): boolean; +var + Min, Max: integer; + SR: TsdStringRec; +begin + Result := False; + + // Find position - binary method + Index := 0; + Min := 0; + Max := Count; + while Min < Max do + begin + Index := (Min + Max) div 2; + SR := TsdRefString(Get(Index)).StringRec; + case sdCompareSR(SR, AStringRec) of + -1: Min := Index + 1; + 0: begin + Result := True; + exit; + end; + 1: Max := Index; + end; + end; + + Index := Min; +end; + +{ TsdStringTable } + +function TsdStringTable.AddString(const S: UTF8String): integer; +var + SR: TsdStringRec; +begin + SR := sdStringToSR(S); + Result := AddStringRec(SR); +end; + +function TsdStringTable.AddStringRec(const SR: TsdStringRec): integer; +var + BySRIndex: integer; + Item: TsdRefString; + NewSR: TsdStringRec; + Res: boolean; +begin + // zero-length string + if SR.Count = 0 then + begin + Result := 0; + exit; + end; + + // Try to find the new string + if FBySR.IndexOfSR(SR, BySRIndex) then + begin + Item := FBySR.Items[BySRIndex]; + inc(Item.FFrequency); + Result := Item.FID; + exit; + end; + + // Not found.. must make new item + Item := TsdRefString.Create; + Item.SetString(SR); + NewSR := Item.StringRec; + Item.FID := NextUniqueID; + FById.Add(Item); + Item.FFrequency := 1; + + // debug: + //SetLength(Item.FValue, Item.FCount); + //Move(Item.FirstPtr(FBase)^, Item.FValue[1], Item.FCount); + + // Insert in BySR lists + Res := FBySR.IndexOfSR(NewSR, BySRIndex); + assert(Res = False); + FBySR.Insert(BySRIndex, Item); + Result := Item.FID; +end; + +function TsdStringTable.ById(index: integer): TsdRefString; +begin + Result := FById[Index]; +end; + +procedure TsdStringTable.Clear; +begin + FByID.Clear; + FBySR.Clear; +end; + +constructor TsdStringTable.Create; +begin + inherited Create; + FByID := TsdRefStringList.Create(False); + FBySR := TsdRefStringList.Create(True); +end; + +procedure TsdStringTable.DecFrequency(AItem: TsdRefString; ByIdIndex: integer); +var + BySRIndex: integer; + Res: boolean; +begin + dec(AItem.FFrequency); + assert(AItem.FFrequency >= 0); + + if AItem.FFrequency = 0 then + begin + // We must remove it + FById.Delete(ByIdIndex); + Res := FBySR.IndexOfSR(AItem.StringRec, BySRIndex); + assert(Res = True); + FBySR.Delete(BySRIndex); + end; +end; + +procedure TsdStringTable.Delete(ByIdIndex: integer); +var + Item: TsdRefString; + BySRIndex: integer; + Res: boolean; +begin + Item := FById[ByIdIndex]; + if Item = nil then + exit; + FById.Delete(ByIdIndex); + Res := FBySR.IndexOfSR(Item.StringRec, BySRIndex); + assert(Res = True); + FBySR.Delete(BySRIndex); +end; + +destructor TsdStringTable.Destroy; +begin + FreeAndNil(FByID); + FreeAndNil(FBySR); + inherited; +end; + +function TsdStringTable.ExistStringRec(const SR: TsdStringRec): boolean; +var + BySRIndex: integer; +begin + // zero-length string + if SR.Count = 0 then + begin + Result := False; + exit; + end; + + // Try to find the new string + Result := FBySR.IndexOfSR(SR, BySRIndex); + +end; + +function TsdStringTable.GetString(ID: integer): UTF8String; +var + Index, Count: integer; + Item: TsdRefString; +begin + if ID = 0 then + begin + Result := ''; + exit; + end; + + // Find the ID + if FByID.IndexOfID(ID, Index) then + begin + Item := FById[Index]; + Count := Item.FCharCount; + SetLength(Result, Count); + Move(Item.FFirst^, Result[1], Count); + exit; + end; + + Result := ''; +end; + +function TsdStringTable.NextUniqueID: integer; +begin + if FById.Count = 0 then + Result := 1 + else + Result := FByID[FByID.Count - 1].FID + 1; +end; + +procedure TsdStringTable.SaveToFile(const AFileName: string); +var + F: TFileStream; +begin + F := TFileStream.Create(AFileName, fmCreate); + try + SaveToStream(F); + finally + F.Free; + end; +end; + +procedure TsdStringTable.SaveToStream(S: TStream); +var + i: integer; + R: UTF8String; +begin + for i := 0 to FBySR.Count - 1 do + begin + R := FBySR[i].AsString + #13#10; + S.Write(R[1], length(R)); + end; +end; + +procedure TsdStringTable.SetString(var ID: integer; const S: UTF8String); +var + ByIdIndex: integer; + Item: TsdRefString; + SR: TsdStringRec; +begin + // Make temp string record + SR := sdStringtoSR(S); + + // Do we have a ref string with this ID? + if (ID > 0) and FByID.IndexOfID(ID, ByIdIndex) then + begin + // Is the string still the same? + Item := FById[ByIdIndex]; + if Item.CompareToSR(SR) = 0 then + exit; + // The string changed.. + DecFrequency(Item, ByIdIndex); + end; + + ID := AddStringRec(SR); +end; + +{utility functions} + +function TsdStringTable.StringCount: integer; +begin + Result := FBySR.Count; +end; + +function sdStringToSR(const S: UTF8String): TsdStringRec; +begin + Result.Count := length(S); + if Result.Count = 0 then + Result.First := nil + else + Result.First := @S[1]; +end; + +function sdSRToString(const SR: TsdStringRec): UTF8String; +begin + SetLength(Result, SR.Count); + if SR.Count > 0 then + Move(SR.First^, Result[1], SR.Count); +end; + +function sdCompareByte(Byte1, Byte2: byte): integer; +begin + if Byte1 < Byte2 then + Result := -1 + else + if Byte1 > Byte2 then + Result := 1 + else + Result := 0; +end; + +function sdCompareInteger(Int1, Int2: integer): integer; +begin + if Int1 < Int2 then + Result := -1 + else + if Int1 > Int2 then + Result := 1 + else + Result := 0; +end; + +function sdCompareSR(const SR1, SR2: TsdStringRec): integer; +var + Count: integer; + First1, First2, Last1, Last2: Pbyte; +begin + // Compare string length first + Result := sdCompareInteger(SR1.Count, SR2.Count); + if Result <> 0 then + exit; + + // Compare first + Result := sdCompareByte(SR1.First^, SR2.First^); + if Result <> 0 then + exit; + Count := SR1.Count; + + // Setup First & Last pointers + First1 := SR1.First; + First2 := SR2.First; + Last1 := First1; inc(Last1, Count); + Last2 := First2; inc(Last2, Count); + + // Compare each time last ptrs then first ptrs, until they meet in the middle + repeat + dec(Last1); + dec(Last2); + if First1 = Last1 then + exit; + Result := sdCompareByte(Last1^, Last2^); + if Result <> 0 then + exit; + inc(First1); inc(First2); + if First1 = Last1 then + exit; + Result := sdCompareByte(First1^, First2^); + if Result <> 0 then + exit; + until False; +end; + +function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer; +// Convert an Unicode (UTF16 LE) memory block to UTF8. This routine will process +// Count wide characters (2 bytes size) to Count UTF8 characters (1-3 bytes). +// Therefore, the block at Dst must be at least 1.5 the size of the source block. +// The function returns the number of *bytes* written. +var + W: word; + DStart: Pbyte; +begin + DStart := Dst; + while Count > 0 do + begin + W := Src^; + inc(Src); + if W <= $7F then + begin + Dst^ := byte(W); + inc(Dst); + end else + begin + if W > $7FF then + begin + Dst^ := byte($E0 or (W shr 12)); + inc(Dst); + Dst^ := byte($80 or ((W shr 6) and $3F)); + inc(Dst); + Dst^ := byte($80 or (W and $3F)); + inc(Dst); + end else + begin // $7F < W <= $7FF + Dst^ := byte($C0 or (W shr 6)); + inc(Dst); + Dst^ := byte($80 or (W and $3F)); + inc(Dst); + end; + end; + dec(Count); + end; + Result := integer(Dst) - integer(DStart); +end; + +function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer; +// Convert an UTF8 memory block to Unicode (UTF16 LE). This routine will process +// Count *bytes* of UTF8 (each character 1-3 bytes) into UTF16 (each char 2 bytes). +// Therefore, the block at Dst must be at least 2 times the size of Count, since +// many UTF8 characters consist of just one byte, and are mapped to 2 bytes. The +// function returns the number of *wide chars* written. Note that the Src block must +// have an exact number of UTF8 characters in it, if Count doesn't match then +// the last character will be converted anyway (going past the block boundary!) +var + W: word; + C: byte; + DStart: Pword; + SClose: Pbyte; +begin + DStart := Dst; + SClose := Src; + inc(SClose, Count); + while integer(Src) < integer(SClose) do + begin + // 1st byte + W := Src^; + inc(Src); + if W and $80 <> 0 then + begin + W := W and $3F; + if W and $20 <> 0 then + begin + // 2nd byte + C := Src^; + inc(Src); + if C and $C0 <> $80 then + // malformed trail byte or out of range char + Continue; + W := (W shl 6) or (C and $3F); + end; + // 2nd or 3rd byte + C := Src^; + inc(Src); + if C and $C0 <> $80 then + // malformed trail byte + Continue; + Dst^ := (W shl 6) or (C and $3F); + inc(Dst); + end else + begin + Dst^ := W; + inc(Dst); + end; + end; + Result := (integer(Dst) - integer(DStart)) div 2; +end; + +procedure sdStreamWrite(S: TStream; const AString: AnsiString); +var + L: integer; +begin + L := Length(AString); + if L > 0 then + begin + S.Write(AString[1], L); + end; +end; + +procedure sdStreamWriteStringRec(S: TStream; const AStringRec: TsdStringRec); +begin + S.Write(PAnsiChar(AStringRec.First)^, AStringRec.Count); +end; + +procedure sdStreamWriteRefString(S: TStream; ARefString: TsdRefString); +begin + if ARefString = nil then + exit; + S.Write(PAnsiChar(ARefString.FFirst)^, ARefString.FCharCount); +end; + +end. diff --git a/System/zlibpas.pas b/System/zlibpas.pas new file mode 100644 index 0000000..64a8526 --- /dev/null +++ b/System/zlibpas.pas @@ -0,0 +1,156 @@ +{Portable Network Graphics Delphi ZLIB linking (16 May 2002) } + +{This unit links ZLIB to pngimage unit in order to implement } +{the library. It's now using the new ZLIB version, 1.1.4 } +{Note: The .obj files must be located in the subdirectory \obj} + +unit zlibpas; + +interface + +type + + TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; + TFree = procedure (AppData, Block: Pointer); + + // Internal structure. Ignore. + TZStreamRec = packed record + next_in: PChar; // next input byte + avail_in: Integer; // number of bytes available at next_in + total_in: Integer; // total nb of input bytes read so far + + next_out: PChar; // next output byte should be put here + avail_out: Integer; // remaining free space at next_out + total_out: Integer; // total nb of bytes output so far + + msg: PChar; // last error message, NULL if no error + internal: Pointer; // not visible by applications + + zalloc: TAlloc; // used to allocate the internal state + zfree: TFree; // used to free the internal state + AppData: Pointer; // private data object passed to zalloc and zfree + + data_type: Integer; // best guess about the data type: ascii or binary + adler: Integer; // adler32 value of the uncompressed data + reserved: Integer; // reserved for future use + end; + +function inflateInit_(var strm: TZStreamRec; version: PChar; + recsize: Integer): Integer; forward; +function inflate(var strm: TZStreamRec; flush: Integer): Integer; forward; +function inflateEnd(var strm: TZStreamRec): Integer; forward; +function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar; + recsize: Integer): Integer; forward; +function deflate(var strm: TZStreamRec; flush: Integer): Integer; forward; +function deflateEnd(var strm: TZStreamRec): Integer; forward; + +const + zlib_version = '1.2.3'; + + +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = (-1); + Z_STREAM_ERROR = (-2); + Z_DATA_ERROR = (-3); + Z_MEM_ERROR = (-4); + Z_BUF_ERROR = (-5); + Z_VERSION_ERROR = (-6); + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = (-1); + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + + _z_errmsg: array[0..9] of PChar = ( + 'need dictionary', // Z_NEED_DICT (2) + 'stream end', // Z_STREAM_END (1) + '', // Z_OK (0) + 'file error', // Z_ERRNO (-1) + 'stream error', // Z_STREAM_ERROR (-2) + 'data error', // Z_DATA_ERROR (-3) + 'insufficient memory', // Z_MEM_ERROR (-4) + 'buffer error', // Z_BUF_ERROR (-5) + 'incompatible version', // Z_VERSION_ERROR (-6) + '' + ); + +implementation + +{$L obj\adler32.obj} +{$L obj\deflate.obj} +{$L obj\infback.obj} +{$L obj\inffast.obj} +{$L obj\inflate.obj} +{$L obj\inftrees.obj} +{$L obj\trees.obj} +{$L obj\compress.obj} +{$L obj\crc32.obj} + + + +function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt; external; + +procedure _memset(P: Pointer; B: Byte; count: Integer);cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer);cdecl; +begin + Move(source^, dest^, count); +end; + + +// deflate compresses data +function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar; + recsize: Integer): Integer; external; +function deflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function deflateEnd(var strm: TZStreamRec): Integer; external; + +// inflate decompresses data +function inflateInit_(var strm: TZStreamRec; version: PChar; + recsize: Integer): Integer; external; +function inflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function inflateEnd(var strm: TZStreamRec): Integer; external; +function inflateReset(var strm: TZStreamRec): Integer; external; + + +function zcalloc(AppData: Pointer; Items, Size: Integer): Pointer; +begin + GetMem(Result, Items*Size); +end; + +procedure zcfree(AppData, Block: Pointer); +begin + FreeMem(Block); +end; + +end. + + + + + + + + + diff --git a/Variations/varAuger.pas b/Variations/varAuger.pas new file mode 100644 index 0000000..74fc52d --- /dev/null +++ b/Variations/varAuger.pas @@ -0,0 +1,176 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varAuger; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationAuger = class(TBaseVariation) + private + auger_freq, auger_weight, auger_scale, auger_sym: double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationAuger.Prepare; +begin +end; + +procedure TVariationAuger.CalcFunction; +var x, y, s, t, dx, dy: double; +begin + x := FTx^; + y := FTy^; + + s := sin(auger_freq * x); + t := sin(auger_freq * y); + + dx := x + auger_weight * (0.5 * auger_scale * t + abs(x) * t); + dy := y + auger_weight * (0.5 * auger_scale * s + abs(y) * s); + + FPx^ := FPx^ + VVAR * (x + auger_sym * (dx - x)); + FPy^ := FPy^ + VVAR * dy; + FPz^ := FPz^ + VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationAuger.Create; +begin + auger_freq := 5; auger_weight := 0.5; + auger_scale := 0.1; auger_sym := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationAuger.GetInstance: TBaseVariation; +begin + Result := TVariationAuger.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationAuger.GetName: string; +begin + Result := 'auger'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationAuger.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'auger_freq'; + 1: Result := 'auger_weight'; + 2: Result := 'auger_scale'; + 3: Result := 'auger_sym'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationAuger.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'auger_freq' then begin + auger_freq := Value; + Result := True; + end else if Name = 'auger_weight' then begin + auger_weight := Value; + Result := True; + end else if Name = 'auger_scale' then begin + auger_scale := Value; + Result := True; + end else if Name = 'auger_sym' then begin + auger_sym := Value; + Result := True; + end +end; +function TVariationAuger.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'auger_freq' then begin + auger_freq := 5; + Result := True; + end else if Name = 'auger_weight' then begin + auger_weight := 0.5; + Result := True; + end else if Name = 'auger_scale' then begin + auger_sym := 0.1; + Result := True; + end else if Name = 'auger_sym' then begin + auger_sym := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationAuger.GetNrVariables: integer; +begin + Result := 4 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationAuger.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'auger_freq' then begin + Value := auger_freq; + Result := True; + end else if Name = 'auger_weight' then begin + Value := auger_weight; + Result := True; + end else if Name = 'auger_scale' then begin + Value := auger_scale; + Result := True; + end else if Name = 'auger_sym' then begin + Value := auger_sym; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationAuger), true, false); +end. \ No newline at end of file diff --git a/Variations/varBipolar.pas b/Variations/varBipolar.pas new file mode 100644 index 0000000..4554adc --- /dev/null +++ b/Variations/varBipolar.pas @@ -0,0 +1,162 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varBipolar; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationBipolar = class(TBaseVariation) + private + bipolar_shift, v_4, v, s: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationBipolar.Prepare; +begin + v_4 := VVAR * 0.15915494309189533576888376337251; + v := VVAR * 0.636619772367581343075535053490061; + s := -1.57079632679489661923 * (bipolar_shift); +end; + +procedure TVariationBipolar.CalcFunction; +var x2y2, y, t, x2, f, g : double; +begin + x2y2 := sqr(FTx^) + sqr(FTy^); + y := 0.5 * ArcTan2(2.0 * FTy^, x2y2 - 1.0) + (s); + + if (y > 1.57079632679489661923) then + y := -1.57079632679489661923 + fmod(y + 1.57079632679489661923, PI) + else if (y < -1.57079632679489661923) then + y := 1.57079632679489661923 - fmod(1.57079632679489661923 - y, PI); + + t := x2y2 + 1.0; + x2 := 2.0 * FTx^; + + f := t + x2; + g := t - x2; + + if (g = 0) or (f/g <= 0) then + Exit; + + FPx^ := FPx^ + (v_4) * Ln((t+x2) / (t-x2)); + FPy^ := FPy^ + (v) * y; + + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationBipolar.Create; +begin + bipolar_shift := 0; + v_4 := 0; + v := 0; + s := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBipolar.GetInstance: TBaseVariation; +begin + Result := TVariationBipolar.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBipolar.GetName: string; +begin + Result := 'bipolar'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBipolar.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'bipolar_shift'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBipolar.SetVariable(const Name: string; var value: double): boolean; +var temp: double; +begin + Result := False; + if Name = 'bipolar_shift' then begin + temp := frac(0.5 * (value + 1.0)); + value := 2.0 * temp - 1.0; + bipolar_shift := Value; + Result := True; + end +end; +function TVariationBipolar.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'bipolar_shift' then begin + bipolar_shift := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBipolar.GetNrVariables: integer; +begin + Result := 1 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBipolar.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'bipolar_shift' then begin + Value := bipolar_shift; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationBipolar), true, false); +end. \ No newline at end of file diff --git a/Variations/varBlurCircle.pas b/Variations/varBlurCircle.pas new file mode 100644 index 0000000..f573392 --- /dev/null +++ b/Variations/varBlurCircle.pas @@ -0,0 +1,141 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varBlurCircle; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationBlurCircle = class(TBaseVariation) + private + VVAR4_PI: double; + PI_4: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationBlurCircle.Prepare; +begin + VVAR4_PI := VVAR * 4.0 / PI; + PI_4 := PI / 4.0; +end; + +procedure TVariationBlurCircle.CalcFunction; +var + x, y, absx, absy, side, perimeter, r, sina, cosa: double; +begin + x := 2.0 * random - 1.0; + y := 2.0 * random - 1.0; + + absx := x; if absx < 0 then absx := absx * -1.0; + absy := y; if absy < 0 then absy := absy * -1.0; + + if (absx >= absy) then + begin + if (x >= absy) then + perimeter := absx + y + else perimeter := 5.0 * absx - y; + side := absx; + end else + begin + if (y >= absx) then + perimeter := 3.0 * absy - x + else perimeter := 7.0 * absy + x; + side := absy; + end; + + r := VVAR * side; + SinCos(PI_4 * perimeter / side - PI_4, sina, cosa); + + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; + FPz^ := FPz^ + vvar * FTz^; +end; + + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationBlurCircle.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBlurCircle.GetInstance: TBaseVariation; +begin + Result := TVariationBlurCircle.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBlurCircle.GetName: string; +begin + Result := 'blur_circle'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurCircle.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurCircle.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurCircle.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurCircle.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationBlurCircle), true, false); +end. \ No newline at end of file diff --git a/Variations/varBlurPixelize.pas b/Variations/varBlurPixelize.pas new file mode 100644 index 0000000..89cb6ea --- /dev/null +++ b/Variations/varBlurPixelize.pas @@ -0,0 +1,153 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varBlurPixelize; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationBlurPixelize = class(TBaseVariation) + private + blur_pixelize_size, blur_pixelize_scale: double; + inv_size, v: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationBlurPixelize.Prepare; +begin + inv_size := 1.0 / blur_pixelize_size; + v := vvar * blur_pixelize_size; +end; + +procedure TVariationBlurPixelize.CalcFunction; +var x, y: double; +begin + x := floor(FTx^*(inv_size)); + y := floor(FTy^*(inv_size)); + + FPx^ := FPx^ + (v) * (x + (blur_pixelize_scale) * (random - 0.5) + 0.5); + FPy^ := FPy^ + (v) * (y + (blur_pixelize_scale) * (random - 0.5) + 0.5); + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationBlurPixelize.Create; +begin + blur_pixelize_size := 0.1; + blur_pixelize_scale := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBlurPixelize.GetInstance: TBaseVariation; +begin + Result := TVariationBlurPixelize.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBlurPixelize.GetName: string; +begin + Result := 'blur_pixelize'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurPixelize.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'blur_pixelize_size'; + 1: Result := 'blur_pixelize_scale'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurPixelize.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'blur_pixelize_size' then begin + if (value < 1e-6) then value := 1e-6; + blur_pixelize_size := Value; + Result := True; + end else if Name = 'blur_pixelize_scale' then begin + blur_pixelize_scale := Value; + Result := True; + end +end; +function TVariationBlurPixelize.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'blur_pixelize_size' then begin + blur_pixelize_size := 0.1; + Result := True; + end else if Name = 'blur_pixelize_scale' then begin + blur_pixelize_size := 1; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurPixelize.GetNrVariables: integer; +begin + Result := 2 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurPixelize.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'blur_pixelize_size' then begin + Value := blur_pixelize_size; + Result := True; + end else if Name = 'blur_pixelize_scale' then begin + Value := blur_pixelize_scale; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationBlurPixelize), true, false); +end. \ No newline at end of file diff --git a/Variations/varBlurZoom.pas b/Variations/varBlurZoom.pas new file mode 100644 index 0000000..c93f629 --- /dev/null +++ b/Variations/varBlurZoom.pas @@ -0,0 +1,144 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varBlurZoom; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationBlurZoom = class(TBaseVariation) + private + blur_zoom_length, blur_zoom_x, blur_zoom_y: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationBlurZoom.Prepare; +begin +end; + +procedure TVariationBlurZoom.CalcFunction; +var z: double; +begin + + z := 1.0 + blur_zoom_length * random; + FPx^ := FPx^ + vvar * ((FTx^ - blur_zoom_x) * z + blur_zoom_x); + FPy^ := FPy^ + vvar * ((FTy^ - blur_zoom_y) * z - blur_zoom_y); + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationBlurZoom.Create; +begin + blur_zoom_length := 0; + blur_zoom_x := 0; + blur_zoom_y := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBlurZoom.GetInstance: TBaseVariation; +begin + Result := TVariationBlurZoom.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBlurZoom.GetName: string; +begin + Result := 'blur_zoom'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurZoom.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'blur_zoom_length'; + 1: Result := 'blur_zoom_x'; + 2: Result := 'blur_zoom_y'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurZoom.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'blur_zoom_length' then begin + blur_zoom_length := Value; + Result := True; + end else if Name = 'blur_zoom_x' then begin + blur_zoom_y := Value; + Result := True; + end else if Name = 'blur_zoom_y' then begin + blur_zoom_y := Value; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurZoom.GetNrVariables: integer; +begin + Result := 3 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBlurZoom.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'blur_zoom_length' then begin + Value := blur_zoom_length; + Result := True; + end else if Name = 'blur_zoom_x' then begin + Value := blur_zoom_x; + Result := True; + end else if Name = 'blur_zoom_y' then begin + Value := blur_zoom_y; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationBlurZoom), true, false); +end. \ No newline at end of file diff --git a/Variations/varBwraps.pas b/Variations/varBwraps.pas new file mode 100644 index 0000000..473f68b --- /dev/null +++ b/Variations/varBwraps.pas @@ -0,0 +1,238 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varBwraps; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationBwraps = class(TBaseVariation) + private + bwraps_cellsize, bwraps_space, bwraps_gain, + bwraps_inner_twist, bwraps_outer_twist, + g2, r2, rfactor: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationBwraps.Prepare; +var + max_bubble, radius: double; +begin + radius := 0.5 * (bwraps_cellsize / (1.0 + sqr(bwraps_space))); + g2 := sqr(bwraps_gain) / (radius + 1e-6) + 1e-6; + max_bubble := g2 * radius; + + if (max_bubble > 2.0) then max_bubble := 1.0 + else max_bubble := max_bubble * (1.0 / (sqr(max_bubble)/4.0 + 1.0)); + + r2 := sqr(radius); + rfactor := radius / max_bubble; +end; + +procedure TVariationBwraps.CalcFunction; +var + Vx, Vy, + Cx, Cy, + Lx, Ly, + r, theta, s, c : double; +begin + Vx := FTx^; + Vy := FTy^; + + if (bwraps_cellsize = 0.0) then + begin + FPx^ := FPx^ + VVAR * FTx^; + FPy^ := FPy^ + VVAR * FTy^; + FPz^ := FPz^ + VVAR * FTz^; + end else + begin + Cx := (floor(Vx / bwraps_cellsize) + 0.5) * bwraps_cellsize; + Cy := (floor(Vy / bwraps_cellsize) + 0.5) * bwraps_cellsize; + + Lx := Vx - Cx; + Ly := Vy - Cy; + + if ((sqr(Lx) + sqr(Ly)) > r2) then + begin + FPx^ := FPx^ + VVAR * FTx^; + FPy^ := FPy^ + VVAR * FTy^; + FPz^ := FPz^ + VVAR * FTz^; + end else + begin + Lx := Lx * g2; + Ly := Ly * g2; + + r := rfactor / ((sqr(Lx) + sqr(Ly)) / 4.0 + 1); + + Lx := Lx * r; + Ly := Ly * r; + + r := (sqr(Lx) + sqr(Ly)) / r2; + theta := bwraps_inner_twist * (1.0 - r) + bwraps_outer_twist * r; + SinCos(theta, s, c); + + Vx := Cx + c * Lx + s * Ly; + Vy := Cy - s * Lx + c * Ly; + + FPx^ := FPx^ + VVAR * Vx; + FPy^ := FPy^ + VVAR * Vy; + FPz^ := FPz^ + VVAR * FTz^; + end; + end; + +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationBwraps.Create; +begin + bwraps_cellsize := 1; + bwraps_space := 0; + bwraps_gain := 1; + bwraps_inner_twist := 0; + bwraps_outer_twist := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBwraps.GetInstance: TBaseVariation; +begin + Result := TVariationBwraps.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationBwraps.GetName: string; +begin + Result := 'bwraps'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBwraps.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'bwraps_cellsize'; + 1: Result := 'bwraps_space'; + 2: Result := 'bwraps_gain'; + 3: Result := 'bwraps_inner_twist'; + 4: Result := 'bwraps_outer_twist'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBwraps.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'bwraps_cellsize' then begin + bwraps_cellsize := Value; + Result := True; + end else if Name = 'bwraps_space' then begin + bwraps_space := Value; + Result := True; + end else if Name = 'bwraps_gain' then begin + bwraps_gain := Value; + Result := True; + end else if Name = 'bwraps_inner_twist' then begin + bwraps_inner_twist := Value; + Result := True; + end else if Name = 'bwraps_outer_twist' then begin + bwraps_outer_twist := Value; + Result := True; + end +end; +function TVariationBwraps.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'bwraps_cellsize' then begin + bwraps_cellsize := 1; + Result := True; + end else if Name = 'bwraps_space' then begin + bwraps_space := 0; + Result := True; + end else if Name = 'bwraps_gain' then begin + bwraps_gain := 1; + Result := True; + end else if Name = 'bwraps_inner_twist' then begin + bwraps_inner_twist := 0; + Result := True; + end else if Name = 'bwraps_outer_twist' then begin + bwraps_outer_twist := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBwraps.GetNrVariables: integer; +begin + Result := 5 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationBwraps.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'bwraps_cellsize' then begin + if Value = 0 then Value := 1e-6; + Value := bwraps_cellsize; + Result := True; + end else if Name = 'bwraps_space' then begin + Value := bwraps_space; + Result := True; + end else if Name = 'bwraps_gain' then begin + Value := bwraps_gain; + Result := True; + end else if Name = 'bwraps_inner_twist' then begin + Value := bwraps_inner_twist; + Result := True; + end else if Name = 'bwraps_outer_twist' then begin + Value := bwraps_outer_twist; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationBwraps), true, false); +end. \ No newline at end of file diff --git a/Variations/varCrop.pas b/Variations/varCrop.pas new file mode 100644 index 0000000..71c1eeb --- /dev/null +++ b/Variations/varCrop.pas @@ -0,0 +1,232 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varCrop; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationCrop = class(TBaseVariation) + const + n_x0 : string = 'crop_left'; + n_y0 : string = 'crop_top'; + n_x1 : string = 'crop_right'; + n_y1 : string = 'crop_bottom'; + n_s : string = 'crop_scatter_area'; + n_z : string = 'crop_zero'; + n : string = 'crop'; + + private + x0, y0, x1, y1, s, w, h: double; + _x0, _y0, _x1, _y1: double; + z: integer; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCrop.Prepare; +begin + if (x0 < x1) then begin + _x0 := x0; + _x1 := x1; + end else begin + _x0 := x1; + _x1 := x0; + end; + + if (y0 < y1) then begin + _y0 := y0; + _y1 := y1; + end else begin + _y0 := y1; + _y1 := y0; + end; + + w := (_x1 - _x0) * 0.5 * s; + h := (_y1 - _y0) * 0.5 * s; +end; + +procedure TVariationCrop.CalcFunction; +var x, y: double; +begin + x := FTx^; + y := FTy^; + + if ((x < _x0) or (x > _x1) or (y < _y0) or (y > _y1)) and (z <> 0) then begin + x := 0; y := 0; + end else begin + if x < _x0 then x := _x0 + random * w + else if x > _x1 then x := _x1 - random * w; + if y < _y0 then y := _y0 + random * h + else if y > _y1 then y := _y1 - random * h; + end; + + FPx^ := FPx^ + VVAR * x; + FPy^ := FPy^ + VVAR * y; + FPz^ := FPz^ + VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationCrop.Create; +begin + x0 := -1; x1 := 1; + y0 := -1; y1 := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCrop.GetInstance: TBaseVariation; +begin + Result := TVariationCrop.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCrop.GetName: string; +begin + Result := n; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCrop.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := n_x0; + 1: Result := n_y0; + 2: Result := n_x1; + 3: Result := n_y1; + 4: Result := n_s; + 5: Result := n_z; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCrop.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_x0 then begin + x0 := Value; + Result := True; + end else if Name = n_y0 then begin + y0 := Value; + Result := True; + end else if Name = n_x1 then begin + x1 := Value; + Result := True; + end else if Name = n_y1 then begin + y1 := Value; + Result := True; + end else if Name = n_s then begin + if (Value < -1) then Value := -1; + if (Value > 1) then Value := 1; + s := Value; + Result := True; + end else if Name = n_z then begin + if (Value > 1) then Value := 1; + if (Value < 0) then Value := 0; + z := Round(Value); + Result := True; + end +end; +function TVariationCrop.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = n_x0 then begin + x0 := -1; + Result := True; + end else if Name = n_y0 then begin + y0 := -1; + Result := True; + end else if Name = n_x1 then begin + x1 := 1; + Result := True; + end else if Name = n_y1 then begin + y1 := 1; + Result := True; + end else if Name = n_s then begin + s := 0; + Result := True; + end else if Name = n_z then begin + z := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCrop.GetNrVariables: integer; +begin + Result := 6 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCrop.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_x0 then begin + Value := x0; + Result := True; + end else if Name = n_y0 then begin + Value := y0; + Result := True; + end else if Name = n_x1 then begin + Value := x1; + Result := True; + end else if Name = n_y1 then begin + Value := y1; + Result := True; + end else if Name = n_s then begin + Value := s; + Result := True; + end else if Name = n_z then begin + Value := z; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationCrop), true, false); +end. \ No newline at end of file diff --git a/Variations/varCross.pas b/Variations/varCross.pas new file mode 100644 index 0000000..f169667 --- /dev/null +++ b/Variations/varCross.pas @@ -0,0 +1,111 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varCross; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationCross = class(TBaseVariation) + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCross.CalcFunction; +var + r: double; +begin + r := Abs((FTx^ - FTy^) * (FTx^ + FTy^) + 1e-6); + if (r < 0) then r := r * -1.0; + r := VVAR / r; + + FPx^ := FPx^ + FTx^ * r; + FPy^ := FPy^ + FTy^ * r; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationCross.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCross.GetInstance: TBaseVariation; +begin + Result := TVariationCross.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCross.GetName: string; +begin + Result := 'cross'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCross.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCross.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCross.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCross.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationCross), true, false); +end. diff --git a/Variations/varCurl.pas b/Variations/varCurl.pas new file mode 100644 index 0000000..1cf0c35 --- /dev/null +++ b/Variations/varCurl.pas @@ -0,0 +1,245 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varCurl; + +interface + +uses + BaseVariation, XFormMan; + +const + variation_name = 'curl'; + num_vars = 2; + var_c1_name='curl_c1'; + var_c2_name='curl_c2'; + +//{$define _ASM_} + +// z +// The formula is: f(z) = ------------------- , where z = complex (x + i*y) +// c2*(z^2) + c1*z + 1 + +type + TVariationCurl = class(TBaseVariation) + private + c2, c1: double; + + c2x2: double; + + procedure CalcZeroC2; + procedure CalcZeroC1; + procedure CalcZeroC2C1; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + math; + +// TVariationCurl + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationCurl.Create; +begin + // seriously? + (*c1 := random; + c2 := random; + + case random(3) of + 0: c1 := 0; + 1: c2 := 0; + {else: do nothing} + end;*) + c1 := 0; + c2 := 0; +end; + +procedure TVariationCurl.Prepare; +begin + c2x2 := 2 * c2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl.GetCalcFunction(var f: TCalcFunction); +begin + if IsZero(c1) then begin + if IsZero(c2) then + f := CalcZeroC2C1 + else + f := CalcZeroC1 + end + else begin + if IsZero(c2) then + f := CalcZeroC2 + else + f := CalcFunction + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl.CalcFunction; +var + r: double; + re, im: double; +begin + re := 1 + c1*FTx^ + c2*(sqr(FTx^) - sqr(FTy^)); + im := c1*FTy^ + c2x2*FTx^*FTy^; + + r := vvar / (sqr(re) + sqr(im)); + + FPx^ := FPx^ + (FTx^*re + FTy^*im) * r; + FPy^ := FPy^ + (FTy^*re - FTx^*im) * r; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationCurl.CalcZeroC2; +var + r: double; + re, im: double; +begin + re := 1 + c1*FTx^; + im := c1*FTy^; + + r := vvar / (sqr(re) + sqr(im)); + + FPx^ := FPx^ + (FTx^*re + FTy^*im) * r; + FPy^ := FPy^ + (FTy^*re - FTx^*im) * r; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationCurl.CalcZeroC1; +var + r: double; + re, im: double; +begin + re := 1 + c2*(sqr(FTx^) - sqr(FTy^)); + im := c2x2*FTx^*FTy^; + + r := vvar / (sqr(re) + sqr(im)); + + FPx^ := FPx^ + (FTx^*re + FTy^*im) * r; + FPy^ := FPy^ + (FTy^*re - FTx^*im) * r; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationCurl.CalcZeroC2C1; +var + r: double; +begin + FPx^ := FPx^ + vvar*FTx^; + FPy^ := FPy^ + vvar*FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCurl.GetInstance: TBaseVariation; +begin + Result := TVariationCurl.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCurl.GetName: string; +begin + Result := variation_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_c1_name; + 1: Result := var_c2_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_c1_name then begin + c1 := value; + Result := True; + end + else if Name = var_c2_name then begin + c2 := value; + Result := True; + end; +end; + +function TVariationCurl.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_c1_name then begin + c1 := 0; + Result := True; + end + else if Name = var_c2_name then begin + c2 := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl.GetNrVariables: integer; +begin + Result := num_vars; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_c1_name then begin + value := c1; + Result := True; + end + else if Name = var_c2_name then begin + value := c2; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationCurl), true, false); +end. diff --git a/Variations/varCurl3D.pas b/Variations/varCurl3D.pas new file mode 100644 index 0000000..fd34c53 --- /dev/null +++ b/Variations/varCurl3D.pas @@ -0,0 +1,295 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varCurl3D; + +interface + +uses + BaseVariation, XFormMan; + +const + variation_name = 'curl3D'; + num_vars = 3; + var_cx_name = 'curl3D_cx'; + var_cy_name = 'curl3D_cy'; + var_cz_name = 'curl3D_cz'; + +type + TVariationCurl3D = class(TBaseVariation) + private + cx, cy, cz: double; + + cx2, cy2, cz2, c2, + c2x, c2y, c2z: double; + + procedure CalcCx; + procedure CalcCy; + procedure CalcCz; + procedure CalcLinear; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + Math; + +// TVariationCurl3D + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationCurl3D.Create; +var + rnd: double; +begin + rnd := 2*random - 1; + + // which maniac made this?? + {case random(3) of + 0: cx := rnd; + 1: cy := rnd; + 2: cz := rnd; + end;} + cy := 0; cy := 0; cz := 0; +end; + +procedure TVariationCurl3D.Prepare; +begin + c2x := 2 * cx; + c2y := 2 * cy; + c2z := 2 * cz; + + cx2 := sqr(cx); + cy2 := sqr(cy); + cz2 := sqr(cz); + + c2 := cx2 + cy2 + cz2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl3D.GetCalcFunction(var f: TCalcFunction); +begin +{ + if IsZero(cx) and IsZero(cy) and IsZero(cz) then f := CalcLinear + else + if IsZero(cx) and IsZero(cy) then f := CalcCz + else + if IsZero(cy) and IsZero(cz) then f := CalcCx + else + if IsZero(cz) and IsZero(cx) then f := CalcCy + else + f := CalcFunction; +} + if IsZero(cx) then begin + if IsZero(cy) then begin + if IsZero(cz) then + f := CalcLinear + else + f := CalcCz; + end + else begin + if IsZero(cz) then + f := CalcCy + else + f := CalcFunction; + end + end + else begin + if IsZero(cy) and IsZero(cz) then + f := CalcCx + else + f := CalcFunction; + end; + + f := CalcFunction; + +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl3D.CalcFunction; +var + r, r2: double; +begin + r2 := sqr(FTx^) + sqr(FTy^) + sqr(Ftz^); + r := vvar / (r2*c2 + c2x*FTx^ - c2y*FTy^ + c2z*FTz^ + 1); + + FPx^ := FPx^ + r * (FTx^ + cx*r2); + FPy^ := FPy^ + r * (FTy^ - cy*r2); + FPz^ := FPz^ + r * (FTz^ + cz*r2); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl3D.CalcCx; +var + x, r, r2: double; +begin + r2 := sqr(FTx^) + sqr(FTy^) + sqr(Ftz^); + + r := vvar / (cx2*r2 + c2x*FTx^ + 1); + + FPx^ := FPx^ + r * (FTx^ + cx*r2); + FPy^ := FPy^ + r * FTy^; + FPz^ := FPz^ + r * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl3D.CalcCy; +var + r, r2: double; +begin + r2 := sqr(FTx^) + sqr(FTy^) + sqr(Ftz^); + + r := vvar / (cy2*r2 - c2y*FTy^ + 1); + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ + r * (FTy^ - cy*r2); + FPz^ := FPz^ + r * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl3D.CalcCz; +var + r, r2: double; +begin + r2 := sqr(FTx^) + sqr(FTy^) + sqr(Ftz^); + + r := vvar / (cz2*r2 + c2z*FTz^ + 1); + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ + r * FTy^; + FPz^ := FPz^ + r * (FTz^ + cz*r2); +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationCurl3D.CalcLinear; +var + r: double; +begin + FPx^ := FPx^ + vvar * FTx^; + FPy^ := FPy^ + vvar * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCurl3D.GetInstance: TBaseVariation; +begin + Result := TVariationCurl3D.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationCurl3D.GetName: string; +begin + Result := variation_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl3D.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_cx_name; + 1: Result := var_cy_name; + 2: Result := var_cz_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl3D.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_cx_name then begin + cx := value; + Result := True; + end + else if Name = var_cy_name then begin + cy := value; + Result := True; + end + else if Name = var_cz_name then begin + cz := value; + Result := True; + end; +end; + +function TVariationCurl3D.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_cx_name then begin + cx := 0; + Result := True; + end + else if Name = var_cy_name then begin + cy := 0; + Result := True; + end + else if Name = var_cz_name then begin + cz := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl3D.GetNrVariables: integer; +begin + Result := num_vars; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationCurl3D.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_cx_name then begin + value := cx; + Result := True; + end + else if Name = var_cy_name then begin + value := cy; + Result := True; + end + else if Name = var_cz_name then begin + value := cz; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationCurl3D), true, false); +end. diff --git a/Variations/varElliptic.pas b/Variations/varElliptic.pas new file mode 100644 index 0000000..d64259b --- /dev/null +++ b/Variations/varElliptic.pas @@ -0,0 +1,131 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varElliptic; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationElliptic = class(TBaseVariation) + private + v: double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + + procedure CalcFunction; override; + procedure Prepare; override; + end; + +implementation + +uses + Math; + + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationElliptic.Prepare; +begin + v := VVAR / (PI / 2.0) +end; +procedure TVariationElliptic.CalcFunction; +function sqrt_safe(x: double): double; + begin + if x < 0.0 then Result := 0.0 + else Result := sqrt(x); + end; +var + a, b, tmp, x2, xmax: double; +begin + tmp := sqr(FTy^) + sqr(FTx^) + 1.0; + x2 := 2.0 * FTx^; + xmax := 0.5 * (sqrt(tmp + x2) + sqrt(tmp - x2)); + + a := FTx^ / xmax; + b := sqrt_safe(1.0 - sqr(a)); + + FPz^ := FPz^ + vvar * FTz^; + FPx^ := FPx^ + v * ArcTan2(a, b); + + if (FTy^ > 0) then FPy^ := FPy^ + v * Ln(xmax + sqrt_safe(xmax - 1.0)) + else FPy^ := FPy^ - v * Ln(xmax + sqrt_safe(xmax - 1.0)) +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationElliptic.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationElliptic.GetInstance: TBaseVariation; +begin + Result := TVariationElliptic.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationElliptic.GetName: string; +begin + Result := 'elliptic'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationElliptic.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationElliptic.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationElliptic.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationElliptic.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationElliptic), true, false); +end. diff --git a/Variations/varEpispiral.pas b/Variations/varEpispiral.pas new file mode 100644 index 0000000..9e64062 --- /dev/null +++ b/Variations/varEpispiral.pas @@ -0,0 +1,159 @@ +unit varEpispiral; // <-- JK Changed unit name to avoid clobbering original +//by Joel Faber (adapted for plugin example by Jed Kelsey (JK) +interface + +uses + BaseVariation, XFormMan; // <-- JK Removed some (unnecessary?) units + +const + EPS: double = 1E-6; +type + TVariationEpispiral = class(TBaseVariation) + private + n, thickness, holes : double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +// TVariationEpispiral + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationEpispiral.Create; +begin + n := 6.0; + thickness := 0.0; + holes := 1.0; +end; + +procedure TVariationEpispiral.Prepare; +begin //calculate constants + // nothing for now +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationEpispiral.CalcFunction; +var + t, theta : double; +begin + theta := arctan2(FTy^, FTx^); + + t := (random*thickness)*(1/cos(n*theta)) - holes; + + + if (abs(t) = 0) then + begin + FPx^ := FPx^; + FPy^ := FPy^; + end + else + begin + FPx^ := FPx^ + vvar*t*cos(theta); + FPy^ := FPy^ + vvar*t*sin(theta); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationEpispiral.GetInstance: TBaseVariation; +begin + Result := TVariationEpispiral.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationEpispiral.GetName: string; +begin + Result := 'epispiral'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEpispiral.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'epispiral_n'; + 1: Result := 'epispiral_thickness'; + 2: Result := 'epispiral_holes'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEpispiral.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'epispiral_n' then begin + n := Value; + Result := True; + end else if Name = 'epispiral_thickness' then begin + thickness := Value; + Result := True; + end + else if Name = 'epispiral_holes' then begin + holes := Value; + Result := True; + end +end; + +function TVariationEpispiral.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'epispiral_n' then begin + n := 6.0; + Result := True; + end else if Name = 'epispiral_thickness' then begin + thickness := 0.0; + Result := True; + end + else if Name = 'epispiral_holes' then begin + holes := 0.0; + Result := True; + end +end; + + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEpispiral.GetNrVariables: integer; +begin + Result := 3; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEpispiral.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'epispiral_n' then begin + Value := n; + Result := True; + end else if Name = 'epispiral_thickness' then begin + Value := thickness; + Result := True; + end + else if Name = 'epispiral_holes' then begin + Value := holes; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationEpispiral), true, false); // <-- JK Plugin manager does this +end. + diff --git a/Variations/varEscher.pas b/Variations/varEscher.pas new file mode 100644 index 0000000..c378c1e --- /dev/null +++ b/Variations/varEscher.pas @@ -0,0 +1,147 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varEscher; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationEscher = class(TBaseVariation) + private + escher_beta, c, d: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationEscher.Prepare; +begin + sincos(escher_beta, d, c); + c := 0.5 * (1.0 + c); + d := 0.5 * d; +end; + +procedure TVariationEscher.CalcFunction; +var sn, cs, a, lnr, m : double; +begin + a := arctan2(FTy^, FTx^); // Angular polar dimension + lnr := 0.5 * ln(FTx^*FTx^ + FTy^*FTy^); // Natural logarithm of the radial polar dimension. + + m := VVAR * exp(c * lnr - d * a); + + sincos(c * a + d * lnr, sn, cs); + + FPx^ := FPx^ + m * cs; + FPy^ := FPy^ + m * sn; + + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationEscher.Create; +begin + escher_beta := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationEscher.GetInstance: TBaseVariation; +begin + Result := TVariationEscher.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationEscher.GetName: string; +begin + Result := 'escher'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEscher.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'escher_beta'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEscher.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'escher_beta' then begin + value := frac((value + PI) / (2 * PI)) * 2 * PI - PI; + escher_beta := Value; + Result := True; + end +end; +function TVariationEscher.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'escher_beta' then begin + escher_beta := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEscher.GetNrVariables: integer; +begin + Result := 1 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationEscher.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'escher_beta' then begin + Value := escher_beta; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationEscher), true, false); +end. \ No newline at end of file diff --git a/Variations/varFalloff2.pas b/Variations/varFalloff2.pas new file mode 100644 index 0000000..a059d1d --- /dev/null +++ b/Variations/varFalloff2.pas @@ -0,0 +1,348 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varFalloff2; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationFalloff2 = class(TBaseVariation) + const + n_scatter : string = 'falloff2_scatter'; + n_mindist : string = 'falloff2_mindist'; + n_mul_x : string = 'falloff2_mul_x'; + n_mul_y : string = 'falloff2_mul_y'; + n_mul_z : string = 'falloff2_mul_z'; + n_mul_c : string = 'falloff2_mul_c'; + n_x0 : string = 'falloff2_x0'; + n_y0 : string = 'falloff2_y0'; + n_z0 : string = 'falloff2_z0'; + n_invert : string = 'falloff2_invert'; + n_blurtype : string = 'falloff2_type'; + + private + rmax: double; + x0, y0, z0: double; + scatter, mindist: double; + invert, blurtype: integer; + mul_x, mul_y, mul_z, mul_c: double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure CalcFunctionRadial; + procedure CalcFunctionGaussian; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationFalloff2.Prepare; +begin + rmax := 0.04 * scatter; +end; + +procedure TVariationFalloff2.GetCalcFunction(var f: TCalcFunction); +begin + if blurtype = 1 then f := CalcFunctionRadial + else if blurtype = 2 then f := CalcFunctionGaussian + else f := CalcFunction; +end; +procedure TVariationFalloff2.CalcFunction; +var + in_x, in_y, in_z, d: double; +begin + in_x := FTx^; + in_y := FTy^; + in_z := FTz^; + + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + FPx^ := FPx^ + VVAR * (in_x + mul_x * random * d); + FPy^ := FPy^ + VVAR * (in_y + mul_y * random * d); + FPz^ := FPz^ + VVAR * (in_z + mul_z * random * d); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; +procedure TVariationFalloff2.CalcFunctionRadial; +var + in_x, in_y, in_z, d, r_in: double; + sigma, phi, r, sins, coss, sinp, cosp: double; +begin + in_x := FTx^; + in_y := FTy^; + in_z := FTz^; + + r_in := sqrt(sqr(in_x) + sqr(in_y) + sqr(in_z)) + 1e-6; + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + sigma := ArcSin(in_z / r_in) + mul_z * random * d; + phi := ArcTan2(in_y, in_x) + mul_y * random * d; + r := r_in + mul_x * random * d; + + SinCos(sigma, sins, coss); + SinCos(phi, sinp, cosp); + + FPx^ := FPx^ + VVAR * (r * coss * cosp); + FPy^ := FPy^ + VVAR * (r * coss * sinp); + FPz^ := FPz^ + VVAR * (sins); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; +procedure TVariationFalloff2.CalcFunctionGaussian; +var + in_x, in_y, in_z, d: double; + sigma, phi, r, sins, coss, sinp, cosp: double; +begin + in_x := FTx^; + in_y := FTy^; + in_z := FTz^; + + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + sigma := d * random * 2 * PI; + phi := d * random * PI; + r := d * random; + + SinCos(sigma, sins, coss); + SinCos(phi, sinp, cosp); + + FPx^ := FPx^ + VVAR * (in_x + mul_x * r * coss * cosp); + FPy^ := FPy^ + VVAR * (in_y + mul_y * r * coss * sinp); + FPz^ := FPz^ + VVAR * (in_z + mul_z * r * sins); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationFalloff2.Create; +begin + scatter := 1; + mindist := 0.5; + mul_x := 1; + mul_y := 1; + mul_z := 0; + mul_c := 0; + x0 := 0; + y0 := 0; + z0 := 0; + invert := 0; + blurtype := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationFalloff2.GetInstance: TBaseVariation; +begin + Result := TVariationFalloff2.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationFalloff2.GetName: string; +begin + Result := 'falloff2'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFalloff2.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := n_scatter; + 1: Result := n_mindist; + 2: Result := n_mul_x; + 3: Result := n_mul_y; + 4: Result := n_mul_z; + 5: Result := n_mul_c; + 6: Result := n_x0; + 7: Result := n_y0; + 8: Result := n_z0; + 9: Result := n_invert; + 10: Result := n_blurtype; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFalloff2.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_scatter then begin + if Value < 1e-6 then Value := 1e-6; + scatter := Value; + Result := True; + end else if Name = n_mindist then begin + if Value < 0 then Value := 0; + mindist := Value; + Result := True; + end else if Name = n_mul_x then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_x := Value; + Result := True; + end else if Name = n_mul_y then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_y := Value; + Result := True; + end else if Name = n_mul_z then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_z := Value; + Result := True; + end else if Name = n_mul_c then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_c := Value; + Result := True; + end else if Name = n_x0 then begin + x0 := Value; + Result := True; + end else if Name = n_y0 then begin + y0 := Value; + Result := True; + end else if Name = n_z0 then begin + z0 := Value; + Result := True; + end else if Name = n_invert then begin + if (Value > 1) then Value := 1; + if (Value < 0) then Value := 0; + invert := Round(Value); + Result := True; + end else if Name = n_blurtype then begin + if (Value > 2) then Value := 2; + if (Value < 0) then Value := 0; + blurtype := Round(Value); + Result := True; + end +end; +function TVariationFalloff2.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = n_scatter then begin + scatter := 1; + Result := True; + end else if Name = n_mindist then begin + mindist := 0.5; + Result := True; + end else if Name = n_mul_x then begin + mul_x := 1; + Result := True; + end else if Name = n_mul_y then begin + mul_y := 1; + Result := True; + end else if Name = n_mul_z then begin + mul_z := 0; + Result := True; + end else if Name = n_mul_c then begin + mul_c := 0; + Result := True; + end else if Name = n_x0 then begin + x0 := 0; + Result := True; + end else if Name = n_y0 then begin + y0 := 0; + Result := True; + end else if Name = n_z0 then begin + z0 := 0; + Result := True; + end else if Name = n_invert then begin + invert := 0; + Result := True; + end else if Name = n_blurtype then begin + blurtype := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFalloff2.GetNrVariables: integer; +begin + Result := 11 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFalloff2.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_scatter then begin + Value := scatter; + Result := True; + end else if Name = n_mindist then begin + Value := mindist; + Result := True; + end else if Name = n_mul_x then begin + Value := mul_x; + Result := True; + end else if Name = n_mul_y then begin + Value := mul_y; + Result := True; + end else if Name = n_mul_z then begin + Value := mul_z; + Result := True; + end else if Name = n_mul_c then begin + Value := mul_c; + Result := True; + end else if Name = n_x0 then begin + Value := x0; + Result := True; + end else if Name = n_y0 then begin + Value := y0; + Result := True; + end else if Name = n_z0 then begin + Value := z0; + Result := True; + end else if Name = n_invert then begin + Value := invert; + Result := True; + end else if Name = n_blurtype then begin + Value := blurtype; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationFalloff2), true, false); +end. \ No newline at end of file diff --git a/Variations/varFan2.pas b/Variations/varFan2.pas new file mode 100644 index 0000000..df9f3c1 --- /dev/null +++ b/Variations/varFan2.pas @@ -0,0 +1,172 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varFan2; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationFan2 = class(TBaseVariation) + private + FX, FY: double; + dy, dx, dx2: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationFan2 } + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationFan2.Prepare; +const + EPS = 1E-10; +begin + dy := FY; + dx := pi * (sqr(FX) + EPS); + dx2 := dx/2; +end; + +procedure TVariationFan2.CalcFunction; +var + r, a : double; + sinr, cosr: double; + Angle: double; +begin +{ + r := sqrt(FTx^ * FTx^ + FTy^ * FTy^); + if (FTx^ < -EPS) or (FTx^ > EPS) or (FTy^ < -EPS) or (FTy^ > EPS) then + Angle := arctan2(FTx^, FTy^) + else + Angle := 0.0; + + dy := FY; + dx := PI * (sqr(FX) + EPS); + dx2 := dx/2; + + t := Angle+dy - System.Int((Angle + dy)/dx) * dx; + if (t > dx2) then + a := Angle - dx2 + else + a := Angle + dx2; + + FPx^ := FPx^ + vvar * r * sin(a); + FPy^ := FPy^ + vvar * r * cos(a); +} + Angle := arctan2(FTx^, FTy^); + if System.Frac((Angle + dy)/dx) > 0.5 then + a := Angle - dx2 + else + a := Angle + dx2; + SinCos(a, sinr, cosr); + r := vvar * sqrt(sqr(FTx^) + sqr(FTy^)); + FPx^ := FPx^ + r * cosr; + FPy^ := FPy^ + r * sinr; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationFan2.Create; +begin + FX := 2 * Random - 1; + FY := 2 * Random - 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationFan2.GetInstance: TBaseVariation; +begin + Result := TVariationFan2.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationFan2.GetName: string; +begin + Result := 'fan2'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFan2.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'fan2_x'; + 1: Result := 'fan2_y'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFan2.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'fan2_x' then begin + FX := Value; + Result := True; + end else if Name = 'fan2_y' then begin + FY := Value; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFan2.GetNrVariables: integer; +begin + Result := 2 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFan2.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'fan2_x' then begin + Value := FX; + Result := True; + end else if Name = 'fan2_y' then begin + Value := FY; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationFan2), true, false); +end. diff --git a/Variations/varFoci.pas b/Variations/varFoci.pas new file mode 100644 index 0000000..2ef8fa0 --- /dev/null +++ b/Variations/varFoci.pas @@ -0,0 +1,118 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varFoci; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationFoci = class(TBaseVariation) + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationFoci.CalcFunction; +var + expx, expnx, siny, cosy, tmp: double; +begin + expx := exp(FTx^) * 0.5; + expnx := 0.25 / expx; + sincos(FTy^, siny, cosy); + + tmp := ( expx + expnx - cosy ); + if (tmp = 0) then tmp := 1e-6; + tmp := VVAR / tmp; + + FPx^ := FPx^ + (expx - expnx) * tmp; + FPy^ := FPy^ + siny * tmp; + + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationFoci.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationFoci.GetInstance: TBaseVariation; +begin + Result := TVariationFoci.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationFoci.GetName: string; +begin + Result := 'foci'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFoci.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFoci.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFoci.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationFoci.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationFoci), true, false); +end. diff --git a/Variations/varGenericPlugin.pas b/Variations/varGenericPlugin.pas new file mode 100644 index 0000000..d5ef909 --- /dev/null +++ b/Variations/varGenericPlugin.pas @@ -0,0 +1,360 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +{ + Variation Plugin DLL support for Apophysis: + Generic Plugin Support Unit + Started by Jed Kelsey, June 2007 + + + Portions Copyright (C) 2008 Joel Faber + + February 2008: + - Remove 30 plugin limit + - Reset variables +} + +unit varGenericPlugin; + +interface + +uses + BaseVariation, XFormMan, Settings, + Classes, //TStrings/TStringList + SysUtils, //FindFirst/FindNext/FindClose + Forms; //MessageBox + +type + TPluginVariationClass = class of TPluginVariation; + + TPluginData = record + Instance: Integer; + PluginHandle: THandle; + PluginClass: TPluginVariationClass; + + PluginVarGetName: function: PAnsiChar; cdecl; + PluginVarGetNrVariables: function: Integer; cdecl; + PluginVarGetVariableNameAt: function(const Index: integer): PAnsiChar; cdecl; + + PluginVarCreate: function: Pointer; cdecl; + PluginVarDestroy: function(var MyVariation: Pointer): LongBool; cdecl; + PluginVarInit: function(MyVariation, FPx, FPy, FTx, FTy: Pointer; vvar: double): LongBool; cdecl; + PluginVarInit3D: function(MyVariation, FPx, FPy, FPz, FTx, FTy, FTz: Pointer; vvar: double): LongBool; cdecl; + PluginVarInitDC: function(MyVariation, FPx, FPy, FPz, FTx, FTy, FTz, color: Pointer; vvar, a, b, c, d, e, f: double): LongBool; cdecl; + PluginVarPrepare: function(MyVariation: Pointer): LongBool; cdecl; + PluginVarCalc: function(MyVariation: Pointer): LongBool; cdecl; + PluginVarGetVariable: function(MyVariation: Pointer; const Name: PAnsiChar; var value: double): LongBool; cdecl; + PluginVarSetVariable: function(MyVariation: Pointer; const Name: PAnsiChar; var value: double): LongBool; cdecl; + PluginVarResetVariable:function(MyVariation: Pointer; const Name: PAnsiChar) : LongBool; cdecl; + end; + PPluginData = ^TPluginData; + + // This class serves as a proxy for the plugin variations. + TPluginVariation = class(TBaseVariation) + + private + PluginData : TPluginData; + MyVariation : Pointer; + public + constructor Create(varData : TPluginData); + destructor Destroy; override; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +type + TVariationPluginLoader = class (TVariationLoader) + public + constructor Create(varData : TPluginData); + destructor Destroy; override; + + function GetName: string; override; + function GetInstance: TBaseVariation; override; + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + private + PluginData : TPluginData; + end; + +procedure InitializePlugins; + +const CurrentPlatform = +{$ifdef Apo7X64} + $00000040 +{$else} + $00000020 +{$endif}; + + ////////////////////////////////////////////////////////////////////// + +implementation + +uses + Windows, //LoadLibrary + Math, + Global, + Registry; + +{ TPluginVariation } + +/////////////////////////////////////////////////////////////////////////////// + +constructor TVariationPluginLoader.Create(varData : TPluginData); +begin + PluginData := varData; +end; + +destructor TVariationPluginLoader.Destroy; +begin + FreeLibrary(PluginData.PluginHandle); +end; + +function TVariationPluginLoader.GetName : string; +begin + Result := String(PluginData.PluginVarGetName); +end; + +function TVariationPluginLoader.GetInstance: TBaseVariation; +begin + Result := TPluginVariation.Create(PluginData); +end; + +function TVariationPluginLoader.GetNrVariables: integer; +begin + Result := PluginData.PluginVarGetNrVariables; +end; + +function TVariationPluginLoader.GetVariableNameAt(const Index: integer): string; +begin + Result := String(PluginData.PluginVarGetVariableNameAt(Index)); +end; + +/////////////////////////////////////////////////////////////////////////////// + +procedure TPluginVariation.Prepare; +begin + with PluginData do begin + if @PluginVarInitDC <> nil then + PluginVarInitDC(MyVariation, Pointer(FPX), Pointer(FPy), Pointer(FPz), Pointer(FTx), Pointer(FTy), Pointer(FTz), Pointer(color), vvar, a, b, c, d, e, f) + else if @PluginVarInit3D <> nil then + PluginVarInit3D(MyVariation, Pointer(FPX), Pointer(FPy), Pointer(FPz), Pointer(FTx), Pointer(FTy), Pointer(FTz), vvar) + else + PluginVarInit(MyVariation, Pointer(FPX), Pointer(FPy), Pointer(FTx), Pointer(FTy), vvar); + PluginVarPrepare(MyVariation); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TPluginVariation.CalcFunction; +begin + PluginData.PluginVarCalc(MyVariation); +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TPluginVariation.Create(varData : TPluginData); +begin + PluginData := varData; + MyVariation := PluginData.PluginVarCreate; +end; + +/////////////////////////////////////////////////////////////////////////////// +destructor TPluginVariation.Destroy; +begin + PluginData.PluginVarDestroy(MyVariation); + inherited; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TPluginVariation.GetInstance: TBaseVariation; +begin + Result := nil; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TPluginVariation.GetName: string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TPluginVariation.GetNrVariables: integer; +begin + Result := PluginData.PluginVarGetNrVariables; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TPluginVariation.GetVariableNameAt(const Index: integer): string; +begin + Result := String(PluginData.PluginVarGetVariableNameAt(Index)); +end; + +/////////////////////////////////////////////////////////////////////////////// +function TPluginVariation.SetVariable(const Name: string; var value: double): boolean; +begin + Result := PluginData.PluginVarSetVariable(MyVariation,PAnsiChar(AnsiString(Name)),value); +end; + +/////////////////////////////////////////////////////////////////////////////// +function TPluginVariation.GetVariable(const Name: string; var value: double): boolean; +begin + Result := PluginData.PluginVarGetVariable(MyVariation,PAnsiChar(AnsiString(Name)),value); +end; + +/////////////////////////////////////////////////////////////////////////////// +function TPluginVariation.ResetVariable(const Name: string) : boolean; +var + dummy: double; +begin + if @PluginData.PluginVarResetVariable <> nil then + Result := PluginData.PluginVarResetVariable(MyVariation, PAnsiChar(AnsiString(Name))) + else begin + dummy := 0; + Result := PluginData.PluginVarSetVariable(MyVariation,PAnsiChar(AnsiString(Name)), dummy); + end; +end; + +function GetPlatformOf(dllPath: string): integer; +var + fs: TFilestream; + signature: DWORD; + dos_header: IMAGE_DOS_HEADER; + pe_header: IMAGE_FILE_HEADER; + opt_header: IMAGE_OPTIONAL_HEADER; +begin + fs := TFilestream.Create(dllPath, fmOpenread or fmShareDenyNone); + try + fs.read(dos_header, SizeOf(dos_header)); + if dos_header.e_magic <> IMAGE_DOS_SIGNATURE then + begin + Result := 0; + Exit; + end; + + fs.seek(dos_header._lfanew, soFromBeginning); + fs.read(signature, SizeOf(signature)); + if signature <> IMAGE_NT_SIGNATURE then + begin + Result := 0; + Exit; + end; + + fs.read(pe_header, SizeOf(pe_header)); + case pe_header.Machine of + IMAGE_FILE_MACHINE_I386: Result := $00000020; + IMAGE_FILE_MACHINE_AMD64: Result := $00000040; + else + Result := 0; + end; { Case } + + finally + fs.Free; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure InitializePlugins; +var + Registry: TRegistry; + searchResult: TSearchRec; + dllPath, name, msg: string; + PluginData : TPluginData; + errno:integer; + errstr:string; +begin + NumBuiltinVars := NRLOCVAR + GetNrRegisteredVariations; + PluginPath := ReadPluginDir; + + // Try to find regular files matching *.dll in the plugins dir + if FindFirst(PluginPath + '*.dll', faAnyFile, searchResult) = 0 then + begin + repeat + with PluginData do begin + dllPath := PluginPath + searchResult.Name; + + //Check plugin platform + if CurrentPlatform <> GetPlatformOf(dllPath) + then continue; + + //Load DLL and initialize plugins! + PluginHandle := LoadLibrary(PChar(dllPath)); + if PluginHandle<>0 then begin + @PluginVarGetName := GetProcAddress(PluginHandle,'PluginVarGetName'); + if @PluginVarGetName = nil then begin // Must not be a valid plugin! + FreeLibrary(PluginHandle); + msg := msg + 'Invalid plugin type: "' + searchResult.Name + '" is not a plugin' + #13#10; + continue; + end; + name := String(PluginVarGetName); + if GetVariationIndex(name) >= 0 then begin + FreeLibrary(PluginHandle); + msg := msg + 'Cannot load plugin from ' + searchResult.Name + ': variation "' + name + '" already exists!' + #13#10; + end + else begin + @PluginVarGetNrVariables := GetProcAddress(PluginHandle,'PluginVarGetNrVariables'); + @PluginVarGetVariableNameAt := GetProcAddress(PluginHandle,'PluginVarGetVariableNameAt'); + @PluginVarCreate := GetProcAddress(PluginHandle,'PluginVarCreate'); + @PluginVarDestroy := GetProcAddress(PluginHandle,'PluginVarDestroy'); + @PluginVarInit := GetProcAddress(PluginHandle,'PluginVarInit'); + @PluginVarInit3D := GetProcAddress(PluginHandle,'PluginVarInit3D'); + @PluginVarInitDC := GetProcAddress(PluginHandle,'PluginVarInitDC'); + @PluginVarPrepare := GetProcAddress(PluginHandle,'PluginVarPrepare'); + @PluginVarCalc := GetProcAddress(PluginHandle,'PluginVarCalc'); + @PluginVarGetVariable := GetProcAddress(PluginHandle,'PluginVarGetVariable'); + @PluginVarSetVariable := GetProcAddress(PluginHandle,'PluginVarSetVariable'); + @PluginVarResetVariable := GetProcAddress(PluginHandle,'PluginVarResetVariable'); + + RegisterVariation(TVariationPluginLoader.Create(PluginData), @PluginVarInit3D <> nil, @PluginVarInitDC <> nil); + RegisterVariationFile(ExtractFilePath(Application.ExeName) + 'Plugins\' + searchResult.Name, name); + end; + end else begin + errno := GetLastError; + errstr := SysErrorMessage(errno); + msg := msg + 'Cannot open plugin file: ' + searchResult.Name + ' (Error #' + IntToStr(GetLastError) + ' - ' + errstr + ')' + #13#10; + end; + end; + until (FindNext(searchResult) <> 0); + SysUtils.FindClose(searchResult); //Since we use Windows unit (LoadLibrary) + + if msg <> '' then + Application.MessageBox( + PChar('There were problems with some of the plugins:' + #13#10#13#10 + msg), + 'Warning', MB_ICONWARNING or MB_OK); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// + +end. + diff --git a/Variations/varHemisphere.pas b/Variations/varHemisphere.pas new file mode 100644 index 0000000..45845d3 --- /dev/null +++ b/Variations/varHemisphere.pas @@ -0,0 +1,97 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varHemisphere; + +interface + +uses + BaseVariation, XFormMan; + +const + var_name = 'hemisphere'; + +{$define _ASM_} + +type + TVariationHemisphere = class(TBaseVariation) + private + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationSpherize } + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationHemisphere.CalcFunction; +var + t: double; +begin + t := vvar / sqrt(sqr(FTx^) + sqr(FTy^) + 1); + + FPx^ := FPx^ + FTx^ * t; + FPy^ := FPy^ + FTy^ * t; + FPz^ := FPz^ + t; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationHemisphere.Create; +begin + +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationHemisphere.GetInstance: TBaseVariation; +begin + Result := TVariationHemisphere.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationHemisphere.GetName: string; +begin + Result := var_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationHemisphere.GetNrVariables: integer; +begin + Result := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationHemisphere), true, false); +end. diff --git a/Variations/varJulia3Djf.pas b/Variations/varJulia3Djf.pas new file mode 100644 index 0000000..7a3ddba --- /dev/null +++ b/Variations/varJulia3Djf.pas @@ -0,0 +1,462 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varJulia3Djf; // original variation code by Joel Faber, modified & optimized by Peter Sdobnov + +interface + +uses +{$ifdef Apo7X64} +{$else} +AsmRandom, +{$endif} + BaseVariation, XFormMan; + +const + var_name = 'julia3D'; + var_n_name='julia3D_power'; + +{$ifdef Apo7X64} +{$else} + {$define _ASM_} +{$endif} + +type + TVariationJulia3DJF = class(TBaseVariation) + private + N: integer; + + absN: integer; + cN: double; + + procedure CalcPower1; + procedure CalcPowerMinus1; + procedure CalcPower2; + procedure CalcPowerMinus2; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + Math; + +// TVariationJulia3DJF + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationJulia3DJF.Create; +begin + N := random(5) + 2; + if random(2) = 0 then N := -N; +end; + +procedure TVariationJulia3DJF.Prepare; +begin + absN := abs(N); + cN := (1/N - 1) / 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJulia3DJF.GetCalcFunction(var f: TCalcFunction); +begin + if N = 2 then f := CalcPower2 + else if N = -2 then f := CalcPowerMinus2 + else if N = 1 then f := CalcPower1 + else if N = -1 then f := CalcPowerMinus1 + else f := CalcFunction; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJulia3DJF.CalcFunction; +{$ifndef _ASM_} +var + r, r2d, z, tmp: double; + sina, cosa: extended; +begin + z := FTz^ / absN; + r2d := sqr(FTx^) + sqr(FTy^); + r := vvar * Math.Power(r2d + sqr(z), cN); // r^n / sqrt(r) --> r^(n-0.5) + + FPz^ := FPz^ + r * z; + + tmp := r * sqrt(r2d); + sincos((arctan2(FTy^, FTx^) + 2*pi*random(absN)) / N, sina, cosa); + + FPx^ := FPx^ + tmp * cosa; + FPy^ := FPy^ + tmp * sina; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx + 32] // FTz + fidiv dword ptr [eax + absN] + fld qword ptr [edx] // FTx + fld qword ptr [edx + 8] // FTy + fld st(1) + fmul st, st + fld st(1) + fmul st, st + faddp + fld qword ptr [eax + cN] + fld st(4) + fmul st, st + fadd st, st(2) +// --- x^y = 2^(y*log2(x)) + fyl2x + fld st + frndint + fsub st(1), st + fxch st(1) + f2xm1 + fld1 + fadd + fscale + fstp st(1) +// --- + fmul qword ptr [eax + vvar] + + fmul st(4), st + fxch st(1) + fsqrt + fmulp + + fxch st(2) + fpatan + mov ecx, eax + mov eax, dword ptr [eax + absN] + call AsmRandInt + push eax + fild dword ptr [esp] + add esp, 4 + fldpi + fadd st, st + fmulp + faddp + fidiv dword ptr [ecx + N] + + fsincos + mov edx, [ecx + FPx] + fmul st, st(2) + fadd qword ptr [edx] // FPx + fstp qword ptr [edx] + fmulp + fadd qword ptr [edx + 8] // FPy + fstp qword ptr [edx + 8] + fadd qword ptr [edx + $18] // FPz + fstp qword ptr [edx + $18] + fwait +{$endif} +end; + +procedure TVariationJulia3DJF.CalcPower2; +{$ifndef _ASM_} +var + r, r2d, z, tmp: double; + sina, cosa: extended; +begin + z := FTz^ / 2; + r2d := sqr(FTx^) + sqr(FTy^); + r := vvar / sqrt(sqrt(r2d + sqr(z))); // vvar * sqrt(r3d) / r3d --> vvar / sqrt(r3d) + + FPz^ := FPz^ + r * z; + + tmp := r * sqrt(r2d); + sincos(arctan2(FTy^, FTx^) / 2 + pi*random(2), sina, cosa); + + FPx^ := FPx^ + tmp * cosa; + FPy^ := FPy^ + tmp * sina; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx + 32] // FTz + fld1 + fadd st, st + fdiv st(1), st + fld qword ptr [edx + 8] // FTy + fld qword ptr [edx] // FTx + fld st(1) + fld st(1) + fpatan + fdivrp st(3), st + + fmul st, st + fxch st(1) + fmul st, st + faddp + fld st(2) + fmul st, st + fadd st, st(1) + fsqrt + fsqrt + fdivr qword ptr [eax + vvar] + fmul st(3), st + + fxch st(1) + fsqrt + fmulp + fxch st(1) + + mov ecx, eax + mov eax, 2 + call AsmRandInt + fldpi + push eax + fimul dword ptr [esp] + add esp, 4 + faddp + + fsincos + mov edx, [ecx + FPx] + fmul st, st(2) + fadd qword ptr [edx] // FPx + fstp qword ptr [edx] + fmulp + fadd qword ptr [edx + 8] // FPy + fstp qword ptr [edx + 8] + fadd qword ptr [edx + $18] // FPz + fstp qword ptr [edx + $18] + fwait +{$endif} +end; + +procedure TVariationJulia3DJF.CalcPowerMinus2; +{$ifndef _ASM_} +var + r, r2d, r3d, z, tmp: double; + sina, cosa: extended; +begin + z := FTz^ / 2; + r2d := sqr(FTx^) + sqr(FTy^); + r3d := sqrt(r2d + sqr(z)); + r := vvar / (sqrt(r3d) * r3d); + + FPz^ := FPz^ + r * z; + + tmp := r * sqrt(r2d); + sincos(arctan2(FTy^, FTx^) / 2 + pi*random(2), sina, cosa); + + FPx^ := FPx^ + tmp * cosa; + FPy^ := FPy^ - tmp * sina; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx + 32] // FTz + fld1 + fadd st, st + fdiv st(1), st + fld qword ptr [edx + 8] // FTy + fld qword ptr [edx] // FTx + fld st(1) + fld st(1) + fpatan + fdivrp st(3), st + + fmul st, st + fxch st(1) + fmul st, st + faddp + fld st(2) + fmul st, st + fadd st, st(1) + fsqrt + fld st + fsqrt + fmulp + fdivr qword ptr [eax + vvar] + fmul st(3), st + + fxch st(1) + fsqrt + fmulp + fxch st(1) + + mov ecx, eax + mov eax, 2 + call AsmRandInt + fldpi + push eax + fimul dword ptr [esp] + add esp, 4 + faddp + + fsincos + mov edx, [ecx + FPx] + fmul st, st(2) + fadd qword ptr [edx] // FPx + fstp qword ptr [edx] + fmulp + fsubr qword ptr [edx + 8] // FPy + fstp qword ptr [edx + 8] + fadd qword ptr [edx + $18] // FPz + fstp qword ptr [edx + $18] + fwait +{$endif} +end; + +procedure TVariationJulia3DJF.CalcPower1; +{$ifndef _ASM_} +begin + FPx^ := FPx^ + vvar * FTx^; + FPy^ := FPy^ + vvar * FTy^; + FPz^ := FPz^ + vvar * FTz^; +{$else} +asm + fld qword ptr [eax + vvar] + mov edx, [eax + FTx] + fld qword ptr [edx] // FTx + fmul st, st(1) + fadd qword ptr [edx + 16] // FPx + fstp qword ptr [edx + 16] + + fld qword ptr [edx + 8] // FTy + fmul st, st(1) + fadd qword ptr [edx + 24] // FPy + fstp qword ptr [edx + 24] + + fmul qword ptr [edx + 32] // FTz + fadd qword ptr [edx + 40] // FPz + fstp qword ptr [edx + 40] + + fwait +{$endif} +end; + +procedure TVariationJulia3DJF.CalcPowerMinus1; +{$ifndef _ASM_} +var + r: double; +begin + r := vvar / (sqr(FTx^) + sqr(FTy^) + sqr(FTz^)); + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ - r * FTy^; + FPz^ := FPz^ + r * FTz^; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx + 32] // FTz + fld qword ptr [edx + 8] // FTy + fld qword ptr [edx] // FTx + fld st(2) + fmul st, st + fld st(2) + fmul st, st + faddp + fld st(1) + fmul st, st + faddp + fdivr qword ptr [eax + vvar] + + fmul st(3), st + fmul st(2), st + fmulp + fadd qword ptr [edx + 16] // FPx + fstp qword ptr [edx + 16] + fsubr qword ptr [edx + 24] // FPy + fstp qword ptr [edx + 24] + fadd qword ptr [edx + 40] // FPz + fstp qword ptr [edx + 40] + fwait +{$endif} +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJulia3DJF.GetInstance: TBaseVariation; +begin + Result := TVariationJulia3DJF.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJulia3DJF.GetName: string; +begin + Result := var_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3DJF.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_n_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3DJF.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + N := Round(Value); + if N = 0 then N := 1; + Value := N; + Result := True; + end; +end; + +function TVariationJulia3DJF.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_n_name then begin + if N = 2 then N := -2 + else N := 2; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3DJF.GetNrVariables: integer; +begin + Result := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3DJF.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + Value := N; + Result := true; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationJulia3DJF), true, false); +end. + diff --git a/Variations/varJulia3Dz.pas b/Variations/varJulia3Dz.pas new file mode 100644 index 0000000..50bb720 --- /dev/null +++ b/Variations/varJulia3Dz.pas @@ -0,0 +1,445 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varJulia3Dz; + +interface + +uses +{$ifdef Apo7X64} +{$else} +AsmRandom, +{$endif} + BaseVariation, XFormMan; + +const + var_name = 'julia3Dz'; + var_n_name='julia3Dz_power'; + +{$ifdef Apo7X64} +{$else} + {$define _ASM_} +{$endif} + +type + TVariationJulia3D = class(TBaseVariation) + private + N: integer; + + absN: integer; + cN: double; + + procedure CalcPower1; + procedure CalcPowerMinus1; + procedure CalcPower2; + procedure CalcPowerMinus2; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + Math; + +// TVariationJulia3D + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationJulia3D.Create; +begin + N := random(5) + 2; + if random(2) = 0 then N := -N; +end; + +procedure TVariationJulia3D.Prepare; +begin + absN := abs(N); + cN := 1 / N / 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJulia3D.GetCalcFunction(var f: TCalcFunction); +begin + if N = 2 then f := CalcPower2 + else if N = -2 then f := CalcPowerMinus2 + else if N = 1 then f := CalcPower1 + else if N = -1 then f := CalcPowerMinus1 + else f := CalcFunction; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJulia3D.CalcFunction; +{$ifndef _ASM_} +var + r, r2d: double; + sina, cosa: extended; +begin + r2d := sqr(FTx^) + sqr(FTy^); + r := vvar * Math.Power(r2d, cN); + + FPz^ := FPz^ + r * FTz^ / (sqrt(r2d) * absN); + + sincos((arctan2(FTy^, FTx^) + 2*pi*random(absN)) / N, sina, cosa); + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx] // FTx + fld qword ptr [edx + 8] // FTy + fld st(1) + fmul st, st + fld st(1) + fmul st, st + faddp + fld qword ptr [eax + cN] + fld st(1) +// --- x^y = 2^(y*log2(x)) + fyl2x + fld st + frndint + fsub st(1), st + fxch st(1) + f2xm1 + fld1 + fadd + fscale + fstp st(1) +// --- + fmul qword ptr [eax + vvar] + + fxch st(1) + fsqrt + fimul dword ptr [eax + absN] + fdivr st, st(1) + fmul qword ptr [edx + 32] // FTz + fadd qword ptr [edx + 40] // FPz + fstp qword ptr [edx + 40] + + fxch st(2) + fpatan + mov ecx, eax + mov eax, dword ptr [eax + absN] + call AsmRandInt + push eax + fild dword ptr [esp] + add esp, 4 + fldpi + fadd st, st + fmulp + faddp + fidiv dword ptr [ecx + N] + + fsincos + fmul st, st(2) + + mov edx, [ecx + FPx] + fadd qword ptr [edx] // FPx + fstp qword ptr [edx] + fmulp + fadd qword ptr [edx + 8] // FPy + fstp qword ptr [edx + 8] + fwait +{$endif} +end; + +procedure TVariationJulia3D.CalcPower2; +{$ifndef _ASM_} +var + r, r2d: double; + sina, cosa: extended; +begin + r2d := sqrt(sqr(FTx^) + sqr(FTy^)); + r := vvar * sqrt(r2d); + + FPz^ := FPz^ + r * FTz^ / r2d / 2; + + sincos((arctan2(FTy^, FTx^)/2 + pi*random(2)), sina, cosa); + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx + 8] // FTy + fld qword ptr [edx] // FTx + fld st(1) + fld st(1) + fpatan + fld1 + fadd st, st + fdivp st(1), st + mov ecx, eax + mov eax, 2 + call AsmRandInt + fldpi + push eax + fimul dword ptr [esp] + add esp, 4 + faddp + + fxch st(2) + fmul st, st + fxch st(1) + fmul st, st + faddp + fsqrt + + fld st + + fsqrt + fmul qword ptr [ecx + vvar] + + fxch st(1) + fadd st, st + fdivr st, st(1) + + mov edx, [ecx + FPx] + fmul qword ptr [edx + $10] // FTz + fadd qword ptr [edx + $18] // FPz + fstp qword ptr [edx + $18] + + fxch st(1) + + fsincos + + fmul st, st(2) + fadd qword ptr [edx] // FPx + fstp qword ptr [edx] + fmulp + fadd qword ptr [edx + 8] // FPy + fstp qword ptr [edx + 8] + fwait +{$endif} +end; + +procedure TVariationJulia3D.CalcPowerMinus2; +{$ifndef _ASM_} +var + r, r2d: double; + sina, cosa: extended; +begin + r2d := sqrt(sqr(FTx^) + sqr(FTy^)); + r := vvar / sqrt(r2d); + + FPz^ := FPz^ + r * FTz^ / r2d / 2; + + sincos(pi*random(2) - arctan2(FTy^, FTx^)/2, sina, cosa); + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx + 8] // FTy + fld qword ptr [edx] // FTx + fld st(1) + fld st(1) + fpatan + fld1 + fadd st, st + fdivp st(1), st + mov ecx, eax + mov eax, 2 + call AsmRandInt + fldpi + push eax + fimul dword ptr [esp] + add esp, 4 + faddp + + fxch st(2) + fmul st, st + fxch st(1) + fmul st, st + faddp + fsqrt + + fld st + + fsqrt + fdivr qword ptr [ecx + vvar] + + fxch st(1) + fadd st, st + fdivr st, st(1) + mov edx, [ecx + FPx] + fmul qword ptr [edx + $10] // FTz + fadd qword ptr [edx + $18] + fstp qword ptr [edx + $18] + + fxch st(1) + fsincos + + fmul st, st(2) + mov edx, [ecx + FPx] + fadd qword ptr [edx] // FPx + fstp qword ptr [edx] + fmulp + fsubr qword ptr [edx + 8] // FPy + fstp qword ptr [edx + 8] + fwait +{$endif} +end; + +procedure TVariationJulia3D.CalcPower1; +{$ifndef _ASM_} +begin + FPx^ := FPx^ + vvar * FTx^; + FPy^ := FPy^ + vvar * FTy^; + FPz^ := FPz^ + vvar * FTz^; +{$else} +asm + fld qword ptr [eax + vvar] + mov edx, [eax + FTx] + fld qword ptr [edx] // FTx + fmul st, st(1) + fadd qword ptr [edx + 16] // FPx + fstp qword ptr [edx + 16] + + fld qword ptr [edx + 8] // FTy + fmul st, st(1) + fadd qword ptr [edx + 24] // FPy + fstp qword ptr [edx + 24] + + fmul qword ptr [edx + 32] // FTz + fadd qword ptr [edx + 40] // FPz + fstp qword ptr [edx + 40] + + fwait +{$endif} +end; + +procedure TVariationJulia3D.CalcPowerMinus1; +{$ifndef _ASM_} +var + r: double; +begin + r := vvar / (sqr(FTx^) + sqr(FTy^)); + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ - r * FTy^; + FPz^ := FPz^ + r * FTz^; +{$else} +asm + mov edx, [eax + FTx] + fld qword ptr [edx + 8] // FTy + fld qword ptr [edx] // FTx + fld st(1) + fmul st, st + fld st(1) + fmul st, st + faddp + fdivr qword ptr [eax + vvar] + + fmul st(2), st + fmul st(1), st + fmul qword ptr [edx + 32] // FTz + fadd qword ptr [edx + 40] // FPz + fstp qword ptr [edx + 40] + + fadd qword ptr [edx + 16] // FPx + fstp qword ptr [edx + 16] + fsubr qword ptr [edx + 24] // FPy + fstp qword ptr [edx + 24] + fwait +{$endif} +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJulia3D.GetInstance: TBaseVariation; +begin + Result := TVariationJulia3D.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJulia3D.GetName: string; +begin + Result := var_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3D.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_n_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3D.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + N := Round(Value); + if N = 0 then N := 1; + Value := N; + Result := True; + end; +end; + +function TVariationJulia3D.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_n_name then begin + if N = 2 then N := -2 + else N := 2; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3D.GetNrVariables: integer; +begin + Result := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulia3D.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + Value := N; + Result := true; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationJulia3D), true, false); +end. diff --git a/Variations/varJuliaN.pas b/Variations/varJuliaN.pas new file mode 100644 index 0000000..1397d4b --- /dev/null +++ b/Variations/varJuliaN.pas @@ -0,0 +1,232 @@ +unit varJuliaN; + +interface + +uses + BaseVariation, XFormMan; + +const + var_name = 'julian'; + var_n_name='julian_power'; + var_c_name='julian_dist'; + +{$ifdef Apo7X64} +{$else} + {$define _ASM_} +{$endif} + +type + TVariationJulian = class(TBaseVariation) + private + N: integer; + c: double; + + absN: integer; + cN, vvar2: double; + + procedure CalcPower1; + procedure CalcPowerMinus1; + procedure CalcPower2; + procedure CalcPowerMinus2; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + Math; + +// TVariationJulian + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationJulian.Create; +begin + N := random(5) + 2; + c := 1.0; +end; + +procedure TVariationJulian.Prepare; +begin + absN := abs(N); + cN := c / N / 2; + + vvar2 := vvar * sqrt(2)/2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJulian.GetCalcFunction(var f: TCalcFunction); +begin + if c = 1 then begin + if N = 2 then f := CalcPower2 + else if N = -2 then f := CalcPowerMinus2 + else if N = 1 then f := CalcPower1 + else if N = -1 then f := CalcPowerMinus1 + else f := CalcFunction; + end + else f := CalcFunction; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJulian.CalcFunction; +var + r: double; + sina, cosa: extended; +begin + sincos((arctan2(FTy^, FTx^) + 2*pi*random(absN)) / N, sina, cosa); + r := vvar * Math.Power(sqr(FTx^) + sqr(FTy^), cN); + + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJulian.CalcPower2; +var + d: double; +begin + d := sqrt( sqrt(sqr(FTx^) + sqr(FTy^)) + FTx^ ); + + if random(2) = 0 then begin + FPx^ := FPx^ + vvar2 * d; + FPy^ := FPy^ + vvar2 / d * FTy^; + end + else begin + FPx^ := FPx^ - vvar2 * d; + FPy^ := FPy^ - vvar2 / d * FTy^; + end; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJulian.CalcPowerMinus2; + +var + r, xd: double; +begin + r := sqrt(sqr(FTx^) + sqr(FTy^)); + xd := r + FTx^; + + r := vvar / sqrt(r * (sqr(Fty^) + sqr(xd)) ); + + if random(2) = 0 then begin + FPx^ := FPx^ + r * xd; + FPy^ := FPy^ - r * FTy^; + end + else begin + FPx^ := FPx^ - r * xd; + FPy^ := FPy^ + r * FTy^; + end; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJulian.CalcPower1; +begin + FPx^ := FPx^ + vvar * FTx^; + FPy^ := FPy^ + vvar * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJulian.CalcPowerMinus1; +var + r: double; +begin + r := vvar / (sqr(FTx^) + sqr(FTy^)); + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ - r * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJulian.GetInstance: TBaseVariation; +begin + Result := TVariationJulian.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJulian.GetName: string; +begin + Result := var_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulian.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_n_name; + 1: Result := var_c_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulian.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + N := Round(Value); + if N = 0 then N := 1; + Value := N; + Result := True; + end + else if Name = var_c_name then begin + c := value; + Result := True; + end; +end; + +function TVariationJulian.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_n_name then begin + if N = 2 then N := -2 + else N := 2; + Result := True; + end + else if Name = var_c_name then begin + c := 1; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulian.GetNrVariables: integer; +begin + Result := 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJulian.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + Value := N; + Result := true; + end + else if Name = var_c_name then begin + Value := c; + Result := true; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationJulian), true, false); +end. + diff --git a/Variations/varJuliaScope.pas b/Variations/varJuliaScope.pas new file mode 100644 index 0000000..1e5528d --- /dev/null +++ b/Variations/varJuliaScope.pas @@ -0,0 +1,251 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varJuliaScope; + +interface + +uses + BaseVariation, XFormMan; + +const + variation_name='juliascope'; + var_n_name='juliascope_power'; + var_c_name='juliascope_dist'; + +{$ifdef Apo7X64} +{$else} + {$define _ASM_} +{$endif} + +type + TVariationJuliaScope = class(TBaseVariation) + private + N: integer; + c: double; + + rN: integer; + cn: double; + + procedure CalcPower1; + procedure CalcPowerMinus1; + procedure CalcPower2; + procedure CalcPowerMinus2; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + math; + +// TVariationJuliaScope + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationJuliaScope.Create; +begin + N := random(5) + 2; + c := 1.0; +end; + +procedure TVariationJuliaScope.Prepare; +begin + rN := abs(N); + cn := c / N / 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJuliaScope.GetCalcFunction(var f: TCalcFunction); +begin + if c = 1 then begin + if N = 2 then f := CalcPower2 + else if N = -2 then f := CalcPowerMinus2 + else if N = 1 then f := CalcPower1 + else if N = -1 then f := CalcPowerMinus1 + else f := CalcFunction; + end + else f := CalcFunction; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationJuliaScope.CalcFunction; +var + rnd: integer; + r: double; + sina, cosa: extended; +begin + rnd := random(rN); + if (rnd and 1) = 0 then + sincos( (2*pi*rnd + arctan2(FTy^, FTx^)) / N, sina, cosa) + else + sincos( (2*pi*rnd - arctan2(FTy^, FTx^)) / N, sina, cosa); + r := vvar * Math.Power(sqr(FTx^) + sqr(FTy^), cn); + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJuliaScope.CalcPower2; +var + r: double; + sina, cosa: extended; +begin + if random(2) = 0 then + sincos(arctan2(FTy^, FTx^)/2, sina, cosa) + else + sincos(pi - arctan2(FTy^, FTx^)/2, sina, cosa); + + r := vvar * sqrt(sqrt(sqr(FTx^) + sqr(FTy^))); + + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJuliaScope.CalcPowerMinus2; +var + r: double; + sina, cosa: extended; +begin + if random(2) = 0 then + sincos(arctan2(FTy^, FTx^)/2, sina, cosa) + else + sincos(pi - arctan2(FTy^, FTx^)/2, sina, cosa); + r := vvar / sqrt(sqrt(sqr(FTx^) + sqr(FTy^))); + + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ - r * sina; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJuliaScope.CalcPower1; +begin + FPx^ := FPx^ + vvar * FTx^; + FPy^ := FPy^ + vvar * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationJuliaScope.CalcPowerMinus1; +var + r: double; +begin + r := vvar / (sqr(FTx^) + sqr(FTy^)); + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ - r * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJuliaScope.GetInstance: TBaseVariation; +begin + Result := TVariationJuliaScope.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationJuliaScope.GetName: string; +begin + Result := variation_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJuliaScope.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_n_name; + 1: Result := var_c_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJuliaScope.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + N := Round(Value); + if N = 0 then N := 1; + Value := N; + Result := True; + end + else if Name = var_c_name then begin + c := value; + Result := True; + end; +end; + +function TVariationJuliaScope.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_n_name then begin + if N = 2 then N := -2 + else N := 2; + Result := True; + end + else if Name = var_c_name then begin + c := 1; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJuliaScope.GetNrVariables: integer; +begin + Result := 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationJuliaScope.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_n_name then begin + Value := N; + Result := true; + end + else if Name = var_c_name then begin + Value := c; + Result := true; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationJuliaScope), true, false); +end. diff --git a/Variations/varLazysusan.pas b/Variations/varLazysusan.pas new file mode 100644 index 0000000..a4a9522 --- /dev/null +++ b/Variations/varLazysusan.pas @@ -0,0 +1,195 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + You should have received a copy of the GNU General Public License + GNU General Public License for more details. + + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varLazysusan; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationLazysusan = class(TBaseVariation) + private + lazysusan_spin, lazysusan_space, lazysusan_twist : double; + lazysusan_x, lazysusan_y : double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationLazysusan.Prepare; +begin +end; +procedure TVariationLazysusan.CalcFunction; +var + a, r, sina, cosa, x, y: double; +begin + x := FTx^ - lazysusan_x; + y := FTy^ + lazysusan_y; + r := sqrt(x*x + y*y); + + if (r < VVAR) then + begin + a := ArcTan2(y, x) + lazysusan_spin + lazysusan_twist*(VVAR-r); + sincos(a, sina, cosa); + FPx^ := FPx^ + VVAR * (r*cosa + lazysusan_x); + FPy^ := FPy^ + VVAR * (r*sina - lazysusan_y); + end else begin + r := 1.0 + lazysusan_space / (r + 1E-6); + FPx^ := FPx^ + VVAR * (r*x + lazysusan_x); + FPy^ := FPy^ + VVAR * (r*y - lazysusan_y); + end; + + FPz^ := FPz^ + VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationLazysusan.Create; +begin + lazysusan_spin := PI; + lazysusan_space := 0; + lazysusan_twist := 0; + lazysusan_x := 0; + lazysusan_y := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationLazysusan.GetInstance: TBaseVariation; +begin + Result := TVariationLazysusan.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationLazysusan.GetName: string; +begin + Result := 'lazysusan'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLazysusan.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'lazysusan_spin'; + 1: Result := 'lazysusan_space'; + 2: Result := 'lazysusan_twist'; + 3: Result := 'lazysusan_x'; + 4: Result := 'lazysusan_y'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLazysusan.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'lazysusan_spin' then begin + Value := frac(value / (2 * PI)) * (2 * PI); + lazysusan_spin := value; + Result := True; + end else if Name = 'lazysusan_space' then begin + lazysusan_space := Value; + Result := True; + end else if Name = 'lazysusan_twist' then begin + lazysusan_twist := Value; + Result := True; + end else if Name = 'lazysusan_x' then begin + lazysusan_x := Value; + Result := True; + end else if Name = 'lazysusan_y' then begin + lazysusan_y := Value; + Result := True; + end; +end; +function TVariationLazysusan.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'lazysusan_spin' then begin + lazysusan_spin := PI; + Result := True; + end else if Name = 'lazysusan_space' then begin + lazysusan_space := 0; + Result := True; + end else if Name = 'lazysusan_twist' then begin + lazysusan_twist := 0; + Result := True; + end else if Name = 'lazysusan_x' then begin + lazysusan_x := 0; + Result := True; + end else if Name = 'lazysusan_y' then begin + lazysusan_x := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLazysusan.GetNrVariables: integer; +begin + Result := 5 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLazysusan.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'lazysusan_spin' then begin + Value := lazysusan_spin; + Result := True; + end else if Name = 'lazysusan_space' then begin + Value := lazysusan_space; + Result := True; + end else if Name = 'lazysusan_twist' then begin + Value := lazysusan_twist; + Result := True; + end else if Name = 'lazysusan_x' then begin + Value := lazysusan_x; + Result := True; + end else if Name = 'lazysusan_y' then begin + Value := lazysusan_y; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationLazysusan), true, false); +end. diff --git a/Variations/varLog.pas b/Variations/varLog.pas new file mode 100644 index 0000000..0cb41cf --- /dev/null +++ b/Variations/varLog.pas @@ -0,0 +1,139 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varLog; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationLog = class(TBaseVariation) + private + base, denom: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationPreSpherical } + + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationLog.Prepare; +begin + denom := 0.5 / Ln(base); +end; +procedure TVariationLog.CalcFunction; +begin + FPx^ := FPx^ + vvar * Ln(sqr(FTx^) + sqr(FTy^)) * denom; + FPy^ := FPy^ + vvar * ArcTan2(FTy^, FTx^); + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationLog.Create; +begin + base := 2.71828182845905; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationLog.GetInstance: TBaseVariation; +begin + Result := TVariationLog.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationLog.GetName: string; +begin + Result := 'log'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLog.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'log_base'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLog.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'log_base' then begin + base := Value; + if (base < 1E-6) then + base := 1E-6; + Result := True; + end; +end; +function TVariationLog.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'log_base' then begin + base := 2.71828182845905; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLog.GetNrVariables: integer; +begin + Result := 1 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLog.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'log_base' then begin + Value := base; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationLog), true, false); +end. diff --git a/Variations/varLoonie.pas b/Variations/varLoonie.pas new file mode 100644 index 0000000..1182fa6 --- /dev/null +++ b/Variations/varLoonie.pas @@ -0,0 +1,131 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varLoonie; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationLoonie = class(TBaseVariation) + private + sqrvar: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationLoonie.Prepare; +begin + sqrvar := VVAR * VVAR; +end; + +procedure TVariationLoonie.CalcFunction; +var r, r2 : double; +begin + r2 := sqr(FTx^) + sqr(FTy^); + + if (r2 < (sqrvar)) and (r2 <> 0) then + begin + r := VVAR * sqrt((sqrvar) / r2 - 1.0); + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ + r * FTy^; + end else begin + FPx^ := FPx^ + VVAR * FTx^; + FPy^ := FPy^ + VVAR * FTy^; + end; + + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationLoonie.Create; +begin + sqrvar := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationLoonie.GetInstance: TBaseVariation; +begin + Result := TVariationLoonie.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationLoonie.GetName: string; +begin + Result := 'loonie'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLoonie.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLoonie.SetVariable(const Name: string; var value: double): boolean; +var temp: double; +begin + Result := False; +end; +function TVariationLoonie.ResetVariable(const Name: string): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLoonie.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationLoonie.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationLoonie), true, false); +end. \ No newline at end of file diff --git a/Variations/varMobius.pas b/Variations/varMobius.pas new file mode 100644 index 0000000..41d7cc4 --- /dev/null +++ b/Variations/varMobius.pas @@ -0,0 +1,216 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varMobius; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationMobius = class(TBaseVariation) + private + Re_A, Im_A, Re_B, Im_B, Re_C, Im_C, Re_D, Im_D: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationMobius.Prepare; +begin +end; + +procedure TVariationMobius.CalcFunction; +var + uRe, uIm, vRe, vIm, vDenom : double; +begin + uRe := (Re_A) * FTX^ - (Im_A) * FTY^ + (Re_B); + uIm := (Re_A) * FTY^ + (Im_A) * FTX^ + (Im_B); + vRe := (Re_C) * FTX^ - (Im_C) * FTY^ + (Re_D); + vIm := (Re_C) * FTY^ + (Im_C) * FTX^ + (Im_D); + + vDenom := vRe * vRe + vIm * vIm; + + FPx^ := FPx^ + VVAR * (uRe*vRe + uIm*vIm) / vDenom; + FPy^ := FPy^ + VVAR * (uIm*vRe - uRe*vIm) / vDenom; + FPz^ := FPz^ + VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationMobius.Create; +begin + Re_A := 1; Im_A := 0; + Re_B := 0; Im_B := 0; + Re_C := 0; Im_C := 0; + Re_D := 1; Im_D := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationMobius.GetInstance: TBaseVariation; +begin + Result := TVariationMobius.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationMobius.GetName: string; +begin + Result := 'mobius'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationMobius.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'Re_A'; + 1: Result := 'Im_A'; + 2: Result := 'Re_B'; + 3: Result := 'Im_B'; + 4: Result := 'Re_C'; + 5: Result := 'Im_C'; + 6: Result := 'Re_D'; + 7: Result := 'Im_D'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationMobius.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'Re_A' then begin + Re_A := Value; + Result := True; + end else if Name = 'Im_A' then begin + Im_A := Value; + Result := True; + end else if Name = 'Re_B' then begin + Re_B := Value; + Result := True; + end else if Name = 'Im_B' then begin + Im_B := Value; + Result := True; + end else if Name = 'Re_C' then begin + Re_C := Value; + Result := True; + end else if Name = 'Im_C' then begin + Im_C := Value; + Result := True; + end else if Name = 'Re_D' then begin + Re_D := Value; + Result := True; + end else if Name = 'Im_D' then begin + Im_D := Value; + Result := True; + end +end; +function TVariationMobius.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'Re_A' then begin + Re_A := 1; + Result := True; + end else if Name = 'Im_A' then begin + Im_A := 0; + Result := True; + end else if Name = 'Re_B' then begin + Re_B := 0; + Result := True; + end else if Name = 'Im_B' then begin + Im_B := 0; + Result := True; + end else if Name = 'Re_C' then begin + Re_C := 0; + Result := True; + end else if Name = 'Im_C' then begin + Im_C := 0; + Result := True; + end else if Name = 'Re_D' then begin + Re_D := 1; + Result := True; + end else if Name = 'Im_D' then begin + Im_D := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationMobius.GetNrVariables: integer; +begin + Result := 8 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationMobius.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'Re_A' then begin + Value := Re_A; + Result := True; + end else if Name = 'Im_A' then begin + Value := Im_A; + Result := True; + end else if Name = 'Re_B' then begin + Value := Re_B; + Result := True; + end else if Name = 'Im_B' then begin + Value := Im_B; + Result := True; + end else if Name = 'Re_C' then begin + Value := Re_C; + Result := True; + end else if Name = 'Im_C' then begin + Value := Im_C; + Result := True; + end else if Name = 'Re_D' then begin + Value := Re_D; + Result := True; + end else if Name = 'Im_D' then begin + Value := Im_D; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationMobius), true, false); +end. \ No newline at end of file diff --git a/Variations/varNGon.pas b/Variations/varNGon.pas new file mode 100644 index 0000000..91411da --- /dev/null +++ b/Variations/varNGon.pas @@ -0,0 +1,187 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + You should have received a copy of the GNU General Public License + GNU General Public License for more details. + + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varNGon; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationNGon = class(TBaseVariation) + private + ngon_sides : integer; + ngon_power, ngon_circle, ngon_corners : double; + cpower, csides, csidesinv : double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationNGon.Prepare; +begin + cpower := -0.5 * ngon_power; + csides := 2.0 * PI / ngon_sides; + csidesinv := 1.0 / csides; +end; +procedure TVariationNGon.CalcFunction; +var + r_factor, theta, phi, amp: double; +begin + + if (FTX^ = 0) and (FTY^ = 0) then r_factor := 0 + else r_factor := Power(FTx^ * FTx^ + FTy^ * FTy^, cpower); + + theta := ArcTan2(FTy^, FTx^); + + phi := theta - csides * floor(theta * csidesinv); + if (phi > 0.5 * csides) then + phi := phi - csides; + + amp := (ngon_corners * (1.0 / cos(phi) - 1.0) + ngon_circle) * VVAR * r_factor; + + FPx^ := FPx^ + amp * FTx^; + FPy^ := FPy^ + amp * FTy^; + FPz^ := FPz^ + VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationNGon.Create; +begin + ngon_sides := 4; + ngon_power := 2; + ngon_circle := 1; + ngon_corners := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationNGon.GetInstance: TBaseVariation; +begin + Result := TVariationNGon.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationNGon.GetName: string; +begin + Result := 'ngon'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationNGon.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'ngon_sides'; + 1: Result := 'ngon_power'; + 2: Result := 'ngon_circle'; + 3: Result := 'ngon_corners'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationNGon.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'ngon_sides' then begin + if (value < 0) and (value > -1) then Value := -1 + else if (value >= 0) and (value < 1) then Value := 1; + ngon_sides := Round(value); + Result := True; + end else if Name = 'ngon_power' then begin + ngon_power := Value; + Result := True; + end else if Name = 'ngon_circle' then begin + ngon_circle := Value; + Result := True; + end else if Name = 'ngon_corners' then begin + ngon_corners := Value; + Result := True; + end; +end; +function TVariationNGon.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'ngon_sides' then begin + ngon_sides := 4; + Result := True; + end else if Name = 'ngon_power' then begin + ngon_power := 2; + Result := True; + end else if Name = 'ngon_circle' then begin + ngon_circle := 1; + Result := True; + end else if Name = 'ngon_corners' then begin + ngon_corners := 1; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationNGon.GetNrVariables: integer; +begin + Result := 4 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationNGon.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'ngon_sides' then begin + Value := ngon_sides; + Result := True; + end else if Name = 'ngon_power' then begin + Value := ngon_power; + Result := True; + end else if Name = 'ngon_circle' then begin + Value := ngon_circle; + Result := True; + end else if Name = 'ngon_corners' then begin + Value := ngon_corners; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationNGon), true, false); +end. diff --git a/Variations/varPolar2.pas b/Variations/varPolar2.pas new file mode 100644 index 0000000..e81ffd7 --- /dev/null +++ b/Variations/varPolar2.pas @@ -0,0 +1,114 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPolar2; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPolar2 = class(TBaseVariation) + private + p2vv, p2vv2: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPolar2.Prepare; +begin + p2vv := VVAR / PI; + p2vv2 := p2vv * 0.5; +end; + +procedure TVariationPolar2.CalcFunction; +begin + FPy^ := FPy^ + p2vv2 * Ln(sqr(FTx^) + sqr(FTy^)); + FPx^ := FPx^ + p2vv * ArcTan2(FTx^, FTy^); + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPolar2.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPolar2.GetInstance: TBaseVariation; +begin + Result := TVariationPolar2.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPolar2.GetName: string; +begin + Result := 'polar2'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPolar2.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPolar2.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPolar2.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPolar2.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPolar2), true, false); +end. \ No newline at end of file diff --git a/Variations/varPostBwraps.pas b/Variations/varPostBwraps.pas new file mode 100644 index 0000000..2b2b48d --- /dev/null +++ b/Variations/varPostBwraps.pas @@ -0,0 +1,228 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPostBwraps; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPostBwraps = class(TBaseVariation) + private + post_bwraps_cellsize, post_bwraps_space, post_bwraps_gain, + post_bwraps_inner_twist, post_bwraps_outer_twist, + g2, r2, rfactor: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPostBwraps.Prepare; +var + max_bubble, radius: double; +begin + radius := 0.5 * (post_bwraps_cellsize / (1.0 + sqr(post_bwraps_space))); + g2 := sqr(post_bwraps_gain) / (radius + 1e-6) + 1e-6; + max_bubble := g2 * radius; + + if (max_bubble > 2.0) then max_bubble := 1.0 + else max_bubble := max_bubble * (1.0 / (sqr(max_bubble)/4.0 + 1.0)); + + r2 := sqr(radius); + rfactor := radius / max_bubble; +end; + +procedure TVariationPostBwraps.CalcFunction; +var + Vx, Vy, + Cx, Cy, + Lx, Ly, + r, theta, s, c : double; +begin + Vx := FPx^; + Vy := FPy^; + + if (post_bwraps_cellsize <> 0.0) then + begin + Cx := (floor(Vx / post_bwraps_cellsize) + 0.5) * post_bwraps_cellsize; + Cy := (floor(Vy / post_bwraps_cellsize) + 0.5) * post_bwraps_cellsize; + + Lx := Vx - Cx; + Ly := Vy - Cy; + + if ((sqr(Lx) + sqr(Ly)) <= r2) then + begin + Lx := Lx * g2; + Ly := Ly * g2; + + r := rfactor / ((sqr(Lx) + sqr(Ly)) / 4.0 + 1); + + Lx := Lx * r; + Ly := Ly * r; + + r := (sqr(Lx) + sqr(Ly)) / r2; + theta := post_bwraps_inner_twist * (1.0 - r) + post_bwraps_outer_twist * r; + SinCos(theta, s, c); + + Vx := Cx + c * Lx + s * Ly; + Vy := Cy - s * Lx + c * Ly; + + FPx^ := VVAR * Vx; + FPy^ := VVAR * Vy; + FPz^ := VVAR * FPz^; + end; + end; + +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPostBwraps.Create; +begin + post_bwraps_cellsize := 1; + post_bwraps_space := 0; + post_bwraps_gain := 1; + post_bwraps_inner_twist := 0; + post_bwraps_outer_twist := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostBwraps.GetInstance: TBaseVariation; +begin + Result := TVariationPostBwraps.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostBwraps.GetName: string; +begin + Result := 'post_bwraps'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostBwraps.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'post_bwraps_cellsize'; + 1: Result := 'post_bwraps_space'; + 2: Result := 'post_bwraps_gain'; + 3: Result := 'post_bwraps_inner_twist'; + 4: Result := 'post_bwraps_outer_twist'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostBwraps.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'post_bwraps_cellsize' then begin + if Value = 0 then Value := 1e-6; + post_bwraps_cellsize := Value; + Result := True; + end else if Name = 'post_bwraps_space' then begin + post_bwraps_space := Value; + Result := True; + end else if Name = 'post_bwraps_gain' then begin + post_bwraps_gain := Value; + Result := True; + end else if Name = 'post_bwraps_inner_twist' then begin + post_bwraps_inner_twist := Value; + Result := True; + end else if Name = 'post_bwraps_outer_twist' then begin + post_bwraps_outer_twist := Value; + Result := True; + end +end; +function TVariationPostBwraps.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'post_bwraps_cellsize' then begin + post_bwraps_cellsize := 1; + Result := True; + end else if Name = 'post_bwraps_space' then begin + post_bwraps_space := 0; + Result := True; + end else if Name = 'post_bwraps_gain' then begin + post_bwraps_gain := 1; + Result := True; + end else if Name = 'post_bwraps_inner_twist' then begin + post_bwraps_inner_twist := 0; + Result := True; + end else if Name = 'post_bwraps_outer_twist' then begin + post_bwraps_outer_twist := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostBwraps.GetNrVariables: integer; +begin + Result := 5 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostBwraps.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'post_bwraps_cellsize' then begin + Value := post_bwraps_cellsize; + Result := True; + end else if Name = 'post_bwraps_space' then begin + Value := post_bwraps_space; + Result := True; + end else if Name = 'post_bwraps_gain' then begin + Value := post_bwraps_gain; + Result := True; + end else if Name = 'post_bwraps_inner_twist' then begin + Value := post_bwraps_inner_twist; + Result := True; + end else if Name = 'post_bwraps_outer_twist' then begin + Value := post_bwraps_outer_twist; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPostBwraps), true, false); +end. \ No newline at end of file diff --git a/Variations/varPostCrop.pas b/Variations/varPostCrop.pas new file mode 100644 index 0000000..0d35f1a --- /dev/null +++ b/Variations/varPostCrop.pas @@ -0,0 +1,231 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPostCrop; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPostCrop = class(TBaseVariation) + const + n_x0 : string = 'post_crop_left'; + n_y0 : string = 'post_crop_top'; + n_x1 : string = 'post_crop_right'; + n_y1 : string = 'post_crop_bottom'; + n_s : string = 'post_crop_scatter_area'; + n_z : string = 'post_crop_zero'; + n : string = 'post_crop'; + + private + x0, y0, x1, y1, s, w, h: double; + _x0, _y0, _x1, _y1: double; + z: integer; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPostCrop.Prepare; +begin + if (x0 < x1) then begin + _x0 := x0; + _x1 := x1; + end else begin + _x0 := x1; + _x1 := x0; + end; + + if (y0 < y1) then begin + _y0 := y0; + _y1 := y1; + end else begin + _y0 := y1; + _y1 := y0; + end; + + w := (_x1 - _x0) * 0.5 * s; + h := (_y1 - _y0) * 0.5 * s; +end; + +procedure TVariationPostCrop.CalcFunction; +var x, y: double; +begin + x := FPx^; + y := FPy^; + + if ((x < _x0) or (x > _x1) or (y < _y0) or (y > _y1)) and (z <> 0) then begin + x := 0; y := 0; + end else begin + if x < _x0 then x := _x0 + random * w + else if x > _x1 then x := _x1 - random * w; + if y < _y0 then y := _y0 + random * h + else if y > _y1 then y := _y1 - random * h; + end; + + FPx^ := VVAR * x; + FPy^ := VVAR * y; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPostCrop.Create; +begin + x0 := -1; x1 := 1; + y0 := -1; y1 := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostCrop.GetInstance: TBaseVariation; +begin + Result := TVariationPostCrop.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostCrop.GetName: string; +begin + Result := n; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCrop.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := n_x0; + 1: Result := n_y0; + 2: Result := n_x1; + 3: Result := n_y1; + 4: Result := n_s; + 5: Result := n_z; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCrop.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_x0 then begin + x0 := Value; + Result := True; + end else if Name = n_y0 then begin + y0 := Value; + Result := True; + end else if Name = n_x1 then begin + x1 := Value; + Result := True; + end else if Name = n_y1 then begin + y1 := Value; + Result := True; + end else if Name = n_s then begin + if (Value < -1) then Value := -1; + if (Value > 1) then Value := 1; + s := Value; + Result := True; + end else if Name = n_z then begin + if (Value > 1) then Value := 1; + if (Value < 0) then Value := 0; + z := Round(Value); + Result := True; + end +end; +function TVariationPostCrop.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = n_x0 then begin + x0 := -1; + Result := True; + end else if Name = n_y0 then begin + y0 := -1; + Result := True; + end else if Name = n_x1 then begin + x1 := 1; + Result := True; + end else if Name = n_y1 then begin + y1 := 1; + Result := True; + end else if Name = n_s then begin + s := 0; + Result := True; + end else if Name = n_z then begin + z := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCrop.GetNrVariables: integer; +begin + Result := 6 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCrop.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_x0 then begin + Value := x0; + Result := True; + end else if Name = n_y0 then begin + Value := y0; + Result := True; + end else if Name = n_x1 then begin + Value := x1; + Result := True; + end else if Name = n_y1 then begin + Value := y1; + Result := True; + end else if Name = n_s then begin + Value := s; + Result := True; + end else if Name = n_z then begin + Value := z; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPostCrop), true, false); +end. \ No newline at end of file diff --git a/Variations/varPostCurl.pas b/Variations/varPostCurl.pas new file mode 100644 index 0000000..db02a2a --- /dev/null +++ b/Variations/varPostCurl.pas @@ -0,0 +1,156 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPostCurl; + +interface + +uses + BaseVariation, XFormMan; + +const + variation_name = 'post_curl'; + num_vars = 2; + +type + TVariationPostCurl = class(TBaseVariation) + private + c1, c2, c22: double; + public + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +// TVariationCurl3D + +procedure TVariationPostCurl.Prepare; +begin + c1 := c1 * VVAR; + c2 := c2 * VVAR; + c22 := 2 * c2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPostCurl.CalcFunction; +var + x, y, r, re, im: double; +begin + x := FPx^; + y := FPy^; + + re := 1 + c1 * x + c2 * (sqr(x) - sqr(y)); + im := c1 * y + c22 * x * y; + + r := sqr(re) + sqr(im); + FPx^ := (x * re + y * im) / r; + FPy^ := (y * re - x * im) / r; +end; +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostCurl.GetInstance: TBaseVariation; +begin + Result := TVariationPostCurl.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostCurl.GetName: string; +begin + Result := variation_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := 'post_curl_c1'; + 1: Result := 'post_curl_c2'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'post_curl_c1' then begin + c1 := value; + Result := True; + end + else if Name = 'post_curl_c2' then begin + c2 := value; + Result := True; + end; +end; + +function TVariationPostCurl.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'post_curl_c1' then begin + c1 := 0; + Result := True; + end + else if Name = 'post_curl_c2' then begin + c2 := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl.GetNrVariables: integer; +begin + Result := num_vars; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'post_curl_c1' then begin + value := c1; + Result := True; + end + else if Name = 'post_curl_c2' then begin + value := c2; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPostCurl), true, false); +end. diff --git a/Variations/varPostCurl3D.pas b/Variations/varPostCurl3D.pas new file mode 100644 index 0000000..45ea5d1 --- /dev/null +++ b/Variations/varPostCurl3D.pas @@ -0,0 +1,187 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPostCurl3D; + +interface + +uses + BaseVariation, XFormMan; + +const + variation_name = 'post_curl3D'; + num_vars = 3; + var_cx_name = 'post_curl3D_cx'; + var_cy_name = 'post_curl3D_cy'; + var_cz_name = 'post_curl3D_cz'; + +type + TVariationPostCurl3D = class(TBaseVariation) + private + cx, cy, cz: double; + + _cx, _cy, _cz, + cx2, cy2, cz2, c_2, + c2x, c2y, c2z: double; + public + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +// TVariationCurl3D + +procedure TVariationPostCurl3D.Prepare; +begin + _cx := VVAR * cx; + _cy := VVAR * cy; + _cz := VVAR * cz; + + c2x := 2 * _cx; + c2y := 2 * _cy; + c2z := 2 * _cz; + + cx2 := sqr(_cx); + cy2 := sqr(_cy); + cz2 := sqr(_cz); + + c_2 := cx2 + cy2 + cz2; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPostCurl3D.CalcFunction; +var + x, y, z, r, r2: double; +begin + x := Max(-1e100, Min(FPx^, 1e100)); // <--- got weird FP overflow there... + y := Max(-1e100, Min(FPy^, 1e100)); + z := Max(-1e100, Min(FPz^, 1e100)); + + r2 := sqr(x) + sqr(y) + sqr(z); + r := 1.0 / (r2*c_2 + c2x*x - c2y*y + c2z*z + 1); + + FPx^ := r * (x + _cx*r2); + FPy^ := r * (y + _cy*r2); + FPz^ := r * (z + _cz*r2); +end; +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostCurl3D.GetInstance: TBaseVariation; +begin + Result := TVariationPostCurl3D.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostCurl3D.GetName: string; +begin + Result := variation_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl3D.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_cx_name; + 1: Result := var_cy_name; + 2: Result := var_cz_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl3D.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_cx_name then begin + cx := value; + Result := True; + end + else if Name = var_cy_name then begin + cy := value; + Result := True; + end + else if Name = var_cz_name then begin + cz := value; + Result := True; + end; +end; + +function TVariationPostCurl3D.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_cx_name then begin + cx := 0; + Result := True; + end + else if Name = var_cy_name then begin + cy := 0; + Result := True; + end + else if Name = var_cz_name then begin + cz := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl3D.GetNrVariables: integer; +begin + Result := num_vars; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostCurl3D.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_cx_name then begin + value := cx; + Result := True; + end + else if Name = var_cy_name then begin + value := cy; + Result := True; + end + else if Name = var_cz_name then begin + value := cz; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPostCurl3D), true, false); +end. diff --git a/Variations/varPostFalloff2.pas b/Variations/varPostFalloff2.pas new file mode 100644 index 0000000..fc315ff --- /dev/null +++ b/Variations/varPostFalloff2.pas @@ -0,0 +1,348 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPostFalloff2; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPostFalloff2 = class(TBaseVariation) + const + n_scatter : string = 'post_falloff2_scatter'; + n_mindist : string = 'post_falloff2_mindist'; + n_mul_x : string = 'post_falloff2_mul_x'; + n_mul_y : string = 'post_falloff2_mul_y'; + n_mul_z : string = 'post_falloff2_mul_z'; + n_mul_c : string = 'post_falloff2_mul_c'; + n_x0 : string = 'post_falloff2_x0'; + n_y0 : string = 'post_falloff2_y0'; + n_z0 : string = 'post_falloff2_z0'; + n_invert : string = 'post_falloff2_invert'; + n_blurtype : string = 'post_falloff2_type'; + + private + rmax: double; + x0, y0, z0: double; + scatter, mindist: double; + invert, blurtype: integer; + mul_x, mul_y, mul_z, mul_c: double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure CalcFunctionRadial; + procedure CalcFunctionGaussian; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPostFalloff2.Prepare; +begin + rmax := 0.04 * scatter; +end; + +procedure TVariationPostFalloff2.GetCalcFunction(var f: TCalcFunction); +begin + if blurtype = 1 then f := CalcFunctionRadial + else if blurtype = 2 then f := CalcFunctionGaussian + else f := CalcFunction; +end; +procedure TVariationPostFalloff2.CalcFunction; +var + in_x, in_y, in_z, d: double; +begin + in_x := FPx^; + in_y := FPy^; + in_z := FPz^; + + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + FPx^ := VVAR * (in_x + mul_x * random * d); + FPy^ := VVAR * (in_y + mul_y * random * d); + FPz^ := VVAR * (in_z + mul_z * random * d); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; +procedure TVariationPostFalloff2.CalcFunctionRadial; +var + in_x, in_y, in_z, d, r_in: double; + sigma, phi, r, sins, coss, sinp, cosp: double; +begin + in_x := FPx^; + in_y := FPy^; + in_z := FPz^; + + r_in := sqrt(sqr(in_x) + sqr(in_y) + sqr(in_z)) + 1e-6; + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + sigma := ArcSin(in_z / r_in) + mul_z * random * d; + phi := ArcTan2(in_y, in_x) + mul_y * random * d; + r := r_in + mul_x * random * d; + + SinCos(sigma, sins, coss); + SinCos(phi, sinp, cosp); + + FPx^ := VVAR * (r * coss * cosp); + FPy^ := VVAR * (r * coss * sinp); + FPz^ := VVAR * (sins); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; +procedure TVariationPostFalloff2.CalcFunctionGaussian; +var + in_x, in_y, in_z, d: double; + sigma, phi, r, sins, coss, sinp, cosp: double; +begin + in_x := FPx^; + in_y := FPy^; + in_z := FPz^; + + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + sigma := d * random * 2 * PI; + phi := d * random * PI; + r := d * random; + + SinCos(sigma, sins, coss); + SinCos(phi, sinp, cosp); + + FPx^ := VVAR * (in_x + mul_x * r * coss * cosp); + FPy^ := VVAR * (in_y + mul_y * r * coss * sinp); + FPz^ := VVAR * (in_z + mul_z * r * sins); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPostFalloff2.Create; +begin + scatter := 1; + mindist := 0.5; + mul_x := 1; + mul_y := 1; + mul_z := 0; + mul_c := 0; + x0 := 0; + y0 := 0; + z0 := 0; + invert := 0; + blurtype := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostFalloff2.GetInstance: TBaseVariation; +begin + Result := TVariationPostFalloff2.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPostFalloff2.GetName: string; +begin + Result := 'post_falloff2'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostFalloff2.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := n_scatter; + 1: Result := n_mindist; + 2: Result := n_mul_x; + 3: Result := n_mul_y; + 4: Result := n_mul_z; + 5: Result := n_mul_c; + 6: Result := n_x0; + 7: Result := n_y0; + 8: Result := n_z0; + 9: Result := n_invert; + 10: Result := n_blurtype; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostFalloff2.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_scatter then begin + if Value < 1e-6 then Value := 1e-6; + scatter := Value; + Result := True; + end else if Name = n_mindist then begin + if Value < 0 then Value := 0; + mindist := Value; + Result := True; + end else if Name = n_mul_x then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_x := Value; + Result := True; + end else if Name = n_mul_y then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_y := Value; + Result := True; + end else if Name = n_mul_z then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_z := Value; + Result := True; + end else if Name = n_mul_c then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_c := Value; + Result := True; + end else if Name = n_x0 then begin + x0 := Value; + Result := True; + end else if Name = n_y0 then begin + y0 := Value; + Result := True; + end else if Name = n_z0 then begin + z0 := Value; + Result := True; + end else if Name = n_invert then begin + if (Value > 1) then Value := 1; + if (Value < 0) then Value := 0; + invert := Round(Value); + Result := True; + end else if Name = n_blurtype then begin + if (Value > 2) then Value := 2; + if (Value < 0) then Value := 0; + blurtype := Round(Value); + Result := True; + end +end; +function TVariationPostFalloff2.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = n_scatter then begin + scatter := 1; + Result := True; + end else if Name = n_mindist then begin + mindist := 0.5; + Result := True; + end else if Name = n_mul_x then begin + mul_x := 1; + Result := True; + end else if Name = n_mul_y then begin + mul_y := 1; + Result := True; + end else if Name = n_mul_z then begin + mul_z := 0; + Result := True; + end else if Name = n_mul_c then begin + mul_c := 0; + Result := True; + end else if Name = n_x0 then begin + x0 := 0; + Result := True; + end else if Name = n_y0 then begin + y0 := 0; + Result := True; + end else if Name = n_z0 then begin + z0 := 0; + Result := True; + end else if Name = n_invert then begin + invert := 0; + Result := True; + end else if Name = n_blurtype then begin + blurtype := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostFalloff2.GetNrVariables: integer; +begin + Result := 11 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPostFalloff2.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_scatter then begin + Value := scatter; + Result := True; + end else if Name = n_mindist then begin + Value := mindist; + Result := True; + end else if Name = n_mul_x then begin + Value := mul_x; + Result := True; + end else if Name = n_mul_y then begin + Value := mul_y; + Result := True; + end else if Name = n_mul_z then begin + Value := mul_z; + Result := True; + end else if Name = n_mul_c then begin + Value := mul_c; + Result := True; + end else if Name = n_x0 then begin + Value := x0; + Result := True; + end else if Name = n_y0 then begin + Value := y0; + Result := True; + end else if Name = n_z0 then begin + Value := z0; + Result := True; + end else if Name = n_invert then begin + Value := invert; + Result := True; + end else if Name = n_blurtype then begin + Value := blurtype; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPostFalloff2), true, false); +end. \ No newline at end of file diff --git a/Variations/varPreBwraps.pas b/Variations/varPreBwraps.pas new file mode 100644 index 0000000..1e15eed --- /dev/null +++ b/Variations/varPreBwraps.pas @@ -0,0 +1,227 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPreBwraps; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPreBwraps = class(TBaseVariation) + private + pre_bwraps_cellsize, pre_bwraps_space, pre_bwraps_gain, + pre_bwraps_inner_twist, pre_bwraps_outer_twist, + g2, r2, rfactor: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPreBwraps.Prepare; +var + max_bubble, radius: double; +begin + radius := 0.5 * (pre_bwraps_cellsize / (1.0 + sqr(pre_bwraps_space))); + g2 := sqr(pre_bwraps_gain) / (radius + 1e-6) + 1e-6; + max_bubble := g2 * radius; + + if (max_bubble > 2.0) then max_bubble := 1.0 + else max_bubble := max_bubble * (1.0 / (sqr(max_bubble)/4.0 + 1.0)); + + r2 := sqr(radius); + rfactor := radius / max_bubble; +end; + +procedure TVariationPreBwraps.CalcFunction; +var + Vx, Vy, + Cx, Cy, + Lx, Ly, + r, theta, s, c : double; +begin + Vx := FTx^; + Vy := FTy^; + + if (pre_bwraps_cellsize <> 0.0) then + begin + Cx := (floor(Vx / pre_bwraps_cellsize) + 0.5) * pre_bwraps_cellsize; + Cy := (floor(Vy / pre_bwraps_cellsize) + 0.5) * pre_bwraps_cellsize; + + Lx := Vx - Cx; + Ly := Vy - Cy; + + if ((sqr(Lx) + sqr(Ly)) <= r2) then + begin + Lx := Lx * g2; + Ly := Ly * g2; + + r := rfactor / ((sqr(Lx) + sqr(Ly)) / 4.0 + 1); + + Lx := Lx * r; + Ly := Ly * r; + + r := (sqr(Lx) + sqr(Ly)) / r2; + theta := pre_bwraps_inner_twist * (1.0 - r) + pre_bwraps_outer_twist * r; + SinCos(theta, s, c); + + Vx := Cx + c * Lx + s * Ly; + Vy := Cy - s * Lx + c * Ly; + + FTx^ := VVAR * Vx; + FTy^ := VVAR * Vy; + FTz^ := VVAR * FTz^; + end; + end; + +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPreBwraps.Create; +begin + pre_bwraps_cellsize := 1; + pre_bwraps_space := 0; + pre_bwraps_gain := 1; + pre_bwraps_inner_twist := 0; + pre_bwraps_outer_twist := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreBwraps.GetInstance: TBaseVariation; +begin + Result := TVariationPreBwraps.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreBwraps.GetName: string; +begin + Result := 'pre_bwraps'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreBwraps.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'pre_bwraps_cellsize'; + 1: Result := 'pre_bwraps_space'; + 2: Result := 'pre_bwraps_gain'; + 3: Result := 'pre_bwraps_inner_twist'; + 4: Result := 'pre_bwraps_outer_twist'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreBwraps.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'pre_bwraps_cellsize' then begin + pre_bwraps_cellsize := Value; + Result := True; + end else if Name = 'pre_bwraps_space' then begin + pre_bwraps_space := Value; + Result := True; + end else if Name = 'pre_bwraps_gain' then begin + pre_bwraps_gain := Value; + Result := True; + end else if Name = 'pre_bwraps_inner_twist' then begin + pre_bwraps_inner_twist := Value; + Result := True; + end else if Name = 'pre_bwraps_outer_twist' then begin + pre_bwraps_outer_twist := Value; + Result := True; + end +end; +function TVariationPreBwraps.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'pre_bwraps_cellsize' then begin + pre_bwraps_cellsize := 1; + Result := True; + end else if Name = 'pre_bwraps_space' then begin + pre_bwraps_space := 0; + Result := True; + end else if Name = 'pre_bwraps_gain' then begin + pre_bwraps_gain := 1; + Result := True; + end else if Name = 'pre_bwraps_inner_twist' then begin + pre_bwraps_inner_twist := 0; + Result := True; + end else if Name = 'pre_bwraps_outer_twist' then begin + pre_bwraps_outer_twist := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreBwraps.GetNrVariables: integer; +begin + Result := 5 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreBwraps.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'pre_bwraps_cellsize' then begin + if Value = 0 then Value := 1e-6; + Value := pre_bwraps_cellsize; + Result := True; + end else if Name = 'pre_bwraps_space' then begin + Value := pre_bwraps_space; + Result := True; + end else if Name = 'pre_bwraps_gain' then begin + Value := pre_bwraps_gain; + Result := True; + end else if Name = 'pre_bwraps_inner_twist' then begin + Value := pre_bwraps_inner_twist; + Result := True; + end else if Name = 'pre_bwraps_outer_twist' then begin + Value := pre_bwraps_outer_twist; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPreBwraps), true, false); +end. \ No newline at end of file diff --git a/Variations/varPreCrop.pas b/Variations/varPreCrop.pas new file mode 100644 index 0000000..8823e66 --- /dev/null +++ b/Variations/varPreCrop.pas @@ -0,0 +1,231 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPreCrop; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPreCrop = class(TBaseVariation) + const + n_x0 : string = 'pre_crop_left'; + n_y0 : string = 'pre_crop_top'; + n_x1 : string = 'pre_crop_right'; + n_y1 : string = 'pre_crop_bottom'; + n_s : string = 'pre_crop_scatter_area'; + n_z : string = 'pre_crop_zero'; + n : string = 'pre_crop'; + + private + x0, y0, x1, y1, s, w, h: double; + _x0, _y0, _x1, _y1: double; + z: integer; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPreCrop.Prepare; +begin + if (x0 < x1) then begin + _x0 := x0; + _x1 := x1; + end else begin + _x0 := x1; + _x1 := x0; + end; + + if (y0 < y1) then begin + _y0 := y0; + _y1 := y1; + end else begin + _y0 := y1; + _y1 := y0; + end; + + w := (_x1 - _x0) * 0.5 * s; + h := (_y1 - _y0) * 0.5 * s; +end; + +procedure TVariationPreCrop.CalcFunction; +var x, y: double; +begin + x := FTx^; + y := FTy^; + + if ((x < _x0) or (x > _x1) or (y < _y0) or (y > _y1)) and (z <> 0) then begin + x := 0; y := 0; + end else begin + if x < _x0 then x := _x0 + random * w + else if x > _x1 then x := _x1 - random * w; + if y < _y0 then y := _y0 + random * h + else if y > _y1 then y := _y1 - random * h; + end; + + FTx^ := VVAR * x; + FTy^ := VVAR * y; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPreCrop.Create; +begin + x0 := -1; x1 := 1; + y0 := -1; y1 := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreCrop.GetInstance: TBaseVariation; +begin + Result := TVariationPreCrop.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreCrop.GetName: string; +begin + Result := n; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreCrop.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := n_x0; + 1: Result := n_y0; + 2: Result := n_x1; + 3: Result := n_y1; + 4: Result := n_s; + 5: Result := n_z; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreCrop.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_x0 then begin + x0 := Value; + Result := True; + end else if Name = n_y0 then begin + y0 := Value; + Result := True; + end else if Name = n_x1 then begin + x1 := Value; + Result := True; + end else if Name = n_y1 then begin + y1 := Value; + Result := True; + end else if Name = n_s then begin + if (Value < -1) then Value := -1; + if (Value > 1) then Value := 1; + s := Value; + Result := True; + end else if Name = n_z then begin + if (Value > 1) then Value := 1; + if (Value < 0) then Value := 0; + z := Round(Value); + Result := True; + end +end; +function TVariationPreCrop.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = n_x0 then begin + x0 := -1; + Result := True; + end else if Name = n_y0 then begin + y0 := -1; + Result := True; + end else if Name = n_x1 then begin + x1 := 1; + Result := True; + end else if Name = n_y1 then begin + y1 := 1; + Result := True; + end else if Name = n_s then begin + s := 0; + Result := True; + end else if Name = n_z then begin + z := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreCrop.GetNrVariables: integer; +begin + Result := 6 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreCrop.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_x0 then begin + Value := x0; + Result := True; + end else if Name = n_y0 then begin + Value := y0; + Result := True; + end else if Name = n_x1 then begin + Value := x1; + Result := True; + end else if Name = n_y1 then begin + Value := y1; + Result := True; + end else if Name = n_s then begin + Value := s; + Result := True; + end else if Name = n_z then begin + Value := z; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPreCrop), true, false); +end. \ No newline at end of file diff --git a/Variations/varPreDisc.pas b/Variations/varPreDisc.pas new file mode 100644 index 0000000..2400512 --- /dev/null +++ b/Variations/varPreDisc.pas @@ -0,0 +1,119 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPreDisc; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPreDisc = class(TBaseVariation) + private + vvar_by_pi: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationPreSpherical } + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPreDisc.Prepare; +begin + vvar_by_pi := vvar / PI; +end; + +procedure TVariationPreDisc.CalcFunction; +var + r, sinr, cosr: double; +begin + SinCos(PI * sqrt(sqr(FTx^) + sqr(FTy^)), sinr, cosr); + r := vvar_by_pi * arctan2(FTx^, FTy^); + FTx^ := sinr * r; + FTy^ := cosr * r; + FTz^ := VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPreDisc.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreDisc.GetInstance: TBaseVariation; +begin + Result := TVariationPreDisc.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreDisc.GetName: string; +begin + Result := 'pre_disc'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreDisc.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreDisc.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreDisc.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreDisc.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPreDisc), true, false); +end. diff --git a/Variations/varPreFalloff2.pas b/Variations/varPreFalloff2.pas new file mode 100644 index 0000000..7fe18e6 --- /dev/null +++ b/Variations/varPreFalloff2.pas @@ -0,0 +1,348 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPreFalloff2; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPreFalloff2 = class(TBaseVariation) + const + n_scatter : string = 'pre_falloff2_scatter'; + n_mindist : string = 'pre_falloff2_mindist'; + n_mul_x : string = 'pre_falloff2_mul_x'; + n_mul_y : string = 'pre_falloff2_mul_y'; + n_mul_z : string = 'pre_falloff2_mul_z'; + n_mul_c : string = 'pre_falloff2_mul_c'; + n_x0 : string = 'pre_falloff2_x0'; + n_y0 : string = 'pre_falloff2_y0'; + n_z0 : string = 'pre_falloff2_z0'; + n_invert : string = 'pre_falloff2_invert'; + n_blurtype : string = 'pre_falloff2_type'; + + private + rmax: double; + x0, y0, z0: double; + scatter, mindist: double; + invert, blurtype: integer; + mul_x, mul_y, mul_z, mul_c: double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure CalcFunctionRadial; + procedure CalcFunctionGaussian; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPreFalloff2.Prepare; +begin + rmax := 0.04 * scatter; +end; + +procedure TVariationPreFalloff2.GetCalcFunction(var f: TCalcFunction); +begin + if blurtype = 1 then f := CalcFunctionRadial + else if blurtype = 2 then f := CalcFunctionGaussian + else f := CalcFunction; +end; +procedure TVariationPreFalloff2.CalcFunction; +var + in_x, in_y, in_z, d: double; +begin + in_x := FTx^; + in_y := FTy^; + in_z := FTz^; + + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + FTx^ := VVAR * (in_x + mul_x * random * d); + FTy^ := VVAR * (in_y + mul_y * random * d); + FTz^ := VVAR * (in_z + mul_z * random * d); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; +procedure TVariationPreFalloff2.CalcFunctionRadial; +var + in_x, in_y, in_z, d, r_in: double; + sigma, phi, r, sins, coss, sinp, cosp: double; +begin + in_x := FTx^; + in_y := FTy^; + in_z := FTz^; + + r_in := sqrt(sqr(in_x) + sqr(in_y) + sqr(in_z)) + 1e-6; + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + sigma := ArcSin(in_z / r_in) + mul_z * random * d; + phi := ArcTan2(in_y, in_x) + mul_y * random * d; + r := r_in + mul_x * random * d; + + SinCos(sigma, sins, coss); + SinCos(phi, sinp, cosp); + + FTx^ := VVAR * (r * coss * cosp); + FTy^ := VVAR * (r * coss * sinp); + FTz^ := VVAR * (sins); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; +procedure TVariationPreFalloff2.CalcFunctionGaussian; +var + in_x, in_y, in_z, d: double; + sigma, phi, r, sins, coss, sinp, cosp: double; +begin + in_x := FTx^; + in_y := FTy^; + in_z := FTz^; + + d := sqrt(sqr(in_x - x0) + sqr(in_y - y0) + sqr(in_z - z0)); + if (invert <> 0) then d := 1 - d; if (d < 0) then d := 0; + d := (d - mindist) * rmax; if (d < 0) then d := 0; + + sigma := d * random * 2 * PI; + phi := d * random * PI; + r := d * random; + + SinCos(sigma, sins, coss); + SinCos(phi, sinp, cosp); + + FTx^ := VVAR * (in_x + mul_x * r * coss * cosp); + FTy^ := VVAR * (in_y + mul_y * r * coss * sinp); + FTz^ := VVAR * (in_z + mul_z * r * sins); + color^ := Abs(Frac(color^ + mul_c * random * d)); +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPreFalloff2.Create; +begin + scatter := 1; + mindist := 0.5; + mul_x := 1; + mul_y := 1; + mul_z := 0; + mul_c := 0; + x0 := 0; + y0 := 0; + z0 := 0; + invert := 0; + blurtype := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreFalloff2.GetInstance: TBaseVariation; +begin + Result := TVariationPreFalloff2.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreFalloff2.GetName: string; +begin + Result := 'pre_falloff2'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreFalloff2.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := n_scatter; + 1: Result := n_mindist; + 2: Result := n_mul_x; + 3: Result := n_mul_y; + 4: Result := n_mul_z; + 5: Result := n_mul_c; + 6: Result := n_x0; + 7: Result := n_y0; + 8: Result := n_z0; + 9: Result := n_invert; + 10: Result := n_blurtype; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreFalloff2.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_scatter then begin + if Value < 1e-6 then Value := 1e-6; + scatter := Value; + Result := True; + end else if Name = n_mindist then begin + if Value < 0 then Value := 0; + mindist := Value; + Result := True; + end else if Name = n_mul_x then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_x := Value; + Result := True; + end else if Name = n_mul_y then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_y := Value; + Result := True; + end else if Name = n_mul_z then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_z := Value; + Result := True; + end else if Name = n_mul_c then begin + if Value < 0 then Value := 0 + else if Value > 1 then Value := 1; + mul_c := Value; + Result := True; + end else if Name = n_x0 then begin + x0 := Value; + Result := True; + end else if Name = n_y0 then begin + y0 := Value; + Result := True; + end else if Name = n_z0 then begin + z0 := Value; + Result := True; + end else if Name = n_invert then begin + if (Value > 1) then Value := 1; + if (Value < 0) then Value := 0; + invert := Round(Value); + Result := True; + end else if Name = n_blurtype then begin + if (Value > 2) then Value := 2; + if (Value < 0) then Value := 0; + blurtype := Round(Value); + Result := True; + end +end; +function TVariationPreFalloff2.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = n_scatter then begin + scatter := 1; + Result := True; + end else if Name = n_mindist then begin + mindist := 0.5; + Result := True; + end else if Name = n_mul_x then begin + mul_x := 1; + Result := True; + end else if Name = n_mul_y then begin + mul_y := 1; + Result := True; + end else if Name = n_mul_z then begin + mul_z := 0; + Result := True; + end else if Name = n_mul_c then begin + mul_c := 0; + Result := True; + end else if Name = n_x0 then begin + x0 := 0; + Result := True; + end else if Name = n_y0 then begin + y0 := 0; + Result := True; + end else if Name = n_z0 then begin + z0 := 0; + Result := True; + end else if Name = n_invert then begin + invert := 0; + Result := True; + end else if Name = n_blurtype then begin + blurtype := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreFalloff2.GetNrVariables: integer; +begin + Result := 11 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreFalloff2.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = n_scatter then begin + Value := scatter; + Result := True; + end else if Name = n_mindist then begin + Value := mindist; + Result := True; + end else if Name = n_mul_x then begin + Value := mul_x; + Result := True; + end else if Name = n_mul_y then begin + Value := mul_y; + Result := True; + end else if Name = n_mul_z then begin + Value := mul_z; + Result := True; + end else if Name = n_mul_c then begin + Value := mul_c; + Result := True; + end else if Name = n_x0 then begin + Value := x0; + Result := True; + end else if Name = n_y0 then begin + Value := y0; + Result := True; + end else if Name = n_z0 then begin + Value := z0; + Result := True; + end else if Name = n_invert then begin + Value := invert; + Result := True; + end else if Name = n_blurtype then begin + Value := blurtype; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPreFalloff2), true, false); +end. \ No newline at end of file diff --git a/Variations/varPreSinusoidal.pas b/Variations/varPreSinusoidal.pas new file mode 100644 index 0000000..295addd --- /dev/null +++ b/Variations/varPreSinusoidal.pas @@ -0,0 +1,107 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPreSinusoidal; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPreSinusoidal = class(TBaseVariation) + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationPreSpherical } + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPreSinusoidal.CalcFunction; +begin + FTx^ := vvar * sin(FTx^); + FTy^ := vvar * sin(FTy^); + FTz^ := VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPreSinusoidal.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreSinusoidal.GetInstance: TBaseVariation; +begin + Result := TVariationPreSinusoidal.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreSinusoidal.GetName: string; +begin + Result := 'pre_sinusoidal'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSinusoidal.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSinusoidal.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSinusoidal.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSinusoidal.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPreSinusoidal), true, false); +end. diff --git a/Variations/varPreSpherical.pas b/Variations/varPreSpherical.pas new file mode 100644 index 0000000..f2e419e --- /dev/null +++ b/Variations/varPreSpherical.pas @@ -0,0 +1,110 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPreSpherical; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationPreSpherical = class(TBaseVariation) + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationPreSpherical } + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPreSpherical.CalcFunction; +var r: double; +begin + r := vvar / (sqr(FTx^) + sqr(FTy^) + 10e-6); + FTx^ := FTx^ * r; + FTy^ := FTy^ * r; + FTz^ := VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPreSpherical.Create; +begin +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreSpherical.GetInstance: TBaseVariation; +begin + Result := TVariationPreSpherical.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPreSpherical.GetName: string; +begin + Result := 'pre_spherical'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSpherical.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSpherical.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSpherical.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPreSpherical.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPreSpherical), true, false); +end. diff --git a/Variations/varRadialBlur.pas b/Variations/varRadialBlur.pas new file mode 100644 index 0000000..ee767a4 --- /dev/null +++ b/Variations/varRadialBlur.pas @@ -0,0 +1,215 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varRadialBlur; + +interface + +uses + BaseVariation, XFormMan; + +const + var_name = 'radial_blur'; + var_a_name = 'radial_blur_angle'; + +{$ifdef Apo7X64} +{$else} + {$define _ASM_} +{$endif} + +type + TVariationRadialBlur = class(TBaseVariation) + private + angle, + spin_var, zoom_var: double; + + rnd: array[0..3] of double; + N: integer; + + procedure CalcZoom; + procedure CalcSpin; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function GetVariable(const Name: string; var value: double): boolean; override; + function SetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + procedure GetCalcFunction(var f: TCalcFunction); override; + end; + +implementation + +uses + math; + +// TVariationRadialBlur + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationRadialBlur.Create; +begin + angle := random * 2 - 1; +end; + +procedure TVariationRadialBlur.Prepare; +begin + spin_var := vvar * sin(angle * pi/2); + zoom_var := vvar * cos(angle * pi/2); + + N := 0; + rnd[0] := random; + rnd[1] := random; + rnd[2] := random; + rnd[3] := random; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationRadialBlur.GetCalcFunction(var f: TCalcFunction); +begin + if IsZero(spin_var) then f := CalcZoom + else if IsZero(zoom_var) then f := CalcSpin + else f := CalcFunction; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationRadialBlur.CalcFunction; +var + rndG, rz, ra: double; + sina, cosa: extended; +begin + rndG := (rnd[0] + rnd[1] + rnd[2] + rnd[3] - 2); + rnd[N] := random; + N := (N+1) and $3; + + ra := sqrt(sqr(FTx^) + sqr(FTy^)); + SinCos(arctan2(FTy^, FTx^) + spin_var * rndG, sina, cosa); + rz := zoom_var * rndG - 1; + + FPx^ := FPx^ + ra * cosa + rz * FTx^; + FPy^ := FPy^ + ra * sina + rz * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationRadialBlur.CalcZoom; +var + r: double; +begin + r := zoom_var * (rnd[0] + rnd[1] + rnd[2] + rnd[3] - 2); + + rnd[N] := random; + N := (N+1) and $3; + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ + r * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationRadialBlur.CalcSpin; +var + r: double; + sina, cosa: extended; +begin + SinCos(arctan2(FTy^, FTx^) + spin_var * (rnd[0] + rnd[1] + rnd[2] + rnd[3] - 2), + sina, cosa); + r := sqrt(sqr(FTx^) + sqr(FTy^)); + + rnd[N] := random; + N := (N+1) and $3; + + FPx^ := FPx^ + r * cosa - FTx^; + FPy^ := FPy^ + r * sina - FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationRadialBlur.GetInstance: TBaseVariation; +begin + Result := TVariationRadialBlur.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationRadialBlur.GetName: string; +begin + Result := var_name; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRadialBlur.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_a_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRadialBlur.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_a_name then begin + Value := angle; + Result := true; + end; +end; + +function TVariationRadialBlur.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_a_name then begin + angle := Value; + Result := True; + end; +end; + +function TVariationRadialBlur.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = var_a_name then begin + if angle <> 0 then angle := 0 + else if angle = 0 then angle := 1; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRadialBlur.GetNrVariables: integer; +begin + Result := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationRadialBlur), true, false); +end. diff --git a/Variations/varRectangles.pas b/Variations/varRectangles.pas new file mode 100644 index 0000000..f276c20 --- /dev/null +++ b/Variations/varRectangles.pas @@ -0,0 +1,175 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + This variation was started by Michael Faber +} + +unit varRectangles; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationRectangles = class(TBaseVariation) + private + FRectanglesX, FRectanglesY: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure GetCalcFunction(var f: TCalcFunction); override; + procedure CalcFunction; override; + procedure CalcZeroX; + procedure CalcZeroY; + procedure CalcZeroXY; + + end; + +implementation + +uses + Math; + +{ TVariationRectangles } + +/////////////////////////////////////////////////////////////////////////////// + +procedure TVariationRectangles.GetCalcFunction(var f: TCalcFunction); +begin + if IsZero(FRectanglesX) then begin + if IsZero(FRectanglesY) then + f := CalcZeroXY + else + f := CalcZeroX; + end + else if IsZero(FRectanglesY) then + f := CalcZeroY + else f := CalcFunction; +end; + +procedure TVariationRectangles.CalcFunction; +begin + FPx^ := FPx^ + vvar * ((2*floor(FTx^/FRectanglesX) + 1)*FRectanglesX - FTx^); + FPy^ := FPy^ + vvar * ((2*floor(FTy^/FRectanglesY) + 1)*FRectanglesY - FTy^); + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationRectangles.CalcZeroX; +begin + FPx^ := FPx^ + vvar * FTx^; + FPy^ := FPy^ + vvar * ((2*floor(FTy^/FRectanglesY) + 1)*FRectanglesY - FTy^); + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationRectangles.CalcZeroY; +begin + FPx^ := FPx^ + vvar * ((2*floor(FTx^/FRectanglesX) + 1)*FRectanglesX - FTx^); + FPy^ := FPy^ + vvar * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +procedure TVariationRectangles.CalcZeroXY; +begin + FPx^ := FPx^ + vvar * FTx^; + FPy^ := FPy^ + vvar * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationRectangles.GetName: string; +begin + Result := 'rectangles'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRectangles.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'rectangles_x'; + 1: Result := 'rectangles_y'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRectangles.GetNrVariables: integer; +begin + Result := 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRectangles.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'rectangles_x' then begin + FRectanglesX := Value; + Result := True; + end else if Name = 'rectangles_y' then begin + FRectanglesY := Value; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRectangles.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'rectangles_x' then begin + Value := FRectanglesX; + Result := True; + end else if Name = 'rectangles_y' then begin + Value := FRectanglesY; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationRectangles.Create; +begin + inherited Create; + + FRectanglesX := 1.0; + FRectanglesY := 1.0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationRectangles.GetInstance: TBaseVariation; +begin + Result := TVariationRectangles.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationRectangles), true, false); +end. diff --git a/Variations/varRings2.pas b/Variations/varRings2.pas new file mode 100644 index 0000000..15b9006 --- /dev/null +++ b/Variations/varRings2.pas @@ -0,0 +1,147 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varRings2; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationRings2 = class(TBaseVariation) + private + FVal, dx: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationRings2 } + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationRings2.Prepare; +const + EPS = 1E-10; +begin + dx := sqr(FVal) + EPS; +end; + +procedure TVariationRings2.CalcFunction; +var + r: double; + Length: double; + Angle: double; +begin + Length := sqrt(sqr(FTx^) + sqr(FTy^)); +{ // all this range-checking crap only slows us down... + if (FTx^ < -EPS) or (FTx^ > EPS) or (FTy^ < -EPS) or (FTy^ > EPS) then + Angle := arctan2(FTx^, FTy^) + else + Angle := 0.0; +} // ...and besides, we don't need arctan() if we have Length! + +// dx := sqr(FVal) + EPS; - we can precalc it!!! +// r := Length + dx - System.Int((Length + dx)/(2 * dx)) * 2 * dx - dx + Length * (1-dx); +// ^^^^......he he, lots of useless calculations......^^^^ + r := vvar * (2 - dx * (System.Int((Length/dx + 1)/2) * 2 / Length + 1)); + + FPx^ := FPx^ + r * FTx^; + FPy^ := FPy^ + r * FTy^; + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationRings2.Create; +begin + FVal := Random * 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationRings2.GetInstance: TBaseVariation; +begin + Result := TVariationRings2.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationRings2.GetName: string; +begin + Result := 'rings2'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRings2.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'rings2_val'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRings2.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'rings2_val' then begin + FVal := Value; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRings2.GetNrVariables: integer; +begin + Result := 1 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationRings2.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'rings2_val' then begin + Value := FVal; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationRings2), true, false); +end. diff --git a/Variations/varScry.pas b/Variations/varScry.pas new file mode 100644 index 0000000..a31cf1a --- /dev/null +++ b/Variations/varScry.pas @@ -0,0 +1,127 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varScry; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationScry = class(TBaseVariation) + private + v: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationScry.Prepare; +begin + if (VVAR = 0) then + v := 1.0 / 1e-6 + else v := 1.0 / vvar; +end; + +procedure TVariationScry.CalcFunction; +var t, r : double; +begin + t := sqr(FTx^) + sqr(FTy^); + r := 1.0 / (sqrt(t) * (t + v)); + + FPx^ := FPx^ + FTx^ * r; + FPy^ := FPy^ + FTy^ * r; + + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationScry.Create; +begin + v := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationScry.GetInstance: TBaseVariation; +begin + Result := TVariationScry.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationScry.GetName: string; +begin + Result := 'scry'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationScry.GetVariableNameAt(const Index: integer): string; +begin + Result := ''; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationScry.SetVariable(const Name: string; var value: double): boolean; +var temp: double; +begin + Result := False; +end; +function TVariationScry.ResetVariable(const Name: string): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationScry.GetNrVariables: integer; +begin + Result := 0 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationScry.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationScry), true, false); +end. \ No newline at end of file diff --git a/Variations/varSeparation.pas b/Variations/varSeparation.pas new file mode 100644 index 0000000..91545a3 --- /dev/null +++ b/Variations/varSeparation.pas @@ -0,0 +1,175 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varSeparation; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationSeparation = class(TBaseVariation) + private + separation_x, separation_y: double; + separation_xinside, separation_yinside: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationSeparation.Prepare; +begin +end; + +procedure TVariationSeparation.CalcFunction; +begin + if(FTx^ > 0.0) then + FPx^ := FPx^ + VVAR * (sqrt(sqr(FTx^) + sqr(separation_x))- FTx^ * (separation_xinside)) + else + FPx^ := FPx^ - VVAR * (sqrt(sqr(FTx^) + sqr(separation_x))+ FTx^ * (separation_xinside)) ; + if(FTy^ > 0.0) then + FPy^ := FPy^ + VVAR * (sqrt(sqr(FTy^) + sqr(separation_y))- FTy^ * (separation_yinside)) + else + FPy^ := FPy^ - VVAR * (sqrt(sqr(FTy^) + sqr(separation_y))+ FTy^ * (separation_yinside)) ; + + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationSeparation.Create; +begin + separation_x := 1; + separation_y := 1; + separation_xinside := 0; + separation_yinside := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationSeparation.GetInstance: TBaseVariation; +begin + Result := TVariationSeparation.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationSeparation.GetName: string; +begin + Result := 'separation'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSeparation.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'separation_x'; + 1: Result := 'separation_y'; + 2: Result := 'separation_xinside'; + 3: Result := 'separation_yinside'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSeparation.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'separation_x' then begin + separation_x := Value; + Result := True; + end else if Name = 'separation_y' then begin + separation_y := Value; + Result := True; + end else if Name = 'separation_xinside' then begin + separation_xinside := Value; + Result := True; + end else if Name = 'separation_yinside' then begin + separation_yinside := Value; + Result := True; + end +end; +function TVariationSeparation.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'separation_x' then begin + separation_x := 1; + Result := True; + end else if Name = 'separation_y' then begin + separation_y := 1; + Result := True; + end else if Name = 'separation_xinside' then begin + separation_xinside := 0; + Result := True; + end else if Name = 'separation_yinside' then begin + separation_yinside := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSeparation.GetNrVariables: integer; +begin + Result := 4 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSeparation.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'separation_x' then begin + Value := separation_x; + Result := True; + end else if Name = 'separation_y' then begin + Value := separation_y; + Result := True; + end else if Name = 'separation_xinside' then begin + Value := separation_xinside; + Result := True; + end else if Name = 'separation_yinside' then begin + Value := separation_yinside; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationSeparation), true, false); +end. \ No newline at end of file diff --git a/Variations/varSplits.pas b/Variations/varSplits.pas new file mode 100644 index 0000000..e566dca --- /dev/null +++ b/Variations/varSplits.pas @@ -0,0 +1,141 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varSplits; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationSplits = class(TBaseVariation) + private + splits_x, splits_y: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationSplits.Prepare; +begin +end; + +procedure TVariationSplits.CalcFunction; +begin + if(FTx^ >= 0.0) then + FPx^ := FPx^ + VVAR * (FTx^ + splits_x) + else + FPx^ := FPx^ + VVAR * (FTx^ - splits_x); + + if(FTy^ >= 0.0) then + FPy^ := FPy^ + VVAR * (FTy^ + splits_y) + else + FPy^ := FPy^ + VVAR * (FTy^ - splits_y); + + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationSplits.Create; +begin + splits_x := 0; + splits_y := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationSplits.GetInstance: TBaseVariation; +begin + Result := TVariationSplits.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationSplits.GetName: string; +begin + Result := 'splits'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSplits.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'splits_x'; + 1: Result := 'splits_y'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSplits.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'splits_x' then begin + splits_x := Value; + Result := True; + end else if Name = 'splits_y' then begin + splits_y := Value; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSplits.GetNrVariables: integer; +begin + Result := 2 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationSplits.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'splits_x' then begin + Value := splits_x; + Result := True; + end else if Name = 'splits_y' then begin + Value := splits_y; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationSplits), true, false); +end. \ No newline at end of file diff --git a/Variations/varWaves2.pas b/Variations/varWaves2.pas new file mode 100644 index 0000000..2339678 --- /dev/null +++ b/Variations/varWaves2.pas @@ -0,0 +1,188 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varWaves2; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationWaves2 = class(TBaseVariation) + private + waves2_freqx, waves2_freqy, waves2_freqz: double; + waves2_scalex, waves2_scaley, waves2_scalez: double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationWaves2.Prepare; +begin +end; + +procedure TVariationWaves2.CalcFunction; +begin + FPx^ := FPx^ + VVAR * (FTx^ + waves2_scalex * sin(FTy^ * waves2_freqx)); + FPy^ := FPy^ + VVAR * (FTy^ + waves2_scaley * sin(FTx^ * waves2_freqy)); + FPz^ := FPz^ + VVAR * (FTz^ + waves2_scalez * sin(sqrt(sqr(FTx^)+sqr(FTy^)) * waves2_freqz)); +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationWaves2.Create; +begin + waves2_freqx := 2; waves2_scalex := 1; + waves2_freqy := 2; waves2_scaley := 1; + waves2_freqz := 0; waves2_scalez := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationWaves2.GetInstance: TBaseVariation; +begin + Result := TVariationWaves2.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationWaves2.GetName: string; +begin + Result := 'waves2'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWaves2.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'waves2_freqx'; + 1: Result := 'waves2_freqy'; + 2: Result := 'waves2_freqz'; + 3: Result := 'waves2_scalex'; + 4: Result := 'waves2_scaley'; + 5: Result := 'waves2_scalez'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWaves2.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'waves2_freqx' then begin + waves2_freqx := Value; + Result := True; + end else if Name = 'waves2_freqy' then begin + waves2_freqy := Value; + Result := True; + end else if Name = 'waves2_freqz' then begin + waves2_freqz := Value; + Result := True; + end else if Name = 'waves2_scalex' then begin + waves2_scalex := Value; + Result := True; + end else if Name = 'waves2_scaley' then begin + waves2_scaley := Value; + Result := True; + end else if Name = 'waves2_scalez' then begin + waves2_scalez := Value; + Result := True; + end +end; +function TVariationWaves2.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'waves2_freqx' then begin + waves2_freqx := 2; + Result := True; + end else if Name = 'waves2_freqy' then begin + waves2_freqy := 2; + Result := True; + end else if Name = 'waves2_freqz' then begin + waves2_freqz := 0; + Result := True; + end else if Name = 'waves2_scalex' then begin + waves2_scalex := 1; + Result := True; + end else if Name = 'waves2_scaley' then begin + waves2_scaley := 1; + Result := True; + end else if Name = 'waves2_scalez' then begin + waves2_scalez := 0; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWaves2.GetNrVariables: integer; +begin + Result := 6 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWaves2.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'waves2_freqx' then begin + Value := waves2_freqx; + Result := True; + end else if Name = 'waves2_freqy' then begin + Value := waves2_freqy; + Result := True; + end else if Name = 'waves2_freqz' then begin + Value := waves2_freqz; + Result := True; + end else if Name = 'waves2_scalex' then begin + Value := waves2_scalex; + Result := True; + end else if Name = 'waves2_scaley' then begin + Value := waves2_scaley; + Result := True; + end else if Name = 'waves2_scalez' then begin + Value := waves2_scalez; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationWaves2), true, false); +end. \ No newline at end of file diff --git a/Variations/varWedge.pas b/Variations/varWedge.pas new file mode 100644 index 0000000..ccd8f77 --- /dev/null +++ b/Variations/varWedge.pas @@ -0,0 +1,183 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + You should have received a copy of the GNU General Public License + GNU General Public License for more details. + + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varWedge; + +interface + +uses + BaseVariation, XFormMan; + +type + TVariationWedge = class(TBaseVariation) + private + wedge_angle, wedge_hole, wedge_swirl: double; + wedge_count : integer; + C1_2PI, comp_fac: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + function ResetVariable(const Name: string): boolean; override; + + procedure Prepare; override; + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationWedge.Prepare; +begin + C1_2PI := 0.15915494309189533576888376337251; + comp_fac := 1.0 - wedge_angle * wedge_count * C1_2PI; +end; +procedure TVariationWedge.CalcFunction; +var + r, a, cosa, sina: double; + c: integer; +begin + + r := sqrt(sqr(FTx^) + sqr(FTy^)); + a := ArcTan2(FTy^, FTx^) + wedge_swirl * r; + c := floor((wedge_count * a + PI) * C1_2PI); + a := a * comp_fac + c * wedge_angle; + SinCos(a, sina, cosa); + + r := vvar * (r + wedge_hole); + FPx^ := FPx^ + r * cosa; + FPy^ := FPy^ + r * sina; + FPz^ := FPz^ + VVAR * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationWedge.Create; +begin + wedge_angle := PI / 2.0; + wedge_hole := 0; + wedge_count := 2; + wedge_swirl := 0; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationWedge.GetInstance: TBaseVariation; +begin + Result := TVariationWedge.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationWedge.GetName: string; +begin + Result := 'wedge'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWedge.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'wedge_angle'; + 1: Result := 'wedge_hole'; + 2: Result := 'wedge_count'; + 3: Result := 'wedge_swirl'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWedge.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'wedge_angle' then begin + wedge_angle := Value; + Result := True; + end else if Name = 'wedge_hole' then begin + wedge_hole := Value; + Result := True; + end else if Name = 'wedge_count' then begin + if (Value < 1) then Value := 1; + Value := Round(value); + wedge_count := Round(Value); + Result := True; + end else if Name = 'wedge_swirl' then begin + wedge_swirl := Value; + Result := True; + end; +end; +function TVariationWedge.ResetVariable(const Name: string): boolean; +begin + Result := False; + if Name = 'wedge_angle' then begin + wedge_angle := PI / 2; + Result := True; + end else if Name = 'wedge_hole' then begin + wedge_hole := 0; + Result := True; + end else if Name = 'wedge_count' then begin + wedge_count := 2; + Result := True; + end else if Name = 'wedge_swirl' then begin + wedge_swirl := 0; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWedge.GetNrVariables: integer; +begin + Result := 4 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationWedge.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'wedge_angle' then begin + Value := wedge_angle; + Result := True; + end else if Name = 'wedge_hole' then begin + Value := wedge_hole; + Result := True; + end else if Name = 'wedge_count' then begin + Value := wedge_count; + Result := True; + end else if Name = 'wedge_swirl' then begin + Value := wedge_swirl; + Result := True; + end; +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationWedge), true, false); +end. diff --git a/Variations/varpdj.pas b/Variations/varpdj.pas new file mode 100644 index 0000000..9751e37 --- /dev/null +++ b/Variations/varpdj.pas @@ -0,0 +1,149 @@ +{ + Apophysis Copyright (C) 2001-2004 Mark Townsend + Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov + Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov + + Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov + Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +unit varPDJ; + +interface + +uses + BaseVariation, XFormMan; + +{$define _ASM_} + +type + TVariationPDJ = class(TBaseVariation) + private + FA,FB,FC,FD: double; + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + function GetNrVariables: integer; override; + function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + + procedure CalcFunction; override; + end; + +implementation + +uses + Math; + +{ TVariationPDJ } + +/////////////////////////////////////////////////////////////////////////////// +procedure TVariationPDJ.CalcFunction; +begin + FPx^ := FPx^ + vvar * (sin(FA * FTy^) - cos(FB * FTx^)); + FPy^ := FPy^ + vvar * (sin(FC * FTx^) - cos(FD * FTy^)); + FPz^ := FPz^ + vvar * FTz^; +end; + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPDJ.Create; +begin + FA := 6 * Random - 3; + FB := 6 * Random - 3; + FC := 6 * Random - 3; + FD := 6 * Random - 3; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPDJ.GetInstance: TBaseVariation; +begin + Result := TVariationPDJ.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPDJ.GetName: string; +begin + Result := 'pdj'; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPDJ.GetVariableNameAt(const Index: integer): string; +begin + case Index Of + 0: Result := 'pdj_a'; + 1: Result := 'pdj_b'; + 2: Result := 'pdj_c'; + 3: Result := 'pdj_d'; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPDJ.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'pdj_a' then begin + FA := Value; + Result := True; + end else if Name = 'pdj_b' then begin + FB := Value; + Result := True; + end else if Name = 'pdj_c' then begin + FC := Value; + Result := True; + end else if Name = 'pdj_d' then begin + FD := Value; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPDJ.GetNrVariables: integer; +begin + Result := 4 +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPDJ.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = 'pdj_a' then begin + Value := FA; + Result := True; + end else if Name = 'pdj_b' then begin + Value := FB; + Result := True; + end else if Name = 'pdj_c' then begin + Value := FC; + Result := True; + end else if Name = 'pdj_d' then begin + Value := FD; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationClassLoader.Create(TVariationPDJ), true, false); +end. diff --git a/Windows7/DelphiVersions.inc b/Windows7/DelphiVersions.inc new file mode 100644 index 0000000..b7a55fe --- /dev/null +++ b/Windows7/DelphiVersions.inc @@ -0,0 +1,34 @@ +{$IFDEF VER150} + {$DEFINE Delphi7} + {$DEFINE Delphi7_UP} +{$ENDIF} + +{$IFDEF VER170} + {$DEFINE Delphi2005} + {$DEFINE Delphi7_UP} + {$DEFINE Delphi2005_UP} +{$ENDIF} + +{$IFDEF VER180} + {$DEFINE Delphi2006} + {$DEFINE Delphi7_UP} + {$DEFINE Delphi2005_UP} + {$DEFINE Delphi2006_UP} +{$ENDIF} + +{$IFDEF VER185} + {$DEFINE Delphi2007} + {$DEFINE Delphi7_UP} + {$DEFINE Delphi2005_UP} + {$DEFINE Delphi2006_UP} + {$DEFINE Delphi2007_UP} +{$ENDIF} + +{$IFDEF VER200} + {$DEFINE Delphi2009} + {$DEFINE Delphi7_UP} + {$DEFINE Delphi2005_UP} + {$DEFINE Delphi2006_UP} + {$DEFINE Delphi2007_UP} + {$DEFINE Delphi2009_UP} +{$ENDIF} diff --git a/Windows7/dwCustomDestinationList.pas b/Windows7/dwCustomDestinationList.pas new file mode 100644 index 0000000..c318f84 --- /dev/null +++ b/Windows7/dwCustomDestinationList.pas @@ -0,0 +1,32 @@ +unit dwCustomDestinationList; + +interface + +uses + Windows, + dwObjectArray; + +const + CLSID_CustomDestinationList: TGUID = '{77f10cf0-3db5-4966-b520-b7c54fd35ed6}'; + +const + KDC_FREQUENT = $01; + KDC_RECENT = $02; + +type + ICustomDestinationList = interface + ['{6332debf-87b5-4670-90c0-5e57b408a49e}'] + procedure SetAppID(pszAppID: LPWSTR); safecall; + function BeginList(out pcMaxSlots: UINT; riid: PGUID): IObjectArray; safecall; + procedure AppendCategory(pszCategory: LPWSTR; poa: IObjectArray); safecall; + procedure AppendKnownCategory(Category: Integer); safecall; + procedure AddUserTasks(poa: IUnknown); safecall; + procedure CommitList(); safecall; + function GetRemovedDestinations(riid: PGUID): IUnknown; safecall; + procedure DeleteList(pszAppID:LPWSTR); safecall; + procedure AbortList(); safecall; + end; + +implementation + +end. diff --git a/Windows7/dwJumpLists.pas b/Windows7/dwJumpLists.pas new file mode 100644 index 0000000..d573c3e --- /dev/null +++ b/Windows7/dwJumpLists.pas @@ -0,0 +1,725 @@ +unit dwJumpLists; + +interface + +{$INCLUDE '..\Packages\DelphiVersions.inc'} + +uses + Classes, Contnrs, ShlObj, + {$IFNDEF Delphi2007_Up} + dwShellItem, + {$ENDIF} + dwCustomDestinationList, dwObjectArray; + +type + TJumpListKnowCategory = (jlkcFrequent, jlkcRecent); + TJumpListKnowCategories = set of TJumpListKnowCategory; + +const + KNOWN_CATEGORIES_DEFAULT: TJumpListKnowCategories = [jlkcFrequent, jlkcRecent]; + +type + TdwLinkObjectType = (lotShellLink, lotShellItem); + +type + TdwLinkObjectItem = class; + TdwLinkObjectList = class; + TdwLinkCategoryItem = class; + TdwLinkCategoryList = class; + TdwJumpLists = class; + + TObjectArray = class(TInterfacedObject, IObjectArray) + private + FObjectList: TInterfaceList; + + function CreateShellLink(ObjectItem: TdwLinkObjectItem): IShellLinkW; + function CreateShellItem(ObjectItem: TdwLinkObjectItem): IShellItem; + procedure LoadObjectList(ObjectList: TdwLinkObjectList; DeletedObjects: IObjectArray); + protected + public + constructor Create(ObjectList: TdwLinkObjectList; DeletedObjects: IObjectArray); + destructor Destroy; override; + + function GetAt(uiIndex: Cardinal; riid: PGUID): IUnknown; safecall; + function GetCount: Cardinal; safecall; + end; + + TdwShellItem = class(TPersistent) + private + FFilename: WideString; + procedure SetFilename(const Value: WideString); + protected + public + constructor Create; + procedure Assign(Source: TPersistent); override; + published + property Filename: WideString read FFilename write SetFilename; + end; + + TdwShellLink = class(TPersistent) + private + FDisplayName: WideString; + FArguments: WideString; + FIconFilename: WideString; + FIconIndex: Integer; + procedure SetArguments(const Value: WideString); + procedure SetDisplayName(const Value: WideString); + procedure SetIconFilename(const Value: WideString); + procedure SetIconIndex(const Value: Integer); + protected + public + constructor Create; + procedure Assign(Source: TPersistent); override; + published + property Arguments: WideString read FArguments write SetArguments; + property DisplayName: WideString read FDisplayName write SetDisplayName; + property IconFilename: WideString read FIconFilename write SetIconFilename; + property IconIndex: Integer read FIconIndex write SetIconIndex; + end; + + TdwLinkObjectItem = class(TCollectionItem) + private + FTag: Integer; + FObjectType: TdwLinkObjectType; + FShellItem: TdwShellItem; + FShellLink: TdwShellLink; + procedure SetTag(const Value: Integer); + procedure SetObjectType(const Value: TdwLinkObjectType); + procedure SetShellItem(const Value: TdwShellItem); + procedure SetShellLink(const Value: TdwShellLink); + protected + public + constructor Create(Collection: TCollection); override; + destructor Destroy; override; + + procedure Assign(Source: TPersistent); override; + published + property Tag: Integer read FTag write SetTag default 0; + property ObjectType: TdwLinkObjectType read FObjectType write SetObjectType default lotShellItem; + property ShellItem: TdwShellItem read FShellItem write SetShellItem; + property ShellLink: TdwShellLink read FShellLink write SetShellLink; + end; + + TdwLinkObjectList = class(TCollection) + private + FOwner: TPersistent; + function GetItem(Index: Integer): TdwLinkObjectItem; + procedure SetItem(Index: Integer; Value: TdwLinkObjectItem); + function GetObjectArray(DeletedObjects: IObjectArray): IObjectArray; + protected + function GetOwner: TPersistent; override; + procedure Update(Item: TCollectionItem); override; + public + constructor Create(Owner: TPersistent); + destructor Destroy; override; + + function Add: TdwLinkObjectItem; + function AddShellItem(const Filename: WideString): TdwLinkObjectItem; + function AddShellLink(const DisplayName, Arguments: WideString; const IconFilename: WideString = ''; IconIndex: Integer = 0): TdwLinkObjectItem; + function AddItem(Item: TdwLinkObjectItem; Index: Integer): TdwLinkObjectItem; + function Insert(Index: Integer): TdwLinkObjectItem; + + property Items[Index: Integer]: TdwLinkObjectItem read GetItem write SetItem; default; + end; + + TdwLinkCategoryItem = class(TCollectionItem) + private + FTitle: WideString; + FTag: Integer; + FItems: TdwLinkObjectList; + procedure SetTitle(const Value: WideString); + procedure SetTag(const Value: Integer); + procedure SetItems(const Value: TdwLinkObjectList); + protected + public + constructor Create(Collection: TCollection); override; + destructor Destroy; override; + + procedure Assign(Source: TPersistent); override; + published + property Title: WideString read FTitle write SetTitle; + property Tag: Integer read FTag write SetTag default 0; + property Items: TdwLinkObjectList read FItems write SetItems; + end; + + TdwLinkCategoryList = class(TCollection) + private + FOwner: TPersistent; + function GetItem(Index: Integer): TdwLinkCategoryItem; + procedure SetItem(Index: Integer; Value: TdwLinkCategoryItem); + protected + function GetOwner: TPersistent; override; + procedure Update(Item: TCollectionItem); override; + public + constructor Create(Owner: TPersistent); + destructor Destroy; override; + + function Add: TdwLinkCategoryItem; + function AddItem(Item: TdwLinkCategoryItem; Index: Integer): TdwLinkCategoryItem; + function Insert(Index: Integer): TdwLinkCategoryItem; + + property Items[Index: Integer]: TdwLinkCategoryItem read GetItem write SetItem; default; + end; + + TdwJumpLists = class(TComponent) + private + FDisplayKnowCategories: TJumpListKnowCategories; + FDestinationList: ICustomDestinationList; + FIsSupported: Boolean; + FCategories: TdwLinkCategoryList; + FTasks: TdwLinkObjectList; + FAppID: WideString; + + procedure SetDisplayKnowCategories(const Value: TJumpListKnowCategories); + function DoStoreDisplayKnowCategories: Boolean; + procedure SetCategories(const Value: TdwLinkCategoryList); + procedure SetTasks(const Value: TdwLinkObjectList); + procedure SetAppID(const Value: WideString); + protected + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + function GetMaxJumpListEntryCount: Integer; + function Commit: Boolean; + + property IsSupported: Boolean read FIsSupported; + published + property DisplayKnowCategories: TJumpListKnowCategories read FDisplayKnowCategories write SetDisplayKnowCategories stored DoStoreDisplayKnowCategories; + property Categories: TdwLinkCategoryList read FCategories write SetCategories; + property Tasks: TdwLinkObjectList read FTasks write SetTasks; + property AppID: WideString read FAppID write SetAppID; + end; + +implementation + +uses + ComObj, ActiveX, SysUtils; + +{ TObjectArray } + +constructor TObjectArray.Create(ObjectList: TdwLinkObjectList; DeletedObjects: IObjectArray); +begin + inherited Create; + + FObjectList := TInterfaceList.Create; + LoadObjectList(ObjectList, DeletedObjects); +end; + +function TObjectArray.CreateShellItem(ObjectItem: TdwLinkObjectItem): IShellItem; +begin + if ObjectItem.FObjectType = lotShellItem then + begin + SHCreateItemFromParsingName(PWideChar(ObjectItem.ShellItem.Filename), nil, StringToGUID(SID_IShellItem), Result); + end + else + begin + Result := nil; + end; +end; + +function TObjectArray.CreateShellLink(ObjectItem: TdwLinkObjectItem): IShellLinkW; +var + ShellLink: IShellLinkW; + PPS: IPropertyStore; + K: TPropertyKey; + P: tagPROPVARIANT; +begin + if ObjectItem.FObjectType = lotShellLink then + begin + CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IID_IShellLinkW, ShellLink); + ShellLink.SetPath(PWideChar(WideString(GetModuleName(HInstance)))); + ShellLink.SetArguments(PWideChar(ObjectItem.ShellLink.FArguments)); + if ObjectItem.ShellLink.FIconFilename <> '' then + ShellLink.SetIconLocation(PWideChar(ObjectItem.ShellLink.FIconFilename), ObjectItem.ShellLink.FIconIndex) + else + ShellLink.SetIconLocation(PWideChar(WideString(GetModuleName(HInstance))), 0); + PPS := ShellLink as IPropertyStore; + K.fmtid := StringToGUID('{F29F85E0-4FF9-1068-AB91-08002B27B3D9}'); + K.pid := 2; + P.vt := VT_LPWSTR; + P.pwszVal := PWideChar(ObjectItem.ShellLink.FDisplayName); + PPS.SetValue(K, P); + PPS.Commit; + Result := ShellLink; + end + else + begin + Result := nil; + end; +end; + +destructor TObjectArray.Destroy; +begin + FObjectList.Free; + + inherited; +end; + +function TObjectArray.GetAt(uiIndex: Cardinal; riid: PGUID): IUnknown; +begin + Result := FObjectList[uiIndex]; +end; + +function TObjectArray.GetCount: Cardinal; +begin + Result := FObjectList.Count; +end; + +procedure TObjectArray.LoadObjectList(ObjectList: TdwLinkObjectList; DeletedObjects: IObjectArray); +var + I: Integer; + ObjectItem: TdwLinkObjectItem; +begin + for I := 0 to ObjectList.Count - 1 do + begin + ObjectItem := ObjectList.Items[I]; + case ObjectItem.FObjectType of + lotShellLink: + begin + FObjectList.Add(CreateShellLink(ObjectItem)); + end; + lotShellItem: + begin + FObjectList.Add(CreateShellItem(ObjectItem)); + end; + end; + end; +end; + +{ TdwShellLink } + +procedure TdwShellItem.Assign(Source: TPersistent); +begin + if Source is TdwShellItem then + begin + Self.FFilename := (Source as TdwShellItem).FFilename; + end + else + begin + inherited Assign(Source); + end; +end; + +constructor TdwShellItem.Create; +begin + inherited Create; + + FFilename := ''; +end; + +procedure TdwShellItem.SetFilename(const Value: WideString); +begin + FFilename := Value; +end; + +{ TdwShellLink } + +procedure TdwShellLink.Assign(Source: TPersistent); +begin + if Source is TdwShellLink then + begin + Self.FArguments := (Source as TdwShellLink).FArguments; + Self.FDisplayName := (Source as TdwShellLink).FDisplayName; + Self.FIconFilename := (Source as TdwShellLink).FIconFilename; + Self.FIconIndex := (Source as TdwShellLink).FIconIndex; + end + else + begin + inherited Assign(Source); + end; +end; + +constructor TdwShellLink.Create; +begin + inherited Create; + + FDisplayName := ''; + FArguments := ''; + FIconFilename := ''; + FIconIndex := 0; +end; + +procedure TdwShellLink.SetArguments(const Value: WideString); +begin + FArguments := Value; +end; + +procedure TdwShellLink.SetDisplayName(const Value: WideString); +begin + FDisplayName := Value; +end; + +procedure TdwShellLink.SetIconFilename(const Value: WideString); +begin + FIconFilename := Value; +end; + +procedure TdwShellLink.SetIconIndex(const Value: Integer); +begin + FIconIndex := Value; +end; + +{ TdwLinkObjectItem } + +procedure TdwLinkObjectItem.Assign(Source: TPersistent); +begin + if Source is TdwLinkObjectItem then + begin + Self.FTag := (Source as TdwLinkObjectItem).FTag; + Self.FObjectType := (Source as TdwLinkObjectItem).FObjectType; + end + else + begin + inherited Assign(Source); + end; +end; + +constructor TdwLinkObjectItem.Create(Collection: TCollection); +begin + inherited Create(Collection); + FTag := 0; + FObjectType := lotShellItem; + FShellItem := TdwShellItem.Create(); + FShellLink := TdwShellLink.Create(); +end; + +destructor TdwLinkObjectItem.Destroy; +begin + FShellItem.Free; + FShellLink.Free; + + inherited; +end; + +procedure TdwLinkObjectItem.SetObjectType(const Value: TdwLinkObjectType); +begin + FObjectType := Value; +end; + +procedure TdwLinkObjectItem.SetShellItem(const Value: TdwShellItem); +begin + FShellItem.Assign(Value); +end; + +procedure TdwLinkObjectItem.SetShellLink(const Value: TdwShellLink); +begin + FShellLink := Value; +end; + +procedure TdwLinkObjectItem.SetTag(const Value: Integer); +begin + FTag := Value; +end; + +{ TdwLinkObjectList } + +function TdwLinkObjectList.Add: TdwLinkObjectItem; +begin + Result := AddItem(nil, -1); +end; + +function TdwLinkObjectList.AddItem(Item: TdwLinkObjectItem; Index: Integer): TdwLinkObjectItem; +begin + if Item = nil then + begin + Result := TdwLinkObjectItem.Create(Self); + end + else + begin + Result := Item; + if Assigned(Item) then + begin + Result.Collection := Self; + if Index < Count then + Index := Count - 1; + Result.Index := Index; + end; + end; +end; + +function TdwLinkObjectList.AddShellItem(const Filename: WideString): TdwLinkObjectItem; +begin + Result := Add; + + Result.FObjectType := lotShellItem; + Result.ShellItem.FFilename := Filename; +end; + +function TdwLinkObjectList.AddShellLink(const DisplayName, Arguments, IconFilename: WideString; IconIndex: Integer): TdwLinkObjectItem; +begin + Result := Add; + Result.FObjectType := lotShellLink; + Result.ShellLink.FDisplayName := DisplayName; + Result.ShellLink.FArguments := Arguments; + Result.ShellLink.FIconFilename := IconFilename; + Result.ShellLink.FIconIndex := IconIndex; +end; + +constructor TdwLinkObjectList.Create(Owner: TPersistent); +begin + inherited Create(TdwLinkObjectItem); + FOwner := Owner; +end; + +destructor TdwLinkObjectList.Destroy; +begin + + inherited; +end; + +function TdwLinkObjectList.GetItem(Index: Integer): TdwLinkObjectItem; +begin + Result := TdwLinkObjectItem(inherited GetItem(Index)); +end; + +function TdwLinkObjectList.GetObjectArray(DeletedObjects: IObjectArray): IObjectArray; +begin + Result := TObjectArray.Create(Self, DeletedObjects) as IObjectArray; +end; + +function TdwLinkObjectList.GetOwner: TPersistent; +begin + Result := FOwner; +end; + +function TdwLinkObjectList.Insert(Index: Integer): TdwLinkObjectItem; +begin + Result := AddItem(nil, Index); +end; + +procedure TdwLinkObjectList.SetItem(Index: Integer; Value: TdwLinkObjectItem); +begin + inherited SetItem(Index, Value); +end; + +procedure TdwLinkObjectList.Update(Item: TCollectionItem); +begin + // nothing to do +end; + +{ TdwLinkCategoryItem } + +procedure TdwLinkCategoryItem.Assign(Source: TPersistent); +begin + if Source is TdwLinkCategoryItem then + begin + Self.FTitle := (Source as TdwLinkCategoryItem).FTitle; + Self.FTag := (Source as TdwLinkCategoryItem).FTag; + end + else + begin + inherited Assign(Source); + end; +end; + +constructor TdwLinkCategoryItem.Create(Collection: TCollection); +begin + inherited Create(Collection); + + FTitle := ''; + FTag := 0; + FItems := TdwLinkObjectList.Create(Self); +end; + +destructor TdwLinkCategoryItem.Destroy; +begin + FItems.Free; + + inherited Destroy; +end; + +procedure TdwLinkCategoryItem.SetItems(const Value: TdwLinkObjectList); +begin + FItems.Assign(Value); +end; + +procedure TdwLinkCategoryItem.SetTag(const Value: Integer); +begin + FTag := Value; +end; + +procedure TdwLinkCategoryItem.SetTitle(const Value: WideString); +begin + FTitle := Value; +end; + +{ TdwLinkCategoryList } + +function TdwLinkCategoryList.Add: TdwLinkCategoryItem; +begin + Result := AddItem(nil, -1); +end; + +function TdwLinkCategoryList.AddItem(Item: TdwLinkCategoryItem; Index: Integer): TdwLinkCategoryItem; +begin + if Item = nil then + begin + Result := TdwLinkCategoryItem.Create(Self); + end + else + begin + Result := Item; + if Assigned(Item) then + begin + Result.Collection := Self; + if Index < Count then + Index := Count - 1; + Result.Index := Index; + end; + end; +end; + +constructor TdwLinkCategoryList.Create(Owner: TPersistent); +begin + inherited Create(TdwLinkCategoryItem); + FOwner := Owner; +end; + +destructor TdwLinkCategoryList.Destroy; +begin + + inherited Destroy; +end; + +function TdwLinkCategoryList.GetItem(Index: Integer): TdwLinkCategoryItem; +begin + Result := TdwLinkCategoryItem(inherited GetItem(Index)); +end; + +function TdwLinkCategoryList.GetOwner: TPersistent; +begin + Result := FOwner; +end; + +function TdwLinkCategoryList.Insert(Index: Integer): TdwLinkCategoryItem; +begin + Result := AddItem(nil, Index); +end; + +procedure TdwLinkCategoryList.SetItem(Index: Integer; Value: TdwLinkCategoryItem); +begin + inherited SetItem(Index, Value); +end; + +procedure TdwLinkCategoryList.Update(Item: TCollectionItem); +begin + // nothing to do +end; + +{ TdwJumpLists } + +function TdwJumpLists.Commit: Boolean; +var + MaxSlots: Cardinal; + IdxCat: Integer; + DeletedObjects: IObjectArray; + Category: TdwLinkCategoryItem; +begin + if IsSupported then + try + DeletedObjects := FDestinationList.BeginList(MaxSlots, @IID_IObjectArray); + + for IdxCat := 0 to FCategories.Count - 1 do + begin + Category := FCategories.Items[IdxCat]; + if Category.Items.Count > 0 then + begin + FDestinationList.AppendCategory(PWideChar(Category.FTitle), Category.Items.GetObjectArray(DeletedObjects)); + end; + end; + + if FTasks.Count > 0 then + FDestinationList.AddUserTasks(FTasks.GetObjectArray(DeletedObjects)); + + if jlkcFrequent in FDisplayKnowCategories then + FDestinationList.AppendKnownCategory(KDC_FREQUENT); + if jlkcRecent in FDisplayKnowCategories then + FDestinationList.AppendKnownCategory(KDC_RECENT); + + FDestinationList.CommitList; + Result := True; + except + Result := False; + end + else + begin + Result := False; + end; +end; + +constructor TdwJumpLists.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + if CheckWin32Version(6, 1) then + begin + FDisplayKnowCategories := KNOWN_CATEGORIES_DEFAULT; + FDestinationList := CreateComObject(CLSID_CustomDestinationList) as ICustomDestinationList; + end + else + begin + FDestinationList := nil; + end; + FIsSupported := FDestinationList <> nil; + + FCategories := TdwLinkCategoryList.Create(Self); + FTasks := TdwLinkObjectList.Create(Self); +end; + +destructor TdwJumpLists.Destroy; +begin + FDestinationList := nil; + FCategories.Free; + FTasks.Free; + + inherited Destroy; +end; + +function TdwJumpLists.DoStoreDisplayKnowCategories: Boolean; +begin + Result := FDisplayKnowCategories <> KNOWN_CATEGORIES_DEFAULT; +end; + +function TdwJumpLists.GetMaxJumpListEntryCount: Integer; +var + Objects: IObjectArray; + MaxSlots: Cardinal; +begin + if not IsSupported then + begin + Result := -1; + end + else + begin + Objects := FDestinationList.BeginList(MaxSlots, @IID_IObjectArray); + FDestinationList.AbortList; + Result := MaxSlots; + end; +end; + +procedure TdwJumpLists.SetAppID(const Value: WideString); +begin + FAppID := Value; + FDestinationList.SetAppID(PWideChar(Value)); +end; + +procedure TdwJumpLists.SetCategories(const Value: TdwLinkCategoryList); +begin + FCategories.Assign(Value); +end; + +procedure TdwJumpLists.SetDisplayKnowCategories(const Value: TJumpListKnowCategories); +begin + if FDisplayKnowCategories <> Value then + begin + FDisplayKnowCategories := Value; + end; +end; + +procedure TdwJumpLists.SetTasks(const Value: TdwLinkObjectList); +begin + FTasks.Assign(Value); +end; + +end. diff --git a/Windows7/dwObjectArray.pas b/Windows7/dwObjectArray.pas new file mode 100644 index 0000000..c1e2600 --- /dev/null +++ b/Windows7/dwObjectArray.pas @@ -0,0 +1,20 @@ +unit dwObjectArray; + +interface + +uses + Windows; + +const + IID_IObjectArray: TGUID = '{92CA9DCD-5622-4BBA-A805-5E9F541BD8C9}'; + +type + IObjectArray = interface + ['{92CA9DCD-5622-4BBA-A805-5E9F541BD8C9}'] + function GetCount(): UInt; safecall; + function GetAt(uiIndex: UInt; riid: PGUID): IUnknown; safecall; + end; + +implementation + +end. diff --git a/Windows7/dwOverlayIcon.pas b/Windows7/dwOverlayIcon.pas new file mode 100644 index 0000000..bbb22b0 --- /dev/null +++ b/Windows7/dwOverlayIcon.pas @@ -0,0 +1,116 @@ +unit dwOverlayIcon; + +interface + +uses + Classes, ImgList, + dwTaskbarComponents; + +type + TdwOverlayIcon = class(TdwTaskbarComponent) + private + FImages: TCustomImageList; + FImageIndex: Integer; + FHint: WideString; + procedure SetImages(const Value: TCustomImageList); + procedure SetImageIndex(const Value: Integer); + function DoShowOverlay: Boolean; + procedure SetHint(const Value: WideString); + protected + function DoInitialize: Boolean; override; + procedure DoUpdate; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + published + property Images: TCustomImageList read FImages write SetImages; + property ImageIndex: Integer read FImageIndex write SetImageIndex; + property Hint: WideString read FHint write SetHint; + end; + +implementation + +uses + SysUtils, Graphics; + +{ TdwOverlayIcon } + +constructor TdwOverlayIcon.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FImages := nil; + FImageIndex := -1; + FHint := ''; +end; + +destructor TdwOverlayIcon.Destroy; +begin + inherited Destroy; +end; + +function TdwOverlayIcon.DoInitialize: Boolean; +begin + Result := DoShowOverlay; +end; + +function TdwOverlayIcon.DoShowOverlay: Boolean; +var + Icon: TIcon; +begin + if CheckWin32Version(6, 1) and (TaskbarList3 <> nil) then + begin + if (FImages = nil) or (FImageIndex < 0) or (FImageIndex >= FImages.Count) then + begin + TaskbarList3.SetOverlayIcon(TaskBarEntryHandle, 0, nil); + Result := True; + end + else + begin + Icon := TIcon.Create; + try + FImages.GetIcon(FImageIndex, Icon); + TaskbarList3.SetOverlayIcon(TaskBarEntryHandle, Icon.ReleaseHandle, PWideChar(FHint)); + Result := True; + finally + Icon.Free; + end; + end; + end + else + begin + Result := False; + end; +end; + +procedure TdwOverlayIcon.DoUpdate; +begin + DoShowOverlay; +end; + +procedure TdwOverlayIcon.SetHint(const Value: WideString); +begin + if FHint <> Value then + begin + FHint := Value; + SendUpdateMessage; + end; +end; + +procedure TdwOverlayIcon.SetImageIndex(const Value: Integer); +begin + if FImageIndex <> Value then + begin + FImageIndex := Value; + SendUpdateMessage; + end; +end; + +procedure TdwOverlayIcon.SetImages(const Value: TCustomImageList); +begin + FImages := Value; + SendUpdateMessage; +end; + +end. diff --git a/Windows7/dwProgressBar.pas b/Windows7/dwProgressBar.pas new file mode 100644 index 0000000..18006ab --- /dev/null +++ b/Windows7/dwProgressBar.pas @@ -0,0 +1,534 @@ +unit dwProgressBar; + +interface + +{$INCLUDE 'DelphiVersions.inc'} + +uses + SysUtils, Classes, Controls, ComCtrls, Messages, Graphics, + dwTaskbarComponents; + +const + ICC_PROGRESS_CLASS = $00000020; + +const + PBS_SMOOTH = $01; + PBS_VERTICAL = $04; + PBS_MARQUEE = $08; + PBS_SMOOTHREVERSE = $10; + +const + PBM_SETMARQUEE = WM_USER + 10; + PBM_SETSTATE = WM_USER + 16; + PBM_GETSTATE = WM_USER + 17; + +const + PBST_NORMAL = $0001; + PBST_ERROR = $0002; + PBST_PAUSED = $0003; + +type + TdwProgressBarState = (pbstMarquee = 0, pbstNormal = 1, pbstError = 2, pbstPaused = 3); + + TdwProgressBar = class(TdwTaskbarWinControl) + private // CodeGear :: ProgressBar + FMin: Integer; + FMax: Integer; + FPosition: Integer; + FStep: Integer; + FOrientation: TProgressBarOrientation; + FSmooth: Boolean; + FSmoothReverse: Boolean; + FBarColor: TColor; + FBackgroundColor: TColor; + + function GetMin: Integer; + function GetMax: Integer; + function GetPosition: Integer; + procedure SetParams(AMin, AMax: Integer); + procedure SetMin(Value: Integer); + procedure SetMax(Value: Integer); + procedure SetPosition(Value: Integer); + procedure SetStep(Value: Integer); + procedure SetOrientation(Value: TProgressBarOrientation); + procedure SetSmooth(Value: Boolean); + procedure SetSmoothReverse(Value: Boolean); + procedure SetBarColor(Value: TColor); + procedure SetBackgroundColor(Value: TColor); + procedure WMEraseBkGnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND; + + private + {$IFDEF Delphi2006_UP} + const LIMIT_16 = 65535; + {$ENDIF} + class procedure ProgressLimitError; + + private + FMsgUpdateTaskbar: Cardinal; + FProgressBarState: TdwProgressBarState; + FMarqueeEnabled: Boolean; + FMarqueeInterval: Integer; + FShowInTaskbar: Boolean; + + procedure SetProgressBarState(const Value: TdwProgressBarState); + procedure SetMarqueeInterval(const Value: Integer); + procedure SetShowInTaskbar(const Value: Boolean); + procedure SetMarqueeEnabled(const Value: Boolean); + + protected // CodeGear :: ProgressBar + procedure CreateParams(var Params: TCreateParams); override; + procedure CreateWnd; override; + procedure DestroyWnd; override; + + protected + class function GetComCtrlClass: Integer; override; + class function GetComCtrlClassName: PChar; override; + + procedure WndProc(var Msg: TMessage); override; + + public // CodeGear ProgressBar + constructor Create(AOwner: TComponent); override; + procedure StepIt; + procedure StepBy(Delta: Integer); + + published // CodeGear ProgressBar + property Align; + property Anchors; + property BorderWidth; + property DragCursor; + property DragKind; + property DragMode; + property Enabled; + property Hint; + property Constraints; + property Min: Integer read GetMin write SetMin default 0; + property Max: Integer read GetMax write SetMax default 100; + property Orientation: TProgressBarOrientation read FOrientation write SetOrientation default pbHorizontal; + property ParentShowHint; + property PopupMenu; + property Position: Integer read GetPosition write SetPosition default 0; + property Smooth: Boolean read FSmooth write SetSmooth default False; + property SmoothReverse: Boolean read FSmoothReverse write SetSmoothReverse default False; + property Step: Integer read FStep write SetStep default 10; + property BarColor: TColor read FBarColor write SetBarColor default clDefault; + property BackgroundColor: TColor read FBackgroundColor write SetBackgroundColor default clDefault; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnContextPopup; + property OnDragDrop; + property OnDragOver; + property OnEndDock; + property OnEndDrag; + property OnEnter; + property OnExit; + {$IFDEF Delphi2006_UP} + property OnMouseActivate; + property OnMouseEnter; + property OnMouseLeave; + {$ENDIF} + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDock; + property OnStartDrag; + property DoubleBuffered; + {$IFDEF Delphi2009_Up} + property ParentDoubleBuffered; + {$ENDIF} + + published + property ProgressBarState: TdwProgressBarState read FProgressBarState write SetProgressBarState default pbstNormal; + property MarqueeEnabled: Boolean read FMarqueeEnabled write SetMarqueeEnabled default False; + property MarqueeInterval: Integer read FMarqueeInterval write SetMarqueeInterval default 75; + property ShowInTaskbar: Boolean read FShowInTaskbar write SetShowInTaskbar default False; + end; + +procedure Register; + +implementation + +uses + Consts, + Themes, CommCtrl, Windows, + dwTaskbarList; + +{$IFNDEF Delphi2006_UP} + const LIMIT_16 = 65535; +{$ENDIF} + +procedure Register; +begin + RegisterComponents('Windows 6+', [TdwProgressBar]); +end; + +{ TdwProgressBar } + +constructor TdwProgressBar.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + Width := 150; + Height := GetSystemMetrics(SM_CYVSCROLL); + FMin := 0; + FMax := 100; + FStep := 10; + FOrientation := pbHorizontal; + FBarColor := clDefault; + FBackgroundColor := clDefault; + FMarqueeInterval := 10; + FSmooth := False; + FSmoothReverse := False; + FMarqueeInterval := 50; + FProgressBarState := pbstNormal; + FShowInTaskbar := False; + + FMsgUpdateTaskbar := RegisterWindowMessage('dw.Control.Update.Taskbar'); +end; + +procedure TdwProgressBar.CreateParams(var Params: TCreateParams); +begin + inherited CreateParams(Params); + + with Params do + begin + if FOrientation = pbVertical then + Style := Style or PBS_VERTICAL; + if FSmooth then + Style := Style or PBS_SMOOTH; + if (FProgressBarState = pbstMarquee) and ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) then + Style := Style or PBS_MARQUEE; + if FSmoothReverse and ThemeServices.ThemesEnabled and CheckWin32Version(6, 0) then + Style := Style or PBS_SMOOTHREVERSE; + end; +end; + +procedure TdwProgressBar.CreateWnd; +begin + inherited CreateWnd; + + if In32BitMode then + begin + SendMessage(Handle, PBM_SETRANGE32, FMin, FMax); + end + else + begin + SendMessage(Handle, PBM_SETRANGE, 0, MakeLong(FMin, FMax)); + end; + + SendMessage(Handle, PBM_SETSTEP, FStep, 0); + Position := FPosition; + BarColor := FBarColor; + BackgroundColor := FBackgroundColor; + ProgressBarState := FProgressBarState; + + if ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) then + begin + if FProgressBarState = pbstMarquee then + SendMessage(Handle, PBM_SETMARQUEE, Integer(BOOL(FMarqueeEnabled)), FMarqueeInterval); + end; +end; + +procedure TdwProgressBar.DestroyWnd; +begin + FPosition := Position; + inherited; +end; + +class function TdwProgressBar.GetComCtrlClass: Integer; +begin + Result := ICC_PROGRESS_CLASS; +end; + +class function TdwProgressBar.GetComCtrlClassName: PChar; +begin + Result := PROGRESS_CLASS; +end; + +function TdwProgressBar.GetMax: Integer; +begin + if HandleAllocated and In32BitMode then + Result := SendMessage(Handle, PBM_GETRANGE, 0, 0) + else + Result := FMax; +end; + +function TdwProgressBar.GetMin: Integer; +begin + if HandleAllocated and In32BitMode then + Result := SendMessage(Handle, PBM_GETRANGE, 1, 0) + else + Result := FMin; +end; + +function TdwProgressBar.GetPosition: Integer; +begin + if HandleAllocated then + begin + if In32BitMode then + Result := SendMessage(Handle, PBM_GETPOS, 0, 0) + else + Result := SendMessage(Handle, PBM_DELTAPOS, 0, 0); + end + else + begin + Result := FPosition; + end; +end; + +class procedure TdwProgressBar.ProgressLimitError; +begin + raise Exception.CreateFmt(SOutOfRange, [0, LIMIT_16]); +end; + +procedure TdwProgressBar.SetBackgroundColor(Value: TColor); +var + ColorRef: TColorRef; +begin + if FBackgroundColor <> Value then + begin + FBackgroundColor := Value; + if Value = clDefault then + ColorRef := TColorRef($FF000000) + else + ColorRef := TColorRef(ColorToRGB(Color)); + + if HandleAllocated then + SendMessage(Handle, PBM_SETBKCOLOR, 0, ColorRef); + end; +end; + +procedure TdwProgressBar.SetBarColor(Value: TColor); +var + ColorRef: TColorRef; +begin + if FBarColor <> Value then + begin + FBarColor := Value; + if Value = clDefault then + ColorRef := TColorRef($FF000000) + else + ColorRef := TColorRef(ColorToRGB(Color)); + + if HandleAllocated then + SendMessage(Handle, PBM_SETBARCOLOR, 0, ColorRef); + end; +end; + +procedure TdwProgressBar.SetMarqueeEnabled(const Value: Boolean); +begin + if FMarqueeEnabled <> Value then + begin + FMarqueeEnabled := Value; + if (FProgressBarState = pbstMarquee) and ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) and HandleAllocated then + begin + SendMessage(Handle, PBM_SETMARQUEE, Integer(BOOL(FMarqueeEnabled)), FMarqueeInterval); + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end; + end; +end; + +procedure TdwProgressBar.SetMarqueeInterval(const Value: Integer); +begin + if FMarqueeInterval <> Value then + begin + FMarqueeInterval := Value; + if (FProgressBarState = pbstMarquee) and ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) and HandleAllocated then + begin + SendMessage(Handle, PBM_SETMARQUEE, Integer(BOOL(FMarqueeEnabled)), FMarqueeInterval); + end; + end; +end; + +procedure TdwProgressBar.SetMax(Value: Integer); +begin + if FMax <> Value then + begin + SetParams(FMin, Value); + end; +end; + +procedure TdwProgressBar.SetMin(Value: Integer); +begin + if FMin <> Value then + begin + SetParams(Value, FMax); + end; +end; + +procedure TdwProgressBar.SetOrientation(Value: TProgressBarOrientation); +begin + if FOrientation <> Value then + begin + FOrientation := Value; + RecreateWnd; + end; +end; + +procedure TdwProgressBar.SetParams(AMin, AMax: Integer); +begin + if AMax < AMin then + raise EInvalidOperation.CreateFmt(SPropertyOutOfRange, [Self.ClassName]); + + if not In32BitMode and ((AMin < 0) or (AMax > LIMIT_16)) then + ProgressLimitError; + + if (FMin <> AMin) or (FMax <> AMax) then + begin + if HandleAllocated then + begin + if In32BitMode then + SendMessage(Handle, PBM_SETRANGE32, AMin, AMax) + else + SendMessage(Handle, PBM_SETRANGE, 0, MakeLong(AMin, AMax)); + + if FMin > FMax then + SendMessage(Handle, PBM_SETPOS, AMin, 0); + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end; + FMin := AMin; + FMax := AMax; + end; +end; + +procedure TdwProgressBar.SetPosition(Value: Integer); +begin + if not In32BitMode and ((Value < 0) or (Value > LIMIT_16)) then + ProgressLimitError; + + if HandleAllocated then + begin + SendMessage(Handle, PBM_SETPOS, Value, 0); + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end + else + begin + FPosition := Value; + end; +end; + +procedure TdwProgressBar.SetProgressBarState(const Value: TdwProgressBarState); +var + DoRecreate: Boolean; +begin + DoRecreate := (FProgressBarState <> Value); + FProgressBarState := Value; + if DoRecreate then + begin + RecreateWnd; + end + else + begin + if CheckWin32Version(6, 0) and HandleAllocated then + SendMessage(Handle, PBM_SETSTATE, Integer(Value), 0); + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end; +end; + +procedure TdwProgressBar.SetShowInTaskbar(const Value: Boolean); +begin + if FShowInTaskbar <> Value then + begin + FShowInTaskbar := Value; + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end; +end; + +procedure TdwProgressBar.SetSmooth(Value: Boolean); +begin + if FSmooth <> Value then + begin + FSmooth := Value; + RecreateWnd; + end; +end; + +procedure TdwProgressBar.SetSmoothReverse(Value: Boolean); +begin + if FSmoothReverse <> Value then + begin + FSmoothReverse := Value; + RecreateWnd; + end; +end; + +procedure TdwProgressBar.SetStep(Value: Integer); +begin + if FStep <> Value then + begin + FStep := Value; + if HandleAllocated then + begin + SendMessage(Handle, PBM_SETSTEP, FStep, 0); + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end; + end; +end; + +procedure TdwProgressBar.StepBy(Delta: Integer); +begin + if HandleAllocated then + begin + SendMessage(Handle, PBM_DELTAPOS, Delta, 0); + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end; +end; + +procedure TdwProgressBar.StepIt; +begin + if HandleAllocated then + begin + SendMessage(Handle, PBM_STEPIT, 0, 0); + PostMessage(Handle, FMsgUpdateTaskbar, 0, 0); + end; +end; + +procedure TdwProgressBar.WMEraseBkGnd(var Message: TWMEraseBkgnd); +begin + DefaultHandler(Message); +end; + +procedure TdwProgressBar.WndProc(var Msg: TMessage); +var + FormHandle: THandle; +begin + if Msg.Msg = FMsgUpdateTaskbar then + begin + if CheckWin32Version(6, 1) and (TaskbarList3 <> nil) then + begin + FormHandle := TaskBarEntryHandle; + if FormHandle <> INVALID_HANDLE_VALUE then + begin + if ShowInTaskbar then + begin + case FProgressBarState of + pbstMarquee: + begin + TaskbarList3.SetProgressState(FormHandle, TBPF_NORMAL); + if FMarqueeEnabled then + TaskbarList3.SetProgressState(FormHandle, TBPF_INDETERMINATE) + else + TaskbarList3.SetProgressState(FormHandle, TBPF_NOPROGRESS); + end; + pbstNormal: TaskbarList3.SetProgressState(FormHandle, TBPF_NORMAL); + pbstError: TaskbarList3.SetProgressState(FormHandle, TBPF_ERROR); + pbstPaused: TaskbarList3.SetProgressState(FormHandle, TBPF_PAUSED); + end; + if FProgressBarState in [pbstNormal, pbstError, pbstPaused] then + begin + TaskbarList3.SetProgressValue(FormHandle, Position - Min, Max - Min); + end; + end + else + begin + TaskbarList3.SetProgressState(FormHandle, TBPF_NOPROGRESS); + end; + end; + end; + end; + + inherited; +end; + +end. diff --git a/Windows7/dwShellItem.pas b/Windows7/dwShellItem.pas new file mode 100644 index 0000000..758ce1a --- /dev/null +++ b/Windows7/dwShellItem.pas @@ -0,0 +1,111 @@ +unit dwShellItem; + +interface + +{$INCLUDE '.\..\Packages\DelphiVersions.inc'} + +uses + ActiveX, Windows; + +const + SID_IShellItem = '{43826d1e-e718-42ee-bc55-a1e261c37bfe}'; + SID_IPropertyStore = '{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}'; + +type + TIID = TGUID; + + IShellItem = interface(IUnknown) + [SID_IShellItem] + function BindToHandler(const pbc: IUnknown; const bhid: TGUID; const riid: TIID; out ppv): HResult; stdcall; + function GetParent(var ppsi: IShellItem): HResult; stdcall; + function GetDisplayName(sigdnName: DWORD; var ppszName: LPWSTR): HResult; stdcall; + function GetAttributes(sfgaoMask: DWORD; var psfgaoAttribs: DWORD): HResult; stdcall; + function Compare(const psi: IShellItem; hint: DWORD; var piOrder: Integer): HResult; stdcall; + end; + + _tagpropertykey = packed record + fmtid: TGUID; + pid: DWORD; + end; + PROPERTYKEY = _tagpropertykey; + PPropertyKey = ^TPropertyKey; + TPropertyKey = _tagpropertykey; + + IPropertyStore = interface(IUnknown) + [SID_IPropertyStore] + function GetCount(out cProps: DWORD): HResult; stdcall; + function GetAt(iProp: DWORD; out pkey: TPropertyKey): HResult; stdcall; + function GetValue(const key: TPropertyKey; out pv: TPropVariant): HResult; stdcall; + function SetValue(const key: TPropertyKey; const propvar: TPropVariant): HResult; stdcall; + function Commit: HResult; stdcall; + end; + +type + PSHItemID = ^TSHItemID; + _SHITEMID = record + cb: Word; + abID: array[0..0] of Byte; + end; + TSHItemID = _SHITEMID; + SHITEMID = _SHITEMID; + + PItemIDList = ^TItemIDList; + _ITEMIDLIST = record + mkid: TSHItemID; + end; + TItemIDList = _ITEMIDLIST; + ITEMIDLIST = _ITEMIDLIST; + +function SHCreateItemFromIDList(pidl: PItemIDList; const riid: TIID; out ppv): HResult; +function SHCreateItemFromParsingName(pszPath: LPCWSTR; const pbc: IUnknown; const riid: TIID; out ppv): HResult; + +implementation + +const + shell32 = 'shell32.dll'; + +var + Shell32Lib: HModule; + _SHCreateItemFromParsingName: function(pszPath: LPCWSTR; const pbc: IUnknown; const riid: TIID; out ppv): HResult; stdcall; + _SHCreateItemFromIDList: function(pidl: PItemIDList; const riid: TIID; out ppv): HResult; stdcall; + +procedure InitShlObj; {$IFDEF Delphi2006_Up} inline; {$ENDIF} +begin + Shell32Lib := GetModuleHandle(shell32); +end; + +function SHCreateItemFromParsingName(pszPath: LPCWSTR; const pbc: IUnknown; const riid: TIID; out ppv): HResult; +begin + if Assigned(_SHCreateItemFromParsingName) then + Result := _SHCreateItemFromParsingName(pszPath, pbc, riid, ppv) + else + begin + InitShlObj; + Result := E_NOTIMPL; + if Shell32Lib > 0 then + begin + _SHCreateItemFromParsingName := GetProcAddress(Shell32Lib, 'SHCreateItemFromParsingName'); // Do not localize + if Assigned(_SHCreateItemFromParsingName) then + Result := _SHCreateItemFromParsingName(pszPath, pbc, riid, ppv); + end; + end; +end; + +function SHCreateItemFromIDList(pidl: PItemIDList; const riid: TIID; out ppv): HResult; +begin + if Assigned(_SHCreateItemFromIDList) then + Result := _SHCreateItemFromIDList(pidl, riid, ppv) + else + begin + InitShlObj; + Result := E_NOTIMPL; + if Shell32Lib > 0 then + begin + _SHCreateItemFromIDList := GetProcAddress(Shell32Lib, 'SHCreateItemFromIDList'); // Do not localize + if Assigned(_SHCreateItemFromIDList) then + Result := _SHCreateItemFromIDList(pidl, riid, ppv); + end; + end; +end; + +end. diff --git a/Windows7/dwTaskbarComponents.pas b/Windows7/dwTaskbarComponents.pas new file mode 100644 index 0000000..3abecbb --- /dev/null +++ b/Windows7/dwTaskbarComponents.pas @@ -0,0 +1,259 @@ +unit dwTaskbarComponents; + +interface + +{$INCLUDE 'DelphiVersions.inc'} + +uses + Classes, Controls, Messages, dwTaskbarList; + +procedure InitCommonControls; stdcall; + +type + TdwTaskbarWinControl = class(TWinControl) + private + FIn32BitMode: Boolean; + FTaskbarList: ITaskbarList; + FTaskbarList2: ITaskbarList2; + FTaskbarList3: ITaskbarList3; + FTaskBarEntryHandle: THandle; + function GetTaskBarEntryHandle: THandle; + + protected + procedure CreateParams(var Params: TCreateParams); override; + property In32BitMode: Boolean read FIn32BitMode; + property TaskbarList: ITaskbarList read FTaskbarList; + property TaskbarList2: ITaskbarList2 read FTaskbarList2; + property TaskbarList3: ITaskbarList3 read FTaskbarList3; + + protected + class function GetComCtrlClass: Integer; virtual; abstract; + class function GetComCtrlClassName: PChar; virtual; abstract; + + public + constructor Create(AOwner: TComponent); override; + + property TaskBarEntryHandle: THandle read GetTaskBarEntryHandle write FTaskBarEntryHandle; + end; + + TdwTaskbarComponent = class(TComponent) + private + FHandle: Cardinal; + FMsgAutoInitialize: Cardinal; + FMsgUpdate: Cardinal; + FAutoInitialize: Boolean; + FIsInitialized: Boolean; + + FTaskbarList: ITaskbarList; + FTaskbarList2: ITaskbarList2; + FTaskbarList3: ITaskbarList3; + FTaskBarEntryHandle: THandle; + function GetTaskBarEntryHandle: THandle; + protected + procedure CheckInitalization; + procedure SendUpdateMessage; + function DoInitialize: Boolean; virtual; + procedure DoUpdate; virtual; + + property AutoInitialize: Boolean read FAutoInitialize write FAutoInitialize default True; + property TaskbarList: ITaskbarList read FTaskbarList; + property TaskbarList2: ITaskbarList2 read FTaskbarList2; + property TaskbarList3: ITaskbarList3 read FTaskbarList3; + + property Handle: Cardinal read FHandle; + function HandleAllocated: Boolean; + procedure WndProc(var Message: TMessage); virtual; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + property TaskBarEntryHandle: THandle read GetTaskBarEntryHandle write FTaskBarEntryHandle; + property IsInitialized: Boolean read FIsInitialized; + end; + +implementation + +uses + Forms, ComCtrls, Windows, ComObj, SysUtils; + +procedure InitCommonControls; stdcall; external comctl32; + +{ TdwCommon } + +constructor TdwTaskbarWinControl.Create(AOwner: TComponent); +var + Obj: IInterface; +begin + inherited; + + FIn32BitMode := InitCommonControl(GetComCtrlClass); + + Obj := CreateComObject(CLSID_TaskbarList); + if Obj = nil then + begin + FTaskbarList := nil; + end + else + begin + FTaskbarList := ITaskbarList(Obj); + FTaskbarList.HrInit; + + FTaskbarList.QueryInterface(CLSID_TaskbarList2, FTaskbarList2); + FTaskbarList.QueryInterface(CLSID_TaskbarList3, FTaskbarList3); + end; + +end; + +procedure TdwTaskbarWinControl.CreateParams(var Params: TCreateParams); +begin + if not In32BitMode then + InitCommonControls; + + inherited; + + CreateSubClass(Params, GetComCtrlClassName); +end; + +function TdwTaskbarWinControl.GetTaskBarEntryHandle: THandle; +begin + if FTaskBarEntryHandle <> 0 then + begin + Result := FTaskBarEntryHandle; + end + else + begin + {$IFNDEF Delphi2007_Up} + Result := Application.Handle; + {$ELSE} + if not Application.MainFormOnTaskBar then + begin + Result := Application.Handle; + end + else + begin + Result := Application.MainForm.Handle; + end; + {$ENDIF} + end; +end; + +{ TdwCommonComponent } + +procedure TdwTaskbarComponent.CheckInitalization; +begin + if FIsInitialized then + raise Exception.Create('Thumbnails are initialized already.'); +end; + +constructor TdwTaskbarComponent.Create(AOwner: TComponent); +var + Obj: IInterface; +begin + inherited; + + Obj := CreateComObject(CLSID_TaskbarList); + if Obj = nil then + begin + FTaskbarList := nil; + end + else + begin + FTaskbarList := ITaskbarList(Obj); + FTaskbarList.HrInit; + + FTaskbarList.QueryInterface(CLSID_TaskbarList2, FTaskbarList2); + FTaskbarList.QueryInterface(CLSID_TaskbarList3, FTaskbarList3); + end; + + if not (csDesigning in ComponentState) then + begin + FHandle := Classes.AllocateHWnd(WndProc); + end + else + begin + FHandle := 0; + end; + + FAutoInitialize := True; + FIsInitialized := False; + FMsgAutoInitialize := RegisterWindowMessage('dw.Component.Taskbar.Thumbnails.Auto.Initialize'); + FMsgUpdate := RegisterWindowMessage('dw.Component.Taskbar.Thumbnails.Update'); + + if HandleAllocated then + PostMessage(Handle, FMsgAutoInitialize, 0, 0); +end; + +destructor TdwTaskbarComponent.Destroy; +begin + if HandleAllocated then + begin + Classes.DeallocateHWnd(FHandle); + FHandle := 0; + end; + inherited; +end; + +function TdwTaskbarComponent.DoInitialize: Boolean; +begin + Result := True; +end; + +procedure TdwTaskbarComponent.DoUpdate; +begin + +end; + +function TdwTaskbarComponent.GetTaskBarEntryHandle: THandle; +begin + if FTaskBarEntryHandle <> 0 then + begin + Result := FTaskBarEntryHandle; + end + else + begin + {$IFNDEF Delphi2007_Up} + Result := Application.Handle; + {$ELSE} + if not Application.MainFormOnTaskBar then + begin + Result := Application.Handle; + end + else + begin + Result := Application.MainForm.Handle; + end; + {$ENDIF} + end; +end; + +function TdwTaskbarComponent.HandleAllocated: Boolean; +begin + Result := FHandle <> 0; +end; + +procedure TdwTaskbarComponent.SendUpdateMessage; +begin + if HandleAllocated then + if FIsInitialized then + PostMessage(Handle, FMsgUpdate, 0, 0); +end; + +procedure TdwTaskbarComponent.WndProc(var Message: TMessage); +begin + if Message.Msg = FMsgAutoInitialize then + begin + if FAutoInitialize then + begin + FIsInitialized := DoInitialize; + end; + end + else + if Message.Msg = FMsgUpdate then + begin + if FIsInitialized then + DoUpdate; + end; + +end; + +end. diff --git a/Windows7/dwTaskbarList.pas b/Windows7/dwTaskbarList.pas new file mode 100644 index 0000000..03a9910 --- /dev/null +++ b/Windows7/dwTaskbarList.pas @@ -0,0 +1,100 @@ +unit dwTaskbarList; + +interface + +{$INCLUDE 'DelphiVersions.inc'} + +uses + Windows; + +{$IFNDEF Delphi2007_Up} +type + ULONGLONG = UInt64; +{$ENDIF} + +const + CLSID_TaskbarList: TGUID = '{56FDF344-FD6D-11D0-958A-006097C9A090}'; + CLSID_TaskbarList2: TGUID = '{602D4995-B13A-429B-A66E-1935E44F4317}'; + CLSID_TaskbarList3: TGUID = '{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}'; + +const + THBF_ENABLED = $0000; + THBF_DISABLED = $0001; + THBF_DISMISSONCLICK = $0002; + THBF_NOBACKGROUND = $0004; + THBF_HIDDEN = $0008; + +const + THB_BITMAP = $0001; + THB_ICON = $0002; + THB_TOOLTIP = $0004; + THB_FLAGS = $0008; + +const + THBN_CLICKED = $1800; + +const + TBPF_NOPROGRESS = $00; + TBPF_INDETERMINATE = $01; + TBPF_NORMAL = $02; + TBPF_ERROR= $04; + TBPF_PAUSED = $08; + +const + TBATF_USEMDITHUMBNAIL: DWORD = $00000001; + TBATF_USEMDILIVEPREVIEW: DWORD = $00000002; + +const + WM_DWMSENDICONICTHUMBNAIL = $0323; + WM_DWMSENDICONICLIVEPREVIEWBITMAP = $0326; + +type + TTipString = array[0..259] of WideChar; + PTipString = ^TTipString; + tagTHUMBBUTTON = packed record + dwMask: DWORD; + iId: UINT; + iBitmap: UINT; + hIcon: HICON; + szTip: TTipString; + dwFlags: DWORD; + end; + THUMBBUTTON = tagTHUMBBUTTON; + THUMBBUTTONLIST = ^THUMBBUTTON; + TThumbButton = THUMBBUTTON; + TThumbButtonList = array of TThumbButton; + +type + ITaskbarList = interface + ['{56FDF342-FD6D-11D0-958A-006097C9A090}'] + procedure HrInit; safecall; + procedure AddTab(hwnd: Cardinal); safecall; + procedure DeleteTab(hwnd: Cardinal); safecall; + procedure ActivateTab(hwnd: Cardinal); safecall; + procedure SetActiveAlt(hwnd: Cardinal); safecall; + end; + + ITaskbarList2 = interface(ITaskbarList) + ['{602D4995-B13A-429B-A66E-1935E44F4317}'] + procedure MarkFullscreenWindow(hwnd: Cardinal; fFullscreen: Bool); safecall; + end; + + ITaskbarList3 = interface(ITaskbarList2) + ['{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}'] + procedure SetProgressValue(hwnd: Cardinal; ullCompleted, ullTotal: ULONGLONG); safecall; + procedure SetProgressState(hwnd: Cardinal; tbpFlags: DWORD); safecall; + procedure RegisterTab(hwndTab: Cardinal; hwndMDI: Cardinal); safecall; + procedure UnregisterTab(hwndTab: Cardinal); safecall; + procedure SetTabOrder(hwndTab: Cardinal; hwndInsertBefore: Cardinal); safecall; + procedure SetTabActive(hwndTab: Cardinal; hwndMDI: Cardinal; tbatFlags: DWORD); safecall; + procedure ThumbBarAddButtons(hwnd: Cardinal; cButtons: UINT; Button: THUMBBUTTONLIST); safecall; + procedure ThumbBarUpdateButtons(hwnd: Cardinal; cButtons: UINT; pButton: THUMBBUTTONLIST); safecall; + procedure ThumbBarSetImageList(hwnd: Cardinal; himl: Cardinal); safecall; + procedure SetOverlayIcon(hwnd: Cardinal; hIcon: HICON; pszDescription: LPCWSTR); safecall; + procedure SetThumbnailTooltip(hwnd: Cardinal; pszTip: LPCWSTR); safecall; + function SetThumbnailClip(hwnd: Cardinal; prcClip: PRect):Cardinal; safecall; + end; + +implementation + +end. diff --git a/Windows7/dwTaskbarThumbnails.pas b/Windows7/dwTaskbarThumbnails.pas new file mode 100644 index 0000000..0272546 --- /dev/null +++ b/Windows7/dwTaskbarThumbnails.pas @@ -0,0 +1,410 @@ +unit dwTaskbarThumbnails; + +interface + +uses + Classes, Messages, ImgList, AppEvnts, Windows, + dwTaskbarComponents, dwTaskbarList; + +type + TdwTaskbarThumbnails = class; + TdwTaskbarThumbnailList = class; + TdwTaskbarThumbnailItem = class; + + TOnThumbnailClick = procedure(Sender: TdwTaskbarThumbnailItem) of object; + + TdwTaskbarThumbnailItem = class(TCollectionItem) + private + FImageIndex: Integer; + FHint: WideString; + FEnabled: Boolean; + FShowBorder: Boolean; + FDismissOnClick: Boolean; + FVisible: Boolean; + FTag: Integer; + procedure SetImageIndex(const Value: Integer); + procedure SetHint(const Value: WideString); + procedure SetEnabled(const Value: Boolean); + procedure SetShowBorder(const Value: Boolean); + procedure SetDismissOnClick(const Value: Boolean); + procedure SetVisible(const Value: Boolean); + protected + public + constructor Create(Collection: TCollection); override; + procedure Assign(Source: TPersistent); override; + published + property ImageIndex: Integer read FImageIndex write SetImageIndex; + property Hint: WideString read FHint write SetHint; + property Enabled: Boolean read FEnabled write SetEnabled default True; + property ShowBorder: Boolean read FShowBorder write SetShowBorder default True; + property DismissOnClick: Boolean read FDismissOnClick write SetDismissOnClick default False; + property Visible: Boolean read FVisible write SetVisible default True; + property Tag: Integer read FTag write FTag default 0; + end; + + TdwTaskbarThumbnailList = class(TCollection) + private + FTaskbarThumbnails: TdwTaskbarThumbnails; + function GetItem(Index: Integer): TdwTaskbarThumbnailItem; + procedure SetItem(Index: Integer; Value: TdwTaskbarThumbnailItem); + protected + function GetOwner: TPersistent; override; + procedure Update(Item: TCollectionItem); override; + public + constructor Create(TaskbarThumbnails: TdwTaskbarThumbnails); + function Add: TdwTaskbarThumbnailItem; + function AddItem(Item: TdwTaskbarThumbnailItem; Index: Integer): TdwTaskbarThumbnailItem; + function Insert(Index: Integer): TdwTaskbarThumbnailItem; + property Items[Index: Integer]: TdwTaskbarThumbnailItem read GetItem write SetItem; default; + end; + + TdwTaskbarThumbnails = class(TdwTaskbarComponent) + private + FAppEvents: TApplicationEvents; + + FImages: TCustomImageList; + FThumbnails: TdwTaskbarThumbnailList; + FOnThumbnailClick: TOnThumbnailClick; + procedure SetImages(const Value: TCustomImageList); + procedure UpdateThumbnail(Index: Integer); + procedure UpdateThumbnails; + procedure SetThumbnails(const Value: TdwTaskbarThumbnailList); + function GetThumbButtons: TThumbButtonList; + procedure DoAppMessage(var Msg: TMsg; var Handled: Boolean); + protected + function DoInitialize: Boolean; override; + procedure DoUpdate; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + procedure ShowThumbnails; + function ClipThumbnail(window:Cardinal; left:integer; right:integer; top:integer; bottom:integer):cardinal; + published + property AutoInitialize; + property Images: TCustomImageList read FImages write SetImages; + property Thumbnails: TdwTaskbarThumbnailList read FThumbnails write SetThumbnails; + property OnThumbnailClick: TOnThumbnailClick read FOnThumbnailClick write FOnThumbnailClick; + end; + +implementation + +uses + SysUtils, Graphics; + +{ TdwTaskbarThumbnailItem } + +procedure TdwTaskbarThumbnailItem.Assign(Source: TPersistent); +begin + if Source is TdwTaskbarThumbnailItem then + begin + Self.FImageIndex := (Source as TdwTaskbarThumbnailItem).FImageIndex; + Self.FHint := (Source as TdwTaskbarThumbnailItem).FHint; + Self.FEnabled := (Source as TdwTaskbarThumbnailItem).FEnabled; + Self.FShowBorder := (Source as TdwTaskbarThumbnailItem).FShowBorder; + Self.FDismissOnClick := (Source as TdwTaskbarThumbnailItem).FDismissOnClick; + Self.FVisible := (Source as TdwTaskbarThumbnailItem).FVisible; + Self.FTag := (Source as TdwTaskbarThumbnailItem).FTag; + end + else + begin + inherited Assign(Source); + end; +end; + +constructor TdwTaskbarThumbnailItem.Create(Collection: TCollection); +begin + inherited Create(Collection); + + FImageIndex := Index; + FHint := ''; + FEnabled := True; + FShowBorder := True; + FDismissOnClick := False; + FVisible := True; + FTag := 0; +end; + +procedure TdwTaskbarThumbnailItem.SetDismissOnClick(const Value: Boolean); +begin + if FDismissOnClick <> Value then + begin + FDismissOnClick := Value; + Changed(False); + end; +end; + +procedure TdwTaskbarThumbnailItem.SetEnabled(const Value: Boolean); +begin + if FEnabled <> Value then + begin + FEnabled := Value; + Changed(False); + end; +end; + +procedure TdwTaskbarThumbnailItem.SetHint(const Value: WideString); +begin + if FHint <> Value then + begin + FHint := Value; + Changed(False); + end; +end; + +procedure TdwTaskbarThumbnailItem.SetImageIndex(const Value: Integer); +begin + if FImageIndex <> Value then + begin + FImageIndex := Value; + Changed(False); + end; +end; + +procedure TdwTaskbarThumbnailItem.SetShowBorder(const Value: Boolean); +begin + if FShowBorder <> Value then + begin + FShowBorder := Value; + Changed(False); + end; +end; + +procedure TdwTaskbarThumbnailItem.SetVisible(const Value: Boolean); +begin + if FVisible <> Value then + begin + FVisible := Value; + Changed(False); + end; +end; + +{ TdwTaskbarThumbnailList } + +function TdwTaskbarThumbnailList.Add: TdwTaskbarThumbnailItem; +begin + FTaskbarThumbnails.CheckInitalization; + + Result := AddItem(nil, -1); +end; + +function TdwTaskbarThumbnailList.AddItem(Item: TdwTaskbarThumbnailItem; Index: Integer): TdwTaskbarThumbnailItem; +begin + FTaskbarThumbnails.CheckInitalization; + + if Item = nil then + begin + Result := TdwTaskbarThumbnailItem.Create(Self); + end + else + begin + Result := Item; + if Assigned(Item) then + begin + Result.Collection := Self; + if Index < Count then + Index := Count - 1; + Result.Index := Index; + end; + end; +end; + +constructor TdwTaskbarThumbnailList.Create(TaskbarThumbnails: TdwTaskbarThumbnails); +begin + inherited Create(TdwTaskbarThumbnailItem); + FTaskbarThumbnails := TaskbarThumbnails; +end; + +function TdwTaskbarThumbnailList.GetItem(Index: Integer): TdwTaskbarThumbnailItem; +begin + Result := TdwTaskbarThumbnailItem(inherited GetItem(Index)); +end; + +function TdwTaskbarThumbnailList.GetOwner: TPersistent; +begin + Result := FTaskbarThumbnails; +end; + +function TdwTaskbarThumbnailList.Insert(Index: Integer): TdwTaskbarThumbnailItem; +begin + FTaskbarThumbnails.CheckInitalization; + + Result := AddItem(nil, Index); +end; + +procedure TdwTaskbarThumbnailList.SetItem(Index: Integer; Value: TdwTaskbarThumbnailItem); +begin + inherited SetItem(Index, Value); +end; + +procedure TdwTaskbarThumbnailList.Update(Item: TCollectionItem); +begin + if Item <> nil then + FTaskbarThumbnails.UpdateThumbnail(Item.Index) + else + FTaskbarThumbnails.UpdateThumbnails; +end; + +{ TdwTaskbarThumbnails } + +constructor TdwTaskbarThumbnails.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FThumbnails := TdwTaskbarThumbnailList.Create(Self); + + FAppEvents := TApplicationEvents.Create(Self); + FAppEvents.OnMessage := DoAppMessage; +end; + +destructor TdwTaskbarThumbnails.Destroy; +begin + FThumbnails.Free; + FAppEvents.Free; + + inherited; +end; + +procedure TdwTaskbarThumbnails.DoAppMessage(var Msg: TMsg; var Handled: Boolean); +begin + if Msg.hwnd = TaskBarEntryHandle then + if Msg.message = WM_COMMAND then + if HiWord(Msg.wParam) = THBN_CLICKED then + begin + Handled := True; + if Assigned(FOnThumbnailClick) then + FOnThumbnailClick(FThumbnails[LoWord(Msg.wParam)]); + end; +end; + +function TdwTaskbarThumbnails.ClipThumbnail(window:Cardinal; left:integer; right:integer; top:integer; bottom:integer):cardinal; +var + rect:TRect; + rectp:PRect; +begin + //rect:=TRect.Create; + rect.Left := left; + rect.Top := top; + rect.Right := right; + rect.Bottom := bottom; + rectp:=@rect; + if (TaskbarList3<>nil) then + Result := TaskbarList3.SetThumbnailClip(window, rectp) + else + Result := 16777216; +end; + +function TdwTaskbarThumbnails.DoInitialize: Boolean; +var + Buttons: TThumbButtonList; +begin + SetLength(Buttons, 0); + if CheckWin32Version(6, 1) and (TaskbarList3 <> nil) then + begin + Buttons := GetThumbButtons; + if TaskbarList3 <> nil then + begin + TaskbarList3.ThumbBarSetImageList(TaskBarEntryHandle, FImages.Handle); + TaskbarList3.ThumbBarAddButtons(TaskBarEntryHandle, Length(Buttons), @Buttons[0]); + Result := True; + end + else + begin + Result := False; + end; + end + else + begin + Result := False; + end; +end; + +procedure TdwTaskbarThumbnails.DoUpdate; +var + Buttons: TThumbButtonList; +begin + SetLength(Buttons, 0); + if not IsInitialized then + Exit; + + Buttons := GetThumbButtons; + TaskbarList3.ThumbBarSetImageList(TaskBarEntryHandle, FImages.Handle); + TaskbarList3.ThumbBarUpdateButtons(TaskBarEntryHandle, Length(Buttons), @Buttons[0]); +end; + +function TdwTaskbarThumbnails.GetThumbButtons: TThumbButtonList; +var + I: Integer; + Thumb: TdwTaskbarThumbnailItem; +begin + if (FThumbnails.Count < 1) or (FThumbnails.Count > 7) then + raise Exception.Create('The thumbnail count must be at least 1 and can be up to 7.'); + + SetLength(Result, FThumbnails.Count); + for I := 0 to FThumbnails.Count - 1 do + begin + Thumb := FThumbnails[I]; + + Result[I].dwMask := THB_FLAGS; + + Result[I].iId := Thumb.Index; + + if FImages <> nil then + if (Thumb.ImageIndex >= 0) and (Thumb.ImageIndex < FImages.Count) then + begin + Result[I].dwMask := Result[I].dwMask or THB_BITMAP; + Result[I].iBitmap := Thumb.ImageIndex; + end; + + if Thumb.FHint <> '' then + begin + Result[I].dwMask := Result[I].dwMask or THB_TOOLTIP; + StringToWideChar(Thumb.Hint, Result[I].szTip, Length(Result[I].szTip)); + end; + + Result[I].dwFlags := 0; + if Thumb.FEnabled then + Result[I].dwFlags := Result[I].dwFlags or THBF_ENABLED + else + Result[I].dwFlags := Result[I].dwFlags or THBF_DISABLED; + + if not Thumb.FShowBorder then + Result[I].dwFlags := Result[I].dwFlags or THBF_NOBACKGROUND; + + if Thumb.DismissOnClick then + Result[I].dwFlags := Result[I].dwFlags or THBF_DISMISSONCLICK; + + if not Thumb.Visible then + Result[I].dwFlags := Result[I].dwFlags or THBF_HIDDEN; + end; +end; + +procedure TdwTaskbarThumbnails.SetImages(const Value: TCustomImageList); +begin + FImages := Value; + SendUpdateMessage; +end; + +procedure TdwTaskbarThumbnails.SetThumbnails(const Value: TdwTaskbarThumbnailList); +begin + FThumbnails.Assign(Value); + SendUpdateMessage; +end; + +procedure TdwTaskbarThumbnails.ShowThumbnails; +begin + CheckInitalization; + DoInitialize; +end; + +procedure TdwTaskbarThumbnails.UpdateThumbnail(Index: Integer); +begin + SendUpdateMessage; +end; + +procedure TdwTaskbarThumbnails.UpdateThumbnails; +begin + SendUpdateMessage; +end; + +end.