├── shrink_all.bat
├── gui
├── gditools.ico
├── rsrc
│ ├── icons
│ │ ├── gditools.icns
│ │ ├── gditools.ico
│ │ ├── gditools.png
│ │ ├── imglist
│ │ │ ├── disc16.ico
│ │ │ ├── file16.ico
│ │ │ └── folder16.ico
│ │ └── highres
│ │ │ ├── Iconleak-Stainless-Document.ico
│ │ │ ├── Oxygen-Icons.org-Oxygen-Mimetypes-inode-directory.ico
│ │ │ └── Oxygen-Icons.org-Oxygen-Actions-tools-media-optical-format.ico
│ └── setupgui.txt
├── gditools.lpr
├── settings.pas
├── about.pas
├── sortfile.lfm
├── sortfile.pas
├── utils.pas
├── settings.lfm
├── extract.lfm
├── extract.pas
├── version.pas
├── gditools.lpi
├── main.pas
├── main.lfm
├── engine.pas
└── about.lfm
├── gdishrink.py
├── addons
├── guihelp.py
├── gdifix.py
└── bin2iso.py
├── .gitignore
├── licences
├── iso9660_license.txt
└── GNU_GPL_v3.txt
├── shrink_all.sh
├── readme.txt
└── iso9660.py
/shrink_all.bat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/shrink_all.bat
--------------------------------------------------------------------------------
/gui/gditools.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/gditools.ico
--------------------------------------------------------------------------------
/gui/rsrc/icons/gditools.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/gditools.icns
--------------------------------------------------------------------------------
/gui/rsrc/icons/gditools.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/gditools.ico
--------------------------------------------------------------------------------
/gui/rsrc/icons/gditools.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/gditools.png
--------------------------------------------------------------------------------
/gui/rsrc/icons/imglist/disc16.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/imglist/disc16.ico
--------------------------------------------------------------------------------
/gui/rsrc/icons/imglist/file16.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/imglist/file16.ico
--------------------------------------------------------------------------------
/gui/rsrc/icons/imglist/folder16.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/imglist/folder16.ico
--------------------------------------------------------------------------------
/gui/rsrc/icons/highres/Iconleak-Stainless-Document.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/highres/Iconleak-Stainless-Document.ico
--------------------------------------------------------------------------------
/gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Mimetypes-inode-directory.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Mimetypes-inode-directory.ico
--------------------------------------------------------------------------------
/gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Actions-tools-media-optical-format.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Actions-tools-media-optical-format.ico
--------------------------------------------------------------------------------
/gdishrink.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from gditools import gdishrink
3 |
4 | def main(argv):
5 | inputfile = argv[1]
6 | outputpath = argv[2] if len(argv) > 2 else None
7 | gdishrink(inputfile, outputpath, True, True)
8 |
9 | def _printUsage(pname='gditools.py'):
10 | print('Usage: {} input_gdi output_path\n'.format(pname))
11 | print('If no output_path is supplied, the image is shrunk in place')
12 |
13 | if __name__ == '__main__':
14 | if len(sys.argv) > 1:
15 | main(sys.argv)
16 | else:
17 | _printUsage(sys.argv[0])
--------------------------------------------------------------------------------
/gui/gditools.lpr:
--------------------------------------------------------------------------------
1 | program gditools;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | uses
6 | {$IFDEF UNIX}{$IFDEF UseCThreads}
7 | cthreads,
8 | {$ENDIF}{$ENDIF}
9 | Interfaces, // this includes the LCL widgetset
10 | Forms, Main, utils, extract, sortfile, Settings, Engine, Version, about;
11 |
12 | {$R *.res}
13 |
14 | begin
15 | Application.Title:='gditools.py GUI';
16 | RequireDerivedFormResource := True;
17 | Application.Initialize;
18 | Application.CreateForm(TfrmMain, frmMain);
19 | Application.CreateForm(TfrmExtractAll, frmExtractAll);
20 | Application.CreateForm(TfrmSortFile, frmSortFile);
21 | Application.CreateForm(TfrmSettings, frmSettings);
22 | Application.CreateForm(TfrmAbout, frmAbout);
23 | Application.Run;
24 | end.
25 |
26 |
--------------------------------------------------------------------------------
/addons/guihelp.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | Program that outputs the volume label of the iso9660 filesystem of
6 | a GDI dump. Designed to be used in a GUI SiZiOUS is writing.
7 |
8 | FamilyGuy 2014
9 |
10 |
11 | GuiHelper is released under the GNU General Public License
12 | (version 3), a copy of which (GNU_GPL_v3.txt) is provided in the
13 | license folder.
14 | """
15 |
16 | import os, sys
17 | sys.path.append('..')
18 | sys.path.append('.')
19 | from gditools import GDIfile
20 |
21 |
22 | if __name__ == '__main__':
23 | with GDIfile(sys.argv[1]) as gdifile:
24 | tmp = gdifile._sorted_records()[0]['name']
25 | if tmp[0] == '/':
26 | tmp = tmp[1:]
27 | print(tmp)
28 | print(gdifile.get_pvd()['volume_identifier'])
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 | *.pyc
6 |
7 | # C extensions
8 | *.so
9 |
10 | # Distribution / packaging
11 | .Python
12 | env/
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *,cover
47 | .hypothesis/
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 |
56 | # Sphinx documentation
57 | docs/_build/
58 |
59 | # PyBuilder
60 | target/
61 |
62 | #Ipython Notebook
63 | .ipynb_checkpoints
64 |
--------------------------------------------------------------------------------
/licences/iso9660_license.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 2013-2014 Barnaby Gale
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to
5 | deal in the Software without restriction, including without limitation the
6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 | sell copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies of the Software and its documentation and acknowledgment shall be
12 | given in the documentation and software packages that this Software was
13 | used.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 | THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/gui/rsrc/setupgui.txt:
--------------------------------------------------------------------------------
1 | ___ __ __
2 | ____ _____/ (_) /_____ ____ / /____
3 | / __ `/ __ / / __/ __ \/ __ \/ / ___/
4 | / /_/ / /_/ / / /_/ /_/ / /_/ / (__ )
5 | \__, /\__,_/_/\__/\____/\____/_/____/
6 | /____/
7 |
8 | For your convenience you can use the GUI provided for your platform.
9 | This package is an addon for the original gditools.py package. It can't
10 | be used alone.
11 |
12 | To use it it's really simple:
13 | 0. Download the gditools.py original package and extract it.
14 | 1. Download the GUI package for your platform (currently Windows or
15 | Linux 64-bit).
16 | 2. Extract the GUI binary at the same location of your gditools.py script.
17 | 3. Just double-click on the 'gditools.exe' or 'gditools' binary to run it.
18 |
19 | The usage is pretty much the same as the excellent GD-ROM Explorer made by
20 | Japanese Cake which is only available on Windows.
21 |
22 | If you want to modify/compile the GUI for your platform, please use the
23 | Lazarus IDE: http://www.lazarus.freepascal.org/
24 |
25 | ______________________________________________________________________/ eof /___
26 |
--------------------------------------------------------------------------------
/addons/gdifix.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | gdifix, like isofix.exe but much more simple.
6 |
7 | This is an example of a simple program that uses gditools.py as a
8 | base library to handle gdi files in a meaningful manner.
9 |
10 | FamilyGuy 2014
11 |
12 |
13 | gdifix.py is released under the GNU General Public License
14 | (version 3), a copy of which (GNU_GPL_v3.txt) is provided in the
15 | license folder.
16 | """
17 |
18 | import os, sys
19 | sys.path.append('..')
20 | sys.path.append('.')
21 | from gditools import GDIfile, _copy_buffered
22 |
23 |
24 | def gdifix(ifile, ofile='{dirname}/fixed.iso'):
25 | gdifile = GDIfile(ifile, verbose = True)._gdifile
26 | gdifile.seek(0,0)
27 | ofile = ofile.format(dirname = os.path.dirname(ifile))
28 | print('Reading: {} \nWriting: {}'.format(ifile,ofile))
29 | with open(ofile,'wb') as of:
30 | _copy_buffered(gdifile,of)
31 |
32 | def main(argv):
33 | if len(argv) > 1 and os.path.isfile(argv[1]):
34 | gdifix(*argv[1:])
35 | else:
36 | print('gdifix, converts a gdi dump into a valid iso file\n')
37 | print('Usage: gdifix.py disc.gdi [fixed.iso]')
38 | print('\nFamilyGuy 2014')
39 |
40 | if __name__ == '__main__':
41 | main(sys.argv)
42 |
--------------------------------------------------------------------------------
/addons/bin2iso.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | bin2iso, blindly read a file as a 2352 bytes/sector cd-rom image
6 | and outputs the corresponding 2048 bytes/sector image file.
7 |
8 | This is an example of a simple program that uses gditools.py as a
9 | base library to handle gdi files in a meaningful manner.
10 |
11 | FamilyGuy 2014
12 |
13 |
14 | bin2iso.py is released under the GNU General Public License
15 | (version 3), a copy of which (GNU_GPL_v3.txt) is provided in the
16 | license folder.
17 | """
18 |
19 | import os, sys
20 | sys.path.append('..')
21 | sys.path.append('.')
22 | from gditools import CdImage, _copy_buffered
23 |
24 |
25 | def bin2iso(ifile, ofile='{dirname}/{basename}.iso', length = None):
26 | binfile = CdImage(ifile, mode = 2352)
27 | ofile = ofile.format(dirname = os.path.dirname(ifile),
28 | basename = os.path.splitext(os.path.basename(ifile))[0])
29 | print('Reading: {} \nWriting: {}'.format(ifile, ofile))
30 | with open(ofile, 'wb') as of:
31 | _copy_buffered(binfile, of, length=length)
32 |
33 | def main(argv):
34 | if len(argv) > 1 and os.path.isfile(argv[1]):
35 | bin2iso(*argv[1:])
36 | else:
37 | print('bin2iso, converts a bin file into an iso, BLINDLY.\n')
38 | print('Usage: bin2iso.py file.bin [file.iso]')
39 | print('\nFamilyGuy 2014')
40 |
41 | if __name__ == '__main__':
42 | main(sys.argv)
43 |
--------------------------------------------------------------------------------
/gui/settings.pas:
--------------------------------------------------------------------------------
1 | {
2 | gditools.py GUI are licensed under the GNU General Public License (version 3),
3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt.
4 |
5 | SiZiOUS 2015 / www.sizious.com
6 | }
7 | unit Settings;
8 |
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
15 | ExtCtrls;
16 |
17 | type
18 | { TfrmSettings }
19 |
20 | TfrmSettings = class(TForm)
21 | btnCancel: TButton;
22 | btnOK: TButton;
23 | btnPythonFileName: TButton;
24 | edtPythonFileName: TEdit;
25 | gbxPython: TGroupBox;
26 | lblPythonHint: TLabel;
27 | opdPythonFileName: TOpenDialog;
28 | pnlPython: TPanel;
29 | pnlButtons: TPanel;
30 | procedure btnPythonFileNameClick(Sender: TObject);
31 | private
32 | function GetPythonExecutable: TFileName;
33 | procedure SetPythonExecutable(AValue: TFileName);
34 | { private declarations }
35 | public
36 | { public declarations }
37 | property PythonExecutable: TFileName
38 | read GetPythonExecutable write SetPythonExecutable;
39 | end;
40 |
41 | var
42 | frmSettings: TfrmSettings;
43 |
44 | implementation
45 |
46 | {$R *.lfm}
47 |
48 | { TfrmSettings }
49 |
50 | procedure TfrmSettings.btnPythonFileNameClick(Sender: TObject);
51 | begin
52 | with opdPythonFileName do
53 | begin
54 | FileName := PythonExecutable;
55 | if Execute then
56 | PythonExecutable := FileName;
57 | end;
58 | end;
59 |
60 | function TfrmSettings.GetPythonExecutable: TFileName;
61 | begin
62 | Result := edtPythonFileName.Text;
63 | end;
64 |
65 | procedure TfrmSettings.SetPythonExecutable(AValue: TFileName);
66 | begin
67 | edtPythonFileName.Text := AValue;
68 | end;
69 |
70 | end.
71 |
72 |
--------------------------------------------------------------------------------
/gui/about.pas:
--------------------------------------------------------------------------------
1 | {
2 | gditools.py GUI are licensed under the GNU General Public License (version 3),
3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt.
4 |
5 | SiZiOUS 2015 / www.sizious.com
6 | }
7 | unit About;
8 |
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
15 | StdCtrls;
16 |
17 | type
18 | { TfrmAbout }
19 |
20 | TfrmAbout = class(TForm)
21 | btnClose: TButton;
22 | imgLogo: TImage;
23 | lblAppInfo: TLabel;
24 | lblAppName: TLabel;
25 | lblAuthors: TLabel;
26 | lblCredits: TLabel;
27 | lblIcons: TLabel;
28 | lblPoweredBy: TLabel;
29 | procedure btnCloseClick(Sender: TObject);
30 | procedure FormCreate(Sender: TObject);
31 | procedure lblAuthorsClick(Sender: TObject);
32 | procedure lblAuthorsMouseEnter(Sender: TObject);
33 | procedure lblAuthorsMouseLeave(Sender: TObject);
34 | private
35 | { private declarations }
36 | public
37 | { public declarations }
38 | end;
39 |
40 | var
41 | frmAbout: TfrmAbout;
42 |
43 | implementation
44 |
45 | uses
46 | LCLIntf, Version;
47 |
48 | {$R *.lfm}
49 |
50 | { TfrmAbout }
51 |
52 | procedure TfrmAbout.btnCloseClick(Sender: TObject);
53 | begin
54 | Close;
55 | end;
56 |
57 | procedure TfrmAbout.FormCreate(Sender: TObject);
58 | begin
59 | lblAppName.Caption := Application.Title;
60 | Caption := 'About ' + Application.Title + '...';
61 | lblAppInfo.Caption := 'Version ' + GetFileVersion + ' on ' + GetTargetInfo;
62 | end;
63 |
64 | procedure TfrmAbout.lblAuthorsClick(Sender: TObject);
65 | begin
66 | OpenURL((Sender as TLabel).Hint);
67 | end;
68 |
69 | procedure TfrmAbout.lblAuthorsMouseEnter(Sender: TObject);
70 | begin
71 | with (Sender as TLabel) do
72 | begin
73 | Font.Underline := True;
74 | Cursor := crHandPoint;
75 | end;
76 | end;
77 |
78 | procedure TfrmAbout.lblAuthorsMouseLeave(Sender: TObject);
79 | begin
80 | with (Sender as TLabel) do
81 | begin
82 | Font.Underline := False;
83 | Cursor := crDefault;
84 | end;
85 | end;
86 |
87 | end.
88 |
89 |
--------------------------------------------------------------------------------
/gui/sortfile.lfm:
--------------------------------------------------------------------------------
1 | object frmSortFile: TfrmSortFile
2 | Left = 496
3 | Height = 190
4 | Top = 308
5 | Width = 320
6 | BorderIcons = [biSystemMenu]
7 | BorderStyle = bsDialog
8 | Caption = 'Generate Sort File'
9 | ClientHeight = 190
10 | ClientWidth = 320
11 | OnCreate = FormCreate
12 | Position = poScreenCenter
13 | LCLVersion = '1.2.6.0'
14 | object gbxDataDir: TGroupBox
15 | Left = 8
16 | Height = 80
17 | Top = 8
18 | Width = 304
19 | Caption = ' Data Directory: '
20 | ClientHeight = 58
21 | ClientWidth = 296
22 | TabOrder = 0
23 | object edtDataDir: TEdit
24 | Left = 8
25 | Height = 22
26 | Top = 8
27 | Width = 280
28 | TabOrder = 0
29 | Text = 'data'
30 | end
31 | object cbxVolumeLabel: TCheckBox
32 | Left = 8
33 | Height = 18
34 | Top = 38
35 | Width = 133
36 | Caption = 'Use Volume Label'
37 | OnChange = cbxVolumeLabelChange
38 | TabOrder = 1
39 | end
40 | end
41 | object gbxOutputDir: TGroupBox
42 | Left = 8
43 | Height = 56
44 | Top = 96
45 | Width = 304
46 | Caption = ' Output FileName: '
47 | ClientHeight = 34
48 | ClientWidth = 296
49 | TabOrder = 1
50 | object edtOutputFileName: TEdit
51 | Left = 8
52 | Height = 22
53 | Top = 8
54 | Width = 240
55 | TabOrder = 0
56 | end
57 | object btnOutputFileName: TButton
58 | Left = 256
59 | Height = 25
60 | Top = 6
61 | Width = 35
62 | Caption = '...'
63 | OnClick = btnOutputFileNameClick
64 | TabOrder = 1
65 | end
66 | end
67 | object btnOK: TButton
68 | Left = 112
69 | Height = 25
70 | Top = 160
71 | Width = 99
72 | Caption = 'OK'
73 | ModalResult = 1
74 | TabOrder = 2
75 | end
76 | object btnCancel: TButton
77 | Left = 213
78 | Height = 25
79 | Top = 160
80 | Width = 99
81 | Caption = 'Cancel'
82 | ModalResult = 2
83 | TabOrder = 3
84 | end
85 | object svdSortFile: TSaveDialog
86 | Title = 'Save the Sort file to...'
87 | DefaultExt = '.txt'
88 | FileName = 'sorttxt.txt'
89 | Filter = 'Sort Files (sorttxt.txt)|sorttxt.txt|Text Files (*.txt)|*.txt|All Files (*.*)|*.*'
90 | Options = [ofOverwritePrompt, ofPathMustExist, ofEnableSizing, ofViewDetail]
91 | left = 208
92 | top = 104
93 | end
94 | end
--------------------------------------------------------------------------------
/shrink_all.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Text formatting
4 | readonly BOLD=$(tput bold)
5 | readonly RED=$(tput setaf 1)
6 | readonly NORMAL=$(tput sgr0)
7 |
8 | promptContinue() {
9 | read -n 1 -s -r -p "${BOLD}Press ctrl+c to cancel or any key to continue...${NORMAL}"
10 | printf "\n\n"
11 | }
12 |
13 | echo "NOTE: Python 2.7.x is required to use gditools, Python 3.x.x will not work."
14 | echo "Your installed Python version is: ${BOLD}${RED}$(python --version 2>&1)${NORMAL}"
15 | promptContinue
16 |
17 | echo "NOTE: If you have the REDUMP game set, they add some non-standard track data to"
18 | echo "their gdi files that may or may not work correctly. TOSEC or TruRip are preferred."
19 | promptContinue
20 |
21 | echo "Instructions:"
22 | echo "Make sure to copy this script as well as the gdishrink.py, gditools.py, and iso9660.py"
23 | echo "files into your directory of Dreamcast game folders or it won't work. The folder must"
24 | echo "contain sub-folders that each have one game's .gdi file and associated image files."
25 | echo " "
26 | echo "For example:"
27 | echo " "
28 | echo "├── Crazy\ Taxi\ v1.004\ (1999)(Sega)(NTSC)(US)[!][10S\ 51035]"
29 | echo "│ ├── Crazy\ Taxi\ v1.004\ (1999)(Sega)(NTSC)(US)[!][10S\ 51035].gdi"
30 | echo "│ ├── track01.bin"
31 | echo "│ ├── track02.raw"
32 | echo "│ └── track03.bin"
33 | echo "├── Dead\ or\ Alive\ 2\ v1.100\ (2000)(Tecmo)(NTSC)(US)[!]"
34 | echo "│ ├── Dead\ or\ Alive\ 2\ v1.100\ (2000)(Tecmo)(NTSC)(US)[!].gdi"
35 | echo "│ ├── track01.bin"
36 | echo "│ ├── track02.raw"
37 | echo "│ └── track03.bin"
38 | echo "├── Rez\ v1.003\ (2001)(Sega)(PAL)(M6)[!]"
39 | echo "| ├── Rez\ v1.003\ (2001)(Sega)(PAL)(M6)[!].gdi"
40 | echo "| ├── track01.bin"
41 | echo "| ├── track02.raw"
42 | echo "| └── track03.bin"
43 | echo "├── gdishrink.py"
44 | echo "├── gditools.py"
45 | echo "├── iso9660.py"
46 | echo "└── shrink_all.sh"
47 | echo " "
48 | echo " "
49 | echo "Are you sure you want to shrink all .gdi images ${BOLD}${RED}IN PLACE${NORMAL} in directory: $(pwd)"
50 | echo "${BOLD}${RED}IMPORTANT:${NORMAL} Make sure you have backups of the original files, as this process is not reversible."
51 | promptContinue
52 |
53 | numthreads=2
54 | read -p "How many threads would you like to use (recommended 2 for HDDs and 10 for SSDs): " numthreads
55 | if [ -n "$numthreads" ] && [ "$numthreads" -eq "$numthreads" ] 2>/dev/null; then
56 | echo "${BOLD}Using $numthreads threads${NORMAL}"
57 | find . -depth -mindepth 2 -maxdepth 2 -name "*.gdi" -exec echo -ne '"{}"\n' \; | sort | xargs -P$numthreads -n1 bash -c 'echo "Shinking $0" && python ./gdishrink.py "$0" > /dev/null 2>&1 && printf "Finished $0\n"'
58 | echo "${BOLD}Done!${NORMAL}"
59 | else
60 | echo "${BOLD}${RED}You must enter a valid number of threads${NORMAL}"
61 | fi
62 |
63 |
--------------------------------------------------------------------------------
/gui/sortfile.pas:
--------------------------------------------------------------------------------
1 | {
2 | gditools.py GUI are licensed under the GNU General Public License (version 3),
3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt.
4 |
5 | SiZiOUS 2015 / www.sizious.com
6 | }
7 | unit SortFile;
8 |
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
15 |
16 | type
17 | { TfrmSortFile }
18 |
19 | TfrmSortFile = class(TForm)
20 | btnCancel: TButton;
21 | btnOK: TButton;
22 | btnOutputFileName: TButton;
23 | cbxVolumeLabel: TCheckBox;
24 | edtDataDir: TEdit;
25 | edtOutputFileName: TEdit;
26 | gbxDataDir: TGroupBox;
27 | gbxOutputDir: TGroupBox;
28 | svdSortFile: TSaveDialog;
29 | procedure btnOutputFileNameClick(Sender: TObject);
30 | procedure cbxVolumeLabelChange(Sender: TObject);
31 | procedure FormCreate(Sender: TObject);
32 | private
33 | function GetDataDirectory: string;
34 | function GetOutputFileName: TFileName;
35 | procedure SetDataDirectory(AValue: string);
36 | procedure SetOutputFileName(AValue: TFileName);
37 | { private declarations }
38 | public
39 | { public declarations }
40 | property DataDirectory: string
41 | read GetDataDirectory write SetDataDirectory;
42 | property OutputFileName: TFileName
43 | read GetOutputFileName write SetOutputFileName;
44 | end;
45 |
46 | var
47 | frmSortFile: TfrmSortFile;
48 |
49 | implementation
50 |
51 | uses
52 | Engine;
53 |
54 | {$R *.lfm}
55 |
56 | { TfrmSortFile }
57 |
58 | procedure TfrmSortFile.btnOutputFileNameClick(Sender: TObject);
59 | begin
60 | with svdSortFile do
61 | begin
62 | FileName := OutputFileName;
63 | if Execute then
64 | OutputFileName := FileName;
65 | end;
66 | end;
67 |
68 | procedure TfrmSortFile.cbxVolumeLabelChange(Sender: TObject);
69 | begin
70 | edtDataDir.Enabled := not cbxVolumeLabel.Checked;
71 | end;
72 |
73 | procedure TfrmSortFile.FormCreate(Sender: TObject);
74 | begin
75 | OutputFileName := IncludeTrailingPathDelimiter(GetCurrentDir) + SFILE_SORT;
76 | end;
77 |
78 | function TfrmSortFile.GetDataDirectory: string;
79 | begin
80 | Result := edtDataDir.Text;
81 | if cbxVolumeLabel.Checked then
82 | Result := SDIR_DATA_VOLUME_LABEL;
83 | end;
84 |
85 | function TfrmSortFile.GetOutputFileName: TFileName;
86 | begin
87 | Result := edtOutputFileName.Text;
88 | end;
89 |
90 | procedure TfrmSortFile.SetDataDirectory(AValue: string);
91 | begin
92 | edtDataDir.Text := AValue;
93 | end;
94 |
95 | procedure TfrmSortFile.SetOutputFileName(AValue: TFileName);
96 | begin
97 | edtOutputFileName.Text := AValue;
98 | end;
99 |
100 | end.
101 |
102 |
--------------------------------------------------------------------------------
/gui/utils.pas:
--------------------------------------------------------------------------------
1 | {
2 | gditools.py GUI are licensed under the GNU General Public License (version 3),
3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt.
4 |
5 | SiZiOUS 2015 / www.sizious.com
6 | }
7 | unit Utils;
8 |
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | Classes, SysUtils, ComCtrls;
15 |
16 | function GetNodePath(TreeNode: TTreeNode): string;
17 | procedure LoadConfig;
18 | procedure SaveConfig;
19 | function GetApplicationPath: TFileName;
20 |
21 | implementation
22 |
23 | uses
24 | Forms, IniFiles, Main;
25 |
26 | var
27 | sAppPath: TFileName;
28 |
29 | { Thanks to L.Saenz
30 | http://www.swissdelphicenter.ch/torry/showcode.php?id=859 }
31 | function GetNodePath(TreeNode: TTreeNode; var Path: string): string; overload;
32 | begin
33 | Result := '';
34 | if Assigned(TreeNode) then
35 | begin
36 | Path := TreeNode.Text + '/' + Path;
37 | if TreeNode.Level = 0 then
38 | Result := Path
39 | else
40 | Result := GetNodePath(TreeNode.Parent, Path);
41 | end;
42 | end;
43 |
44 | function GetNodePath(TreeNode: TTreeNode): string;
45 | var
46 | Path: string;
47 |
48 | begin
49 | Path := '';
50 | Result := StringReplace(GetNodePath(TreeNode, Path), '//', '/', []);
51 | end;
52 |
53 | // Get the application configuration file name.
54 | function GetConfigFile: TFileName;
55 | begin
56 | Result := GetApplicationPath +
57 | ChangeFileExt(ExtractFileName(Application.ExeName), '.conf');
58 | end;
59 |
60 | // Load the previous saved configuration.
61 | procedure LoadConfig;
62 | var
63 | IniFile: TIniFile;
64 |
65 | begin
66 | IniFile := TIniFile.Create(GetConfigFile);
67 | try
68 | GDReader.PythonExecutable := IniFile.ReadString('General', 'PythonExecutable', 'python');
69 | finally
70 | IniFile.Free;
71 | end;
72 | end;
73 |
74 | // Save the current configuration.
75 | procedure SaveConfig;
76 | var
77 | IniFile: TIniFile;
78 |
79 | begin
80 | IniFile := TIniFile.Create(GetConfigFile);
81 | try
82 | IniFile.WriteString('General', 'PythonExecutable', GDReader.PythonExecutable);
83 | finally
84 | IniFile.Free;
85 | end;
86 | end;
87 |
88 | // Get the application location
89 | function GetApplicationPath: TFileName;
90 | var
91 | Path: TFileName;
92 | {$IFDEF Darwin}
93 | i: Integer;
94 | {$ENDIF}
95 |
96 | begin
97 | if (sAppPath = '') then
98 | begin
99 | Path := Application.Location;
100 | {$IFDEF Darwin}
101 | i := Pos('.app', Path);
102 | if i > 0 then
103 | begin
104 | i := LastDelimiter('/', Copy(Path, 1, i));
105 | Path := Copy(Path, 1, i);
106 | end;
107 | {$ENDIF}
108 | sAppPath := IncludeTrailingPathDelimiter(Path);
109 | end;
110 | Result := sAppPath;
111 | end;
112 |
113 | initialization
114 | sAppPath := '';
115 |
116 | end.
117 |
118 |
--------------------------------------------------------------------------------
/gui/settings.lfm:
--------------------------------------------------------------------------------
1 | object frmSettings: TfrmSettings
2 | Left = 594
3 | Height = 182
4 | Top = 399
5 | Width = 320
6 | AutoSize = True
7 | BorderIcons = [biSystemMenu]
8 | BorderStyle = bsDialog
9 | Caption = 'Settings'
10 | ClientHeight = 182
11 | ClientWidth = 320
12 | Position = poScreenCenter
13 | LCLVersion = '1.2.6.0'
14 | object gbxPython: TGroupBox
15 | Left = 4
16 | Height = 136
17 | Top = 4
18 | Width = 312
19 | Align = alClient
20 | BorderSpacing.Around = 4
21 | Caption = ' Python Executable: '
22 | ClientHeight = 114
23 | ClientWidth = 304
24 | TabOrder = 0
25 | object lblPythonHint: TLabel
26 | Left = 12
27 | Height = 76
28 | Top = 4
29 | Width = 280
30 | Align = alClient
31 | AutoSize = False
32 | BorderSpacing.Left = 8
33 | BorderSpacing.Right = 8
34 | BorderSpacing.Around = 4
35 | Caption = 'Please select the location of your Python 2 executable.'#13#10#13#10'If your Python 2 executable is already in your PATH,'#13#10'inputting ''python'' in the box below should be fine.'
36 | ParentColor = False
37 | end
38 | object pnlPython: TPanel
39 | Left = 0
40 | Height = 30
41 | Top = 84
42 | Width = 304
43 | Align = alBottom
44 | BevelOuter = bvNone
45 | ClientHeight = 30
46 | ClientWidth = 304
47 | TabOrder = 0
48 | object btnPythonFileName: TButton
49 | Left = 260
50 | Height = 25
51 | Top = 0
52 | Width = 35
53 | Anchors = [akTop, akRight]
54 | Caption = '...'
55 | OnClick = btnPythonFileNameClick
56 | TabOrder = 0
57 | end
58 | object edtPythonFileName: TEdit
59 | Left = 10
60 | Height = 22
61 | Top = 2
62 | Width = 242
63 | Anchors = [akTop, akLeft, akRight]
64 | BorderSpacing.Bottom = 10
65 | TabOrder = 1
66 | Text = 'python'
67 | end
68 | end
69 | end
70 | object pnlButtons: TPanel
71 | Left = 0
72 | Height = 38
73 | Top = 144
74 | Width = 320
75 | Align = alBottom
76 | BevelOuter = bvNone
77 | ClientHeight = 38
78 | ClientWidth = 320
79 | TabOrder = 1
80 | object btnOK: TButton
81 | Left = 112
82 | Height = 25
83 | Top = 8
84 | Width = 99
85 | Caption = 'OK'
86 | ModalResult = 1
87 | TabOrder = 0
88 | end
89 | object btnCancel: TButton
90 | Left = 213
91 | Height = 25
92 | Top = 8
93 | Width = 99
94 | Caption = 'Cancel'
95 | ModalResult = 2
96 | TabOrder = 1
97 | end
98 | end
99 | object opdPythonFileName: TOpenDialog
100 | Title = 'Please select the Python 2 executable...'
101 | Filter = 'Python 2|python;python.exe|All Files|*.*'
102 | Options = [ofPathMustExist, ofFileMustExist, ofEnableSizing, ofViewDetail]
103 | left = 136
104 | top = 80
105 | end
106 | end
107 |
--------------------------------------------------------------------------------
/gui/extract.lfm:
--------------------------------------------------------------------------------
1 | object frmExtractAll: TfrmExtractAll
2 | Left = 462
3 | Height = 285
4 | Top = 270
5 | Width = 320
6 | BorderIcons = [biSystemMenu]
7 | BorderStyle = bsDialog
8 | Caption = 'Extract All'
9 | ClientHeight = 285
10 | ClientWidth = 320
11 | OnCreate = FormCreate
12 | Position = poScreenCenter
13 | LCLVersion = '1.2.6.0'
14 | object gbxDataDir: TGroupBox
15 | Left = 8
16 | Height = 80
17 | Top = 8
18 | Width = 304
19 | Caption = ' Data Directory: '
20 | ClientHeight = 58
21 | ClientWidth = 296
22 | TabOrder = 0
23 | object edtDataDir: TEdit
24 | Left = 8
25 | Height = 22
26 | Top = 8
27 | Width = 280
28 | TabOrder = 0
29 | Text = 'data'
30 | end
31 | object cbxVolumeLabel: TCheckBox
32 | Left = 8
33 | Height = 18
34 | Top = 38
35 | Width = 133
36 | Caption = 'Use Volume Label'
37 | OnChange = cbxVolumeLabelChange
38 | TabOrder = 1
39 | end
40 | end
41 | object gbxOutputDir: TGroupBox
42 | Left = 8
43 | Height = 56
44 | Top = 96
45 | Width = 304
46 | Caption = ' Output Directory: '
47 | ClientHeight = 34
48 | ClientWidth = 296
49 | TabOrder = 1
50 | object edtOutputDir: TEdit
51 | Left = 8
52 | Height = 22
53 | Top = 8
54 | Width = 240
55 | TabOrder = 0
56 | end
57 | object btnOutputDir: TButton
58 | Left = 256
59 | Height = 25
60 | Top = 6
61 | Width = 35
62 | Caption = '...'
63 | OnClick = btnOutputDirClick
64 | TabOrder = 1
65 | end
66 | end
67 | object ckgOptions: TCheckGroup
68 | Left = 7
69 | Height = 80
70 | Top = 160
71 | Width = 305
72 | AutoFill = True
73 | Caption = ' Options: '
74 | ChildSizing.LeftRightSpacing = 6
75 | ChildSizing.TopBottomSpacing = 6
76 | ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
77 | ChildSizing.EnlargeVertical = crsHomogenousChildResize
78 | ChildSizing.ShrinkHorizontal = crsScaleChilds
79 | ChildSizing.ShrinkVertical = crsScaleChilds
80 | ChildSizing.Layout = cclLeftToRightThenTopToBottom
81 | ChildSizing.ControlsPerLine = 1
82 | ClientHeight = 58
83 | ClientWidth = 297
84 | Items.Strings = (
85 | 'Extract Bootsector (IP.BIN)'
86 | 'Generate Sort File (sorttxt.txt)'
87 | )
88 | TabOrder = 2
89 | Data = {
90 | 020000000202
91 | }
92 | end
93 | object btnOK: TButton
94 | Left = 112
95 | Height = 25
96 | Top = 248
97 | Width = 99
98 | Caption = 'OK'
99 | ModalResult = 1
100 | TabOrder = 3
101 | end
102 | object btnCancel: TButton
103 | Left = 213
104 | Height = 25
105 | Top = 248
106 | Width = 99
107 | Caption = 'Cancel'
108 | ModalResult = 2
109 | TabOrder = 4
110 | end
111 | object bfdExtractAll: TSelectDirectoryDialog
112 | Title = 'Select the output directory:'
113 | left = 208
114 | top = 112
115 | end
116 | end
117 |
--------------------------------------------------------------------------------
/gui/extract.pas:
--------------------------------------------------------------------------------
1 | {
2 | gditools.py GUI are licensed under the GNU General Public License (version 3),
3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt.
4 |
5 | SiZiOUS 2015 / www.sizious.com
6 | }
7 | unit Extract;
8 |
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
15 | ExtCtrls;
16 |
17 | type
18 | { TfrmExtractAll }
19 |
20 | TfrmExtractAll = class(TForm)
21 | btnOutputDir: TButton;
22 | btnOK: TButton;
23 | btnCancel: TButton;
24 | cbxVolumeLabel: TCheckBox;
25 | ckgOptions: TCheckGroup;
26 | edtOutputDir: TEdit;
27 | edtDataDir: TEdit;
28 | gbxDataDir: TGroupBox;
29 | gbxOutputDir: TGroupBox;
30 | bfdExtractAll: TSelectDirectoryDialog;
31 | procedure btnOutputDirClick(Sender: TObject);
32 | procedure cbxVolumeLabelChange(Sender: TObject);
33 | procedure FormCreate(Sender: TObject);
34 | private
35 | { private declarations }
36 | function GetDataDirectory: string;
37 | function GetExtractBootstrap: Boolean;
38 | function GetGenerateSortFile: Boolean;
39 | function GetOutputDirectory: TFileName;
40 | procedure SetDataDirectory(AValue: string);
41 | procedure SetExtractBootstrap(AValue: Boolean);
42 | procedure SetGenerateSortFile(AValue: Boolean);
43 | procedure SetOutputDirectory(AValue: TFileName);
44 | public
45 | { public declarations }
46 | property DataDirectory: string read GetDataDirectory write SetDataDirectory;
47 | property OutputDirectory: TFileName
48 | read GetOutputDirectory write SetOutputDirectory;
49 | property ExtractBootstrap: Boolean read GetExtractBootstrap
50 | write SetExtractBootstrap;
51 | property GenerateSortFile: Boolean read GetGenerateSortFile
52 | write SetGenerateSortFile;
53 | end;
54 |
55 | var
56 | frmExtractAll: TfrmExtractAll;
57 |
58 | implementation
59 |
60 | uses
61 | Engine;
62 |
63 | {$R *.lfm}
64 |
65 | { TfrmExtractAll }
66 |
67 | procedure TfrmExtractAll.btnOutputDirClick(Sender: TObject);
68 | begin
69 | with bfdExtractAll do
70 | begin
71 | FileName := OutputDirectory;
72 | if Execute then
73 | OutputDirectory := FileName;
74 | end;
75 | end;
76 |
77 | procedure TfrmExtractAll.cbxVolumeLabelChange(Sender: TObject);
78 | begin
79 | edtDataDir.Enabled := not cbxVolumeLabel.Checked;
80 | end;
81 |
82 | procedure TfrmExtractAll.FormCreate(Sender: TObject);
83 | begin
84 | ExtractBootstrap := True;
85 | GenerateSortFile := True;
86 | OutputDirectory := GetCurrentDir;
87 | end;
88 |
89 | function TfrmExtractAll.GetDataDirectory: string;
90 | begin
91 | Result := edtDataDir.Text;
92 | if cbxVolumeLabel.Checked then
93 | Result := SDIR_DATA_VOLUME_LABEL;
94 | end;
95 |
96 | function TfrmExtractAll.GetExtractBootstrap: Boolean;
97 | begin
98 | Result := ckgOptions.Checked[0];
99 | end;
100 |
101 | function TfrmExtractAll.GetGenerateSortFile: Boolean;
102 | begin
103 | Result := ckgOptions.Checked[1];
104 | end;
105 |
106 | function TfrmExtractAll.GetOutputDirectory: TFileName;
107 | begin
108 | Result := IncludeTrailingPathDelimiter(edtOutputDir.Text);
109 | end;
110 |
111 | procedure TfrmExtractAll.SetDataDirectory(AValue: string);
112 | begin
113 | edtDataDir.Text := AValue;
114 | end;
115 |
116 | procedure TfrmExtractAll.SetExtractBootstrap(AValue: Boolean);
117 | begin
118 | ckgOptions.Checked[0] := AValue;
119 | end;
120 |
121 | procedure TfrmExtractAll.SetGenerateSortFile(AValue: Boolean);
122 | begin
123 | ckgOptions.Checked[1] := AValue;
124 | end;
125 |
126 | procedure TfrmExtractAll.SetOutputDirectory(AValue: TFileName);
127 | begin
128 | edtOutputDir.Text := IncludeTrailingPathDelimiter(AValue);
129 | end;
130 |
131 | end.
132 |
133 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | ___ __ __
2 | ____ _____/ (_) /_____ ____ / /____
3 | / __ `/ __ / / __/ __ \/ __ \/ / ___/
4 | / /_/ / /_/ / / /_/ /_/ / /_/ / (__ )
5 | \__, /\__,_/_/\__/\____/\____/_/____/
6 | /____/
7 |
8 | gditools, a Python library to extract files, sorttxt.txt and
9 | bootsector (IP.BIN) from SEGA Gigabyte Disc (GD-ROM) dumps in
10 | gdi format.
11 |
12 | The goals is to make it efficient, readable and multi-platform.
13 |
14 | As of December 2014 it's tested working on Linux and Win7 under
15 | python 2.7 but it was only tested on x86_64 processors. The
16 | performances are typically limited by the usage of a platter HDD.
17 | When using a SSD, the CPU can be the bottleneck if it's an old one
18 | or if it's used in power-saving mode. 3-tracks gdi can be extracted
19 | in less than 2 seconds with the right configuration (~1GiB of data).
20 |
21 | To get the most recent version, browse code on:
22 | https://sourceforge.net/projects/dcisotools/
23 |
24 | or using git:
25 | git clone git://git.code.sf.net/p/dcisotools/code dcisotools-code
26 |
27 | Releases of stable code might be sporadically packaged into a .zip
28 | archive for convenience, and made available on the SourceForge page
29 | download section.
30 |
31 | bin2iso.py and gdifix.py (creating a single .iso from a gdi dump)
32 | are provided in the 'addons' folder. They can be used as is or be
33 | used to see how to incorporate gditools.py in another project.
34 |
35 | See the Legal Stuff section at the end of this readme for the infos
36 | on licensing and using this project in another one.
37 |
38 | Enjoy!
39 |
40 | FamilyGuy 2015
41 |
42 | Thanks to SiZiOUS for testing the code, providing support and for the GUI.
43 |
44 | ___ _ __
45 | / _ \___ ___ ___ __(_)______ __ _ ___ ___ / /____
46 | ___/ , _/ -_) _ `/ // / / __/ -_) ' \/ -_) _ \/ __(_-<________________________
47 | /_/|_|\__/\_, /\_,_/_/_/ \__/_/_/_/\__/_//_/\__/___/
48 | /_/
49 |
50 | - Python 2.7.x, Python 3 won't work.
51 | - On Windows you have to add the python folder to your path manually (or
52 | choose the option when installing).
53 |
54 | __ __
55 | / / / /__ ___ ____ ____
56 | ___/ /_/ (_- _ `/ _ `/ -_)___________________________________________________
57 | \____/___/\_,_/\_, /\__/
58 | /___/
59 | python gditools.py -i input_gdi [options]
60 |
61 | -h, --help Display this help
62 | -l, --list List all files in the filesystem and exit
63 | -o [outdir] Output directory. Default: gdi folder
64 | -s [filename] Create a sorttxt file with custom name
65 | (It uses *data-folder* as prefix)
66 | -b [ipname] Dump the ip.bin with custom name
67 | -e [filename] Dump a single file from the filesystem
68 | --extract-all Dump all the files in the *data-folder*
69 | --data-folder [name] *data-folder* subfolder. Default: data
70 | (__volume_label__ --> Use ISO9660 volume label)
71 | --sort-spacer [num] Sorttxt entries are sperated by num
72 | --silent Minimal verbosity mode
73 | [no option] Display gdi infos if not silent
74 |
75 | __ __ ____ __
76 | / / / /__ ___ ____ ____ / __/_ _____ ___ _ ___ / /__ ___
77 | ___/ /_/ (_- _ `/ _ `/ -_)_/ _/ \ \ / _ `/ ' \/ _ \/ / -_|_-<_______________
78 | \____/___/\_,_/\_, /\__/ /___//_\_\\_,_/_/_/_/ .__/_/\__/___/
79 | /___/ /_/
80 |
81 | 0- Listing all files in the gdi:
82 | gditools.py -i /folder/disc.gdi --list
83 |
84 | 1- Displaying gdi infos:
85 | gditools.py -i /folder/disc.gdi
86 |
87 | 2- Dumping bootsector/initial program/ip.bin:
88 | gditools.py -i /folder/disc.gdi -b ip.bin
89 |
90 | 3- Generating a sorttxt file:
91 | gditools.py -i /folder/disc.gdi -s sorttxt.txt
92 |
93 | 4- Generating a sorttxt file with a different "data" folder (see example 9):
94 | gditools.py -i /folder/disc.gdi -s sorttxt.txt --data-folder MyDump
95 |
96 | 5- Extracting a single file:
97 | gditools.py -i /folder/disc.gdi -e 1st_read.bin
98 |
99 | 6- Specifying a different output folder:
100 | (default one is the gdi folder)
101 | gditools.py -i /folder/disc.gdi -e 1st_read.bin -o /OtherFolder
102 |
103 | 7- Extracting all the files from the gdi:
104 | gditools.py -i /folder/disc.gdi --extract-all
105 |
106 | 8- Specifying a different subfolder name:
107 | (default one is "data")
108 | gditools.py -i /folder/disc.gdi --extract-all --data-folder MyFolder
109 |
110 | 9- Using the iso9660 filesystem volume label as the subfolder name:
111 | gditools.py -i /folder/disc.gdi --extract-all --data-folder __volume_label__
112 |
113 | 10- Doing most of the above at once:
114 | gditools.py -i /folder/disc.gdi -s sorttxt.txt -b ip.bin
115 | -o /OtherFolder --data-folder __volume_label__ --extract-all
116 |
117 | __ __ _ __ __ _______ ______
118 | / / / /__ (_)__ ___ _ / /_/ / ___ / ___/ / / / _/
119 | ___/ /_/ (_- / _ \/ _ `/ / __/ _ \/ -_) / (_ / /_/ // /______________________
120 | \____/___/_/_//_/\_, / \__/_//_/\__/ \___/\____/___/
121 | /___/
122 |
123 | For your convenience you can use the GUI provided for your platform.
124 |
125 | To use it it's really simple:
126 | 1. Download the package for your platform (Windows, Linux 64-bit or
127 | Mac OS X).
128 | 2. Extract the GUI binary at the same location of your gditools.py script.
129 | 3. Just double-click on the 'gditools.exe' or 'gditools' binary to run it.
130 |
131 | The usage is pretty much the same as the excellent GD-ROM Explorer made by
132 | Japanese Cake which is only available on Windows.
133 |
134 | If you want to modify/compile the GUI for your platform, please use the
135 | Lazarus IDE: http://www.lazarus.freepascal.org/
136 |
137 | Please note this procedure is also included in the gditools-gui-* packages
138 | into the 'setupgui.txt' file.
139 | __ __ ______ ______
140 | / / ___ ___ ____ _/ / / __/ /___ __/ _/ _/
141 | ___ / /__/ -_) _ `/ _ `/ / _\ \/ __/ // / _/ _/________________________________
142 | /____/\__/\_, /\_,_/_/ /___/\__/\_,_/_//_/
143 | /___/
144 |
145 | gditools.py, provided addons and the GUI are licensed under the GNU
146 | General Public License (version 3), a copy of which is provided
147 | in the licences folder: GNU_GPL_v3.txt
148 |
149 | Original iso9660.py by Barney Gale : github.com/barneygale/iso9660
150 | iso9660.py is licensed under a BSD license, a copy of which is
151 | provided in the licences folder: iso9660_license.txt
152 |
153 | _____________________________________________________________________/ eof /___
154 |
--------------------------------------------------------------------------------
/gui/version.pas:
--------------------------------------------------------------------------------
1 | Unit Version;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | Interface
6 |
7 | (*
8 | Building on the excellent vinfo.pas supplied by Paul Ishenin and available elsewhere on these Lazarus
9 | Forums
10 | - I hid the TVersionInfo class from the end user to simplify their (mine) number of required Uses...
11 | - Added defensive code to TVersionInfo if no build info is compiled into the exe
12 | - Deduced GetResourceStrings - works under Linux 64/GTK2 with Lazarus 0.9.30, but fails under
13 | Win XP 32bit/Lazarus 0.9.29 - suspecting my install as the lazresexplorer example also fails
14 | for me under Lazarus 0.9.29, but works with Lazarus 0.9.30
15 |
16 | Trawled through IDE source code, FPC source code and Lazarus supplied example program lasresexplorer
17 | to find the other defines and lookups...
18 |
19 | End user only needs to use VersionSupport - no other units necessary for their project.
20 |
21 | Jedi CodeFormatter seems to fail on the {$I %VARIABLE%} references, so sticking them all in here
22 | means end user code can be neatly formatted using Jedi CodeFormatter
23 |
24 | Other interesting includes I picked up in my travels are...
25 | // {$I %HOME%} = User Home Directory
26 | // {$I %FILE%} = Current pas file
27 | // {$I %LINE%} = current line number
28 |
29 | Mike Thompson - mike.cornflake@gmail.com
30 | July 24 2011
31 | *)
32 |
33 | Uses
34 | Classes, SysUtils;
35 |
36 | Function GetFileVersion: String;
37 | Function GetProductVersion: String;
38 | Function GetCompiledDate: String;
39 | Function GetCompilerInfo: String;
40 | Function GetTargetInfo: String;
41 | Function GetOS: String;
42 | Function GetResourceStrings(oStringList : TStringList) : Boolean;
43 | Function GetLCLVersion: String;
44 | function GetWidgetSet: string;
45 |
46 | Const
47 | WIDGETSET_GTK = 'GTK widget set';
48 | WIDGETSET_GTK2 = 'GTK 2 widget set';
49 | WIDGETSET_WIN = 'Win32/Win64 widget set';
50 | WIDGETSET_WINCE = 'WinCE widget set';
51 | WIDGETSET_CARBON = 'Carbon widget set';
52 | WIDGETSET_QT = 'QT widget set';
53 | WIDGETSET_fpGUI = 'fpGUI widget set';
54 | WIDGETSET_OTHER = 'Other gui';
55 |
56 | Implementation
57 |
58 | Uses
59 | resource, versiontypes, versionresource, LCLVersion, InterfaceBase;
60 |
61 | Type
62 | TVersionInfo = Class
63 | private
64 | FBuildInfoAvailable: Boolean;
65 | FVersResource: TVersionResource;
66 | Function GetFixedInfo: TVersionFixedInfo;
67 | Function GetStringFileInfo: TVersionStringFileInfo;
68 | Function GetVarFileInfo: TVersionVarFileInfo;
69 | public
70 | Constructor Create;
71 | Destructor Destroy; override;
72 |
73 | Procedure Load(Instance: THandle);
74 |
75 | Property BuildInfoAvailable: Boolean Read FBuildInfoAvailable;
76 |
77 | Property FixedInfo: TVersionFixedInfo Read GetFixedInfo;
78 | Property StringFileInfo: TVersionStringFileInfo Read GetStringFileInfo;
79 | Property VarFileInfo: TVersionVarFileInfo Read GetVarFileInfo;
80 | End;
81 |
82 | function GetWidgetSet: string;
83 | begin
84 | case WidgetSet.LCLPlatform of
85 | lpGtk: Result := WIDGETSET_GTK;
86 | lpGtk2: Result := WIDGETSET_GTK2;
87 | lpWin32: Result := WIDGETSET_WIN;
88 | lpWinCE: Result := WIDGETSET_WINCE;
89 | lpCarbon:Result := WIDGETSET_CARBON;
90 | lpQT: Result := WIDGETSET_QT;
91 | lpfpGUI: Result := WIDGETSET_fpGUI;
92 | else
93 | Result:=WIDGETSET_OTHER;
94 | end;
95 | end;
96 |
97 | Function GetCompilerInfo: String;
98 | begin
99 | Result := 'FPC '+{$I %FPCVERSION%};
100 | end;
101 |
102 | Function GetTargetInfo: String;
103 | begin
104 | Result := {$I %FPCTARGETCPU%}+' - '+{$I %FPCTARGETOS%};
105 | end;
106 |
107 | Function GetOS: String;
108 | Begin
109 | Result := {$I %FPCTARGETOS%};
110 | End;
111 |
112 | Function GetLCLVersion: String;
113 | begin
114 | Result := 'LCL '+lcl_version;
115 | end;
116 |
117 | Function GetCompiledDate: String;
118 | Var
119 | sDate, sTime: String;
120 | Begin
121 | sDate := {$I %DATE%};
122 | sTime := {$I %TIME%};
123 |
124 | Result := sDate + ' at ' + sTime;
125 | End;
126 |
127 | { Routines to expose TVersionInfo data }
128 |
129 | Var
130 | FInfo: TVersionInfo;
131 |
132 | Procedure CreateInfo;
133 | Begin
134 | If Not Assigned(FInfo) Then
135 | Begin
136 | FInfo := TVersionInfo.Create;
137 | FInfo.Load(HINSTANCE);
138 | End;
139 | End;
140 |
141 | Function GetResourceStrings(oStringList: TStringList): Boolean;
142 | Var
143 | i, j : Integer;
144 | oTable : TVersionStringTable;
145 | begin
146 | CreateInfo;
147 |
148 | oStringList.Clear;
149 | Result := False;
150 |
151 | If FInfo.BuildInfoAvailable Then
152 | Begin
153 | Result := True;
154 | For i := 0 To FInfo.StringFileInfo.Count-1 Do
155 | Begin
156 | oTable := FInfo.StringFileInfo.Items[i];
157 |
158 | For j := 0 To oTable.Count-1 Do
159 | If Trim(oTable.ValuesByIndex[j])<>'' Then
160 | oStringList.Values[oTable.Keys[j]] := oTable.ValuesByIndex[j];
161 | end;
162 | end;
163 | end;
164 |
165 | Function ProductVersionToString(PV: TFileProductVersion): String;
166 | Begin
167 | Result := Format('%d.%d.%d.%d', [PV[0], PV[1], PV[2], PV[3]]);
168 | End;
169 |
170 | Function GetProductVersion: String;
171 | Begin
172 | CreateInfo;
173 |
174 | If FInfo.BuildInfoAvailable Then
175 | Result := ProductVersionToString(FInfo.FixedInfo.ProductVersion)
176 | Else
177 | Result := 'No build information available';
178 | End;
179 |
180 | Function GetFileVersion: String;
181 | Begin
182 | CreateInfo;
183 |
184 | If FInfo.BuildInfoAvailable Then
185 | Result := ProductVersionToString(FInfo.FixedInfo.FileVersion)
186 | Else
187 | Result := 'No build information available';
188 | End;
189 |
190 | { TVersionInfo }
191 |
192 | Function TVersionInfo.GetFixedInfo: TVersionFixedInfo;
193 | Begin
194 | Result := FVersResource.FixedInfo;
195 | End;
196 |
197 | Function TVersionInfo.GetStringFileInfo: TVersionStringFileInfo;
198 | Begin
199 | Result := FVersResource.StringFileInfo;
200 | End;
201 |
202 | Function TVersionInfo.GetVarFileInfo: TVersionVarFileInfo;
203 | Begin
204 | Result := FVersResource.VarFileInfo;
205 | End;
206 |
207 | Constructor TVersionInfo.Create;
208 | Begin
209 | Inherited Create;
210 |
211 | FVersResource := TVersionResource.Create;
212 | FBuildInfoAvailable := False;
213 | End;
214 |
215 | Destructor TVersionInfo.Destroy;
216 | Begin
217 | FVersResource.Free;
218 |
219 | Inherited Destroy;
220 | End;
221 |
222 | Procedure TVersionInfo.Load(Instance: THandle);
223 | Var
224 | Stream: TResourceStream;
225 | ResID: Integer;
226 | Res: TFPResourceHandle;
227 |
228 | Begin
229 | FBuildInfoAvailable := False;
230 | ResID := 1;
231 |
232 | // Defensive code to prevent failure if no resource available...
233 | Res := FindResource(Instance, PChar(PtrInt(ResID)), PChar(RT_VERSION));
234 | If Res = 0 Then
235 | Exit;
236 |
237 | Stream := TResourceStream.CreateFromID(Instance, ResID, PChar(RT_VERSION));
238 | Try
239 | FVersResource.SetCustomRawDataStream(Stream);
240 |
241 | // access some property to load from the stream
242 | FVersResource.FixedInfo;
243 |
244 | // clear the stream
245 | FVersResource.SetCustomRawDataStream(nil);
246 |
247 | FBuildInfoAvailable := True;
248 | Finally
249 | Stream.Free;
250 | End;
251 | End;
252 |
253 | Initialization
254 | FInfo := nil;
255 |
256 | Finalization
257 | If Assigned(FInfo) Then
258 | FInfo.Free;
259 |
260 | End.
261 |
--------------------------------------------------------------------------------
/gui/gditools.lpi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
--------------------------------------------------------------------------------
/iso9660.py:
--------------------------------------------------------------------------------
1 | import urllib
2 | import struct
3 |
4 | try:
5 | from cStringIO import StringIO
6 | except ImportError:
7 | from StringIO import StringIO
8 |
9 | class ISO9660IOError(IOError):
10 | def __init__(self, path):
11 | self.path = path
12 |
13 | def __str__(self):
14 | return "Path not found: %s" % self.path
15 |
16 | class ISO9660(object):
17 | def __init__(self, url):
18 | self._buff = None #input buffer
19 | self._root = None #root node
20 | self._pvd = {} #primary volume descriptor
21 | self._paths = [] #path table
22 |
23 | self._url = url
24 | self._get_sector = self._get_sector_url if url.startswith('http') else self._get_sector_file
25 |
26 | ### Volume Descriptors
27 | sector = 0x10
28 | while True:
29 | self._get_sector(sector, 2048)
30 | sector += 1
31 | ty = self._unpack('B')
32 |
33 | if ty == 1:
34 | self._unpack_pvd()
35 | elif ty == 255:
36 | break
37 | else:
38 | continue
39 |
40 | ### Path table
41 | l0 = self._pvd['path_table_size']
42 | self._get_sector(self._pvd['path_table_l_loc'], l0)
43 |
44 | while l0 > 0:
45 | p = {}
46 | l1 = self._unpack('B')
47 | l2 = self._unpack('B')
48 | p['ex_loc'] = self._unpack('i')
180 | self._pvd['path_table_opt_m_loc'] = self._unpack('>i')
181 | _, self._root = self._unpack_record() #root directory record
182 | self._pvd['volume_set_identifer'] = self._unpack_string(128)
183 | self._pvd['publisher_identifier'] = self._unpack_string(128)
184 | self._pvd['data_preparer_identifier'] = self._unpack_string(128)
185 | self._pvd['application_identifier'] = self._unpack_string(128)
186 | self._pvd['copyright_file_identifier'] = self._unpack_string(38)
187 | self._pvd['abstract_file_identifier'] = self._unpack_string(36)
188 | self._pvd['bibliographic_file_identifier'] = self._unpack_string(37)
189 | self._pvd['volume_datetime_created'] = self._unpack_vd_datetime()
190 | self._pvd['volume_datetime_modified'] = self._unpack_vd_datetime()
191 | self._pvd['volume_datetime_expires'] = self._unpack_vd_datetime()
192 | self._pvd['volume_datetime_effective'] = self._unpack_vd_datetime()
193 | self._pvd['file_structure_version'] = self._unpack('B')
194 |
195 | ##
196 | ## Unpack a directory record (a listing of a file or folder)
197 | ##
198 |
199 | def _unpack_record(self, read=0):
200 | l0 = self._unpack('B')
201 |
202 | if l0 == 0:
203 | return read+1, None
204 |
205 | l1 = self._unpack('B')
206 |
207 | d = dict()
208 | d['ex_loc'] = self._unpack_both('I')
209 | d['ex_len'] = self._unpack_both('I')
210 | d['datetime'] = self._unpack_dir_datetime()
211 | d['flags'] = self._unpack('B')
212 | d['interleave_unit_size'] = self._unpack('B')
213 | d['interleave_gap_size'] = self._unpack('B')
214 | d['volume_sequence'] = self._unpack_both('h')
215 |
216 | l2 = self._unpack('B')
217 | d['name'] = self._unpack_string(l2).split(';')[0]
218 | if d['name'] == '\x00':
219 | d['name'] = ''
220 |
221 | if l2 % 2 == 0:
222 | self._unpack('B')
223 |
224 | t = 34 + l2 - (l2 % 2)
225 |
226 | e = l0-t
227 | if e>0:
228 | extra = self._unpack_raw(e)
229 |
230 | return read+l0, d
231 |
232 | #Assuming d is a directory record, this generator yields its children
233 | def _unpack_dir_children(self, d):
234 | sector = d['ex_loc']
235 | read = 0
236 | self._get_sector(sector, 2048)
237 |
238 | read, r_self = self._unpack_record(read)
239 | read, r_parent = self._unpack_record(read)
240 |
241 | while read < r_self['ex_len']: #Iterate over files in the directory
242 | if read % 2048 == 0:
243 | sector += 1
244 | self._get_sector(sector, 2048)
245 | read, data = self._unpack_record(read)
246 |
247 | if data == None: #end of directory listing
248 | to_read = 2048 - (read % 2048)
249 | self._unpack_raw(to_read)
250 | read += to_read
251 | else:
252 | yield data
253 |
254 | #Search for one child amongst the children
255 | def _search_dir_children(self, d, term):
256 | for e in self._unpack_dir_children(d):
257 | if e['name'] == term:
258 | return e
259 |
260 | raise ISO9660IOError(term)
261 | ##
262 | ## Datatypes
263 | ##
264 |
265 | def _unpack_raw(self, l):
266 | return self._buff.read(l)
267 |
268 | #both-endian
269 | def _unpack_both(self, st):
270 | a = self._unpack('<'+st)
271 | b = self._unpack('>'+st)
272 | assert a == b
273 | return a
274 |
275 | def _unpack_string(self, l):
276 | return self._buff.read(l).rstrip(' ')
277 |
278 | def _unpack(self, st):
279 | if st[0] not in ('<','>'):
280 | st = '<' + st
281 | d = struct.unpack(st, self._buff.read(struct.calcsize(st)))
282 | if len(st) == 2:
283 | return d[0]
284 | else:
285 | return d
286 |
287 | def _unpack_vd_datetime(self):
288 | return self._unpack_raw(17) #TODO
289 |
290 | def _unpack_dir_datetime(self):
291 | return self._unpack_raw(7) #TODO
292 |
293 |
294 | if __name__ == '__main__':
295 | import sys
296 | if len(sys.argv) < 2:
297 | print "usage: python iso9660.py isourl [path]"
298 | else:
299 | iso_path = sys.argv[1]
300 | ret_path = sys.argv[2] if len(sys.argv) > 2 else None
301 | cd = ISO9660(iso_path)
302 | if ret_path:
303 | sys.stdout.write(cd.get_file(ret_path))
304 | else:
305 | for path in cd.tree():
306 | print path
--------------------------------------------------------------------------------
/gui/main.pas:
--------------------------------------------------------------------------------
1 | {
2 | gditools.py GUI are licensed under the GNU General Public License (version 3),
3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt.
4 |
5 | SiZiOUS 2015 / www.sizious.com
6 | }
7 | unit Main;
8 |
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
15 | ComCtrls, Menus, ExtCtrls, Engine, Types, LCLIntf;
16 |
17 | type
18 | { TfrmMain }
19 |
20 | TfrmMain = class(TForm)
21 | btnOpen: TButton;
22 | edtFileName: TEdit;
23 | gbxDiscImage: TGroupBox;
24 | gbxContents: TGroupBox;
25 | ilDirectories: TImageList;
26 | ilFiles: TImageList;
27 | lvwFiles: TListView;
28 | miSep5: TMenuItem;
29 | miOpenItem: TMenuItem;
30 | miGenerateSortFile: TMenuItem;
31 | miExtractBootstrap: TMenuItem;
32 | miSep4: TMenuItem;
33 | miExtract2: TMenuItem;
34 | miSettings: TMenuItem;
35 | miSep3: TMenuItem;
36 | miExtractAll: TMenuItem;
37 | miTools: TMenuItem;
38 | miExtract: TMenuItem;
39 | miFile: TMenuItem;
40 | miSep2: TMenuItem;
41 | miHelp: TMenuItem;
42 | miOpenFile: TMenuItem;
43 | miCloseFile: TMenuItem;
44 | miSep1: TMenuItem;
45 | miQuit: TMenuItem;
46 | miProjectPage: TMenuItem;
47 | miAbout: TMenuItem;
48 | miGetAssistance: TMenuItem;
49 | mmMain: TMainMenu;
50 | opdGDI: TOpenDialog;
51 | pmFiles: TPopupMenu;
52 | sbrMain: TStatusBar;
53 | svdExtract: TSaveDialog;
54 | Splitter1: TSplitter;
55 | svdExtractBootstrap: TSaveDialog;
56 | tmrResetStatusBar: TTimer;
57 | tvwDirectories: TTreeView;
58 | procedure btnOpenClick(Sender: TObject);
59 | procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
60 | procedure FormCreate(Sender: TObject);
61 | procedure FormShow(Sender: TObject);
62 | procedure lvwFilesContextPopup(Sender: TObject; MousePos: TPoint;
63 | var Handled: Boolean);
64 | procedure lvwFilesDblClick(Sender: TObject);
65 | procedure lvwFilesSelectItem(Sender: TObject; Item: TListItem;
66 | Selected: Boolean);
67 | procedure miAboutClick(Sender: TObject);
68 | procedure miCloseFileClick(Sender: TObject);
69 | procedure miGetAssistanceClick(Sender: TObject);
70 | procedure miProjectPageClick(Sender: TObject);
71 | procedure miQuitClick(Sender: TObject);
72 | procedure miExtractAllClick(Sender: TObject);
73 | procedure miExtractBootstrapClick(Sender: TObject);
74 | procedure miExtractClick(Sender: TObject);
75 | procedure miGenerateSortFileClick(Sender: TObject);
76 | procedure miOpenItemClick(Sender: TObject);
77 | procedure miSettingsClick(Sender: TObject);
78 | procedure tmrResetStatusBarTimer(Sender: TObject);
79 | procedure tvwDirectoriesClick(Sender: TObject);
80 | private
81 | { private declarations }
82 | fSelectedFile: string;
83 | procedure ChangeButtonsState(State: Boolean);
84 | function GetSelectedNodePath: string;
85 | function GetStatusText: string;
86 | procedure SetStatusText(AValue: string);
87 | procedure ResetStatusBar(Success: Boolean);
88 | public
89 | { public declarations }
90 | property SelectedFile: string read fSelectedFile;
91 | property StatusText: string read GetStatusText write SetStatusText;
92 | end;
93 |
94 | var
95 | frmMain: TfrmMain;
96 | GDReader: TGDReader;
97 |
98 | implementation
99 |
100 | {$R *.lfm}
101 |
102 | uses
103 | {$IFDEF Darwin}
104 | LCLType,
105 | {$ENDIF}
106 | Utils,
107 | Extract,
108 | SortFile,
109 | Settings,
110 | About;
111 |
112 | { TfrmMain }
113 |
114 | procedure TfrmMain.btnOpenClick(Sender: TObject);
115 | var
116 | Success: Boolean;
117 |
118 | begin
119 | with opdGDI do
120 | if Execute then
121 | begin
122 | if FileExists(FileName) then
123 | begin
124 | StatusText := 'Opening the specified file... Please wait.';
125 |
126 | // Load the file then populate the TreeView
127 | GDReader.LoadFromFile(FileName);
128 | GDReader.FillTreeView(tvwDirectories);
129 |
130 | // Check if the file was successfully opened or not
131 | Success := tvwDirectories.Items.Count > 0;
132 |
133 | // Reset the status bar
134 | ResetStatusBar(Success);
135 |
136 | // If we can open the root folder, do it
137 | // This means that the opened file is valid.
138 | if Success then
139 | begin
140 | edtFileName.Text := FileName;
141 | ChangeButtonsState(True);
142 | tvwDirectories.Items[0].Selected := True;
143 | tvwDirectoriesClick(Self);
144 | end
145 | else
146 | begin
147 | MessageDlg('The specified file seems to be invalid.', mtWarning, [mbOK], 0);
148 | miCloseFileClick(Self);
149 | end;
150 | end
151 | else
152 | MessageDlg('The specified GDI image doesn''t exist.', mtWarning, [mbOK], 0);
153 | end;
154 | end;
155 |
156 | procedure TfrmMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
157 | begin
158 | SaveConfig;
159 | end;
160 |
161 | procedure TfrmMain.FormCreate(Sender: TObject);
162 | begin
163 | Caption := Application.Title;
164 | ChangeButtonsState(False);
165 | end;
166 |
167 | procedure TfrmMain.FormShow(Sender: TObject);
168 | begin
169 | LoadConfig;
170 | end;
171 |
172 | procedure TfrmMain.lvwFilesContextPopup(Sender: TObject; MousePos: TPoint;
173 | var Handled: Boolean);
174 | begin
175 | // Show the context menu only on items
176 | if not Assigned(lvwFiles.Selected) then
177 | Handled := True;
178 | miExtract.Enabled := not Handled;
179 | miExtract2.Enabled := not Handled;
180 | end;
181 |
182 | procedure TfrmMain.lvwFilesDblClick(Sender: TObject);
183 | var
184 | Node: TTreeNode;
185 |
186 | begin
187 | if Assigned(lvwFiles.Selected) then
188 | if lvwFiles.Selected.ImageIndex = 1 then // it's a directory
189 | begin
190 | // get the directory on the left tree view
191 | Node := tvwDirectories.Items.FindNodeWithText(lvwFiles.Selected.Caption);
192 | if Assigned(Node) then
193 | begin
194 | // the current directory was found in the left tree view, open the contents
195 | Node.Selected := True;
196 | tvwDirectoriesClick(Self);
197 | end;
198 | end
199 | else
200 | MessageDlg('This action is only available on folders.', mtWarning, [mbOK], 0);
201 | end;
202 |
203 | procedure TfrmMain.lvwFilesSelectItem(Sender: TObject; Item: TListItem;
204 | Selected: Boolean);
205 | begin
206 | if Selected then
207 | fSelectedFile := GetSelectedNodePath + Item.Caption;
208 | miExtract.Enabled := Selected;
209 | miExtract2.Enabled := Selected;
210 | end;
211 |
212 | procedure TfrmMain.miAboutClick(Sender: TObject);
213 | begin
214 | frmAbout.ShowModal;
215 | end;
216 |
217 | procedure TfrmMain.miCloseFileClick(Sender: TObject);
218 | begin
219 | edtFileName.Clear;
220 | lvwFiles.Clear;
221 | tvwDirectories.Items.Clear;
222 | fSelectedFile := '';
223 | ChangeButtonsState(False);
224 | end;
225 |
226 | procedure TfrmMain.miGetAssistanceClick(Sender: TObject);
227 | begin
228 | OpenURL('http://www.assemblergames.com/forums/showthread.php?55022-gditools-py-a-Python-program-library-to-handle-GDI-files!');
229 | end;
230 |
231 | procedure TfrmMain.miProjectPageClick(Sender: TObject);
232 | begin
233 | OpenURL('https://sourceforge.net/projects/dcisotools/');
234 | end;
235 |
236 | procedure TfrmMain.miQuitClick(Sender: TObject);
237 | begin
238 | Close;
239 | end;
240 |
241 | procedure TfrmMain.miExtractAllClick(Sender: TObject);
242 | var
243 | Success: Boolean;
244 |
245 | begin
246 | Success := True;
247 | with frmExtractAll do
248 | if ShowModal = mrOK then
249 | begin
250 | StatusText := 'Please wait while extracting the whole dump...';
251 | GDReader.ExtractAll(OutputDirectory, DataDirectory);
252 | Success := Success and DirectoryExists(OutputDirectory);
253 | if ExtractBootstrap then
254 | Success := Success and GDReader.ExtractBootstrap(OutputDirectory + SFILE_BOOTSTRAP);
255 | if GenerateSortFile then
256 | Success := Success and GDReader.GenerateSortFile(OutputDirectory + SFILE_SORT, DataDirectory);
257 | ResetStatusBar(Success);
258 | end;
259 | end;
260 |
261 | procedure TfrmMain.miExtractBootstrapClick(Sender: TObject);
262 | var
263 | Success: Boolean;
264 |
265 | begin
266 | with svdExtractBootstrap do
267 | if Execute then
268 | begin
269 | StatusText := 'Extracting Boostrap...';
270 | Success := GDReader.ExtractBootstrap(FileName);
271 | ResetStatusBar(Success);
272 | end;
273 | end;
274 |
275 | procedure TfrmMain.miExtractClick(Sender: TObject);
276 | var
277 | Success: Boolean;
278 |
279 | begin
280 | if Assigned(lvwFiles.Selected) then
281 | begin
282 | // An item is selected
283 |
284 | // If the item is a directory, the feature can't be used (for now)
285 | if lvwFiles.Selected.ImageIndex = 1 then
286 | MessageDlg('This feature was only designed to handle files.', mtWarning, [mbOK], 0)
287 | else
288 | begin
289 | // Extract the file
290 | with svdExtract do
291 | begin
292 | FileName := lvwFiles.Selected.Caption;
293 | if Execute then
294 | begin
295 | StatusText := Format('Extracting ''%s''...', [SelectedFile]);
296 | Success := GDReader.Extract(SelectedFile, FileName);
297 | ResetStatusBar(Success);
298 | end;
299 | end;
300 | end;
301 | end
302 | else
303 | begin
304 | MessageDlg('Please select a file in order to use this feature.', mtWarning, [mbOK], 0);
305 | end;
306 | end;
307 |
308 | procedure TfrmMain.miGenerateSortFileClick(Sender: TObject);
309 | var
310 | Success: Boolean;
311 |
312 | begin
313 | with frmSortFile do
314 | if ShowModal = mrOK then
315 | begin
316 | StatusText := 'Generating Sort File...';
317 | Success := GDReader.GenerateSortFile(OutputFileName, DataDirectory);
318 | ResetStatusBar(Success);
319 | end;
320 | end;
321 |
322 | procedure TfrmMain.miOpenItemClick(Sender: TObject);
323 | begin
324 | if Assigned(lvwFiles.Selected) then
325 | lvwFilesDblClick(Self)
326 | end;
327 |
328 | procedure TfrmMain.miSettingsClick(Sender: TObject);
329 | begin
330 | with frmSettings do
331 | begin
332 | PythonExecutable := GDReader.PythonExecutable;
333 | if ShowModal = mrOK then
334 | GDReader.PythonExecutable := PythonExecutable;
335 | end;
336 | end;
337 |
338 | procedure TfrmMain.tmrResetStatusBarTimer(Sender: TObject);
339 | begin
340 | StatusText := '';
341 | tmrResetStatusBar.Enabled := False;
342 | end;
343 |
344 | procedure TfrmMain.tvwDirectoriesClick(Sender: TObject);
345 | begin
346 | GDReader.FillListView(lvwFiles, GetSelectedNodePath);
347 | end;
348 |
349 | procedure TfrmMain.ChangeButtonsState(State: Boolean);
350 | begin
351 | miCloseFile.Enabled := State;
352 | miExtractAll.Enabled := State;
353 | miExtractBootstrap.Enabled := State;
354 | miGenerateSortFile.Enabled := State;
355 | if not State then
356 | begin
357 | miExtract.Enabled := False;
358 | miExtract2.Enabled := False;
359 | end;
360 | end;
361 |
362 | function TfrmMain.GetSelectedNodePath: string;
363 | begin
364 | Result := GetNodePath(tvwDirectories.Selected);
365 | end;
366 |
367 | function TfrmMain.GetStatusText: string;
368 | begin
369 | Result := sbrMain.SimpleText;
370 | end;
371 |
372 | procedure TfrmMain.SetStatusText(AValue: string);
373 | begin
374 | sbrMain.SimpleText := AValue;
375 | end;
376 |
377 | procedure TfrmMain.ResetStatusBar(Success: Boolean);
378 | begin
379 | if Success then
380 | StatusText := 'Done!'
381 | else
382 | StatusText := 'Failed!';
383 | tmrResetStatusBar.Enabled := True;
384 | end;
385 |
386 | initialization
387 | GDReader := TGDReader.Create;
388 |
389 | finalization
390 | GDReader.Free;
391 |
392 | end.
393 |
394 |
--------------------------------------------------------------------------------
/gui/main.lfm:
--------------------------------------------------------------------------------
1 | object frmMain: TfrmMain
2 | Left = 259
3 | Height = 522
4 | Top = 137
5 | Width = 784
6 | Caption = ' (Main Form)'
7 | ClientHeight = 522
8 | ClientWidth = 784
9 | Menu = mmMain
10 | OnClose = FormClose
11 | OnCreate = FormCreate
12 | OnShow = FormShow
13 | Position = poScreenCenter
14 | LCLVersion = '1.2.6.0'
15 | object gbxDiscImage: TGroupBox
16 | Left = 4
17 | Height = 49
18 | Top = 4
19 | Width = 776
20 | Align = alTop
21 | BorderSpacing.Around = 4
22 | Caption = ' Disc Image: '
23 | ClientHeight = 27
24 | ClientWidth = 768
25 | TabOrder = 0
26 | object btnOpen: TButton
27 | Left = 680
28 | Height = 25
29 | Top = 0
30 | Width = 83
31 | Anchors = [akTop, akRight]
32 | Caption = 'Open...'
33 | OnClick = btnOpenClick
34 | TabOrder = 0
35 | end
36 | object edtFileName: TEdit
37 | Left = 8
38 | Height = 22
39 | Top = 0
40 | Width = 668
41 | Anchors = [akTop, akLeft, akRight]
42 | Color = clBtnFace
43 | ReadOnly = True
44 | TabOrder = 1
45 | end
46 | end
47 | object gbxContents: TGroupBox
48 | Left = 4
49 | Height = 446
50 | Top = 57
51 | Width = 776
52 | Align = alClient
53 | BorderSpacing.Around = 4
54 | Caption = ' Contents: '
55 | ClientHeight = 424
56 | ClientWidth = 768
57 | TabOrder = 1
58 | object tvwDirectories: TTreeView
59 | Left = 4
60 | Height = 416
61 | Top = 4
62 | Width = 264
63 | Align = alLeft
64 | BorderSpacing.Around = 4
65 | DefaultItemHeight = 18
66 | Images = ilDirectories
67 | ReadOnly = True
68 | TabOrder = 0
69 | OnClick = tvwDirectoriesClick
70 | Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
71 | end
72 | object lvwFiles: TListView
73 | Left = 281
74 | Height = 416
75 | Top = 4
76 | Width = 483
77 | Align = alClient
78 | BorderSpacing.Around = 4
79 | Columns = <
80 | item
81 | AutoSize = True
82 | Caption = 'Filename'
83 | Width = 481
84 | end>
85 | ColumnClick = False
86 | PopupMenu = pmFiles
87 | ReadOnly = True
88 | RowSelect = True
89 | SmallImages = ilFiles
90 | TabOrder = 1
91 | ViewStyle = vsReport
92 | OnContextPopup = lvwFilesContextPopup
93 | OnDblClick = lvwFilesDblClick
94 | OnSelectItem = lvwFilesSelectItem
95 | end
96 | object Splitter1: TSplitter
97 | Left = 272
98 | Height = 424
99 | Top = 0
100 | Width = 5
101 | end
102 | end
103 | object sbrMain: TStatusBar
104 | Left = 0
105 | Height = 15
106 | Top = 507
107 | Width = 784
108 | AutoHint = True
109 | Panels = <>
110 | end
111 | object ilDirectories: TImageList
112 | left = 176
113 | top = 96
114 | Bitmap = {
115 | 4C69020000001000000010000000000000000000000000000000000000000000
116 | 000000000000625D5C02746F6D1B75716F1D6A68670400000000000000000000
117 | 000000000000000000000000000000000000000000000000000000000000988C
118 | 882DC5BAB9A4D5CBCBF0E1D8D8FFE5DEDEFFDEDEDEF6D5DADBB3B9BDBC3E0000
119 | 0000000000000000000000000000000000000000000000000000A19B9571D6C2
120 | BCFADCD1D0FFE1D8D8FFE5DEDEFFE9E4E4FFE7EAEBFFEAF1F2FFEAF4F7FEBECE
121 | D09051575702000000000000000000000000000000007D8D8D6CBFD1CFFED6CD
122 | C5FFE1D4D0FFE5DEDEFFEAE4E4FFEDEAEAFFEBF0F1FFEDF6F8FFE9FAFDFFE3F9
123 | FCFFA8BABC9100000000000000000000000048444A22B9BACEF7BBD3D9FFC9DB
124 | DAFFE0D7D0FFEAE2E1FFEFEAEAFFF0F0F0FFEEF7F8FFEBFBFCFFE2FAFCFFDAF6
125 | F9FFD0F2F6FE6C7A7B4000000000000000008B838A90D1C8D7FFCECADEFFC5D6
126 | E3FFD1E4E4FFE3DED8FBECEAEAD2ECEEEECEE5F3F3F7E1FAFCFFD5F7FAFFCFF6
127 | F9FFD3F6F9FF95B8BAB50000000013121201B5ACADD8DED5D9FFDFD8E0FFDCD9
128 | E7FFCFD8E8FDEFF5F59FFBFBFB90FBFBFB91F3F9F992C8F1F3F8BFF8FAFFAAF7
129 | F9FF8FF4F8FF83E5E8F6162020070F0E0E04D7CECEF8C3BEBEFFB3B0B0FFC9C5
130 | C5FFCDCCCFE8FBFBFB8E5A5A5A5537363649FBFBFB91ACF1F2D282F9FBFF7FF9
131 | FCFF7DFAFCFF7BFAFCFF1927262209080806D8D1D1F6CAC5C5FFB5B2B2FFB7B5
132 | B5FFC4C4C4EEFBFBFB8CADABAC4FA2A1A141FBFBFB907ECDE4D849C7E5FF48C8
133 | E5FF47C8E6FF47C7E6FF121B1C2206060602B7B2B1D5D8D3D3FFE7E5E5FFCBCB
134 | CEFF8B99DCFEAFCCEAB3FBFBFB8CFBFBFB8EBBDBECA41391CAFD1589CBFF1684
135 | C8FF1386C7FF147EB5F306090B09000000007675748CF5F2F2FFE2E1F4FF6F8D
136 | E9FF3895D8FF3699D0FF49A1D1E94CA2D1E61B88CAFE1990D0FF179BD3FF1B96
137 | D1FF228BCDFF1C567BB0000000000000000014141421B1B2E1F3598CE6FF4AAB
138 | DEFF50AFDEFF48ACDDFF30A1D9FF30A1D9FF31A0D9FF349DD9FF32A1DAFF2DAB
139 | DCFF2EA6D4FB0F1D243C000000000000000000000000253B5B6E5FBBE2FD66C0
140 | E7FF6CC3E8FF56BAE5FF4BB5E3FF4BB5E3FF4BB5E3FF4CB3E3FF4DB0E3FF4BB3
141 | E2FE204C5B870103030100000000000000000000000001020202243E476E77C3
142 | DDF582D5F1FF66CCEDFF65CBEDFF65CBEDFF65CBEDFF65CAEDFF62BCE1F92949
143 | 5785010202050000000000000000000000000000000000000000000000000C11
144 | 122D446A749D62ABBEE177D0E6F978D2E8FA66B1C4E640707CA90F16183A0001
145 | 0102000000000000000000000000000000000000000000000000000000000000
146 | 0000000000010000000A000000190000001B0000000D00000001000000000000
147 | 0000000000000000000000000000000000000000000000000000000000000000
148 | 0000000000000000000000000000000000000000000000000000000000000000
149 | 000000000000000000000000000000000000EDBF9AB2EDC5A4FFEDC5A4FFEDC4
150 | A1EBDEAB82330000000000000000000000000000000000000000000000000000
151 | 000000000000000000000000000000000000EABA93BFEAC09DFFEAC09DFFEAC0
152 | 9DFFEABE9AFFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC
153 | 97FFEABC97FFEAB890B800000000E3B18874E3AF84DDE3B186FFE3B186FFE3B1
154 | 86FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B1
155 | 86FFE3B186FFE3AF84DDE4B28A74E29459E2E3985EF8E3985FFFE3985FFFE398
156 | 5FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE398
157 | 5FFFE3985FFFE3985EF8E29459E2EC9E65D6ECA068F8ECA068FFECA068FFECA0
158 | 68FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA0
159 | 68FFECA068FFECA068F8EC9E65D6F4A871CAF3A872F8F3A872FFF3A872FFF3A8
160 | 72FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A8
161 | 72FFF3A872FFF3A872F8F4A871CAF6B17DBEF5B07CF8F4AF7BFFF4AF7BFFF4AF
162 | 7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF
163 | 7BFFF4AF7BFFF5B07CF8F6B17DBEF8BA89B2F6B786F9F5B685FFF5B685FFF5B6
164 | 85FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B6
165 | 85FFF5B685FFF6B786F9F8BA89B2FAC396A6F7BE90F9F6BD8EFFF6BD8EFFF6BD
166 | 8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD
167 | 8EFFF6BD8EFFF7BE90F9FAC396A6FCCCA29AF8C69AFAF7C598FFF7C598FFF7C5
168 | 98FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C5
169 | 98FFF7C598FFF8C69AFAFCCCA29AFDD5AE8EFACDA2FBF9CCA1FFF9CCA1FFF9CC
170 | A1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CC
171 | A1FFF9CCA1FFFACDA2FBFDD5AE8EC8A68381F4C393FEF3C392FFF3C392FFF3C3
172 | 92FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C3
173 | 92FFF3C392FFF4C393FECBA8858102020118000000490000004C0000004C0000
174 | 004C0000004C0000004C0000004C0000004C0000004C0000004C0000004C0000
175 | 004C0000004C0000004903020218000000000000000000000000000000000000
176 | 0000000000000000000000000000000000000000000000000000000000000000
177 | 0000000000000000000000000000000000000000000000000000000000000000
178 | 0000000000000000000000000000000000000000000000000000000000000000
179 | 0000000000000000000000000000
180 | }
181 | end
182 | object ilFiles: TImageList
183 | left = 408
184 | top = 328
185 | Bitmap = {
186 | 4C690200000010000000100000000000000000000000A4A4A459ABABAB69A9A9
187 | A969A6A6A669A3A3A369A1A1A1699D9D9D687D7D7D2200000000000000000000
188 | 00000000000000000000000000000000000000000000D8D8D8D9E8E8E8FFE6E6
189 | E6FFE2E2E2FFDDDDDDFFD9D9D9FFD4D4D4FFCACACAF48F8F8F57000000000000
190 | 00000000000000000000000000000000000000000000C8C8C8DAEAEAEAFFE9E9
191 | E9FFE7E7E7FFE3E3E3FFDFDFDFFFDADADAFFD6D6D6FFD1D1D1FD808080700000
192 | 00000000000000000000000000000000000000000000C7C7C7DCEBEBEBFFEAEA
193 | EAFFE9E9E9FFE8E8E8FFE4E4E4FFE0E0E0FFDCDCDCFFE6E6E6FFD1D1D1FE7676
194 | 76720000000000000000000000000000000000000000C8C8C8DDEDEDEDFFECEC
195 | ECFFEBEBEBFFE9E9E9FFE8E8E8FFE6E6E6FFE1E1E1FFADADADFFA5A5A5FFA3A3
196 | A3FD6262625300000000000000000000000000000000C8C8C8DFEEEEEEFFEDED
197 | EDFFECECECFFEBEBEBFFEAEAEAFFE9E9E9FFE7E7E7FFCBCBCBFFC5C5C5FFC1C1
198 | C1FFA0A0A0D400000000000000000000000000000000C9C9C9E0F0F0F0FFEFEF
199 | EFFFEEEEEEFFECECECFFEBEBEBFFEAEAEAFFE9E9E9FFE7E7E7FFE4E4E4FFE0E0
200 | E0FFB6B6B6DF00000000000000000000000000000000C9C9C9E2F2F2F2FFF0F0
201 | F0FFEFEFEFFFEEEEEEFFEDEDEDFFECECECFFEAEAEAFFE9E9E9FFE8E8E8FFE5E5
202 | E5FFBABABAE000000000000000000000000000000000CACACAE2F3F3F3FFF2F2
203 | F2FFF1F1F1FFF0F0F0FFEEEEEEFFEDEDEDFFECECECFFEBEBEBFFEAEAEAFFE8E8
204 | E8FFBDBDBDE100000000000000000000000000000000CBCBCBE3F5F5F5FFF3F3
205 | F3FFF2F2F2FFF1F1F1FFF0F0F0FFEFEFEFFFEEEEEEFFECECECFFEBEBEBFFEAEA
206 | EAFFBFBFBFE200000000000000000000000000000000CCCCCCE4F6F6F6FFF5F5
207 | F5FFF4F4F4FFF3F3F3FFF1F1F1FFF0F0F0FFEFEFEFFFEEEEEEFFEDEDEDFFECEC
208 | ECFFBFBFBFE300000000000000000000000000000000CCCCCCE5F8F8F8FFF7F7
209 | F7FFF5F5F5FFF4F4F4FFF3F3F3FFF2F2F2FFF1F1F1FFEFEFEFFFEEEEEEFFEDED
210 | EDFFC0C0C0E400000000000000000000000000000000CDCDCDE6F9F9F9FFF8F8
211 | F8FFF7F7F7FFF6F6F6FFF5F5F5FFF3F3F3FFF2F2F2FFF1F1F1FFF0F0F0FFEFEF
212 | EFFFC1C1C1E400000000000000000000000000000000CECECEE7FBFBFBFFFAFA
213 | FAFFF8F8F8FFF7F7F7FFF6F6F6FFF5F5F5FFF4F4F4FFF3F3F3FFF1F1F1FFF0F0
214 | F0FFC2C2C2E500000000000000000000000000000000CFCFCFE7FCFCFCFFFBFB
215 | FBFFFAFAFAFFF9F9F9FFF8F8F8FFF6F6F6FFF5F5F5FFF4F4F4FFF3F3F3FFF2F2
216 | F2FFC3C3C3E6000000000000000000000000000000003C3C3C50484848574848
217 | 4857484848574848485747474757474747574747475747474757464646574646
218 | 4657393939500000000000000000000000000000000000000000000000000000
219 | 0000000000000000000000000000000000000000000000000000000000000000
220 | 000000000000000000000000000000000000EDBF9AB2EDC5A4FFEDC5A4FFEDC4
221 | A1EBDEAB82330000000000000000000000000000000000000000000000000000
222 | 000000000000000000000000000000000000EABA93BFEAC09DFFEAC09DFFEAC0
223 | 9DFFEABE9AFFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC
224 | 97FFEABC97FFEAB890B800000000E3B18874E3AF84DDE3B186FFE3B186FFE3B1
225 | 86FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B1
226 | 86FFE3B186FFE3AF84DDE4B28A74E29459E2E3985EF8E3985FFFE3985FFFE398
227 | 5FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE398
228 | 5FFFE3985FFFE3985EF8E29459E2EC9E65D6ECA068F8ECA068FFECA068FFECA0
229 | 68FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA0
230 | 68FFECA068FFECA068F8EC9E65D6F4A871CAF3A872F8F3A872FFF3A872FFF3A8
231 | 72FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A8
232 | 72FFF3A872FFF3A872F8F4A871CAF6B17DBEF5B07CF8F4AF7BFFF4AF7BFFF4AF
233 | 7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF
234 | 7BFFF4AF7BFFF5B07CF8F6B17DBEF8BA89B2F6B786F9F5B685FFF5B685FFF5B6
235 | 85FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B6
236 | 85FFF5B685FFF6B786F9F8BA89B2FAC396A6F7BE90F9F6BD8EFFF6BD8EFFF6BD
237 | 8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD
238 | 8EFFF6BD8EFFF7BE90F9FAC396A6FCCCA29AF8C69AFAF7C598FFF7C598FFF7C5
239 | 98FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C5
240 | 98FFF7C598FFF8C69AFAFCCCA29AFDD5AE8EFACDA2FBF9CCA1FFF9CCA1FFF9CC
241 | A1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CC
242 | A1FFF9CCA1FFFACDA2FBFDD5AE8EC8A68381F4C393FEF3C392FFF3C392FFF3C3
243 | 92FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C3
244 | 92FFF3C392FFF4C393FECBA8858102020118000000490000004C0000004C0000
245 | 004C0000004C0000004C0000004C0000004C0000004C0000004C0000004C0000
246 | 004C0000004C0000004903020218000000000000000000000000000000000000
247 | 0000000000000000000000000000000000000000000000000000000000000000
248 | 0000000000000000000000000000000000000000000000000000000000000000
249 | 0000000000000000000000000000000000000000000000000000000000000000
250 | 0000000000000000000000000000
251 | }
252 | end
253 | object mmMain: TMainMenu
254 | left = 72
255 | top = 96
256 | object miFile: TMenuItem
257 | Caption = 'File'
258 | object miOpenFile: TMenuItem
259 | Caption = 'Open...'
260 | Hint = 'Load a GD-ROM Image file in the application.'
261 | ShortCut = 16463
262 | ShortCutKey2 = 4175
263 | OnClick = btnOpenClick
264 | end
265 | object miCloseFile: TMenuItem
266 | Caption = 'Close'
267 | Hint = 'Close the current GD-ROM Image file.'
268 | OnClick = miCloseFileClick
269 | end
270 | object miSep1: TMenuItem
271 | Caption = '-'
272 | end
273 | object miQuit: TMenuItem
274 | Caption = 'Quit'
275 | Hint = 'Return to your life.'
276 | ShortCut = 16465
277 | ShortCutKey2 = 4177
278 | OnClick = miQuitClick
279 | end
280 | end
281 | object miTools: TMenuItem
282 | Caption = 'Tools'
283 | object miExtractAll: TMenuItem
284 | Caption = 'Extract All...'
285 | Hint = 'Extract the whole data of the current GD-ROM image.'
286 | ShortCut = 16501
287 | ShortCutKey2 = 4213
288 | OnClick = miExtractAllClick
289 | end
290 | object miExtract2: TMenuItem
291 | Caption = 'Extract Selected...'
292 | Hint = 'Extract the selected file.'
293 | ShortCut = 117
294 | OnClick = miExtractClick
295 | end
296 | object miSep3: TMenuItem
297 | Caption = '-'
298 | end
299 | object miExtractBootstrap: TMenuItem
300 | Caption = 'Extract Bootstrap (IP.BIN)...'
301 | Hint = 'Extract the Bootstrap of the current loaded GD-ROM Image file.'
302 | ShortCut = 118
303 | OnClick = miExtractBootstrapClick
304 | end
305 | object miGenerateSortFile: TMenuItem
306 | Caption = 'Generate Sort File (sorttxt.txt)'
307 | Hint = 'Generate the Sort file needed for mkisofs.'
308 | ShortCut = 119
309 | OnClick = miGenerateSortFileClick
310 | end
311 | object miSep4: TMenuItem
312 | Caption = '-'
313 | end
314 | object miSettings: TMenuItem
315 | Caption = 'Settings...'
316 | Hint = 'Configure the application.'
317 | ShortCut = 113
318 | OnClick = miSettingsClick
319 | end
320 | end
321 | object miHelp: TMenuItem
322 | Caption = 'Help'
323 | object miGetAssistance: TMenuItem
324 | Caption = 'Get Assistance...'
325 | Hint = 'Open the official thread help.'
326 | ShortCut = 112
327 | OnClick = miGetAssistanceClick
328 | end
329 | object miProjectPage: TMenuItem
330 | Caption = 'Project Page...'
331 | Hint = 'Go to the project home page.'
332 | OnClick = miProjectPageClick
333 | end
334 | object miSep2: TMenuItem
335 | Caption = '-'
336 | end
337 | object miAbout: TMenuItem
338 | Caption = 'About...'
339 | Hint = 'This item is really useless.'
340 | ShortCut = 123
341 | OnClick = miAboutClick
342 | end
343 | end
344 | end
345 | object pmFiles: TPopupMenu
346 | left = 408
347 | top = 120
348 | object miOpenItem: TMenuItem
349 | Caption = 'Open'
350 | Default = True
351 | OnClick = miOpenItemClick
352 | end
353 | object miSep5: TMenuItem
354 | Caption = '-'
355 | end
356 | object miExtract: TMenuItem
357 | Caption = 'Extract...'
358 | OnClick = miExtractClick
359 | end
360 | end
361 | object svdExtract: TSaveDialog
362 | Title = 'Extract the selected file to...'
363 | Filter = 'All Files (*.*)|*.*'
364 | Options = [ofOverwritePrompt, ofPathMustExist, ofEnableSizing, ofViewDetail]
365 | left = 408
366 | top = 192
367 | end
368 | object tmrResetStatusBar: TTimer
369 | Enabled = False
370 | Interval = 3000
371 | OnTimer = tmrResetStatusBarTimer
372 | left = 96
373 | top = 392
374 | end
375 | object opdGDI: TOpenDialog
376 | Title = 'Please select the GD-ROM Image to open...'
377 | DefaultExt = '.gdi'
378 | Filter = 'GD-ROM Images Files (*.gdi)|*.gdi;*.GDI|All Files (*.*)|*.*'
379 | Options = [ofFileMustExist, ofEnableSizing, ofViewDetail]
380 | left = 672
381 | top = 120
382 | end
383 | object svdExtractBootstrap: TSaveDialog
384 | Title = 'Extract the Bootstrap file to...'
385 | DefaultExt = '.BIN'
386 | FileName = 'IP.BIN'
387 | Filter = 'Bootstrap Files (IP.BIN)|IP.BIN|Binary Files (*.BIN)|*.BIN|All Files (*.*)|*.*'
388 | Options = [ofOverwritePrompt, ofPathMustExist, ofEnableSizing, ofViewDetail]
389 | left = 408
390 | top = 256
391 | end
392 | end
393 |
--------------------------------------------------------------------------------
/gui/engine.pas:
--------------------------------------------------------------------------------
1 | {
2 | gditools.py GUI are licensed under the GNU General Public License (version 3),
3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt.
4 |
5 | SiZiOUS 2015 / www.sizious.com
6 | }
7 | unit Engine;
8 |
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | SysUtils, Classes, Contnrs, ComCtrls;
15 |
16 | const
17 | SFILE_BOOTSTRAP = 'IP.BIN';
18 | SFILE_SORT = 'sorttxt.txt';
19 | SDIR_DATA_VOLUME_LABEL = '__volume_label__';
20 |
21 | type
22 | EGDReader = class(Exception);
23 |
24 | { TFileEntry }
25 |
26 | TFileEntry = class(TObject)
27 | private
28 | fDirectory: Boolean;
29 | fFileName: string;
30 | fFullPath: string;
31 | fSortHashStr: string;
32 | procedure Update;
33 | public
34 | constructor Create(AFileName, AFullPath: string);
35 | property FileName: string read fFileName;
36 | property Directory: Boolean read fDirectory;
37 | end;
38 |
39 | { TFilesList }
40 |
41 | TFilesList = class(TObject)
42 | private
43 | fList: TList;
44 | function GetCount: Integer;
45 | function GetItem(Index: Integer): TFileEntry;
46 | procedure Add(AFileName, AFullPath: string);
47 | procedure Clear;
48 | public
49 | constructor Create;
50 | destructor Destroy; override;
51 | property Count: Integer read GetCount;
52 | property Items[Index: Integer]: TFileEntry read GetItem; default;
53 | end;
54 |
55 | { TGDReader }
56 |
57 | TGDReader = class(TObject)
58 | private
59 | fLoadedFileName: TFileName;
60 | fDirectoriesList: TStringList;
61 | fFilesListHashTable: TFPDataHashTable;
62 | fPythonExecutable: TFileName;
63 | fPythonScriptFileName: TFileName;
64 | procedure Clear;
65 | procedure HashTableCleanUp(Item: Pointer; const Key: string; var Continue: Boolean);
66 | procedure HashTableUpdateDirectoryRecord(Item: Pointer; const Key: string; var Continue: Boolean);
67 | procedure HashTableSortRecords(Item: Pointer; const Key: string; var Continue: Boolean);
68 | function RunCommandFileOutput(const CmdSwitch: string; const OutputFileName: TFileName): Boolean;
69 | function RunCommand(OutputDirectory: TFileName; CommandLine: string): string;
70 | public
71 | constructor Create;
72 | destructor Destroy; override;
73 | function GetFilesList(const Path: string): TFilesList;
74 | function Extract(const AFullPath: string; const OutputFileName: TFileName): Boolean;
75 | procedure ExtractAll(const OutputDirectory: TFileName; const DataFolder: string);
76 | function ExtractBootstrap(const OutputFileName: TFileName): Boolean;
77 | function GenerateSortFile(const OutputFileName: TFileName; const DataFolder: string): Boolean;
78 | procedure LoadFromFile(const AFileName: TFileName);
79 | procedure FillListView(ListView: TListView; Path: string);
80 | procedure FillTreeView(TreeView: TTreeView);
81 | property LoadedFileName: TFileName read fLoadedFileName;
82 | property PythonExecutable: TFileName read fPythonExecutable write fPythonExecutable;
83 | end;
84 |
85 | implementation
86 |
87 | uses
88 | {$IFDEF DEBUG}
89 | Dialogs,
90 | {$ENDIF}
91 | Utils,
92 | Forms,
93 | Process
94 | {$IF Defined(Unix) OR Defined(Darwin)}
95 | , UTF8Process
96 | {$ENDIF};
97 |
98 | const
99 | SFILE_GDITOOLS_PY = 'gditools.py';
100 |
101 | { TFileEntry }
102 |
103 | procedure TFileEntry.Update;
104 | var
105 | S: string;
106 |
107 | begin
108 | S := '1';
109 | if fDirectory then
110 | S := '0';
111 | fSortHashStr := S + UpperCase(fFileName);
112 | end;
113 |
114 | constructor TFileEntry.Create(AFileName, AFullPath: string);
115 | begin
116 | fFileName := AFileName;
117 | fFullPath := AFullPath;
118 | fDirectory := False;
119 | Update;
120 | end;
121 |
122 | { TFilesList }
123 |
124 | function TFilesList.GetCount: Integer;
125 | begin
126 | Result := fList.Count;
127 | end;
128 |
129 | function TFilesList.GetItem(Index: Integer): TFileEntry;
130 | begin
131 | Result := TFileEntry(fList[Index]);
132 | end;
133 |
134 | procedure TFilesList.Add(AFileName, AFullPath: string);
135 | begin
136 | fList.Add(TFileEntry.Create(AfileName, AFullPath));
137 | end;
138 |
139 | procedure TFilesList.Clear;
140 | var
141 | i: Integer;
142 |
143 | begin
144 | for i := 0 to fList.Count - 1 do
145 | TFileEntry(fList[i]).Free;
146 | fList.Clear;
147 | end;
148 |
149 | constructor TFilesList.Create;
150 | begin
151 | fList := TList.Create;
152 | end;
153 |
154 | destructor TFilesList.Destroy;
155 | begin
156 | Clear;
157 | fList.Free;
158 | inherited Destroy;
159 | end;
160 |
161 | { TGDReader }
162 |
163 | procedure TGDReader.Clear;
164 | begin
165 | fDirectoriesList.Clear;
166 | fFilesListHashTable.Iterate(@HashTableCleanUp);
167 | fFilesListHashTable.Clear;
168 | end;
169 |
170 | procedure TGDReader.HashTableCleanUp(Item: Pointer; const Key: string;
171 | var Continue: Boolean);
172 | begin
173 | FreeAndNil(Item);
174 | Continue := True;
175 | end;
176 |
177 | // This code was made to determine if a FileEntry is in reality a directory.
178 | // This can be optimized if the gditools.py script prints if the entry is a
179 | // directory or a file.
180 | procedure TGDReader.HashTableUpdateDirectoryRecord(Item: Pointer;
181 | const Key: string; var Continue: Boolean);
182 | var
183 | i, Index: Integer;
184 | FilesList: TFilesList;
185 | FileEntry: TFileEntry;
186 |
187 | begin
188 | FilesList := TFilesList(Item);
189 |
190 | // for each entry in the current directory...
191 | for i := 0 to FilesList.Count - 1 do
192 | begin
193 | FileEntry := FilesList[i];
194 |
195 | // if the current entry is in fDirectoriesList, then it's a directory.
196 | if fDirectoriesList.Find(FileEntry.fFullPath + '/', Index) then
197 | begin
198 | FileEntry.fDirectory := True;
199 | FileEntry.Update;
200 | end;
201 | end;
202 | Continue := True;
203 | end;
204 |
205 | function __Compare__FileEntry(Item1, Item2: Pointer): Integer;
206 | var
207 | FileEntry1, FileEntry2: TFileEntry;
208 |
209 | begin
210 | FileEntry1 := TFileEntry(Item1);
211 | FileEntry2 := TFileEntry(Item2);
212 |
213 | Result := -1;
214 | if FileEntry1.fSortHashStr > FileEntry2.fSortHashStr then
215 | Result := 1
216 | else if FileEntry1.fSortHashStr = FileEntry2.fSortHashStr then
217 | Result := 0;
218 | end;
219 |
220 | procedure TGDReader.HashTableSortRecords(Item: Pointer; const Key: string;
221 | var Continue: Boolean);
222 | var
223 | FilesList: TFilesList;
224 |
225 | begin
226 | FilesList := TFilesList(Item);
227 | FilesList.fList.Sort(@__Compare__FileEntry);
228 | Continue := True;
229 | end;
230 |
231 | { This is a shortcut for commands generating output files (like IP.BIN and
232 | sorttxt.txt). }
233 | function TGDReader.RunCommandFileOutput(const CmdSwitch: string;
234 | const OutputFileName: TFileName): Boolean;
235 | var
236 | OutputDirectory, TargetFileName: TFileName;
237 |
238 | begin
239 | OutputDirectory := IncludeTrailingPathDelimiter(ExtractFilePath(OutputFileName));
240 | TargetFileName := ExtractFileName(OutputFileName);
241 | RunCommand(OutputDirectory, Format('%s %s -o .', [CmdSwitch, TargetFileName]));
242 | Result := FileExists(OutputDirectory + TargetFileName);
243 | end;
244 |
245 | { Thanks to Marc Weustink and contributors
246 | http://wiki.freepascal.org/Executing_External_Programs }
247 | function TGDReader.RunCommand(OutputDirectory: TFileName;
248 | CommandLine: string): string;
249 | const
250 | READ_BYTES = 2048;
251 |
252 | var
253 | OutputLines: TStringList;
254 | MemStream: TMemoryStream;
255 | {$IFDEF Windows}
256 | OurProcess: TProcess;
257 | {$ELSE}
258 | OurProcess: TProcessUTF8;
259 | {$ENDIF}
260 | NumBytes: LongInt;
261 | BytesRead: LongInt;
262 | SavedDirectory: TFileName;
263 |
264 | begin
265 | // Checking the presence of the gditools.py script
266 | if not FileExists(fPythonScriptFileName) then
267 | raise EGDReader.Create('The gditools.py script wasn''t found');
268 |
269 | // Saving the current directory
270 | SavedDirectory := GetCurrentDir;
271 |
272 | // Handling the output directory
273 | OutputDirectory := IncludeTrailingPathDelimiter(OutputDirectory);
274 | ForceDirectories(OutputDirectory);
275 | SetCurrentDir(OutputDirectory);
276 |
277 | // A temp Memorystream is used to buffer the output
278 | MemStream := TMemoryStream.Create;
279 | try
280 | BytesRead := 0;
281 | {$IFDEF Windows}
282 | OurProcess := TProcess.Create(nil);
283 | {$ELSE}
284 | OurProcess := TProcessUTF8.Create(nil);
285 | {$ENDIF}
286 | try
287 |
288 | {$IFDEF Windows}
289 | OurProcess.Executable := PythonExecutable;
290 | OurProcess.Parameters.Add(Format('"%s" -i "%s" %s', [fPythonScriptFileName, LoadedFileName, CommandLine]));
291 | {$ELSE}
292 | { On Linux (at least), we can't use the Parameters method above for an unknow reason.
293 | I think I should add several parameters for every part of the command line but it's too complicated for no gain.
294 | So I use the old deprecated CommandLine property instead and it works like a charm! }
295 | OurProcess.CommandLine := Format('"%s" "%s" -i "%s" %s', [PythonExecutable, fPythonScriptFileName, LoadedFileName, CommandLine]);
296 | {$ENDIF}
297 |
298 | {$IFDEF DEBUG}
299 | ShowMessage(OurProcess.Parameters.Text);
300 | {$ENDIF}
301 |
302 | { We cannot use poWaitOnExit here since we don't know the size of the output.
303 | On Linux the size of the output pipe is 2 kB; if the output data is more, we
304 | need to read the data. This isn't possible since we are waiting.
305 | So we get a deadlock here if we use poWaitOnExit. }
306 | OurProcess.Options := [poUsePipes, poStderrToOutput];
307 | OurProcess.ShowWindow := swoHide;
308 | OurProcess.Execute;
309 |
310 | while True do
311 | begin
312 | // Refresh the GUI
313 | Application.ProcessMessages;
314 |
315 | // make sure we have room
316 | MemStream.SetSize(BytesRead + READ_BYTES);
317 |
318 | // try reading it
319 | NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);
320 | if NumBytes > 0 then
321 | begin
322 | Inc(BytesRead, NumBytes);
323 | end
324 | else
325 | Break;
326 | end;
327 |
328 | MemStream.SetSize(BytesRead);
329 |
330 | OutputLines := TStringList.Create;
331 | try
332 | OutputLines.LoadFromStream(MemStream);
333 | Result := OutputLines.Text;
334 | finally
335 | OutputLines.Free;
336 | end;
337 |
338 | finally
339 | OurProcess.Free;
340 | end;
341 |
342 | finally
343 | MemStream.Free;
344 | end;
345 |
346 | // Restoring the right directory
347 | SetCurrentDir(SavedDirectory);
348 | end;
349 |
350 | constructor TGDReader.Create;
351 | begin
352 | fFilesListHashTable := TFPDataHashTable.Create;
353 | fDirectoriesList := TStringList.Create;
354 | with fDirectoriesList do
355 | begin
356 | Sorted := True;
357 | Duplicates := dupIgnore;
358 | end;
359 | fPythonScriptFileName:= GetApplicationPath + SFILE_GDITOOLS_PY;
360 | end;
361 |
362 | destructor TGDReader.Destroy;
363 | begin
364 | Clear;
365 | fFilesListHashTable.Free;
366 | fDirectoriesList.Free;
367 | inherited Destroy;
368 | end;
369 |
370 | procedure TGDReader.LoadFromFile(const AFileName: TFileName);
371 | const
372 | FILELIST_SIGN = 'Listing all files in the filesystem:';
373 |
374 | var
375 | Index, i, StartIndex: Integer;
376 | OutputBuffer, RecordFullPath, RecordDirectoryPath, RecordFileName: string;
377 | FilesList: TStringList;
378 | Buffer: TFilesList;
379 |
380 | begin
381 | Clear;
382 | fLoadedFileName := AFileName;
383 |
384 | // Executing gditools.py
385 | OutputBuffer := RunCommand(GetCurrentDir, '--list');
386 |
387 | // Extracting the files listing
388 | StartIndex := Pos(FILELIST_SIGN, OutputBuffer);
389 | if StartIndex = 0 then
390 | raise EGDReader.CreateFmt('Error when parsing the GD-ROM Image%s%s',
391 | [sLineBreak, Trim(OutputBuffer)]);
392 | Index := StartIndex + Length(FILELIST_SIGN) + 1;
393 |
394 | // Parsing the files list...
395 | FilesList := TStringList.Create;
396 | try
397 | // Load the files list buffer
398 | FilesList.Text := Trim(Copy(OutputBuffer, Index, Length(OutputBuffer) - Index));
399 |
400 | // Extracting the directory listing and building the files list
401 | for i := 0 to FilesList.Count - 1 do
402 | begin
403 | RecordFullPath := Trim(FilesList[i]);
404 | RecordDirectoryPath := ExtractFilePath(RecordFullPath);
405 | RecordFileName := ExtractFileName(RecordFullPath);
406 |
407 | // Building the directory listing...
408 | fDirectoriesList.Add(RecordDirectoryPath);
409 |
410 | // Handling the files list...
411 | if not Assigned(fFilesListHashTable.Find(RecordDirectoryPath)) then
412 | fFilesListHashTable.Add(RecordDirectoryPath, TFilesList.Create);
413 | Buffer := TFilesList(fFilesListHashTable[RecordDirectoryPath]);
414 |
415 | // Adding the record...
416 | if RecordFileName <> '' then
417 | Buffer.Add(RecordFileName, RecordFullPath);
418 | end;
419 |
420 | // Setting the Directory flag:
421 | // This can be optimized if the output of gditools.py indicates if the entry is a file/dir
422 | fFilesListHashTable.Iterate(@HashTableUpdateDirectoryRecord);
423 |
424 | // Sorting the directories and the files order
425 | fFilesListHashTable.Iterate(@HashTableSortRecords);
426 | finally
427 | FilesList.Free;
428 | end;
429 | end;
430 |
431 | procedure TGDReader.FillTreeView(TreeView: TTreeView);
432 | var
433 | i, ImageIndex: Integer;
434 | Directory, DirectoryName, DirectoryPath: string;
435 | HashTable: TFPDataHashTable;
436 | Node: TTreeNode;
437 |
438 | begin
439 | HashTable := TFPDataHashTable.Create;
440 | try
441 | TreeView.Items.Clear;
442 | ImageIndex := 0;
443 | for i := 0 to fDirectoriesList.Count - 1 do
444 | begin
445 | // Work with the current directory entry
446 | Directory := fDirectoriesList[i];
447 |
448 | // Get only the directory name
449 | DirectoryName := ExtractFileName(Copy(Directory, 1, Length(Directory) - 1));
450 |
451 | // Get the directory path (to handle parent nodes)
452 | DirectoryPath := Copy(Directory, 1, Pos(DirectoryName, Directory) - 1);
453 |
454 | // If the directory name is empty, then use the full path (the 'directory' it-self)
455 | if DirectoryName = '' then
456 | DirectoryName := Directory;
457 |
458 | // Get the parent node (returns 'nil' if the parent node doesn't exists
459 | Node := TTreeNode(HashTable.Items[DirectoryPath]);
460 |
461 | // Add the current directory under the found parent (or under 'nil')
462 | Node := TreeView.Items.AddChild(Node, DirectoryName);
463 | Node.ImageIndex := ImageIndex;
464 | Node.SelectedIndex := ImageIndex;
465 |
466 | // For the first node (the root) the image will be a 'CD', after 'folders'
467 | ImageIndex := 1;
468 |
469 | // Adding the current directory (may be a parent for further nodes)
470 | HashTable.Add(Directory, Node);
471 | end;
472 | finally
473 | HashTable.Free;
474 | end;
475 |
476 | // Open the first node
477 | if TreeView.Items.Count > 0 then
478 | TreeView.Items[0].Expand(False);
479 | end;
480 |
481 | procedure TGDReader.FillListView(ListView: TListView; Path: string);
482 | var
483 | FilesList: TFilesList;
484 | i: Integer;
485 | FileEntry: TFileEntry;
486 |
487 | begin
488 | // Get the selected files list from the GDI path
489 | FilesList := GetFilesList(Path);
490 |
491 | // Fill the ListView with the contents of the files list
492 | ListView.Clear;
493 | if Assigned(FilesList) then
494 | begin
495 | ListView.BeginUpdate;
496 | for i := 0 to FilesList.Count - 1 do
497 | with ListView.Items.Add do
498 | begin
499 | FileEntry := FilesList[i];
500 | Caption := FileEntry.FileName;
501 |
502 | // By default, every entries are files...
503 | ImageIndex := 0;
504 |
505 | // ... but mark directories with the right icon
506 | if FileEntry.Directory then
507 | ImageIndex := 1;
508 | end;
509 | ListView.EndUpdate;
510 | end;
511 | end;
512 |
513 | function TGDReader.GetFilesList(const Path: string): TFilesList;
514 | begin
515 | Result := TFilesList(fFilesListHashTable.Items[Path]);
516 | end;
517 |
518 | function TGDReader.Extract(const AFullPath: string;
519 | const OutputFileName: TFileName): Boolean;
520 | var
521 | SourceFileName, TargetFileName, OutputDir: TFileName;
522 |
523 | begin
524 | Result := False;
525 |
526 | SourceFileName := ExtractFileName(AFullPath);
527 | TargetFileName := ExtractFileName(OutputFileName);
528 |
529 | // Handling the output directory
530 | OutputDir := IncludeTrailingPathDelimiter(ExtractFilePath(OutputFileName));
531 |
532 | // Calling the gditools.py script
533 | RunCommand(OutputDir, Format('-e %s -o .', [AFullPath]));
534 |
535 | // if the file need to be renamed, do it
536 | if (SourceFileName <> TargetFileName) then
537 | RenameFile(OutputDir + SourceFileName, OutputDir + TargetFileName);
538 |
539 | Result := FileExists(OutputFileName);
540 | end;
541 |
542 | procedure TGDReader.ExtractAll(const OutputDirectory: TFileName;
543 | const DataFolder: string);
544 | begin
545 | RunCommand(OutputDirectory, Format('--extract-all -o . --data-folder %s', [DataFolder]));
546 | end;
547 |
548 | function TGDReader.ExtractBootstrap(const OutputFileName: TFileName): Boolean;
549 | begin
550 | Result := RunCommandFileOutput('-b', OutputFileName);
551 | end;
552 |
553 | function TGDReader.GenerateSortFile(const OutputFileName: TFileName;
554 | const DataFolder: string): Boolean;
555 | begin
556 | Result := RunCommandFileOutput(Format('--data-folder %s -s', [DataFolder]), OutputFileName);
557 | end;
558 |
559 | end.
--------------------------------------------------------------------------------
/licences/GNU_GPL_v3.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/gui/about.lfm:
--------------------------------------------------------------------------------
1 | object frmAbout: TfrmAbout
2 | Left = 639
3 | Height = 166
4 | Top = 402
5 | Width = 406
6 | AutoSize = True
7 | BorderIcons = [biSystemMenu]
8 | BorderStyle = bsDialog
9 | Caption = ' (About Form)'
10 | ClientHeight = 166
11 | ClientWidth = 406
12 | OnCreate = FormCreate
13 | Position = poScreenCenter
14 | LCLVersion = '1.2.6.0'
15 | object imgLogo: TImage
16 | Left = 8
17 | Height = 128
18 | Top = 8
19 | Width = 128
20 | BorderSpacing.Bottom = 30
21 | Picture.Data = {
22 | 1754506F727461626C654E6574776F726B477261706869635344000089504E47
23 | 0D0A1A0A0000000D4948445200000080000000800806000000C33E61CB000000
24 | 097048597300000EC400000EC401952B0E1B000020004944415478DAED7D7778
25 | 5CD599FEFB9D73EF548DBA6459B6DC7B37CD404C6FA6991242494280141248AF
26 | 6C7637BFEC6EB225D9EC26D96481248484107A02A1188301D331D518DCBB245B
27 | D59634D2F47BEF39E7F7C72D7367349225B0C1C9FA3ECF3CA3A99A7BDFF77CDF
28 | FB95730E70E438721C398E1C478E23C791E3C871E438721C39FE6F1DF4B77A62
29 | 4F3FF32A314620C6C088883106222A38DFB7DF591BADAAAA2E4FA75329611A89
30 | C58B8F5600400410632028054029A5A094C092E38E52470870981E4F3EF53271
31 | C68931463DBDFB75D334672B60B61062C29EF6BDB32A2B2AE60503C15ACE7944
32 | D37898732DA46B9AA6691AA494B02C4B082973528A8C1022655A567C2031B039
33 | 9B4E6D9C3573D61EC6686B2C1A595F535D99B13921D5E2C58BD511027C48C78A
34 | 95CF93C63530C6D940221E4967B367F4F4F69CA069DA39E5B1F239B168991E2B
35 | 8BA1A23C8650280422726E806B08DCE7F27F63D063D33430904860203180642A
36 | 210712895DDBB66D7BE2B8638F7AB5AABC7C556545AC5729A9A4946AE1A2A3D5
37 | 11021CC2E3E1479F218D6BE01A67DB776C9B6898D6559AA62DAFACA85C545B53
38 | 13A8AFAD83AEEB43023D3AF009440A008191725E572052905260DFFE1E74EDEB
39 | 16BDF1F83629D463D55515F74D99347E9D924A0A29B160C15F87BBA0BF0EE057
40 | 93A66994480C54A4D2E9CB7AE37D578F1D33F6C409E39B785934324230470BBE
41 | 738108603EF0EDE794F71C00188681E6D63DAAADB37B733299FABDB48C7B4E39
42 | F9C40E29A49C3377913A4280F7783CF8F033A46B1A6BD9D33C6F6F7BDB37A74D
43 | 9EFAD1A671E323B5353500F2C01D4AF0FD04C883AF8ADEA3C01803000C2492D8
44 | DDBAD76AD9D3FE746343FD4FA64E6A7A5E082166CD5EA08E106084C7FD0F3E45
45 | 015D67ED1D7B8FE9EAEAFCBBE9D3665C3875D2646E9B777C00E09307BE3BDA5D
46 | F0C97507F0BB051AF4FF9452D8D5B2476DDEBAEB9531F5353F9A32B169A52584
47 | 344D53CD9F7FF8B887C38A00773FF02405749D7574B61DDF1BEFFBDED44953CF
48 | 9A3C71220B68BC04381F04F8CEAD24F8CAF79EC104B0DF47904AA1756F3B366D
49 | DDF1767555E50F264F1CFFA8691A62CE9CC32382382C08F0BB3F3E467A4067A6
50 | 91AB7BFD8D57FEFD84254BAF9E3471320F68CC36BF8C9C51F841814F3EB0E900
51 | E06348F0E1FB4E80D0DCBA57AD79E3ED27485ADF58FA91E3B6E772865CB46889
52 | FA3F4D80DBEE5CC1F6B4EEE48CE1335595D5FF3A7BD6DCEA70380402C089C098
53 | EB873F48F0E1F978E6031B0EF8C51AC04932D9EF67F9EFB7BF93E0CF3F599689
54 | 751B3665BBF6F5FEA4BEBAE23F6AAA2B323923A78E3DF614F57F8A00BFF8ED5F
55 | 28A8EB6CDBD60D7363E5E5BF99376BF671F5F5F5F605830BB83DF26D2B907FEE
56 | 83019F7C6A3F0F7EB12660CCFD1FCCA7070683EFFF4E22A0B72F8E356FACDBF5
57 | F6DBEB3E77D5C796BF60185971D4D11F3C093E1402FCF2B70FB25DDBB7F07059
58 | C5272B6B1A7E397FD6AC484863E01A1CC0A9C09496B602870A7C2A8A00D43002
59 | 10608C7C603B401339AEA3187CF82C870494C43B1B378B07FEBCF2DF16CD9FFE
60 | C3D9B3A65A471F73BAFC9B25C0FFDC7A076981106532B9D8C6CDDB7EB1E4C4D3
61 | 3FD938661C694C21C0015D57D0D96070189163010A497068C0A7421F5F00BE2A
62 | 720BC5E2CF459B9CCF5109F07D9A020A80404757179E7EEEF5D503F1BEEB4EFE
63 | C8D16DD95C4E7E64E9F9EA6F8A00B7DCF65BE25A90FDE98107E61D7FEA0577CF
64 | 99B5784E241205C0C009D03810D414748DC0992BBE0A01E33E4B7068C1A712A1
65 | 5E7112A89000280098BC0B5BCAADB8C402A46D092090CD64F0DC2B6BBB376CD8
66 | FAC9B34F5FF2AC6198E2848F1C7A127C2004F8D56DB7901E08F335AFBEB174CE
67 | 82631F9A317D51A5221D0ACC192D04CE08010D08E880CEDCE44B1E4C4604C694
68 | A70B0E0DF82832D3F0093E55E0065831F8CED52462CEF85743B815E7FB94EFFB
69 | 20A0940094C0AB6F6D301F78F0E9CFCE9EDE78CFFC79B3C4474E5A2EFFAA09F0
70 | EBDB7E413B76ECD676B7B45DB0ECDC73EE9A3E7D5ED81401989606A1589E04C4
71 | A03120A8DB96C08E000AC16464AB6C76C8C0CFE7FF87039FE08A52E65DC1FCE7
72 | 99776187041FAAC0B5404900EECDC2FA4D3BE45DF7ADBA694A53CDFFCC9B3FDB
73 | 3AE9E48BE45F25016EF9F57FB3DD3B5B78774FFCD3E79C73DA2FA74E9AAA29E8
74 | 30A406D3D461080D121C4A91377274CD264180B926DF070EF204F0875B070F7C
75 | 1C40002A5FE847252C87DFFF0F1694F6E78BC047FE463E126CDDDEA27E7FD7E3
76 | FF3DB1B1FAEFE7CC9D619D7ADA47E55F1501FEF7961FB3E6E63D5A5F7FF26BE7
77 | 9D7BFABF378D1FCF080C0087543A4CA923277498960629199463051811023A10
78 | D26C41580C74A1153814E017FAE9C1E03B6E880D01BEF7B952E0C3137FF6CBD2
79 | 013FFF3A200129A0948596BD1DF8FD5D2B7F5B5719FEE29CB933CC33CEBC5CFE
80 | 5510E09737FF8835EF6EE5FB7AFB3F75D1F2B37E3D61FC38669B469B00008354
81 | 011852474E68B02C0EA938146C2BC03520C809214D81B3C13EBFD8151C1CF069
82 | 98F4AF1FFCD299BFE1C177DD084090DE636FE47B28E4DD8152124A59686E6DC7
83 | AF6E7FF427E3C694FDE3ECD933CC73965D250F6B02FCEC7F7E48AD2D7BB5963D
84 | 5DE77FECF273EF9F3679B24EC4BC8B6E274C1894D221950653EAC80A0DA6A541
85 | 399A807182C680B0060438C059615E804A5A81F70B7E3E0270416183C02F1DFE
86 | 159007C381EF33FBA41C21580C3EA0948282DD860629B07567B3FAED1D2BBEDD
87 | 34B6E21733674EB5CEBFE06A795812E0BF7EFA7DDAD3DAAEBDFCCADB277CF96B
88 | D7AD9C337346C41FCEC1137CB61550D020A50643E8C80A1D96E48E2864608CA0
89 | 3B24D0B9E3F75D80593E4368FBE28301BE5FFDAB4125E0A18A3F0560A3389454
90 | C380EF37FB7EF0E1809FB706520AACDFBC5DDE76FBA3D74E995873EF8C1953AC
91 | 8B2FF9B43AAC08F0A31FFD1D45A251FED88A67675D7EE5852F2C9C37B78A18F9
92 | 4CA21B32B9611207A04181433AAE20273458D2B604203B340C7220A4D9790286
93 | C291C7589E04070FFCA13380403EF53BD8CCBB02B004F85ED2070049E7C2FBC1
94 | B749A19433FA55FE35B72155490BAFADDD6CFED3BFFCCFF9679FB1E4B9695327
95 | 591FBBFCF3EAB020C0BFFDF09B148D46D9BD0F3C5E76E52796AF3EE1B8638ED2
96 | 342D0FBA4B8282308901C441D0201587907654605B02472B104167E473056E34
97 | 408E15B00129D608A3077F70A84625C02F54FF28721B7EF05104BE1C1E7C2828
98 | 1483EF7F2C0125208489A79E7FBBF31B5FFFFE09FFFD93EFEE4D2452E293577F
99 | E57D91403B1804086A41FAC52FEFD0CF39FF94FF5C3C7FE651BA468EA9734715
100 | F3122680724CB9722E8802270922E159889C2008A9A0C8BE74862270E53A105F
101 | B5CD777F70C0F73F56BEC7B2C4EB25BE1FA5C07747BE2AF8C92EF0A547BEFB18
102 | 5E94001018E33869C9EC866F7DE7CBBFFDC7EFFDE785DFFFDE577300C4876A01
103 | 7EF44F37515B67A7DE15EFBBEC9AABCFFBE3B8C64652CEE8B6CD3D2B1CF9AE25
104 | F0FC257778C8209506216D3D60080EA16CADC08810E284A0A6A0712A48047979
105 | 8122D047073EF9467A7106500E53FB2F56FF859D43766CAF7CE0AB82516F9BF8
106 | 5266DF268842FEFDCAD509CA427B5737FEF7D70FFFA0AD65C7BF5E78E199E627
107 | 3EF955F9A110E09FBFF54DEAEAE9D69E7CFE8599FFFA2F5F7979CEECA9E5F926
108 | 3A1B3C906BCE6D4BE081EFDD33904300226E470642434ED8BA40289B449C11C2
109 | 1A21C06D12D855427F583898042307BF183C38255F59E8166808CB510A7C5220
110 | A53CAB5710E7AB22F03DA0E181EF48411F592414EC0AA25216D66FDA2DBEF3DD
111 | 9F9D77FAC98B9E6D9AD0685DF7E96FAB0FDC05840261F6E4B32FE85FFADC353F
112 | 9DD534AD9C0982E2EE890B8000450440D823DDB958AA28D60684F31A819370A7
113 | E600201892209482520C96B44342AEEC04D1600EBF1FF0A9A89E2F0B7C3CD110
114 | 4DA3182C2041B0AF015022CE1F0E7C3504F8CA015F79BF7BEEAC26FEB5AF7DFA
115 | E6CF5CF7F5636EFEDFEF27DEAB2B78CF16E09FBFF95DF6F21B6BF44824F2B1AF
116 | 5CF3A93F8C195345D005109080266D91EFDA68CF0A386120633E81C81CCBC07D
117 | D10187501A4CA1236BE930248752765F608803418DA0732A481533F23F1E0DF8
118 | 833376A5AA807646920D023B5FF5437EE40F4AF2285FA8A70A433DD7C42BF8DC
119 | 42FEBD79F01D11E93EAF24F6F5F6E3E7FFFBD0BFB5366FFBC1F9E79D665C73ED
120 | B7E5074280EFDCF875AAA9ACE43FFFEDAF6A7EFC9DFFB776F19C598DE012C405
121 | 3C12E812E00AC408CA7109E4BA04F7E601E32780FDB752F91C414E681E097446
122 | 0870425007349FD9670C5E016974E017D6FF6D918A2172FFA54ABA85E07B7EDF
123 | EFF38BCDFEB0E0CB22B39F0F13FDA47049F0F6BBADB94F5D77D3711FBFE2ECCD
124 | 631BEBAD2FDCF03D75C85D40381CA65FFDF177FA25CB96FFC3F449D31AA13440
125 | 487B3483034A80944304A7F80126F232DEE59E57E45145A25E4191B0E37BB7F8
126 | 2E184CA92040B014C0A51D16C2972154647F131B35F87EF5EE1784C5E4284EF2
127 | 503EAFEF2BF4808A433D0C4EF2F8C59D7FE4437A5942F8C347555838724C0266
128 | CF1C1BFCF64D5FFACF9FFDD7CF2FFDBBEF7C5E8ED6158C9A00DFBAF1EBD4D6D9
129 | C1CB62E5734E5B7AF21722656550D2CEEB9114F6892B0652CCFE2DBAE312987B
130 | 51241491D308C1F266920400CD1B3576224642E302E4B809B208962248102C49
131 | D0A46DF67DDD18BE386B24E00F5D082A047F084DE13500A9BC3925E533ABFE91
132 | EFA67765DEE7230FB452AAC855488737FE918F3C291CAB110C6A38E52333CF7E
133 | F82F33CF7FF891A71FBEE5E61FC81B6E1CB9151835012291087B70C55F02179F
134 | 7FF1D7274D98A02B8DD94C960EE84A8124032C06521C101628E8F82E4DD96E81
135 | 44DE0139C575EFE215A866090E02D32C80982D282D825404A108A652E092C0B4
136 | 628F361AF0D53023BD502816440B2861F63DB75064F6510C7EA1C853C5A69D6C
137 | 4290EBFFDD3C82471278D1051430AEA10AD75D77E54D975D7AF5CAE5CBCFB446
138 | 6305464580AF7DE12BD4D6D9CE99C6A72C39E6D88F6981A027EB6DECC9B17394
139 | 071FCC7107A2D08731E95DEC7C5208792BE066D09C705127CB71170C8660904A
140 | 4148068B3949225F3E5EC1977DC448AB80A5C9502828D510E0FBCDBE3FD6974E
141 | 86CF21C320852FF366DF1BDDF67B093EF740CA1BF14EA6C0C31F50E09C61FE9C
142 | 31472D3BEFDCB31E7EF8E9C77FF98B1FC82F7D796456401BA5EF670F3FFE88BE
143 | ECCC655F9D3C7E6280DC588C94CF2A9193E05320C54052822C0B501C50961D5E
144 | 2969FF675F08985753168834CF1FDBF776A690F986A129EC2CA1296D3DC098E7
145 | 507CCD99236FFE18CAE7032819FA817CD7D7EBECC12013EE82AF20EDB0B840E1
146 | FB47BE2C4A0DCBA25A010A48605FEAFCFF6C6CA8C4A7AEB9EC9B1FBFE2334F5F
147 | 78E1391600EBA012E0864F7F81DA3B3BB8841A7FF289277F22180C3917C26717
148 | DD1FC614481194B4AD011403090932180876EF9B77C21C80B2AD81B2D33B0E29
149 | 1C7148B61560B08561C0CB2A3298922015832519B822701740B011E605E0231A
150 | 8AC0F745B13E8D005F66CF9FF2CDFB7CE9A97737AE579025C3BBBCD02B7419F9
151 | 1BF2114051E8A6FCAE40D9C9B145F3C79D70C659672E7DF89155CFFCEC673F10
152 | 5FFBDA81ADC08809108E4468E5D32BF5D34E3AFDFA29132684DCA94FE4CBCF7B
153 | 155F90739ECAB10612500C900C64D8E94C48DB25F8AD81A70DBC8B2B9DF0D026
154 | 02038139D640814082604A272A1000670ACC569BB691F4B5690B61C1B24C0821
155 | 20A5F4AA6C2E11382770CEC03983AE7104831A34674E625E5BFADBB830087C05
156 | 6947302A0FB6F2C0C5A091AF0AFA01E1D546FC69E1BCAF27DFE857250C02C384
157 | 718D74F5A72EFFD2B5575FFFE2B2654B47A4054644806B3E712D757677F296D6
158 | 96E049272EBD2A148AC0D3C179064031DF28D11C6D0005080E72C5A1928069BB
159 | 0628D3B9F75D04E666054DE7E7E55BAEDDC916A42C40772C8145B02473424306
160 | CE00E66802CB12304D039669402939C8E7E77D8F8294B618B32C05C350486760
161 | 13211440381404D77861CEB1A0A7CF156D7208F0FD424FFA74801C1CDAF9C1F7
162 | AC80AB0FC8971C72CD12076361305E81008FE1C4E3ADB3264C9C34E6B1C79E6A
163 | FDD71F7E59FEC33FFE42BD6F02442251DAB8699776CAC9A79F31764CC3587F35
164 | 8E0010F79950AFE0837CAF3473A48B0420C88E16A40209660B3D65D80C0F38CC
165 | 26E9EB99CBC7EB70442123828E7CF5109684541C9654E0D2FE5C3A9D816559BE
166 | C69162F08BBB79D5204D20A440269341369B413814402412761242FE0C9FDDBE
167 | 95075FFA7CB8CC2B7E2F969705227010011C31992F0C2A5FEE447AA39D480763
168 | 6560BC028C4501D20148348CA9D7961CBFF88A77D7ADFDD9E9A72D1607B20223
169 | 2240281C622FBCFC82FE8DAF7EFBB286FAB100736BF2289A00413E45EC8BAB5D
170 | A3C56087814A39E74E8094208B39C9230BD0453E9462565ED02978F5029B78C2
171 | 9E45A45976CD40D8B90123958312067446E03EEB94F7F930A5541D44D4AB696C
172 | 80739E16C20A48A9CA0155CD393512A9905F6C0140269B452E97452412422412
173 | 2AC8DC1582EF53F64556A050E8C9C251EEFBDB5F16F69783010E626130560EE2
174 | E5602C643FAF0C48AB0B527443539D38FB9CE3AF78E0BE876EDEDDDC6A7CFB5B
175 | 97CBFFFCC9FDEA3D13E0E3575D4D6B5E5BC36A6BEB2A16CE5F7C1ED7B58204B2
176 | 720778F1A8F24613F39A203CF70000AE4074DC826D0D9857F2842E419A9B05B3
177 | 603FF0996E2230122027FE1352A23F958390409813B8D32CE2FCAE4420A0AF8B
178 | 4623DBA3D1E8AE6030A0954A832BA554369B4D653299F1994C628652D6B18C44
179 | AD2DC4EC45E3D2E9344C338BF2F232AFD943A9FC88579E3B5379F0917771CACD
180 | F415157B0AB386AA50F2910EC6A260AC02C4CB40A403CA84147D90629F0DBEEC
181 | 839229401998DC64CE5BB8F8A8D93B77B4AE3DE698E9D6FBB200E17084DADAF6
182 | EAF3E72FBAB0716C6399937A2B2C2650618637DF09E2BB635E90E6F4863A27AB
183 | 1420292F122D5B30DAAEC1CA9B3E261D30A53397C806979384696661660DE8A4
184 | 41920643011C040ED55F511E7BA6B6A66A9DA669DCF9327DC8C2081185C3E1B2
185 | 70381C07AA5F370CE3B9FEFE9EC9A6D17F11E762ACCD2506D314E8EBED437945
186 | 041AE7BE919F07DB1EC5A228B47308E38AC282D19F37F7A414143888059DD15E
187 | E18C760525D310D61E67C4F740A924A00C28985E7435656280E6CD9BF4D1BBEE
188 | 7CF0DDA54B679AC3B981031220140AB33D7B5BF54B2FBBEA94DABABAC2125851
189 | 028E50A00907979C88F97C9A633A94A3D894B2AD011C6D604AE7B19B45B4AD01
190 | 29B2EF1D4B90CDA591CD18D0B9732A26C154DC8A95953DDBD450B32618D09553
191 | 621CF511080422757563BBB2D9AA9F0F0CEC9BA764DF254432AA148754403CDE
192 | 8FF25804BACE4B809FD70070F40BF9EB005404BE6BF64907B10838AB00F11808
193 | 1A14B2905607A4E8B247BC1C00540E80832D39D1941345D4D7693876C9ACB3EE
194 | BA13FFD6D2D299FBE28DCBE4FFDEFC841A35012EBEE4727AFD8D571980E0ACD9
195 | 739612E7A56B88058F558149202F6C295E39C3F5F3BEA8562990E71AF29680A4
196 | F0A963A7D40C82659AC865D220D2A0395942223630B5A1F1DEEA8AF28E83D5F0
197 | 1A0A85C2A150D3CE8181C87FA512CD9F662C375E3965EBFE817E5456948173F2
198 | 5901E5CB096050926790CA07012C04C66260AC02A010000125E390561784EC86
199 | 92FD80CA402937C7E3772DF932B472EA2893C663766D5D7DE5AEDD9DA9850B27
200 | 5BEFC90284C3616A6FDFABCD5F70D494EAAA9AB1C48A0B2E8309B065FB167476
201 | 76A02C1A85699AD8B865232A2B2A70E9791723140CE4B36DC82B6FB78042809D
202 | D6737581522021F22EC1971D93C244269D849DFE110018B480BE77E298C9F786
203 | 4291D4A198F0525E5EA3380FDC1CEFDD7C39D7928BA0420018060606505119B1
204 | AB90AE89477EE4E743377FAF00D9669E2260BC02C4CAEC248A4C418A7648D105
205 | 25FBA054DA1EE9CA721A6B4A640F7D8472AB90E31A499B377FEEA94F3DF5EC7D
206 | 4B8E9B36A41B189600C16090DADAF66AD366CE39B9AEAE9E1411188A423CE7AE
207 | 754F0B1E79EC4130CE71F289A760FAD46908878268EB6CC786CD1B70D985973A
208 | 6935E7032A5FCAF53A653D41A1EC8BA194A30D246049BBA6A02414974867134E
209 | C7997D5E9AC63BC78E9B7D87A6052D1CC2231A8D05399F7FEFFEEE5719E7030B
210 | 40610841480C98282F2F2B91E2CD0B3EF2AC6310C4CAC0A902604140E5A08463
211 | E2652FA05279BFEEEA08123E77529437F042C7BC956F1C13C2C44955C701F873
212 | 20C8E83D5980EEEE2E06403B76C98927565755FA1A3AE1D5F201E0C5979EC573
213 | CF3F83891326E1539FF8B49D4173E8F1B14B2EC7D18B8E861E0A7BF972F20B06
214 | 77764CBE5DD679CD3599E4D514E0E40D72E984ED3D34406900E32A55DF30EBDE
215 | D182AF94821042D734CD1C9D4B0887ABAA17DEDFD7F74A3D67B9064565304C20
216 | 9B630887023EF5EF4BEC10035104C4CA4154E6B88B7E286B1FA4DC07259300B2
217 | DE480709AF7C0E7F51A8386AA0E2D633FB7175B586A38E9E7EEA1DB7435FFDCC
218 | 26F6D9CF9D4EB7FD66B51A3101969D7B217576B43300812993A72C72DBA10AFB
219 | FC8127563E8237DF7A0D0D63C6E2DA6B3F5F140D009C31CC9831AB60A42B6F02
220 | 95FF44FC753CE523029C516F93400A0B664682B806280906C89AB1B3EF0F0663
221 | FD07024E08A1C5E3F199E9747A92522AC039274DD32CCBB2342184628C65A2D1
222 | E8AE8A8A8AED8CB1613368D1B26ADDB216DD9E4ABEF24D820C82A2C8A4930805
223 | CB9D11299DC294065019188BD901884A43CADD50C2F1EBC802B040B0F2C9A352
224 | 1604AE8F1F227A4061F848A430AE81A60483A108E3940C059985E2E4C6700408
225 | 0643C43867814020148D441B4A4DBF6A6EDE8937DF7A0D00F0D18F7EBCE49A38
226 | 2E194CD34440D73D6E64D26964322954565440D7F4C230C83310D20B210912C4
227 | 19D2D90C140B82A405B2042295756B23B131AD0718E9D4D3D3B3309D4E4FADAE
228 | AE6EA9AEAE5E474483FAE7A4943C994C8EDFB367CF47CBCBCBD75755556D1DEE
229 | 7B2B2AC79BE974F52AA53A2E24C5212447269342241201608B3AA230000B4AED
230 | 83945D80EC8752190086D30463796E830ACAE2AA64A2A860E0A8D2E0BB7FD7D6
231 | 0A6DFEC2C5D357AF5ED3B378F1441A950B080683F4E61BAFF2638E3B615AAC2C
232 | 1628065F4A81071EB8CB161CE39A50575F6F4761A6012515C2E11014805C2E0B
233 | 25151203FD58F5CC1318E8EF473295C48C69D3317BE66CBCFAD6EB48241238F9
234 | 841331B169A2AF0266C7DC9E7022826559B09402716E979D49372A1A263E371C
235 | 48966505DADBDBCFADAAAA6AABADAD7D65B8F732C6447979794B2C166BE9EFEF
236 | 9FB677EFDE498D8D8D4F31C6E4D02438FAB5BE9E074F25D61FE3AC1E524641AC
237 | CE99009B8014AD50AACFF6EB30ECD14EA220610497E83EA1A8E0EF2FC803AB8A
238 | 46B9BF4B206F611DD11A03A2D1D01C00AF07026C741A40D77502C0CBCA623363
239 | B1F2C2742F011B36BC835C2E0B0058B2E444EFF578BC0F8F3DF62006060690C9
240 | 6410080470D5959FC4C48993515656862D5B360100CE39EB5C54565662E28449
241 | F8E18F7E80B5EFBC8D6B3E7E3516CD5F54C074F24DAE34AC1C14713B29044259
242 | 4DED2B5A309C1A0EFCB6B6B6E563C78E5D17080452A5DF2348D3B82A4A08A1B2
243 | B272472814AADAB367CF454D4D4D0F0F458248A44ACFA4173ECDD9C0255CAF87
244 | 52064CB3051A8F032A05859C3DCAC949CB2BE5E431FC22CE67E655D13C025538
245 | C2A9C468A7A291EFBEA7B25287AE9B1300685CA3D15900CD218002265496C706
246 | B55B6FDBB6D9B514983D7BBEF75A43C3584C9830092FBEF81C8808575D753526
247 | 4E9A0202D0DADA0200B8FE7337A0B2BA1A0050555D8D2F7EFE8BB8F39E3BF1F2
248 | 6B6BB078D1515ECDCB9B58E15C24D312CE4E1E0C444AC5EA1BDE1CCEECB7B7B7
249 | 9F5B0C7E369B632F3CFFE2B83BEEB823BB65CB162B93CE28C618CD9A355BBFE2
250 | CA2BB44B2E5DDE6ECF6B0442A1505F7D7DFDB6F6F6F633C78F1FBF6AA8FF5516
251 | 9BB53E957AE64233DDA609918515B0501EE38E6F1F1CAF17177F0A4C3D15E509
252 | 06E5584A9BFB528FAB2A38161D356BF2D3AB5EE2CFAEDECA2EBFE278BAFFBE57
253 | D5010970FC8927D1DA375F27007CDE824593C3E1F0A01EBB542A0900A8AB1B83
254 | 402050F05A67A79D83F9D8C7AEC2F4E9B6007CFBED37D1DDDD85DADA3A4C9B3E
255 | 13524AA4D329C4E3719852E0D8639720DED78B55CF3C85F2F27234D43760EAE4
256 | C9DE48B04CD32E893BFD018170A899EB812147FFBE7DFB8EAAAEAEDEE3077FEF
257 | DEBD55DFF9CE4DFC2F7F79E8994C26D30520ED38616DE3E6F5B1152B1F6D3CF1
258 | 96934EB8F9965F0ECC9C353DE5E4427AA3D1684D3C1E9F565959B9A3B4BB2C53
259 | FBBA3B37697C6081ED061514051DF055A18A57A5157C813F279F8F1F94312CEC
260 | 46A2C2E270C17BCBCA18EAEA63D30168448A69DA082D80C6B9BBBF8E565F3FA6
261 | A654836563E378ECD9D382643251F09A6118D8BEDDD64E93274FF75E7BE6197B
262 | 009D77DE721011F6EDDF879EDE1E241203686D69413295407B7B1BDE5AFB96F7
263 | 3BE6CE9E831BAEBF0104C094398071CFBC452AAB760C63FAF55C2E37A9BEBEDE
264 | F3F99D9D9DD5577FF2EA7DCF3DFFDC3300F603709DB2DB9E1CCC6633ADAB9F5B
265 | B5FBE28B2E39EF9147FF12993E635A1A002A2B2BB7B7B6B69E585151B1834A5B
266 | 5294954D6FCE66D62C701B3A2C4B21A0B3C1628E4A6502556176D4D76A366864
267 | 97785F416B25E5230502100A51A5DD680962DC5F8D1B86008C71B7378B8743E1
268 | B25211C019679C83AEAE0E3437EFC2EDB7DF8A0B2EB814BAAEE1DE7BFF000038
269 | F7DC0B5159590122C2FAF5EBD0D3B31FA15008F3E72F0011A1AEBE1E0D631B41
270 | 4478FDF55791CB66F1AD6F7D17BB77EDC46F6FFF3594524824935EF248486F22
271 | 00008570343AA4428FC7E373ABABAB3D82643359FE0FFFF00FE9E79E7FEE5100
272 | 9D00FA0138521C4ED60901001100892DDB363EF0A51BBFF2A9C79F7C34CDEDC1
273 | 808A8A8AAEFEFEFE49959595CD25AF199FB29ED88B173AAD3B10C20402DA1040
274 | 2B5F165815085F1A81691FF2792AD2040484822A02406B6DE96353A6D48FCC02
275 | 30E64D74E6A150305A6A35AE6030844F7FFA0BD8B0E11DBCFBEE3AAC5BF72622
276 | 9108E6CD5B80CF7EF646442211F4F7C7515555850D1BDE0500CC9E3D37BFE823
277 | D74044D8B56B275A5A9A9DD473080B162C84520A9C6BB8F1C62FDB3E9F9C2430
278 | E3CEEF60D00281C4500448A7D34D3535359E3E78E5953563EEBEFBEEDB00EC05
279 | D00320198D460D21849052C2344DD2759D1B86917203F397D6BCF0E88A47577E
280 | 74F9C5177402402C166BEDEAEA9A311401C2E10691495B760F1B5758F9210000
281 | 20004944415414A44461F9BBD86FD350237BA4E0E71B5814869AE2A510082204
282 | 80B5B6F6B9EB758C400412A1B3B39D00B04020102E06DFEF12E6CF5F84050B16
283 | 17345B6EDFBE05814008B5B535C86633D8BC79A3ADFCCF397FD08C9D071FBCDF
284 | 6E3BBBE633D0340D4F3DF52482C1206EBAE9EF112B8F792923E964D31400A669
285 | 6922328609E7027E53FDC73BEF6ACD66B3AD007A2A2B2BFBABAAAA73FBF6750B
286 | C33020A5B467DD496545A365562A95943689525B1E79E4B1F8F28B2FB0135A9C
287 | 9B9665458614CD5A901494C548720505FB5BD91020AA52977C58A0871BFDC3CD
288 | EF0B0555C0A98692926284518052D4D5D5691727753D3CD2A5D85E79E525C4E3
289 | 7D98366D3AA64C990C22C2934F3E0EC330B060C122D4D5D516807FDB6DB7A2BD
290 | BD0D975EFA311C7DF4D1D8B1633B5E7FFD35DC74D3DF63CC9806DF0C1CE5650B
291 | 0180693C3E5CB64FD334CBA707D8AE5DBB5CB39F3CFEF81372EFBEFBAE482693
292 | 05885896A902015D4D9A3829DBDCD2CC01F4AD5DFB661B801A1FB1D830BD04D2
293 | 3259BFA6E5EA01405A124AD201C054C3FE7540933F5441D6F744302035628C2B
294 | 29498E94004E51C15E979169FA81C0DFBD7B07D6AD5B0BC618CE39E73C949595
295 | 8188904CA63CF177EEB9E77BE0EFD8B11D4F3CF11876EDDA89E5CB2FC1A9A79E
296 | 86542A858E8E0E7CF5ABDF40454545413651F9461311C0352D3BD4E5314D33AC
297 | F95E8FF7F5F36C36D701207DDC71C719E15058B4B7B7A9215C871A33668C4867
298 | D2B9EEEEEE3411A5FC04E07CF8B60269202D44DAFE1D16C10A9A837D3A61B0CD
299 | 56853E7CD047463485B73431B832A8BCBC22D01FEF831472640490527AE51A21
300 | ACDC70E0FFF18FB7231EEFC3F2E59762F2E4A9DE7B76EEDC81FBEFBFDBFBCE75
301 | EBDE465D5D3DD6AF5F877DFBF661F2E4A9B8FEFA1B118984BDE68E534E397544
302 | 5BC328A5CA864960652CCB0AB98F2BAB2A2C4DD32300CC050B168ADB6EFBCDB0
303 | 43ACB6AE4E2928D1DDDD6D84236151645D86FB2889ECFE1AC5724E5F07839531
304 | 871EA1231EF1EFEF73E99492FDF13E0B008D9600EE88CA96025F08815FFCE227
305 | 088542B8E186AF16E50208914804575EF9495455550220F4F70F8073E0F4D3CF
306 | C28409139D5D36F2EF8FC5CA86059FB92D65449052560E75C29C73CBB22C2DEF
307 | 9B35357DEAF4F297D73C2F971CB744DD76DB6F86BD6013264C402693010075D1
308 | F28BC6145D972153C24A4A5DE6FAA3D251F55C3258999137221DAA255BD329CD
309 | 74D932620288BCAF508691CB1483DFDCBC0B7FF8C36D983C792AAEBDF67325A7
310 | 5F8D1B37BE40F0D5D5D5BD87B97AF9F773CE61FB30829432A0940A1351660802
311 | 1B4AE567FC5C7AE9A5B3FEF2E89F836D6D6DC9035DB0E9D3A6A3A3A31D139A26
312 | D49E79D6998D00E2CEE8D7354D4B0FF539C3489295CE32B7AF412A82C5180695
313 | 47078DDCC13AE1609221938E7A62599823D400C2125EA6229BCBA6FD40A45249
314 | DC76DBCDA8AF6F1812FCD12DCE8011997DCE19A4945E66500851AD695A5BE9FC
315 | 7C646F3A9DAE8F46A3DD0070E639A7A6969D79E115BB9B77FFEAF1154F58E79D
316 | BF6C48FB3975EA14FADDEF6EE737DEF8C54F2C5ABCC0139BC964B2291289EC1C
317 | EA73A9DECD0D229D8372AAC801229844071CE7F9C2CFA1B10ED94C24EBE6A14D
318 | C31A19012CCBF408904A26D32E10E9740AB7DCF27300C0A9A79EF181814F44D0
319 | 751D96657ACFE572C682A108505959B9A1B3B373B94B8070248C7FFEE1FF3BE6
320 | 9B5FFBCEEE3163C63CFED28B6BC4D2934E184482975E7C89DE79F75D7ED96597
321 | 7DFCFACF5F3F8E884C5714C7E3F1B113264C18B29A98EA583B57242C675A9284
322 | 22C0B2DE1B7A348CBFA7511340A6DD28DA3447E8020CD350353535AAA7A747EE
323 | DAB563BF0BC6EDB7DF8A78BC0F00F0F8E38FA0AAAA0A53A74E2B0926006CDFBE
324 | 059CEB98366D9AF7DA962D76CFE0E9A7DB04EAEBEB851002EE8651FBF7EF07E7
325 | 0C3535B50564090603308C1C34CE11086820527301AC06901B1C936B66201068
326 | 49269363CBCACA3A0060C6ACA9E9FFFEF98F2F7BF2F1679A66CC9E7AC7E64D5B
327 | 52D16814132636A9B6BDED944AA7A8AFB7AF064A7DEEEBDFF8FAB4582C66FA32
328 | 8BD32B2A2AD611911A226AE23DDB56CD843D70404CD91396B8DBCE6ECF037CAF
329 | 2399DE231984045219D9EB59809112C0340C5455D5A0A7A747B4B7EDDD934AA7
330 | 511E2BC3C28547239D7E01030303482613F8D5AF7E8979F31660FEFC85983B77
331 | 1EC2E1B037F2B76DDB82952B57402989050B16E2ECB397E195575EC2A38F3E82
332 | DADA1A6CD9B2195FFAD297B171E346DC73CF1F71EBADBF0111E17BDFFB7B9C7E
333 | FA19B8F2CAAB0AD6E4D5B4A0D752669A39A492FDD150305CC91875958A93EAEA
334 | EADEDAB367CFF2402030E01684A6CF9C9A993069FC82979E7BF5E6FBEF79E8AD
335 | 638F3BBA7BD5CA6732DBB7EE8CB4B7B78F3BFAD8C50BBE70C317D28C310FFC4C
336 | 26539D4AA542E3C78F1FB2F630D0B5A15E643BCBED665620A011445239ABA4A9
337 | BC5570C8301472F90851E5434537FDA1868F044A7D653C4DD8B5BBABC5692C94
338 | B9DC085D402E6728E66C666359D6DE814402E5B1184E3DF5749C7CF2A9E8EAEA
339 | 403A9D462E97432231005DD7BD9FE18E74CBB210898421A5740A4684152B1EC3
340 | F7BFFF2F8846A3F8C10FBE8F175E781ED3A64D73D2B52F21140A432985B2B218
341 | 1863608C8173F2B662555220954C405A59282B8B14D396C6CACAFF02CE25344D
342 | 15CE4E22D5D8D8B8B2ADADEDA2B163C7BEED9220180CE28C734EC99C71CE2973
343 | 00CCB12C0B5ABE4C5620F2B2D96C557777F78CA6A6A687871BA0EDEFDC7C8690
344 | 6928C1EC390D44B0B285B0D8449000535094BFA7918C7EA50ADBEC474886DE3E
345 | 8EBDED037B0088D9532A94614835420264A16B9A02203BDAF6EE1A480C80A8D1
346 | 19891CE3C7371DD0E70783416CDBB61542085C73CD7500089AA6A1B5B515D3A6
347 | 4D412693412412C1DEBD7B5157578F471F7D149665A2B6B60E1D1D6D080434C7
348 | BC4A08CBDE5387948430D2809505A5E3C8F474CF8DC6C66D669595ADA8AE4E43
349 | D7A59F049AA619E3C68D7BD8ED088AC5626D25DC45C944587F7FFFB464321919
350 | AE190400FADA5F99DAD7F6E45425094A3030C90049B02CE66402A9A09FC72B00
351 | 91B22D826715FC5D40541A5435187D1A2647D0D71F8429CB5B6DCD2C65362746
352 | EA0272EEB758DBB76D694FA69269228A8C46F05996892F7CE14B686BDB83E6E6
353 | 662C58B010575C71151E7AE80154565661C1828538EEB82578EAA92771EEB9E7
354 | 219349C3B22CD4D45463D7AEDD104242497726ADBDA884C624746942F6EE87D6
355 | D901BDAF8FB291FDE745EAC63C8C3973DA505D9D814DDC02123435353DD2D3D3
356 | B3301E8F9F585555B53B1A8D7696F2E7524A964C26C7F7F5F54D88C562EBC78F
357 | 1FBF65F85C8CD25A5EF9C169CACC42297BEE608013A460807B93642F9D3328D0
358 | CB93C1B60EC2F95B7AF324D420904BE4FED5D06E2091A9467757D74E00966929
359 | 95C9899159809E9E1E75CCB14B646747BB009089F7C73B893065346A7FEEDC79
360 | 2022CC9A35DB7B6DC1820558B870A1B3AE1F83A6712C5FBEDCDB7A5D4A092925
361 | 4E3CF123905ED64D00D202CC2C904EA0ACBF17C68E5D080EA4117F67135AEEBA
362 | 2BBAE8E73F5D1C9A30A1071515D96202B8EEA0B6B6769D1062433C1E9FD9D7D7
363 | B7482915D4348D344D334DD3D4A594923196894422BB9B9A9ADE186ED4BBC7EE
364 | 353F3A6DA0ED8D46DBC43B696A2661097B593B2508B01C2228723AC0FC6EA190
365 | 168A9CA65026BD29F26AC8FC802A594424DF27F6A763B9E6DD6FEFB55DB9522A
366 | 374211688B9FB473F561BEF2F24B9BCE39FD8C297609F7BD867AE4ACC2C1A169
367 | 1CDCA9EDDBCD13C2977DF475BE2A09481330B240A20FD4B617FACEDDD0321676
368 | DFFD67A4B66CC2A48F2E4567E733B3C66B676FD588E2C301C639B76A6A6A36D6
369 | D4D46C744DBD6559014DD30CA2D169F47DDB562C6E7EF13F4E20B2433E02100E
370 | 0848D399CF22094ADA135E21EDD5CD942312DDD9F145B2AFA0546C773F49C722
371 | 382D655444063574FF8090404722B6CDE97B10131BC2F2A577F68FBC2D3C9DCE
372 | B8B31272AD2DBBD7EEEBE9B960EC9831A306DF5E768543D73938E7608C9C0919
373 | 0A4258BED92CF9B504E09A7D6102B934A86F3FA8B919B4A70D465F0A5B7EFA33
374 | C4AA639874E5198847FBD1DDFB1AC5577FEF9CF99FB8AD8303DD230EAFECFC82
375 | 31DAB0ACBF7DDDD477EFB9FA3C0583DC454F39976096407E869E6BFADDD90E0C
376 | 52DAD64049F22C77814528E1DC957F7E04492812A0529D424564D8970E61DDE6
377 | AE754E982C323935BAC9A1B95C56358E1B2FDADBF61A1BDE5DB7B6B3BB4B3436
378 | 34F091806FAB77065DD77CA31D1042C1302C6F8D1EF77325C1370D209300EDEB
379 | 06EDDA09D69740CFBB5BD17CDB6D9870CA3108CD1B83FD813EC4037DC8980A7D
380 | 9B1E0CE77ED773DDA2ABEF7928182EDF768852EBE8DEF2E4D1EFDC7DF5B94A9A
381 | 9C3933CE39938806E0AC909EAFDE29008A932D063580DC557B2C404906E9B885
382 | C1DADC2F0279412791DB64AA48E497A9A3422D00007DA202BD49F51600A3B24C
383 | 13E99C1C2501B219C5389700CC7DDDDD1D1D1D1DADB470E1E4A1C0678C9C91AE
384 | 79A3DDA9DCC1B28463E65541034449F0A505980628110775EC056DDF0512C0CE
385 | 3FDC83F4867731F3F2B3603532F447BA9164FD48892C5430005DAB42DFEE1742
386 | AFDD7CEA958B3E79DFD3E563A6BF7290B1D776AEFEE9193B57FDF312902262CC
387 | 5EB680294435D89354BD915A347F87034AB349A05C02088059B62570D58654C5
388 | 533FBC2DA87CBC60BE98C25D454D7A5FE2868DDD6A7266E3FAD7DE0160948575
389 | 91354649809E9E1E3567EE3CB1AFBBDB04905ABDFAE977979D79D6645DD78BFC
390 | 3A7340B747BBBB7F8F1012420808218B80A7D2E02B65CF8BCB6540F15E504B33
391 | 78CB1E6406D2D8FA9F3F41454D19A67DF24CA42BD24886F723AB27C09801DD04
392 | 0CC1C1B518480F23D3D74CAFDF72D25913977E6DD6A493BEFCB41E8CB6BE4FE0
393 | A97FEF3BB3B6AFFCFE69BDBB5EA82B58174701114DD8EB237BE79737D96E2F03
394 | F9AC0149001A41590E21ACBC5EE0DE40A68279BF439583F31633BFF8A6828205
395 | A03D59B945082B0EC08C04B918C896D6B4C34E0E4DA7D3CAE62B327B5A9AD7B4
396 | 75745C3465D244706E2B785DD79DD1EE0A3A09D37447BBC8CF8B1C6EA166177C
397 | 61823269D0FE2ED0CE1D603D71EC7F7B3D9A7F7B3B269E7A2CC2F3C76020D68F
398 | 74288E9C968274560E8D71424E10520681730DBCA21156268EDDCFFDB8A9EDCD
399 | DF5D37F9B4EF6C695C74E59AF740049EECDE3165D7EA1F2DED5AFFD0047B9598
400 | 7C431067405950821383B7ECB13BB5CD6709FC8B91B924000794A60041CE5C50
401 | 3B6250D2567FD25D3E51D190E04B9F2D40D13E841DA900DEDEB2EF3547009AC1
402 | 80A63AF7C6D5A80B4D631A1A1814825D5D9DD54434EBDE3F3D7CCF79679F5917
403 | 08E8E09C39820E9052F8809745A3FD00E04B090803944C80B5EF016DDF01A473
404 | D8F1873B91D9B209932F3C19721C47B22C8E4C600026CF4292F4CD4ECEAF1C9A
405 | CCE51F4B918395E985B472605C47CDB4B3527533CED8523363D9CE40A47A3FE3
406 | 5A1F1159BEE44F505AD9AA44D7E6FA7D9B1F9FD1BDF9F169E9FDDB83F9245C3E
407 | 26D339501690DEBA884400711B3567A71C570EF8A6D217A482ECBC81B4BB5D95
408 | 132A2AC16C5228F22C8152430580439590155EDD3FD5FA973B377EBCB7B7E7B5
409 | F288D653571DCDECDCDB2F476D0172D99C629C090039A554CFC37F79F0E58B2F
410 | 5876B1AE7348690B3ACBB26059A248CD8F047C5BFD909101E27D602D2D60BB77
411 | 23D3BD0F5B7EFE3FA81C538DE9579F8D746506A9E87EE402290866382BCB70DF
412 | CA5F4E973267D0752063107202602C8400AB83C82520AC347AB63F11EDD9FEC4
413 | D158F1EDA319D7A1872B11AC9868F0602C971B680B1B890E6E194972D73AB68B
414 | 3ACC5E9206EE1EE70A214D21E4F8FCE2D53ADD30BE608328E65F4A810A7B84B9
415 | E3F9B8230E056C4BE0B306CACD1FF8C66B5E610C2E12642CC2C67DE5EB7A7B7B
416 | F600C88543BA9535D47B5B252C1EEF5353A64C95BD3D3D0680D4DB6BDF7C72D3
417 | D66D17CD983A8D4C33AFE6475AD2F5C0570A1002944D83F67783EDDC09D6D58D
418 | AE575F43EB3DF760D2E94B105ED080447902E9F0000C2D0DC59C553D9DDD46FC
419 | 7B0FB98F3908318D10960AA99C842101E21C4C69CED635CA33A046A61746A637
420 | 007B3E800778FE7A9297ADB18107423CBF8975C1BB8AB68921778E5FD1D2B3DE
421 | 96393E2AB8CBE7D92E01805090826C4B2098E3DE0B2D010D63093A06A2787B6B
422 | F76A0003008CA0AEC9546EE856B6032E12954AA765341AB552A9547AF3C60D9B
423 | DF7873EDCEA6C6A6697E253F2AF0A5B4C14F0E80757480B66F85EAE9C3D63FDC
424 | 895CCB2ECCFAF832C8713A06CAE3C886123079CEC990B102930F0C2680FB1B74
425 | 0E54700B39066495425612A4BBE2C8486AAF8EF9D51810E00A41EE9E231B345D
426 | CF03D423017C2B83233FF99315AE36AE06057C8E3690042608EE92CACA4B273B
427 | 6EC397421C3CFE159A339392EFBCBBEA0500A958583734CE654F3CF1DED709CC
428 | 6633AAAABADA4AA55259007D7FFED303AB4F59BA745A6D4DCDE8C08703BE6980
429 | F5F5825A5BC076ED427A7733B6DEFA2B548DAF43D3D567235B63201DED432E98
430 | 82C54D6773095E00F2F0042028290112D035051E5408EB7671C6148025ED704B
431 | 2A2A00C1DD2E9611A033059DE577248542A19273378BF0FEF6B182E581A7823C
432 | BD7F07B17CB3BBDFB8BBD680389CBD2229EF16A47373C057BEDFE1FE979E34C7
433 | 1B3BB22F99A6D105201B0C6A563A27864D691F9000FDF1B8AAA8A810B0A75125
434 | 5F78F6E995EBD6AFBFECACD34EAB1E39F8D25EEC299705DBBFCF36F97BF7A2F3
435 | F9E7B1E7914730E98CE311593016A9CA3432D101987A0E82097B979092E6DEFD
436 | BFBE3D687C729BEC9568BDC5291931047485805EA266A60A97861FFC069FFD56
437 | 45CF2B3F90285CAE058E4B50EE025885AB9E945A6DCF9B44A608E0F60E6C4A92
438 | 33B33CAF0DF2BAA0A05880ED0363AD97DFDAF4A063FEB3D5B190D8B6A7EFFDAF
439 | 159C4AA6644D4D8DD9D3D393CE6432EDF7DE73D713C71E75D4C7AB2A2B0F003E
440 | 404A808400A592601DEDA06DDBA0DADAB0E5CE3B61747560F627CE856C0A2051
441 | 9140369C84D00C4852CE3673FE3589293FD3A64000FA2D00BC8C0A0967E93446
442 | 45337446D16B5762E40F2640E137917F8D231F09BC420D292F7EA341CBC0FB44
443 | A2B237C9860414578050B645F05B029927416F86E3A5EDFC95AEAEF62D00D2D1
444 | 9066660C71C082D6880890CD6650573F46F4F4F46401C49F59F5C4A3EF5C73ED
445 | 05A79D7452F9F0E04B906180FAE3602DCD603B7722B57113B6FEFEF7A89E3416
446 | 13AF59866C8D814C6C00B9600652B36C935F64DAA930B82EF19CDF02486F172E
447 | 2282F294FC7BECBF578582B0B89447CA9FB12B8ACBDD5C805F0FF8B69729EE0E
448 | F2AD9BE5ACA969AFC06EAFC74BF6AC430990F411C1997DB4BDBF56BEF8C6E63F
449 | 01E80590A92A0F5B69431C9CFD0252A9948A2493221C0EE732994C726060A0E5
450 | BE7BEF5975CCE2C59755949797065F58A06C16BC673F68E70E50730B3A56AD42
451 | DBD34F61F2592722B2701CD2D51964A22998C11C24930031675FE16273CFF29B
452 | 539422872F01AF24151805C6F87B07BF406AD301ACC050FADC9FABB7C9E05A02
453 | 3FA7E10BEDA844B95F31F2A201BBC1CBCD23300C64185ED91178BDADAD753D80
454 | 4434A4651963A2A72F71F0368CC864D22A162BB732F6AC89BE554F3CFEC8E557
455 | 5C79D699A79E5A41BEADDB2015485A60C91458673BD8B66D103BB663DB1FEF82
456 | D5DF8B39575F00393184646512B968069666DA0D93DECEA28347BB3FDECF9BF3
457 | C23D88FD4BAA2BE1CC9367E4DB3D04EF93045488AD2AA10D4A9180F21D40DE2A
458 | 688348A00ABEDEBFBF747E753572D2CAB635703767850436B6558967D66C7C00
459 | F6BA07E9AAF2B07920F1376A02249349158E445C2B90E8EDE9D9F9EB5FDDFAA7
460 | D933677EA6695C63FEC44C03ACBF0FBCA505B4633B126FBC896DF7DE8BDA694D
461 | 68B8E43C64EB2C642B9230C319086E394BCFF322300BCDFA50A4F00883BCF977
462 | 17492052765C4F07699AC57024F087658A8A3B34F2337FA970A52F8F044C0DCA
463 | 13946EF6C81797C8118AED718627DFC1D37BF6B4AE03900090658CC4FE118CFE
464 | 5111C0E99055B158CCCCD8DD223D4FAC7874C599679D7DD2F5D75D3B838340B9
465 | 0C784F0FD8CE1DA0EDDBD0FED80AB4AD790553CF598AC8A2714857E7902DCF40
466 | 040D08A600D2F20A7CD0681E2ADC439116C857C8F2519774F2067CD07E3B0785
467 | 0005E0175A01523478DE27A9C1A1A06F1731288704BE53540A43B3C1493C0810
468 | DEEA1CDBBB62D5737703E802901A575F66A40D31E22D644745806422A122A190
469 | 8884C3B974269300B0F7F65FDF7AE709471FF3FDA3A64ED678473BD8B6ADB0D6
470 | AFC7B6BBEF86CCA531EF53CB21278591AAC9C188A661E9F60EA28C7869535FCA
471 | D717287E0C127F9E7A9676778EBD84AC9B3F3888C7B056A0582C16B56C150B43
472 | 5F0187C8D72E4EF095C78BFF7F61F3C8E6EE00EE59D17A5F2A95DA01602012D2
473 | 328C91D8DF9B3C741B4766D21955192B37D3994C8A80BE8E5D3BDF7EFA4FF7BF
474 | 3CF7E28B4E29DBB51389E79FC7D607FF8CBA595331F6ECD390AB97C855656084
475 | 73909AB31FD0A0C44E7E14178676189E00FED8DF6FFE017B69197508A65C8EC0
476 | 150C4A27176FF64885E290942C8C0E30C4DC01DFD7273284A7D6576E7CF38D57
477 | 9F84BDEA49AA3C163452596B541B488F9A00895452559745C5B8DADAECBE783C
478 | 313E16DBD7F7C66BCFB7D7542F8E3CBBBABCF3B5573175D949882C1E8F4C9D85
479 | 5C450E56D080E476C70C2B19BB0F11DAF9DE437EF1576AAB58E91B3D8CF29D34
480 | 879200C52E40158BC212A91EF2258D088EE9F7ED1AE6DF88BAC4C79553407DB9
481 | B93A71DF836FFD16F6B23703E110CF10207AE39943BF79744B57973C7EFA0CAB
482 | AFAF2F5D110CF6D770DED2B272C5B6FABDBB8F99F3D98B404D51A46B0D986539
483 | 88802DF41815FBED626187C1C99D12A37DF067DDC127BDEA1C11CB0BAB43710C
484 | 110E8EC80A386FC96F3E69B77D91DB04EB2E9EED6D25E72F4FD8AB2CBFD51A50
485 | BFB9B7F9CEEEAEEE754EDC9FAAAF8998F18439EA93D6DEEB3590B9AC9CDFD898
486 | 4D19465F672AB5ADB9BAFA71B9ECA486FAE9A1F1C1DA1CAC8809C9A5BDB4DB20
487 | E156ECCB7D041832C133CC7B9C8D19ECD1EF166D0887F42826C1504418CA920F
488 | D2042A1F2EBA7FB3C2FD1400A0A507F8F38BDAD3EBD66D5E057BC5B344657930
489 | 97CA0AD93F90FDE008F07A6BAB3A77F264B1A5AF2FF14E47476B6F32F96C664F
490 | 6BFA9CAAE9379D373156C57514AAFC92611D068776C01082AF8800DE679C75F2
491 | 653EFB57D0B67548095094241A05090A6A077E1214AD0E0E9F3B48641456AC8D
492 | EDBAFF81957F04D00AA03F14E4E95050B33AF7A5E47B390DEDFD5C03CB34D48C
493 | CA0A6353BCAF77C7C0004920B7F19E9EF2F28653BE71F2DC608815C4E1C3B900
494 | 14297E94D609C516C4358E52DAC9240628C50EBEFA7F3F51C181C6649125B04F
495 | 313F5D0CCC2646D65478664B59EFED77ADB95508B1C331FD89DAEA88319034E4
496 | 7B3D85F73D4E4E686CA08434B50D9D3D1100D500C64F9F5C7BD58F6F3AE3734B
497 | A607B5E1553D861484BEA26BE16BAC48242A09257290560ACA4A4349CBB757CF
498 | 0741022A51CE1B0D0954C1E9E4C34147103209532A3CB92198FA979FBFF1F3B6
499 | BDEDAB01B400E8A9AF89A42CA1CCD10ABF834A0000985E5FC52C487D77777F14
500 | 402D80A679331BAEFDAFEF9EF9F1859302AC387D3B28DE776FACB0FC4AAC3479
501 | 0AB6AB5102CAC8405A49289145A9B5F03E7057E09181868E1E0685877E6BA0BC
502 | 684040E1E90DCCF8E1CDEB6ED9B9B3791580DD00F6579607139ACE8DFD3DE9F7
503 | C5F683E6291B6AA2AC2F910DE40C1173483071C9E2A6CFFFF83BA75F346B7C90
504 | BCE6381F19A800F42290FD65E0E21A804B1EA5A0A40965A66D0B208C0F76F497
505 | 22811ACE250C5133A0D2BA4041E1B94D4AFCF8F75B6F7FE79D8D8F39E0EF0B06
506 | F840452C94EBEE49BD6FB61F340284021A9595055822990B3A24A80330F9B48F
507 | 4CBFE19FBE7CF2B2399342841271FE605780D26160B13680DDDBA7440ECA4841
508 | 5A19B7C91E1FCAA186B002831E0F9724CABF2494C2731B95F8E57DBBEE5EF3EA
509 | 9B0F03D809A03B18E0FD15E5A15C326D8A74DA78DFB1AE76B0CE3F6B580A29C8
510 | 5859D0403297CC19820160CFBEBCFD57896436F3EF372DBB78D1B408F354BAEF
511 | ACA964F267B026C84700282C9D119C1675061C8CEADF41B702A311848029249E
512 | 5C87DC4FEF58F7870D1B373D056017807D76C8173E68E01F540BE01EE1A04665
513 | 65413E90C88672862877DDC1DC99632FFFD1DF5F78C59239653AF356FD2E55D5
514 | C3B004281839D284128EF9B7CC0F6FF48F86041826414940C69058F116923FFE
515 | F58BBF6B6E6E7EC1077EBCB23C9CB584B492A9DC41CB721D9268391CD2A92C1A
516 | E0FB7A5221002E09C64F9F5C7FE1BF7E77F935272DAA0A07037C087750D4438D
517 | 21C8E0A87F65A5A084BBA3A6FAF0092087204129175174C4531656BC49BD3FBE
518 | F5E9DBDADBDBD6386A7F3F80FECAF270C612CA4AA6B207F5240F59BA2414D4A8
519 | 2C1AE403C96CD0B02D4135807163EA2A4EF9C60D677DE6D233A78CA9AB0A0CB2
520 | 04C3EA035FEE5F490B4A661D02649DD1FF2113E040510160AF1530C832003BDA
521 | 0DDCF36C6AC79D0F3C77474FCFFE7500F638E00F54C4C259CB92562A933BE827
522 | 7848F365C1804665D1004F247301C3143187040D04CCFBECA74EBFE6FA2B8F39
523 | 6AFAC4081D68E45371D3A75250CA72C04F4349B368E81D2E24A061B6F67396D2
524 | 31155EDA98937F78B4E3A98757AC5AA194DA0AA0DD49F40C94978573A69056E6
525 | 10807FC80900008180466591004BA47241D3145100558E4B987CD4824917FDF3
526 | DF5DB27CC9DCAA6028C887D600285C7F50290148034A38E65F8AC363F41F480F
527 | 1411A1B7DFC4CA37ACFE5FFCEEC5FBB76EDBBEC655FA00FA023A4FC6CAC2B974
528 | C614996CEE909D1C7D10D742D73885C33ACB640CDDB464044085EB12EA6B2B8E
529 | FFFC75675DF9D173E74C9E323E5254F62D45067B1AB912599B00D27026DDE330
530 | 2640A100344D89B55BB3EABE55DDEF3CF4D8CB0FF5F5F56C845DD6DD0FA05FD7
531 | 783A1A0D1A998C2972867948994D1FE4358946028C73A60F24B22100650E09EA
532 | 004C3DF6A869677EE3C60B967DE4E831E535E581215C826BFE6DF5AF441A50E6
533 | C8A67C1D16240076EDCD62E5ABD9CE3BEE5FF3D8962D5BD73A2ABFCB35F99150
534 | 20C339B33239535A9638E427461FF435090634A6699C1BA615705C826B0DC632
535 | 4633AFBEF28C8BAEFFD4C94B664E2A6391102FCE93DA3B6ECAAC63FA33CEE83F
536 | FC09B0BFD7C4CB1BB2B9BB1FDEB17AD5AA179EB384B5DBF1F53DB057244F9545
537 | 43592195C8645B9398D6000003ED49444154721F98A0A10FE3BA681AA7505067
538 | D9ACA15B42861D6B50E910617CC398EA451FBB64E9599FF8E8F1F3A74E88B2B2
539 | B096BF9ECA0244164AA61DF32F0F5F0200E8DC9FC39B9B73C69F57EE7A7DF573
540 | 6B9FEFE9D9BF137629773FEC6D6C129AC6D29170D0CCE64C6118D6077A32F461
541 | 5E9C6040639C336E98226859220220E610A106C0B89A9AF299975D7CF299D75E
542 | B174D1D40965BC3CCAA19409C8B413FA998725F84A016D5D19BCBE2997F9F3E3
543 | 5B5F7BF6B9B52FC5E37D7B1C3FBFCF19F10300D2D1483027A4B20CC35252CA0F
544 | FC64E8C3BE589C330A043426A5D473392B087BEFBE72E7560D606C792C32EDC2
545 | F34E38E5F24B3FB270EAF8606C7C3D10D4CCC36EF40F244D6C6F4DE1CD4D46F7
546 | 93AB37AE7BF1E577D624138936006D8E8FEF87DDBB9FE29C6543C18099334CF1
547 | 41F8FAC396003EB7C082018D6573A62E840C39442873885009600C808685F3A7
548 | CC3BE6A8C98B2E3D6FCE9C498D41BD696CC4D9A1F3C339D2190BCD6D696CDC69
549 | A6563CB365FDDAB75BD66DDBB66DB713CE7502E873467BD2055ED3B829A51296
550 | 2594521FAE823D6C08E0447CC43927C6880B4BEA42CA20803080A8E31E624E1E
551 | A18E080D272F9DB770DCD88AC9179CBD70EAC471C18A86BA101A6AC3D0F8A13B
552 | AD9C21D1D69D46E73E436DDA95DBFFC2CB9B77EE6AEEDFF9D65BEB364B297B1C
553 | 13EF073D0920CD39CB39C05B8703F0872501FCBF8B73468C312E84D0A4540187
554 | 08619F652873C8500DA0BCB23236F6F8E366CC1CDB503EFE8C93E736358E0956
555 | 4643C42A62015496075011D3A1F1915B0AC31488274CF4F51B48A44CF42560ED
556 | 69CFF6BCFCDAB696E6D678DBBBEF6EDF1A8FF7B940F739263E017B4FE2B473CB
557 | 32C6729AC62C29218410F27001FE702780F7FB1823D23863422A4D08A9010802
558 | 0839B7887373AD4485E332CA00446A6BABABE7CC9E38B6B25CAFD5033CD638B6
559 | 3E525B531EAAAA8C846265C16059440B0674A6A573D24CA5ACDC4032978DF7A7
560 | B33D3D03D9EE7D3DA964D24AF4F51BDD3B76B476ECDFBF7F00F6B2AB29C797F7
561 | FBC0CEF8EEB300729AC64D2808A99470C4DD6119AA1CEE0428F89D8C11233B55
562 | A8092175D80B3C051C52F88911F23DEF5A8E10001DF68C110EBB71C0BDF7265D
563 | C35E175102301DC0333E600DE73EEBBCE6DE1B000C22328960113129A5104A0D
564 | 4A071D21C041FACDE4108101E04A290EBBB9C52585EEDCB4A2BF5DF0C977EF2D
565 | E4E9002F7D44706FA6EFDE74003701588C9125A5128C9194D20B4BD45FD3C5FC
566 | 6B3EC8470852764B907F74BB7F6B4523DEFD5CF1EECEB28808A2E8E63E271923
567 | 21A52A6CE4FF2BBD807F4B47F19A1B7EA06988D78B13B7AAC44D0EF1FADFC405
568 | FB5B3F68047F179360B8BF8F1C478E23C791E3C871E4F85B38FE3FF52F073A2C
569 | 1146B50000000049454E44AE426082
570 | }
571 | end
572 | object btnClose: TButton
573 | Left = 288
574 | Height = 25
575 | Top = 136
576 | Width = 112
577 | Anchors = [akRight, akBottom]
578 | Caption = 'Okay, he!'
579 | OnClick = btnCloseClick
580 | TabOrder = 0
581 | end
582 | object lblAppName: TLabel
583 | Left = 144
584 | Height = 16
585 | Top = 8
586 | Width = 202
587 | BorderSpacing.Top = 8
588 | Caption = ''
589 | Font.Style = [fsBold]
590 | ParentColor = False
591 | ParentFont = False
592 | end
593 | object lblAppInfo: TLabel
594 | Left = 144
595 | Height = 16
596 | Top = 24
597 | Width = 195
598 | Caption = ''
599 | ParentColor = False
600 | ParentFont = False
601 | end
602 | object lblAuthors: TLabel
603 | Left = 144
604 | Height = 16
605 | Hint = 'http://www.sizious.com/'
606 | Top = 48
607 | Width = 174
608 | Caption = 'Created in 2015 by SiZiOUS'
609 | Font.Color = clHighlight
610 | ParentColor = False
611 | ParentFont = False
612 | OnClick = lblAuthorsClick
613 | OnMouseEnter = lblAuthorsMouseEnter
614 | OnMouseLeave = lblAuthorsMouseLeave
615 | end
616 | object lblPoweredBy: TLabel
617 | Left = 144
618 | Height = 16
619 | Top = 72
620 | Width = 235
621 | Caption = 'Powered by gditools.py by FamilyGuy'
622 | ParentColor = False
623 | end
624 | object lblCredits: TLabel
625 | Left = 144
626 | Height = 16
627 | Top = 88
628 | Width = 302
629 | Caption = 'Inspired by GD-ROM Explorer by Japanese Cake'
630 | ParentColor = False
631 | end
632 | object lblIcons: TLabel
633 | Left = 144
634 | Height = 16
635 | Top = 112
636 | Width = 305
637 | BorderSpacing.Right = 10
638 | Caption = 'Icons created by Oxygen-Icons.org and Iconleak'
639 | ParentColor = False
640 | end
641 | end
--------------------------------------------------------------------------------